この戦略は,平均真値範囲 (ATR) とコモディティチャネルインデックス (CCI) を組み合わせて価格動向を特定し,入口および出口信号として過買い/過売りレベルを使用する.ATRは上下帯を計算し,CCIはトレンド方向を決定する.CCIが過買いレベルを下回るときは短く,CCIが過売りレベルを下回るときは長く,したがってトレンドに従う.
この戦略は,トレンドの特定とチャネルブレイクを組み合わせて,効果的にトレンドを追います.
ストップ・ロスト・レンジは,市場状況に基づいて最適化が必要である.他の指標と組み合わせることで,戦略をさらに強化することができる.トレンドフォロー戦略の初心者として,学ぶ価値があり,参照する価値があります.
/*backtest start: 2023-08-26 00:00:00 end: 2023-09-25 00:00:00 period: 3h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=4 strategy("Trend Trader Karan",overlay=true) res = input(title="Resolution", type=input.resolution, defval="60",confirm = true) ProfitPerc = input(title=" Take Profit (%)",type=input.float, minval=0.0, step=0.1, defval=1.4) * 0.01 stoploss = input(title=" Stop Loss (%)",type=input.float, minval=0.0, step=0.1, defval=0.7) * 0.01 CCI = input(10,title = "CCI") ATR = input(2,title = "ATR") Multiplier= 1 original = false thisCCI = cci(close, CCI) lastCCI = nz(thisCCI[1]) calcx()=> bufferDn= high + Multiplier * wma(tr,ATR) bufferUp= low - Multiplier * wma(tr,ATR) if (thisCCI >= 0 and lastCCI < 0) bufferUp := bufferDn[1] if (thisCCI <= 0 and lastCCI > 0) bufferDn := bufferUp[1] if (thisCCI >= 0) if (bufferUp < bufferUp[1]) bufferUp := bufferUp[1] else if (thisCCI <= 0) if (bufferDn > bufferDn[1]) bufferDn := bufferDn[1] x = 0.0 x := thisCCI >= 0 ?bufferUp:thisCCI <= 0 ?bufferDn:x[1] x tempx = calcx() calcswap() => swap = 0.0 swap := tempx>tempx[1]?1:tempx<tempx[1]?-1:swap[1] swap tempswap = calcswap() swap2=tempswap==1?color.green:color.red swap3=thisCCI >=0 ?color.green :color.red swap4=original?swap3:swap2 //display current timeframe's Trend plot(tempx,color=swap4 == color.green ? color.green : swap4,transp=0,linewidth=4) htfx = security(syminfo.tickerid,res,tempx[1],lookahead = barmerge.lookahead_on) htfswap4 = security(syminfo.tickerid,res,swap4[1],lookahead = barmerge.lookahead_on) plot(htfx,color=htfswap4,transp=0,linewidth=3) //plotarrow( ? 1 : swap4[1] == color.yellow and swap4 == color.blue ? -1 :0 , title="Up Entry Arrow", colorup=color.green,colordown = color.blue, maxheight=10, minheight=10, transp=0) plotshape( swap4[1] == color.red and swap4 == color.green ? 1 : na , style = shape.triangleup , color = color.blue , location = location.belowbar , size = size.tiny ) plotshape( swap4[1] == color.green and swap4 == color.red ? 1 : na , style = shape.triangledown , color = color.red , location = location.abovebar , size = size.tiny) buy = swap4[1] == color.red and swap4 == color.green and htfswap4 == color.green sell = swap4[1] == color.green and swap4 == color.red and htfswap4 == color.red if(buy) strategy.entry("buy",true) if(sell) strategy.entry("sell",false) if(swap4[1] == color.red and swap4 == color.green) strategy.close("sell") if(swap4[1] == color.green and swap4 == color.red ) strategy.close("buy") longExitPrice = strategy.position_avg_price * (1 + ProfitPerc) shortExitPrice = strategy.position_avg_price * (1 - ProfitPerc) stop_buy = strategy.position_avg_price * (1 - stoploss) stop_sell = strategy.position_avg_price * (1 + stoploss) if (strategy.position_size > 0) strategy.exit(id="Target", limit=longExitPrice , stop = stop_buy) if (strategy.position_size < 0) strategy.exit(id="Target", limit=shortExitPrice , stop = stop_sell) ///////////////study("EMA ", overlay=true) plot(ema(close, 200), color=#FF7000, linewidth=2, title='200 Day EMA') plot(ema(close, 20), color=#0088FA, linewidth=2, title='20 Day EMA') plot(ema(close, 50), color=#FA00D0, linewidth=2, title='50 Day EMA') //////////////////study("Trend Lines+++", overlay=true) // src = input(low) len0 = input(100) calcSlope(src, len0) => if not barstate.islast [float(na), float(na), float(na)] else sumX = 0.0 sumY = 0.0 sumXSqr = 0.0 sumXY = 0.0 for i = 0 to len0 - 1 val = src[i] per = i + 1.0 sumX := sumX + per sumY := sumY + val sumXSqr := sumXSqr + per * per sumXY := sumXY + val * per slope = (len0 * sumXY - sumX * sumY) / (len0 * sumXSqr - sumX * sumX) average = sumY / len0 intercept = average - slope * sumX / len0 + slope [slope, average, intercept] [s, a, i] = calcSlope(src, len0) startPrice = i + s * (len0 - 1) endPrice = i // var line baseLine = na // if na(baseLine) // baseLine := line.new(bar_index - len0 + 1, startPrice, bar_index, endPrice, width=4, extend=extend.right) // else // line.set_xy1(baseLine, bar_index - len0 + 1, startPrice) // line.set_xy2(baseLine, bar_index, endPrice) // na // mx = input(100, "Range", minval=1) mn = max(2, round(mx / 10) + 1) LN(B, CLR) => s1 = B == 1 ? highest(src, mx) : lowest(src, mx) s2 = B == 1 ? highest(src, mn) : lowest(src, mn) c1 = s1 == src c2 = s2 == src b1 = barssince(c1) b2 = barssince(c2) v1 = valuewhen(c1, s1, 0) v2 = valuewhen(c2, s2, 0) // line.new(bar_index - b1, v1, bar_index - b2, v2, extend=extend.both, color=CLR, width=2) // L1 = LN(1, #ff0088), line.delete(L1[1]) // L2 = LN(0, #00ff88), line.delete(L2[1]) // // Input variables len=input(30,title="loockback length pivots") wicks=input(true,title="Draw lines from wicks (checked) or real bodies (unchecked)?") disp_select=input(true,title="Display only falling 'high' and rising 'low' trendlines?") do_mono=input(false,title="checked = monochrome lines, unchecked = direction colored lines?") limit_extension=input(0,title="Limit extensions of the lines? 0 = infinite, other values x 100 bars",minval=0) do_alerts=input(true,title="show trendline breaks") trendline_nr=input(5,title="number of past trendlines to check for breaks (max = 10)",minval=0,maxval=10) select_breaks=input(true,title="only display 'long' breaks on trendlines connecting 'highs' and 'short' for 'lows'") log_chart=input(false,title="USING A LOG CHART? MAKE SURE TO CHECK THIS BOX!!") // Calculating the 'time value' of one bar bar_time=time-time[1] // Initialising color scheme var color color_rising=do_mono?color.teal:color.lime var color color_falling=do_mono?color.teal:color.fuchsia /////// Function declarations /////// // Declaration of trendline function f_trendline(_input_function,_delay,_only_up,_extend) => // Calculate line coordinates (Ax,Ay) - (Bx,By) var int Ax = 0 var int Bx = 0 var float By = 0.0 var float slope = 0.0 Ay = fixnan(_input_function) if change(Ay)!=0 Ax := time[_delay] By:= Ay[1] Bx := Ax[1] slope:=log_chart?((log(Ay)-log(By))/(Ax-Bx)):((Ay-By)/(Ax-Bx)) else Ax := Ax[1] Bx := Bx[1] By := By[1] // Draw trendlines var line trendline=na var int Axbis=0 var float Aybis=0.0 var bool _xtend=true extension_time = limit_extension*bar_time*100 Axbis := Ax + extension_time Aybis := log_chart?(Ay*exp(extension_time*slope)):(Ay + extension_time*slope) if limit_extension!=0 _xtend:=false if change(Ay)!=0 line_color = slope*time<0?(_only_up?(disp_select?na:color_rising):color_rising):(_only_up?color_falling:(disp_select?na:color_falling)) if not na(line_color) trendline = line.new(Bx,By,Axbis, Aybis, xloc.bar_time, extend=_xtend?extend.right:extend.none, color=line_color, style=line.style_dotted, width=1) [Bx,By,Axbis,Aybis,slope] // Function to get trendline price for X bars ago ("0" = current value) line_get_price(_start_time,_start_price,_slope,_lookback_period,_log_chart) => var float current_price=0.0 elapsed_time = (time-_start_time) current_price := _log_chart?(_start_price*exp((elapsed_time-(_lookback_period*bar_time))*_slope)):(_start_price + (elapsed_time-(_lookback_period*bar_time))*_slope) // Function to check for trendline crosses line_cross(_check_value,_start_time,_start_price,_slope,_log_chart) => var float current_value=0.0 var float previous_value=0.0 // Get current and previous price for the trendline current_value := line_get_price(_start_time,_start_price,_slope,0,_log_chart) previous_value := line_get_price(_start_time,_start_price,_slope,1,_log_chart) // Return 1 for crossover, -1 for crossunder and 0 for no cross detected cross = _check_value[1]<previous_value and _check_value>current_value?1: _check_value[1]>previous_value and _check_value<current_value?-1:0 /////// Start of main script /////// // Calculate pivot points high_point=pivothigh(wicks?high:(close>open?close:open),len,len/2) low_point=pivotlow(wicks?low:(close>open?open:close),len,len/2) // Call trendline function for high and low pivot points [phx1,phy1,phx2,phy2,slope_high]=f_trendline(high_point,len/2,false,true) [plx1,ply1,plx2,ply2,slope_low]=f_trendline(low_point,len/2,true,true) // Initialition of pseudo array to keep track of last 10 high and 10 low trendline values var int high_x0=0, var float high_y0=0.0, var float high_sl0=0.0 var int high_x1=0, var float high_y1=0.0, var float high_sl1=0.0 var int high_x2=0, var float high_y2=0.0, var float high_sl2=0.0 var int high_x3=0, var float high_y3=0.0, var float high_sl3=0.0 var int high_x4=0, var float high_y4=0.0, var float high_sl4=0.0 var int high_x5=0, var float high_y5=0.0, var float high_sl5=0.0 var int high_x6=0, var float high_y6=0.0, var float high_sl6=0.0 var int high_x7=0, var float high_y7=0.0, var float high_sl7=0.0 var int high_x8=0, var float high_y8=0.0, var float high_sl8=0.0 var int high_x9=0, var float high_y9=0.0, var float high_sl9=0.0 var int low_x0=0, var float low_y0=0.0, var float low_sl0=0.0 var int low_x1=0, var float low_y1=0.0, var float low_sl1=0.0 var int low_x2=0, var float low_y2=0.0, var float low_sl2=0.0 var int low_x3=0, var float low_y3=0.0, var float low_sl3=0.0 var int low_x4=0, var float low_y4=0.0, var float low_sl4=0.0 var int low_x5=0, var float low_y5=0.0, var float low_sl5=0.0 var int low_x6=0, var float low_y6=0.0, var float low_sl6=0.0 var int low_x7=0, var float low_y7=0.0, var float low_sl7=0.0 var int low_x8=0, var float low_y8=0.0, var float low_sl8=0.0 var int low_x9=0, var float low_y9=0.0, var float low_sl9=0.0 // If a new trendline is formed, shift all values in the array one place up and forget the last values if change(fixnan(high_point))!=0 high_x9:=high_x8, high_y9:=high_y8, high_sl9:=high_sl8 high_x8:=high_x7, high_y8:=high_y7, high_sl8:=high_sl7 high_x7:=high_x6, high_y7:=high_y6, high_sl7:=high_sl6 high_x6:=high_x5, high_y6:=high_y5, high_sl6:=high_sl5 high_x5:=high_x4, high_y5:=high_y4, high_sl5:=high_sl4 high_x4:=high_x3, high_y4:=high_y3, high_sl4:=high_sl3 high_x3:=high_x2, high_y3:=high_y2, high_sl3:=high_sl2 high_x2:=high_x1, high_y2:=high_y1, high_sl2:=high_sl1 high_x1:=high_x0, high_y1:=high_y0, high_sl1:=high_sl0 high_x0:=phx1, high_y0:=phy1, high_sl0:=slope_high if change(fixnan(low_point))!=0 low_x9:=low_x8, low_y9:=low_y8, low_sl9:=low_sl8 low_x8:=low_x7, low_y8:=low_y7, low_sl8:=low_sl7 low_x7:=low_x6, low_y7:=low_y6, low_sl7:=low_sl6 low_x6:=low_x5, low_y6:=low_y5, low_sl6:=low_sl5 low_x5:=low_x4, low_y5:=low_y4, low_sl5:=low_sl4 low_x4:=low_x3, low_y4:=low_y3, low_sl4:=low_sl3 low_x3:=low_x2, low_y3:=low_y2, low_sl3:=low_sl2 low_x2:=low_x1, low_y2:=low_y1, low_sl2:=low_sl1 low_x1:=low_x0, low_y1:=low_y0, low_sl1:=low_sl0 low_x0:=plx1, low_y0:=ply1, low_sl0:=slope_low // Check Trendline crosses for last X nr. of trendlines cross_high0= disp_select and high_sl0*time>0?0: line_cross(close,high_x0,high_y0,high_sl0,log_chart) cross_low0= disp_select and low_sl0*time<0?0: line_cross(close,low_x0,low_y0,low_sl0,log_chart) cross_high1= disp_select and high_sl1*time>0?0: line_cross(close,high_x1,high_y1,high_sl1,log_chart) cross_low1= disp_select and low_sl1*time<0?0: line_cross(close,low_x1,low_y1,low_sl1,log_chart) cross_high2= disp_select and high_sl2*time>0?0: line_cross(close,high_x2,high_y2,high_sl2,log_chart) cross_low2= disp_select and low_sl2*time<0?0: line_cross(close,low_x2,low_y2,low_sl2,log_chart) cross_high3= disp_select and high_sl3*time>0?0: line_cross(close,high_x3,high_y3,high_sl3,log_chart) cross_low3= disp_select and low_sl3*time<0?0: line_cross(close,low_x3,low_y3,low_sl3,log_chart) cross_high4= disp_select and high_sl4*time>0?0: line_cross(close,high_x4,high_y4,high_sl4,log_chart) cross_low4= disp_select and low_sl4*time<0?0: line_cross(close,low_x4,low_y4,low_sl4,log_chart) cross_high5= disp_select and high_sl5*time>0?0: line_cross(close,high_x5,high_y5,high_sl5,log_chart) cross_low5= disp_select and low_sl5*time<0?0: line_cross(close,low_x5,low_y5,low_sl5,log_chart) cross_high6= disp_select and high_sl6*time>0?0: line_cross(close,high_x6,high_y6,high_sl6,log_chart) cross_low6= disp_select and low_sl6*time<0?0: line_cross(close,low_x6,low_y6,low_sl6,log_chart) cross_high7= disp_select and high_sl7*time>0?0: line_cross(close,high_x7,high_y7,high_sl7,log_chart) cross_low7= disp_select and low_sl7*time<0?0: line_cross(close,low_x7,low_y7,low_sl7,log_chart) cross_high8= disp_select and high_sl8*time>0?0: line_cross(close,high_x8,high_y8,high_sl8,log_chart) cross_low8= disp_select and low_sl8*time<0?0: line_cross(close,low_x8,low_y8,low_sl8,log_chart) cross_high9= disp_select and high_sl9*time>0?0: line_cross(close,high_x9,high_y9,high_sl9,log_chart) cross_low9= disp_select and low_sl9*time<0?0: line_cross(close,low_x9,low_y9,low_sl9,log_chart) long_break= (trendline_nr>9?cross_high9==1 or (select_breaks?false:cross_low9==1):false) or (trendline_nr>8?cross_high8==1 or (select_breaks?false:cross_low8==1):false) or (trendline_nr>7?cross_high7==1 or (select_breaks?false:cross_low7==1):false) or (trendline_nr>6?cross_high6==1 or (select_breaks?false:cross_low6==1):false) or (trendline_nr>5?cross_high5==1 or (select_breaks?false:cross_low5==1):false) or (trendline_nr>4?cross_high4==1 or (select_breaks?false:cross_low4==1):false) or (trendline_nr>3?cross_high3==1 or (select_breaks?false:cross_low3==1):false) or (trendline_nr>2?cross_high2==1 or (select_breaks?false:cross_low2==1):false) or (trendline_nr>1?cross_high1==1 or (select_breaks?false:cross_low1==1):false) or cross_high0==1 or (select_breaks?false:cross_low0==1) short_break= (trendline_nr>9?(select_breaks?false:cross_high9==-1) or cross_low9==-1:false) or (trendline_nr>8?(select_breaks?false:cross_high8==-1) or cross_low8==-1:false) or (trendline_nr>7?(select_breaks?false:cross_high7==-1) or cross_low7==-1:false) or (trendline_nr>6?(select_breaks?false:cross_high6==-1) or cross_low6==-1:false) or (trendline_nr>5?(select_breaks?false:cross_high5==-1) or cross_low5==-1:false) or (trendline_nr>4?(select_breaks?false:cross_high4==-1) or cross_low4==-1:false) or (trendline_nr>3?(select_breaks?false:cross_high3==-1) or cross_low3==-1:false) or (trendline_nr>2?(select_breaks?false:cross_high2==-1) or cross_low2==-1:false) or (trendline_nr>1?(select_breaks?false:cross_high1==-1) or cross_low1==-1:false) or (select_breaks?false:cross_high0==-1) or cross_low0==-1 // Plot and connect pivot points color_high=slope_high*time<0?color_rising:(disp_select?na:color_falling) color_low=slope_low*time>0?color_falling:(disp_select?na:color_rising) plot(high_point,color=color_high,offset=-len/2) plot(low_point,color=color_low,offset=-len/2) // // Function outputs 1 when it's the first bar of the D/W/M/Y is_newbar(res) => ch = 0 if(res == 'Y') t = year(time('D')) ch := change(t) != 0 ? 1 : 0 else t = time(res) ch := change(t) != 0 ? 1 : 0 ch //////////// // INPUTS // //////////// pp_period = input(title = "Period", type=input.string, defval="Day", options = ['Day', 'Week', 'Month', 'Year']) pp_res = pp_period == 'Day' ? 'D' : pp_period == 'Week' ? 'W' : pp_period == 'Month' ? 'M' : 'Y' ///////////////////// // Get HLC from HT // // Calc High high_cur = 0.0 high_cur := is_newbar(pp_res) ? high : max(high_cur[1], high) phigh = 0.0 phigh := is_newbar(pp_res) ? high_cur[1] : phigh[1] // Calc Low low_cur = 0.0 low_cur := is_newbar(pp_res) ? low : min(low_cur[1], low) plow = 0.0 plow := is_newbar(pp_res) ? low_cur[1] : plow[1] // Calc Close pclose = 0.0 pclose := is_newbar(pp_res) ? close[1] : pclose[1]