この記事では,トレンドを決定するために複数の指標を組み合わせた定量的な取引戦略を紹介しています.移動平均値,新しい高値/低値,年間水準などを使用して中長期の価格傾向を追跡します.
戦略は以下の点に基づいています.
移動平均値,新高値/低値指数を使用して価格傾向を決定します.
短期的な失敗を避けるために 年間レベルを組み込む
偽造をフィルタリングする 配列された指標バンド信号を入力します
スーパートレンドに追いついて トレンドの利益を確保する
移動平均の違反を 止める
戦略の利点
複数の指標により 意思決定の正確性が向上します
明確なトレンドで取引するだけで 不必要な取引は避けられます
スーパートレンドは利益を固定し 引き下げを減らします
脱出の際の 適切な停止は 勝利率を向上させます
明確な論理は最適化を直感的にします
潜在的リスクは以下のとおりです.
複数のフィルターで取引が失敗する可能性があります
スーパートレンドのトレイルは 利益を制限します
悪い脱出停止は不必要な出口を引き起こす.
パラメータ調整は性能に大きく影響します
この戦略は,トレンドを決定するために複数の技術指標を組み合わせます.適切な最適化によって,良いリターンを達成することができます. しかし,トレーダーはトレンドの正確性を監視し,それに応じてパラメータを調整する必要があります.
/*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)