
Strategi harga relatif adalah strategi perdagangan kuantitatif yang didasarkan pada abnormalitas volume transaksi dan fluktuasi harga. Strategi ini menilai apakah volume transaksi abnormal dengan membandingkan hubungan volume transaksi saat ini dengan volume transaksi rata-rata historis; dan, dalam kombinasi dengan rentang amplitudo rata-rata nyata, menentukan apakah harga berada dalam rentang yang relatif stabil.
Logika inti dari strategi harga relatif didasarkan pada dua indikator, yaitu volume perdagangan relatif dan rentang fluktuasi harga.
Pertama, kita menghitung rata-rata bergerak sederhana dari volume transaksi dalam 20 siklus terakhir, sebagai volume transaksi rata-rata historis. Kemudian kita mengatur parameter perkalian (misalnya 1,5 kali lipat), yang kita anggap sebagai volume transaksi yang tidak normal, yaitu ketika volume transaksi saat ini lebih besar dari volume transaksi rata-rata 1,5 kali lipat.
Kedua, kita menghitung rata-rata true amplitude ((ATR) dari 14 siklus terakhir sebagai ukuran dari pergerakan harga. Selain itu kita juga menghitung standard deviation dari rata-rata amplitude. Jika true amplitude saat ini berada di antara nilai rata-rata positif dan negatif satu standar deviasi, kita menganggap pergerakan harga berada dalam kisaran yang relatif stabil.
Ketika kedua kondisi di atas terpenuhi secara bersamaan, maka sinyal melakukan lebih banyak, membuka posisi melakukan lebih banyak. Dalam proses memegang posisi, ATR dikurangi dua kali lipat sebagai stop loss dengan titik terendah maksimum, ATR dikurangi dua kali lipat sebagai stop loss dengan titik tertinggi maksimum.
Keuntungan terbesar dari strategi harga relatif adalah menangkap tren harga yang dibawa oleh volume transaksi yang tidak biasa. Ketika volume transaksi melonjak, ini mewakili perubahan sikap para peserta pasar, yang sering menandakan terobosan harga dan pembentukan tren baru. Strategi ini dapat secara efektif menentukan kapan volume transaksi yang tidak biasa terjadi dengan membandingkan hubungan volume transaksi dengan nilai rata-rata historis.
Di sisi lain, strategi ini juga mempertimbangkan volatilitas harga, sehingga sinyal terjadi pada saat harga relatif stabil. Ini menghindari risiko kerugian besar yang disebabkan oleh mengejar tinggi pada saat fluktuasi tajam. Ini juga meningkatkan peluang untuk mendapatkan keuntungan, karena tren biasanya mulai pecah setelah relatif stabil.
Risiko terbesar dari strategi ini adalah bahwa indikator volume perdagangan tidak dapat 100 persen menentukan tren baru, lonjakan volume perdagangan mungkin merupakan false breakout, dan harga akan berbalik dengan cepat. Dalam hal ini, strategi vrfs mengalami kerugian yang lebih besar.
Untuk mengurangi kerugian, dapat disesuaikan dengan parameter yang lebih tinggi dari jumlah transaksi yang relatif, menetapkan standar yang lebih ketat untuk menilai volume transaksi yang tidak normal. Atau menambahkan indikator penilaian lainnya, seperti menambahkan analisis volume transaksi, untuk menilai apakah pertumbuhan volume transaksi sesuai dengan jumlah transaksi.
Strategi ini dapat dioptimalkan dalam beberapa hal:
Menambahkan penilaian indikator lain, seperti kenaikan dan penurunan, volume transaksi, dan lain-lain, membuat sinyal volume transaksi yang tidak normal lebih andal.
Parameter ATR dapat dioptimalkan untuk berbagai saham, lebih akurat menentukan rentang harga stabil.
Menambahkan algoritma pembelajaran mesin untuk menilai secara positif ketidaksetaraan volume transaksi, bukan hanya membandingkan dengan rata-rata historis.
Prediksi pergerakan harga berdasarkan model pembelajaran mendalam, bukan hanya berdasarkan ATR historis.
Strategi harga relatif dengan menangkap volume transaksi yang tidak normal sebagai sinyal karakteristik, dikombinasikan dengan penilaian stabilitas harga untuk mengirimkan sinyal perdagangan. Strategi ini sederhana dan praktis, lebih efektif dalam melacak volume perdagangan saham yang tidak normal. Namun, ada risiko tertentu dari sinyal palsu, perlu lebih mengoptimalkan indikator untuk meningkatkan penilaian.
/*backtest
start: 2022-12-21 00:00:00
end: 2023-12-27 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("[KL] Relative Volume + ATR Strategy",overlay=true,pyramiding=1)
ENUM_LONG = "Long"
// Timeframe {
backtest_timeframe_start = input(defval = timestamp("01 Apr 2016 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
// }
len_volat = input(14,title="Length of ATR to determine volatility")
ATR_volat = atr(len_volat)
avg_ATR_volat = sma(ATR_volat, len_volat)
std_ATR_volat = stdev(ATR_volat, len_volat)
// }
// 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))
// }
// Signals for entry {
_avg_vol = sma(volume,input(20, title="SMA(volume) length (for relative comparison)"))
_relative_vol = _avg_vol * input(1.5,title="Multiple of avg vol to consider relative volume as being high",type=input.float)
__lowerOfOpenClose = min(open,close)
_wickRatio_lower = (__lowerOfOpenClose - low) / (high - low)
entry_signal1 = volume > _relative_vol
entry_signal2 = ATR_volat < avg_ATR_volat + std_ATR_volat and ATR_volat > avg_ATR_volat - std_ATR_volat
// }
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 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: // placed before entry, will re-enter if stopped out
exit_msg = close <= strategy.position_avg_price ? "stop loss" : "take profit"
if strategy.position_size > 0 and TSL_source <= stop_loss_price
strategy.close(ENUM_LONG, comment=exit_msg)
// ENTRY :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
if entry_signal1 and entry_signal2// and entry_signal3
entry_msg = strategy.position_size > 0 ? "adding" : "initial"
strategy.entry(ENUM_LONG, strategy.long, comment=entry_msg)
// CLEAN UP:
if strategy.position_size == 0
stop_loss_price := float(0)