Filter tren multidimensi

ADX DI CCI RSI ATR VOLUME
Tanggal Pembuatan: 2025-09-08 13:49:10 Akhirnya memodifikasi: 2025-09-08 13:49:10
menyalin: 0 Jumlah klik: 255
2
fokus pada
319
Pengikut

Filter tren multidimensi Filter tren multidimensi

Mekanisme penyaringan enam kali, bukan kombinasi indikator teknis biasa

Dari ribuan strategi, sebagian besar adalah kombinasi sederhana dari satu indikator. Strategi ini secara langsung mengintegrasikan kondisi penyaringan enam dimensi ADX, DI, CCI, RSI, ATR, dan volume transaksi. Bukan untuk bermain-main, tetapi untuk menyelesaikan masalah sinyal palsu dari satu indikator. Data retrospeksi menunjukkan peningkatan kualitas sinyal yang jelas setelah penyaringan berulang, tetapi dengan biaya penurunan frekuensi sinyal sekitar 40%.

ADX+DI: Validasi ganda kekuatan dan arah tren

Strategi tradisional melihat kekuatan tren atau arah tren, jarang ada yang menggabungkan ADX dan DI secara sistematis. Desain di sini cerdas: DI + / DI-cross menentukan arah, ADX threshold ((default 25) memfilter tren lemah.

CCI dan Moving Average

Panjang CCI ditetapkan menjadi 20 siklus, dengan 14 siklus rata-rata bergerak. Kombinasi parameter ini dioptimalkan, dapat menemukan titik keseimbangan antara sensitivitas dan stabilitas. Mendukung 5 jenis rata-rata bergerak, tetapi SMA dan EMA efek yang paling stabil dalam pertempuran nyata.

RSI Perbatasan Filter: Hindari Perangkap Overbuying dan Overselling

Filter RSI disetel pada batas 3070, bukan untuk menyalin, tetapi untuk menghindari terobosan palsu dalam situasi ekstrem. Perbaikan hanya diizinkan ketika RSI berada di bawah 30, dan kosong di atas 70. Desain ini membantu strategi menghindari sejumlah besar sinyal palsu pasar yang bergoyang, terutama pada tahap penyusunan horizontal.

ATR dan Volume Transaksi: Asuransi Ganda untuk Aktivitas Pasar

Filter ATR memastikan bahwa pasar memiliki volatilitas yang cukup, dengan ambang batas default 1.0 . Filter volume transaksi diperlukan 1,5 kali lipat dari rata-rata volume transaksi saat ini lebih dari 20 siklus . Kedua kondisi ini bekerja bersama-sama, memfilter banyak peluang perdagangan berkualitas rendah . Data menunjukkan bahwa sinyal yang memenuhi kedua kondisi ini, rata-rata tingkat pengembalian posisi lebih tinggi dari yang tidak terpenuhi 35%.

Tiga Mekanisme Keluar: Fleksibilitas dalam Beradaptasi dengan Perbedaan Kondisi Pasar

Ada tiga mekanisme yang dapat digunakan secara terpisah atau dalam kombinasi. Moving Average Output, ADX Change Stop Loss, dan Performance Stop Loss. Moving Average Output cocok untuk pasar tren, ADX Change Stop Loss cocok untuk konversi tren, dan Performance Stop Loss adalah asuransi terakhir.

Fitur Reverse Trading: Mencari Peluang dari Kerugian

Fungsi Countertrade memungkinkan untuk membuka posisi terbalik segera setelah posisi kosong. Ini bukan perjudian, tetapi berdasarkan logika indikator teknis yang terbalik. Namun, perhatikan bahwa fitur ini dapat menyebabkan kerugian berturut-turut di pasar tren yang kuat, dan disarankan hanya untuk digunakan di pasar yang bergoyang atau di akhir tren.

Tips Risiko dan Skenario Aplikasi

Strategi ini berkinerja baik di pasar dengan tren yang jelas, tetapi sinyal jarang terjadi saat bergejolak horizontal. Meskipun filter ganda meningkatkan kualitas sinyal, tetapi juga meningkatkan risiko kehilangan peluang.

Kode Sumber Strategi
/*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)