Algorithm Reference

Handling Data

Introduction

Requested data is passed into event handlers for you to use to make trading decisions. The primary event handler, Slice, groups all data types together at a single moment in time in the OnData(Slice data)def OnData(self, slice): handler. Slice is short for "time slice" - representing a slice of time and values of the data at that time. C# and F# also allow you to receive data with dedicated event handlers for each data type e.g OnData(TradeBars data).Python only supports the Slice event handlers.

All data uses DataDictionary objects to group data by symbol and provide easy access to information. The plural of the type denotes the collection of objects e.g. the TradeBars DataDictionary is made up of TradeBar objects. You can access individual data points in the dictionary through its string or symbol dictionary index. For example var ibmTradeBar = slice.Bars["IBM"] ibmBar = slice.Bars["IBM"].

Time Slices

The Slice event handler combine all of the data together into a single method. It represents the data at a point in time. The Slice object contains many helpers for accessing your data. The Slice objects arrive to the OnData(Slice data)def OnData(self, slice) event handler.

The Slice object gives you threetwo ways to access your data:

  • Dynamic string/symbol indexer which returns a dynamic object of your type slice["IBM"].
  • Statically typed properties (slice.Bars[], slice.QuoteBars[]).
  • Statically typed Get<T>() helper

Strongly typed access gives you compile time safety but dynamic types can sometimes simplify coding. We recommend static types as they are easier to debug.

Slice has the following internal structure:

class Slice : IEnumerable<KeyValuePair<Symbol, BaseData>>
{
    TradeBars Bars;
    QuoteBars QuoteBars;
    Ticks Ticks;
    OptionChains OptionChains;
    FuturesChains FuturesChains;
    Splits Splits;
    Dividends Dividends;
    Delistings Delistings;
    SymbolChangedEvents SymbolChangedEvents;
}
class Slice:
    TradeBars Bars;
    QuoteBars QuoteBars;
    Ticks Ticks;
    OptionChains OptionChains;
    FuturesChains FuturesChains;
    Splits Splits;
    Dividends Dividends;
    Delistings Delistings;
    SymbolChangedEvents SymbolChangedEvents;

It contains all the data for a given moment of time. TradeBars and QuoteBars are symbol/string indexed dictionaries so you can easily access the data. Ticks is a list of ticks for that moment of time; indexed by the symbol.

To make accessing the data easier the Slice object itself can also be indexed. e.g. slice["IBM"] will return a TradeBar for IBM. slice["EURUSD"] will return a QuoteBar for EURUSD.

// Event handler for Slice method
public void OnData(Slice data) {
}
// Event handler for Slice method
member this.OnData(slice:Slice) =
      ()
# Event handler for the slice method
def OnData(self, slice):
    pass
//Access data in a Slice object:
// 1. Strong Typed Properties: Ticks, TradeBars, Delistings, SymbolChangedEvents, Splits and Dividends
var bars = slice.Bars; // e.g. bars["IBM"].Open

// 2. Strong Typed Get Accessor:
var bars = slice.Get(); //e.g. bars["IBM"].Open
var bar   = slice.Get("IBM"); //e.g. bar.Open

// 3. Dynamic String / Symbol Indexer:
var bar = slice["IBM"]; // e.g. bar.Open
#Access data in a Slice object:
# 1. Grouped Properties: Ticks, Bars, Delistings, SymbolChangedEvents, Splits and Dividends
bars = slice.Bars; # e.g. bars["IBM"].Open

# 2. Dynamic String / Symbol Indexer:
bar = slice["IBM"] # e.g. bar.Open - TradeBar properties OHLCV
spyTickList = data["SPY"] # Tick assets return a list of Tick objects.

Since the Slice object is indexed, it is possible to check if the time slice contains specific data. e.g. slice.ContainsKey("EURUSD") will return a boolean. Even if requesting data to be filled forward you should check if the data exists in the dictionary first. If there is little trading, or you are in the same time loop as when you added the security, it may not have any data.

Other Event Handlers

In C#/F# data is also piped into dedicated event handlers for each data type. To use data this way you need to put an event handler in your algorithm which follows the pattern: public void OnData(TradeBars data) {}. LEAN automatically detects the method exists and sends data to it. Python passes all data events into the def OnData(self, slice): event handler. This is the preferred way to access data for your strategy. This includes all the data you've requested for your algorithm, including custom data.

public void OnData(TradeBars data) {
    // TradeBars objects are piped into this method.
}
public void OnData(Ticks data) {
    // Ticks objects are piped into this method.
}

Data Formats

There are six financial data types: TradeBars, Ticks, Delistings, SymbolChangedEvents, Splits and Dividends.

All data extends from BaseData - the core data class which provides Symbol, Time and Value properties.

TradeBar events contains Open, High, Low, Close and Volume properties for a given period of time.

Dividend events are triggered on payment of a dividend. It provides the Distribution per share.

Split events are triggered on a share split or reverse split event. It provides a SplitFactor and ReferencePrice.

SymbolChangedEvent provide notice of new ticker names for stocks, or mergers of two tickers into one. It provides the OldSymbol and NewSymbol tickers.

Delisting events provide notice an asset is no longer trading on the exchange.

Ticks is a string indexed dictionary of lists of ticks.

These data types all have dedicated event handlers which follow the pattern above (public void OnData(Type data) {}); and are also passed into the OnData(Slice data) event handler.

All these data types are accessible through their properties on the slice object. i.e.

  • slice.Bars
  • slice.Ticks
  • slice.Splits
  • slice.Dividends
  • slice.Delistings
  • slice.SymbolChangedEvents
//TradeBars collection of TradeBar objects
TradeBars data; TradeBar ibm = data["IBM"];

//Dividends collection of Dividend objects
Dividends data; Dividend ibm = data["IBM"];

You can also see our Tutorials and Videos. You can also get in touch with us via Chat.

Did you find this page Helpful ?