Ver en GitHub

Básico Martingale EA 3

Descripción general

La estrategia Básica Martingale EA 3 replica el asesor experto MetaTrader 5 que combina un filtro de tendencias basado en la media móvil exponencial triple (TEMA) con un promedio de martingala impulsado por ATR. La versión convertida StockSharp mantiene los mismos parámetros de riesgo, ventana de negociación y lógica de administración de dinero, al tiempo que expone todo a través de parámetros de estrategia para su optimización.

Lógica comercial

  1. Generación de señal: en cada vela completa del período de tiempo seleccionado, el precio de cierre se compara con el valor de TEMA. Un cierre por encima del indicador abre una cesta larga, mientras que un cierre por debajo abre una cesta corta. Sólo una dirección puede estar activa al mismo tiempo.
  2. Ventana de negociación: se permiten cestas nuevas solo entre el StartHour y el EndHour (hora de intercambio). Si ambos horarios son iguales la ventana se considera siempre abierta. Establezca TradeAtNewBar en true para limitar las cestas nuevas a una por vela, similar al cambio original TradeAtNewBar en MT5.
  3. Cuadrícula promedio: una vez que existe una posición, la estrategia mide la distancia desde el peor/mejor precio de entrada. Siempre que el mercado se mueve al menos GridMultiplier × ATR, se agrega una orden adicional en la dirección definida por Averaging (promedio hacia abajo o promedio hacia arriba) hasta alcanzar MaxAverageOrders. El nuevo tamaño del pedido sigue el modo martingala elegido (Multiply o Increment).
  4. Salidas protectoras: los niveles opcionales de stop-loss y take-profit se heredan de la primera orden de la cesta. Además, el bloque final imita la implementación de MT5: después de TrailingStart puntos de ganancia, el stop se mueve a price - TrailingStop (o price + TrailingStop para cortos) y se ajusta en TrailingStep.
  5. Aplanamiento: si se toca algún nivel stop, take-profit o trailing, toda la cesta se cierra en el mercado y todos los contadores de promedio se reinician.

Parámetros

Parámetro Tipo Predeterminado Descripción
CandleType DataType Periodo H1 Serie de velas que impulsa la estrategia.
StartVolume decimal 0.01 Volumen inicial para el primer pedido en una cesta.
StopLossPoints decimal 20 Distancia de stop-loss en pasos de precio. Establezca en 0 para desactivar.
TakeProfitPoints decimal 20 Distancia de obtención de beneficios en pasos de precio. Establezca en 0 para desactivar.
StartHour int 3 Hora (inclusive) en la que se pueden iniciar nuevas cestas.
EndHour int 18 Hora (exclusiva) en la que se detiene la creación de la cesta.
TemaPeriod int 50 Longitud del indicador TEMA.
BarsCalculated int 3 Número de velas terminadas necesarias antes de que comience la negociación.
AtrPeriod int 14 Período del indicador Average True Range.
GridMultiplier decimal 0.75 multiplicador ATR que define el espaciado de la cuadrícula.
MaxAverageOrders int 3 Número máximo de órdenes promediadas por dirección (incluida la inicial).
Averaging enumeración AverageDown Elija entre promediar en reducción, promediar en ganancias o deshabilitar entradas adicionales.
Martin enumeración Multiply Seleccione entre tamaño de martingala multiplicativo o incremental.
LotMultiplier decimal 1.5 Factor utilizado por el modo martingala Multiply.
LotIncrement decimal 0.1 Volumen adicional utilizado por el modo martingala Increment.
TradeAtNewBar bool false Limite las cestas nuevas a una por cada vela terminada.
TrailingStart int 100 Ganancia en puntos necesarios para activar el seguimiento.
TrailingStop int 50 Distancia del trailing stop en puntos.
TrailingStep int 30 Mejora mínima (puntos) antes de volver a mover el trailing stop.

Notas de conversión

  • La versión StockSharp mantiene la configuración del indicador MT5 (TEMA(50) + ATR(14)) y expone el parámetro bar como BarsCalculated, asegurando al menos el número especificado de velas antes de operar.
  • El manejo del volumen respeta los MinVolume, MaxVolume y VolumeStep del instrumento, por lo que las operaciones en vivo respetan los límites de intercambio incluso con pasos fraccionarios de martingala.
  • La lógica de seguimiento sigue el comportamiento original de equilibrio más el paso de seguimiento, pero se implementa con datos de posición agregados porque las posiciones StockSharp se compensan por instrumento.
  • Las anotaciones de gráficos del experto MT5 no se transfirieron porque StockSharp ya proporciona visualización de orden y posición en los paneles de gráficos.
namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Basic Martingale EA 3 strategy: WMA crossover with RSI filter.
/// Buys when WMA fast crosses above slow and RSI below midline, sells on opposite conditions.
/// </summary>
public class BasicMartingaleEa3Strategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _rsiPeriod;

	private decimal _prevFast;
	private decimal _prevSlow;
	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 RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }

	public BasicMartingaleEa3Strategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_fastPeriod = Param(nameof(FastPeriod), 5)
			.SetGreaterThanZero()
			.SetDisplay("Fast WMA", "Fast WMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 15)
			.SetGreaterThanZero()
			.SetDisplay("Slow WMA", "Slow WMA period", "Indicators");
		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI period", "Indicators");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = 0;
		_prevSlow = 0;
		_hasPrev = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_hasPrev = false;
		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };
		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, slow, rsi, ProcessCandle).Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue, decimal rsiValue)
	{
		if (candle.State != CandleStates.Finished) return;

		if (_hasPrev)
		{
			if (_prevFast <= _prevSlow && fastValue > slowValue && rsiValue < 45 && Position <= 0)
				BuyMarket();
			else if (_prevFast >= _prevSlow && fastValue < slowValue && rsiValue > 55 && Position >= 0)
				SellMarket();
		}
		else
		{
			if (fastValue > slowValue && rsiValue < 45 && Position <= 0)
				BuyMarket();
			else if (fastValue < slowValue && rsiValue > 55 && Position >= 0)
				SellMarket();
		}

		_prevFast = fastValue;
		_prevSlow = slowValue;
		_hasPrev = true;
	}
}