Strategi pembalikan purata berdasarkan ATR

Penulis:ChaoZhang, Tarikh: 2023-10-17 16:27:44
Tag:

img

Ringkasan

Strategi ini menggunakan pengujian hipotesis untuk menentukan sama ada ATR menyimpang dari nilai purata. Digabungkan dengan ramalan trend harga, ia melaksanakan strategi pembalikan purata berdasarkan ATR. Penyimpangan yang ketara dari ATR menunjukkan potensi turun naik yang tidak normal di pasaran. Jika trend harga diramalkan menjadi bullish, kedudukan panjang boleh ditubuhkan.

Logika Strategi

  1. Ujian Hipotesis

    • Melakukan ujian t dua sampel antara tempoh ATR pantas (atr_fast) dan tempoh ATR perlahan (atr_slow). Hipotesis sifar H0 adalah bahawa tidak ada perbezaan yang ketara antara kedua-dua sampel.

    • Jika statistik ujian melebihi ambang (selang kebolehpercayaan yang ditentukan oleh faktor kebolehpercayaan), tolak hipotesis sifar, iaitu ATR cepat dianggap menyimpang secara ketara dari ATR perlahan.

  2. Ramalan Trend Harga

    • Purata bergerak pulangan logaritma dikira sebagai kadar drift yang dijangkakan (drift).

    • Jika drift meningkat, trend semasa dinilai sebagai bullish.

  3. Pendaftaran dan Pendaftaran Stop Loss

    • Pergi panjang apabila ATR yang cepat dan perlahan berbeza dengan ketara dan trend adalah bullish.

    • Terus menyesuaikan stop loss menggunakan ATR. Posisi keluar apabila harga pecah di bawah stop loss.

Analisis Kelebihan

  • Menggunakan ujian hipotesis untuk menentukan penyimpangan ATR lebih saintifik dan adaptif.

  • Menggabungkan dengan ramalan trend harga mengelakkan perdagangan yang salah berdasarkan penyimpangan ATR sahaja.

  • Penyesuaian stop loss terus menguruskan risiko penurunan.

Analisis Risiko

  • Tidak dapat menghentikan kerugian apabila harga jatuh.

  • Ramalan trend yang salah boleh mengakibatkan pembelian di bahagian atas.

  • Tetapan parameter yang tidak betul mungkin terlepas entri yang betul atau menambah perdagangan yang tidak perlu.

Cadangan Pengoptimuman

  • Pertimbangkan untuk menambah penunjuk lain untuk pengesahan pelbagai faktor untuk mengelakkan kesilapan.

  • Uji kombinasi parameter ATR yang berbeza untuk mencari nilai yang lebih stabil.

  • Tambah kriteria mengenai penembusan tahap harga utama untuk mengelakkan penembusan palsu.

Kesimpulan

Logik keseluruhan strategi ini jelas. Menggunakan ujian hipotesis untuk mengesan turun naik yang tidak normal adalah munasabah. Walau bagaimanapun, penyimpangan ATR sahaja tidak mencukupi untuk menentukan trend. Lebih banyak faktor pengesahan diperlukan untuk meningkatkan ketepatan. Peraturan stop loss boleh dipercayai tetapi tidak berkesan terhadap kemalangan gaya tebing. Penambahbaikan masa depan boleh dibuat dalam bidang seperti kriteria kemasukan, pemilihan parameter, pengoptimuman 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

Lebih lanjut