GetAllDataForSymbol

Modified on 2017/09/05 08:03 by Eugene — Categorized as: Community Components

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

symbolSymbol name
scaleThe symbol's BarScale
barInterval The symbol's bar interval
(optional) dataSetNameName 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:

  1. First, load the entire available historical data for a symbol
  2. Build your indicator using this Bars object (or its DataSeries)
  3. 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.

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);

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 ); } } } } }

Legacy syntax example:


using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
using Community.Components; /*** Requires installation of Community.Components Extension from www.wealth-lab.com > Extensions ***/

namespace WealthLab.Strategies { public class MyStrategy : WealthScript { protected override void Execute() { //Bars b = Utility.GetAllDataForSymbol( Bars.Symbol, Bars.Scale, Bars.BarInterval ); Bars b = Utility.GetAllDataForSymbol( "Dow 30", Bars.Symbol, 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:

Image