1. Home
  2. Docs
  3. Knowledge Base
  4. MT University
  5. Handling Data

Handling Data

An algorithm’s 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 whichever event handler you are using, either the OnData(Slice data)handler or the OnTradeBar(Slice slice) handler. Slice is short for “time slice” – representing a slice of time and values of the data at that time.

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 btcTradeBar = slice.Bars["BTCUSD"].

Time Slices

The Slice event handler combines all of the data 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 OnTradeBar(Slice slice) event handler.

In C# the Slice object gives you three ways to access your data:

  • Dynamic string/symbol indexer, which returns a dynamic object of your type slice["BTCUSD"].
  • Statically typed properties: slice.Bars[].

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

It contains all the data for a given moment in time. TradeBars is a symbol/string indexed dictionary, so you can easily access the data. Ticks (when they become available in the Engine) will be 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["BTCUSD"] will return a TradeBar for BTC/USD.

Since the Slice object is indexed, it is possible to check if the time slice contains specific data. e.g. slice.ContainsKey("BTCUSD") 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# a third way of accessing your data is available. Data can also be piped into dedicated event handlers for each data type. To use data this way, you need to put an event handler in your algorithm that follows the pattern:

				
					public void OnData(TradeBars data) {}

				
			

The Machina Engine automatically detects that the method exists and sends data to it.

				
					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 two primary financial data types that we are concerned with, namely, TradeBar and Tick. All data extends from BaseData, the core data class, which provides Symbol, Time, and Value properties.

TradeBars

TradeBars are individual trades from the exchanges consolidated into price bars. The TradeBar provides Open, High, Low, Close, and Volume properties for a given period of time. TradeBars are supported for all Crypto assets.

tradebar

The following code sample shows three ways of accessing TradeBar values in your algorithm.

  1. Inside the foreach loop that iterates over the list of symbols stored in MTO.Symbols
  2. By accessing the Bars property of the Slice object
  3. By directly subsetting the Slice object using the symbol name
				
					// Assuming you selected Binance exchange and
// instrument BTCUSDT 
// MTO.Symbols = ["BTCUSDT"]
        
public void OnTradeBar(Slice slice)
{
    foreach (Symbol symbol in slice.Symbols)
    {
        var btcOpen = slice[symbol.Value].Open;
        Log($"btcOpen = {btcOpen}");
    }
    // You can access the TradeBar dictionary in 
    // the slice object and then subset by symbol
    // to get the TradeBar for BTCUSDT
    var tradeBars = slice.Bars;
    var btcTradeBar = tradeBars["BTCUSDT"];
    var btcOpen = btcTradeBar.Open;      // Open price
    var btcClose = btcTradeBar.Close;    // Close price
    
    // Or you can access the BTCUSDT TradeBar by 
    // directly subsetting the slice object
    var btcOpen = slice["BTCUSDT"].Open;   // Open price
    var btcClose = slice["BTCUSDT"].Close; // Close price
				
			

Ticks

Tick data provides LastPrice and Quantity properties for a given time. A Trade Tick is a record of a transaction or sale for the security. For Crypto assets, all of the ticks for given second are grouped together in backtesting. In live trading, ticks are streamed directly to your algorithm as soon as they occur. Data with millisecond resolution timestamps (Crypto, Forex, CFD, and Futures) generally only have 1 tick in their list, but when multiple trades occur within a millisecond they may also be grouped together.

				
					public void OnData(Slice data):

     ## Use the [-1] indexer to access to most recent tick that arrived
     Debug($"Last price: {data["BTCUSD"][-1].LastPrice}");
     Debug($"Last price: {data["BTCUSD"][-1].Quantity}");
				
			

Tick data is raw and unfiltered. It may contain bad ticks which skew your trade results. We recommend only using tick data if you understand the risks and are able to perform your own online tick filtering. Ticks which MachinaTrader believes are suspicious are marked with the boolean Suspicious flag.

Was this article helpful to you? Yes No

How can we help?

Close Menu