Strategi perdagangan momentum yang disesuaikan dengan risiko dinamis

Penulis:ChaoZhang, Tanggal: 2024-01-24 11:13:39
Tag:

img

Gambaran umum

Strategi perdagangan berbasis aturan yang unik ini berada dalam kategori tren berikut. Ini menggunakan seri harga yang dinormalisasi yang diubah dari harga ticker mentah menjadi sinyal perdagangan gernerate. Ukuran posisi canggih dan teknik manajemen risiko, yang biasanya disediakan untuk manajemen portofolio institusional, digunakan dalam strategi ini - teknologi penentuan posisi dan pengendalian risiko yang terbukti digunakan oleh penasihat keuangan seperti Penasihat Perdagangan Komoditas dan dana berjangka yang dikelola.

Mekanika Strategi

harga normalisasi adalah rangkaian pengembalian harian terakumulasi yang disesuaikan dengan volatilitas. Pencarian balik penyesuaian volatilitas harian ditentukan oleh pengguna. Rata-rata bergerak Hull dari harga normalisasi digunakan sebagai indikator tren utama. Periode pencarian balik HMA juga ditentukan oleh pengguna, dengan periode default 100 hari untuk sinyal responsif tanpa memicu over-trading.

Perdagangan inti adalah sederhana, panjang ketika harga normal crossover HMA, pendek ketika crossunder HMA.

Ukuran posisi disesuaikan secara dinamis berdasarkan volatilitas harga baru-baru ini dan target risiko tahunan yang ditentukan pengguna. Posisi ditimbang risiko, ukuran yang lebih besar dengan volatilitas yang lebih rendah dan lebih kecil dengan volatilitas yang lebih tinggi. Volatilitas baru-baru ini adalah penyimpangan standar pengembalian selama 14 periode terakhir, kemudian diekstrapolasi ke volatilitas tahunan sebagai pengembalian yang diharapkan. Target risiko tahunan digunakan sebagai referensi untuk ukuran posisi yang disesuaikan dengan volatilitas. Target default adalah 10% dari total modal. Modal awal harus ditetapkan sebagai kerugian maksimum per perdagangan. Leverage maksimum memungkinkan untuk mencapai target risiko jika volatilitas alami yang mendasari tidak cukup, dan mengurangi volatilitas yang terlalu rendah.

Hard stop didasarkan pada pengganda rentang rata-rata harga baru-baru ini, dapat dikonfigurasi pengguna.

Keuntungan

  • Harga normal mengurangi sinyal palsu
  • Kontrol ukuran posisi dinamis berisiko efektif
  • Hentian keras mencegah kerugian kabur
  • Tren sederhana mengikuti logika transparansi

Risiko

  • Masalah keterlambatan dengan rata-rata bergerak Hull
  • Membatas keuntungan sambil menurunkan risiko melalui ukuran posisi yang disesuaikan dengan volatilitas
  • Menutup terlalu erat rentan terhadap paku

Langkah-langkah pengendalian risiko termasuk pilihan rata-rata bergerak alternatif, penyesuaian target risiko.

Peningkatan

  • Efektivitas uji jenis rata-rata bergerak lainnya
  • Mengoptimalkan parameter rata-rata bergerak
  • Coba varian panjang atau pendek saja
  • Jangkauan kerugian stop tune halus
  • Percobaan dengan mekanisme stop loss lainnya

Kesimpulan

Strategi ini mengintegrasikan berbagai teknik seperti normalisasi, penyesuaian posisi dinamis, hard stop untuk mengendalikan risiko. Perdagangan didasarkan pada aturan tren sederhana. Parameter dapat disesuaikan dengan preferensi pribadi dan rezim pasar.


/*backtest
start: 2023-01-17 00:00:00
end: 2024-01-23 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/
// © Crunchster1

//@version=5
strategy(title="Crunchster's Normalised Trend Strategy", shorttitle="Normalised Trend Strategy", overlay=false )

// Inputs and Parameters
src = input(close, 'Source', group='Strategy Settings')
length = input.int(title="Lookback period for price normalisation filter", defval=14, minval=2, group='Strategy Settings', tooltip='This sets the lookback period for the volatility adjustment of returns, which is used to transform the price series into the "real price"')
hlength = input.int(title="Lookback period for Hull Moving Average", defval=100, minval=2, group='Strategy Settings')
offset = input.int(title="HMA Offset", defval=0, minval=0, group='Strategy Settings')
long = input(true, 'Long', inline='08', group='Strategy Settings')
short = input(true, 'Short', inline='08', group='Strategy Settings', tooltip='Toggle long/short strategy on/off')

stopMultiple = input.float(1, 'Stop multiple', step=0.25, group='Risk Management Settings', tooltip='Multiple for ATR, setting hard stop loss from entry price')
lev = input.float(1, 'Max Leverage', step=0.5, group='Risk Management Settings', tooltip='Max leverage sets maximum allowable leverage of total capital (initial capital + any net profit), capping maximum volatility adjusted position size')
riskT = input.float(10, maxval=75, title='Annualised Volatility Target %', group='Risk Management Settings', tooltip='Specify annual risk target, used to determine volatility adjusted position size. Annualised daily volatility is referenced to this value and position size adjusted accordingly')
comp = input(false, 'Compounding', inline='09', group='Risk Management Settings')
Comppct = input.float(50, '%', step=5, inline='09', group='Risk Management Settings', tooltip='Toggle compounding of profit, and set % of profit to compound')

// Backtesting period
FromDay = input.int(defval=1, title='From Day', minval=1, maxval=31, inline='04', group='Backtest range')
FromMonth = input.int(defval=1, title='From Mon', minval=1, maxval=12, inline='04', group='Backtest range')
FromYear = input.int(defval=2018, title='From Yr', minval=1900, inline='04', group='Backtest range', tooltip='Set start of backtesting period')
ToDay = input.int(defval=1, title='To Day', minval=1, maxval=31, inline='05', group='Backtest range')
ToMonth = input.int(defval=1, title='To Mon', minval=1, maxval=12, inline='05', group='Backtest range')
ToYear = input.int(defval=9999, title='To Yr', minval=1900, inline='05', group='Backtest range', tooltip='Set end of backtesting period')

start = timestamp(FromYear, FromMonth, FromDay, 00, 00)
finish = timestamp(ToYear, ToMonth, ToDay, 23, 59)
window = true

// Normalised returns calculation
nRet = (src - src[1]) / ta.stdev((src - src[1]), length)

nPrice = ta.cum(nRet)

//Hull Moving Average - using normalised price series
fHMA = ta.wma(2 * ta.wma(nPrice[offset], hlength / 2) - ta.wma(nPrice[offset], hlength), math.round(math.sqrt(hlength)))

//Risk Management formulae
strategy.initial_capital = 50000
tr = math.max(high - low, math.abs(high - close), math.abs(low - close)) //True range
stopL = ta.sma(tr, 14) //Average true range
stdev = ta.stdev(close-close[1], 14) //volatility of recent returns
maxcapital = strategy.initial_capital+strategy.netprofit //Maximum capital available to invest - initial capital net of profit
annvol = 100*math.sqrt(365)*stdev/close //converts recent volatility of returns into annualised volatility of returns - assumes daily timeframe

risk = 1.1
if comp
    risk := (strategy.initial_capital+(Comppct*strategy.netprofit/100))//adjust investment capital to include compounding
else
    risk := strategy.initial_capital

shares = (risk * (riskT/annvol)) / close //calculates volatility adjusted position size, dependent on user specified annualised risk target
if ((shares*close) > lev*maxcapital) //ensures position size does not exceed available capital multiplied by user specified maximum leverage
    shares := lev*maxcapital/close

//To set the price at the entry point of trade
Posopen() =>
    math.abs(strategy.position_size[1]) <= 0 and math.abs(strategy.position_size) > 0

var float openN = na
if Posopen()
    openN := stopL

// Strategy Rules
if long
    longCondition = ta.crossover(nPrice, fHMA) and window
    exitlong = ta.crossunder(nPrice, fHMA)
    if (longCondition)
        strategy.entry('Go Long!', strategy.long, qty=shares)
    if strategy.position_size > 0    
        strategy.exit('Stop Long', from_entry = 'Go Long!', stop=(strategy.opentrades.entry_price(0) - (openN * stopMultiple)))
    if (exitlong)
        strategy.close('Go Long!', immediately = true)

if short
    shortCondition = ta.crossunder(nPrice, fHMA) and window
    exitshort = ta.crossover(nPrice, fHMA)
    if (shortCondition)
        strategy.entry('Go Short!', strategy.short, qty=shares)
    if strategy.position_size < 0   
        strategy.exit('Stop Short', from_entry = 'Go Short!', stop=(strategy.opentrades.entry_price(0) + (openN * stopMultiple)))
    if (exitshort)
        strategy.close('Go Short!', immediately = true)

// Visuals of trend and direction
plot(nPrice, title='Real Price', color=color.black)

MAColor = fHMA > fHMA[3] ? #00ff00 : #ff0000
MA1 = plot(fHMA, title='Hull MA', color=MAColor)
MA2 = plot(fHMA[3], title='Hull MA Offset', color=MAColor)
fill(MA1, MA2, title='Band Filler', color=MAColor)

Lebih banyak