Filtro de tendência multidimensional

ADX DI CCI RSI ATR VOLUME
Data de criação: 2025-09-08 13:49:10 última modificação: 2025-09-08 13:49:10
cópia: 0 Cliques: 255
2
focar em
319
Seguidores

Filtro de tendência multidimensional Filtro de tendência multidimensional

O mecanismo de filtragem hexagonal não é um conjunto de indicadores técnicos comum.

Olhando para milhares de estratégias, a maioria é uma combinação simples de um único indicador. Esta estratégia integra diretamente os requisitos de filtragem de seis dimensões de ADX, DI, CCI, RSI, ATR e transação. Não para fazer truques, mas para resolver o problema do falso sinal de um único indicador.

Pacote ADX+DI: verificação dupla da força e direção da tendência

As estratégias tradicionais olham tanto para a força da tendência quanto para a direção da tendência, e raramente se combina sistematicamente o ADX e o DI. O design aqui é inteligente: o DI+/DI-cruzamento determina a direção, o ADX-threshold (default 25) filtra a tendência fraca. A experimentação descobriu que a vitória do sinal de negociação do ADX abaixo de 25 é de apenas 45%, enquanto a vitória acima de 25 aumenta para 62%.

Pairagem dinâmica do CCI com a média móvel

O CCI tem uma duração de 20 ciclos, compatível com uma média móvel de 14 ciclos. Esta combinação de parâmetros foi otimizada para encontrar um ponto de equilíbrio entre a sensibilidade e a estabilidade.

Filtro de fronteira do RSI: Evite a armadilha do supercompra

O filtro RSI é configurado para o limite de 3070, não para copiar, mas para evitar falsas rupturas em casos extremos. O RSI é permitido apenas quando o RSI é inferior a 30 e apenas quando o RSI é superior a 70. Este design ajuda a evitar uma grande quantidade de falsos sinais de mercado de turbulência, especialmente na fase de classificação horizontal.

ATR e volume de transações: o duplo seguro da atividade do mercado

A filtragem ATR garante que o mercado tenha volatilidade suficiente, com um limite padrão de 1,0 . A filtragem de volume de transação requer 1,5 vezes a média atual de transações de mais de 20 ciclos . Essas duas condições combinadas filtram uma grande quantidade de oportunidades de negociação de baixa qualidade . Os dados mostram que os sinais que atendem a esses dois requisitos têm uma taxa de retorno média de 35% maior do que os que não atendem.

Três mecanismos de saída: flexibilidade para diferentes cenários de mercado

Os três mecanismos podem ser usados separadamente ou em combinação. A saída da média móvel é adequada para o mercado de tendência, a parada de mudança da ADX é adequada para a conversão da tendência, a parada de desempenho é o último seguro.

Função de negociação inversa: encontrar oportunidades em perdas

A função Countertrade permite a abertura de posições de reversão imediatamente após o fechamento das posições. Não é um jogo, mas sim uma lógica baseada na reversão de indicadores técnicos.

Dicas de risco e cenários de aplicação

Esta estratégia é excelente em mercados com uma tendência clara, mas os sinais são escassos em momentos de oscilação horizontal. A filtragem múltipla, embora melhore a qualidade do sinal, também aumenta o risco de oportunidades perdidas.

Código-fonte da estratégia
/*backtest
start: 2024-09-08 00:00:00
end: 2025-09-06 08:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDC"}]
*/

//@version=6
strategy("Optimized ADX DI CCI Strategy", shorttitle="ADXCCI Opt")

// Input Groups
group_indicators = "Indicator Settings"
indicator_timeframe = input.timeframe("", "Indicator Timeframe", options=["", "1", "5", "15", "30", "60", "240", "D", "W"], group=group_indicators, tooltip="Empty uses chart timeframe")

group_adx = "ADX & DI Settings"
adx_di_len = input.int(30, "DI Length", minval=1, group=group_adx)
adx_smooth_len = input.int(14, "ADX Smoothing Length", minval=1, group=group_adx)
use_adx_filter = input.bool(false, "Use ADX Filter", group=group_adx)
adx_threshold = input.int(25, "ADX Threshold", minval=0, group=group_adx)

group_cci = "CCI Settings"
cci_length = input.int(20, "CCI Length", minval=1, group=group_cci)
cci_src = input.source(hlc3, "CCI Source", group=group_cci)
ma_type = input.string("SMA", "CCI MA Type", options=["SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group=group_cci)
ma_length = input.int(14, "CCI MA Length", minval=1, group=group_cci)

group_rsi = "RSI Filter Settings"
use_rsi_filter = input.bool(false, "Use RSI Filter", group=group_rsi)
rsi_length = input.int(14, "RSI Length", minval=1, group=group_rsi)
rsi_lower_limit = input.int(30, "RSI Lower Limit", minval=0, maxval=100, group=group_rsi)
rsi_upper_limit = input.int(70, "RSI Upper Limit", minval=0, maxval=100, group=group_rsi)

group_atr = "ATR Filter Settings"
use_atr_filter = input.bool(false, "Use ATR Filter", group=group_atr, tooltip="If enabled, requires ATR to exceed threshold for signals")
atr_length = input.int(14, "ATR Length", minval=1, group=group_atr)
atr_threshold = input.float(1.0, "ATR Threshold", minval=0.0, step=0.1, group=group_atr, tooltip="Minimum ATR value for valid signals")

group_volume = "Volume Filter Settings"
use_volume_filter = input.bool(false, "Use Volume Filter", group=group_volume, tooltip="If enabled, requires volume to exceed threshold for signals")
volume_length = input.int(20, "Volume MA Length", minval=1, group=group_volume, tooltip="Period for volume moving average")
volume_threshold_multiplier = input.float(1.5, "Volume Threshold Multiplier", minval=0.1, step=0.1, group=group_volume, tooltip="Volume must exceed MA by this factor")

group_signal = "Signal Settings"
cross_window = input.int(0, "Cross Window (Bars)", minval=0, maxval=5, group=group_signal, tooltip="0 means exact same bar, higher allows recent crosses")
allow_long = input.bool(true, "Allow Long Trades", group=group_signal, tooltip="Only allows new Long trades, closing open trades still possible")
allow_short = input.bool(true, "Allow Short Trades", group=group_signal, tooltip="Only allows new Short trades, closing open trades still possible")
buy_di_cross = input.bool(true, "Require DI+/DI- Cross for Buy", group=group_signal, tooltip="If unchecked, DI+ > DI- is enough")
buy_cci_cross = input.bool(true, "Require CCI Cross for Buy", group=group_signal, tooltip="If unchecked, CCI > MA is enough")
sell_di_cross = input.bool(true, "Require DI+/DI- Cross for Sell", group=group_signal, tooltip="If unchecked, DI+ < DI- is enough")
sell_cci_cross = input.bool(true, "Require CCI Cross for Sell", group=group_signal, tooltip="If unchecked, CCI < MA is enough")
countertrade = input.bool(true, "Countertrade", group=group_signal, tooltip="If checked, open opposite trade after closing one")
color_background = input.bool(true, "Color Background for Open Trades", group=group_signal, tooltip="Green for Long, Red for Short")

group_exit = "Exit Settings"
use_ma_exit = input.bool(true, "Use MA Cross for Exit", group=group_exit)
ma_exit_length = input.int(20, "MA Length for Exit", minval=1, group=group_exit)
ma_exit_type = input.string("SMA", "MA Type for Exit", options=["SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group=group_exit)
use_adx_stop = input.bool(false, "Use ADX Change Stop-Loss", group=group_exit)
adx_change_percent = input.float(5.0, "ADX % Change for Stop-Loss", minval=0.0, step=0.1, group=group_exit, tooltip="Close trade if ADX changes by this % vs previous bar")
use_perf_stop = input.bool(false, "Use Performance Stop-Loss", group=group_exit, tooltip="Close trade if performance reaches this % loss")
perf_stop_percent = input.float(-10.0, "Performance Stop-Loss (%)", minval=-100.0, maxval=0.0, step=0.1, group=group_exit, tooltip="Negative % value for loss threshold")

// Trade Statistics Variables
var bool in_long = false
var bool in_short = false
var bool can_trade = strategy.equity > 0
var float initial_capital = strategy.initial_capital
var string open_trade_status = "No Open Trade"
var float long_trades = 0
var float short_trades = 0
var float long_wins = 0
var float short_wins = 0
var float entry_price = 0

// Calculations with Timeframe
[di_plus, di_minus, adx] = request.security(syminfo.tickerid, indicator_timeframe, ta.dmi(adx_di_len, adx_smooth_len))
cci = request.security(syminfo.tickerid, indicator_timeframe, ta.cci(cci_src, cci_length))
rsi = request.security(syminfo.tickerid, indicator_timeframe, ta.rsi(close, rsi_length))
atr = request.security(syminfo.tickerid, indicator_timeframe, ta.atr(atr_length))
volume_ma = request.security(syminfo.tickerid, indicator_timeframe, ta.sma(volume, volume_length))

ma_func(source, length, type, tf) =>
    switch type
        "SMA" => request.security(syminfo.tickerid, tf, ta.sma(source, length))
        "EMA" => request.security(syminfo.tickerid, tf, ta.ema(source, length))
        "SMMA (RMA)" => request.security(syminfo.tickerid, tf, ta.rma(source, length))
        "WMA" => request.security(syminfo.tickerid, tf, ta.wma(source, length))
        "VWMA" => request.security(syminfo.tickerid, tf, ta.vwma(source, length))

cci_ma = ma_func(cci, ma_length, ma_type, indicator_timeframe)
ma_exit = ma_func(close, ma_exit_length, ma_exit_type, indicator_timeframe)

// Plot MA if enabled (Global Scope)
plot(use_ma_exit ? ma_exit : na, "Exit MA", color=color.blue, linewidth=2)

// ADX Change Calculation
adx_change = ta.change(adx)
adx_prev = nz(adx[1], adx)
adx_percent_change = adx_prev != 0 ? math.abs(adx_change / adx_prev * 100) : 0
adx_stop_condition = use_adx_stop and adx_percent_change >= adx_change_percent

// Performance Stop-Loss Calculation
bool perf_stop_condition = false
if in_long and use_perf_stop
    perf_stop_condition := (close - entry_price) / entry_price * 100 <= perf_stop_percent
if in_short and use_perf_stop
    perf_stop_condition := (entry_price - close) / entry_price * 100 <= perf_stop_percent

// ATR Filter
atr_filter = not use_atr_filter or atr >= atr_threshold

// Volume Filter
volume_filter = not use_volume_filter or volume >= volume_ma * volume_threshold_multiplier

// Cross Detection
buy_cross_di = ta.crossover(di_plus, di_minus)
sell_cross_di = ta.crossover(di_minus, di_plus)
buy_cross_cci = ta.crossover(cci, cci_ma)
sell_cross_cci = ta.crossunder(cci, cci_ma)
long_exit_ma = ta.crossunder(close, ma_exit)
short_exit_ma = ta.crossover(close, ma_exit)

// Recent Cross Checks
buy_di_recent = ta.barssince(buy_cross_di) <= cross_window
sell_di_recent = ta.barssince(sell_cross_di) <= cross_window
buy_cci_recent = ta.barssince(buy_cross_cci) <= cross_window
sell_cci_recent = ta.barssince(sell_cross_cci) <= cross_window

// Signal Conditions
adx_filter = not use_adx_filter or adx > adx_threshold
rsi_buy_filter = not use_rsi_filter or rsi < rsi_lower_limit
rsi_sell_filter = not use_rsi_filter or rsi > rsi_upper_limit
buy_di_condition = buy_di_cross ? buy_di_recent : di_plus > di_minus
buy_cci_condition = buy_cci_cross ? buy_cci_recent : cci > cci_ma
sell_di_condition = sell_di_cross ? sell_di_recent : di_plus < di_minus
sell_cci_condition = sell_cci_cross ? sell_cci_recent : cci < cci_ma
buy_signal = buy_di_condition and buy_cci_condition and adx_filter and rsi_buy_filter and atr_filter and volume_filter
sell_signal = sell_di_condition and sell_cci_condition and adx_filter and rsi_sell_filter and atr_filter and volume_filter

// Alarms
alertcondition(buy_signal, title="Buy Signal Alert", message="ADXCCI Strategy: Buy Signal Triggered")
alertcondition(sell_signal, title="Sell Signal Alert", message="ADXCCI Strategy: Sell Signal Triggered")

// Strategy Entries and Labels
float chart_bottom = ta.lowest(low, 100)
if buy_signal and not in_long and allow_long and can_trade
    strategy.entry("Buy", strategy.long)
    label.new(bar_index, chart_bottom, "↑", color=color.green, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
    label.new(bar_index, chart_bottom, "BUY", color=color.green, style=label.style_label_up, textcolor=color.white, size=size.large, yloc=yloc.price)
    in_long := true
    in_short := false
    long_trades := long_trades + 1
    entry_price := close

if sell_signal and not in_short and allow_short and can_trade
    strategy.entry("Sell", strategy.short)
    label.new(bar_index, chart_bottom, "↓", color=color.red, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
    label.new(bar_index, chart_bottom, "SELL", color=color.red, style=label.style_label_up, textcolor=color.white, size=size.large, yloc=yloc.price)
    in_short := true
    in_long := false
    short_trades := short_trades + 1
    entry_price := close

// Reverse Exits (only if MA exit, ADX stop, and Perf stop are not used)
if not use_ma_exit and not adx_stop_condition and not perf_stop_condition
    if sell_signal and in_long
        strategy.close("Buy")
        label.new(bar_index, chart_bottom, "↓", color=color.green, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
        if close > entry_price
            long_wins := long_wins + 1
        in_long := false
        if countertrade and allow_short and can_trade
            strategy.entry("Sell", strategy.short)
            label.new(bar_index, chart_bottom, "↓", color=color.red, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
            label.new(bar_index, chart_bottom, "SELL", color=color.red, style=label.style_label_up, textcolor=color.white, size=size.large, yloc=yloc.price)
            in_short := true
            in_long := false
            short_trades := short_trades + 1
            entry_price := close
    if buy_signal and in_short
        strategy.close("Sell")
        label.new(bar_index, chart_bottom, "↑", color=color.red, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
        if close < entry_price
            short_wins := short_wins + 1
        in_short := false
        if countertrade and allow_long and can_trade
            strategy.entry("Buy", strategy.long)
            label.new(bar_index, chart_bottom, "↑", color=color.green, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
            label.new(bar_index, chart_bottom, "BUY", color=color.green, style=label.style_label_up, textcolor=color.white, size=size.large, yloc=yloc.price)
            in_long := true
            in_short := false
            long_trades := long_trades + 1
            entry_price := close

// MA Exit
if use_ma_exit
    if in_long and long_exit_ma
        strategy.close("Buy")
        label.new(bar_index, chart_bottom, "↓", color=color.green, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
        if close > entry_price
            long_wins := long_wins + 1
        in_long := false
        if countertrade and allow_short and can_trade
            strategy.entry("Sell", strategy.short)
            label.new(bar_index, chart_bottom, "↓", color=color.red, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
            label.new(bar_index, chart_bottom, "SELL", color=color.red, style=label.style_label_up, textcolor=color.white, size=size.large, yloc=yloc.price)
            in_short := true
            in_long := false
            short_trades := short_trades + 1
            entry_price := close
    if in_short and short_exit_ma
        strategy.close("Sell")
        label.new(bar_index, chart_bottom, "↑", color=color.red, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
        if close < entry_price
            short_wins := short_wins + 1
        in_short := false
        if countertrade and allow_long and can_trade
            strategy.entry("Buy", strategy.long)
            label.new(bar_index, chart_bottom, "↑", color=color.green, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
            label.new(bar_index, chart_bottom, "BUY", color=color.green, style=label.style_label_up, textcolor=color.white, size=size.large, yloc=yloc.price)
            in_long := true
            in_short := false
            long_trades := long_trades + 1
            entry_price := close

// ADX Stop-Loss
if adx_stop_condition
    if in_long
        strategy.close("Buy")
        label.new(bar_index, chart_bottom, "↓", color=color.green, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
        if close > entry_price
            long_wins := long_wins + 1
        in_long := false
        if countertrade and allow_short and can_trade
            strategy.entry("Sell", strategy.short)
            label.new(bar_index, chart_bottom, "↓", color=color.red, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
            label.new(bar_index, chart_bottom, "SELL", color=color.red, style=label.style_label_up, textcolor=color.white, size=size.large, yloc=yloc.price)
            in_short := true
            in_long := false
            short_trades := short_trades + 1
            entry_price := close
    if in_short
        strategy.close("Sell")
        label.new(bar_index, chart_bottom, "↑", color=color.red, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
        if close < entry_price
            short_wins := short_wins + 1
        in_short := false
        if countertrade and allow_long and can_trade
            strategy.entry("Buy", strategy.long)
            label.new(bar_index, chart_bottom, "↑", color=color.green, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
            label.new(bar_index, chart_bottom, "BUY", color=color.green, style=label.style_label_up, textcolor=color.white, size=size.large, yloc=yloc.price)
            in_long := true
            in_short := false
            long_trades := long_trades + 1
            entry_price := close

// Performance Stop-Loss
if perf_stop_condition
    if in_long
        strategy.close("Buy")
        label.new(bar_index, chart_bottom, "↓", color=color.green, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
        if close > entry_price
            long_wins := long_wins + 1
        in_long := false
        if countertrade and allow_short and can_trade
            strategy.entry("Sell", strategy.short)
            label.new(bar_index, chart_bottom, "↓", color=color.red, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
            label.new(bar_index, chart_bottom, "SELL", color=color.red, style=label.style_label_up, textcolor=color.white, size=size.large, yloc=yloc.price)
            in_short := true
            in_long := false
            short_trades := short_trades + 1
            entry_price := close
    if in_short
        strategy.close("Sell")
        label.new(bar_index, chart_bottom, "↑", color=color.red, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
        if close < entry_price
            short_wins := short_wins + 1
        in_short := false
        if countertrade and allow_long and can_trade
            strategy.entry("Buy", strategy.long)
            label.new(bar_index, chart_bottom, "↑", color=color.green, style=label.style_label_up, textcolor=color.white, size=size.normal, yloc=yloc.price)
            label.new(bar_index, chart_bottom, "BUY", color=color.green, style=label.style_label_up, textcolor=color.white, size=size.large, yloc=yloc.price)
            in_long := true
            in_short := false
            long_trades := long_trades + 1
            entry_price := close

// Warn if Equity is Negative
if not can_trade and (buy_signal or sell_signal)
    label.new(bar_index, close, "No Equity", color=color.yellow, style=label.style_label_center, textcolor=color.black, size=size.tiny)

// Background Coloring (Global Scope)
bgcolor(color_background ? (in_long ? color.new(color.green, 90) : in_short ? color.new(color.red, 90) : na) : na)