Trend Kompaun Mengikut Strategi

Penulis:ChaoZhang, Tarikh: 2023-09-16 19:10:37
Tag:

Ringkasan

Artikel ini memperkenalkan strategi perdagangan kuantitatif yang menggabungkan beberapa penunjuk untuk menentukan trend. Ia mengesan trend harga jangka sederhana hingga panjang menggunakan purata bergerak, tertinggi / terendah baru, tahap tahunan dan banyak lagi.

Logika Strategi

Strategi ini berdasarkan:

  1. Menggunakan purata bergerak, indeks tertinggi / rendah baru untuk menentukan trend harga.

  2. Menggabungkan tahap tahunan untuk mengelakkan whipsaws jangka pendek.

  3. Memasuki isyarat bundel penunjuk yang sejajar untuk menapis palsu.

  4. Mengikuti dengan supertrend untuk mengunci keuntungan trend.

  5. Menghentikan pelanggaran purata bergerak.

Analisis Kelebihan

Kelebihan strategi:

  1. Pelbagai penunjuk meningkatkan ketepatan keputusan.

  2. Hanya perdagangan trend yang jelas mengelakkan perdagangan yang tidak perlu.

  3. Supertrend mengunci keuntungan dan mengurangkan pengeluaran.

  4. Hentikan pelarian dengan tepat pada masa meningkatkan kadar kemenangan.

  5. Logik yang jelas menjadikan pengoptimuman intuitif.

Analisis Risiko

Risiko berpotensi termasuk:

  1. Pelbagai penapis boleh menyebabkan perdagangan yang gagal.

  2. Laluan supertrend boleh terlalu membatasi keuntungan.

  3. Perhentian melarikan diri yang buruk menyebabkan keluar yang tidak perlu.

  4. Penyesuaian parameter memberi kesan yang ketara terhadap prestasi.

Kesimpulan

Strategi ini menggabungkan pelbagai penunjuk teknikal untuk menentukan trend. Dengan pengoptimuman yang betul, ia boleh mencapai pulangan yang baik. Tetapi peniaga harus menonton ketepatan trend dan menyesuaikan parameter dengan sewajarnya.


/*backtest
start: 2023-08-16 00:00:00
end: 2023-09-15 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("AlignedMA and Cumulative HighLow Strategy V2", overlay=true, initial_capital = 1000, 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)

MAType = input(title="Moving Average Type", defval="hma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
includePartiallyAligned = input(true)
HighLowPeriod = input(22, minval=1,step=1)
LookbackPeriod = input(10, minval=1,step=1)
considerYearlyHighLow = input(false)

dirTBars = input(1)
dirRBars = input(30)

PMAType = input(title="Moving Average Type", defval="ema", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
PMALength = input(10, minval=2, step=10)
shift = input(2, minval=1, step=1)

//Use 2 for ASX stocks
supertrendMult = input(3, minval=1, maxval=10, step=0.5)
supertrendLength = input(22, minval=1)

riskReward = input(2, minval=1, maxval=10, step=0.5)

tradeDirection = input(title="Trade Direction", defval=strategy.direction.all, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short])
backtestYears = input(1, 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_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

f_getHighLowValue(HighLowPeriod)=>
    currentHigh = highest(high,HighLowPeriod) == high
    currentLow = lowest(low,HighLowPeriod) == low
    currentHigh?1:currentLow?-1:0

f_getDirection(Series)=>
    direction = Series > Series[1] ? 1 : Series < Series[1] ? -1 : 0
    direction := direction == 0? nz(direction[1],0):direction
    direction

f_getDirectionT(Series, tBars, rBars)=>
    compH = Series > 0? Series[tBars] : Series[rBars]
    compL = Series < 0? Series[tBars] : Series[rBars]
    direction = Series > compH ? 1 : Series < compL ? -1 : 0
    direction := direction == 0? nz(direction[1],0):direction
    direction

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
    
    [yearlyHighCondition,yearlyLowCondition]

f_getOpenCloseMA(MAType, length)=>
    openMA = f_getMovingAverage(open, MAType, length)
    closeMA = f_getMovingAverage(close, MAType, length)
    direction = openMA < closeMA ? 1 : -1
    [openMA, closeMA, direction]

inDateRange = true

maAlignment = f_getMaAlignment(MAType,includePartiallyAligned)
alignedMaIndex = sum(maAlignment,LookbackPeriod)

maAlignmentDirection=f_getDirectionT(alignedMaIndex,dirTBars, dirRBars)
atr = atr(22)
highLowIndex = f_getHighLowValue(HighLowPeriod)
cumulativeHighLowIndex = sum(highLowIndex,LookbackPeriod)

hlDirection = f_getDirectionT(cumulativeHighLowIndex,dirTBars,dirRBars)
[yearlyHighCondition,yearlyLowCondition] = f_getYearlyHighLowCondition(considerYearlyHighLow)
[supertrend, dir] = supertrend(supertrendMult, supertrendLength)
[esupertrend, edir] = supertrend(supertrendMult+1, supertrendLength)

movingAverage = f_getMovingAverage(close, PMAType, PMALength)

secondaryBuyFilter = movingAverage > movingAverage[shift]
secondarySellFilter = movingAverage < movingAverage[shift]

closeBuyFilter = dir == 1
closeSellFilter = dir == -1
buyFilter = (maAlignmentDirection == 1 and hlDirection == 1 and yearlyHighCondition)
sellFilter = (maAlignmentDirection == -1 and hlDirection == -1 and yearlyLowCondition)

barColor = buyFilter?color.lime:sellFilter?color.orange:color.gray

bandColor = secondaryBuyFilter ? color.green : secondarySellFilter ? color.red : color.gray

compound = strategy.position_size > 0? strategy.position_avg_price + (atr* supertrendMult * riskReward) : strategy.position_size < 0 ? strategy.position_avg_price - (atr* supertrendMult * riskReward) : na
riskFree = na(compound)?false:strategy.position_size > 0 ? supertrend > compound : strategy.position_size < 0 ? supertrend < compound : false

trailingStop = riskFree?(dir==-1?supertrend - 2*atr : supertrend + 2*atr) :supertrend
trailingStop := (strategy.position_size > 0 and trailingStop < trailingStop[1]) ? trailingStop[1] :  ((strategy.position_size < 0 and trailingStop > trailingStop[1])? trailingStop[1] :trailingStop)
plot(trailingStop, title="Supertrend", color=riskFree? color.blue:dir==-1?color.green:color.red, linewidth=2)


buyEntry = buyFilter and secondaryBuyFilter and not closeBuyFilter and low > trailingStop
sellEntry = sellFilter and secondarySellFilter and not closeSellFilter and low < trailingStop
Fi1 = plot(movingAverage[shift], title="MA", color=color.red, linewidth=1, transp=50)
Fi2 = plot(movingAverage, title="Shift", color=color.green, linewidth=1, transp=50)
fill(Fi1, Fi2, title="Band Filler", color=bandColor, transp=40)

barcolor(barColor)

//plot(compound, title="Compound"mzn, color=dir==-1?color.lime:color.orange, linewidth=2)

strategy.risk.allow_entry_in(tradeDirection)
strategy.entry("Buy", strategy.long, when=buyEntry and inDateRange and (riskFree or strategy.position_size==0), oca_name="oca_buy")
strategy.exit("ExitBuy", "Buy", stop = trailingStop)
strategy.close("Buy", when=closeBuyFilter)


strategy.entry("Sell", strategy.short, when=sellEntry and inDateRange and (riskFree or strategy.position_size==0), oca_name="oca_sell")
strategy.exit("ExitSell", "Buy", stop = trailingStop)
strategy.close("Sell", when=closeSellFilter)


Lebih lanjut