Market data
The market data of an instrument reaches an extension through a few shared types: a MarketDataArg for a trade or a changed level of the order book, the InstrumentInfo of the instrument (the tick size, the name, the exchange) and the market depth. This article shows them on a chart indicator; the chart-specific data (candles, footprint, cumulative trades, MBO) is described in the chart indicator articles.
Trades
OnNewTrade(arg) receives every trade: the price, the volume,
the time and the direction (TradeDirection: Buy or Sell). It is called on
the data-feed thread, so
keep the work small and never write to the data series from there, see
Performance.
Market depth
MarketDepthChanged(arg) is called for every changed
level of the order book: the side (IsBid, IsAsk), the price and the new volume of the level, 0 when the level is
gone.
using ATAS.Indicators;
namespace ATAS.Docs.Samples.CommonApi;
public class MarketDepthChangedIndicator : Indicator
{
private decimal _lastChangedBidPrice;
private decimal _lastChangedBidVolume;
protected override void OnCalculate(int bar, decimal value)
{
}
protected override void MarketDepthChanged(MarketDataArg arg)
{
// Called on the data-feed thread for every changed level of the order book:
// the side (IsBid / IsAsk), the price and the new volume of the level (0 when the level is gone)
if (arg.IsBid)
{
_lastChangedBidPrice = arg.Price;
_lastChangedBidVolume = arg.Volume;
}
}
}
MarketDepthInfo gives the current state of the book: the total volumes of all bids and all asks, CumulativeDomBids and CumulativeDomAsks, and a snapshot of all levels from GetMarketDepthSnapshot(). The indicator below records the history of the total bid and ask volumes:
using System.Windows.Media;
using ATAS.Indicators;
namespace ATAS.Docs.Samples.CommonApi;
public class DomPowerIndicator : Indicator
{
private readonly ValueDataSeries _asks;
private readonly ValueDataSeries _bids = new("Bids");
private int _lastCalculatedBar;
private bool _first = true;
public DomPowerIndicator() : base(true)
{
Panel = IndicatorDataProvider.NewPanel;
_asks = (ValueDataSeries)DataSeries[0];
_asks.Name = "Asks";
_bids.Color = Colors.Green;
DataSeries.Add(_bids);
}
protected override void OnCalculate(int bar, decimal value)
{
}
protected override void MarketDepthChanged(MarketDataArg arg)
{
if (_first)
{
_first = false;
_lastCalculatedBar = CurrentBar - 1;
}
var depth = MarketDepthInfo;
if (depth == null)
return;
var lastCandle = CurrentBar - 1;
var cumAsks = depth.CumulativeDomAsks;
var cumBids = depth.CumulativeDomBids;
for (var i = _lastCalculatedBar; i <= lastCandle; i++)
{
_asks[i] = -cumAsks;
_bids[i] = cumBids;
}
_lastCalculatedBar = lastCandle;
}
}