Strategi Trend ATR Reversasi Rata-rata

Penulis:ChaoZhang, Tanggal: 2023-09-21 11:42:06
Tag:

Gambaran umum

Strategi ini memanfaatkan volatilitas harga tinggi dan rendah untuk menentukan waktu masuk dan keluar dari posisi.

Logika Strategi

  1. Gunakan indikator ATR untuk mengukur volatilitas harga. Hitung ATR selama 20 periode terakhir dan dapatkan rata-rata bergerak dan standar deviasinya. Jika nilai ATR saat ini melebihi rata-rata ditambah satu standar deviasi, volatilitas harga dianggap tinggi.

  2. Gunakan rasio perubahan harga logaritma urutan pertama untuk menentukan tren harga. Hitung rasio perubahan harga logaritma dekat selama 20 periode terakhir, dapatkan rata-rata bergeraknya. Jika rasio perubahan saat ini melebihi rata-rata selama 3 hari berturut-turut dan positif, harga dianggap naik.

  3. Ketika volatilitas harga tinggi dan harga menunjukkan tren naik, pergi panjang. Ketika harga menarik kembali dan stop loss dipicu, posisi tutup. Harga stop loss disesuaikan secara dinamis untuk tetap di bawah harga terendah dikurangi 2 kali ATR.

Analisis Keuntungan

  1. Menggunakan volatilitas harga dan tren untuk menentukan jangka panjang/pendek, menghindari over-trading di berbagai pasar.

  2. Stop loss dinamis menghindari kerugian yang berlebihan dari stop yang terlalu luas.

  3. Backtest menunjukkan pengembalian tahunan sebesar 159% selama 2015-2021, jauh melebihi 120% dari buy & hold.

Analisis Risiko

  1. Parameter ATR yang terlalu agresif dapat mengakibatkan terlalu sedikit kesempatan masuk.

  2. Indikator tren dapat menghasilkan sinyal palsu yang bertentangan dengan tren aktual.

  3. Periode backtest hanya 6 tahun. perlu sampel yang lebih besar dan pengujian ketahanan untuk menghindari overfit.

  4. Tidak dapat menilai kinerja dalam kondisi ekstrim seperti flash crash.

Arahan Optimasi

  1. Tambahkan lebih banyak indikator konfirmasi tren seperti MACD, KDJ untuk meningkatkan akurasi tren.

  2. Penyesuaian parameter ATR secara adaptif berdasarkan produk dan rezim pasar yang berbeda untuk mengoptimalkan indikator volatilitas.

  3. Tambahkan logika breakout dan faktor trend akselerasi untuk mengukur pada breakouts.

  4. Uji jenis stop loss yang berbeda seperti persentase, volatility stop pada kinerja.

  5. Evaluasi pada metrik seperti frekuensi perdagangan, stabilitas kurva, penarikan maksimum untuk memastikan ketahanan.

Ringkasan

Strategi ini menggabungkan keuntungan dari mengukur volatilitas dan tren untuk menentukan kemungkinan titik pembalikan untuk masuk pada volatilitas yang diperkuat, dan menggunakan berhenti dinamis untuk mengendalikan risiko. Backtest menunjukkan alpha yang layak dihasilkan. Tetapi sampel 6 tahun terbatas, parameter kunci perlu penyesuaian khusus pasar, dan lebih banyak faktor konfirmasi diperlukan untuk mengurangi sinyal palsu. Pemeriksaan ketahanan yang komprehensif juga diperlukan sebelum diterapkan untuk perdagangan langsung. Secara keseluruhan ini memberikan gagasan tentang rata-rata pembalikan pada volatilitas tetapi masih membutuhkan penyempurnaan dan verifikasi kuantitatif yang ketat untuk menjadi strategi kuantitatif yang kuat.


/*backtest
start: 2022-09-14 00:00:00
end: 2023-09-20 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 (kevinhhl)

//@version=4
strategy("Mean Reversion (ATR) Strategy [KL]",overlay=true,pyramiding=1)
ENUM_LONG = "Long"

// Timeframe {
backtest_timeframe_start = input(defval = timestamp("01 Apr 2000 13:30 +0000"), title = "Backtest Start Time", type = input.time)
USE_ENDTIME = input(false,title="Define backtest end-time (If false, will test up to most recent candle)")
backtest_timeframe_end = input(defval = timestamp("01 May 2021 19:30 +0000"), title = "Backtest End Time (if checked above)", type = input.time)
within_timeframe = true
// }

// Trailing stop loss {
ATR_X2_TSL = atr(input(14,title="Length of ATR for trailing stop loss")) * input(2.0,title="ATR Multiplier for trailing stop loss",type=input.float)
TSL_source = low
var stop_loss_price = float(0)
TSL_line_color = color.green, TSL_transp = 100
if strategy.position_size == 0 or not within_timeframe
    TSL_line_color := color.black
    stop_loss_price := TSL_source - ATR_X2_TSL 
else if strategy.position_size > 0
    stop_loss_price := max(stop_loss_price, TSL_source - ATR_X2_TSL)
    TSL_transp := 0
plot(stop_loss_price, color=color.new(TSL_line_color, TSL_transp))
// }

// Variables for confirmations of entry {
_len_volat = input(20,title="Length of ATR to determine volatility")
_ATR_volat = atr(_len_volat)
_avg_atr = sma(_ATR_volat, _len_volat)
_std_volat = stdev(_ATR_volat,_len_volat)
signal_diverted_ATR = _ATR_volat > (_avg_atr + _std_volat) or _ATR_volat < (_avg_atr - _std_volat)

_len_drift = input(20,title="Length of Drift")//default set to const: _len_vol's default value
_prcntge_chng = log(close/close[1])
_drift = sma(_prcntge_chng, _len_drift) - pow(stdev(_prcntge_chng, _len_drift),2)*0.5
_chg_drift = _drift/_drift[1]-1
signal_uptrend = (_drift > _drift[1] and _drift > _drift[2]) or _drift > 0

entry_signal_all = signal_diverted_ATR and signal_uptrend
// }

alert_per_bar(msg)=>
    prefix = "[" + syminfo.root + "] "
    suffix = "(P=" + tostring(close) + "; atr=" + tostring(_ATR_volat) + ")"
    alert(tostring(prefix) + tostring(msg) + tostring(suffix), alert.freq_once_per_bar)

// MAIN {
if within_timeframe

    if strategy.position_size > 0 and strategy.position_size[1] > 0 and (stop_loss_price/stop_loss_price[1]-1) > 0.005
        alert_per_bar("TSL raised to " + tostring(stop_loss_price))

    // EXIT:
	if strategy.position_size > 0 and TSL_source <= stop_loss_price
	    exit_msg = close <= strategy.position_avg_price ? "stop loss" : "take profit"
        strategy.close(ENUM_LONG, comment=exit_msg)
    // ENTRY:
    else if entry_signal_all and (strategy.position_size == 0 or (strategy.position_size > 0 and close > stop_loss_price))
		entry_msg = strategy.position_size > 0 ? "adding" : "initial"
		strategy.entry(ENUM_LONG, strategy.long, comment=entry_msg)

if strategy.position_size == 0
    stop_loss_price := float(0)
// }


Lebih banyak