Ver en GitHub

Estrategia TradingView Supertrend Flip

Estrategia basada en cambios del indicador Supertrend con confirmación de volumen

Las pruebas indican un retorno anual promedio de aproximadamente 79%. Funciona mejor en el mercado de acciones.

TradingView Supertrend Flip emula los cambios de color del popular indicador. Un cambio de rojo a verde señala una entrada larga y de verde a rojo señala una entrada corta. La estrategia sale en el siguiente cambio.

La confirmación de volumen se puede utilizar para evitar falsas señales durante períodos de negociación escasa. Al actuar solo en cambios con volumen de respaldo, el método apunta a capturar reversiones más confiables.

Detalles

  • Criterios de entrada: Señales basadas en ATR, Supertrend.
  • Largo/Corto: Ambas direcciones.
  • Criterios de salida: Señal opuesta.
  • Stops: No.
  • Valores predeterminados:
    • SupertrendPeriod = 10
    • SupertrendMultiplier = 3.0m
    • VolumeAvgPeriod = 20
    • CandleType = TimeSpan.FromMinutes(5)
  • Filtros:
    • Categoría: Tendencia
    • Dirección: Ambos
    • Indicadores: ATR, Supertrend
    • Stops: No
    • Complejidad: Básico
    • Marco temporal: Intradía (5m)
    • Estacionalidad: No
    • Neural Networks: 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>
/// Strategy based on Supertrend indicator flips.
/// Detects when Supertrend direction changes and trades accordingly.
/// </summary>
public class TradingViewSupertrendFlipStrategy : Strategy
{
	private readonly StrategyParam<int> _supertrendPeriod;
	private readonly StrategyParam<decimal> _supertrendMultiplier;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevSupertrendValue;
	private bool _prevIsUpTrend;
	private bool _hasPrevValues;

	/// <summary>
	/// Period for Supertrend calculation.
	/// </summary>
	public int SupertrendPeriod
	{
		get => _supertrendPeriod.Value;
		set => _supertrendPeriod.Value = value;
	}

	/// <summary>
	/// Multiplier for Supertrend calculation.
	/// </summary>
	public decimal SupertrendMultiplier
	{
		get => _supertrendMultiplier.Value;
		set => _supertrendMultiplier.Value = value;
	}

	/// <summary>
	/// Candle type.
	/// </summary>
	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	/// <summary>
	/// Initialize the TradingView Supertrend Flip strategy.
	/// </summary>
	public TradingViewSupertrendFlipStrategy()
	{
		_supertrendPeriod = Param(nameof(SupertrendPeriod), 10)
			.SetDisplay("Supertrend Period", "Period for Supertrend calculation", "Indicators")
			.SetOptimize(7, 14, 1);

		_supertrendMultiplier = Param(nameof(SupertrendMultiplier), 4.0m)
			.SetDisplay("Supertrend Multiplier", "Multiplier for Supertrend", "Indicators")
			.SetOptimize(3.0m, 5.0m, 0.5m);

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles to use", "General");
	}

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

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevSupertrendValue = default;
		_prevIsUpTrend = default;
		_hasPrevValues = default;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var supertrend = new SuperTrend
		{
			Length = SupertrendPeriod,
			Multiplier = SupertrendMultiplier
		};

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(supertrend, ProcessCandle)
			.Start();

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

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

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		if (supertrendValue == 0)
			return;

		// Determine trend direction
		var isUpTrend = candle.ClosePrice > supertrendValue;

		if (!_hasPrevValues)
		{
			_hasPrevValues = true;
			_prevIsUpTrend = isUpTrend;
			_prevSupertrendValue = supertrendValue;
			return;
		}

		// Detect flip
		var isFlippedBullish = isUpTrend && !_prevIsUpTrend;
		var isFlippedBearish = !isUpTrend && _prevIsUpTrend;

		_prevIsUpTrend = isUpTrend;
		_prevSupertrendValue = supertrendValue;

		if (isFlippedBullish && Position <= 0)
		{
			var volume = Volume + Math.Abs(Position);
			BuyMarket(volume);
		}
		else if (isFlippedBearish && Position >= 0)
		{
			var volume = Volume + Math.Abs(Position);
			SellMarket(volume);
		}
	}
}