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/Corto: Ambos
- Criterios de salida: Reversión de Supertrend
- Stops: Usa Supertrend como trailing stop
- Valores predeterminados:
SupertrendPeriod = 10
SupertrendMultiplier = 3.0m
AdxPeriod = 14
AdxThreshold = 25m
CandleType = TimeSpan.FromMinutes(15).TimeFrame()
Una señal de entrada contra una posición abierta la invierte.
- 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.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Supertrend ADX strategy.
/// A close above the Supertrend line while ADX is above AdxThreshold goes long and a close below it while ADX is above the threshold goes short,
/// reversing an opposite position. The Supertrend line is the trailing stop: a long closes when price closes below it, as Supertrend flips
/// down, and a short when price closes above it.
/// </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<DataType> _candleType;
/// <summary>
/// ATR period of Supertrend.
/// </summary>
public int SupertrendPeriod
{
get => _supertrendPeriod.Value;
set => _supertrendPeriod.Value = value;
}
/// <summary>
/// ATR multiplier of Supertrend.
/// </summary>
public decimal SupertrendMultiplier
{
get => _supertrendMultiplier.Value;
set => _supertrendMultiplier.Value = value;
}
/// <summary>
/// Period of ADX.
/// </summary>
public int AdxPeriod
{
get => _adxPeriod.Value;
set => _adxPeriod.Value = value;
}
/// <summary>
/// ADX level of a strong trend.
/// </summary>
public decimal AdxThreshold
{
get => _adxThreshold.Value;
set => _adxThreshold.Value = value;
}
/// <summary>
/// Candle type.
/// </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", "ATR period of Supertrend", "Supertrend");
_supertrendMultiplier = Param(nameof(SupertrendMultiplier), 3m)
.SetGreaterThanZero()
.SetDisplay("Supertrend Multiplier", "ATR multiplier of Supertrend", "Supertrend");
_adxPeriod = Param(nameof(AdxPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("ADX Period", "Period of ADX", "ADX");
_adxThreshold = Param(nameof(AdxThreshold), 25m)
.SetDisplay("ADX Threshold", "ADX level of a strong trend", "ADX");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).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 OnStarted2(DateTime time)
{
base.OnStarted2(time);
var supertrend = new SuperTrend { Length = SupertrendPeriod, Multiplier = SupertrendMultiplier };
var adx = new AverageDirectionalIndex { Length = AdxPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(supertrend, adx, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, supertrend);
DrawOwnTrades(area);
var oscillators = CreateChartArea();
if (oscillators != null)
{
DrawIndicator(oscillators, adx);
}
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue supertrendValue, IIndicatorValue adxValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!supertrendValue.IsFormed || !adxValue.IsFormed || supertrendValue is not SuperTrendIndicatorValue trend)
return;
if (adxValue is not AverageDirectionalIndexValue { MovingAverage: decimal strength })
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var line = trend.Value;
var isUpTrend = trend.IsUpTrend;
var close = candle.ClosePrice;
var strong = strength > AdxThreshold;
if (close > line && strong && Position <= 0)
BuyMarket(Volume + Math.Abs(Position));
else if (close < line && strong && Position >= 0)
SellMarket(Volume + Math.Abs(Position));
else if (Position > 0 && !isUpTrend)
SellMarket(Position);
else if (Position < 0 && isUpTrend)
BuyMarket(-Position);
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Decimal
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import SuperTrend, AverageDirectionalIndex
from StockSharp.Algo.Strategies import Strategy
class supertrend_adx_strategy(Strategy):
"""
Supertrend ADX strategy.
A close above the Supertrend line while ADX is above AdxThreshold goes long and a close below it while ADX is above the threshold goes short,
reversing an opposite position. The Supertrend line is the trailing stop: a long closes when price closes below it, as Supertrend flips
down, and a short when price closes above it.
"""
def __init__(self):
super(supertrend_adx_strategy, self).__init__()
self._supertrend_period = self.Param("SupertrendPeriod", 10).SetGreaterThanZero().SetDisplay("Supertrend Period", "ATR period of Supertrend", "Supertrend")
self._supertrend_multiplier = self.Param("SupertrendMultiplier", 3.0).SetGreaterThanZero().SetDisplay("Supertrend Multiplier", "ATR multiplier of Supertrend", "Supertrend")
self._adx_period = self.Param("AdxPeriod", 14).SetGreaterThanZero().SetDisplay("ADX Period", "Period of ADX", "ADX")
self._adx_threshold = self.Param("AdxThreshold", 25.0).SetDisplay("ADX Threshold", "ADX level of a strong trend", "ADX")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(15))).SetDisplay("Candle Type", "Type of candles to use", "General")
@property
def candle_type(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(supertrend_adx_strategy, self).OnStarted2(time)
supertrend = SuperTrend()
supertrend.Length = self._supertrend_period.Value
supertrend.Multiplier = Decimal(self._supertrend_multiplier.Value)
adx = AverageDirectionalIndex()
adx.Length = self._adx_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(supertrend, adx, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, supertrend)
self.DrawOwnTrades(area)
oscillators = self.CreateChartArea()
if oscillators is not None:
self.DrawIndicator(oscillators, adx)
def _process_candle(self, candle, supertrend_value, adx_value):
if candle.State != CandleStates.Finished:
return
if not supertrend_value.IsFormed or not adx_value.IsFormed or adx_value.MovingAverage is None:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
line = supertrend_value.Value
is_up_trend = supertrend_value.IsUpTrend
close = candle.ClosePrice
strong = adx_value.MovingAverage > Decimal(self._adx_threshold.Value)
if close > line and strong and self.Position <= 0:
self.BuyMarket(self.Volume + abs(self.Position))
elif close < line and strong and self.Position >= 0:
self.SellMarket(self.Volume + abs(self.Position))
elif self.Position > 0 and not is_up_trend:
self.SellMarket(self.Position)
elif self.Position < 0 and is_up_trend:
self.BuyMarket(-self.Position)
def CreateClone(self):
return supertrend_adx_strategy()