EMA Estrategia de cobertura de competencia cruzada
Esta estrategia reproduce el asesor experto MetaTrader EMA_CROSS_CONTEST_HEDGED dentro de StockSharp. El robot busca un cruce alcista/bajista entre una media móvil exponencial rápida y lenta (EMA) y, opcionalmente, comprueba el histograma MACD como confirmación de tendencia. Cuando aparece una señal, la estrategia abre inmediatamente una posición de mercado y coloca una escalera de órdenes stop que cubren la operación agregando más exposición si el precio mantiene la tendencia.
Lógica de trading
Calcule un EMA corto y un EMA largo en la serie de velas configuradas. Las señales se pueden tomar de la barra completada anteriormente (predeterminado) o de la barra actual una vez que se cierra la vela.
Detecte un cruce alcista cuando el EMA corto sube por encima del EMA largo y un cruce bajista cuando cae por debajo del EMA largo.
Opcionalmente, requiera que la línea MACD esté por encima de cero para operaciones largas y por debajo de cero para operaciones cortas, replicando el filtro MQL.
Cuando se cumpla la condición alcista, compre en el mercado, fije objetivos de limitación de pérdidas y toma de ganancias, y ponga en cola cuatro órdenes pendientes de limitación de compra espaciadas por la distancia de cobertura.
Cuando se cumpla la condición bajista, venda en el mercado, adjunte objetivos de riesgo y ponga en cola cuatro órdenes pendientes de venta por debajo del precio.
Las órdenes pendientes se cancelan después de su fecha de vencimiento si no se activan.
Los stop dinámicos se estrechan a medida que crecen las ganancias abiertas y los cruces opuestos pueden forzar salidas anticipadas cuando Use Close está habilitado.
Parámetros
Tipo de vela: período de tiempo utilizado para todos los cálculos.
Volumen de orden: volumen de operaciones para la posición inicial y cada orden de cobertura.
Take Profit (pips) – distancia de obtención de beneficios en pips.
Stop Loss (pips) – distancia del stop-loss en pips.
Trailing Stop (pips) – distancia de trailing stop (0 desactiva el trailing).
Nivel de cobertura (pips) – espacio entre las órdenes pendientes de cobertura.
Usar Cerrar: cierra posiciones existentes cuando ocurre un cruce opuesto.
Utilice MACD: solicite MACD confirmación para las entradas comerciales.
Vencimiento(s) – vida útil de las órdenes de cobertura pendientes.
Corto EMA – duración de la EMA rápida.
Long EMA – duración del EMA lento (debe ser mayor que el EMA rápido).
Barra de señal: elija si desea evaluar las señales en la barra actual (0) o en la barra anterior (1).
Notas
Todos los comentarios en el código se proporcionan en inglés según lo solicitado.
La estructura de cobertura pendiente sigue el comportamiento del asesor experto original MQL, colocando cuatro órdenes en pasos de igual distancia.
Las conversiones de precios de pips tienen en cuenta los PriceStep y Decimals del símbolo para coincidir con los cálculos de puntos de MetaTrader.
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>
/// EMA Cross Contest strategy - dual EMA crossover.
/// Buys when short EMA crosses above long EMA.
/// Sells when short EMA crosses below long EMA.
/// </summary>
public class EmaCrossContestHedgedLadderStrategy : Strategy
{
private readonly StrategyParam<int> _shortPeriod;
private readonly StrategyParam<int> _longPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevShort;
private decimal _prevLong;
private bool _hasPrev;
public int ShortPeriod { get => _shortPeriod.Value; set => _shortPeriod.Value = value; }
public int LongPeriod { get => _longPeriod.Value; set => _longPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public EmaCrossContestHedgedLadderStrategy()
{
_shortPeriod = Param(nameof(ShortPeriod), 9)
.SetDisplay("Short EMA", "Short EMA period", "Indicators");
_longPeriod = Param(nameof(LongPeriod), 21)
.SetDisplay("Long EMA", "Long EMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
protected override void OnReseted() { base.OnReseted(); _prevShort = 0m; _prevLong = 0m; _hasPrev = false; }
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var shortEma = new ExponentialMovingAverage { Length = ShortPeriod };
var longEma = new ExponentialMovingAverage { Length = LongPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(shortEma, longEma, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal shortEma, decimal longEma)
{
if (candle.State != CandleStates.Finished)
return;
if (!_hasPrev)
{
_prevShort = shortEma;
_prevLong = longEma;
_hasPrev = true;
return;
}
if (_prevShort <= _prevLong && shortEma > longEma && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
else if (_prevShort >= _prevLong && shortEma < longEma && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevShort = shortEma;
_prevLong = longEma;
}
}