Auf GitHub ansehen

Multi-TF AI SuperTrend with ADX Strategy

This strategy combines two SuperTrend indicators filtered by an ADX strength check. Trend direction is confirmed by comparing price WMAs with SuperTrend WMAs. Long trades open when both SuperTrends are bullish and ADX shows positive strength. Short trades open under opposite conditions. The first SuperTrend's ATR provides a trailing stop.

  • Long: Both SuperTrends bullish, price WMAs above SuperTrend WMAs, +DI > -DI and ADX above threshold.
  • Short: Both SuperTrends bearish, price WMAs below SuperTrend WMAs, -DI > +DI and ADX above threshold.
  • Indicators: SuperTrend, WMA, ATR, ADX.
  • Stops: ATR-based trailing stop from the first 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);
		}
	}
}