DataSet Provider API
A DataSet Provider Extension supplies one or more predefined DataSets that users can select for backtesting and trading in WealthLab 9. DataSets supplied by a DataSet Provider appear under a dedicated node in the WealthLab DataSet tree.

Build Environment
You can create a DataSet Provider in a .NET development tool such as Visual Studio 2026.
Create a class library project that targets .NET10, then reference the WealthLab.Core library DLL that you'll find in the WL9 installation folder.
Your DataSet Provider will be a class in this library that descends from DataSetProviderBase, which is defined in the WealthLab.Core library, in the WealthLab.Data namespace. After you implement and build your library, simply copy the resulting assembly DLL into the WL9 installation folder. The next time WL9 starts up, it will discover your DataSet Provider, making it available in appropriate locations of the WL9 user interface.

Accessing the Host (WL9) Environment
The IHost interface provides access to the current WealthLab environment. Extensions can use it to retrieve application-level information and services, such as the location of the user's WealthLab data folder or the DataSets defined by the user.
You can access the current IHost instance from anywhere in your extension through the WLHost singleton and its Instance property. For example, the following code retrieves the path to the user's WealthLab data folder:
string folder = WLHost.Instance.DataFolder;
Use WLHost.Instance whenever your extension needs access to functionality exposed by the IHost interface.
Descriptive Properties
public string Name
Override this property to return the name of the node that will contain your Provider's DataSets in the WealthLab DataSet tree. If you do not override Name, the default value is based on the name of your extension assembly.
Core Functionality
public virtual void Initialize()
Override this method to perform any initialization required by your DataSet Provider. Typically, this is where you create and initialize the DataSet instances that will subsequently be returned by the DataSets property.
public abstract List<DataSet> DataSets
Override this property to return the DataSets supplied by your Provider. You can return instances of the DataSet class directly or instances of custom classes derived from DataSet. Each DataSet in the returned collection appears as a sub-node beneath your Provider in the WealthLab DataSet tree.
public virtual void SymbolsModified(
DataSet ds,
List<string> symbols)
WealthLab calls this method when the user modifies the symbols belonging to one of your Provider's DataSets. This can occur only when the DataSet's ReadOnlySymbols property is false. The default implementation assigns symbols to the DataSet's Symbols property. Override this method if additional processing or persistence is required when the symbol list changes. If you want to retain the default behavior, call:
base.SymbolsModified(ds, symbols);
Creating DataSet Instances
The following properties are commonly used when creating and configuring the DataSet instances returned by your Provider. You can use DataSet directly or create your own class derived from DataSet when custom behavior is required.
Name
public string Name
Assign the name that WealthLab should display for the DataSet.
Symbols
public List<string> Symbols
Contains the symbols that belong to the DataSet. Assign a collection to this property or populate the existing collection with the symbols that comprise your DataSet.
TradableSymbols
public virtual List<string> TradableSymbols
Returns the symbols that should currently be considered tradable. The default implementation returns the DataSet's Symbols collection. Override this property in a DataSet-derived class when some symbols should remain part of the DataSet for historical purposes but should no longer be considered available for current trading. For example, a DataSet representing an index might contain historical constituents that have since been delisted. They can remain in Symbols while being excluded from TradableSymbols.
The Strategy Monitor uses TradableSymbols when processing a Strategy activated against the DataSet.
GlyphResource
public string GlyphResource
Override this property in a DataSet-derived class to provide an icon for the DataSet. Return the resource name of an image embedded in your extension assembly. For example, if your assembly is:
MyCompany.WLExtension
and it contains the embedded resource:
Glyphs/MyImage.png
the GlyphResource would be:
MyCompany.WLExtension.Glyphs.MyImage.png
PreferredDataProviderName
public string PreferredDataProviderName
Use this property when the DataSet should preferentially obtain historical data from a particular Historical Data Provider. Assign the Provider's Name to this property. When WealthLab requests historical data for the DataSet, it will attempt to use that Provider first.
ReadOnlySymbols
public bool ReadOnlySymbols
Controls whether users can modify the DataSet's symbol list. Set this property to true when the DataSet's membership is managed entirely by your Provider and should not be edited by the user.
DynamicDateRanges
public Dictionary<string, DateRange> DynamicDateRanges
Contains the valid historical membership ranges for symbols in a dynamic DataSet. The Dictionary is keyed by symbol. Each associated DateRange specifies the period during which that symbol should be considered an active member of the DataSet. When WealthLab backtests using the DataSet, trades for a symbol are permitted only during its executable date range. This allows DataSet Providers to model changing index membership and other dynamic universes, helping prevent survivorship bias when backtesting historical constituents.
Self-Loading DataSets
A custom class derived from DataSet can load its own historical data instead of relying on WealthLab's normal Historical Data Provider mechanism. This is useful when the DataSet itself needs complete control over how its historical data is obtained or processed.
ShouldReturnOwnData
public virtual bool ShouldReturnOwnData
Override this property and return true to indicate that the DataSet will provide its own historical data. When enabled, WealthLab calls the DataSet's GetHistory method instead of using its normal Historical Data Provider loading mechanism.
SupportsScale
public virtual bool SupportsScale(HistoryScale scale)
Override this method to indicate whether the DataSet can provide historical data for the specified HistoryScale. Return true for supported scales and false otherwise.
GetHistory
public virtual BarHistory GetHistory(
string symbol,
HistoryScale scale,
DateTime startDate,
DateTime endDate,
int maxBars,
DataRequestOptions cb)
WealthLab calls this method when requesting historical data from a self-loading DataSet. Interpret the date and bar-count parameters as follows:
- If maxBars is non-zero, return up to that number of the most recent bars.
- If endDate is
DateTime.MaxValue, return data through the current date and time. - If startDate is
DateTime.MinValue, return data going as far back into the past as possible. - Otherwise, return data for the range specified by startDate and endDate.
A typical implementation should:
- Verify that the requested scale is supported. Return
nullif it is not. - Verify that the requested symbol is supported by the DataSet. Return
nullif it is not. - Create a BarHistory using the constructor that accepts the symbol and HistoryScale.
- Assign the BarHistory's SecurityName if one is available.
- Obtain historical data from your underlying data source for as much of the requested range as possible.
- Use the BarHistory Add method to add each bar's date, open, high, low, close, and volume.
- Return the completed BarHistory.
For example, the basic structure might look like:
public override BarHistory GetHistory(
string symbol,
HistoryScale scale,
DateTime startDate,
DateTime endDate,
int maxBars,
DataRequestOptions cb)
{
if (!SupportsScale(scale))
return null;
if (!Symbols.Contains(symbol))
return null;
BarHistory bars = new BarHistory(symbol, scale);
// Obtain historical data and populate bars here.
return bars;
}
PostDataLoad
public virtual void PostDataLoad(BarHistory bh)
WealthLab calls this method after a self-loading DataSet has returned historical data from GetHistory. The default implementation processes the DataSet's DynamicDateRanges and applies the appropriate executable ranges to the BarHistory using AddExecutableRange. Override this method when additional processing is required after historical data has been loaded. If you override it and still want WealthLab to apply the DataSet's dynamic membership ranges, call:
base.PostDataLoad(bh);
Avoiding Survivorship Bias
A DataSet Provider can model historical index membership so that backtests operate only on symbols that were actually constituents of an index at a particular point in time. A typical implementation works as follows:
- Create a custom class derived from DataSet, for example
MySqlDataSet. - Have your DataSetProviderBase implementation create and return one or more MySqlDataSet instances through its DataSets property.
- Configure the custom DataSet appropriately. For example:
ReadOnlySymbols = true;
PreferredDataProviderName = "My SQL Provider";
and override ShouldReturnOwnData to return true.
- Override GetHistory to obtain the historical data for the requested symbol.
- From GetHistory, obtain the appropriate Historical Data Provider and request the symbol's BarHistory for the requested date range.
- Determine the period during which the symbol was a member of the index.
- Call the BarHistory's AddExecutableRange method with that membership period.
For example:
BarHistory bars = // obtain historical data
bars.AddExecutableRange(startMembership, endMembership);
return bars;
The executable range tells WealthLab that the symbol can participate in the backtest only during the period in which it was actually a member of the DataSet. This allows the DataSet to retain former constituents for historical testing while preventing Strategies from trading those symbols outside their actual membership periods.