Ver en GitHub

Estrategia Turtle Trader V1

Turtle Trader V1 combina múltiples osciladores de momentum con un filtro de media móvil. Se abre una posición larga cuando la EMA rápida está por encima de la EMA lenta y RSI, Stochastic, CCI, Momentum y el oscilador Chaikin apuntan hacia arriba. Los cortos requieren las condiciones opuestas.

Detalles

  • Criterios de entrada:
    • EMA rápida por encima de la EMA lenta (por debajo para cortos)
    • RSI subiendo y por debajo de 70 para largos, RSI bajando y por encima de 30 para cortos
    • Stochastic %K por debajo de 88 para largos, por encima de 12 para cortos
    • CCI y Momentum aumentando para largos, disminuyendo para cortos
    • Oscilador Chaikin moviéndose en la dirección de la operación
  • Largo/Corto: Ambos
  • Criterios de salida: señal opuesta
  • Stops: ninguno por defecto
  • Valores predeterminados:
    • FastMaPeriod = 10
    • SlowMaPeriod = 50
    • RsiPeriod = 14
    • StochPeriod = 14
    • CciPeriod = 20
    • MomentumPeriod = 10
    • ChoFastPeriod = 3
    • ChoSlowPeriod = 10
  • Filtros:
    • Categoría: Seguimiento de tendencia / Momentum
    • Dirección: Ambos
    • Indicadores: EMA, RSI, Stochastic, CCI, Momentum, Chaikin Oscillator
    • Stops: Ninguno
    • Complejidad: Avanzado
    • Marco temporal: 1 hora
    • 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>
/// Turtle Trader strategy based on EMA crossover with RSI confirmation.
/// </summary>
public class TurtleTraderV1Strategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevFast;
	private decimal _prevSlow;
	private bool _hasPrev;

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

	public TurtleTraderV1Strategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast MA", "Fast EMA period", "General");
		_slowPeriod = Param(nameof(SlowPeriod), 50)
			.SetGreaterThanZero()
			.SetDisplay("Slow MA", "Slow EMA period", "General");
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle type", "Data");
	}

	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;
	}
}