Ver en GitHub

Supertrend Signal Strategy

This strategy opens positions when the closing price crosses the SuperTrend line. A long trade is placed when price moves above the line, and a short trade is opened when price drops below it. Opposite signals close and reverse existing positions.

The SuperTrend indicator uses the Average True Range (ATR) to follow price and define the prevailing trend. Parameters allow configuring ATR period, multiplier and candle timeframe.

Details

  • Entry Criteria:
    • Long: Close price crosses above SuperTrend
    • Short: Close price crosses below SuperTrend
  • Long/Short: Long and Short
  • Exit Criteria:
    • Opposite SuperTrend crossover
  • Stops: None
  • Default Values:
    • AtrPeriod = 5
    • Multiplier = 3
    • CandleType = TimeSpan.FromMinutes(15).TimeFrame()
  • Filters:
    • Category: Trend following
    • Direction: Both
    • Indicators: SuperTrend (ATR-based)
    • Stops: No
    • Complexity: Beginner
    • Timeframe: Mid-term
    • Seasonality: None
    • Neural Networks: No
    • Divergence: No
    • Risk Level: Medium
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>
/// Simple SuperTrend crossover strategy.
/// </summary>
public class SupertrendSignalStrategy : Strategy
{
	private readonly StrategyParam<int> _atrPeriod;
	private readonly StrategyParam<decimal> _multiplier;
	private readonly StrategyParam<DataType> _candleType;

	private bool? _prevIsUpTrend;

	public int AtrPeriod { get => _atrPeriod.Value; set => _atrPeriod.Value = value; }
	public decimal Multiplier { get => _multiplier.Value; set => _multiplier.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public SupertrendSignalStrategy()
	{
		_atrPeriod = Param(nameof(AtrPeriod), 5)
			.SetDisplay("ATR Period", "ATR period for SuperTrend", "Parameters");

		_multiplier = Param(nameof(Multiplier), 3m)
			.SetDisplay("Multiplier", "ATR multiplier for SuperTrend", "Parameters");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe for candles", "Parameters");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevIsUpTrend = null;
	}

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

		var st = new SuperTrend { Length = AtrPeriod, Multiplier = Multiplier };
		var subscription = SubscribeCandles(CandleType);
		subscription
			.BindEx(st, ProcessCandle)
			.Start();

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

	private void ProcessCandle(ICandleMessage candle, IIndicatorValue stValue)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!stValue.IsFormed)
			return;

		var stv = stValue as SuperTrendIndicatorValue;
		if (stv == null)
			return;

		var isUpTrend = stv.IsUpTrend;

		if (IsFormedAndOnlineAndAllowTrading() && _prevIsUpTrend.HasValue)
		{
			if (isUpTrend && !_prevIsUpTrend.Value && Position <= 0)
				BuyMarket();
			else if (!isUpTrend && _prevIsUpTrend.Value && Position >= 0)
				SellMarket();
		}

		_prevIsUpTrend = isUpTrend;
	}
}