
Strategi penembusan dinamik adalah strategi trend yang mengesan dinamik pasaran. Ia menggabungkan pelbagai petunjuk untuk menentukan sama ada pasaran kini berada dalam trend menaik atau menurun, dan membuat lebih banyak kedudukan apabila melanggar titik rintangan utama, dan membuka posisi apabila melanggar titik sokongan utama.
Strategi ini digunakan untuk menilai trend pasaran dan harga utama dengan mengira pelbagai saluran Donchian jangka panjang. Khususnya, ia menilai trend naik apabila harga menembusi siklus yang lebih lama seperti saluran Donchian selama 40 hari, dan berdasarkan itu, ia mengeluarkan banyak isyarat dengan syarat penapis seperti tinggi baru dalam setahun, urutan arah rata-rata bergerak, dan sebagainya.
Dalam hal keluar dari kedudukan, strategi ini menawarkan dua pilihan: garisan pembatalan tetap dan tracking stop loss. Garisan pembatalan tetap adalah untuk menetapkan stop loss berdasarkan kitaran yang lebih pendek seperti saluran Donchian 20 hari; dan tracking stop loss adalah untuk menghitung stop loss floating berdasarkan nilai ATR setiap hari. Kedua-dua jenis stop loss dapat mengawal risiko dengan baik.
Strategi ini menggabungkan penghakiman trend dan operasi penembusan, yang dapat menangkap peluang ke arah garis pendek di pasaran secara berkesan. Berbanding dengan satu indikator, ia menggunakan pelbagai syarat penapisan secara komprehensif, yang dapat menapis beberapa penembusan palsu dan meningkatkan kualiti isyarat masuk. Selain itu, penggunaan strategi hentikan kerugian juga menjadikannya lebih tahan lama, walaupun perubahan jangka pendek dapat mengawal kerugian dengan berkesan.
Risiko utama strategi ini adalah bahawa pasaran mungkin mengalami turun naik yang hebat, menyebabkan hentian kerugian yang dicetuskan untuk keluar dari kedudukan. Dalam kes ini, peluang mungkin terlepas jika pasaran berbalik dengan cepat. Selain itu, penggunaan pelbagai syarat penapisan juga akan menapis beberapa peluang, mengurangkan frekuensi memegang strategi.
Untuk mengurangkan risiko, nilai ATR boleh disesuaikan dengan sewajarnya atau jarak orbit Donchian dapat diperluas, yang dapat mengurangkan kemungkinan penghentian terputus. Anda juga boleh mengurangkan atau membatalkan syarat penapisan sebahagiannya, meningkatkan frekuensi masuk, tetapi risiko juga meningkat.
Strategi ini boleh dioptimumkan dalam beberapa aspek:
Dengan menguji parameter yang berbeza, anda boleh mencari kombinasi parameter yang paling baik dan mencapai keseimbangan antara risiko dan faedah.
Strategi ini menggunakan pelbagai petunjuk untuk menentukan arah trend, dan menghantar isyarat perdagangan ketika titik-titik penting pecah. Mekanisme hentiannya juga menjadikan strategi ini mempunyai keupayaan kawalan risiko yang kuat. Dengan menetapkan parameter yang dioptimumkan, strategi ini dapat mencapai keuntungan tambahan yang stabil. Ia sesuai untuk pelabur yang tidak mempunyai penilaian yang jelas terhadap pasaran tetapi ingin mengikuti trend.
/*backtest
start: 2024-01-23 00:00:00
end: 2024-02-22 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/
// © HeWhoMustNotBeNamed
//@version=4
strategy("BuyHigh-SellLow Strategy", overlay=true, initial_capital = 10000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true)
donchianEntryLength = input(40, step=10)
donchianExitLength = input(20, step=10)
considerNewLongTermHighLows = input(true)
shortHighLowPeriod = input(120, step=10)
longHighLowPeriod = input(180, step=10)
considerMAAlignment = input(true)
MAType = input(title="Moving Average Type", defval="ema", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
LookbackPeriod = input(40, minval=10,step=10)
atrLength = input(22)
atrMult = input(4)
exitStrategy = input(title="Exit Strategy", defval="tsl", options=["dc", "tsl"])
considerYearlyHighLow = input(true)
backtestYears = input(10, minval=1, step=1)
f_getMovingAverage(source, MAType, length)=>
ma = sma(source, length)
if(MAType == "ema")
ma := ema(source,length)
if(MAType == "hma")
ma := hma(source,length)
if(MAType == "rma")
ma := rma(source,length)
if(MAType == "vwma")
ma := vwma(source,length)
if(MAType == "wma")
ma := wma(source,length)
ma
f_getTrailingStop(atr, atrMult)=>
stop = close - atrMult*atr
stop := strategy.position_size > 0 ? max(stop, stop[1]) : stop
stop
f_getMaAlignment(MAType, includePartiallyAligned)=>
ma5 = f_getMovingAverage(close,MAType,5)
ma10 = f_getMovingAverage(close,MAType,10)
ma20 = f_getMovingAverage(close,MAType,20)
ma30 = f_getMovingAverage(close,MAType,30)
ma50 = f_getMovingAverage(close,MAType,50)
ma100 = f_getMovingAverage(close,MAType,100)
ma200 = f_getMovingAverage(close,MAType,200)
upwardScore = 0
upwardScore := close > ma5? upwardScore+1:upwardScore
upwardScore := ma5 > ma10? upwardScore+1:upwardScore
upwardScore := ma10 > ma20? upwardScore+1:upwardScore
upwardScore := ma20 > ma30? upwardScore+1:upwardScore
upwardScore := ma30 > ma50? upwardScore+1:upwardScore
upwardScore := ma50 > ma100? upwardScore+1:upwardScore
upwardScore := ma100 > ma200? upwardScore+1:upwardScore
upwards = close > ma5 and ma5 > ma10 and ma10 > ma20 and ma20 > ma30 and ma30 > ma50 and ma50 > ma100 and ma100 > ma200
downwards = close < ma5 and ma5 < ma10 and ma10 < ma20 and ma20 < ma30 and ma30 < ma50 and ma50 < ma100 and ma100 < ma200
upwards?1:downwards?-1:includePartiallyAligned ? (upwardScore > 5? 0.5: upwardScore < 2?-0.5:upwardScore>3?0.25:-0.25) : 0
//////////////////////////////////// Calculate new high low condition //////////////////////////////////////////////////
f_calculateNewHighLows(shortHighLowPeriod, longHighLowPeriod, considerNewLongTermHighLows)=>
newHigh = highest(shortHighLowPeriod) == highest(longHighLowPeriod) or not considerNewLongTermHighLows
newLow = lowest(shortHighLowPeriod) == lowest(longHighLowPeriod) or not considerNewLongTermHighLows
[newHigh,newLow]
//////////////////////////////////// Calculate Yearly High Low //////////////////////////////////////////////////
f_getYearlyHighLowCondition(considerYearlyHighLow)=>
yhigh = security(syminfo.tickerid, '12M', high[1])
ylow = security(syminfo.tickerid, '12M', low[1])
yhighlast = yhigh[365]
ylowlast = ylow[365]
yhighllast = yhigh[2 * 365]
ylowllast = ylow[2 * 365]
yearlyTrendUp = na(yhigh)? true : na(yhighlast)? close > yhigh : na(yhighllast)? close > max(yhigh,yhighlast) : close > max(yhigh, min(yhighlast, yhighllast))
yearlyHighCondition = ( (na(yhigh) or na(yhighlast) ? true : (yhigh > yhighlast) ) and ( na(yhigh) or na(yhighllast) ? true : (yhigh > yhighllast))) or yearlyTrendUp or not considerYearlyHighLow
yearlyTrendDown = na(ylow)? true : na(ylowlast)? close < ylow : na(ylowllast)? close < min(ylow,ylowlast) : close < min(ylow, max(ylowlast, ylowllast))
yearlyLowCondition = ( (na(ylow) or na(ylowlast) ? true : (ylow < ylowlast) ) and ( na(ylow) or na(ylowllast) ? true : (ylow < ylowllast))) or yearlyTrendDown or not considerYearlyHighLow
label_x = time+(60*60*24*1000*1)
[yearlyHighCondition,yearlyLowCondition]
donchian(rangeLength)=>
upper = highest(rangeLength)
lower = lowest(rangeLength)
middle = (upper+lower)/2
[middle, upper, lower]
inDateRange = true
[eMiddle, eUpper, eLower] = donchian(donchianEntryLength)
[exMiddle, exUpper, exLower] = donchian(donchianExitLength)
maAlignment = f_getMaAlignment(MAType, false)
[yearlyHighCondition, yearlyLowCondition] = f_getYearlyHighLowCondition(considerYearlyHighLow)
[newHigh,newLow] = f_calculateNewHighLows(shortHighLowPeriod, longHighLowPeriod, considerNewLongTermHighLows)
maAlignmentLongCondition = highest(maAlignment, LookbackPeriod) == 1 or not considerMAAlignment
atr = atr(atrLength)
tsl = f_getTrailingStop(atr, atrMult)
//U = plot(eUpper, title="Up", color=color.green, linewidth=2, style=plot.style_linebr)
//D = plot(exLower, title="Ex Low", color=color.red, linewidth=2, style=plot.style_linebr)
longCondition = crossover(close, eUpper[1]) and yearlyHighCondition and newHigh and maAlignmentLongCondition
exitLongCondition = crossunder(close, exLower[1])
shortCondition = crossunder(close, eLower[1]) and yearlyLowCondition and newLow
exitShortCondition = crossover(close, exUpper[1])
strategy.entry("Buy", strategy.long, when=longCondition and inDateRange, oca_name="oca_buy")
strategy.exit("ExitBuyDC", "Buy", when=exitStrategy=='dc', stop=exLower)
strategy.exit("ExitBuyTSL", "Buy", when=exitStrategy=='tsl', stop=tsl)
plot(strategy.position_size > 0 ? (exitStrategy=='dc'?exLower:tsl) : na, title="Trailing Stop", color=color.red, linewidth=2, style=plot.style_linebr)
//strategy.close("Buy", when=exitLongCondition)