Strategi Waktu Pasar yang Difilter Volatilitas

Penulis:ChaoZhang, Tanggal: 2024-01-15 12:27:47
Tag:

img

Gambaran umum

Strategi ini menerapkan strategi beli dan tahan yang ditingkatkan dengan menambahkan filter berdasarkan volatilitas historis. Filter menutup posisi panjang selama rezim pasar volatilitas tinggi dan memasuki kembali posisi panjang ketika volatilitas rendah, untuk mengurangi penarikan maksimum.

Logika Strategi

  1. Menghitung volatilitas historis SPY selama 100 hari terakhir
  2. Jika volatilitas saat ini lebih tinggi dari persentil ke-95 dari volatilitas 100 hari terakhir, saringkan hari perdagangan itu, tutup posisi panjang
  3. Jika volatilitas berada di bawah 95 persenil, masukkan posisi panjang

Analisis Keuntungan

Dibandingkan dengan pembelian sederhana dan memegang tanpa filter, strategi ini meningkatkan pengembalian tahunan selama periode backtest 28 tahun (7,95% vs 9,92%) dan secara signifikan mengurangi penarikan maksimum (50,79% vs 31,57%).

Analisis Risiko

Risiko utama berasal dari akurasi metodologi perhitungan volatilitas dan penyesuaian parameter filter. Jika perhitungan volatilitas tidak akurat, filter akan gagal. Jika parameter filter disetel dengan buruk (terlalu konservatif atau agresif), itu dapat berdampak negatif pada pengembalian strategi. Juga, kinerja masa lalu tidak menjamin hasil masa depan.

Arahan Optimasi

Pertimbangkan untuk menambahkan indikator konfirmasi lain sebagai filter tambahan, seperti rata-rata bergerak jangka panjang, indeks ADX dll. Penyesuaian parameter juga penting, seperti pengujian periode lookback yang berbeda, ambang penyaringan dll. Teknik pembelajaran mesin & analisis deret waktu juga dapat digunakan untuk membangun dan mengoptimalkan model prediksi volatilitas.

Ringkasan

Strategi ini sangat meningkatkan pengembalian dan mengurangi penarikan maksimum dari strategi SPY buy & hold melalui filter volatilitas sederhana. Ini menunjukkan pentingnya identifikasi rezim pasar dan alokasi aset.


/*backtest
start: 2023-01-08 00:00:00
end: 2024-01-14 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/
// 
// @author Sunil Halai
//
// This script has been created to demonstrate the effectiveness of using market regime filters in your trading strategy, and how they can improve your returns and lower your drawdowns
//
// This strategy adds a simple filter (The historical volatility filter, which can be found on my trading profile) to a traditional buy and hold strategy of the index SPY. There are other filters
// that could also be added included a long term moving average / percentile rank filter / ADX filter etc, to improve the returns further.
//
// The filter added closes our long position during periods of volatility that exceed the 95th percentile (or in the top 5% of volatile days)
//
// Have included the back test results since 1993 which is 28 years of data at the time of writing,  Comparing  buy and hold of the SPY (S&P 500), to improved by and hold offered here.
//
// Traditional buy and hold:
//
// Return per year:     7.95   % (ex Dividends)
// Total return :       851.1  %
// Max drawdown:        50.79  %
//
// 'Modified' buy and hold (this script):
//
// Return per year:     9.92    % (ex Dividends)
// Total return:        1412.16 %
// Max drawdown:        31.57   %
//
// Feel free to use some of the market filters in my trading profile to improve and refine your strategies further, or make a copy and play around with the code yourself. This is just 
// a simple example for demo purposes.
//

//@version=4
strategy(title = "Simple way to beat the market [STRATEGY]", shorttitle = "Beat The Market [STRATEGY]", overlay=true, initial_capital=100000, default_qty_type=strategy.percent_of_equity, currency="USD", default_qty_value=100)


upperExtreme = input(title = "Upper percentile filter (Do not trade above this number)", type = input.integer, defval = 95)
lookbackPeriod = input(title = "Lookback period", type = input.integer, defval = 100)

annual = 365
per = timeframe.isintraday or timeframe.isdaily and timeframe.multiplier == 1 ? 1 : 7
hv = lookbackPeriod * stdev(log(close / close[1]), 10) * sqrt(annual / per)

filtered = hv >= percentile_nearest_rank(hv, 100, upperExtreme)

if(not(filtered))
    strategy.entry("LONG", strategy.long)
else
    strategy.close("LONG")

Lebih banyak