이 문서에서는 단순 이동 평균 (SMA) 과 적응 이동 평균 (ALMA) 을 결합한 양적 거래 전략을 소개합니다. 이 전략은 여러 기술적 지표를 통합하고 다른 매개 변수 설정을 기반으로 거래 신호를 생성합니다.
I. 전략 원칙
이 전략의 핵심은 서로 다른 매개 변수 설정으로 SMA와 ALMA의 조합이다. SMA는 한 기간 동안 폐쇄 가격의 수학적 평균을 계산함으로써 트렌드의 방향과 동력을 보여주는 매우 일반적인 트렌드 추적 지표이다. ALMA는 역사적 가격을 평균하는 SMA와 유사하지만, 2 개의 조정 가능한 매개 변수 α와 σ를 추가하여 SMA보다 시장 변화에 더 민감하게 반응한다.
이 전략은 먼저 각각 단기, 중기 및 장기 트렌드를 나타내는 세 개의 SMA를 계산합니다. 동시에 다른 시간 프레임에서 움직이는 평균을 나타내는 세 개의 ALMA를 계산합니다. SMA와 ALMA 사이의 크로스오버는 여러 세트의 지표를 형성합니다. 단기 SMA가 중기 SMA를 넘을 때 구매 신호가 생성됩니다. 단기 SMA가 중기 SMA를 넘을 때 판매 신호가 생성됩니다. ALMA의 조정 가능한 매개 변수로 인해 신호는 시장에 더 빠르게 반응 할 수 있습니다.
또한, 상대적 강도 지수 (RSI) 는 과잉 구매 및 과잉 판매 조건을 식별하는 데 도움을 주기 위해 도입된다. RSI가 과잉 구매 임계보다 높을 때, 시장은 과잉 구매로 간주된다. 이 경우, SMA와 ALMA가 구매 신호를 생성하더라도 오해할 수 있다. 마찬가지로, RSI가 과잉 판매 라인보다 낮을 때, 지표의 판매 신호는 리바운드를 놓칠 수 있다. 따라서 RSI의 보조 판단은 특정 포획 위험을 피할 수 있다.
SMA, ALMA 및 RSI의 매개 변수 설정을 포괄적으로 활용하고 다른 매개 변수의 지표 간의 교차 조합을 통해 상대적으로 민감한 거래 전략 신호를 형성 할 수 있습니다. 또한, RSI의 과잉 구매 및 과잉 판매 판단은 진입 시기를 더욱 최적화하고 함락 가능성을 줄일 수 있습니다.
II. 전략의 장점
이 전략의 가장 큰 장점은 지표 매개 변수들의 유연한 조합과 적용이다. SMA와 ALMA는 서로 다른 종류의 이동 평균을 표현하기 위해 매개 변수를 조정하는 데 유연하다. RSI는 또한 매개 변수를 조정함으로써 신호의 주파수를 제어할 수 있다. 이 지표들의 조합은 서로를 보완하고 입력 시기를 최적화할 수 있는 거래 신호를 형성한다.
단일 SMA 지표와 비교하면 ALMA는 시장 변화에 대한 민감성을 향상시키고 트렌드 반전에 더 빠르게 대응할 수 있습니다. 또한 보조 RSI 판단은 이동 평균의 신호를 맹목적으로 따르지 않습니다. 따라서이 전략은 전반적으로 상대적으로 강한 적응력과 최적화 기능을 가지고 있습니다.
또 다른 장점은 전략의 신호 소스의 다양성이다. 다른 시간 프레임에서 SMA와 ALMA 사이의 상호 작용은 전략에 대한 다층 참조를 제공합니다. 이것은 어느 정도 무작위 시장 소음을 필터링하고 신호를 더 신뢰할 수 있습니다.
일반적으로 이 전략은 유연한 매개 변수를 가지고 있고 안정적인 신호를 생성하여 다른 제품들을 통한 알고리즘 거래에 적합합니다.
III. 잠재적 위험
이 전략은 몇 가지 장점을 가지고 있지만 실제로 적용할 때 여전히 몇 가지 위험을 고려해야 합니다.
첫째, 지표 설정에 의한 과잉 최적화 문제. SMA, ALMA 및 RSI는 자유롭게 조정되지만 잘못된 조정으로 인해 과잉 최적화 및 시장의 장기적인 구조적 변화에 적응할 수 없습니다. 이것은 단순히 단기 결과를 추구하는 대신 다른 제품의 특성에 기반한 신중한 매개 변수 설정을 필요로합니다.
두 번째로, 전략 신호는 지연될 수 있다. ALMA가 SMA보다 더 빨리 반응하지만, 여전히 일정 지연이 있다. 빠르게 변화하는 시장에서, 이것은 최적의 진입 시기를 놓치는 결과를 초래할 수 있다. 여기서 우리는 최적화하기 위해 몇 가지 주요 지표를 결합하는 것을 고려할 수 있다.
마지막으로, 여러 지표에서 나오는 모순적인 신호에 주의를 기울여야 합니다. 특정 시점에서는 다른 지표가 모순적인 지표를 줄 수 있습니다. 이를 해결하기 위해서는 경험에 기반한 명확한 우선 순위 규칙이 필요합니다.
요약하자면, 이 전략은 완벽하지 않으며 실제로는 지속적인 조정과 최적화를 요구합니다. 그러나 유연한 매개 변수 설정과 여러 지표 조합의 장점은 장기적으로 실행 가능한 알고리즘 거래 시스템을 만듭니다.
IV. 요약
이 기사에서는 SMA, ALMA, RSI를 결합한 양적 거래 전략을 상세히 소개했습니다. 가변적인 지표 조합을 통해 시장에 민감한 신호를 형성합니다. 단일 지표와 비교하면 더 강력한 적응력과 노이즈 필터링 기능을 가지고 있습니다. 그러나 우리는 과도한 최적화, 신호 지연 및 판단 오류와 같은 잠재적 문제에 대해서도 주의를 기울여야합니다. 전반적으로이 전략은 합리적으로 구성되어 있으며 지속적인 최적화로 안정적인 알고리즘 거래 신호를 생성 할 수 있습니다.
/*backtest start: 2023-09-06 00:00:00 end: 2023-09-13 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //The plotchar UP/DOWN Arrows is the crossover of the fastest MA and fastest IIR MAs // //The dots at the bottom are the two simple averages crossing over // //The count over/under the candles is the count of bars that the SMAs on their //respective resolution are fanning out. // //The colored background indicates a squeeze, lime=kinda tight : green=very tight squeeze. based on the 3 IIRs // //To answer my own question in a forum, looking at the code, i couldn't figure out how to get it from another timeframe //and run the same calculations with the same results. My answer in the end was to scale the chosen MA length //in the corresponding CurrentPeriod/ChosenMAPeriod proportion. This results in the same line in the same place when browsing through the //different time resolutions. Somebody might find this invaluable // //The counts are for MA's fanning out, or going parabolic. Theres IIRs, Almas, one done of the other. A lot. //The arrows above and below bars are from standard RSI numbers for OB/OS // //The IIRs changes color depending on their slope, which can be referenced easily with a variable. // //The backgrond on a bar-by-bar basis is colored when 2 sets of moving averages are in a squeeze, aka //when price is consolidating. // //This aims to help the trader combine conditions and entry criteria of the trade and explore these options visually. //They detail things from all time-frames on the current one. I prefer it because of the fractal nature of price-action, both large and small, //either yesterday or last year. For best results, go long in short-term trades when the long-term trend is also up. //and other profitable insights. This is also a great example of an automation algorith. // //The pretty ribbon is my script called 'Trading With Colors'. Use them together for fanciest results. 55/233 is my Fib Cross (golden/death) Compare it to the classic 50/200 if //you get bored. I believe it simply works better, at least for Crypto. // //Evidently, I am a day-trader. But this yields higher profits on larger time-frames anyways, so do play around with it. Find what works for you. //Thanks and credit for code snippets goes to: //matryskowal //ChrisMoody, probably twice //Alex Orekhov (everget) //author=LucF and midtownsk8rguy, for PineCoders //If you use code from this, real quick search for perhaps the original and give them a shoutout too. I may have missed something //Author: Sean Duffy //@version=4 strategy(title = "Combination Parabolic MA/IIR/ALMA Strategy", shorttitle = "MA-QuickE", overlay = true, backtest_fill_limits_assumption = 0, default_qty_type = strategy.cash, default_qty_value = 1000, initial_capital = 1000, currency = currency.USD, linktoseries = true) // calc_on_order_fills = true, // calc_on_every_tick = true, // Input Variables showFIBMAs = input(false, type=input.bool, title="═══════════════ Show Fibby MAs ═══════════════") maRes = input(960, type=input.integer, title="MA-Cross Resolution") mal1 = input(8, type=input.integer, title="MA#1 Length") mal2 = input(13, type=input.integer, title="MA#2 Length") mal3 = input(34, type=input.integer, title="MA#3 Length") loosePercentClose = input(1.1, type=input.float, title="SMA LooseSqueeze Percent") showIIRs = input(false, type=input.bool, title="═══════════════════ Show IIRs ═══════════════════") iirRes = input(60, type=input.integer, title="IIR Resolution") percentClose = input(title="IIR Squeeze PercentClose", type=input.float, defval=.8) iirlength1 = input(title="IIR Length 1", type=input.integer, defval=34) iirlength2 = input(title="IIR Length 2", type=input.integer, defval=144)//input(title="ATR Period", type=input.integer, defval=1) iirlength3 = input(title="IIR Length 3", type=input.integer, defval=720)//input(title="ATR Period", type=input.integer, defval=1) showIIR1 = input(true, type=input.bool, title="Show IIR1") showIIR2 = input(true, type=input.bool, title="Show IIR2") showIIR3 = input(true, type=input.bool, title="Show IIR3") showCounts = input(true, type=input.bool, title="═════════════ Show Parabolic MA Counts ════════════") showSignals = input(true, type=input.bool, title="══════════════ Show Buy/Sell Signals ══════════════") showBackground = input(true, type=input.bool, title="══════════════ Show Background Colors ══════════════") //runStrategy = input(true, type=input.bool, title="══════════════ Run Strategy ══════════════") debug = input(false, type=input.bool, title="══════════════ Show Debug ══════════════") barLookbackPeriod = input(title="══ Bar Lookback Period ══", type=input.integer, defval=5) percentageLookbackPeriod = input(title="══ Percentage Lookback Period ══", type=input.integer, defval=1) bullcolor = color.green bearcolor = color.red color bgcolor = na var bool slope1Green = na var bool slope2Green = na var bool slope3Green = na var bool buySignal = na var bool sellSignal = na var bool bigbuySignal = na var bool bigsellSignal = na bool smbuySignal = false bool smsellSignal = false var bool insqueeze = na var bool intightsqueeze = na var bool infastsqueeze = na var bool awaitingEntryIn = false // My counting variables var int count1 = 0 var float madist1 = 0 var int count2 = 0 var float madist2 = 0 var int sinceSmSignal = 0 var entryPrice = 0.0 var entryBarIndex = 0 var stopLossPrice = 0.0 // var updatedEntryPrice = 0.0 // var alertOpenPosition = false // var alertClosePosition = false // var label stopLossPriceLabel = na // var line stopLossPriceLine = na positionType = "LONG" // Strategy type, and the only current option hasOpenPosition = strategy.opentrades != 0 hasNoOpenPosition = strategy.opentrades == 0 strategyClose() => if (hasOpenPosition) if positionType == "LONG" strategy.close("LONG", when=true) else strategy.close("SHORT", when=true) strategyOpen() => if (hasNoOpenPosition) if positionType == "LONG" strategy.entry("LONG", strategy.long, when=true) else strategy.entry("SHORT", strategy.short, when=true) checkEntry() => buysignal = false if (hasNoOpenPosition) strategyOpen() buysignal := true // if (slope1Green and (trend1Green or trend2Green) and awaitingEntryIn and hasNoOpenPosition) // strategyOpen() // buysignal := true buysignal checkExit() => sellsignal = false // if (trend1Green == false and trend2Green == false) // to later have quicker exit strategy // sellsignal := true // strategyClose() if (hasOpenPosition) sellsignal := true strategyClose() sellsignal multiplier(_adjRes, _adjLength) => // returns adjusted length multiplier = _adjRes/timeframe.multiplier round(_adjLength*multiplier) //reset the var variables before new calculations buySignal := false sellSignal := false smbuySignal := false smsellSignal := false bigbuySignal := false bigsellSignal := false ma1 = sma(close, multiplier(maRes, mal1)) ma2 = sma(close, multiplier(maRes, mal2)) ma3 = sma(close, multiplier(maRes, mal3)) madist1 := abs(ma1 - ma2) madist2 := abs(ma1 - ma3) // check if MA's are fanning/going parabolic if (ma1 >= ma2 and ma2 >= ma3 and madist1[0] > madist1[1]) //and abs(dataB - dataC >= madist2) // dataA must be higher than b, and distance between gaining, same with C count1 := count1 + 1 else count1 := 0 if (ma1 <= ma2 and ma2 <= ma3 and madist1[0] > madist1[1]) //<= madist2 and dataB <= dataC) //and abs(dataB - dataC >= madist2) // dataA must be higher than b, and distance between gaining, same with C count2 := count2 + 1 else count2 := 0 crossoverAB = crossover(ma1, ma2) crossunderAB = crossunder(ma1, ma2) plot(showFIBMAs ? ma1 : na, linewidth=3) plot(showFIBMAs ? ma2 : na) plot(showFIBMAs ? ma3 : na) // Fast Squeese Check WORK IN PROGRESS // float singlePercent = close / 100 if max(madist1, madist2) <= singlePercent*loosePercentClose bgcolor := color.yellow infastsqueeze := true else infastsqueeze := false // IIR MOVING AVERAGE f(a) => a[0] // fixes mutable error iirma(iirlength, iirsrc) => cf = 2*tan(2*3.14159*(1/iirlength)/2) a0 = 8 + 8*cf + 4*pow(cf,2) + pow(cf,3) a1 = -24 - 8*cf + 4*pow(cf,2) + 3*pow(cf,3) a2 = 24 - 8*cf - 4*pow(cf,2) + 3*pow(cf,3) a3 = -8 + 8*cf - 4*pow(cf,2) + pow(cf,3) //---- c = pow(cf,3)/a0 d0 = -a1/a0 d1 = -a2/a0 d2 = -a3/a0 //---- out = 0. out := nz(c*(iirsrc + iirsrc[3]) + 3*c*(iirsrc[1] + iirsrc[2]) + d0*out[1] + d1*out[2] + d2*out[3],iirsrc) f(out) iirma1 = iirma(multiplier(iirRes, iirlength1), close) iirma2 = iirma(multiplier(iirRes, iirlength2), close) iirma3 = iirma(multiplier(iirRes, iirlength3), close) // adjusts length for current resolution now, length is lengthened/shortened accordingly, upholding exact placement of lines // iirmaD1 = security(syminfo.tickerid, tostring(iirRes), iirma1, barmerge.gaps_on, barmerge.lookahead_on) // iirmaD2 = security(syminfo.tickerid, tostring(iirRes), iirma2, barmerge.gaps_on, barmerge.lookahead_on) // iirmaD3 = security(syminfo.tickerid, tostring(iirRes), iirma3, barmerge.gaps_on, barmerge.lookahead_on) slope1color = slope1Green ? color.lime : color.blue slope2color = slope2Green ? color.lime : color.blue slope3color = slope3Green ? color.lime : color.blue plot(showIIR1 and showIIRs ? iirma1 : na, title="IIR1", color=slope1color, linewidth=2, transp=30) plot(showIIR2 and showIIRs ? iirma2 : na, title="IIR2", color=slope2color, linewidth=3, transp=30) plot(showIIR3 and showIIRs ? iirma3 : na, title="IIR3", color=slope3color, linewidth=4, transp=30) // checks slope of IIRs to create a boolean variable and and color it differently if (iirma1[0] >= iirma1[1]) slope1Green := true else slope1Green := false if (iirma2[0] >= iirma2[1]) slope2Green := true else slope2Green := false if (iirma3[0] >= iirma3[1]) slope3Green := true else slope3Green := false // calculate space between IIRs and then if the price jumps above both //float singlePercent = close / 100 // = a single percent var float distIIR1 = na var float distIIR2 = na distIIR1 := abs(iirma1 - iirma2) distIIR2 := abs(iirma1 - iirma3) if (distIIR1[0] < percentClose*singlePercent and close[0] >= iirma1[0]) if close[0] >= iirma2[0] and close[0] >= iirma3[0] bgcolor := color.green insqueeze := true intightsqueeze := true else bgcolor := color.lime insqueeze := true intightsqueeze := false else insqueeze := false intightsqueeze := false // if (true)//sinceSmSignal > 0) // cutting down on fastest MAs noise // sinceSmSignal := sinceSmSignal + 1 // if (crossoverAB) // //checkEntry() // //smbuySignal := true // sinceSmSignal := 0 // if (crossunderAB) // and all NOT greennot (slope1Green and slope2Green and slope3Green) // //checkExit() // //smsellSignal := true // sinceSmSignal := 0 // else // sinceSmSignal := sinceSmSignal + 1 f_draw_infopanel(_x, _y, _line, _text, _color)=> _rep_text = "" for _l = 0 to _line _rep_text := _rep_text + "\n" _rep_text := _rep_text + _text var label _la = na label.delete(_la) _la := label.new( x=_x, y=_y, text=_rep_text, xloc=xloc.bar_time, yloc=yloc.price, color=color.black, style=label.style_labelup, textcolor=_color, size=size.normal) posx = timenow + round(change(time)*60) posy = highest(50) // CONSTRUCTION ZONE // TODO: program way to eliminate noise and false signals // MAYBEDO: program it to differentiate between a moving average bump and a cross // I think the best way would be to calculate the tangent line... OR // Take the slope of both going back a couple bars and if it's close enough, its a bounce off // and an excellent entry signal // program in quickest exit, 2 bars next to eachother both closing under, as to avoid a single wick from // prompting to close the trade // Some other time, have it move SMA up or down depending on whether trending up or down. Then use those MA crosses //THIS CHECKS THE SLOPE FROM CURRENT PRICE TO BACK 10 BARS checkSlope(_series) => (_series[0]/_series[10])*100 // it now returns it as a percentage doNewX = input(true, type=input.bool, title="══════════ Show misc MA Cross Strategy ══════════") iirX = input(13, title="IIRx Length: ", type=input.integer) iirXperiod = input(21, title="IIRx Period/TF: ", type=input.integer) iirX2 = input(144, title="IIRx2 Length: ", type=input.integer) iirX2period = input(233, title="IIRx2 Period/TF: ", type=input.integer) //15 almaXperiod = input(defval=21, title="Alma of IIR1 Period: ", type=input.integer) almaXalpha = input(title="Alma Alpha Value: ", defval=.99, maxval=.99, type=input.float) almaXsigma = input(title="Alma Sigma Value: ", defval=8, type=input.float) iirmaOTF = iirma(multiplier(iirXperiod, iirX), close) iirma2OTF = iirma(multiplier(iirX2period, iirX2), close) smaOTF = alma(iirmaOTF, almaXperiod, almaXalpha, almaXsigma) // maybe dont touch, its precise // I took the ALMA of the IIRMA, and i hope thats not cheating ;) // I could have removed this. the multiplier function adjusts the length to fit the current timeframe while displaying the same // smaXOTF = security(syminfo.tickerid, smaXperiod, smaOTF, barmerge.gaps_on, barmerge.lookahead_on) // iirmaXOTF = security(syminfo.tickerid, iirXperiod, iirmaOTF, barmerge.gaps_on, barmerge.lookahead_on) // iirmaX2OTF = security(syminfo.tickerid, iirX2period, iirma2OTF, barmerge.gaps_on, barmerge.lookahead_on) plot(doNewX ? smaOTF : na, title="FastMA X-Over : ", color=color.blue, linewidth=1, transp=40) plot(doNewX ? iirmaOTF : na, title="IIR MAx : ", color=color.purple, linewidth=1, transp=30) plot(doNewX ? iirma2OTF : na, title="IIR MAx : ", color=color.purple, linewidth=2, transp=20) iirma2Up = iirma2OTF[0] > iirma2OTF[1] // just another slope up/down variable. //calculate spaces between averages distiiralma = abs(iirmaOTF - smaOTF) crossoverFast = crossover(iirmaOTF[0], smaOTF[0]) // and (iirmaOTF[1] <= smaOTF[1]) crossunderFast = crossunder(iirmaOTF[0], smaOTF[0]) // and (iirmaOTF[1] >= smaOTF[1]) if (crossoverFast and iirma2Up == true) // and (count1 != 0))// or close[0] < (lowest(barLookbackPeriod) + singlePercent*3))) // must be at most a few percent up from a recent low. Avoid buying highs :P buySignal := true strategyOpen() // if (slope1Green and slope2Green and slope3Green and infastsqueeze == false) // checkEntry() if (crossunderFast) sellSignal := true checkExit() // I feel like I didn't cite the OG author for this panel correctly. I hope I did, but there are extentions of his/her work in multiple places. // I could have gotten it confused. if (debug) f_draw_infopanel(posx, posy, 18, "distiiralma from IIR: " + tostring(distiiralma), color.lime) //f_draw_infopanel(posx, posy, 16, "distiirs: " + tostring(distiirX1), color.lime) f_draw_infopanel(posx, posy, 14, "Value of iirmaOTF: " + tostring(iirmaOTF), color.lime) f_draw_infopanel(posx, posy, 6, "slope X: " + tostring(abs(100 - checkSlope(iirmaOTF))), color.lime) f_draw_infopanel(posx, posy, 12, "value of smaOTF: " + tostring(smaOTF), color.lime) f_draw_infopanel(posx, posy, 6, "slopeAlma: " + tostring(abs(100 - checkSlope(smaOTF))), color.lime) f_draw_infopanel(posx, posy, 2, "slopeIIR2 " + tostring(abs(100 - checkSlope(iirma2OTF))), color.lime) f_draw_infopanel(posx, posy, 2, "slopeIIR2 " + tostring(abs(100 - checkSlope(iirma2OTF))), color.lime) // I kept this separate because it discludes the calculations. Its hard to hold a train of thought while fishing for the right section bgcolor(showBackground ? bgcolor : na) plotshape(showSignals ? buySignal : na, location=location.bottom, style=shape.circle, text="", size=size.tiny, color=color.blue, transp=60) plotshape(showSignals ? sellSignal : na, location=location.bottom, style=shape.circle, text="", size=size.tiny, color=color.red, transp=60) plotchar(showSignals and smbuySignal, title="smBuy", location=location.belowbar, char='↑', size=size.tiny, color=color.green, transp=0) plotchar(showSignals and smsellSignal, title="smSell", location=location.abovebar, char='↓', size=size.tiny, color=color.orange, transp=0) // can not display a variable. Can only match the count to a corresponding plotchar // to display a non-constant variable, use the debug box, which was so kindly offered up by our community. plotchar(showCounts and count1==1, title='', char='1', location=location.belowbar, color=#2c9e2c, transp=0) plotchar(showCounts and count1==2, title='', char='2', location=location.belowbar, color=#2c9e2c, transp=0) plotchar(showCounts and count1==3, title='', char='3', location=location.belowbar, color=#2c9e2c, transp=0) plotchar(showCounts and count1==4, title='', char='4', location=location.belowbar, color=#2c9e2c, transp=0) plotchar(showCounts and count1==5, title='', char='5', location=location.belowbar, color=#2c9e2c, transp=0) plotchar(showCounts and count1==6, title='', char='6', location=location.belowbar, color=#2c9e2c, transp=0) plotchar(showCounts and count1==7, title='', char='7', location=location.belowbar, color=#2c9e2c, transp=0) plotchar(showCounts and count1==8, title='', char='8', location=location.belowbar, color=#2c9e2c, transp=0) plotchar(showCounts and count1==9, title='', char='9', location=location.belowbar, color=#2c9e2c, transp=0) plotchar(showCounts and count1>=10, title='', char='$', location=location.belowbar, color=#2c9e2c, transp=0) plotchar(showCounts and count2==1, title='', char='1', location=location.abovebar, color=#e91e63, transp=0) plotchar(showCounts and count2==2, title='', char='2', location=location.abovebar, color=#e91e63, transp=0) plotchar(showCounts and count2==3, title='', char='3', location=location.abovebar, color=#e91e63, transp=0) plotchar(showCounts and count2==4, title='', char='4', location=location.abovebar, color=#e91e63, transp=0) plotchar(showCounts and count2==5, title='', char='5', location=location.abovebar, color=#e91e63, transp=0) plotchar(showCounts and count2==6, title='', char='6', location=location.abovebar, color=#e91e63, transp=0) plotchar(showCounts and count2==7, title='', char='7', location=location.abovebar, color=#e91e63, transp=0) plotchar(showCounts and count2==8, title='', char='8', location=location.abovebar, color=#e91e63, transp=0) plotchar(showCounts and count2==9, title='', char='9', location=location.abovebar, color=#e91e63, transp=0) plotchar(showCounts and count2>=10, title='', char='$', location=location.abovebar, color=#e91e63, transp=0) showRSIind = input(true, type=input.bool, title="═══════════════════ Show RSI Arrows ═══════════════════") // Get user input rsiSource = input(title="RSI Source", type=input.source, defval=close) rsiLength = input(title="RSI Length", type=input.integer, defval=14) rsiOverbought = input(title="RSI Overbought Level", type=input.integer, defval=80) rsiOversold = input(title="RSI Oversold Level", type=input.integer, defval=20) // Get RSI value rsiValue = rsi(rsiSource, rsiLength) isRsiOB = rsiValue >= rsiOverbought isRsiOS = rsiValue <= rsiOversold // Plot signals to chart plotshape(isRsiOB, title="Overbought", location=location.abovebar, color=color.red, transp=0, style=shape.triangledown) plotshape(isRsiOS, title="Oversold", location=location.belowbar, color=color.green, transp=0, style=shape.triangleup) //reset the var variables before new calculations buySignal := false sellSignal := false smbuySignal := false smsellSignal := false bigbuySignal := false bigsellSignal := false