Table of Contents

Ticks and cumulative trades

Every tick

Override OnNewTrade(arg) to receive every trade of the chart instrument as it arrives. The MarketDataArg carries the price, the volume, the time and the direction. The method is called on the data-feed thread (see Performance).

using ATAS.Indicators;

namespace ATAS.Docs.Samples.ChartIndicators.MarketData;

public class NewTradeIndicator : Indicator
{
    private decimal _lastTradeVolume;

    protected override void OnCalculate(int bar, decimal value)
    {
    }

    protected override void OnNewTrade(MarketDataArg arg)
    {
        // Called on the data-feed thread for every trade of the chart instrument
        _lastTradeVolume = arg.Volume;
    }
}

Cumulative trades

A cumulative trade is a series of ticks produced by one market order. The platform calls OnCumulativeTrade(trade) when a new one appears and OnUpdateCumulativeTrade(trade) while it grows. To tell whether an update belongs to the trade you saw before, compare the trades with the IsEqual extension method (class ATAS.Indicators.Extensions, it compares the time, the direction and the first price), not by reference. The example sums the delta of the cumulative trades of 3 lots and more on the last bar:

using ATAS.Indicators;

namespace ATAS.Docs.Samples.ChartIndicators.MarketData;

public class CumulativeTradesDeltaIndicator : Indicator
{
    private CumulativeTrade? _lastTrade;
    private decimal _lastCumulativeTradeVolume;

    protected override void OnCalculate(int bar, decimal value)
    {
    }

    protected override void OnCumulativeTrade(CumulativeTrade trade)
    {
        AddCumulativeTrade(trade);
    }

    protected override void OnUpdateCumulativeTrade(CumulativeTrade trade)
    {
        AddCumulativeTrade(trade);
    }

    private void AddCumulativeTrade(CumulativeTrade trade)
    {
        if (trade.Volume < 3)
            return;

        // An update of the same cumulative trade has the same Time, Direction and FirstPrice
        if (_lastTrade == null || !_lastTrade.IsEqual(trade))
        {
            _lastTrade = trade;
            this[CurrentBar - 1] += GetVolumeByDirection(trade.Volume, trade.Direction);
        }
        else
        {
            this[CurrentBar - 1] += GetVolumeByDirection(trade.Volume - _lastCumulativeTradeVolume, trade.Direction);
        }

        _lastCumulativeTradeVolume = trade.Volume;
    }

    private static decimal GetVolumeByDirection(decimal volume, TradeDirection direction)
    {
        return volume * (direction == TradeDirection.Buy ? 1 : -1);
    }
}

Historical cumulative trades

Call RequestForCumulativeTrades with a CumulativeTradesRequest (the start and the end of the period, the minimum and the maximum volume; 0 for both volumes means no filter) and override OnCumulativeTradesResponse to receive the trades. Rules:

  • the requested period must not exceed 7 days;
  • only one request at a time: a second call before the response has arrived throws an exception;
  • when the indicator is hidden and its alerts are disabled, the request is postponed until the indicator is shown.

OnFinishRecalculate is called after every recalculation, so a request sent from it needs a guard against repeating. The example requests the trades of the loaded bars once, limited to the last 7 days:

using System;
using System.Collections.Generic;
using System.Linq;

using ATAS.Indicators;

namespace ATAS.Docs.Samples.ChartIndicators.MarketData;

public class HistoricalCumulativeTradesIndicator : Indicator
{
    private List<CumulativeTrade> _trades = new();
    private CumulativeTradesRequest? _request;

    protected override void OnCalculate(int bar, decimal value)
    {
    }

    protected override void OnFinishRecalculate()
    {
        // OnFinishRecalculate is called after every recalculation: send the request only once
        if (_request != null || CurrentBar <= 0)
            return;

        var lastTime = GetCandle(CurrentBar - 1).LastTime;
        var startTime = GetCandle(0).Time;

        // The requested period must not exceed 7 days
        if (lastTime - startTime > TimeSpan.FromDays(7))
            startTime = lastTime.AddDays(-7);

        _request = new CumulativeTradesRequest(startTime, lastTime, 0, 0);
        RequestForCumulativeTrades(_request);
    }

    protected override void OnCumulativeTradesResponse(CumulativeTradesRequest request, IEnumerable<CumulativeTrade> cumulativeTrades)
    {
        if (request != _request)
            return;

        _trades = cumulativeTrades.ToList();
    }
}