단순 이동 평균과 적응 이동 평균 전략을 결합

저자:차오장, 날짜: 2023-09-14 18:14:34
태그:

이 문서에서는 단순 이동 평균 (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


더 많은