Zona Aksi ATR Reverse Order Quant Strategi

Penulis:ChaoZhang, Tanggal: 2023-11-24
Tag:

img

Gambaran umum

Ide utama dari strategi ini adalah untuk menggabungkan Zona Aksi dan indikator ATR untuk pergi panjang ketika ada salib emas dan pergi pendek ketika ada salib mati. Ini juga menetapkan harga stop loss dan take profit. Ketika sinyal pembalikan harga terjadi, itu akan membuka posisi terbalik untuk mencapai fungsi reverse order.

Prinsip-prinsip

  1. Gunakan EMA cepat dan EMA lambat untuk menghitung sinyal panjang dan pendek.
  2. Ketika tidak ada posisi, pergi panjang pada salib emas dan pergi pendek pada salib mati.
  3. Ketika sudah memiliki posisi, jika sinyal pembalikan terjadi, pertama akan menutup posisi saat ini, kemudian membuka posisi baru ke arah yang berlawanan.
  4. Menggunakan indikator ATR untuk menghitung harga stop loss dan mengambil profit.
  5. Ketika harga memasuki zona overbought atau oversold, harga stop loss akan disesuaikan dengan harga tertinggi atau terendah dari bar terakhir untuk menghindari terjebak.

Keuntungan

  1. Menggabungkan Zona Aksi dan ATR dapat membuka posisi di sepanjang tren selama tren dan mengatur stop loss dan mengambil keuntungan tepat waktu.
  2. Menerapkan fungsi reverse order dapat dengan cepat mengubah arah ketika harga berbalik, memanfaatkan fluktuasi harga dua arah untuk pengembalian yang lebih tinggi.
  3. Mekanisme stop loss ATR dapat secara efektif mengendalikan risiko stop loss tunggal dan mencapai tingkat kemenangan yang tinggi secara keseluruhan.
  4. Dikombinasikan dengan penilaian overbought dan oversold untuk menghindari terjebak oleh peristiwa tiba-tiba.

Risiko dan Solusi

  1. Perintah reverse dapat menyebabkan frekuensi transaksi yang berlebihan di pasar yang terikat rentang, meningkatkan biaya perdagangan dan kemungkinan stop loss.
    • Solusi: Meningkatkan periode pemegang minimum untuk mengurangi pembalikan di pasar yang terikat rentang.
  2. Perubahan nilai ATR dapat menyebabkan rentang stop loss terlalu besar atau terlalu kecil.
    • Solusi: Sesuaikan jarak stop loss sesuai dengan nilai ATR real-time.
  3. Pengaturan parameter yang tidak benar dapat menyebabkan frekuensi perdagangan yang terlalu tinggi atau efek sinyal yang buruk.
    • Solusi: Pilih kombinasi parameter yang wajar sesuai dengan varietas yang berbeda.

Arahan Optimasi

  1. Mengoptimalkan pengaturan parameter untuk menemukan kombinasi parameter terbaik.
  2. Tambahkan indikator teknis tambahan ke filter untuk meningkatkan kualitas sinyal.
  3. Tambahkan modul manajemen modal untuk menghubungkan ukuran posisi dengan total aset rekening.
  4. Tambahkan analisis jangka waktu silang untuk meningkatkan kinerja strategi dengan lebih banyak informasi.

Ringkasan

Strategi ini mengintegrasikan keuntungan dari zona aksi dan indikator ATR untuk mencapai perdagangan dua arah yang efisien. Mekanisme order terbalik dan stop loss ATR cerdas dapat memanfaatkan fluktuasi harga sepenuhnya. Mengoptimalkan pengaturan parameter dan menggabungkan lebih banyak indikator dapat lebih meningkatkan kinerja strategi. Strategi ini cocok untuk perdagangan dua arah frekuensi tinggi dan juga dapat berfungsi sebagai alat pengambilan keputusan tambahan.


/*backtest
start: 2023-10-24 00:00:00
end: 2023-11-23 00:00:00
period: 1h
basePeriod: 15m
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/
// © fenirlix

//@version=5
// Strategy parameter incl. position size, commission and initial capital
strategy("ACTIONZONE-ATR REVERSEORDER STRATEGY", "ACTIONZONEATR-REVERSEORDER", overlay=true
     )

// User Input Variable
fastMaInput     = input.int(12, "Fast MA Period", minval=2, step=1)
slowMaInput     = input.int(26, "Fast MA Period", minval=2, step=1)

atrLengthInput  = input.int(14, "ATR length", minval=2,step=1)
atrInnerMultInput = input.float(1, "atr inner multiplier", minval=0.1, step=0.1)
atrMidMultInput = input.float(2, "atr inner multiplier", minval=0.1, step=0.1) //***** MOST OF RISK MANAGEMENT LOGIC BASE ON THIS INPUT *****//
atrOuterMultInput = input.float(3, "atr inner multiplier", minval=0.1, step=0.1)

// Backtesting Date range
startYearInput      = input.int(2021, "Start Year", minval=1900, maxval=2100, step=1)
startMonthInput     = input.int(12, "Start Month", minval=1, maxval=12, step=1)
startDateInput      = input.int(1, "Start Day", minval=1, maxval=31, step=1)
setEndRangeInput    = input.bool(false, "Using Specific End Test Date") //Set specific End date or use present(end of candle) data
endYearInput        = input.int(2022, "End Year", minval=1900, maxval=2100, step=1)
endMonthInput       = input.int(1, "End Month", minval=1, maxval=12, step=1)
endDateInput        = input.int(31, "End Day", minval=1, maxval=31, step=1)

startDate = timestamp(syminfo.timezone, startYearInput, startMonthInput, startDateInput)
endDate = timestamp(syminfo.timezone, endYearInput, endMonthInput, endDateInput)
inDateRange = time >= startDate //Set backtest date range to present data
if setEndRangeInput
    inDateRange and time <= endDate //set backtest date range to specific date

// minimum position hold period (to get rid of false signal in sideway trend)
minHoldInput = input.int(8, 'Minimum position Hold Limit', minval=1, maxval=365, step=1) // Set Minimum Position Hold

var bool reverseToLong = false // Assign reverse order operator
var bool reverseToShort = false // Assign reverse order operator

// Indicator Declaration
fastEma = ta.ema(close, fastMaInput)
slowEma = ta.ema(close, slowMaInput)
atr = ta.atr(atrLengthInput)

// Declare trend of asset
isBullish = fastEma > slowEma
isBearish = fastEma <= slowEma

// Record position hold length, to limit minimum hold period(candle)
var int hold_length = 0
if strategy.opentrades > 0 or strategy.opentrades < 0
    hold_length := hold_length + 1
else
    hold_length := 0

// create permanent variable of stop price
var float longStopPrice = na
var float shortStopPrice = na
    
// Chart-Indicator COLOR declaration
REDBEAR     = color.new(color.red, 80)
GREENBULL   = color.new(color.green, 80)

greenLong = isBullish and close > fastEma
yellowLong = isBullish and close < fastEma
blueShort = isBearish and close > fastEma
redShort = isBearish and close < fastEma

// assign oversold, overbought condition(in this case, price over middle atr plus/minus fastEma)
overBand = high[1] > fastEma + (2*atr)
underBand = low[1] < fastEma - (2*atr)

// Strategy

// Main Entry Condition
goLong = isBullish and isBullish[1] == 0
goShort = isBearish and isBearish[1] == 0

inPosition = strategy.position_size != 0
minHoldPeriod = hold_length > minHoldInput ? true : false

// Entry Condition
if not inPosition and inDateRange and barstate.isconfirmed == true //compute after close of the bar to avoid repainting
    if goLong or reverseToLong // Long if longcondition or reverse order receive.
        strategy.entry('long', strategy.long)
        longStopPrice := fastEma - (atr * 2) // Set stop loss price
        reverseToLong := false // Reset reverse order status
    
    else if goShort or reverseToShort
        strategy.entry('short', strategy.short)
        shortStopPrice := fastEma + (atr * 2)
        reverseToShort := false
// Take profit and Set Higher Stop 
if inPosition and minHoldPeriod and barstate.isconfirmed == true // check if we're in position and pass minimum hold period, confirm no repainting
    if strategy.position_size > 0
        // if exit position by Sellcondition(which is the same as ShortCondition), Exit Long position and make Short order(by set reverse order to true)
        strategy.close('long', when=goShort, comment='exitLong(' + str.tostring(hold_length) + ')')
        reverseToShort := true
        if overBand //If overbought condition met, set Stop price to LAST LOW, and not reverse any position
            longStopPrice := low[1]
            reverseToShort := false
    else if strategy.position_size < 0
        strategy.close('short', when=goLong, comment='exitShort(' + str.tostring(hold_length) + ')')
        reverseToLong := true
        if underBand
            shortStopPrice := high[1]
            reverseToLong := false
// Stop Loss and Set calculate stop loss using Atr Channel
if inPosition 
    if strategy.position_size > 0
        if fastEma - (atr * atrMidMultInput) > longStopPrice // set long stop price to the higher of latest long stop price and ATR lower channel
            longStopPrice := fastEma - (atr * atrMidMultInput)
        strategy.exit('Long Stop atr ', 'long', stop=longStopPrice)
    else if strategy.position_size < 0
        if fastEma + (atr * atrMidMultInput) < shortStopPrice
            shortStopPrice := fastEma + (atr * atrMidMultInput)
        strategy.exit('Short Stop atr ', 'short', stop=shortStopPrice)

// Plotting
fastLine = plot(fastEma, title='fast ema line', linewidth=1, color=isBullish ? color.green : color.red)
slowLine = plot(slowEma, title='slow ema line', linewidth=2, color= isBullish? color.green : color.red)
atrUpperLine1 = plot(fastEma + (atr * atrInnerMultInput), title='ATR Upperline1', color=color.new(color.black,85))
atrLowerLine1 = plot(fastEma - (atr * atrInnerMultInput), title='ATR Lowerline1', color=color.new(color.black,85))
atrUpperLine2 = plot(fastEma + (atr * atrMidMultInput), title='ATR Upperline2', color=color.new(color.black,75))
atrLowerLine2 = plot(fastEma - (atr * atrMidMultInput), title='ATR Lowerline2', color=color.new(color.black,75))
atrUpperLine3 = plot(fastEma + (atr * atrOuterMultInput), title='ATR Upperline3', color=color.new(color.black,50))
atrLowerLine3 = plot(fastEma - (atr * atrOuterMultInput), title='ATR Lowerline3', color=color.new(color.black,50))

plot(longStopPrice, color=strategy.position_size > 0 ? color.red : na, linewidth=2)
plot(shortStopPrice, color=strategy.position_size < 0 ? color.red : na, linewidth=2)

//  Filling
fill(fastLine, slowLine, color=isBullish ? GREENBULL : REDBEAR)
fill(atrUpperLine3, atrLowerLine3, color=inPosition and (minHoldInput - hold_length > 0) ? color.new(color.blue,90): na)

barColor = switch
    greenLong => color.green
    yellowLong =>  color.yellow
    blueShort => color.blue
    redShort => color.red
    => color.black
barcolor(color=barColor)

// Fill background to distinguish inactive time(Zulu time)
nightTime = time(timeframe.period, "1500-0100") ? color.new(color.black, 95): na
bgcolor(nightTime)


Lebih banyak