Subscrições de Alto Nível

Visão Geral

A classe Strategy fornece um conjunto de métodos de alto nível para subscrição de dados de mercado: SubscribeCandles, SubscribeTicks, SubscribeLevel1 e SubscribeOrderBook. Estes métodos devolvem um objeto ISubscriptionHandler<T> que permite associar manipuladores de dados e indicadores num estilo fluente conveniente.

Ao contrário da criação manual de um objeto Subscription e da chamada a Subscribe(), os métodos de alto nível:

  • Criam automaticamente uma subscrição com os parâmetros corretos
  • Fornecem um ISubscriptionHandler<T> tipado para associar manipuladores
  • Integram-se com o sistema de indicadores através dos métodos Bind
  • Suportam renderização automática no gráfico
  • Gerem corretamente o ciclo de vida da subscrição

Métodos de Subscrição

SubscribeCandles

Subscreve candles. Aceita um período ou DataType:

// Subscrever por período
ISubscriptionHandler<ICandleMessage> SubscribeCandles(
    TimeSpan tf,
    bool isFinishedOnly = true,
    Security security = default);

// Subscrever por DataType (suporta todos os tipos de candles)
ISubscriptionHandler<ICandleMessage> SubscribeCandles(
    DataType dt,
    bool isFinishedOnly = true,
    Security security = default);

// Assinar usando um objeto Subscription pronto
ISubscriptionHandler<ICandleMessage> SubscribeCandles(Subscription subscription);

O parâmetro isFinishedOnly é true por defeito -- o manipulador recebe apenas candles concluídas.

SubscribeTicks

Subscreve negócios tick:

ISubscriptionHandler<ITickTradeMessage> SubscribeTicks(Security security = null);
ISubscriptionHandler<ITickTradeMessage> SubscribeTicks(Subscription subscription);

SubscribeLevel1

Subscreve dados Level1 (melhores preços bid/ask, último negócio e outros campos):

ISubscriptionHandler<Level1ChangeMessage> SubscribeLevel1(Security security = null);
ISubscriptionHandler<Level1ChangeMessage> SubscribeLevel1(Subscription subscription);

SubscribeOrderBook

Subscreve o livro de ordens:

ISubscriptionHandler<IOrderBookMessage> SubscribeOrderBook(Security security = null);
ISubscriptionHandler<IOrderBookMessage> SubscribeOrderBook(Subscription subscription);

Se o parâmetro security não for especificado, é usado o Security da estratégia.

Interface ISubscriptionHandler

O objeto ISubscriptionHandler<T> fornece os seguintes métodos:

Start / Stop

Iniciar e parar a subscrição:

handler.Start();   // calls Subscribe
handler.Stop();    // calls UnSubscribe

Bind (sem indicadores)

Associar um manipulador de dados simples:

handler.Bind(Action<T> callback);

Bind (com indicadores)

Associar um manipulador com um ou mais indicadores. O indicador processa automaticamente os dados recebidos e o manipulador recebe o valor já calculado:

// Um indicador -- valor decimal
handler.Bind(IIndicator indicator, Action<T, decimal> callback);

// Dois indicadores
handler.Bind(IIndicator ind1, IIndicator ind2, Action<T, decimal, decimal> callback);

// Até oito indicadores
handler.Bind(ind1, ind2, ind3, ..., callback);

// Array de indicadores
handler.Bind(IIndicator[] indicators, Action<T, decimal[]> callback);

O manipulador com Bind é chamado apenas quando todos os indicadores devolveram um valor não vazio.

BindWithEmpty

Semelhante a Bind, mas o manipulador é chamado mesmo se o indicador devolver um valor vazio. Os valores são representados como decimal?:

handler.BindWithEmpty(IIndicator indicator, Action<T, decimal?> callback);

BindEx

Fornece acesso ao objeto IIndicatorValue completo em vez do decimal extraído:

handler.BindEx(IIndicator indicator, Action<T, IIndicatorValue> callback, bool allowEmpty = false);

Exemplo: Estratégia com Indicadores

public class SmaStrategy : Strategy
{
    private readonly StrategyParam<int> _shortPeriod;
    private readonly StrategyParam<int> _longPeriod;
    private readonly StrategyParam<DataType> _candleType;

    public int ShortPeriod
    {
        get => _shortPeriod.Value;
        set => _shortPeriod.Value = value;
    }

    public int LongPeriod
    {
        get => _longPeriod.Value;
        set => _longPeriod.Value = value;
    }

    public DataType CandleType
    {
        get => _candleType.Value;
        set => _candleType.Value = value;
    }

    public SmaStrategy()
    {
        _shortPeriod = Param(nameof(ShortPeriod), 10);
        _longPeriod = Param(nameof(LongPeriod), 20);
        _candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame());
    }

    protected override void OnStarted2(DateTime time)
    {
        base.OnStarted2(time);

        var shortSma = new SimpleMovingAverage { Length = ShortPeriod };
        var longSma = new SimpleMovingAverage { Length = LongPeriod };

        var subscription = SubscribeCandles(CandleType);

        // Vinculação de dois indicadores -- o manipulador é chamado
        // quando ambos os indicadores estiverem formados
        subscription
            .Bind(shortSma, longSma, (candle, shortValue, longValue) =>
            {
                if (!IsFormedAndOnlineAndAllowTrading())
                    return;

                if (shortValue > longValue && Position <= 0)
                    BuyMarket(Volume + Math.Abs(Position));
                else if (shortValue < longValue && Position >= 0)
                    SellMarket(Volume + Math.Abs(Position));
            })
            .Start();

        // Chart setup
        var area = CreateChartArea();
        if (area != null)
        {
            DrawCandles(area, subscription);
            DrawIndicator(area, shortSma);
            DrawIndicator(area, longSma);
            DrawOwnTrades(area);
        }
    }
}

Exemplo: Subscrição de Ticks

protected override void OnStarted2(DateTime time)
{
    base.OnStarted2(time);

    SubscribeTicks()
        .Bind(tick =>
        {
            if (!IsFormedAndOnlineAndAllowTrading())
                return;

            this.AddInfoLog("Tick: preço={0}, volume={1}", tick.Price, tick.Volume);
        })
        .Start();
}

Exemplo: Subscrição do Livro de Ordens

protected override void OnStarted2(DateTime time)
{
    base.OnStarted2(time);

    SubscribeOrderBook()
        .Bind(book =>
        {
            var bestBid = book.GetBestBid();
            var bestAsk = book.GetBestAsk();

            if (bestBid != null && bestAsk != null)
            {
                var spread = bestAsk.Price - bestBid.Price;
                this.AddInfoLog("Spread: {0}", spread);
            }
        })
        .Start();
}

Diferenças em Relação à Criação Manual de Subscrições

Aspeto Subscrição manual Método de alto nível
Criação new Subscription(DataType, Security) SubscribeCandles(tf)
Tratamento de dados Subscrição de eventos do conector Bind(callback)
Indicadores Chamada manual a indicator.Process() Automaticamente através de Bind(indicator, callback)
Registo de indicadores Adição manual a Indicators Automaticamente ao usar Bind
Renderização no gráfico Integração manual com IChart DrawCandles, DrawIndicator

Os métodos de alto nível são recomendados para utilização na maioria das estratégias, pois reduzem significativamente a quantidade de código e diminuem a probabilidade de erros.