- ago
In my latest project I switch back and forth between WealthData and Norgate Data.
The last days I was chasing some discrepancies but could not find any bug in my code.

As it turned out, WealthLab does not call Execute() for all symbols in a DataSet.

This happens with WealthData DataSets only.
It happens if the Data Range is set to a Date Range:



Because it is always hard to see somenthing NOT HAPPEN I wrote a special C# coded strategy:

CODE:
using System; using System.Collections.Generic; using System.Text; using WealthLab.Core; using WealthLab.Backtest; namespace WealthScript3 { public class MyStrategy : UserStrategyBase {       static SortedSet<string> execSymbols = new();       static SortedSet<string> btSymbols = new();        public override void BacktestBegin() {          info($"{Backtester.Symbols.Count} symbols in Backtester.Symbols, DataSet={Backtester.ExecutionDataSetName}");          foreach(var bh in Backtester.Symbols) btSymbols.Add(bh.Symbol); } public override void Execute(BarHistory bars, int idx) {          execSymbols.Add(bars.Symbol);       } public override void BacktestComplete() {          info($"{execSymbols.Count} symbols in Execute()");          int numNever = btSymbols.Count - execSymbols.Count;          info($"-- {numNever} Symbols never executed --");          StringBuilder sb = new();          btSymbols.ExceptWith(execSymbols);          foreach(string sym in btSymbols)          {             sb.Append(sym);             sb.Append(", ");          }          info(sb.ToString()); }       private void info(string text)       {          WLHost.Instance.AddLogItem("ExecTest", text, WLColor.Blue);       } } }


If this is run on say Nasdaq-100;WealthData it produces this Log Output:



The missing symbols usually do have data in the Date Range specified.

No such effect with Norgate Data.

0
151
1 Replies

Reply

Bookmark

Jump to End
- ago
#1
Hi DrKoch,

This is actually not a bug, but an intentional feature of WealthData DataSets.

WealthData preloads some historical bars prior to a symbol's entry into an index. This allows indicators to be properly initialized when the symbol becomes an index constituent, rather than starting with insufficient historical data.

However, Execute() is not called for dates when the symbol was not actually a member of the index, even though historical bars may be available for those dates. This is essential for avoiding survivorship bias in backtests.

Another possibility is that the symbol simply didn't trade during the specified Date Range, for whatever reason.

So the presence of historical bars doesn't necessarily mean that Execute() should be called for that symbol. This is by design and one of the benefits of WealthData's historical index constituent tracking.
0

Reply

Bookmark

Jump to Top