Esta estratégia replica o especialista MetaTrader "2 1000 1 0,7% 0,5 500lev st" inserindo uma negociação no início de cada novo dia de negociação e filtrando a direção com a inclinação do histograma MACD. O sistema foi projetado para velas horárias e depende de parâmetros fixos de gerenciamento de dinheiro convertidos das configurações originais MQL.
Lógica de negociação
A estratégia monitora velas horárias e detecta a primeira vela de cada novo dia.
Ele avalia o histograma MACD nas duas velas concluídas mais recentes do dia anterior.
Se o histograma cair entre essas duas barras, o sistema abre uma posição longa na primeira vela do novo dia.
Se o histograma aumentar, ele abre uma posição curta.
Apenas uma posição pode estar ativa por vez. Os sinais opostos fecham a negociação atual antes de abrir a nova direção.
Gestão de risco
Distância inicial do stop loss: 875 pontos (convertido em preço multiplicando pela etapa de preço do instrumento).
Distância de lucro: 510 pontos.
Distância de parada final: 2.172 pontos. O stop segue o preço mais alto (longo) ou mais baixo (curto) alcançado desde a entrada e substitui o stop inicial quando este se torna mais apertado.
A opção de ponto de equilíbrio original foi desativada e, portanto, omitida aqui.
Parâmetros
Nome
Descrição
Padrão
CandleType
Série de velas utilizadas pela estratégia (de hora em hora por padrão).
Velas de 1 hora
MacdFastPeriod
Período EMA rápido para o MACD.
58
MacdSlowPeriod
Período EMA lento para o MACD.
195
MacdSignalPeriod
Período da linha de sinal para o MACD.
183
StopLossPoints
Distância de stop-loss expressa em pontos do instrumento.
875
TakeProfitPoints
Distância de lucro em pontos.
510
TrailingStopPoints
Distância de parada final em pontos.
2172
Notas
A estratégia usa apenas velas concluídas para evitar antecipação intrabarra, espelhando a opção "Usar valor da barra anterior" do especialista fonte.
As saídas móveis e fixas são tratadas internamente, portanto, as proteções adicionais do portfólio devem permanecer desativadas para evitar o tratamento duplo de stops.
A lógica pressupõe que a corretora usa definições de pontos padrão (etapa de preço). Ajuste os parâmetros se o instrumento usar um tamanho de tick diferente.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Day Opening MACD Histogram strategy: MACD histogram direction.
/// Buys when MACD histogram turns positive, sells when turns negative.
/// </summary>
public class DayOpeningMacdHistogramStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<int> _signalPeriod;
private readonly StrategyParam<int> _signalCooldownCandles;
private decimal _prevHistogram;
private int _candlesSinceTrade;
private bool _hasPrev;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public int SignalPeriod { get => _signalPeriod.Value; set => _signalPeriod.Value = value; }
public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }
public DayOpeningMacdHistogramStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 12)
.SetGreaterThanZero()
.SetDisplay("MACD Fast", "MACD fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 26)
.SetGreaterThanZero()
.SetDisplay("MACD Slow", "MACD slow EMA period", "Indicators");
_signalPeriod = Param(nameof(SignalPeriod), 9)
.SetGreaterThanZero()
.SetDisplay("Signal Period", "MACD signal period", "Indicators");
_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 4)
.SetGreaterThanZero()
.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevHistogram = 0;
_candlesSinceTrade = SignalCooldownCandles;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevHistogram = 0;
_candlesSinceTrade = SignalCooldownCandles;
_hasPrev = false;
var macd = new MovingAverageConvergenceDivergenceSignal
{
Macd = { ShortMa = { Length = FastPeriod }, LongMa = { Length = SlowPeriod } },
SignalMa = { Length = SignalPeriod }
};
var subscription = SubscribeCandles(CandleType);
subscription.BindEx(macd, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue macdValue)
{
if (candle.State != CandleStates.Finished) return;
if (!macdValue.IsFinal) return;
if (_candlesSinceTrade < SignalCooldownCandles)
_candlesSinceTrade++;
if (macdValue is not MovingAverageConvergenceDivergenceSignalValue typed) return;
if (typed.Macd is not decimal macdMain || typed.Signal is not decimal signal) return;
var histogram = macdMain - signal;
if (_hasPrev)
{
if (_prevHistogram <= 0 && histogram > 0 && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
BuyMarket();
_candlesSinceTrade = 0;
}
else if (_prevHistogram >= 0 && histogram < 0 && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
SellMarket();
_candlesSinceTrade = 0;
}
}
_prevHistogram = histogram;
_hasPrev = true;
}
}
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 MovingAverageConvergenceDivergenceSignal
from StockSharp.Algo.Strategies import Strategy
class day_opening_macd_histogram_strategy(Strategy):
def __init__(self):
super(day_opening_macd_histogram_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(60)))
self._fast_period = self.Param("FastPeriod", 12)
self._slow_period = self.Param("SlowPeriod", 26)
self._signal_period = self.Param("SignalPeriod", 9)
self._signal_cooldown_candles = self.Param("SignalCooldownCandles", 4)
self._prev_histogram = 0.0
self._candles_since_trade = 4
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def FastPeriod(self):
return self._fast_period.Value
@FastPeriod.setter
def FastPeriod(self, value):
self._fast_period.Value = value
@property
def SlowPeriod(self):
return self._slow_period.Value
@SlowPeriod.setter
def SlowPeriod(self, value):
self._slow_period.Value = value
@property
def SignalPeriod(self):
return self._signal_period.Value
@SignalPeriod.setter
def SignalPeriod(self, value):
self._signal_period.Value = value
@property
def SignalCooldownCandles(self):
return self._signal_cooldown_candles.Value
@SignalCooldownCandles.setter
def SignalCooldownCandles(self, value):
self._signal_cooldown_candles.Value = value
def OnReseted(self):
super(day_opening_macd_histogram_strategy, self).OnReseted()
self._prev_histogram = 0.0
self._candles_since_trade = self.SignalCooldownCandles
self._has_prev = False
def OnStarted2(self, time):
super(day_opening_macd_histogram_strategy, self).OnStarted2(time)
self._prev_histogram = 0.0
self._candles_since_trade = self.SignalCooldownCandles
self._has_prev = False
macd = MovingAverageConvergenceDivergenceSignal()
macd.Macd.ShortMa.Length = self.FastPeriod
macd.Macd.LongMa.Length = self.SlowPeriod
macd.SignalMa.Length = self.SignalPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.BindEx(macd, self._process_candle).Start()
def _process_candle(self, candle, macd_value):
if candle.State != CandleStates.Finished:
return
if not macd_value.IsFinal:
return
if self._candles_since_trade < self.SignalCooldownCandles:
self._candles_since_trade += 1
if macd_value.Macd is None or macd_value.Signal is None:
return
macd_main = float(macd_value.Macd)
signal = float(macd_value.Signal)
histogram = macd_main - signal
if self._has_prev:
if self._prev_histogram <= 0 and histogram > 0 and self.Position <= 0 and self._candles_since_trade >= self.SignalCooldownCandles:
self.BuyMarket()
self._candles_since_trade = 0
elif self._prev_histogram >= 0 and histogram < 0 and self.Position >= 0 and self._candles_since_trade >= self.SignalCooldownCandles:
self.SellMarket()
self._candles_since_trade = 0
self._prev_histogram = histogram
self._has_prev = True
def CreateClone(self):
return day_opening_macd_histogram_strategy()