Ver en GitHub

Estrategia de cruce de divisas simple

Resumen

  • Puerto de alto nivel del asesor experto MetaTrader 4 simplefx2.mq4 (Simple FX 2.0).
  • Intercambia cruces entre una media móvil simple rápida y una lenta en velas terminadas.
  • Mantiene solo una posición abierta y cambia cuando se invierte la tendencia dominante.

Lógica de trading

  1. Cree velas utilizando el parámetro de marco de tiempo configurable.
  2. Calcule dos promedios móviles simples (rápido y lento) sobre los precios de cierre de velas.
  3. Confirme una tendencia alcista cuando tanto la vela actual como la anterior muestren la MA rápida por encima de la MA lenta. Confirme una tendencia bajista cuando ambas velas muestren la MA rápida por debajo de la MA lenta.
  4. Cuando la tendencia confirmada difiere del estado de tendencia almacenado, cierre cualquier posición opuesta y abra inmediatamente una orden de mercado en la nueva dirección utilizando el volumen configurado.
  5. Se pueden habilitar protecciones opcionales de stop-loss y take-profit expresadas en incrementos de precios. Utilizan el servicio de protección integrado de StockSharp para emular la configuración de riesgo MT4.

La estrategia solo procesa velas terminadas, nunca ticks intrabar, para mantenerse cerca del comportamiento original del asesor experto. Se proporciona un registro de cada nueva entrada para que cada decisión cruzada pueda ser auditada.

Parámetros

Nombre Descripción Predeterminado Optimización
ShortPeriod Longitud de la media móvil simple rápida. 50 10 → 150 paso 5
LongPeriod Longitud de la media móvil simple lenta. 200 50 → 400 paso 10
Volume Volumen de órdenes enviadas con cada operación de mercado. 0.1 0,1 → 2 paso 0,1
StopLossPoints Distancia de parada protectora en pasos de precio del instrumento (0 desactiva). 0
TakeProfitPoints Distancia objetivo de ganancias en pasos de precio del instrumento (0 desactiva). 0
CandleType Plazo de vela utilizado para el análisis. 1 hora

Notas y diferencias con la versión MT4

  • El archivo de persistencia MT4 (simplefx.dat) no es necesario; la última dirección de la tendencia es rastreada en la memoria por el estado de la estrategia.
  • Las opciones de deslizamiento, comentario de orden, número mágico y color de flecha del asesor experto original no están expuestas porque StockSharp maneja el enrutamiento de manera diferente.
  • Las distancias de stop-loss y take-profit se interpretan en escalones de precio (tics del instrumento). Ajústelos para que coincidan con la definición de pips de su corredor.
  • Sólo puede haber una posición abierta en cualquier momento; la estrategia se basa en ClosePosition() antes de cambiar de dirección, lo que garantiza un cambio limpio entre operaciones largas y cortas.

Uso

  1. Adjunte la estrategia a un valor/instrumento y establezca el período de tiempo de vela deseado.
  2. Configure períodos de media móvil y parámetros de riesgo.
  3. Iniciar la estrategia; se suscribirá a velas, gestionará el estado de la tendencia y enviará órdenes de mercado cuando se confirme un cruce en dos velas consecutivas.
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>
/// Simple FX crossover strategy.
/// Uses fast and slow SMA crossover for trend detection.
/// Buys on golden cross, sells on death cross.
/// </summary>
public class SimpleFxCrossoverStrategy : 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 SimpleFxCrossoverStrategy()
	{
		_shortPeriod = Param(nameof(ShortPeriod), 10)
			.SetDisplay("Fast SMA", "Fast SMA period", "Indicators");

		_longPeriod = Param(nameof(LongPeriod), 30)
			.SetDisplay("Slow SMA", "Slow SMA period", "Indicators");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).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();
		_prevShort = 0m;
		_prevLong = 0m;
		_hasPrev = false;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_hasPrev = false;

		var fast = new SimpleMovingAverage { Length = ShortPeriod };
		var slow = new SimpleMovingAverage { Length = LongPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, slow, ProcessCandle)
			.Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!_hasPrev)
		{
			_prevShort = fast;
			_prevLong = slow;
			_hasPrev = true;
			return;
		}

		var crossUp = _prevShort <= _prevLong && fast > slow;
		var crossDown = _prevShort >= _prevLong && fast < slow;

		if (crossUp && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		else if (crossDown && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevShort = fast;
		_prevLong = slow;
	}
}