La CCI et l'ATR ont adopté une stratégie de tendance

Auteur:ChaoZhang est là., Date: le 26 septembre 2023 16:08:37
Les étiquettes:

Résumé

Cette stratégie identifie les tendances des prix en combinant Average True Range (ATR) et Commodity Channel Index (CCI), et utilise les niveaux de surachat/survente comme signaux d'entrée et de sortie. ATR calcule les bandes supérieure et inférieure, tandis que CCI détermine la direction de la tendance.

La logique de la stratégie

  1. Calculer l'ATR, ici l'ATR à 2 périodes est utilisé
  2. Calculer la valeur du CCI, ici le CCI à 10 périodes est utilisé
  3. Déterminer la direction de la tendance sur la base de la valeur actuelle de l'ICC
    • CCI >= 0, défini comme tendance haussière
    • CCI < 0, défini comme tendance à la baisse
  4. Calculer la bande supérieure et la bande inférieure
    • Bandes supérieures = plus élevé + ATR * multiplicateur
    • Bandes inférieures = basse inférieure - ATR * multiplicateur
  5. Dans les différentes directions de tendance, enregistrer et mettre à jour les bandes supérieures et inférieures
    • Lorsque le CCI est supérieur à 0, si la bande supérieure est inférieure à la bande supérieure précédente, le réinitialiser; lorsque le CCI est inférieur à 0, si la bande inférieure est supérieure à la bande inférieure précédente, le réinitialiser
    • Cela évite que les canaux se déplacent à l'envers avec le prix
  6. Entrée à la bande supérieure ou inférieure en fonction de la valeur CCI comme signal d'entrée
  7. Sortie lorsque le CCI franchit 0 comme signal de sortie
  8. Mettre en place un stop-loss et une sortie de profit

Les avantages

Cette stratégie combine l'identification des tendances et la découverte des canaux, qui suit efficacement les tendances.

  1. Utilisation de l'indice de convergence pour déterminer l'orientation de l'évolution des prix afin d'évaluer rapidement les tendances longues/courtes
  2. Le canal ATR définit un stop-loss et un profit pour contrôler les risques
  3. Les canaux peuvent rapidement ajuster la direction lorsque le prix inverse, évitant d'être piégés dans le canal de tendance d'origine
  4. La sortie de la CCI 0 suit les tendances et évite les problèmes

Risques et améliorations

  1. Les paramètres CCI et ATR doivent être optimisés pour obtenir les meilleurs résultats pour les périodes et les paramètres
  2. Bien que l'ajustement des canaux évite la congestion, des retours en arrière importants peuvent encore entraîner des profits ou des pertes insuffisants
  3. Le placement de stop loss nécessite une optimisation, des arrêts de relâchement pour éviter les arrêts excessifs
  4. Des filtres supplémentaires sur le signal d'entrée peuvent optimiser les opportunités d'entrée
  5. La combinaison avec un indicateur de tendance à plus long terme peut éviter de négocier contre une tendance plus élevée

Résumé

Dans l'ensemble, il s'agit d'une stratégie de suivi de tendance simple et pratique. Son avantage est la logique claire et la facilité de mise en œuvre pour capitaliser rapidement sur les tendances. Mais des paramètres tels que la plage de stop loss nécessitent une optimisation basée sur les conditions du marché. La combinaison avec d'autres indicateurs peut améliorer encore la stratégie. En tant que stratégie de suivi de tendance débutante, il vaut la peine d'apprendre et de se référer.


/*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]


Plus de