Esta estratégia é uma versão StockSharp do consultor especialista MetaTrader 20/200 expert v4.2 (AntS). Ele aguarda uma hora específica do dia de negociação e depois compara dois preços históricos de abertura por hora (6 e 2 barras na configuração padrão). Se a abertura distante for superior à abertura mais próxima em mais de Short Delta pips, a estratégia vende, enquanto o gap reverso que excede Long Delta pips abre uma posição longa.
Lógica de negociação
A estratégia assina velas horárias (configuráveis através de Candle Type).
Apenas uma negociação por dia é permitida. Os pedidos são feitos quando uma vela com hora igual a Trade Hour se torna ativa.
Os sinais usam o preço de abertura LookbackFar e LookbackNear barras atrás da vela atual.
Configuração curta:Open[t1] - Open[t2] > Short Delta × pip.
Configuração longa:Open[t2] - Open[t1] > Long Delta × pip.
Uma ordem de mercado é enviada com o volume calculado. As distâncias de stop-loss e take-profit são retiradas da versão MetaTrader e expressas em pips, convertidas automaticamente em preços via Security.PriceStep.
Apenas uma posição pode existir por vez. A negociação diária é retomada no próximo dia corrido.
Gestão de posição
Stop-loss e take-profit são avaliados em cada atualização da vela usando os extremos máximo/mínimo da vela.
Max Open Hours força uma saída do mercado quando o tempo de vida da posição excede o número configurado de horas (504 horas por padrão). Defina o parâmetro como zero para desativar o temporizador de segurança.
Gestão de dinheiro
Fixed Volume define o tamanho do contrato substituto usado quando Use Auto Lot está desativado ou as informações de saldo não estão disponíveis.
Quando Use Auto Lot está ativado, o tamanho do lote segue a enorme tabela de etapas do consultor especialista. Em StockSharp a tabela é aproximada por volume = round(balance × Auto Lot Factor, 2) com o fator padrão 0.000038, reproduzindo os valores MT4 dentro de um pip de volume em toda a faixa documentada (300 USD a 270.000 USD+).
Se o valor atual do portfólio cair abaixo do último saldo registrado, a próxima negociação será multiplicada por Big Lot Multiplier, imitando a negociação de recuperação "Big Lot" no código original.
Os volumes são alinhados a Security.VolumeStep e limitados entre MinVolume/MaxVolume quando disponíveis.
Diferenças versus MetaTrader EA
O script MT4 armazenou mais de mil linhas de limite manual. A versão StockSharp usa um coeficiente linear (Auto Lot Factor) que se ajusta à mesma escada. Ajuste o fator se precisar de uma réplica exata para um corretor diferente.
As ordens stop-loss/take-profit são simuladas através de saídas de mercado nos extremos das velas. Isso mantém o comportamento consistente em backtests e negociações ao vivo, sem depender do suporte de ordens stop do lado da bolsa.
Variáveis globais (globalBalans, globalPosic) são substituídas pelo estado na memória. Nenhum sistema de arquivos ou estado de terminal é necessário.
Parâmetros
Parâmetro
Descrição
Lucro Longo/Curto
Distância em pips para metas de lucro.
Stop Loss Longo/Curto
Distância em pips para stop loss.
Horário comercial
Hora da sessão (0–23) em que os sinais podem ser acionados.
Lookback distante/perto
Quantas barras voltam para inspecionar os dois preços de abertura.
Delta longo/curto
Gap de pip necessário para abrir uma posição.
Horário máximo de abertura
Vida útil máxima da posição em horas (0 desativa a proteção).
Volume Fixo
Volume de contrato de linha de base quando o dimensionamento automático está desabilitado.
Usar lote automático
Habilite o dimensionamento do lote a partir do valor da conta.
Fator de lote automático
Multiplicador aplicado ao valor do portfólio para emular a tabela de passos MT4.
Multiplicador de lote grande
Multiplicador de volume aplicado após uma queda no patrimônio.
Tipo de vela
Período usado para as velas de sinalização.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class Twenty200TimeBreakoutStrategy : Strategy
{
private readonly StrategyParam<int> _shortPeriod;
private readonly StrategyParam<int> _longPeriod;
private readonly StrategyParam<int> _cooldownCandles;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevShort;
private decimal _prevLong;
private bool _hasPrev;
private int _cooldownRemaining;
public int ShortPeriod { get => _shortPeriod.Value; set => _shortPeriod.Value = value; }
public int LongPeriod { get => _longPeriod.Value; set => _longPeriod.Value = value; }
public int CooldownCandles { get => _cooldownCandles.Value; set => _cooldownCandles.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Twenty200TimeBreakoutStrategy()
{
_shortPeriod = Param(nameof(ShortPeriod), 20).SetDisplay("Short SMA", "Short SMA period", "Indicators");
_longPeriod = Param(nameof(LongPeriod), 200).SetDisplay("Long SMA", "Long SMA period", "Indicators");
_cooldownCandles = Param(nameof(CooldownCandles), 100).SetDisplay("Cooldown", "Candles between signals", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevShort = default;
_prevLong = default;
_hasPrev = default;
_cooldownRemaining = default;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevShort = 0;
_prevLong = 0;
_hasPrev = false;
_cooldownRemaining = 0;
var shortSma = new SimpleMovingAverage { Length = ShortPeriod };
var longSma = new SimpleMovingAverage { Length = LongPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(shortSma, longSma, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal shortSma, decimal longSma)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev) { _prevShort = shortSma; _prevLong = longSma; _hasPrev = true; return; }
if (_cooldownRemaining > 0)
{
_cooldownRemaining--;
_prevShort = shortSma;
_prevLong = longSma;
return;
}
if (_prevShort <= _prevLong && shortSma > longSma && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
_cooldownRemaining = CooldownCandles;
}
else if (_prevShort >= _prevLong && shortSma < longSma && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
_cooldownRemaining = CooldownCandles;
}
_prevShort = shortSma;
_prevLong = longSma;
}
}