Strategi ini menggunakan pengujian hipotesis untuk menentukan apakah ATR menyimpang dari nilai rata-ratanya. Dikombinasikan dengan prediksi tren harga, ia menerapkan strategi pembalikan rata-rata berdasarkan ATR. Penyimpangan signifikan dari ATR menunjukkan potensi volatilitas abnormal di pasar. Jika tren harga diprediksi akan naik, posisi panjang dapat didirikan.
Pengujian Hipotesis
Melakukan uji t dua sampel antara periode ATR cepat (atr_fast) dan periode ATR lambat (atr_slow).
Jika statistik uji melebihi ambang (interval keandalan yang ditentukan oleh reliability_factor), tolak hipotesis nol, yaitu ATR cepat dianggap menyimpang secara signifikan dari ATR lambat.
Prediksi Tren Harga
Rata-rata bergerak laba logaritma dihitung sebagai tingkat drift yang diharapkan (drift).
Jika drift meningkat, tren saat ini dinilai bullish.
Entry dan Stop Loss Exit
Pergi panjang ketika ATR cepat dan lambat berbeda secara signifikan dan tren bullish.
Terus-menerus menyesuaikan stop loss menggunakan ATR. Posisi keluar ketika harga pecah di bawah stop loss.
Menggunakan pengujian hipotesis untuk menentukan penyimpangan ATR lebih ilmiah dan adaptif.
Menggabungkan dengan prediksi tren harga menghindari perdagangan yang salah berdasarkan penyimpangan ATR saja.
Menyesuaikan stop loss secara terus menerus mengelola risiko penurunan.
Tidak mampu menghentikan kerugian ketika harga jatuh.
Prediksi tren yang salah dapat mengakibatkan pembelian di bagian atas.
Pengaturan parameter yang tidak benar dapat melewatkan entri yang benar atau menambahkan perdagangan yang tidak perlu.
Pertimbangkan untuk menambahkan indikator lain untuk konfirmasi multifaktor untuk menghindari kesalahan.
Uji kombinasi parameter ATR yang berbeda untuk menemukan nilai yang lebih stabil.
Tambahkan kriteria tentang terobosan tingkat harga kunci untuk menghindari terobosan palsu.
Logika keseluruhan strategi ini jelas. Menggunakan pengujian hipotesis untuk mendeteksi volatilitas abnormal adalah wajar. Namun, penyimpangan ATR saja tidak cukup untuk menentukan tren. Lebih banyak faktor konfirmasi diperlukan untuk meningkatkan akurasi. Aturan stop loss dapat diandalkan tetapi tidak efektif terhadap kecelakaan gaya tebing. Perbaikan di masa depan dapat dilakukan di bidang seperti kriteria masuk, pemilihan parameter, pengoptimalan stop loss.
/*backtest start: 2022-10-16 00:00:00 end: 2023-10-16 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © DojiEmoji //@version=5 strategy("Mean Reversion (ATR) Strategy v2 [KL] ", overlay=true, pyramiding=1) var string ENUM_LONG = "Long" var string GROUP_TEST = "Hypothesis testing" var string GROUP_TSL = "Stop loss" var string GROUP_TREND = "Trend prediction" backtest_timeframe_start = input(defval=timestamp("01 Apr 2000 13:30 +0000"), title="Backtest Start Time") within_timeframe = true // TSL: calculate the stop loss price. { ATR_TSL = ta.atr(input(14, title="Length of ATR for trailing stop loss", group=GROUP_TSL)) * input(2.0, title="ATR Multiplier for trailing stop loss", group=GROUP_TSL) TSL_source = low TSL_line_color = color.green TSL_transp = 100 var stop_loss_price = float(0) if strategy.position_size == 0 or not within_timeframe TSL_line_color := color.black stop_loss_price := TSL_source - ATR_TSL else if strategy.position_size > 0 stop_loss_price := math.max(stop_loss_price, TSL_source - ATR_TSL) TSL_transp := 0 plot(stop_loss_price, color=color.new(TSL_line_color, TSL_transp)) // } end of "TSL" block // Entry variables { // ATR diversion test via Hypothesis testing (2-tailed): // H0 : atr_fast equals atr_slow // Ha : reject H0 if z_stat is above critical value, say reliability factor of 1.96 for a 95% confidence interval len_fast = input(14,title="Length of ATR (fast) for diversion test", group=GROUP_TEST) atr_fast = ta.atr(len_fast) std_error = ta.stdev(ta.tr, len_fast) / math.pow(len_fast, 0.5) // Standard Error (SE) = std / sq root(sample size) atr_slow = ta.atr(input(28,title="Length of ATR (slow) for diversion test", group=GROUP_TEST)) test_stat = (atr_fast - atr_slow) / std_error reject_H0 = math.abs(test_stat) > input.float(1.645,title="Reliability factor", tooltip="Strategy uses 2-tailed test; Confidence Interval = Point Estimate (avg ATR) +/- Reliability Factor x Standard Error; i.e use 1.645 for a 90% confidence interval", group=GROUP_TEST) // main entry signal, subject to confirmation(s), gets passed onto the next bar var _signal_diverted_ATR = false if not _signal_diverted_ATR _signal_diverted_ATR := reject_H0 // confirmation: trend prediction; based on expected lognormal returns _prcntge_chng = math.log(close / close[1]) // Expected return (drift) = average percentage change + half variance over the lookback period len_drift = input(14, title="Length of drift", group=GROUP_TREND) _drift = ta.sma(_prcntge_chng, len_drift) - math.pow(ta.stdev(_prcntge_chng, len_drift), 2) * 0.5 _signal_uptrend = _drift > _drift[1] entry_signal_all = _signal_diverted_ATR and _signal_uptrend // main signal + confirmations // } end of "Entry variables" block // MAIN { // Update the stop limit if strategy holds a position if strategy.position_size > 0 and ta.change(stop_loss_price) strategy.exit(ENUM_LONG, comment="sl", stop=stop_loss_price) // Entry if within_timeframe and entry_signal_all strategy.entry(ENUM_LONG, strategy.long, comment=strategy.position_size > 0 ? "adding" : "initial") // Alerts _atr = ta.atr(14) alert_helper(msg) => prefix = "[" + syminfo.root + "] " suffix = "(P=" + str.tostring(close, "#.##") + "; atr=" + str.tostring(_atr, "#.##") + ")" alert(str.tostring(prefix) + str.tostring(msg) + str.tostring(suffix), alert.freq_once_per_bar) if strategy.position_size > 0 and ta.change(strategy.position_size) if strategy.position_size > strategy.position_size[1] alert_helper("BUY") else if strategy.position_size < strategy.position_size[1] alert_helper("SELL") // Clean up - set the variables back to default values once no longer in use if strategy.position_size == 0 stop_loss_price := float(0) if ta.change(strategy.position_size) _signal_diverted_ATR := false // } end of MAIN block