A estratégia DeMarker mais simples reproduz a lógica do consultor especialista MetaTrader original. Ele rastreia o oscilador DeMarker para detectar quando a dinâmica do preço sai das zonas de sobrecompra ou sobrevenda. Quando o oscilador volta para dentro da faixa neutra, a estratégia abre uma posição na direção da reversão esperada enquanto gerencia o risco por meio de distâncias configuráveis de stop-loss e take-profit.
Lógica principal
Assine as velas do período selecionado e calcule o indicador DeMarker com o período configurado.
Marque o estado do mercado como sobrecompra sempre que o valor anterior do DeMarker estiver acima do limite de sobrecompra e como sobrevenda quando estiver abaixo do limite de sobrevenda.
Gere sinais quando o valor atual do DeMarker cruzar de volta para dentro da área neutra:
Venda quando o oscilador cair abaixo do nível de sobrecompra, depois de anteriormente estar acima dele.
Compre quando o oscilador subir acima do nível de sobrevenda, depois de anteriormente estar abaixo dele.
Coloque apenas uma posição de cada vez. Se Trade On Bar Open estiver ativado, o pedido será adiado até a próxima barra abrir; caso contrário, a posição será inserida imediatamente no fechamento da barra atual.
Aplique ordens stop-loss e take-profit usando o serviço de proteção integrado para imitar as distâncias fixas da versão MQL.
Parâmetros
Volume – tamanho do pedido em lotes/contratos.
Período DeMarker – período do oscilador DeMarker.
Nível de sobrecompra – limite superior do DeMarker que define condições de sobrecompra.
Nível de sobrevenda – limite inferior do DeMarker que define condições de sobrevenda.
Trade On Bar Open – se ativado, as entradas são executadas na próxima barra aberta, e não imediatamente.
Pontos de Stop Loss – distância protetora de stop-loss expressa em pontos de preço.
Take Profit Points – distância alvo de lucro expressa em faixas de preço.
Tipo de vela – tipo de vela (período de tempo) usado para cálculos de indicadores.
Gestão de capital
As ordens stop-loss e take-profit são registradas automaticamente por meio de StartProtection com distâncias convertidas em faixas de preço.
Apenas uma posição pode estar ativa por vez. Novos sinais são ignorados enquanto existe uma posição.
Elementos do gráfico
Velas de preço para a assinatura selecionada.
A curva do indicador DeMarker.
Marcadores de negociações próprios para validação visual de entradas e saídas.
Notas
Utilize instrumentos de liquidez suficientemente elevados para garantir a qualidade da execução do stop-loss e do take-profit.
O sinalizador Trade On Bar Open se aproxima do comportamento original do consultor especialista que aguarda uma nova barra antes de enviar o pedido.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Simplest DeMarker strategy: DeMarker oscillator crossover.
/// Buys when DeMarker crosses above oversold, sells when crosses below overbought.
/// </summary>
public class SimplestDeMarkerStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _demarkerPeriod;
private readonly StrategyParam<decimal> _oversold;
private readonly StrategyParam<decimal> _overbought;
private readonly StrategyParam<int> _signalCooldownCandles;
private decimal _prevValue;
private int _candlesSinceTrade;
private bool _hasPrev;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int DemarkerPeriod { get => _demarkerPeriod.Value; set => _demarkerPeriod.Value = value; }
public decimal Oversold { get => _oversold.Value; set => _oversold.Value = value; }
public decimal Overbought { get => _overbought.Value; set => _overbought.Value = value; }
public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }
public SimplestDeMarkerStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_demarkerPeriod = Param(nameof(DemarkerPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("DeMarker Period", "DeMarker period", "Indicators");
_oversold = Param(nameof(Oversold), 0.2m)
.SetDisplay("Oversold", "DeMarker oversold level", "Signals");
_overbought = Param(nameof(Overbought), 0.8m)
.SetDisplay("Overbought", "DeMarker overbought level", "Signals");
_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 4)
.SetGreaterThanZero()
.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevValue = 0;
_candlesSinceTrade = SignalCooldownCandles;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevValue = 0;
_candlesSinceTrade = SignalCooldownCandles;
_hasPrev = false;
var demarker = new DeMarker { Length = DemarkerPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(demarker, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal demarkerValue)
{
if (candle.State != CandleStates.Finished) return;
if (_candlesSinceTrade < SignalCooldownCandles)
_candlesSinceTrade++;
if (_hasPrev)
{
if (_prevValue < Oversold && demarkerValue >= Oversold && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
BuyMarket();
_candlesSinceTrade = 0;
}
else if (_prevValue > Overbought && demarkerValue <= Overbought && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
SellMarket();
_candlesSinceTrade = 0;
}
}
_prevValue = demarkerValue;
_hasPrev = true;
}
}