Estrategia Supertrend Adx
Estrategia basada en el indicador Supertrend y ADX para confirmación de la fuerza de tendencia. Criterios de entrada: Largo: Price > Supertrend && ADX > 25 (tendencia alcista con movimiento fuerte). Corto: Price < Supertrend && ADX > 25 (tendencia bajista con movimiento fuerte). Criterios de salida: Largo: Price < Supertrend (precio cae por debajo de Supertrend). Corto: Price > Supertrend (precio sube por encima de Supertrend).
Las pruebas indican un retorno anual promedio de aproximadamente 166%. Funciona mejor en el mercado de acciones.
Supertrend proporciona un camino ajustado por volatilidad mientras ADX confirma la potencia del movimiento. Las operaciones ocurren cuando ambos indicadores se alinean.
Para quienes desean aprovechar tendencias fuertes con trailing stops. ATR determina la colocación del stop.
Detalles
- Criterios de entrada:
- Largo:
Close > Supertrend && ADX > AdxThreshold - Corto:
Close < Supertrend && ADX > AdxThreshold
- Largo:
- Largo/Corto: Ambos
- Criterios de salida: Reversión de Supertrend
- Stops: Usa Supertrend como trailing stop
- Valores predeterminados:
SupertrendPeriod= 10SupertrendMultiplier= 3.0mAdxPeriod= 14AdxThreshold= 25mCandleType= TimeSpan.FromMinutes(15).TimeFrame()
- Filtros:
- Categoría: Tendencia
- Dirección: Ambos
- Indicadores: Supertrend, ADX
- Stops: Sí
- Complejidad: Intermedio
- Marco temporal: Medio plazo
- Estacionalidad: No
- Redes neuronales: No
- Divergencia: No
- Nivel de riesgo: Medio
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>
/// Strategy based on Supertrend indicator and ADX for trend strength confirmation.
///
/// Entry criteria:
/// Long: Price > Supertrend && ADX > 25 (uptrend with strong movement)
/// Short: Price < Supertrend && ADX > 25 (downtrend with strong movement)
///
/// Exit criteria:
/// Long: Price < Supertrend (price falls below Supertrend)
/// Short: Price > Supertrend (price rises above Supertrend)
/// </summary>
public class SupertrendAdxStrategy : Strategy
{
private readonly StrategyParam<int> _supertrendPeriod;
private readonly StrategyParam<decimal> _supertrendMultiplier;
private readonly StrategyParam<int> _adxPeriod;
private readonly StrategyParam<decimal> _adxThreshold;
private readonly StrategyParam<int> _cooldownBars;
private readonly StrategyParam<DataType> _candleType;
private decimal _lastSupertrend;
private bool _isAboveSupertrend;
private int _cooldown;
/// <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>
/// Period for ADX calculation.
/// </summary>
public int AdxPeriod
{
get => _adxPeriod.Value;
set => _adxPeriod.Value = value;
}
/// <summary>
/// Threshold for ADX to confirm trend strength.
/// </summary>
public decimal AdxThreshold
{
get => _adxThreshold.Value;
set => _adxThreshold.Value = value;
}
/// <summary>
/// Bars to wait between trades.
/// </summary>
public int CooldownBars
{
get => _cooldownBars.Value;
set => _cooldownBars.Value = value;
}
/// <summary>
/// Type of candles to use.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public SupertrendAdxStrategy()
{
_supertrendPeriod = Param(nameof(SupertrendPeriod), 10)
.SetGreaterThanZero()
.SetDisplay("Supertrend Period", "Period for ATR calculation in Supertrend", "Indicators")
.SetOptimize(5, 20, 5);
_supertrendMultiplier = Param(nameof(SupertrendMultiplier), 3.0m)
.SetGreaterThanZero()
.SetDisplay("Supertrend Multiplier", "Multiplier for ATR in Supertrend", "Indicators")
.SetOptimize(1.0m, 5.0m, 1.0m);
_adxPeriod = Param(nameof(AdxPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("ADX Period", "Period for ADX calculation", "Indicators")
.SetOptimize(7, 21, 7);
_adxThreshold = Param(nameof(AdxThreshold), 30m)
.SetGreaterThanZero()
.SetDisplay("ADX Threshold", "Minimum ADX value to confirm trend strength", "Indicators")
.SetOptimize(20m, 30m, 5m);
_cooldownBars = Param(nameof(CooldownBars), 50)
.SetRange(1, 100)
.SetDisplay("Cooldown Bars", "Bars between trades", "General");
_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();
_lastSupertrend = 0;
_isAboveSupertrend = false;
_cooldown = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var supertrend = new SuperTrend { Length = SupertrendPeriod, Multiplier = SupertrendMultiplier };
var dummyEma = new ExponentialMovingAverage { Length = 10 };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(supertrend, dummyEma, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, supertrend);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue stVal, IIndicatorValue dummyVal)
{
if (candle.State != CandleStates.Finished)
return;
if (stVal is not SuperTrendIndicatorValue st)
return;
var isUpTrend = st.IsUpTrend;
var trendChanged = isUpTrend != _isAboveSupertrend && _lastSupertrend > 0;
if (_cooldown > 0)
_cooldown--;
if (_cooldown == 0 && trendChanged)
{
if (isUpTrend && Position <= 0)
{
BuyMarket();
_cooldown = CooldownBars;
}
else if (!isUpTrend && Position >= 0)
{
SellMarket();
_cooldown = CooldownBars;
}
}
_lastSupertrend = 1;
_isAboveSupertrend = isUpTrend;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import SuperTrend, ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
class supertrend_adx_strategy(Strategy):
"""
Strategy based on Supertrend indicator trend direction changes.
Trades on supertrend trend flips with cooldown.
"""
def __init__(self):
super(supertrend_adx_strategy, self).__init__()
self._supertrend_period = self.Param("SupertrendPeriod", 10) \
.SetGreaterThanZero() \
.SetDisplay("Supertrend Period", "Period for ATR calculation in Supertrend", "Indicators")
self._supertrend_multiplier = self.Param("SupertrendMultiplier", 3.0) \
.SetGreaterThanZero() \
.SetDisplay("Supertrend Multiplier", "Multiplier for ATR in Supertrend", "Indicators")
self._adx_period = self.Param("AdxPeriod", 14) \
.SetGreaterThanZero() \
.SetDisplay("ADX Period", "Period for ADX calculation", "Indicators")
self._adx_threshold = self.Param("AdxThreshold", 30.0) \
.SetGreaterThanZero() \
.SetDisplay("ADX Threshold", "Minimum ADX value to confirm trend strength", "Indicators")
self._cooldown_bars = self.Param("CooldownBars", 50) \
.SetRange(1, 100) \
.SetDisplay("Cooldown Bars", "Bars between trades", "General")
self._candle_type = self.Param("CandleType", tf(5)) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._last_supertrend = 0
self._is_above_supertrend = False
self._cooldown = 0
@property
def CandleType(self):
return self._candle_type.Value
def OnReseted(self):
super(supertrend_adx_strategy, self).OnReseted()
self._last_supertrend = 0
self._is_above_supertrend = False
self._cooldown = 0
def OnStarted2(self, time):
super(supertrend_adx_strategy, self).OnStarted2(time)
self._last_supertrend = 0
self._is_above_supertrend = False
self._cooldown = 0
supertrend = SuperTrend()
supertrend.Length = self._supertrend_period.Value
supertrend.Multiplier = self._supertrend_multiplier.Value
dummyEma = ExponentialMovingAverage()
dummyEma.Length = 10
subscription = self.SubscribeCandles(self.CandleType)
subscription.BindEx(supertrend, dummyEma, self.ProcessCandle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, supertrend)
self.DrawOwnTrades(area)
def ProcessCandle(self, candle, st_val, dummy_val):
if candle.State != CandleStates.Finished:
return
is_up_trend = st_val.IsUpTrend
trend_changed = is_up_trend != self._is_above_supertrend and self._last_supertrend > 0
if self._cooldown > 0:
self._cooldown -= 1
cooldown_val = int(self._cooldown_bars.Value)
if self._cooldown == 0 and trend_changed:
if is_up_trend and self.Position <= 0:
self.BuyMarket()
self._cooldown = cooldown_val
elif not is_up_trend and self.Position >= 0:
self.SellMarket()
self._cooldown = cooldown_val
self._last_supertrend = 1
self._is_above_supertrend = is_up_trend
def CreateClone(self):
return supertrend_adx_strategy()