Strategi Dagangan Crossover Purata Bergerak Dinamik

Penulis:ChaoZhang, Tarikh: 2023-11-13 10:27:54
Tag:

img

Ringkasan

Idea utama strategi ini adalah untuk membina pelbagai purata bergerak berdasarkan penunjuk Ratio OCHL Averager jangka masa yang berbeza dan menjana isyarat perdagangan berdasarkan persilangan. Ia dapat menangkap trend harga secara dinamik dan sesuai untuk perdagangan jangka menengah.

Logika Strategi

Strategi ini menggunakan dua penunjuk Ratio OCHL Averager dengan jangka masa yang berbeza sebagai garis cepat dan perlahan.

b = abs(close-open)/(high - low)
c = min(max(b, 0), 1)  
Ratio OCHL Averager = c*close + (1-c)*previous Ratio OCHL Averager

Di sini, b mewakili nisbah pergerakan harga intraday dan c adalah b yang dinormalisasi. Ratio OCHL Averager menggabungkan harga terbuka, tutup, tinggi dan rendah untuk membina purata bergerak.

Strategi ini menetapkan tempoh yang lebih pendek untuk garisan pantas dan tempoh yang lebih lama untuk garisan perlahan. Isyarat beli dihasilkan apabila garisan pantas melintasi di atas garisan perlahan, dan isyarat jual apabila garisan pantas melintasi di bawah. Ia menangkap trend dengan logik persilangan purata bergerak.

Kelebihan

  1. Ratio OCHL Averager meratakan data harga dan menapis bunyi pasaran, menjadikan isyarat perdagangan lebih dipercayai.

  2. Perpindahan purata bergerak berganda digabungkan dengan jangka masa yang berbeza dapat mengesan permulaan trend baru dengan lebih baik.

  3. Tempoh garis cepat dan perlahan boleh diselaraskan dengan keadaan pasaran yang berbeza.

  4. Logik strategi adalah mudah dan intuitif. Mudah difahami dan dilaksanakan.

  5. Stop loss dan mengambil keuntungan boleh ditetapkan secara fleksibel untuk mengawal risiko.

Risiko

  1. Crossover purata bergerak boleh menghasilkan isyarat palsu yang berlebihan. Penunjuk teknikal lain mungkin diperlukan untuk penapis.

  2. Tempoh garis cepat dan perlahan harus dipilih dengan munasabah, jika tidak, ia boleh menjejaskan prestasi strategi.

  3. Ia adalah trend mengikuti strategi yang tidak sesuai untuk pasaran terhad julat.

  4. Stop loss dan mengambil keuntungan harus diselaraskan dengan betul untuk mengurangkan kerugian dan mengoptimumkan tahap keuntungan.

Arahan pengoptimuman

  1. Pertimbangkan untuk menggabungkan penunjuk momentum seperti MACD, KDJ untuk penapisan isyarat dan peningkatan kualiti.

  2. Uji kombinasi tempoh garis pantas dan perlahan yang berbeza untuk mencari parameter yang optimum.

  3. Mengoptimumkan stop loss dan mengambil keuntungan berdasarkan hasil backtest.

  4. Pertimbangkan menyesuaikan parameter secara dinamik dalam keadaan pasaran tertentu, sebagai contoh, meningkatkan tempoh dalam pasaran terhad julat.

Kesimpulan

Strategi ini mempunyai logik yang jelas menggunakan persilangan purata bergerak cepat dan perlahan untuk menentukan arah trend. Ini adalah trend dinamik mengikuti strategi yang sesuai untuk perdagangan jangka sederhana. Masih ada banyak ruang untuk pengoptimuman dengan penyesuaian parameter, penapisan isyarat dll. Secara keseluruhan, ini adalah strategi perdagangan trend yang fleksibel dan praktikal.


/*backtest
start: 2023-11-05 00:00:00
end: 2023-11-12 00:00:00
period: 3m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy(title="[XC] Adaptive Strategy V3 - Ratio OCHL Averager no repaint",shorttitle="R_OHCL", overlay=true, currency=currency.EUR,initial_capital=10000,
     default_qty_value=100, default_qty_type=strategy.percent_of_equity , calc_on_every_tick=false, calc_on_order_fills=true)


//                  ╔═ SETTINGS                  ╗
//░░░░░░░░░░░░░░░░░ ╚════════════════════════════╝ ░░░░░░░░░░░░░░░░░░░░░░░░

strategy_1     = input ( defval=true   , type=input.bool    , title="STRATEGY 1? —>"      )
Recursive      = input(false)
RES201         = "Min",RES202= "D",RES203 = "W",RES204 = "M"

//++ Resolution 1 ++
inp_resolution1 = input(600, minval=1, title="Resolution Line 1")
restype1        = input ( defval="Min"  , type=input.string , title= "Resolution Line 1" , options=[ "Min","D","W","M"])
multiplier1     = restype1 == "Min" ? "" : restype1 == "D" ? "D" : restype1 == "W" ? "W" : "M"
resolution1     = tostring(inp_resolution1)+ multiplier1

//++ Resolution 2 ++
inp_resolution2 = input(1440, minval=1, title="Resolution Line 2")
restype2        = input ( defval="Min"  , type=input.string , title= "Resolution Line 2" , options=["Min","D","W","M"])
multiplier2     = restype2 == "Min" ? "" : restype2 == "D" ? "D" : restype2 == "W" ? "W" : "M"
resolution2     = tostring(inp_resolution2)+ multiplier2

StopLoss        = input(defval = 500 , title = "Stop Loss", minval = 0)
TakeProfit      = input(defval = 2500 , title = "Take Profit", minval = 0)
// === RISK MANAGEMENT VALUE PREP ===
// if an input is less than 1, assuming not wanted so we assign 'na' value to disable it.
useTakeProfit   = TakeProfit  >= 1 ? TakeProfit  : na
useStopLoss     = StopLoss    >= 1 ? StopLoss    : na


//                  ╔═ BACKTEST RANGE            ╗
//░░░░░░░░░░░░░░░░░ ╚════════════════════════════╝ ░░░░░░░░░░░░░░░░░░░░░░░░
line_breakBTR  = input ( defval = true   , type=input.bool   , title="BACKTEST RANGE —"      ) 
FromYear       = input ( defval = 2019, title = "From Year", minval = 2017)
FromMonth      = input ( defval = 1, title = "From Month", minval = 1, maxval = 12)
FromDay        = input ( defval = 2, title = "From Day", minval = 1, maxval = 31)
//FromHour     = input ( defval = 1, title = "From Hour", minval = 1, maxval = 24)
ToYear         = input ( defval = 9999, title = "To Year", minval = 2017)
//ToHour       = input ( defval = 0, title = "From Hour", minval = 0, maxval = 24)
ToMonth        = input ( defval = 1, title = "To Month", minval = 1, maxval = 12)
ToDay          = input ( defval = 1, title = "To Day", minval = 1, maxval = 31)

// === FUNCTION EXAMPLE ===
start     = timestamp(syminfo.timezone, FromYear, FromMonth, FromDay, 0, 00)  // backtest start window
finish    = timestamp(syminfo.timezone, ToYear  , ToMonth  , ToDay  , 0, 59)  // backtest finish window
window()  => time >= start and time <= finish ? true : false // create function "within window of time"

//                  ╔═ INDICATOR                 ╗
//░░░░░░░░░░░░░░░░░ ╚════════════════════════════╝ ░░░░░░░░░░░░░░░░░░░░░░░░

// "Ratio OCHL Averager" -> alexgrover / tradingview.com/script/RGAtOI6h-Ratio-OCHL-Averager-An-Alternative-to-VWAP/

rochla( res,Recursive)=>
    //Recursive = false
    H =  security(syminfo.tickerid,res,high[1],gaps = barmerge.gaps_off,  lookahead = barmerge.lookahead_on)
    L =  security(syminfo.tickerid,res,low[1] ,gaps = barmerge.gaps_off,  lookahead = barmerge.lookahead_on)
    d = 0.
    //----
    a = Recursive ? nz(d[1],open) : open
    b = abs(close-a)/(H - L)
    c = b > 1 ? 1 : b
    d := c*close+(1-c)*nz(d[1],close)



strat1_line1=rochla(resolution1,Recursive)
strat1_line2=rochla(resolution2,Recursive)

plot(strat1_line1, title="Ratio OCHL Averager 1", color=#DAA520,linewidth=2,transp=0)
plot(strat1_line2, title="Ratio OCHL Averager 2", color=#B22222,linewidth=2,transp=0)



//                  ╔═ STRATEGY 1                ╗
//░░░░░░░░░░░░░░░░░ ╚════════════════════════════╝ ░░░░░░░░░░░░░░░░░░░░░░░░

trading_strat1_line1 = strategy_1 == 1    ? strat1_line1   : na
trading_strat1_line2 = strategy_1 == 1    ? strat1_line2   : na

longCross  = crossunder (trading_strat1_line2, trading_strat1_line1) ? true : false
shortCross = crossover  (trading_strat1_line2, trading_strat1_line1) ? true : false

plot( longCross  ? trading_strat1_line1 : na , title = "Long"  , color=color.aqua, style=plot.style_circles, linewidth=5, offset= 0)
plot( shortCross ? trading_strat1_line2 : na , title = "Short" , color=color.red , style=plot.style_circles, linewidth=5, offset= 0)



//                  ╔═ Backtest 1                ╗
//░░░░░░░░░░░░░░░░░ ╚════════════════════════════╝ ░░░░░░░░░░░░░░░░░░░░░░░░


strategy.exit("close",loss = useStopLoss, profit = useTakeProfit)

if longCross  and window() and strategy_1 == 1 
    strategy.entry("Go Long", strategy.long)
if shortCross and window() and strategy_1 == 1 
    strategy.entry("Go Short", strategy.short)

//end

Lebih lanjut