Artikel ini memperkenalkan strategi perdagangan kuantitatif yang menggabungkan beberapa indikator untuk menentukan tren.
Strategi ini didasarkan pada:
Menggunakan rata-rata bergerak, indeks tertinggi/rendah baru untuk menentukan tren harga.
Menggabungkan tingkat tahunan untuk menghindari whipsaws jangka pendek.
Masukkan sinyal bundel indikator yang selaras untuk menyaring pemalsuan.
Mengikuti dengan supertrend untuk mengunci keuntungan tren.
Menghentikan pelanggaran rata-rata bergerak.
Keuntungan dari strategi:
Berbagai indikator meningkatkan keakuratan keputusan.
Hanya perdagangan tren yang jelas menghindari perdagangan yang tidak perlu.
Supertrend trailing mengunci keuntungan dan mengurangi drawdowns.
Penutupan yang tepat waktu pada pelarian meningkatkan tingkat kemenangan.
Logika yang jelas membuat optimasi intuitif.
Risiko potensial termasuk:
Beberapa filter dapat menyebabkan perdagangan yang gagal.
Jalur supertrend bisa terlalu membatasi keuntungan.
Perhentian kabur yang buruk menyebabkan keluar yang tidak perlu.
Pengaturan parameter berdampak signifikan pada kinerja.
Strategi ini menggabungkan beberapa indikator teknis untuk menentukan tren. Dengan optimasi yang tepat, itu dapat mencapai pengembalian yang baik. Tapi pedagang harus menonton akurasi tren dan menyesuaikan parameter sesuai.
/*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)