A Estratégia de Coletor de Dados Espalhados é uma porta StockSharp do utilitário MetaTrader 5 "Coletor de dados espalhados" (MQL entrada 33314). O consultor especialista original não faz pedidos; em vez disso, ele escuta o fluxo de compra/venda e conta quantos ticks estão dentro de intervalos de spread predefinidos. Sempre que o ano comercial muda ou o especialista para, ele imprime um resumo estatístico. Esta versão C# reproduz o mesmo comportamento usando o SubscribeLevel1() API de alto nível e expõe os limites do intervalo como parâmetros configuráveis.
Detalhes da operação
A estratégia assina atualizações de nível 1 (bid/ask) do Security principal quando é iniciada.
Cada vez que os preços de compra e venda estão disponíveis, a estratégia calcula o spread e o converte em unidades de preço multiplicando os limites de pontos configurados por Security.PriceStep.
Seis contadores são mantidos:
Spread estritamente abaixo do primeiro limite.
Espalhe entre o primeiro e o segundo limites.
Espalhe entre o segundo e o terceiro limites.
Espalhe entre o terceiro e o quarto limites.
Espalhe entre o quarto e o quinto limiares.
Spread acima do quinto limite.
As transições de ano são detectadas a partir do carimbo de data/hora da troca (Level1ChangeMessage.ServerTime). Quando o ano muda, a estratégia imprime o resumo do ano finalizado e zera os contadores.
Quando a estratégia para, ela imprime as estatísticas do ano em curso antes de encerrar.
A porta mantém a natureza apenas de registro do utilitário MQL, permitindo que os traders analisem como os spreads se comportaram durante diferentes períodos sem enviar ordens ou manipular posições.
Parâmetros
Todas as entradas são expressas em pontos (terminologia MetaTrader). A distância do preço real é calculada como points × Security.PriceStep.
Parâmetro
Padrão
Descrição
FirstBucketPoints
10
Limite superior do primeiro balde de distribuição. Os spreads estritamente abaixo deste limite são contabilizados na primeira categoria.
SecondBucketPoints
20
Limite superior do segundo balde de distribuição. Os spreads em [FirstBucketPoints, SecondBucketPoints) são contados aqui.
ThirdBucketPoints
30
Limite superior do terceiro balde de distribuição. Spreads em [SecondBucketPoints, ThirdBucketPoints) aumentam este contador.
FourthBucketPoints
40
Limite superior do quarto balde de spread. Os spreads em [ThirdBucketPoints, FourthBucketPoints) são registrados aqui.
FifthBucketPoints
50
Limite superior do quinto balde de spread. Spreads em [FourthBucketPoints, FifthBucketPoints) aumentam este contador.
Todos os limites devem ser estritamente crescentes. A tentativa de iniciar a estratégia com valores Security.PriceStep inválidos ou não positivos resulta em uma exceção de tempo de execução, que protege o usuário de estatísticas inconsistentes.
Registros e saídas
As estatísticas são impressas por meio de AddInfoLog no seguinte formato:
Esta saída reflete as declarações Print do especialista MetaTrader, facilitando a comparação dos dois ambientes. Use o visualizador de registros StockSharp ou redirecione os registros para um arquivo para análise adicional.
Lista de verificação de uso
Atribua o instrumento alvo a Strategy.Security e certifique-se de que seu PriceStep corresponda ao tamanho de ponto MetaTrader (para a maioria dos símbolos Forex isso é igual a 0,0001).
Ajuste os limites do intervalo se precisar de intervalos de spread diferentes. Mantenha os valores estritamente crescentes.
Inicie a estratégia e deixe-a funcionar. Nenhum pedido será enviado.
Revise os logs anuais para entender o comportamento de propagação entre as sessões.
A estratégia é intencionalmente leve e segura para ser executada em conjunto com sistemas de negociação ao vivo. Ele ajuda as mesas a construir distribuições históricas de spreads, validar suposições de liquidez e monitorar as condições das corretoras durante longos períodos.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Spread Data Collector strategy: RSI mean reversion.
/// Buys when RSI crosses below oversold, sells when RSI crosses above overbought.
/// </summary>
public class SpreadDataCollectorStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _oversold;
private readonly StrategyParam<decimal> _overbought;
private decimal _prevRsi;
private bool _hasPrev;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public decimal Oversold { get => _oversold.Value; set => _oversold.Value = value; }
public decimal Overbought { get => _overbought.Value; set => _overbought.Value = value; }
public SpreadDataCollectorStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period", "Indicators");
_oversold = Param(nameof(Oversold), 30m)
.SetDisplay("Oversold", "RSI oversold level", "Levels");
_overbought = Param(nameof(Overbought), 70m)
.SetDisplay("Overbought", "RSI overbought level", "Levels");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevRsi = 0;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(rsi, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal rsiValue)
{
if (candle.State != CandleStates.Finished) return;
if (_hasPrev)
{
if (_prevRsi >= Oversold && rsiValue < Oversold && Position <= 0)
BuyMarket();
else if (_prevRsi <= Overbought && rsiValue > Overbought && Position >= 0)
SellMarket();
}
_prevRsi = rsiValue;
_hasPrev = true;
}
}