Estratégia Auto ADX
Visão geral
A Estratégia Auto ADX é um port direto do consultor especialista MetaTrader Auto ADX.mq5 para a API de alto nível do StockSharp. A estratégia avalia a força do Índice Direcional Médio (ADX) e a relação entre os componentes +DI e -DI para determinar a direção do trade. Reproduz os controles de risco originais, incluindo stop-loss, take-profit, sinais reversíveis e trailing stops baseados em pips, enquanto adota conceitos do StockSharp como assinaturas de candles e vínculos de indicadores.
Lógica de Trading
- Fonte de Candles – A estratégia assina um tipo de candle configurável (padrão: período de 1 hora) e processa apenas candles concluídos para evitar ruído intrabar.
- Cálculo ADX – Um único indicador
AverageDirectionalIndex é vinculado através de BindEx, dando acesso ao valor ADX suavizado bem como às linhas +DI e -DI.
- Entrada Comprada – Acionada quando:
- +DI é maior que -DI (momentum direcional positivo),
- ADX está acima do nível ADX configurável, e
- ADX está subindo comparado com o candle anterior.
- Entrada Vendida – Acionada quando:
- -DI é maior que +DI (momentum direcional negativo),
- ADX está abaixo do nível configurado, e
- ADX está caindo versus o candle anterior.
- Modo Reverso – Quando
ReverseSignals está habilitado (comportamento padrão), posições abertas são fechadas se:
- Uma posição comprada vê +DI cair abaixo de -DI ou ADX decresce,
- Uma posição vendida vê +DI subir acima de -DI ou ADX sobe.
- Dimensionamento de Posição – As ordens são emitidas com o
Volume da estratégia. O tratamento de reversão depende de ClosePosition() para sair de toda a exposição antes que um novo sinal seja considerado.
Gestão de Risco
- Stop-Loss / Take-Profit – Convertidos de entradas em pips para distâncias de preço absolutas usando o
PriceStep do instrumento. O auxiliar StartProtection do StockSharp coloca as ordens protetoras com execução de mercado opcional.
- Trailing Stop – A lógica original de trailing baseada em pips é replicada:
- O trailing é ativado apenas depois que o lucro não realizado excede a distância de trailing.
- O nível de stop se move em passos de tamanho pip (
TrailingStepPips).
- Uma posição comprada sai se o preço imprimir abaixo do trailing stop; uma vendida sai quando o preço sobe acima do trailing stop.
- Conversão de Pip – Para imitar a implementação MQL, o tamanho do pip é igual ao
PriceStep, multiplicado por 10 quando o instrumento usa preços de 3 ou 5 decimais. Isso mantém o comportamento consistente entre símbolos forex.
Parâmetros
| Nome |
Padrão |
Descrição |
StopLossPips |
50 |
Distância do stop protetor em pips. Definir como zero para desabilitar o stop-loss. |
TakeProfitPips |
50 |
Distância do alvo de lucro em pips. Definir como zero para desabilitar o take-profit. |
TrailingStopPips |
5 |
Tamanho do trailing stop em pips. Definir como zero para desabilitar o trailing. |
TrailingStepPips |
5 |
Ganho incremental mínimo (em pips) antes de deslocar o trailing stop. Deve ser positivo quando o trailing está habilitado. |
AdxPeriod |
14 |
Período de média para o indicador ADX. |
AdxLevel |
30 |
Limiar de força ADX que filtra as entradas. |
ReverseSignals |
true |
Habilita o fechamento de posições existentes quando a relação DI ou a inclinação ADX muda. |
CandleType |
1 hora |
Tipo de candle usado para análise e trading. |
Notas de Implementação
BindEx é usado para acessar o AverageDirectionalIndexValue completo, garantindo que nunca dependemos da recuperação manual de valores de indicadores.
- A lógica de trailing mantém registro do último nível de stop e o move apenas quando o preço progride pelo menos
TrailingStepPips a favor da posição, replicando o comportamento de passo de trailing MQL.
- Todos os comentários inline no código-fonte C# estão em inglês para satisfazer as diretrizes do repositório.
- A estratégia é autônoma dentro de
API/2908_Auto_ADX/CS/AutoAdxStrategy.cs; não há contraparte Python conforme os requisitos.
Dicas de Uso
- Anexar a estratégia a um instrumento com metadados
PriceStep corretos para que a conversão de pips permaneça precisa.
- Ajustar
AdxLevel para corresponder ao perfil de volatilidade do instrumento negociado — limiares mais altos reduzem a frequência de sinais.
- Quando o trailing está desabilitado (
TrailingStopPips = 0), TrailingStepPips é ignorado, reproduzindo o comportamento do consultor especialista original.
- Fazer backtests em múltiplos mercados para validar as distâncias de proteção baseadas em pips e confirmar que a filtragem de inclinação ADX corresponde às expectativas.
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>
/// Auto ADX strategy (simplified). Uses RSI for trend strength detection
/// combined with EMA for direction, mimicking ADX directional movement logic.
/// </summary>
public class AutoAdxStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiLength;
private readonly StrategyParam<int> _emaLength;
private readonly StrategyParam<decimal> _rsiHigh;
private readonly StrategyParam<decimal> _rsiLow;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int RsiLength
{
get => _rsiLength.Value;
set => _rsiLength.Value = value;
}
public int EmaLength
{
get => _emaLength.Value;
set => _emaLength.Value = value;
}
public decimal RsiHigh
{
get => _rsiHigh.Value;
set => _rsiHigh.Value = value;
}
public decimal RsiLow
{
get => _rsiLow.Value;
set => _rsiLow.Value = value;
}
public AutoAdxStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candles", "General");
_rsiLength = Param(nameof(RsiLength), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Length", "RSI period", "Indicators");
_emaLength = Param(nameof(EmaLength), 20)
.SetGreaterThanZero()
.SetDisplay("EMA Length", "EMA period for direction", "Indicators");
_rsiHigh = Param(nameof(RsiHigh), 60m)
.SetDisplay("RSI High", "RSI threshold for bullish strength", "Logic");
_rsiLow = Param(nameof(RsiLow), 40m)
.SetDisplay("RSI Low", "RSI threshold for bearish weakness", "Logic");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi = new RelativeStrengthIndex { Length = RsiLength };
var ema = new ExponentialMovingAverage { Length = EmaLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(rsi, ema, (ICandleMessage candle, decimal rsiVal, decimal emaVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var close = candle.ClosePrice;
// Strong trend up: RSI above threshold and price above EMA
if (rsiVal > RsiHigh && close > emaVal && Position <= 0)
BuyMarket();
// Weak trend / bearish: RSI below threshold and price below EMA
else if (rsiVal < RsiLow && close < emaVal && Position >= 0)
SellMarket();
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawOwnTrades(area);
var rsiArea = CreateChartArea();
if (rsiArea != null)
DrawIndicator(rsiArea, rsi);
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import RelativeStrengthIndex, ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class auto_adx_strategy(Strategy):
def __init__(self):
super(auto_adx_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candles", "General")
self._rsi_length = self.Param("RsiLength", 14) \
.SetDisplay("RSI Length", "RSI period", "Indicators")
self._ema_length = self.Param("EmaLength", 20) \
.SetDisplay("EMA Length", "EMA period for direction", "Indicators")
self._rsi_high = self.Param("RsiHigh", 60.0) \
.SetDisplay("RSI High", "RSI threshold for bullish strength", "Logic")
self._rsi_low = self.Param("RsiLow", 40.0) \
.SetDisplay("RSI Low", "RSI threshold for bearish weakness", "Logic")
@property
def CandleType(self):
return self._candle_type.Value
@property
def RsiLength(self):
return self._rsi_length.Value
@property
def EmaLength(self):
return self._ema_length.Value
@property
def RsiHigh(self):
return self._rsi_high.Value
@property
def RsiLow(self):
return self._rsi_low.Value
def OnStarted2(self, time):
super(auto_adx_strategy, self).OnStarted2(time)
rsi = RelativeStrengthIndex()
rsi.Length = self.RsiLength
ema = ExponentialMovingAverage()
ema.Length = self.EmaLength
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(rsi, ema, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def _on_process(self, candle, rsi_value, ema_value):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
rv = float(rsi_value)
ev = float(ema_value)
if rv > self.RsiHigh and close > ev and self.Position <= 0:
self.BuyMarket()
elif rv < self.RsiLow and close < ev and self.Position >= 0:
self.SellMarket()
def CreateClone(self):
return auto_adx_strategy()