A Estratégia de Reversão de Gap é uma porta direta do MetaTrader 4 consultor especialista gaps.mq4. O sistema monitora velas e loo de 15 minutos
ks para abertura de gaps que ocorrem fora da faixa máxima/baixa da vela anterior. Quando tal lacuna aparece, a estratégia imediatamente muda.
entra no mercado na direção do movimento de reversão à média esperado.
A versão StockSharp segue a lógica original enquanto depende da assinatura de vela de alto nível API. Toda a gestão comercial é
feito com ordens de mercado e nenhuma ordem de proteção fixa é colocada, refletindo o comportamento encontrado no código MQL.
Regras de negociação
Assine velas de 15 minutos (configuráveis através do parâmetro CandleType).
Mantenha os valores máximos e mínimos da vela concluída anterior.
Quando uma nova vela começa:
Calcule o buffer de lacuna: (MinGapSize + spreadInSteps) * pointValue.
Se o preço de abertura estiver acimapreviousHigh + gapBuffer, abra uma posição curta.
Se o preço de abertura estiver abaixo de previousLow - gapBuffer, abra uma posição longa.
Apenas uma negociação por vela é permitida. Uma vez colocada uma ordem, a estratégia espera pela próxima vela antes de gerar uma nova.
sinal.
O componente de spread usa o melhor lance/venda atual, se disponível. Quando nenhum dado de cotação é fornecido, a estratégia cai em pecado
passo de preço como um buffer conservador.
Parâmetros
Parâmetro
Padrão
Descrição
MinGapSize
1
Tamanho mínimo do intervalo nas etapas de preço que deve ser excedido antes de enviar um pedido.
GapVolume
0.1
Volume de pedidos para entradas no mercado desencadeadas por lacunas.
CandleType
15m TimeFrame
Tipo de vela usado para cálculos (o padrão é velas de 15 minutos).
Todos os parâmetros são registrados como StrategyParam<T> e suportam otimização dentro do StockSharp Designer ou outras ferramentas.
Notas de implementação
Usa SubscribeCandles com Bind para processar apenas velas concluídas.
Lembra o intervalo da vela anterior para evitar o recálculo da série de dados.
Bloqueia pedidos duplicados na mesma vela rastreando o tempo de abertura da barra que acionou a negociação.
A saída do gráfico desenha as velas subscritas e as negociações estratégicas para uma rápida inspeção visual.
Diferenças da versão MQL
Os níveis de take-profit e stop-loss não foram definidos corretamente no EA original (o código MQL passou valores para os parâmetros errados)
. A porta StockSharp, portanto, mantém o comportamento de execução sem ordens de proteção.
O gerenciamento de spread agora verifica cotações de compra/venda em tempo real quando disponíveis, fornecendo um buffer mais adaptável.
Requisitos
StockSharp API com acesso aos dados da vela para o instrumento selecionado.
As cotações de nível 1 são opcionais, mas melhoram a detecção de spread.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Gap Reversion strategy - detects gap openings and trades mean reversion.
/// Buys when candle opens below previous low (gap down reversion).
/// Sells when candle opens above previous high (gap up reversion).
/// Uses EMA as trend filter for exits.
/// </summary>
public class GapReversionStrategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevHigh;
private decimal _prevLow;
private bool _hasPrev;
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public GapReversionStrategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 20)
.SetDisplay("EMA Period", "EMA trend filter", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
protected override void OnReseted() { base.OnReseted(); _prevHigh = 0m; _prevLow = 0m; _hasPrev = false; }
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema, ProcessCandle)
.Start();
StartProtection(
takeProfit: new Unit(2, UnitTypes.Percent),
stopLoss: new Unit(1, UnitTypes.Percent)
);
}
private void ProcessCandle(ICandleMessage candle, decimal ema)
{
if (candle.State != CandleStates.Finished)
return;
if (!_hasPrev)
{
_prevHigh = candle.HighPrice;
_prevLow = candle.LowPrice;
_hasPrev = true;
return;
}
var open = candle.OpenPrice;
var close = candle.ClosePrice;
// Gap down reversion - open below previous low, expect bounce
if (open < _prevLow && close > ema && Position == 0)
BuyMarket();
// Gap up reversion - open above previous high, expect pullback
else if (open > _prevHigh && close < ema && Position == 0)
SellMarket();
_prevHigh = candle.HighPrice;
_prevLow = candle.LowPrice;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
from StockSharp.Messages import Unit, UnitTypes
class gap_reversion_strategy(Strategy):
def __init__(self):
super(gap_reversion_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 20).SetDisplay("EMA Period", "EMA trend filter", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_high = 0.0
self._prev_low = 0.0
self._has_prev = False
@property
def ema_period(self): return self._ema_period.Value
@property
def candle_type(self): return self._candle_type.Value
def OnReseted(self):
super(gap_reversion_strategy, self).OnReseted()
self._prev_high = 0.0
self._prev_low = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(gap_reversion_strategy, self).OnStarted2(time)
self._has_prev = False
ema = ExponentialMovingAverage()
ema.Length = self.ema_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ema, self.process_candle).Start()
self.StartProtection(takeProfit=Unit(2, UnitTypes.Percent), stopLoss=Unit(1, UnitTypes.Percent))
def process_candle(self, candle, ema):
if candle.State != CandleStates.Finished:
return
if not self._has_prev:
self._prev_high = float(candle.HighPrice)
self._prev_low = float(candle.LowPrice)
self._has_prev = True
return
op = float(candle.OpenPrice)
close = float(candle.ClosePrice)
ema_val = float(ema)
if op < self._prev_low and close > ema_val and self.Position == 0:
self.BuyMarket()
elif op > self._prev_high and close < ema_val and self.Position == 0:
self.SellMarket()
self._prev_high = float(candle.HighPrice)
self._prev_low = float(candle.LowPrice)
def CreateClone(self):
return gap_reversion_strategy()