Dos MA Otro marco temporal Estrategia de intersección correcta
Descripción general
Esta estrategia es un puerto StockSharp del asesor experto MetaTrader 5 "Intersección correcta de otro marco temporal de dos MA". El EA original se basa en dos promedios móviles, cada uno de los cuales se calcula en su propio período de tiempo (por ejemplo, H1 frente a D1), mientras que las decisiones comerciales se sincronizan con el período de tiempo del gráfico. La conversión mantiene el comportamiento de múltiples períodos de tiempo y abre posiciones largas cuando la media móvil rápida cruza por encima de la media móvil lenta. Por el contrario, las posiciones cortas se abren cuando el promedio rápido cruza por debajo del lento. Todas las órdenes se ejecutan al precio de mercado y la estrategia siempre cierra cualquier exposición opuesta antes de abrir una nueva operación, coincidiendo con el modelo de ejecución impulsado por el motor del script MQL5.
Lógica comercial
Suscríbase a tres flujos de velas: el marco temporal de negociación principal, el marco temporal de MA rápida y el marco de tiempo de MA lenta.
Calcule los promedios móviles rápido y lento en sus períodos de tiempo dedicados. Cada media móvil admite los mismos métodos de suavizado y fuentes de precios que expuso el indicador iCustom original.
Opcionalmente, aplique un desplazamiento horizontal configurable a las salidas de promedio móvil antes de compararlas, reproduciendo las entradas ma_shift del EA.
Cada vez que finaliza una vela en el período de tiempo de negociación principal, verifique si hay un cruce entre los valores de promedio móvil más recientes y anteriores:
Si la MA rápida estaba por debajo de la MA lenta en el paso anterior y ahora está por encima de ella, cierre cualquier posición corta y abra (o invierta) una posición larga.
Si la MA rápida estaba por encima de la MA lenta en el paso anterior y ahora está por debajo de ella, cierre cualquier posición larga y abra (o invierta) una posición corta.
Todas las entradas utilizan el volumen comercial configurado. Al revertir una posición existente, la estrategia aumenta el tamaño de la orden en la magnitud de la exposición opuesta para garantizar que la posición cambie en una única orden de mercado.
Parámetros
Parámetro
Descripción
TradeVolume
Volumen base para entradas al mercado. Se utiliza tanto para operaciones largas como cortas.
CandleType
Plazo de negociación principal. Las señales se evalúan cada vez que se cierra una vela de este tipo.
FastTimeFrame
Marco de tiempo utilizado para construir la media móvil rápida.
SlowTimeFrame
Plazo utilizado para construir la media móvil lenta.
FastLength
Número de barras incluidas en la media móvil rápida.
SlowLength
Número de barras incluidas en la media móvil lenta.
FastShift
Desplazamiento horizontal aplicado a la producción promedio móvil rápido antes de la comparación.
SlowShift
Desplazamiento horizontal aplicado a la producción promedio móvil lento antes de la comparación.
FastMethod
Algoritmo de suavizado para la media móvil rápida (simple, exponencial, suavizado o lineal ponderado).
SlowMethod
Algoritmo de suavizado para la media móvil lenta.
FastAppliedPrice
Precio de vela utilizado por el promedio móvil rápido (apertura, máximo, mínimo, cierre, mediana, típico o ponderado).
SlowAppliedPrice
Precio de vela utilizado por la media móvil lenta.
Notas de implementación
Los promedios móviles se procesan a través de StockSharp suscripciones de alto nivel (SubscribeCandles().Bind(...)) y continúan ejecutándose incluso cuando el período de negociación difiere del período de cálculo.
Los parámetros de cambio se implementan con pequeñas colas que retrasan la salida del indicador en el número de barras solicitado, replicando el comportamiento de las entradas ma_shift.
La estrategia utiliza StartProtection() para alinearse con StockSharp utilidades de protección de cuentas, al igual que el motor comercial original que protegía las posiciones abiertas.
La representación del gráfico agrega las velas principales junto con los promedios móviles rápido y lento para que las señales cruzadas permanezcan visibles durante las pruebas retrospectivas.
No hay ningún módulo de stop-loss, take-profit o trailing-stop en el EA original. Los operadores pueden combinar este módulo con estrategias separadas de administración de dinero si se requiere un control de riesgo adicional.
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Dual moving average crossover strategy.
/// Converted from the "Two MA Other TimeFrame Correct Intersection" MQL5 expert advisor.
/// Uses fast and slow SMA on a single timeframe with crossover signals.
/// </summary>
public class TwoMAOtherTimeFrameCorrectIntersectionStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastLength;
private readonly StrategyParam<int> _slowLength;
private ExponentialMovingAverage _fastMa;
private ExponentialMovingAverage _slowMa;
private decimal? _prevFast;
private decimal? _prevSlow;
/// <summary>
/// Initializes strategy parameters.
/// </summary>
public TwoMAOtherTimeFrameCorrectIntersectionStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Primary timeframe used for signal evaluation", "General");
_fastLength = Param(nameof(FastLength), 20)
.SetDisplay("Fast MA Length", "Number of bars for the fast moving average", "Indicators")
.SetGreaterThanZero();
_slowLength = Param(nameof(SlowLength), 50)
.SetDisplay("Slow MA Length", "Number of bars for the slow moving average", "Indicators")
.SetGreaterThanZero();
}
/// <summary>
/// Primary candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Number of bars used by the fast moving average.
/// </summary>
public int FastLength
{
get => _fastLength.Value;
set => _fastLength.Value = value;
}
/// <summary>
/// Number of bars used by the slow moving average.
/// </summary>
public int SlowLength
{
get => _slowLength.Value;
set => _slowLength.Value = value;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevFast = null;
_prevSlow = null;
_fastMa = new ExponentialMovingAverage { Length = FastLength };
_slowMa = new ExponentialMovingAverage { Length = SlowLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(_fastMa, _slowMa, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, _fastMa);
DrawIndicator(area, _slowMa);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!_fastMa.IsFormed || !_slowMa.IsFormed)
{
_prevFast = fastValue;
_prevSlow = slowValue;
return;
}
if (_prevFast is null || _prevSlow is null)
{
_prevFast = fastValue;
_prevSlow = slowValue;
return;
}
var volume = Volume;
if (volume <= 0)
volume = 1;
// Fast crosses above slow => buy
if (_prevFast < _prevSlow && fastValue > slowValue)
{
if (Position <= 0)
BuyMarket(Position < 0 ? Math.Abs(Position) + volume : volume);
}
// Fast crosses below slow => sell
else if (_prevFast > _prevSlow && fastValue < slowValue)
{
if (Position >= 0)
SellMarket(Position > 0 ? Math.Abs(Position) + volume : volume);
}
_prevFast = fastValue;
_prevSlow = slowValue;
}
/// <inheritdoc />
protected override void OnReseted()
{
_prevFast = null;
_prevSlow = null;
_fastMa = null;
_slowMa = null;
base.OnReseted();
}
}