Ver en GitHub

Estrategia del sistema Forex inteligente

Descripción general

La estrategia Smart Forex System es una versión StockSharp del asesor experto MetaTrader "Smart Forex System". El robot combina un filtro de impulso de una sola vela con una cuadrícula de promedio estilo martingala. La primera operación se abre cuando la vela anterior muestra un cierre direccional fuerte y el precio actual se ha alejado lo suficiente del cierre de referencia. Se agregan entradas adicionales a intervalos de pips fijos en la dirección adversa, y el tamaño de la posición aumenta mediante un multiplicador configurable. La estrategia gestiona las salidas a través de niveles promedio de toma de ganancias y un stop-loss de seguridad vinculado a la última orden de la red.

Lógica de trading

  • Generación de señal
    • Evalúe la última vela completa en el período de tiempo seleccionado.
    • Calcule una relación de impulso: (current close - previous close) / previous close * 10,000.
    • Si la vela anterior es bajista y el impulso es inferior al umbral negativo, puede comenzar una cesta larga.
    • Si la vela anterior es alcista y el impulso supera el umbral positivo, puede comenzar una cesta corta.
    • El comercio puede limitarse a solo largo, solo corto, en ambas direcciones o deshabilitarse por completo a través del parámetro Trading Mode.
  • Expansión de la red
    • Una vez que existe una cesta, se agregan nuevas entradas cada vez que el precio se mueve contra la posición por al menos Grid Step pips desde el precio de la última orden.
    • Cada nuevo volumen de pedido se multiplica por Lot Multiplier. Los volúmenes están sujetos a los límites del corredor y al Max Volume configurado.
    • La cesta deja de crecer cuando el número de pedidos llega a Max Trades.
  • Gestión de salida
    • Se coloca un stop-loss estricto a Stop Loss pips del precio de la última orden. Al superar esa distancia se cierra toda la canasta.
    • Los niveles de obtención de beneficios dependen del tamaño de la cesta:
      • Una sola orden utiliza First Take Profit pips del precio de entrada promedio ponderado por volumen.
      • Varias órdenes utilizan Grid Take Profit pips del mismo precio de entrada promedio para capturar rebotes más pequeños.
    • Las salidas se procesan en velas terminadas para garantizar que los indicadores tengan valores finales.

Notas de gestión de riesgos

  • El tamaño de la posición tipo martingala aumenta drásticamente la exposición a tendencias adversas. Utilice multiplicadores y tamaños de cesta conservadores en instrumentos altamente volátiles.
  • El stop-loss predeterminado (400 pips) es intencionalmente amplio para reflejar el EA original. Considere alinearlo con el ATR del instrumento si se requieren pérdidas menores.
  • El comercio en red consume margen rápidamente. Asegúrese de que el apalancamiento de la cuenta, el tamaño del contrato y los parámetros Start Volume sean consistentes con las especificaciones del corredor.

Parámetros

Nombre Descripción Predeterminado
Modo de negociación Dirección comercial permitida (solo larga, solo corta, ambas o deshabilitada). Largo y corto
Umbral de impulso Impulso mínimo en pseudo-pips necesario para activar una señal. 1
Volumen inicial Volumen del primer pedido en una cesta nueva. 0,01
Volumen máximo Límite estricto aplicado a cualquier volumen de pedido único. 2
Multiplicador de lote Multiplicador utilizado al dimensionar pedidos de cuadrícula posteriores. 1.5
Paso de cuadrícula Distancia mínima en pips antes de agregar la siguiente orden. 26
Operaciones máximas Número máximo de pedidos permitidos por dirección. 12
Primera toma de ganancias Distancia de obtención de beneficios en pips cuando solo hay una orden abierta. 30
Toma de ganancias de la red Distancia de obtención de beneficios en pips una vez que la cesta contiene varias órdenes. 7
Detener pérdidas Distancia de parada en pips desde el último precio de la orden. 400
Tipo de vela Plazo utilizado para la evaluación de la señal. velas de 1 hora

Uso recomendado

  1. Adjunte la estrategia a un símbolo de divisas con suficiente liquidez y un diferencial predecible.
  2. Configure el Candle Type para que coincida con el período operativo del EA original (H1 por defecto) o adáptelo a su horizonte preferido.
  3. Optimice el filtro de espacio, multiplicador y impulso de la red en datos históricos antes de la implementación en vivo.
  4. Supervise de cerca el uso del margen. La canasta puede crecer rápidamente, así que considere combinar la estrategia con una protección de capital en toda la cuenta.
  5. Evite la superposición con otros sistemas basados en redes en el mismo instrumento para reducir el riesgo de caídas compuestas.

Diferencias en comparación con la versión MetaTrader

  • El puerto StockSharp funciona con velas terminadas en lugar de actualizaciones paso a paso, lo que reduce el ruido y hace que la lógica sea determinista.
  • Los volúmenes de pedidos se ajustan utilizando metadatos de seguridad StockSharp (mínimo, máximo y paso), lo que garantiza la compatibilidad con una amplia gama de corredores.
  • Las comprobaciones de toma de ganancias y límite de pérdidas se manejan dentro de la lógica de la estrategia en lugar de enviar modificaciones de órdenes individuales para cada nivel de la red.
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// Smart Forex System strategy: Triple EMA alignment.
/// Enters when fast > mid > slow (buy) or fast < mid < slow (sell).
/// </summary>
public class SmartForexSystemStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _midPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private bool _wasBullishAlignment;
	private bool _hasPrevAlignment;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int MidPeriod { get => _midPeriod.Value; set => _midPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }

	public SmartForexSystemStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
		_midPeriod = Param(nameof(MidPeriod), 25)
			.SetGreaterThanZero()
			.SetDisplay("Mid EMA", "Mid EMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 50)
			.SetGreaterThanZero()
			.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_wasBullishAlignment = false;
		_hasPrevAlignment = false;
	}

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

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

		var bullishAlignment = fastValue > midValue && midValue > slowValue;
		var bearishAlignment = fastValue < midValue && midValue < slowValue;
		var crossedUp = bullishAlignment && (!_hasPrevAlignment || !_wasBullishAlignment);
		var crossedDown = bearishAlignment && (!_hasPrevAlignment || _wasBullishAlignment);

		if (crossedUp && Position <= 0)
			BuyMarket();
		else if (crossedDown && Position >= 0)
			SellMarket();

		if (bullishAlignment || bearishAlignment)
		{
			_wasBullishAlignment = bullishAlignment;
			_hasPrevAlignment = true;
		}
	}
}