Bars Object

The Bars object represents a collection of historical open, high, low, close and volume values.

BuyAtMarket

BarInterval Property

int BarInterval

Returns the intraday bar interval of the Bars object.  For example, if the Bars object contains 5-minute bars, BarInterval will return 5.

Remarks


Example

protected override void Execute(){
    // Returns the chart bar interval
    if( Bars.BarInterval > 0 )
        PrintDebug( "BarInterval: " + Bars.BarInterval + " tick, second or minute " ); else
        PrintDebug( "BarInterval is Daily or greater" );
}
BuyAtMarket

Cache Property

Dictionary<string, DataSeries> Cache

Each Bars object maintains an internal cache that stores the indicators (which are DataSeries objects) created based on itself, or its open, high, low, close, or volume.  The Cache property provides access to these indicators.  The Cache is a name=DataSeries Dictionary, and the DataSeries are stored using their Description as the Dictionary key.  You will likely never need to use the Cache in Strategy code, but it can be useful when building custom Performance Visualizers, because it provides access to all of the indicators created by the Strategy.

Remarks


Example

protected override void Execute(){    // Creating a SMA the regular way:
    DataSeries sma = SMA.Series( Close,20 );
    
    // Creating a proxy data series:
    DataSeries sma_test  = new DataSeries(Bars,"test");
    
    // Find the 20-period SMA in the Bars.Cache property by its Description...
    if (Bars.Cache.ContainsKey("SMA(Close,20)"))
        //... and assign the result to the proxy series:
        sma_test = (DataSeries)Bars.Cache["SMA(Close,20)"];
    
    // Test by plotting the proxy series
    ChartPane test = CreatePane( 30, false, true );
    PlotSeries( test, sma_test, Color.Black, LineStyle.Solid, 1 );
}
BuyAtMarket

Close Property

DataSeries Close

Returns a DataSeries object that represents the closing prices of the Bars object.  Access individual closing prices via the square bracket syntax:

//Access closing price of the last bar
double lastClose = Bars.Close[Bars.Count - 1];

Remarks

 


Example

protected override void Execute(){
    //Access closing price of the last bar
    double lastClose = Bars.Close[Bars.Count-1];
    // The string is output with 2 digits
    DrawLabel( PricePane, "Last close: " + String.Format( "{0:f}", lastClose ), Color.Black );
}
BuyAtMarket

ConvertDateToBar

int ConvertDateToBar(DateTime date, bool exactMatch);

Returns the bar number that matches the DateTime provided in the date parameter.  If exactMatch is true, the precise DateTime value must be located in the Bars object.  Otherwise, the first bar whose DateTime is greater than or equal to the specified date is returned.

Remarks

  • (Doesn't affect WealthScript Strategy coding). In development of PosSizers and Performance Visualizers, accessing an EquityCurve or CashCurve value in multi-symbol portfolio simulations may produce unexpected results because the different historical DataSets aren't synchronized when backtesting. Solution: in a multi-symbol backtest, it's advised to use the ConvertDateToBar method of the EquityCurve or CashCurve DataSeries to get a correct bar. For example, here's how to determine the equity curve value at the beginning of a month using ConvertDateToBar:

double MonthStartEquity = EquityCurve[0];
DateTime b = bars.Date[bar];
DateTime tmp = new DateTime(b.Year, b.Month, 1);
MonthStartEquity = EquityCurve[EquityCurve.ConvertDateToBar(tmp, false)];


Example

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Threading;
using System.Globalization;
using WealthLab;

namespace WealthLab.Strategies
{
    // Print how much days since year began
    
    public class MyStrategy : WealthScript
    {
        public int HowMuchDaysToBar( int bar, int year )
        {
            CultureInfo en = new CultureInfo("en-US");
            Thread.CurrentThread.CurrentCulture = en;
            String format = "yyyyMMdd";
            DateTime dtParsed = DateTime.ParseExact( Convert.ToString( year * 10000 + 101 ), format, en.DateTimeFormat );
            return bar - Bars.ConvertDateToBar( dtParsed, false ) + 1;
        }

        protected override void Execute()
        {
            int year = 2007;
            DrawLabel( PricePane, HowMuchDaysToBar( Bars.Count-1, year ) + " bars since year " + year + " started" );
        }
    }
}
BuyAtMarket

Count Property

int Count

Returns the number of bars that are contained in the Bars object.  The Bars object's Date, Open, High, Low, Close, Volume, and any "Named DataSeries" it contains, will always have the same number of values as the Bar's Count.


Example

protected override void Execute(){
    // Typical trading system main loop relies on Bars.Count property
    for(int bar = 20; bar < Bars.Count; bar++)
    {
    ///...            
    }
}
BuyAtMarket

DataScale Property

BarDataScale DataScale

Returns a BarDataScale struct, which contains the Bars object's Scale and BarInterval in one structure.


Example

protected override void Execute(){
    // Returns the chart bar interval and data scale
    BarDataScale ds = Bars.DataScale;
    if( ds.BarInterval == 0 )
    PrintDebug( ds.Scale ); else
    PrintDebug( ds.BarInterval + "-" + ds.Scale );    
}
BuyAtMarket

Date Property

IList<DateTime> Date

Returns a list of DateTime values that represents the historical date/times of the Bars object. Access individual date values via the square bracket syntax:

//Access the last date being charted
DateTime lastDate = Bars.Date[Bars.Count - 1];


Example

protected override void Execute(){
    //Access the last date being charted
    DateTime lastDate = Bars.Date[Bars.Count - 1];
    DrawLabel( PricePane, "Last trading date: " + String.Format( "{0:d}", lastDate ), Color.Black );
}
BuyAtMarket

FindNamedSeries

DataSeries FindNamedSeries(string name);

Locates a "Named DataSeries" that exists within the Bars object.  Named DataSeries can be registered with a Bars object by specific Data Providers.  A common example of a possible Named DataSeries is open interest for futures data.  Another example are additional data fields that are imported in ASCII files.

Remarks

  • If the specified Named DataSeries was not found, FindNamedSeries returns null.
  • Workaround: Use GetExternalSymbol overload that accepts dataSetName as shown here. As an alternative, use GetAllDataForSymbol (example).

Example

protected override void Execute(){
    DataSeries MySeries;
    MySeries = Bars.FindNamedSeries( "SeriesName" );
}
BuyAtMarket

FirstActualBar Property

int FirstActualBar

Returns an integer number of the bar that represents the first "real" bar of the secondary series. You can use this value to make sure that you don't enter trades on the symbol before its actual history began.

This function is useful in scripts that loop through and execute trades on all of the symbols in a DataSet. In these cases, Wealth-Lab's synchronization feature will transform secondary data series so that they synchronize with the Primary series, the one clicked to run the script. If a secondary data series has a shorter history than the Primary series, data bars are appended to the beginning of the secondary series so that it's BarCount equals that of the Primary series.


Example

using System;
using System.Collections;
using System.Text;
using WealthLab;

namespace WealthLab.Strategies
{
    public class MyStrategy : WealthScript
    {
        protected override void Execute()
        {
            const char tab = '\u0009';                
            SortedList list = new SortedList( DataSetSymbols.Count );            
            
            for(int ds = 0; ds < DataSetSymbols.Count; ds++)
            {
                SetContext( DataSetSymbols[ds], true );
                list.Add( ds, Bars.FirstActualBar );
                RestoreContext();
            }
            
            foreach( DictionaryEntry i in list )
                PrintDebug( "First bar of " + DataSetSymbols[(int)i.Key] + tab + ": -- #" + i.Value );
        }
    }
}
BuyAtMarket

FormatValue

string FormatValue(double value);

Formats the specified value into a string, using the current number of Decimals.


Example

protected override void Execute(){
    // Output closing value to the chart
    DrawLabel( PricePane, Bars.FormatValue( Bars.Close[Bars.Count-1] ), Color.Red );
}
BuyAtMarket

HasNamedDataSeries Property

bool HasNamedDataSeries

The HasNamedDataSeries property returns true if any "Named DataSeries" have been registered in the Bars object.


Example

protected override void Execute(){
{
    if( Bars.HasNamedDataSeries )
    {
        PrintDebug( Bars.Symbol + " contains " + 
            Bars.NamedSeries.Count + " named series"  );
    } 
    else
        PrintDebug( Bars.Symbol + " does not contain named series" );            
}
BuyAtMarket

High Property

DataSeries High

Returns a DataSeries object that represents the high prices of the Bars object.  Access individual high prices via the square bracket syntax:

//Access high price of the last bar
double lastHigh = Bars.High[Bars.Count - 1];

Remarks

  • See the DataSeries object reference for a listing of available properties and methods on the DataSeries object.

 


Example

protected override void Execute(){
    // Print high price of the last bar
    double high = Bars.High[Bars.Count-1];
    DrawLabel( PricePane, "High: " + String.Format( "{0:f}", high ), Color.Black );
}
BuyAtMarket

IntradayBarNumber

int IntradayBarNumber(int bar)

Returns the intraday bar number of the day for intraday data.  If the Bars object contains non-intraday data, IntradayBarNumber always returns -1.  The first bar of a particular date returns 0, the next bar returns 1, and so on.


Example

protected override void Execute(){
    // Check for intraday data
    if ( Bars.IsIntraday )
    {
        // Color the middle of the trading day

        // First determine how many bars there are in one day
        int MaxBars = 0;
        double pct;
        
        for(int bar = Bars.Count-1; bar > -1; bar--)
            if ( Bars.IntradayBarNumber( bar ) == 0 )
        {
            MaxBars = Bars.IntradayBarNumber( bar-1 );
            break;
        }
        if ( MaxBars == 0 )
            return;

        // Now color the bars 40 - 60% within the day's range            
        for(int bar = 0; bar < Bars.Count; bar++)
        {
            pct = (float) Bars.IntradayBarNumber( bar ) / MaxBars;
            if ( ( pct >= 0.4 ) & ( pct <= 0.6 ) )
                SetBarColor( bar, Color.Olive );

        }
    }
}
BuyAtMarket

IsIntraday Property

bool IsIntraday

Returns whether the Bars object contains intraday data.


Example

protected override void Execute(){
    if ( Bars.IsIntraday != true )
        System.Windows.Forms.MessageBox.Show( "Not an intraday chart " );
    else
        System.Windows.Forms.MessageBox.Show( "The intraday bar interval is " + Bars.BarInterval );
}
BuyAtMarket

IsLastBarOfDay

bool IsLastBarOfDay(int bar)

Returns true if this is the last bar of a particular day for intraday data.  If the Bars object contains non-intraday data, IsLastBarOfDay always returns false.  If bar equals the last bar of data in the chart, IsLastBarOfDay finds the previous bar that was the last bar of the day, and compares the time values to determine if the bar is in fact the last bar of the current day.


Example

protected override void Execute(){
    // Daytrading SMA crossover script (backtesting only) 
    // that closes all positions at the end of the day.

    DataSeries hMAFast = SMA.Series( Close, 10 );
    DataSeries hMASlow = SMA.Series( Close, 30 );
    PlotSeries( PricePane, hMAFast, Color.Green, WealthLab.LineStyle.Solid, 1 );
    PlotSeries( PricePane, hMASlow, Color.Red, WealthLab.LineStyle.Solid, 1 );
    
    for(int bar = hMASlow.FirstValidValue; bar < Bars.Count; bar++)
    {
        if (!IsLastPositionActive)
        {
            if ( Bars.IsLastBarOfDay( bar ) == false )
                if ( CrossOver( bar, hMAFast, hMASlow ) )
                BuyAtMarket( bar+1, "XOver" );
        }
        else
        {
            Position p = LastPosition;
            if ( Bars.IsLastBarOfDay( bar ) == true )
                SellAtClose( bar, p, "EOD" );
            else
            {
                // normal intraday exit logic
                if ( CrossUnder( bar, hMAFast, hMASlow ) )
                    SellAtMarket( bar+1, p, "XUnder" );
                }
        }
    }
}
BuyAtMarket

IsSynthetic

bool IsSynthetic(int bar);

Allows you to determine if individual bars in the Bars object are "synthetic".  Synthetic bars are bars that are created as a result of the AddCalendarDays WealthScript method.

Remarks

  • Known issue: Bars.IsSynthetic wrongly marks the first trading bar after a series of synthetic bars added by AddCalendarDays. It does not work as documented, i.e. synthetic bars are not marked.

Example

protected override void Execute(){
    // Highlight added bars
    
    if( Bars.Scale == 0 )
    {
        int added = AddCalendarDays( true );
        DrawLabel( PricePane, "Interpolated bars: "+ added.ToString(), Color.YellowGreen );
    
        for(int bar = 0; bar < Bars.Count; bar++)
        {
            if( Bars.IsSynthetic( bar ) )
                SetBarColor( bar, Color.YellowGreen );
        }
    } else
        System.Windows.Forms.MessageBox.Show( "Data must be Daily" );
}
BuyAtMarket

LoadFromFile

void LoadFromFile(string fileName)
void LoadFromFile(string fileName, int maxBars)
void LoadFromFile(string fileName, System.DateTime startDate, System.DateTime endDate)
void LoadFromFile(string fileName, System.DateTime startDate, System.DateTime endDate, int maxBars)

Loads the Bars object from an existing file on disk. The binary file can be created by any Wealth-Lab data provider, or manually in Strategy code (see SaveToFile).

Optionally, it's possible to load a specific amount of most-recent bars no greater than the maxBars value (see example below). In addition, you can limit the time interval using the startDate and endDate parameters.


Example

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;

namespace WealthLab.Strategies
{
    /*  Load bars from file */
    
    public class TestLoadBars : WealthScript
    {
        protected override void Execute()
        {
            Bars bars = new Bars("NewBars",BarScale.Daily,0);
            
            /* Pass "true" to GetDataPath() if using Wealth-Lab Pro,
            for Wealth-Lab Developer make it "false" 
            
            Note: The data should NOT be relocated, otherwise you would have 
            to correct the path inside the GetDataPath() function body */
            
            string sym = GetDataPath( false ) + @"Daily\A\A.WL";
            
            // Load just 100 recent bars of the stock called "A"
            bars.LoadFromFile( sym, 100 );
            
            // Plot the data
            bars = Synchronize( bars ); 
            ChartPane newBars = CreatePane( 50, true, true );
            PlotSymbol( newBars, bars, Color.Blue, Color.Red );
        }
        
        // Get the path to directory where data is stored
        public static string GetDataPath( bool pro )
        {
            string path = pro ?
                @"\Fidelity Investments\WealthLabPro\1.0.0.0\Data\FidelityStaticProvider\" :
                @"\Fidelity Investments\WealthLabDev\1.0.0.0\Data\YahooStaticProvider\";
            return 
                Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + path;
        }
    }
}
BuyAtMarket

Low Property

DataSeries Low

Returns a DataSeries object that represents the low prices of the Bars object.  Access individual low prices via the square bracket syntax:

//Access low price of the last bar
double lastLow = Bars.Low[Bars.Count - 1];

Remarks

  • See the DataSeries object reference for a listing of available properties and methods on the DataSeries object.

 


Example

protected override void Execute(){
    // Print low price of the last bar
    double low = Bars.Low[Bars.Count-1];
    DrawLabel( PricePane, "Low: " + String.Format( "{0:f}", low ), Color.Black );
}
BuyAtMarket

NamedSeries Property

ICollection<DataSeries> NamedSeries

The NamedSeries property returns a list of all of the "Named DataSeries" that have been registered in the Bars object.  Named DataSeries can be registered with a Bars object by specific Data Providers.  A common example of a possible Named DataSeries is open interest for futures data.  Another example are additional data fields that are imported in ASCII files.


Example

protected override void Execute(){
    // Run this on a DataSet with defined Custom series
    
    // For example:
    //DATE;TIME;VOLUME;OPEN;CLOSE;MIN;MAX
    //06/08/2007;22:36:41;0;21.83;21.83;21.83;21.83
    //06/08/2007;22:36:51;0;21.83;21.83;21.83;21.83
    //06/08/2007;22:37:01;0;21.83;21.83;21.83;21.83
    // Will output 'Min' and 'Max'
    
    if ( Bars.NamedSeries.Count > 0 )
    {            
        foreach( DataSeries d in Bars.NamedSeries )
            PrintDebug( d.Description );
    }
}
BuyAtMarket

Open Property

DataSeries Open

Returns a DataSeries object that represents the open prices of the Bars object.  Access individual open prices via the square bracket syntax:

//Access open price of the last bar
double lastOpen = Bars.Open[Bars.Count - 1];

Remarks

  • See the DataSeries object reference for a listing of available properties and methods on the DataSeries object.

 


Example

protected override void Execute(){
    // Print open price of the last bar
    double open = Bars.Open[Bars.Count-1];
    DrawLabel( PricePane, "Open price: " + String.Format( "{0:f}", open ), Color.Black );
}
BuyAtMarket

SaveToFile

void SaveToFile(string fileName)

Saves the Bars object to a file on disk. The binary file can be recognized by Wealth-Lab natively (see LoadFromFile).


Example

protected override void Execute(){
    /* Create a Heikin-Ashi chart and save the resulting bars to file */

    HideVolume();
    Bars bars = new Bars( Bars.Symbol.ToString() + " (Heikin-Ashi)", BarScale.Daily, 0 );
    
    // Create Heikin-Ashi series
    DataSeries HO = Open + 0;
    DataSeries HH = High + 0;
    DataSeries HL = Low + 0;         
    DataSeries HC = (Open + High + Low + Close) / 4;
    
    // Build the Bars object
    for (int bar = 1; bar < Bars.Count; bar++)
    {
        double o1 = HO[bar-1]; 
        double c1 = HC[bar-1]; 
        HO[bar] = ( o1 + c1 ) / 2; 
        HH[bar] = Math.Max( HO[bar], High[bar] ); 
        HL[bar] = Math.Min( HO[bar], Low[bar] );             
        
        bars.Add( Bars.Date[bar], HO[bar], HH[bar], HL[bar], HC[bar], Bars.Volume[bar]);
    }

    // Save the virtual Heikin-Ashi bars to disk
    string file = @"C:\Heikin-Ashi.WL";
    bars.SaveToFile( file );
    
    // Verify by loading from disk and plotting
    Bars haBars = new Bars("Saved Heikin-Ashi Bars",BarScale.Daily,0);
    haBars.LoadFromFile( file );            
    haBars = Synchronize( haBars );            
    ChartPane haPane = CreatePane(50, false, true);
    PlotSymbol(haPane, haBars, Color.DodgerBlue, Color.Red);            
}
BuyAtMarket

Scale Property

BarScale Scale

Returns the Scale of the data contained in the Bars object.  Possible Scale values are:

  • Daily
  • Weekly
  • Monthly
  • Minute
  • Second
  • Tick
  • Quarterly
  • Yearly

Example

protected override void Execute(){
    System.Windows.Forms.MessageBox.Show( "Data scale is " + Bars.Scale );
}
BuyAtMarket

SecurityName Property

string SecurityName

Returns the security name of the symbol contained in the Bars object.  This will be the company name for stocks, and the name of the commodity or future for futures symbols.


Example

protected override void Execute(){
    System.Windows.Forms.MessageBox.Show( "We're now viewing " + Bars.SecurityName + " chart");
}
BuyAtMarket

Symbol Property

string Symbol

Returns the symbol for the data that was loaded into the Bars object.


Example

protected override void Execute(){
    // Show the closing price with the symbol in a chart label }
    double x = Close[Bars.Count-1];
    DrawLabel( PricePane, "Closing price for " + Bars.Symbol + " is " + x, Color.DarkSlateGray );
}
BuyAtMarket

SymbolInfo Property

The SymbolInfo object represents a number of symbol's properties: Decimals, Margin, Point Value, Security Type and Tick.


Example

protected override void Execute(){
    SymbolInfo si = Bars.SymbolInfo;
    PrintDebug( Bars.Symbol );    
    PrintDebug( "Symbol= " + si.Symbol );              
    PrintDebug( "Point Value = " + si.PointValue );
    PrintDebug( "Tick = " + si.Tick );  
    PrintDebug( "Margin = " + si.Margin );
    PrintDebug( "Decimals = " + si.Decimals); 
    PrintDebug( "" );
}
BuyAtMarket

Tag Property

object Tag

The Tag property allows you to store any object with a Bars object.


Example

protected override void Execute(){//
            //"currentPos" is null when sizing trading signals on bar+1 (Alert) in PosSizers.
            //This example illustrates how to send a double value to a PosSizer
            //from a Strategy to size an Alert.            
            //        

            for(int bar = 5; bar < Bars.Count; bar++)
            {
                if( IsLastPositionActive )
                {
                    SellAtMarket( bar+1, LastPosition );
                } 
                else
                {
                    if( Close[bar] <= Lowest.Series( Close, 5 )[bar-1] )
                    {
                        double size = 100;
                        if( BuyAtMarket( bar+1 ) == null && (bar == Bars.Count-1) )
                        {
                            // Store some double value in the current Bars.Tag property
                            Bars.Tag = size;
                        }
                    }
                }
            }
            
            // Next, in your PosSizer's SizePosition method call:
            
            // double size = (double)bars.Tag;
        }
    }
}
BuyAtMarket

Volume Property

DataSeries Volume

Returns a DataSeries object that represents the volume of the Bars object.  Access individual bar volumes via the square bracket syntax:

//Access volume of the first bar
double firstVolume = Bars.Volume[0];

Remarks

  • See the DataSeries object reference for a listing of available properties and methods on the DataSeries object.

 


Example

protected override void Execute(){
    //Access volume of the last bar
    double turnover = Bars.Close[Bars.Count-1] * Bars.Volume[Bars.Count-1];
    // Print stock turnover
    DrawLabel( PricePane, "Turnover: " + String.Format( "${0:0,0}", turnover ), Color.Black );
}