Ver en GitHub

Estrategia X Trader V3

Esta estrategia opera cruces entre dos medias móviles del precio medio. La primera media móvil es más larga y desplazada, mientras que la segunda es corta. Se abre una posición larga cuando la primera media móvil cruza por debajo de la segunda y permanece por debajo durante dos barras tras estar por encima dos barras antes. Se abre una posición corta en el cruce opuesto. Las posiciones pueden cerrarse con señales inversas. El trading se limita a una ventana horaria intradía específica. Están disponibles stops protectores opcionales.

Detalles

  • Criterios de entrada:
    • SMA del precio medio(Ma1Period) cruza por debajo de la SMA del precio medio(Ma2Period) y permanece por debajo durante dos barras ⇒ comprar cuando AllowBuy es verdadero.
    • SMA del precio medio(Ma1Period) cruza por encima de la SMA del precio medio(Ma2Period) y permanece por encima durante dos barras ⇒ vender cuando AllowSell es verdadero.
    • Tiempo de la vela entre StartTime y EndTime.
  • Largo/Corto: Ambos.
  • Criterios de salida:
    • Cruce opuesto cuando CloseOnReverseSignal es verdadero.
  • Stops:
    • Take profit y stop loss opcionales en ticks mediante TakeProfitTicks y StopLossTicks.
  • Valores predeterminados:
    • Ma1Period = 16
    • Ma2Period = 1
    • TakeProfitTicks = 150
    • StopLossTicks = 100
  • Filtros:
    • Categoría: Cruce
    • Dirección: Ambos
    • Indicadores: SMA
    • Stops: Opcional
    • Complejidad: Bajo
    • Marco temporal: Cualquiera
    • Estacionalidad: No
    • Redes neuronales: No
    • Divergencia: No
    • Nivel de riesgo: Medio
using System;
using System.Collections.Generic;

using Ecng.Common;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

namespace StockSharp.Samples.Strategies;

/// <summary>
/// X Trader V3 strategy based on EMA crossover.
/// </summary>
public class XTraderV3Strategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

	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 XTraderV3Strategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe", "General");

		_fastPeriod = Param(nameof(FastPeriod), 12)
			.SetGreaterThanZero()
			.SetDisplay("Fast Period", "Fast EMA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 26)
			.SetGreaterThanZero()
			.SetDisplay("Slow Period", "Slow EMA period", "Indicators");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
		=> [(Security, CandleType)];

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

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

		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };

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

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

		if (!_hasPrev)
		{
			_prevFast = fastVal;
			_prevSlow = slowVal;
			_hasPrev = true;
			return;
		}

		var crossUp = _prevFast <= _prevSlow && fastVal > slowVal;
		var crossDown = _prevFast >= _prevSlow && fastVal < slowVal;

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

		_prevFast = fastVal;
		_prevSlow = slowVal;
	}
}