Convertido do MetaTrader 4 consultor especialista MQL/7637/3_lccfpgubwykd__www_forex-instruments_info.mq4.
Usa um fluxo de trabalho de três períodos de tempo: velas horárias acionam ambos os filtros MACD, velas de 15 minutos fornecem osciladores Stochastic e velas de 1 minuto confirmam quebras de preços e gerenciam saídas finais.
Implementa uma estratégia StockSharp de alto nível usando SubscribeCandles(...).Bind(...) / BindEx(...) sem pesquisa manual de dados.
As posições são abertas com ordens de mercado e gerenciadas inteiramente dentro da estratégia (não foram necessárias alterações externas no equipamento de teste).
Indicadores e Parâmetros
Nome
Tipo
Padrão
Descrição
LongStopLoss
decimal
17
Distância inicial de parada para negociações longas, expressa em pontos de instrumento.
ShortStopLoss
decimal
40
Distância inicial de parada para negociações curtas (pontos).
LongTrailingStop
decimal
88
Distância final para posições longas.
ShortTrailingStop
decimal
76
Distância final para posições curtas.
OrderVolume
decimal
0.1
Volume base de negociação (lotes) espelhado da entrada MQL.
MacdCandleType
DataType
H1
Prazo para os filtros MACD de alta e baixa (22/27/9 e 19/77/9).
StochasticCandleType
DataType
M15
Período usado para ambos os osciladores Stochastic (5/3/11 e 9/3/19).
EntryCandleType
DataType
M1
Prazo que fornece confirmação de rompimento e lógica de rastreamento.
Todas as configurações baseadas em pontos são convertidas em preços absolutos por meio do instrumento PriceStep, reproduzindo fielmente o multiplicador MetaTrader Point.
Regras de negociação
Entrada longa
A linha principal horária MACD(22,27,9) cruza acima de seu valor anterior, mas permanece abaixo de zero.
M15 Stochastic(%K=5,%D=3,slowing=11) está abaixo de 26 e subindo em relação ao seu valor anterior.
O fechamento atual do M1 perfura a máxima anterior do M1.
Quando todas as condições se alinham e nenhuma posição está aberta, a estratégia compra OrderVolume mais qualquer quantidade necessária para inverter uma posição vendida existente.
Entrada curta
A linha principal horária MACD(19,77,9) fica abaixo do valor anterior, com o valor anterior acima de zero.
M15 Stochastic(%K=9,%D=3,slowing=19) está acima de 70.
O fechamento atual do M1 quebra abaixo da mínima anterior do M1.
Uma posição curta é aberta com a mesma lógica de inversão de posição do EA original.
Sair e seguir
As paradas iniciais refletem as distâncias MQL StopLoss em pontos.
Os trailing stops são ativados quando o preço se move mais do que a distância final especificada em favor da posição e são recalculados em cada vela M1 finalizada.
Se o preço atingir o nível de stop ativo (inicial ou de trilha), a posição será fechada com uma ordem de mercado.
Notas de implementação
As assinaturas de velas são divididas por período de tempo para que as atualizações dos indicadores permaneçam independentes, correspondendo exatamente ao comportamento de vários períodos de tempo do EA.
As comparações finais de MQL Bid/Ask são aproximadas com os máximos/mínimos da vela M1 finalizados, que é a representação mais próxima dentro do alto nível baseado em vela API.
O código segue as diretrizes do repositório: recuo de tabulação, namespace StockSharp.Samples.Strategies, comentários em inglês e declarações de parâmetros dentro do construtor via Param(...).
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>
/// MACD + Stochastic trailing strategy.
/// Enters long when MACD histogram is positive and Stochastic K crosses above D from oversold.
/// Enters short when MACD histogram is negative and Stochastic K crosses below D from overbought.
/// </summary>
public class MacdStochasticTrailingStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private decimal? _prevK;
private decimal? _prevD;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public MacdStochasticTrailingStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevK = null;
_prevD = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevK = null;
_prevD = null;
var macd = new MovingAverageConvergenceDivergenceSignal();
var stoch = new StochasticOscillator();
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(macd, stoch, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue macdValue, IIndicatorValue stochValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!macdValue.IsFinal || !stochValue.IsFinal)
return;
var macdVal = (MovingAverageConvergenceDivergenceSignalValue)macdValue;
var stochVal = (StochasticOscillatorValue)stochValue;
if (macdVal.Macd is not decimal macd || macdVal.Signal is not decimal signal)
return;
if (stochVal.K is not decimal k || stochVal.D is not decimal d)
return;
if (_prevK is not decimal prevK || _prevD is not decimal prevD)
{
_prevK = k;
_prevD = d;
return;
}
var histogram = macd - signal;
var kCrossUp = prevK <= prevD && k > d;
var kCrossDown = prevK >= prevD && k < d;
// Buy: MACD histogram positive + stochastic K crosses above D
if (histogram > 0 && kCrossUp && k < 50 && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Sell: MACD histogram negative + stochastic K crosses below D
else if (histogram < 0 && kCrossDown && k > 50 && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevK = k;
_prevD = d;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import MovingAverageConvergenceDivergenceSignal, StochasticOscillator
from StockSharp.Algo.Strategies import Strategy
class macd_stochastic_trailing_strategy(Strategy):
"""MACD + Stochastic trailing strategy.
Enters long when MACD histogram positive and Stochastic K crosses above D from oversold.
Enters short when MACD histogram negative and Stochastic K crosses below D from overbought."""
def __init__(self):
super(macd_stochastic_trailing_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_k = None
self._prev_d = None
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnReseted(self):
super(macd_stochastic_trailing_strategy, self).OnReseted()
self._prev_k = None
self._prev_d = None
def OnStarted2(self, time):
super(macd_stochastic_trailing_strategy, self).OnStarted2(time)
self._prev_k = None
self._prev_d = None
macd = MovingAverageConvergenceDivergenceSignal()
stoch = StochasticOscillator()
subscription = self.SubscribeCandles(self.CandleType)
subscription.BindEx(macd, stoch, self._process_candle).Start()
def _process_candle(self, candle, macd_value, stoch_value):
if candle.State != CandleStates.Finished:
return
if not macd_value.IsFinal or not stoch_value.IsFinal:
return
macd_raw = macd_value.Macd if hasattr(macd_value, 'Macd') else None
signal_raw = macd_value.Signal if hasattr(macd_value, 'Signal') else None
if macd_raw is None or signal_raw is None:
return
macd_main = float(macd_raw)
signal_line = float(signal_raw)
k_raw = stoch_value.K if hasattr(stoch_value, 'K') else None
d_raw = stoch_value.D if hasattr(stoch_value, 'D') else None
if k_raw is None or d_raw is None:
return
k = float(k_raw)
d = float(d_raw)
if self._prev_k is None or self._prev_d is None:
self._prev_k = k
self._prev_d = d
return
prev_k = self._prev_k
prev_d = self._prev_d
histogram = macd_main - signal_line
k_cross_up = prev_k <= prev_d and k > d
k_cross_down = prev_k >= prev_d and k < d
# Buy: MACD histogram positive + stochastic K crosses above D from oversold
if histogram > 0 and k_cross_up and k < 50 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Sell: MACD histogram negative + stochastic K crosses below D from overbought
elif histogram < 0 and k_cross_down and k > 50 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_k = k
self._prev_d = d
def CreateClone(self):
return macd_stochastic_trailing_strategy()