Convertido del MetaTrader 4 asesor experto MQL/7637/3_lccfpgubwykd__www_forex-instruments_info.mq4.
Utiliza un flujo de trabajo de tres períodos de tiempo: las velas horarias impulsan ambos filtros MACD, las velas de 15 minutos suministran osciladores Stochastic y las velas de 1 minuto confirman las rupturas de precios y gestionan las salidas finales.
Implementa una estrategia StockSharp de alto nivel utilizando SubscribeCandles(...).Bind(...)/BindEx(...) sin sondeo de datos manual.
Las posiciones se abren con órdenes de mercado y se gestionan completamente dentro de la estrategia (no se requirieron cambios de pruebas externas).
Indicadores y parámetros
Nombre
Tipo
Predeterminado
Descripción
LongStopLoss
decimal
17
Distancia de parada inicial para operaciones largas, expresada en puntos del instrumento.
ShortStopLoss
decimal
40
Distancia de parada inicial para operaciones cortas (puntos).
LongTrailingStop
decimal
88
Distancia de seguimiento para posiciones largas.
ShortTrailingStop
decimal
76
Distancia de seguimiento para posiciones cortas.
OrderVolume
decimal
0.1
Volumen comercial base (lotes) reflejado desde la entrada MQL.
MacdCandleType
DataType
H1
Marco temporal para los filtros alcistas y bajistas MACD (22/27/9 y 19/77/9).
StochasticCandleType
DataType
M15
Marco de tiempo utilizado para los osciladores Stochastic (5/3/11 y 9/3/19).
EntryCandleType
DataType
M1
Marco de tiempo que proporciona confirmación de ruptura y lógica de seguimiento.
Todas las configuraciones basadas en puntos se convierten a precios absolutos a través del instrumento PriceStep, reproduciendo fielmente el multiplicador MetaTrader Point.
Reglas de trading
Entrada larga
La línea principal horaria MACD(22,27,9) cruza por encima de su valor anterior pero permanece por debajo de cero.
M15 Stochastic(%K=5,%D=3,slowing=11) está por debajo de 26 y aumenta con respecto a su valor anterior.
El cierre actual de M1 perfora el máximo de M1 anterior.
Cuando todas las condiciones se alinean y no hay ninguna posición abierta, la estrategia compra OrderVolume más cualquier cantidad necesaria para invertir una posición corta existente.
Entrada corta
La línea principal horaria MACD(19,77,9) cae por debajo de su valor anterior, con el valor anterior por encima de cero.
M15 Stochastic(%K=9,%D=3,desaceleración=19) está por encima de 70.
El cierre actual de M1 cae por debajo del mínimo anterior de M1.
Se abre un corto con la misma lógica de cambio de posición que el EA original.
Salir y seguir
Las paradas iniciales reflejan las distancias MQL StopLoss en puntos.
Los trailingstops se activan una vez que el precio se mueve más que la distancia de seguimiento especificada a favor de la posición y se recalculan en cada vela M1 terminada.
Si el precio toca el nivel de stop activo (inicial o arrastrado), la posición se cierra con una orden de mercado.
Notas de implementación
Las suscripciones a velas se dividen por período de tiempo, por lo que las actualizaciones de los indicadores siguen siendo independientes y coinciden exactamente con el comportamiento de múltiples períodos de tiempo de EA.
Las comparaciones finales MQL Bid/Ask se aproximan con máximos/mínimos de velas M1 terminadas, que es la representación más cercana dentro del nivel alto basado en velas API.
El código sigue las pautas del repositorio: sangría de tabulación, espacio de nombres StockSharp.Samples.Strategies, comentarios en inglés y declaraciones de parámetros dentro del constructor a través de 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()