Ver en GitHub

Estrategia de Cruce de EMA ETH/USDT

Esta estrategia opera ETH/USDT utilizando un cruce de EMA con filtros adicionales.

Se abre una posición larga cuando la EMA de 20 períodos cruza por encima de la EMA de 50 períodos mientras el precio está por encima de la EMA de 200 períodos, el RSI está por encima de 30, la volatilidad medida por ATR está por encima de su media móvil, y el volumen es mayor que su promedio. Se abre una posición corta en las condiciones opuestas.

Las posiciones se invierten cuando aparece la señal contraria. No se utiliza stop loss ni take profit explícito.

Detalles

  • Criterios de entrada:

    • Largo: EMA20 cruza por encima de EMA50 && Close > EMA200 && RSI > 30 && ATR > SMA(ATR,10) && Volume > SMA(Volume,20)
    • Corto: EMA20 cruza por debajo de EMA50 && Close < EMA200 && RSI < 70 && ATR > SMA(ATR,10) && Volume > SMA(Volume,20)
  • Largo/Corto: Ambos lados

  • Criterios de salida:

    • Señal inversa
  • Stops: No

  • Valores predeterminados:

    • EMA200 Length = 200
    • EMA20 Length = 20
    • EMA50 Length = 50
    • RSI Length = 14
    • ATR Length = 14
  • Filtros:

    • Categoría: Seguimiento de tendencia
    • Dirección: Ambos
    • Indicadores: EMA, RSI, ATR
    • Stops: No
    • Complejidad: Moderado
    • Marco temporal: Corto plazo
    • 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;

public class EthUsdtEmaCrossoverStrategy : Strategy
{
	private readonly StrategyParam<int> _fastEmaPeriod;
	private readonly StrategyParam<int> _slowEmaPeriod;
	private readonly StrategyParam<DataType> _candleType;
	private decimal _prevFastEma;
	private decimal _prevSlowEma;

	public int FastEmaPeriod { get => _fastEmaPeriod.Value; set => _fastEmaPeriod.Value = value; }
	public int SlowEmaPeriod { get => _slowEmaPeriod.Value; set => _slowEmaPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public EthUsdtEmaCrossoverStrategy()
	{
		_fastEmaPeriod = Param(nameof(FastEmaPeriod), 120)
			.SetGreaterThanZero()
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
		_slowEmaPeriod = Param(nameof(SlowEmaPeriod), 450)
			.SetGreaterThanZero()
			.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles to use", "General");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFastEma = 0m;
		_prevSlowEma = 0m;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		var fastEma = new ExponentialMovingAverage { Length = FastEmaPeriod };
		var slowEma = new ExponentialMovingAverage { Length = SlowEmaPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fastEma, slowEma, ProcessCandle).Start();
		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, fastEma);
			DrawIndicator(area, slowEma);
			DrawOwnTrades(area);
		}
	}

	private void ProcessCandle(ICandleMessage candle, decimal fastEmaValue, decimal slowEmaValue)
	{
		if (candle.State != CandleStates.Finished) return;
		if (_prevFastEma == 0m || _prevSlowEma == 0m)
		{
			_prevFastEma = fastEmaValue;
			_prevSlowEma = slowEmaValue;
			return;
		}
		if (_prevFastEma <= _prevSlowEma && fastEmaValue > slowEmaValue && Position <= 0)
			BuyMarket();
		else if (_prevFastEma >= _prevSlowEma && fastEmaValue < slowEmaValue && Position >= 0)
			SellMarket();
		_prevFastEma = fastEmaValue;
		_prevSlowEma = slowEmaValue;
	}
}