Coleta estatísticas detalhadas para o spread de compra e venda do instrumento selecionado e notifica quando o spread ultrapassa um limite configurável. A estratégia escuta continuamente as atualizações do Nível 1, rastreia o spread máximo, mínimo e médio em pontos e registra um resumo quando para. É útil para pesquisar as condições de liquidez antes de executar sistemas sensíveis à latência ou otimizar janelas de negociação no Testador de Estratégia.
Detalhes
Fonte de dados: melhor lance de nível 1 e melhores cotações de venda.
Estatísticas capturadas:
Carimbos de data e hora de início e término do período de observação.
Spread máximo e o momento em que ocorreu.
Spread mínimo e o momento em que ocorreu.
Spread médio calculado em todas as amostras de Nível 1 observadas.
Alertas:
Alerta opcional quando o spread (em pontos) ultrapassa o limite MaxSpreadPoints configurado.
A frequência de alerta é limitada por AlertIntervalSeconds para evitar spam no log.
Os alertas só são acionados quando o spread ultrapassa o limite por baixo.
Registro:
Alertas em tempo real são gravados por meio de LogInfo.
O resumo final das estatísticas é emitido durante OnStopped.
Valores padrão:
MaxSpreadPoints = 0 (alertas desabilitados).
AlertIntervalSeconds = 0 (sem limitação).
Parâmetros
Nome
Descrição
Padrão
Notas
MaxSpreadPoints
Spread máximo permitido em pontos. Defina como 0 para desativar alertas.
0
Os pontos são calculados usando a etapa de preço do instrumento.
AlertIntervalSeconds
Tempo mínimo entre alertas consecutivos.
0
Evita alertas duplicados quando a propagação permanece ampla.
Notas de uso
Anexe a estratégia a um instrumento e garanta que os dados do Nível 1 estejam disponíveis.
Configure MaxSpreadPoints de acordo com o spread aceitável para o instrumento.
Opcionalmente, aumente AlertIntervalSeconds para suprimir notificações repetidas durante períodos voláteis.
Pare a estratégia para revisar as estatísticas registradas na saída do terminal.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Spread Informer strategy: CCI momentum crossover.
/// Buys when CCI crosses above zero, sells when crosses below zero.
/// </summary>
public class SpreadInformerStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _cciPeriod;
private readonly StrategyParam<decimal> _cciLevel;
private readonly StrategyParam<int> _signalCooldownCandles;
private decimal _prevCci;
private int _candlesSinceTrade;
private bool _hasPrev;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
public decimal CciLevel { get => _cciLevel.Value; set => _cciLevel.Value = value; }
public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }
public SpreadInformerStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_cciPeriod = Param(nameof(CciPeriod), 30)
.SetGreaterThanZero()
.SetDisplay("CCI Period", "CCI period", "Indicators");
_cciLevel = Param(nameof(CciLevel), 100m)
.SetDisplay("CCI Level", "CCI threshold for crossover", "Signals");
_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 4)
.SetGreaterThanZero()
.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevCci = 0;
_candlesSinceTrade = SignalCooldownCandles;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevCci = 0;
_candlesSinceTrade = SignalCooldownCandles;
_hasPrev = false;
var cci = new CommodityChannelIndex { Length = CciPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(cci, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal cciValue)
{
if (candle.State != CandleStates.Finished) return;
if (_candlesSinceTrade < SignalCooldownCandles)
_candlesSinceTrade++;
if (_hasPrev)
{
if (_prevCci < -CciLevel && cciValue >= -CciLevel && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
BuyMarket();
_candlesSinceTrade = 0;
}
else if (_prevCci > CciLevel && cciValue <= CciLevel && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
SellMarket();
_candlesSinceTrade = 0;
}
}
_prevCci = cciValue;
_hasPrev = true;
}
}