Syntax
public static Bars GetAllDataForSymbol(this string symbol, BarScale scale, int barInterval)
public static Bars GetAllDataForSymbol(this string symbol, string dataSet, BarScale scale, int barInterval)
Parameter Description
symbol | Symbol name |
scale | The symbol's BarScale |
barInterval | The symbol's bar interval |
(optional) dataSetName | Name of specific DataSet to pick the symbol from |
Description
The inability to load a number of bars
before the start of the test period to build indicators, known as "Lead Bars" in legacy versions of Wealth-Lab, affects B&H comparisons and performance metrics sensitive to changes in start/end dates. Imagine an indicator that takes a while to build up - like a 200-day moving average. The Buy & Hold starts immediately while the Strategy has to wait for at least 200 bars. Should Lead Bars exist, they would provide a slightly more accurate statement of performance over the test period when backtesting such Strategy.
Fortunately, there's a
script-based workaround for situations when there's enough historical data for a symbol (e.g. started trading in 1971) and you're only interested in backtesting on a data range (fixed 1000 bars or last 20 years, for instance). This overlap provides a good reserve for preloading the symbol's data and building DataSeries that start immediately, enabling a system to trade on bar #1.
The premise behind this method is simple:
- First, load the entire available historical data for a symbol
- Build your indicator using this Bars object (or its DataSeries)
- Synchronize your indicator with the chart
The idea is that instead of using the Bars object that adheres to the selected data loading range, to create your indicators, you load its complete data using
GetAllDataForSymbol into a Bars object and pass it (or its DataSeries) to your indicator. Optional parameter
dataSetName allows to specify the DataSet that will be searched when an external symbol is requested, which can differ from the DataSet of the symbol on which the Strategy is being executed.
Example
See demo below for an example of loading all history for a symbol to alleviate the absence of "lead bars".
Example using C# extension methods:
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
namespace WealthLab.Strategies
{
public class MyStrategy : WealthScript
{
protected override void Execute()
{
//Bars b = Bars.Symbol.GetAllDataForSymbol( Bars.Scale, Bars.BarInterval );
Bars b = Bars.Symbol.GetAllDataForSymbol( "Dow 30", Bars.Scale, Bars.BarInterval );
DataSeries sma = SMA.Series( b.Close, 200 );
sma = Synchronize( sma );
PlotSeries( PricePane, sma, Color.Blue, LineStyle.Solid, 2 );
for(int bar = 1; bar < Bars.Count; bar++)
{
if (IsLastPositionActive)
{
if( CrossUnder( bar, Close, sma ) )
SellAtMarket( bar+1, LastPosition );
}
else
{
if( CrossOver( bar, Close, sma ) )
BuyAtMarket( bar+1 );
}
}
}
}
}
The Strategy start trading on bar #1 even though it uses a 200-day SMA:
Different scales
Note: The scale parameter has no effect in the GetAllDataForSymbol call. For example, if you scale a chart for Weekly, but load a Daily symbol data file with GetAllDataForSymbol(), daily bars are returned. To get the full history of weekly bars, you have to create a new Bars object and scale manually.
/* Example of how to work with "full history" Weekly bars in a Weekly chart derived from a Daily Bars source */
// GetAllDataForSymbol doesn't return scaled bars
Bars basebars = Bars.Symbol.GetAllDataForSymbol( this.GetDataSetName(), Bars.Scale, Bars.BarInterval );
PrintDebug(basebars.Count);
// Rescale to weekly
Bars bars = new Bars(Bars.Symbol, Bars.Scale, Bars.BarInterval);
DateTime dt = basebars.Date[0];
double o = basebars.Open[0];
double h = basebars.High[0];
double l = basebars.Low[0];
double c = basebars.Close[0];
double v = basebars.Volume[0];
for (int bar = 1; bar < basebars.Count; bar++)
{
if (basebars.Date[bar].DayOfWeek < dt.DayOfWeek)
{
bars.Add(dt, o, h, l, c, v);
dt = basebars.Date[bar];
o = basebars.Open[bar];
h = basebars.High[bar];
l = basebars.Low[bar];
c = basebars.Close[bar];
v = basebars.Volume[bar];
}
else
{
dt = basebars.Date[bar];
c = basebars.Close[bar];
if (basebars.High[bar] > h)
h = basebars.High[bar];
if (basebars.Low[bar] < l)
l = basebars.Low[bar];
v += basebars.Volume[bar];
}
}
bars.Add(dt, o, h, l, c, v);
// Now you can create indicator(s) based on full-history Weekly data
DataSeries sma20 = SMA.Series(bars.Close, 20);
// Synchronize with the chart
sma20 = Synchronize(sma20);
PlotSeries(PricePane, sma20, Color.Blue, LineStyle.Solid, 2);