Ver en GitHub

Estrategia Multi-TF AI SuperTrend con ADX

Esta estrategia combina dos indicadores SuperTrend filtrados por una verificación de fuerza ADX. La dirección de la tendencia se confirma comparando las WMA del precio con las WMA del SuperTrend. Las operaciones largas se abren cuando ambos SuperTrend son alcistas y el ADX muestra fuerza positiva. Las operaciones cortas se abren bajo condiciones opuestas. El ATR del primer SuperTrend proporciona un stop trailing.

  • Largo: Ambos SuperTrend alcistas, WMA del precio por encima de las WMA del SuperTrend, +DI > -DI y ADX por encima del umbral.
  • Corto: Ambos SuperTrend bajistas, WMA del precio por debajo de las WMA del SuperTrend, -DI > +DI y ADX por encima del umbral.
  • Indicadores: SuperTrend, WMA, ATR, ADX.
  • Stops: Stop trailing basado en el ATR del primer SuperTrend.
using System;
using System.Linq;
using System.Collections.Generic;

using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Multi-TF AI SuperTrend with ADX Strategy - simplified EMA cross with RSI filter.
/// </summary>
public class MultiTfAiSuperTrendWithAdxStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastLength;
	private readonly StrategyParam<int> _slowLength;
	private readonly StrategyParam<int> _rsiLength;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int FastLength { get => _fastLength.Value; set => _fastLength.Value = value; }
	public int SlowLength { get => _slowLength.Value; set => _slowLength.Value = value; }
	public int RsiLength { get => _rsiLength.Value; set => _rsiLength.Value = value; }

	public MultiTfAiSuperTrendWithAdxStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles", "General");
		_fastLength = Param(nameof(FastLength), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
		_slowLength = Param(nameof(SlowLength), 30)
			.SetGreaterThanZero()
			.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
		_rsiLength = Param(nameof(RsiLength), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI", "RSI period", "Indicators");
	}

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

		var fast = new ExponentialMovingAverage { Length = FastLength };
		var slow = new ExponentialMovingAverage { Length = SlowLength };
		var rsi = new RelativeStrengthIndex { Length = RsiLength };

		var prevFast = 0m;
		var prevSlow = 0m;
		var initialized = false;

		var subscription = SubscribeCandles(CandleType);

		subscription
			.Bind(fast, slow, rsi, (candle, fastVal, slowVal, rsiVal) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!fast.IsFormed || !slow.IsFormed || !rsi.IsFormed)
					return;

				if (!initialized)
				{
					prevFast = fastVal;
					prevSlow = slowVal;
					initialized = true;
					return;
				}

				// EMA crossover with RSI confirmation
				if (prevFast <= prevSlow && fastVal > slowVal && rsiVal > 45 && Position <= 0)
					BuyMarket();
				else if (prevFast >= prevSlow && fastVal < slowVal && rsiVal < 55 && Position > 0)
					SellMarket();

				prevFast = fastVal;
				prevSlow = slowVal;
			})
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, fast);
			DrawIndicator(area, slow);
			DrawOwnTrades(area);
		}
	}
}