본문 바로가기
트레이딩/차트 기초

트레이딩뷰 올인원 지표, 무료 버전에 여러 개 띄우기

by jonver 2026. 9. 24.

트레이딩뷰 올인원 지표, 무료 버전에 여러 개 띄우기

트레이딩뷰 무료 버전은 차트당 사용할 수 있는 지표가 2개로 제한된다. 이렇다 보니 무료 사용자들은 이동평균선, 볼린저 밴드, VWAP, RSI처럼 자주 쓰는 지표를 추가하는 것만으로도 차트 구성이 빠듯해진다. 지표를 바꿀 때마다 기존 지표를 지우고 다시 설정해야 하는 것도 번거롭다.

이번에 만든 JC MAIN과 JC SUB는 이 문제를 줄이기 위한 Pine Script다. 메인 차트에는 추세와 가격 위치를 보는 지표 20개, 아래 보조 패널에는 모멘텀·추세 강도·거래량을 확인하는 지표 20개를 포함한다.

트레이딩뷰 - 바로가기

올인원 스크립트에 포함된 지표

구분 메인 차트 보조 패널
01 지수이동평균선 (EMA) 상대강도지수 (RSI)
02 단순이동평균선 (SMA) 스토캐스틱 RSI (Stochastic RSI)
03 가중이동평균선 (WMA) 이동평균 수렴확산 (MACD)
04 헐 이동평균선 (HMA) 평균방향지수 / 방향성지수 (ADX / DMI)
05 거래량 가중 이동평균선 (VWMA) 평균진폭 (ATR)
06 볼린저 밴드 (Bollinger Bands) 상품채널지수 (CCI)
07 일목균형표 (Ichimoku Cloud) 자금흐름지수 (MFI)
08 거래량 가중 평균가격 (VWAP) 누적거래량 (OBV)
09 앵커드 VWAP (Anchored VWAP) 거래량 (Volume)
10 슈퍼트렌드 (Supertrend) 윌리엄스 %R (Williams %R)
11 파라볼릭 SAR (Parabolic SAR) 변화율 (ROC)
12 피벗 포인트 (Pivot Points) 모멘텀 (Momentum)
13 켈트너 채널 (Keltner Channels) 얼티밋 오실레이터 (Ultimate Oscillator)
14 돈치안 채널 (Donchian Channels) 어썸 오실레이터 (Awesome Oscillator)
15 이동평균 엔벨로프 (MA Envelope) 차이킨 머니 플로우 (Chaikin Money Flow)
16 지그재그 (Zig Zag) 차이킨 오실레이터 (Chaikin Oscillator)
17 선형회귀 채널 (Linear Regression Channel) 트릭스 (TRIX)
18 샹들리에 엑시트 (Chandelier Exit) 퍼센티지 프라이스 오실레이터 (PPO)
19 이동평균 리본 (MA Ribbon) 엘더 레이 (Elder Ray)
20 오토 키 레벨 (Auto Key Levels) 포스 인덱스 (Force Index)

메인 차트 지표는 필요한 항목을 여러 개 함께 켤 수 있고, 보조지표는 한 번에 하나씩 선택할 수 있다. Pine Script만으로 무료 버전의 하단 보조 패널을 여러 개 추가할 수는 없다. 그렇다고 하나의 패널에 RSI, MACD, 거래량처럼 스케일이 서로 다른 지표를 겹쳐 놓으면 제대로 읽을 수 없기 때문에 사실상 의미가 없어진다.

무료 버전에서는 메인 차트에 추세·가격 위치를 보는 지표를 필요한 만큼 조합하고, 아래 패널에는 지금 확인하려는 보조지표 하나만 표시하는 방식으로 활용할 수 있다. RSI가 필요할 때는 RSI를 보고, 거래량이나 MACD를 확인할 때는 설정에서 해당 지표로 바꿔 쓰면 된다.

올인원 지표를 차트에 추가하는 방법

1. 볼륨을 제외한 기존에 사용 중이던 지표를 잠시 모두 비활성화한 뒤 트레이딩뷰 차트 우측 하단 도구모음에서 Pine Editor를 연다.

우측 하단 도구모음에서 Pine 선택
우측 하단 도구모음에서 Pine 선택
트레이딩뷰 모바일 버전 파인 에디터 실행하는 방법
모바일 앱은 하단 ... 표시 누른 뒤 파인 에디터 선택

2. 기존 코드를 모두 지우고 아래 코드를 붙여 넣는다.

Pine Editor 기존 코드 삭제 후 JC MAIN 코드 붙여 넣기 및 차트에 적용하는 방법
Pine Editor 기존 코드 삭제 후 JC MAIN 코드 붙여 넣기 및 차트에 적용하는 방법

JC MAIN 코드 (차트 영역)

메인 차트에 표시되는 스크립트다. 처음 추가하면 EMA 5·20·60이 보이며, 설정 창에서 다른 지표를 켜거나 기간을 바꿀 수 있다.

//@version=6
indicator("JONVER CHAIN MAIN", shorttitle="JC MAIN", overlay=true, max_lines_count=500, max_labels_count=500, max_bars_back=5000)

plotDisplay  = display.all - display.status_line
inputDisplay = display.data_window

//=====================================================================
// 공통 함수
//=====================================================================

f_source(sourceType) =>
    switch sourceType
        "종가" => close
        "시가" => open
        "고가" => high
        "저가" => low
        "(고 + 저) / 2" => hl2
        "(고 + 저 + 종) / 3" => hlc3
        "(시 + 고 + 저 + 종) / 4" => ohlc4
        "(고 + 저 + 종 + 종) / 4" => hlcc4
        => close

f_ma(src, len, maType) =>
    switch maType
        "EMA"  => ta.ema(src, len)
        "SMA"  => ta.sma(src, len)
        "WMA"  => ta.wma(src, len)
        "VWMA" => ta.vwma(src, len)
        "RMA"  => ta.rma(src, len)
        => ta.sma(src, len)

f_donchianMid(len) =>
    math.avg(ta.lowest(low, len), ta.highest(high, len))

//=====================================================================
// ▼ 01. 지수이동평균선 (EMA)
//=====================================================================

g01 = "▼ 01. 지수이동평균선 (EMA)"

emaSourceType = input.string("종가", "기준 가격",
     options=["종가","시가","고가","저가","(고 + 저) / 2","(고 + 저 + 종) / 3","(시 + 고 + 저 + 종) / 4","(고 + 저 + 종 + 종) / 4"],
     group=g01, display=inputDisplay)

emaSource = f_source(emaSourceType)

ema1On = input.bool(true, "EMA 1 표시", group=g01, display=inputDisplay)
ema1Len = input.int(5, "EMA 1 기간", minval=1, group=g01, display=inputDisplay)

ema2On = input.bool(true, "EMA 2 표시", group=g01, display=inputDisplay)
ema2Len = input.int(20, "EMA 2 기간", minval=1, group=g01, display=inputDisplay)

ema3On = input.bool(true, "EMA 3 표시", group=g01, display=inputDisplay)
ema3Len = input.int(60, "EMA 3 기간", minval=1, group=g01, display=inputDisplay)

ema4On = input.bool(false, "EMA 4 표시", group=g01, display=inputDisplay)
ema4Len = input.int(120, "EMA 4 기간", minval=1, group=g01, display=inputDisplay)

ema5On = input.bool(false, "EMA 5 표시", group=g01, display=inputDisplay)
ema5Len = input.int(200, "EMA 5 기간", minval=1, group=g01, display=inputDisplay)

plot(ema1On ? ta.ema(emaSource, ema1Len) : na, "EMA 1", color=color.yellow, linewidth=2, display=plotDisplay)
plot(ema2On ? ta.ema(emaSource, ema2Len) : na, "EMA 2", color=color.orange, linewidth=2, display=plotDisplay)
plot(ema3On ? ta.ema(emaSource, ema3Len) : na, "EMA 3", color=color.red, linewidth=2, display=plotDisplay)
plot(ema4On ? ta.ema(emaSource, ema4Len) : na, "EMA 4", color=color.aqua, linewidth=2, display=plotDisplay)
plot(ema5On ? ta.ema(emaSource, ema5Len) : na, "EMA 5", color=color.purple, linewidth=2, display=plotDisplay)

//=====================================================================
// ▼ 02. 단순이동평균선 (SMA)
//=====================================================================

g02 = "▼ 02. 단순이동평균선 (SMA)"

smaSourceType = input.string("종가", "기준 가격",
     options=["종가","시가","고가","저가","(고 + 저) / 2","(고 + 저 + 종) / 3","(시 + 고 + 저 + 종) / 4","(고 + 저 + 종 + 종) / 4"],
     group=g02, display=inputDisplay)

smaSource = f_source(smaSourceType)

sma1On = input.bool(false, "SMA 1 표시", group=g02, display=inputDisplay)
sma1Len = input.int(5, "SMA 1 기간", minval=1, group=g02, display=inputDisplay)

sma2On = input.bool(false, "SMA 2 표시", group=g02, display=inputDisplay)
sma2Len = input.int(20, "SMA 2 기간", minval=1, group=g02, display=inputDisplay)

sma3On = input.bool(false, "SMA 3 표시", group=g02, display=inputDisplay)
sma3Len = input.int(60, "SMA 3 기간", minval=1, group=g02, display=inputDisplay)

sma4On = input.bool(false, "SMA 4 표시", group=g02, display=inputDisplay)
sma4Len = input.int(120, "SMA 4 기간", minval=1, group=g02, display=inputDisplay)

sma5On = input.bool(false, "SMA 5 표시", group=g02, display=inputDisplay)
sma5Len = input.int(200, "SMA 5 기간", minval=1, group=g02, display=inputDisplay)

plot(sma1On ? ta.sma(smaSource, sma1Len) : na, "SMA 1", color=color.blue, linewidth=2, display=plotDisplay)
plot(sma2On ? ta.sma(smaSource, sma2Len) : na, "SMA 2", color=color.teal, linewidth=2, display=plotDisplay)
plot(sma3On ? ta.sma(smaSource, sma3Len) : na, "SMA 3", color=color.fuchsia, linewidth=2, display=plotDisplay)
plot(sma4On ? ta.sma(smaSource, sma4Len) : na, "SMA 4", color=color.gray, linewidth=2, display=plotDisplay)
plot(sma5On ? ta.sma(smaSource, sma5Len) : na, "SMA 5", color=color.silver, linewidth=2, display=plotDisplay)

//=====================================================================
// ▼ 03. 가중이동평균선 (WMA)
//=====================================================================

g03 = "▼ 03. 가중이동평균선 (WMA)"

wmaOn = input.bool(false, "WMA 표시", group=g03, display=inputDisplay)

wmaSourceType = input.string("종가", "기준 가격",
     options=["종가","시가","고가","저가","(고 + 저) / 2","(고 + 저 + 종) / 3","(시 + 고 + 저 + 종) / 4","(고 + 저 + 종 + 종) / 4"],
     group=g03, display=inputDisplay)

wmaLen = input.int(20, "기간", minval=1, group=g03, display=inputDisplay)
wmaOffset = input.int(0, "오프셋", minval=-500, maxval=500, group=g03, display=inputDisplay)

wmaSource = f_source(wmaSourceType)

plot(wmaOn ? ta.wma(wmaSource, wmaLen) : na, "WMA",
     color=color.blue, linewidth=2, offset=wmaOffset, display=plotDisplay)

//=====================================================================
// ▼ 04. 헐 이동평균선 (HMA)
//=====================================================================

g04 = "▼ 04. 헐 이동평균선 (HMA)"

hmaOn = input.bool(false, "HMA 표시", group=g04, display=inputDisplay)

hmaSourceType = input.string("종가", "기준 가격",
     options=["종가","시가","고가","저가","(고 + 저) / 2","(고 + 저 + 종) / 3","(시 + 고 + 저 + 종) / 4","(고 + 저 + 종 + 종) / 4"],
     group=g04, display=inputDisplay)

hmaLen = input.int(55, "기간", minval=1, group=g04, display=inputDisplay)
hmaOffset = input.int(0, "오프셋", minval=-500, maxval=500, group=g04, display=inputDisplay)

hmaSource = f_source(hmaSourceType)

plot(hmaOn ? ta.hma(hmaSource, hmaLen) : na, "HMA",
     color=color.aqua, linewidth=2, offset=hmaOffset, display=plotDisplay)

//=====================================================================
// ▼ 05. 거래량 가중 이동평균선 (VWMA)
//=====================================================================

g05 = "▼ 05. 거래량 가중 이동평균선 (VWMA)"

vwmaOn = input.bool(false, "VWMA 표시", group=g05, display=inputDisplay)

vwmaSourceType = input.string("종가", "기준 가격",
     options=["종가","시가","고가","저가","(고 + 저) / 2","(고 + 저 + 종) / 3","(시 + 고 + 저 + 종) / 4","(고 + 저 + 종 + 종) / 4"],
     group=g05, display=inputDisplay)

vwmaLen = input.int(20, "기간", minval=1, group=g05, display=inputDisplay)
vwmaOffset = input.int(0, "오프셋", minval=-500, maxval=500, group=g05, display=inputDisplay)

vwmaSource = f_source(vwmaSourceType)

plot(vwmaOn ? ta.vwma(vwmaSource, vwmaLen) : na, "VWMA",
     color=color.purple, linewidth=2, offset=vwmaOffset, display=plotDisplay)

//=====================================================================
// ▼ 06. 볼린저 밴드 (BOLLINGER BANDS)
//=====================================================================

g06 = "▼ 06. 볼린저 밴드 (BOLLINGER BANDS)"

bbOn = input.bool(false, "볼린저 밴드 표시", group=g06, display=inputDisplay)

bbSourceType = input.string("종가", "기준 가격",
     options=["종가","시가","고가","저가","(고 + 저) / 2","(고 + 저 + 종) / 3","(시 + 고 + 저 + 종) / 4","(고 + 저 + 종 + 종) / 4"],
     group=g06, display=inputDisplay)

bbMAType = input.string("SMA", "이동평균 종류",
     options=["SMA","EMA","WMA","VWMA","RMA"],
     group=g06, display=inputDisplay)

bbLen = input.int(20, "기간", minval=1, group=g06, display=inputDisplay)
bbMult = input.float(2.0, "표준편차 배수", minval=0.1, step=0.1, group=g06, display=inputDisplay)

bbBasisOn = input.bool(true, "중심선 표시", group=g06, display=inputDisplay)
bbUpperOn = input.bool(true, "상단 밴드 표시", group=g06, display=inputDisplay)
bbLowerOn = input.bool(true, "하단 밴드 표시", group=g06, display=inputDisplay)
bbFillOn = input.bool(true, "밴드 영역 표시", group=g06, display=inputDisplay)

bbOffset = input.int(0, "오프셋", minval=-500, maxval=500, group=g06, display=inputDisplay)

bbSource = f_source(bbSourceType)
bbBasis = f_ma(bbSource, bbLen, bbMAType)
bbDev = ta.stdev(bbSource, bbLen) * bbMult

bbUpper = bbBasis + bbDev
bbLower = bbBasis - bbDev

bbU = plot(bbOn and bbUpperOn ? bbUpper : na, "BB 상단", color=color.blue, offset=bbOffset, display=plotDisplay)
plot(bbOn and bbBasisOn ? bbBasis : na, "BB 중심", color=color.gray, offset=bbOffset, display=plotDisplay)
bbL = plot(bbOn and bbLowerOn ? bbLower : na, "BB 하단", color=color.blue, offset=bbOffset, display=plotDisplay)

fill(bbU, bbL, color=color.new(color.blue, 90), title="BB 영역", show_last=bbFillOn ? 100000 : 0)

//=====================================================================
// ▼ 07. 일목균형표 (ICHIMOKU CLOUD)
//=====================================================================

g07 = "▼ 07. 일목균형표 (ICHIMOKU CLOUD)"

ichiOn = input.bool(false, "일목균형표 표시", group=g07, display=inputDisplay)

tenkanOn = input.bool(true, "전환선 표시", group=g07, display=inputDisplay)
kijunOn = input.bool(true, "기준선 표시", group=g07, display=inputDisplay)
spanAOn = input.bool(true, "선행스팬 A 표시", group=g07, display=inputDisplay)
spanBOn = input.bool(true, "선행스팬 B 표시", group=g07, display=inputDisplay)
chikouOn = input.bool(true, "후행스팬 표시", group=g07, display=inputDisplay)

tenkanLen = input.int(9, "전환선 기간", minval=1, group=g07, display=inputDisplay)
kijunLen = input.int(26, "기준선 기간", minval=1, group=g07, display=inputDisplay)
spanBLen = input.int(52, "선행스팬 B 기간", minval=1, group=g07, display=inputDisplay)
ichiDisp = input.int(26, "이동 기간", minval=1, group=g07, display=inputDisplay)

tenkan = f_donchianMid(tenkanLen)
kijun = f_donchianMid(kijunLen)
spanA = math.avg(tenkan, kijun)
spanB = f_donchianMid(spanBLen)

plot(ichiOn and tenkanOn ? tenkan : na, "전환선", color=color.blue, display=plotDisplay)
plot(ichiOn and kijunOn ? kijun : na, "기준선", color=color.red, display=plotDisplay)

ichiA = plot(ichiOn and spanAOn ? spanA : na, "선행스팬 A",
     color=color.green, offset=ichiDisp - 1, display=plotDisplay)

ichiB = plot(ichiOn and spanBOn ? spanB : na, "선행스팬 B",
     color=color.red, offset=ichiDisp - 1, display=plotDisplay)

plot(ichiOn and chikouOn ? close : na, "후행스팬",
     color=color.green, offset=-(ichiDisp - 1), display=plotDisplay)

fill(ichiA, ichiB, color=color.new(color.green, 88), title="일목 구름")

//=====================================================================
// ▼ 08. 거래량 가중 평균가격 (VWAP)
//=====================================================================

g08 = "▼ 08. 거래량 가중 평균가격 (VWAP)"

vwapOn = input.bool(false, "VWAP 표시", group=g08, display=inputDisplay)

vwapSourceType = input.string("(고 + 저 + 종) / 3", "기준 가격",
     options=["종가","시가","고가","저가","(고 + 저) / 2","(고 + 저 + 종) / 3","(시 + 고 + 저 + 종) / 4","(고 + 저 + 종 + 종) / 4"],
     group=g08, display=inputDisplay)

vwapOffset = input.int(0, "오프셋", minval=-500, maxval=500, group=g08, display=inputDisplay)

vwapSource = f_source(vwapSourceType)

plot(vwapOn ? ta.vwap(vwapSource) : na, "VWAP",
     color=color.fuchsia, linewidth=2, offset=vwapOffset, display=plotDisplay)

//=====================================================================
// ▼ 09. 앵커드 VWAP (ANCHORED VWAP)
//=====================================================================

g09 = "▼ 09. 앵커드 VWAP (ANCHORED VWAP)"

avwapOn = input.bool(false, "앵커드 VWAP 표시", group=g09, display=inputDisplay)

avwapSourceType = input.string("(고 + 저 + 종) / 3", "기준 가격",
     options=["종가","시가","고가","저가","(고 + 저) / 2","(고 + 저 + 종) / 3","(시 + 고 + 저 + 종) / 4","(고 + 저 + 종 + 종) / 4"],
     group=g09, display=inputDisplay)

anchorTime = input.time(timestamp("01 Jan 2026 00:00 +0000"), "앵커 시작 시점",
     group=g09, display=inputDisplay)

avwapSource = f_source(avwapSourceType)
anchorActive = time >= anchorTime

var float avwapPV = na
var float avwapVol = na

if not anchorActive
    avwapPV := na
    avwapVol := na
else
    avwapPV := nz(avwapPV) + avwapSource * volume
    avwapVol := nz(avwapVol) + volume

avwap = anchorActive and avwapVol > 0 ? avwapPV / avwapVol : na

plot(avwapOn ? avwap : na, "Anchored VWAP",
     color=color.orange, linewidth=2, display=plotDisplay)

//=====================================================================
// ▼ 10. 슈퍼트렌드 (SUPERTREND)
//=====================================================================

g10 = "▼ 10. 슈퍼트렌드 (SUPERTREND)"

stOn = input.bool(false, "슈퍼트렌드 표시", group=g10, display=inputDisplay)
stFactor = input.float(3.0, "ATR 배수", minval=0.1, step=0.1, group=g10, display=inputDisplay)
stATRLen = input.int(10, "ATR 기간", minval=1, group=g10, display=inputDisplay)

stUpOn = input.bool(true, "상승 추세선 표시", group=g10, display=inputDisplay)
stDownOn = input.bool(true, "하락 추세선 표시", group=g10, display=inputDisplay)

[stValue, stDirection] = ta.supertrend(stFactor, stATRLen)

plot(stOn and stUpOn and stDirection < 0 ? stValue : na,
     "Supertrend 상승", color=color.green, linewidth=2,
     style=plot.style_linebr, display=plotDisplay)

plot(stOn and stDownOn and stDirection >= 0 ? stValue : na,
     "Supertrend 하락", color=color.red, linewidth=2,
     style=plot.style_linebr, display=plotDisplay)

//=====================================================================
// ▼ 11. 파라볼릭 SAR (PARABOLIC SAR)
//=====================================================================

g11 = "▼ 11. 파라볼릭 SAR (PARABOLIC SAR)"

sarOn = input.bool(false, "Parabolic SAR 표시", group=g11, display=inputDisplay)
sarStart = input.float(0.02, "시작값", minval=0.001, step=0.01, group=g11, display=inputDisplay)
sarInc = input.float(0.02, "증가값", minval=0.001, step=0.01, group=g11, display=inputDisplay)
sarMax = input.float(0.20, "최대값", minval=0.01, step=0.01, group=g11, display=inputDisplay)

plot(sarOn ? ta.sar(sarStart, sarInc, sarMax) : na, "Parabolic SAR",
     color=color.orange, linewidth=2, style=plot.style_circles, display=plotDisplay)

//=====================================================================
// ▼ 12. 피벗 포인트 (PIVOT POINTS)
//=====================================================================

g12 = "▼ 12. 피벗 포인트 (PIVOT POINTS)"

pivotOn = input.bool(false, "피벗 포인트 표시", group=g12, display=inputDisplay)
pivotTF = input.timeframe("D", "기준 시간봉", group=g12, display=inputDisplay)

pivotPOn = input.bool(true, "P 표시", group=g12, display=inputDisplay)
pivotR1On = input.bool(true, "R1 표시", group=g12, display=inputDisplay)
pivotR2On = input.bool(true, "R2 표시", group=g12, display=inputDisplay)
pivotS1On = input.bool(true, "S1 표시", group=g12, display=inputDisplay)
pivotS2On = input.bool(true, "S2 표시", group=g12, display=inputDisplay)

// 피벗을 켠 경우에만 시간봉을 검증합니다.
if pivotOn and timeframe.in_seconds(pivotTF) < timeframe.in_seconds()
    runtime.error("피벗 기준 시간봉은 차트 시간봉 이상으로 선택해 주세요.")

[pHigh, pLow, pClose] = request.security(syminfo.tickerid, pivotTF,
     [high[1], low[1], close[1]], lookahead=barmerge.lookahead_on)

pivotP = (pHigh + pLow + pClose) / 3
pivotR1 = 2 * pivotP - pLow
pivotS1 = 2 * pivotP - pHigh
pivotR2 = pivotP + (pHigh - pLow)
pivotS2 = pivotP - (pHigh - pLow)

plot(pivotOn and pivotPOn ? pivotP : na, "Pivot P", color=color.yellow, style=plot.style_stepline, display=plotDisplay)
plot(pivotOn and pivotR1On ? pivotR1 : na, "Pivot R1", color=color.red, style=plot.style_stepline, display=plotDisplay)
plot(pivotOn and pivotR2On ? pivotR2 : na, "Pivot R2", color=color.maroon, style=plot.style_stepline, display=plotDisplay)
plot(pivotOn and pivotS1On ? pivotS1 : na, "Pivot S1", color=color.green, style=plot.style_stepline, display=plotDisplay)
plot(pivotOn and pivotS2On ? pivotS2 : na, "Pivot S2", color=color.teal, style=plot.style_stepline, display=plotDisplay)

//=====================================================================
// ▼ 13. 켈트너 채널 (KELTNER CHANNELS)
//=====================================================================

g13 = "▼ 13. 켈트너 채널 (KELTNER CHANNELS)"

kcOn = input.bool(false, "켈트너 채널 표시", group=g13, display=inputDisplay)

kcSourceType = input.string("종가", "기준 가격",
     options=["종가","시가","고가","저가","(고 + 저) / 2","(고 + 저 + 종) / 3","(시 + 고 + 저 + 종) / 4","(고 + 저 + 종 + 종) / 4"],
     group=g13, display=inputDisplay)

kcMAType = input.string("EMA", "중심선 종류",
     options=["EMA","SMA","WMA","VWMA","RMA"],
     group=g13, display=inputDisplay)

kcLen = input.int(20, "중심선 기간", minval=1, group=g13, display=inputDisplay)
kcATRLen = input.int(10, "ATR 기간", minval=1, group=g13, display=inputDisplay)
kcMult = input.float(2.0, "ATR 배수", minval=0.1, step=0.1, group=g13, display=inputDisplay)

kcBasisOn = input.bool(true, "중심선 표시", group=g13, display=inputDisplay)

kcSource = f_source(kcSourceType)
kcBasis = f_ma(kcSource, kcLen, kcMAType)
kcRange = ta.atr(kcATRLen) * kcMult

kcUpper = kcBasis + kcRange
kcLower = kcBasis - kcRange

kcU = plot(kcOn ? kcUpper : na, "KC 상단", color=color.orange, display=plotDisplay)
plot(kcOn and kcBasisOn ? kcBasis : na, "KC 중심", color=color.gray, display=plotDisplay)
kcL = plot(kcOn ? kcLower : na, "KC 하단", color=color.orange, display=plotDisplay)

fill(kcU, kcL, color=color.new(color.orange, 92), title="KC 영역")

//=====================================================================
// ▼ 14. 돈치안 채널 (DONCHIAN CHANNELS)
//=====================================================================

g14 = "▼ 14. 돈치안 채널 (DONCHIAN CHANNELS)"

dcOn = input.bool(false, "돈치안 채널 표시", group=g14, display=inputDisplay)
dcLen = input.int(20, "기간", minval=1, group=g14, display=inputDisplay)
dcMiddleOn = input.bool(true, "중심선 표시", group=g14, display=inputDisplay)
dcOffset = input.int(0, "오프셋", minval=-500, maxval=500, group=g14, display=inputDisplay)

dcUpper = ta.highest(high, dcLen)
dcLower = ta.lowest(low, dcLen)
dcMiddle = math.avg(dcUpper, dcLower)

dcU = plot(dcOn ? dcUpper : na, "Donchian 상단", color=color.blue, offset=dcOffset, display=plotDisplay)
plot(dcOn and dcMiddleOn ? dcMiddle : na, "Donchian 중심", color=color.gray, offset=dcOffset, display=plotDisplay)
dcL = plot(dcOn ? dcLower : na, "Donchian 하단", color=color.blue, offset=dcOffset, display=plotDisplay)

fill(dcU, dcL, color=color.new(color.blue, 94), title="Donchian 영역")

//=====================================================================
// ▼ 15. 이동평균 엔벨로프 (MA ENVELOPE)
//=====================================================================

g15 = "▼ 15. 이동평균 엔벨로프 (MA ENVELOPE)"

envOn = input.bool(false, "MA 엔벨로프 표시", group=g15, display=inputDisplay)

envSourceType = input.string("종가", "기준 가격",
     options=["종가","시가","고가","저가","(고 + 저) / 2","(고 + 저 + 종) / 3","(시 + 고 + 저 + 종) / 4","(고 + 저 + 종 + 종) / 4"],
     group=g15, display=inputDisplay)

envMAType = input.string("SMA", "이동평균 종류",
     options=["SMA","EMA","WMA","VWMA","RMA"],
     group=g15, display=inputDisplay)

envLen = input.int(20, "이동평균 기간", minval=1, group=g15, display=inputDisplay)
envPct = input.float(2.5, "밴드 폭 (%)", minval=0.1, step=0.1, group=g15, display=inputDisplay)
envBasisOn = input.bool(true, "중심선 표시", group=g15, display=inputDisplay)
envOffset = input.int(0, "오프셋", minval=-500, maxval=500, group=g15, display=inputDisplay)

envSource = f_source(envSourceType)
envBasis = f_ma(envSource, envLen, envMAType)

envUpper = envBasis * (1 + envPct / 100)
envLower = envBasis * (1 - envPct / 100)

envU = plot(envOn ? envUpper : na, "Envelope 상단", color=color.teal, offset=envOffset, display=plotDisplay)
plot(envOn and envBasisOn ? envBasis : na, "Envelope 중심", color=color.gray, offset=envOffset, display=plotDisplay)
envL = plot(envOn ? envLower : na, "Envelope 하단", color=color.teal, offset=envOffset, display=plotDisplay)

fill(envU, envL, color=color.new(color.teal, 94), title="Envelope 영역")

//=====================================================================
// ▼ 16. 지그재그 (ZIG ZAG)
//=====================================================================

g16 = "▼ 16. 지그재그 (ZIG ZAG)"

zigOn = input.bool(false, "지그재그 표시", group=g16, display=inputDisplay,
     tooltip="피벗은 오른쪽 봉이 지난 뒤 과거 위치에 표시됩니다. 마지막 실선 끝점은 더 큰 극점이 확인되면 이동할 수 있습니다.")

zigDev = input.float(5.0, "반전 기준 가격 편차 (%)",
     minval=0.1, step=0.1, group=g16, display=inputDisplay)

zigLeg = input.int(10, "피벗 레그", minval=2, maxval=500,
     group=g16, display=inputDisplay,
     tooltip="좌우 탐색 봉 수는 각각 floor(피벗 레그 / 2)입니다. 최대 500으로 제한합니다.")

zigProjectedOn = input.bool(true, "예상 피벗 계산",
     group=g16, display=inputDisplay,
     tooltip="점선은 미확정 예상 구간으로 실시간 가격에 따라 변경됩니다.")

zigPriceOn = input.bool(true, "반전 가격 표시",
     group=g16, display=inputDisplay)

zigVolumeOn = input.bool(true, "누적 거래량 표시",
     group=g16, display=inputDisplay,
     tooltip="시작 피벗 봉은 제외하고 끝 피벗 봉은 포함합니다. 거래량 누락 구간은 N/A로 표시합니다.")

zigChangeOn = input.bool(true, "반전 가격 변동 표시",
     group=g16, display=inputDisplay)

zigChangeMode = input.string("절대값", "가격 변동 표시 방식",
     options=["절대값", "퍼센트"], group=g16, display=inputDisplay)

zigTextSize = input.string("보통", "글자 크기",
     options=["작게", "보통", "크게"], group=g16, display=inputDisplay)

zigLabelSize = zigTextSize == "작게" ? size.small : zigTextSize == "크게" ? size.large : size.normal
zigDepth = math.max(1, int(math.floor(zigLeg / 2.0)))

f_zigDeviation(basePrice, newPrice) =>
    basePrice != 0 ? 100.0 * (newPrice - basePrice) / math.abs(basePrice) : na

f_zigVolumeText(vol) =>
    string txt = "N/A"

    if not na(vol)
        float av = math.abs(vol)
        txt := av >= 1000000000 ? str.tostring(vol / 1000000000, "#.###") + "B" : av >= 1000000 ? str.tostring(vol / 1000000, "#.###") + "M" : av >= 1000 ? str.tostring(vol / 1000, "#.###") + "K" : str.tostring(vol, "#")

    txt

f_zigLabelText(oldPrice, newPrice, vol) =>
    string txt = zigPriceOn ? str.tostring(newPrice, format.mintick) : ""

    if zigChangeOn and not na(oldPrice)
        float changeValue = zigChangeMode == "퍼센트" ? f_zigDeviation(oldPrice, newPrice) : newPrice - oldPrice
        string changeText = na(changeValue) ? "N/A" : zigChangeMode == "퍼센트" ? str.tostring(changeValue, "#.##") + "%" : str.tostring(changeValue, format.mintick)
        txt := txt + (txt == "" ? "" : " ") + "(" + changeText + ")"

    if zigVolumeOn
        txt := txt + (txt == "" ? "" : "\n") + f_zigVolumeText(vol)

    txt

// 원본의 동가 피벗 판정 규칙을 유지합니다.
f_zigPivot(src, length, isHigh) =>
    bool found = false
    float candidate = na

    if bar_index >= length * 2
        candidate := src[length]
        found := not na(candidate)

        for i = 0 to length - 1
            if na(src[i]) or (isHigh ? src[i] > candidate : src[i] < candidate)
                found := false

        for i = length + 1 to length * 2
            if na(src[i]) or (isHigh ? src[i] >= candidate : src[i] <= candidate)
                found := false

    found ? candidate : na

zigHighPrice = f_zigPivot(high, zigDepth, true)
zigLowPrice = f_zigPivot(low, zigDepth, false)

// 긴 구간을 volume[offset]으로 역조회하지 않습니다.
zigCumVol = ta.cum(nz(volume, 0.0))
zigCumMissing = ta.cum(na(volume) ? 1.0 : 0.0)

zigPivotCum = zigCumVol[zigDepth]
zigPivotMissing = zigCumMissing[zigDepth]
zigPivotTime = time[zigDepth]
zigPivotBar = bar_index - zigDepth

var array<line> zigLines = array.new_line()
var array<label> zigLabels = array.new_label()

var line zigLastLine = na
var label zigLastLabel = na
var line zigProjectionLine = na
var label zigProjectionLabel = na

var int zigLastBar = na
var int zigLastTime = na
var float zigLastPrice = na
var bool zigLastIsHigh = false
var float zigLastCum = na
var float zigLastMissing = na

var float zigLegStartPrice = na
var float zigLegStartCum = na
var float zigLegStartMissing = na

// 예상 끝점을 매 봉 누적 추적하므로 4999봉 이전 극점도 잃지 않습니다.
var float zigRunHigh = na
var float zigRunLow = na
var int zigRunHighTime = na
var int zigRunLowTime = na
var float zigRunHighCum = na
var float zigRunLowCum = na
var float zigRunHighMissing = na
var float zigRunLowMissing = na

bool zigChanged = false

// 한 봉이 고점과 저점에 동시에 해당하면 선후 관계를 알 수 없어 건너뜁니다.
bool zigHasHigh = not na(zigHighPrice)
bool zigHasLow = not na(zigLowPrice)

if zigOn and barstate.isconfirmed and zigHasHigh != zigHasLow
    bool nextIsHigh = zigHasHigh
    float nextPrice = nextIsHigh ? zigHighPrice : zigLowPrice
    bool accept = false
    bool createLeg = false

    if na(zigLastPrice)
        accept := true
    else if zigPivotBar > zigLastBar
        if nextIsHigh == zigLastIsHigh
            accept := nextIsHigh ? nextPrice > zigLastPrice : nextPrice < zigLastPrice
        else
            float deviation = f_zigDeviation(zigLastPrice, nextPrice)
            accept := not na(deviation) and (nextIsHigh ? deviation >= zigDev : deviation <= -zigDev)
            createLeg := accept

    if accept
        if createLeg
            zigLegStartPrice := zigLastPrice
            zigLegStartCum := zigLastCum
            zigLegStartMissing := zigLastMissing

            zigLastLine := line.new(
                 zigLastTime, zigLastPrice,
                 zigPivotTime, nextPrice,
                 xloc=xloc.bar_time,
                 color=color.orange,
                 width=2)

            array.push(zigLines, zigLastLine)
            zigLastLabel := na

        else if not na(zigLastLine)
            line.set_xy2(zigLastLine, zigPivotTime, nextPrice)

        if not na(zigLastLine)
            float segmentVolume = zigPivotMissing == zigLegStartMissing ? math.max(0.0, zigPivotCum - zigLegStartCum) : na
            string labelText = f_zigLabelText(zigLegStartPrice, nextPrice, segmentVolume)

            if labelText != ""
                if na(zigLastLabel)
                    zigLastLabel := label.new(
                         zigPivotTime,
                         nextPrice,
                         labelText,
                         xloc=xloc.bar_time,
                         style=label.style_none,
                         textcolor=nextIsHigh ? color.green : color.red,
                         size=zigLabelSize)

                    array.push(zigLabels, zigLastLabel)
                else
                    label.set_xy(zigLastLabel, zigPivotTime, nextPrice)
                    label.set_text(zigLastLabel, labelText)

        zigLastBar := zigPivotBar
        zigLastTime := zigPivotTime
        zigLastPrice := nextPrice
        zigLastIsHigh := nextIsHigh
        zigLastCum := zigPivotCum
        zigLastMissing := zigPivotMissing
        zigChanged := true

if zigOn and not na(zigLastPrice)
    if zigChanged
        zigRunHigh := na
        zigRunLow := na

    // 피벗 변경 시에만 피벗 이후의 짧은 확인 구간을 재구성합니다.
    int scanEnd = zigChanged ? zigDepth - 1 : 0

    for i = 0 to scanEnd
        if bar_index - i > zigLastBar
            if na(zigRunHigh) or high[i] > zigRunHigh
                zigRunHigh := high[i]
                zigRunHighTime := time[i]
                zigRunHighCum := zigCumVol[i]
                zigRunHighMissing := zigCumMissing[i]

            if na(zigRunLow) or low[i] < zigRunLow
                zigRunLow := low[i]
                zigRunLowTime := time[i]
                zigRunLowCum := zigCumVol[i]
                zigRunLowMissing := zigCumMissing[i]

if barstate.islast
    float projectionPrice = zigLastIsHigh ? zigRunLow : zigRunHigh
    int projectionTime = zigLastIsHigh ? zigRunLowTime : zigRunHighTime
    float projectionCum = zigLastIsHigh ? zigRunLowCum : zigRunHighCum
    float projectionMissing = zigLastIsHigh ? zigRunLowMissing : zigRunHighMissing
    float projectionDeviation = f_zigDeviation(zigLastPrice, projectionPrice)

    bool projectionReady = zigOn and zigProjectedOn and not na(zigLastPrice) and not na(projectionPrice) and not na(projectionDeviation)
    projectionReady := projectionReady and (zigLastIsHigh ? projectionDeviation <= -zigDev : projectionDeviation >= zigDev)

    if projectionReady
        if na(zigProjectionLine)
            zigProjectionLine := line.new(
                 zigLastTime, zigLastPrice,
                 projectionTime, projectionPrice,
                 xloc=xloc.bar_time,
                 color=color.orange,
                 width=2,
                 style=line.style_dashed)
        else
            line.set_xy1(zigProjectionLine, zigLastTime, zigLastPrice)
            line.set_xy2(zigProjectionLine, projectionTime, projectionPrice)

        float projectionVolume = projectionMissing == zigLastMissing ? math.max(0.0, projectionCum - zigLastCum) : na
        string projectionText = f_zigLabelText(zigLastPrice, projectionPrice, projectionVolume)

        if projectionText != ""
            if na(zigProjectionLabel)
                zigProjectionLabel := label.new(
                     projectionTime,
                     projectionPrice,
                     projectionText,
                     xloc=xloc.bar_time,
                     style=label.style_none,
                     size=zigLabelSize)

            label.set_xy(zigProjectionLabel, projectionTime, projectionPrice)
            label.set_text(zigProjectionLabel, projectionText)
            label.set_textcolor(zigProjectionLabel, zigLastIsHigh ? color.red : color.green)

        else if not na(zigProjectionLabel)
            label.delete(zigProjectionLabel)
            zigProjectionLabel := na

    else
        if not na(zigProjectionLine)
            line.delete(zigProjectionLine)
            zigProjectionLine := na

        if not na(zigProjectionLabel)
            label.delete(zigProjectionLabel)
            zigProjectionLabel := na

// 입력을 변경하면 스크립트 전체가 재실행되어 숨긴 지표의 객체도 초기화됩니다.
while array.size(zigLines) > 450
    line.delete(array.shift(zigLines))

while array.size(zigLabels) > 450
    label.delete(array.shift(zigLabels))

//=====================================================================
// ▼ 17. 선형회귀 채널 (LINEAR REGRESSION CHANNEL)
//=====================================================================

g17 = "▼ 17. 선형회귀 채널 (LINEAR REGRESSION CHANNEL)"

lrOn = input.bool(false, "선형회귀 채널 표시",
     group=g17, display=inputDisplay,
     tooltip="현재 회귀 구간의 직선과 잔차 표준편차 채널입니다. 새 봉과 실시간 가격에 따라 전체 구간이 다시 계산됩니다.")

lrSourceType = input.string("종가", "기준 가격",
     options=["종가","시가","고가","저가","(고 + 저) / 2","(고 + 저 + 종) / 3","(시 + 고 + 저 + 종) / 4","(고 + 저 + 종 + 종) / 4"],
     group=g17, display=inputDisplay)

lrLen = input.int(100, "회귀 기간", minval=2, maxval=2000,
     group=g17, display=inputDisplay)

lrMult = input.float(2.0, "표준편차 배수", minval=0.1, step=0.1,
     group=g17, display=inputDisplay)

lrBasisOn = input.bool(true, "회귀 중심선 표시",
     group=g17, display=inputDisplay)

lrExtendType = input.string("오른쪽", "확장 방향",
     options=["오른쪽", "왼쪽", "양쪽", "확장 없음"],
     group=g17, display=inputDisplay)

lrExtend = switch lrExtendType
    "오른쪽" => extend.right
    "왼쪽" => extend.left
    "양쪽" => extend.both
    => extend.none

lrSource = f_source(lrSourceType)

var line lrCenterLine = na
var line lrUpperLine = na
var line lrLowerLine = na
var linefill lrArea = na

if barstate.islast
    bool lrReady = lrOn and bar_index >= lrLen - 1
    float lrStart = na
    float lrEnd = na
    float lrWidth = na

    if lrReady
        // x=0은 현재 봉, x=lrLen-1은 가장 오래된 봉입니다.
        float sumY = 0.0
        float sumXY = 0.0

        for i = 0 to lrLen - 1
            float y = lrSource[i]

            if na(y)
                lrReady := false

            sumY += y
            sumXY += i * y

        if lrReady
            float n = float(lrLen)
            float sumX = n * (n - 1.0) / 2.0
            float sumXX = n * (n - 1.0) * (2.0 * n - 1.0) / 6.0

            float slope = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX)
            float intercept = (sumY - slope * sumX) / n

            float residualSum = 0.0

            for i = 0 to lrLen - 1
                float residual = lrSource[i] - (intercept + slope * i)
                residualSum += residual * residual

            lrEnd := intercept
            lrStart := intercept + slope * (n - 1.0)
            lrWidth := math.sqrt(math.max(0.0, residualSum / n)) * lrMult

    if lrReady
        int startBar = bar_index - lrLen + 1

        if na(lrCenterLine)
            lrCenterLine := line.new(
                 startBar, lrStart,
                 bar_index, lrEnd,
                 width=2,
                 extend=lrExtend)

            lrUpperLine := line.new(
                 startBar, lrStart + lrWidth,
                 bar_index, lrEnd + lrWidth,
                 color=color.teal,
                 extend=lrExtend)

            lrLowerLine := line.new(
                 startBar, lrStart - lrWidth,
                 bar_index, lrEnd - lrWidth,
                 color=color.teal,
                 extend=lrExtend)

            lrArea := linefill.new(
                 lrUpperLine,
                 lrLowerLine,
                 color.new(color.teal, 93))

        line.set_xy1(lrCenterLine, startBar, lrStart)
        line.set_xy2(lrCenterLine, bar_index, lrEnd)
        line.set_color(lrCenterLine, lrBasisOn ? color.yellow : na)
        line.set_extend(lrCenterLine, lrExtend)

        line.set_xy1(lrUpperLine, startBar, lrStart + lrWidth)
        line.set_xy2(lrUpperLine, bar_index, lrEnd + lrWidth)
        line.set_extend(lrUpperLine, lrExtend)

        line.set_xy1(lrLowerLine, startBar, lrStart - lrWidth)
        line.set_xy2(lrLowerLine, bar_index, lrEnd - lrWidth)
        line.set_extend(lrLowerLine, lrExtend)

    else
        if not na(lrArea)
            linefill.delete(lrArea)
            lrArea := na

        if not na(lrCenterLine)
            line.delete(lrCenterLine)
            line.delete(lrUpperLine)
            line.delete(lrLowerLine)

            lrCenterLine := na
            lrUpperLine := na
            lrLowerLine := na

//=====================================================================
// ▼ 18. 샹들리에 엑시트 (CHANDELIER EXIT)
//=====================================================================

g18 = "▼ 18. 샹들리에 엑시트 (CHANDELIER EXIT)"

ceOn = input.bool(false, "샹들리에 엑시트 표시", group=g18, display=inputDisplay)

ceLen = input.int(22, "고가/저가 탐색 기간", minval=1, group=g18, display=inputDisplay)
ceATRLen = input.int(22, "ATR 기간", minval=1, group=g18, display=inputDisplay)
ceMult = input.float(3.0, "ATR 배수", minval=0.1, step=0.1, group=g18, display=inputDisplay)

ceLongOn = input.bool(true, "롱 스톱 표시", group=g18, display=inputDisplay)
ceShortOn = input.bool(true, "숏 스톱 표시", group=g18, display=inputDisplay)
ceUseClose = input.bool(false, "고가/저가 대신 종가 사용", group=g18, display=inputDisplay)

ceATR = ta.atr(ceATRLen) * ceMult

ceHighest = ceUseClose ? ta.highest(close, ceLen) : ta.highest(high, ceLen)
ceLowest = ceUseClose ? ta.lowest(close, ceLen) : ta.lowest(low, ceLen)

ceLong = ceHighest - ceATR
ceShort = ceLowest + ceATR

plot(ceOn and ceLongOn ? ceLong : na, "Chandelier Long",
     color=color.green, linewidth=2, style=plot.style_linebr, display=plotDisplay)

plot(ceOn and ceShortOn ? ceShort : na, "Chandelier Short",
     color=color.red, linewidth=2, style=plot.style_linebr, display=plotDisplay)

//=====================================================================
// ▼ 19. 이동평균 리본 (MA RIBBON)
//=====================================================================

g19 = "▼ 19. 이동평균 리본 (MA RIBBON)"

ribbonOn = input.bool(false, "MA 리본 표시", group=g19, display=inputDisplay)

ribbonSourceType = input.string("종가", "기준 가격",
     options=["종가","시가","고가","저가","(고 + 저) / 2","(고 + 저 + 종) / 3","(시 + 고 + 저 + 종) / 4","(고 + 저 + 종 + 종) / 4"],
     group=g19, display=inputDisplay)

ribbonMAType = input.string("EMA", "이동평균 종류",
     options=["EMA","SMA","WMA","VWMA","RMA"],
     group=g19, display=inputDisplay)

ribbonLen1 = input.int(8, "MA 1 기간", minval=1, group=g19, display=inputDisplay)
ribbonLen2 = input.int(13, "MA 2 기간", minval=1, group=g19, display=inputDisplay)
ribbonLen3 = input.int(21, "MA 3 기간", minval=1, group=g19, display=inputDisplay)
ribbonLen4 = input.int(34, "MA 4 기간", minval=1, group=g19, display=inputDisplay)
ribbonLen5 = input.int(55, "MA 5 기간", minval=1, group=g19, display=inputDisplay)

ribbonSource = f_source(ribbonSourceType)

ribbon1 = f_ma(ribbonSource, ribbonLen1, ribbonMAType)
ribbon2 = f_ma(ribbonSource, ribbonLen2, ribbonMAType)
ribbon3 = f_ma(ribbonSource, ribbonLen3, ribbonMAType)
ribbon4 = f_ma(ribbonSource, ribbonLen4, ribbonMAType)
ribbon5 = f_ma(ribbonSource, ribbonLen5, ribbonMAType)

plot(ribbonOn ? ribbon1 : na, "Ribbon MA 1", color=color.yellow, linewidth=1, display=plotDisplay)
plot(ribbonOn ? ribbon2 : na, "Ribbon MA 2", color=color.orange, linewidth=1, display=plotDisplay)
plot(ribbonOn ? ribbon3 : na, "Ribbon MA 3", color=color.red, linewidth=1, display=plotDisplay)
plot(ribbonOn ? ribbon4 : na, "Ribbon MA 4", color=color.aqua, linewidth=1, display=plotDisplay)
plot(ribbonOn ? ribbon5 : na, "Ribbon MA 5", color=color.purple, linewidth=1, display=plotDisplay)

//=====================================================================
// ▼ 20. 오토 키 레벨 (AUTO KEY LEVELS)
//=====================================================================

g20 = "▼ 20. 오토 키 레벨 (AUTO KEY LEVELS)"

keyOn = input.bool(false, "오토 키 레벨 표시", group=g20, display=inputDisplay)

keyLen = input.int(
     100,
     "탐색 기간",
     minval=2,
     group=g20,
     display=inputDisplay)

keyHighOn = input.bool(
     true,
     "주요 고점 표시",
     group=g20,
     display=inputDisplay)

keyLowOn = input.bool(
     true,
     "주요 저점 표시",
     group=g20,
     display=inputDisplay)

keyMidOn = input.bool(
     true,
     "중간 레벨 표시",
     group=g20,
     display=inputDisplay)

keyHigh = ta.highest(high, keyLen)
keyLow = ta.lowest(low, keyLen)
keyMid = math.avg(keyHigh, keyLow)

plot(
     keyOn and keyHighOn ? keyHigh : na,
     "Auto Key High",
     color=color.red,
     linewidth=2,
     style=plot.style_stepline,
     display=plotDisplay)

plot(
     keyOn and keyLowOn ? keyLow : na,
     "Auto Key Low",
     color=color.green,
     linewidth=2,
     style=plot.style_stepline,
     display=plotDisplay)

plot(
     keyOn and keyMidOn ? keyMid : na,
     "Auto Key Mid",
     color=color.gray,
     linewidth=1,
     style=plot.style_stepline,
     display=plotDisplay)

3. 하단 패널에 들어갈 SUB 코드는 새로 만들기 - 인디케이터를 선택한 뒤 아래 코드를 붙여 넣는다.

새로 만들기 - 인디케이터를 선택한 뒤 아래 코드를 붙여 넣기
새로 만들기 - 인디케이터를 선택한 뒤 아래 코드를 붙여 넣기

JC SUB 코드 (하단 보조 패널)

보조 패널에 표시되는 스크립트다. 기본값은 RSI이며, 설정 창의 표시할 보조지표 메뉴에서 원하는 항목 하나를 선택할 수 있다.

//@version=6
indicator("JONVER CHAIN SUB", shorttitle="JC SUB", overlay=false, explicit_plot_zorder=true)

plotDisplay  = display.all - display.status_line
inputDisplay = display.data_window

// 계산 불가능한 값을 0으로 바꾸지 않습니다.
f_safeDiv(numerator, denominator) =>
    not na(numerator) and not na(denominator) and denominator != 0 ? numerator / denominator : na

// 연속된 유효 데이터가 부족하면 평활선도 표시하지 않습니다.
// 이 함수는 조건문 밖에서 매 봉 호출해야 합니다.
f_validSma(src, length) =>
    float average = ta.sma(src, length)
    float validCount = math.sum(not na(src) ? 1.0 : 0.0, length)
    validCount == length ? average : na

//=====================================================================
// 보조지표 선택
//=====================================================================

g00 = "▼ 보조지표 선택"

indicatorType = input.string(
     "RSI",
     "표시할 보조지표",
     options=[
         "RSI",
         "STOCHASTIC RSI",
         "MACD",
         "ADX / DMI",
         "ATR",
         "CCI",
         "MFI",
         "OBV",
         "VOLUME",
         "WILLIAMS %R",
         "ROC INDICATOR",
         "MOMENTUM",
         "ULTIMATE OSCILLATOR",
         "AWESOME OSCILLATOR",
         "CHAIKIN MONEY FLOW",
         "CHAIKIN OSCILLATOR",
         "TRIX INDICATOR",
         "PPO",
         "ELDER RAY",
         "FORCE INDEX"
     ],
     group=g00,
     display=inputDisplay)

//=====================================================================
// ▼ 01. 상대강도지수 (RSI)
//=====================================================================

g01 = "▼ 01. 상대강도지수 (RSI)"

rsiLen   = input.int(14, "RSI 기간", minval=1, group=g01, display=inputDisplay)
rsiOver  = input.float(70, "과매수", minval=0, maxval=100, group=g01, display=inputDisplay)
rsiMid   = input.float(50, "중앙선", minval=0, maxval=100, group=g01, display=inputDisplay)
rsiUnder = input.float(30, "과매도", minval=0, maxval=100, group=g01, display=inputDisplay)

showRSI = indicatorType == "RSI"
rsiValue = ta.rsi(close, rsiLen)

plot(showRSI ? rsiValue : na, "RSI", color=color.purple, linewidth=2, display=plotDisplay)
plot(showRSI ? rsiOver : na, "RSI 과매수", color=color.red, display=plotDisplay)
plot(showRSI ? rsiMid : na, "RSI 중앙선", color=color.gray, display=plotDisplay)
plot(showRSI ? rsiUnder : na, "RSI 과매도", color=color.green, display=plotDisplay)

//=====================================================================
// ▼ 02. 스토캐스틱 RSI (STOCHASTIC RSI)
//=====================================================================

g02 = "▼ 02. 스토캐스틱 RSI (STOCHASTIC RSI)"

stochRsiLen = input.int(14, "RSI 기간", minval=1, group=g02, display=inputDisplay)
stochLen    = input.int(14, "Stochastic 기간", minval=1, group=g02, display=inputDisplay)
stochKLen   = input.int(3, "%K 평활", minval=1, group=g02, display=inputDisplay)
stochDLen   = input.int(3, "%D 평활", minval=1, group=g02, display=inputDisplay)
stochOver   = input.float(80, "과매수", minval=0, maxval=100, group=g02, display=inputDisplay)
stochUnder  = input.float(20, "과매도", minval=0, maxval=100, group=g02, display=inputDisplay)

showStoch = indicatorType == "STOCHASTIC RSI"

stochRSIbase = ta.rsi(close, stochRsiLen)
stochLowest  = ta.lowest(stochRSIbase, stochLen)
stochHighest = ta.highest(stochRSIbase, stochLen)

stochRange = stochHighest - stochLowest
stochBaseCount = math.sum(not na(stochRSIbase) ? 1.0 : 0.0, stochLen)
stochRatio = f_safeDiv(100.0 * (stochRSIbase - stochLowest), stochRange)
stochRaw = stochBaseCount == stochLen ? stochRatio : na

stochK = f_validSma(stochRaw, stochKLen)
stochD = f_validSma(stochK, stochDLen)

plot(showStoch ? stochK : na, "Stoch RSI %K",
     color=color.blue, linewidth=2, style=plot.style_linebr, display=plotDisplay)

plot(showStoch ? stochD : na, "Stoch RSI %D",
     color=color.orange, linewidth=2, style=plot.style_linebr, display=plotDisplay)

plot(showStoch ? stochOver : na, "Stoch RSI 과매수", color=color.red, display=plotDisplay)
plot(showStoch ? stochUnder : na, "Stoch RSI 과매도", color=color.green, display=plotDisplay)

//=====================================================================
// ▼ 03. 이동평균 수렴확산 (MACD)
//=====================================================================

g03 = "▼ 03. 이동평균 수렴확산 (MACD)"

macdFast   = input.int(12, "빠른 EMA", minval=1, group=g03, display=inputDisplay)
macdSlow   = input.int(26, "느린 EMA", minval=1, group=g03, display=inputDisplay)
macdSignal = input.int(9, "시그널 기간", minval=1, group=g03, display=inputDisplay)

showMACD = indicatorType == "MACD"

[macdLine, signalLine, macdHist] = ta.macd(close, macdFast, macdSlow, macdSignal)

plot(showMACD ? macdLine : na, "MACD", color=color.blue, linewidth=2, display=plotDisplay)
plot(showMACD ? signalLine : na, "MACD Signal", color=color.orange, linewidth=2, display=plotDisplay)
plot(showMACD ? macdHist : na, "MACD Histogram", color=color.gray, style=plot.style_columns, display=plotDisplay)

//=====================================================================
// ▼ 04. 평균방향지수 / 방향성지수 (ADX / DMI)
//=====================================================================

g04 = "▼ 04. 평균방향지수 / 방향성지수 (ADX / DMI)"

dmiLen    = input.int(14, "DI 기간", minval=1, group=g04, display=inputDisplay)
adxSmooth = input.int(14, "ADX 평활", minval=1, group=g04, display=inputDisplay)
adxLevel  = input.float(25, "추세 기준선", minval=0, maxval=100, group=g04, display=inputDisplay)

showADX = indicatorType == "ADX / DMI"

[plusDI, minusDI, adxValue] = ta.dmi(dmiLen, adxSmooth)

plot(showADX ? plusDI : na, "+DI", color=color.green, linewidth=2, display=plotDisplay)
plot(showADX ? minusDI : na, "-DI", color=color.red, linewidth=2, display=plotDisplay)
plot(showADX ? adxValue : na, "ADX", color=color.blue, linewidth=2, display=plotDisplay)
plot(showADX ? adxLevel : na, "ADX 기준선", color=color.gray, display=plotDisplay)

//=====================================================================
// ▼ 05. 평균진폭 (ATR)
//=====================================================================

g05 = "▼ 05. 평균진폭 (ATR)"

atrLen = input.int(14, "ATR 기간", minval=1, group=g05, display=inputDisplay)

showATR = indicatorType == "ATR"
atrValue = ta.atr(atrLen)

plot(showATR ? atrValue : na, "ATR", color=color.orange, linewidth=2, display=plotDisplay)

//=====================================================================
// ▼ 06. 상품채널지수 (CCI)
//=====================================================================

g06 = "▼ 06. 상품채널지수 (CCI)"

cciLen   = input.int(20, "CCI 기간", minval=1, group=g06, display=inputDisplay)
cciUpper = input.float(100, "상단 기준", group=g06, display=inputDisplay)
cciLower = input.float(-100, "하단 기준", group=g06, display=inputDisplay)

showCCI = indicatorType == "CCI"
cciValue = ta.cci(hlc3, cciLen)

plot(showCCI ? cciValue : na, "CCI", color=color.blue, linewidth=2, display=plotDisplay)
plot(showCCI ? cciUpper : na, "CCI 상단", color=color.red, display=plotDisplay)
plot(showCCI ? 0 : na, "CCI 중앙선", color=color.gray, display=plotDisplay)
plot(showCCI ? cciLower : na, "CCI 하단", color=color.green, display=plotDisplay)

//=====================================================================
// ▼ 07. 자금흐름지수 (MFI)
//=====================================================================

g07 = "▼ 07. 자금흐름지수 (MFI)"

mfiLen   = input.int(14, "MFI 기간", minval=1, group=g07, display=inputDisplay)
mfiUpper = input.float(80, "과매수", minval=0, maxval=100, group=g07, display=inputDisplay)
mfiLower = input.float(20, "과매도", minval=0, maxval=100, group=g07, display=inputDisplay)

showMFI = indicatorType == "MFI"
mfiValue = ta.mfi(hlc3, mfiLen)

plot(showMFI ? mfiValue : na, "MFI", color=color.purple, linewidth=2, display=plotDisplay)
plot(showMFI ? mfiUpper : na, "MFI 과매수", color=color.red, display=plotDisplay)
plot(showMFI ? 50 : na, "MFI 중앙선", color=color.gray, display=plotDisplay)
plot(showMFI ? mfiLower : na, "MFI 과매도", color=color.green, display=plotDisplay)

//=====================================================================
// ▼ 08. 누적거래량 (OBV)
//=====================================================================

g08 = "▼ 08. 누적거래량 (OBV)"

obvMaLen = input.int(20, "OBV 이동평균 기간", minval=1, group=g08, display=inputDisplay)
obvMaOn  = input.bool(true, "OBV 이동평균 표시", group=g08, display=inputDisplay)

showOBV = indicatorType == "OBV"

obvValue = ta.cum(math.sign(ta.change(close)) * volume)
obvMA = ta.sma(obvValue, obvMaLen)

plot(showOBV ? obvValue : na, "OBV", color=color.blue, linewidth=2, display=plotDisplay)
plot(showOBV and obvMaOn ? obvMA : na, "OBV MA", color=color.orange, linewidth=2, display=plotDisplay)

//=====================================================================
// ▼ 09. 거래량 (VOLUME)
//=====================================================================

g09 = "▼ 09. 거래량 (VOLUME)"

volumeMaLen = input.int(20, "거래량 MA 기간", minval=1, group=g09, display=inputDisplay)
volumeMaOn  = input.bool(true, "거래량 MA 표시", group=g09, display=inputDisplay)

showVolume = indicatorType == "VOLUME"
volumeMA = ta.sma(volume, volumeMaLen)

plot(showVolume ? volume : na, "Volume", color=color.gray, style=plot.style_columns, display=plotDisplay)
plot(showVolume and volumeMaOn ? volumeMA : na, "Volume MA", color=color.orange, linewidth=2, display=plotDisplay)

//=====================================================================
// ▼ 10. 윌리엄스 %R (WILLIAMS %R)
//=====================================================================

g10 = "▼ 10. 윌리엄스 %R (WILLIAMS %R)"

wrLen = input.int(14, "기간", minval=1, group=g10, display=inputDisplay)

showWR = indicatorType == "WILLIAMS %R"

wrHighest = ta.highest(high, wrLen)
wrLowest  = ta.lowest(low, wrLen)
wrRange   = wrHighest - wrLowest
wrValue = f_safeDiv(-100.0 * (wrHighest - close), wrRange)

plot(showWR ? wrValue : na, "Williams %R",
     color=color.purple, linewidth=2, style=plot.style_linebr, display=plotDisplay)

plot(showWR ? -20 : na, "Williams 과매수", color=color.red, display=plotDisplay)
plot(showWR ? -50 : na, "Williams 중앙선", color=color.gray, display=plotDisplay)
plot(showWR ? -80 : na, "Williams 과매도", color=color.green, display=plotDisplay)

//=====================================================================
// ▼ 11. 변화율 (ROC)
//=====================================================================

g11 = "▼ 11. 변화율 (ROC)"

rocLen = input.int(12, "ROC 기간", minval=1, group=g11, display=inputDisplay)

showROC = indicatorType == "ROC INDICATOR"
rocValue = ta.roc(close, rocLen)

plot(showROC ? rocValue : na, "ROC", color=color.blue, linewidth=2, display=plotDisplay)
plot(showROC ? 0 : na, "ROC 기준선", color=color.gray, display=plotDisplay)

//=====================================================================
// ▼ 12. 모멘텀 (MOMENTUM)
//=====================================================================

g12 = "▼ 12. 모멘텀 (MOMENTUM)"

momLen = input.int(10, "Momentum 기간", minval=1, group=g12, display=inputDisplay)

showMomentum = indicatorType == "MOMENTUM"
momentumValue = ta.mom(close, momLen)

plot(showMomentum ? momentumValue : na, "Momentum", color=color.orange, linewidth=2, display=plotDisplay)
plot(showMomentum ? 0 : na, "Momentum 기준선", color=color.gray, display=plotDisplay)

//=====================================================================
// ▼ 13. 얼티밋 오실레이터 (ULTIMATE OSCILLATOR)
//=====================================================================

g13 = "▼ 13. 얼티밋 오실레이터 (ULTIMATE OSCILLATOR)"

uoFast = input.int(7, "단기 기간", minval=1, group=g13, display=inputDisplay)
uoMid  = input.int(14, "중기 기간", minval=1, group=g13, display=inputDisplay)
uoSlow = input.int(28, "장기 기간", minval=1, group=g13, display=inputDisplay)

showUO = indicatorType == "ULTIMATE OSCILLATOR"

uoPrevClose = nz(close[1], close)
uoBP = close - math.min(low, uoPrevClose)
uoTR = math.max(high, uoPrevClose) - math.min(low, uoPrevClose)

// 분자와 분모 모두 조건문 밖에서 매 봉 계산합니다.
uoFastTR = math.sum(uoTR, uoFast)
uoMidTR  = math.sum(uoTR, uoMid)
uoSlowTR = math.sum(uoTR, uoSlow)

uoFastBP = math.sum(uoBP, uoFast)
uoMidBP  = math.sum(uoBP, uoMid)
uoSlowBP = math.sum(uoBP, uoSlow)

uoAvgFast = f_safeDiv(uoFastBP, uoFastTR)
uoAvgMid  = f_safeDiv(uoMidBP, uoMidTR)
uoAvgSlow = f_safeDiv(uoSlowBP, uoSlowTR)

uoValue = 100 * (4 * uoAvgFast + 2 * uoAvgMid + uoAvgSlow) / 7

plot(showUO ? uoValue : na, "Ultimate Oscillator",
     color=color.purple, linewidth=2, style=plot.style_linebr, display=plotDisplay)

plot(showUO ? 70 : na, "UO 과매수", color=color.red, display=plotDisplay)
plot(showUO ? 50 : na, "UO 중앙선", color=color.gray, display=plotDisplay)
plot(showUO ? 30 : na, "UO 과매도", color=color.green, display=plotDisplay)

//=====================================================================
// ▼ 14. 어썸 오실레이터 (AWESOME OSCILLATOR)
//=====================================================================

g14 = "▼ 14. 어썸 오실레이터 (AWESOME OSCILLATOR)"

aoFast = input.int(5, "단기 SMA", minval=1, group=g14, display=inputDisplay)
aoSlow = input.int(34, "장기 SMA", minval=1, group=g14, display=inputDisplay)

showAO = indicatorType == "AWESOME OSCILLATOR"
aoValue = ta.sma(hl2, aoFast) - ta.sma(hl2, aoSlow)

plot(showAO ? aoValue : na, "Awesome Oscillator",
     color=color.teal, style=plot.style_columns, display=plotDisplay)

plot(showAO ? 0 : na, "AO 기준선", color=color.gray, display=plotDisplay)

//=====================================================================
// ▼ 15. 차이킨 머니 플로우 (CHAIKIN MONEY FLOW)
//=====================================================================

g15 = "▼ 15. 차이킨 머니 플로우 (CHAIKIN MONEY FLOW)"

cmfLen = input.int(20, "CMF 기간", minval=1, group=g15, display=inputDisplay)

showCMF = indicatorType == "CHAIKIN MONEY FLOW"

cmfRange = high - low

// 고가=저가인 봉의 자금흐름 기여는 0으로 처리합니다.
// 전체 기간의 거래량 합계가 0인 경우는 별도로 na 처리합니다.
cmfMultiplier = cmfRange != 0 ? ((close - low) - (high - close)) / cmfRange : 0
cmfMoneyVolume = cmfMultiplier * volume

cmfVolumeSum = math.sum(volume, cmfLen)
cmfMoneyVolumeSum = math.sum(cmfMoneyVolume, cmfLen)
cmfValue = f_safeDiv(cmfMoneyVolumeSum, cmfVolumeSum)

plot(showCMF ? cmfValue : na, "Chaikin Money Flow",
     color=color.blue, linewidth=2, style=plot.style_linebr, display=plotDisplay)

plot(showCMF ? 0 : na, "CMF 기준선", color=color.gray, display=plotDisplay)

//=====================================================================
// ▼ 16. 차이킨 오실레이터 (CHAIKIN OSCILLATOR)
//=====================================================================

g16 = "▼ 16. 차이킨 오실레이터 (CHAIKIN OSCILLATOR)"

choFast = input.int(3, "빠른 EMA", minval=1, group=g16, display=inputDisplay)
choSlow = input.int(10, "느린 EMA", minval=1, group=g16, display=inputDisplay)

showCHO = indicatorType == "CHAIKIN OSCILLATOR"

adRange = high - low
adMultiplier = adRange != 0 ? ((close - low) - (high - close)) / adRange : 0
adValue = ta.cum(adMultiplier * volume)

choValue = ta.ema(adValue, choFast) - ta.ema(adValue, choSlow)

plot(showCHO ? choValue : na, "Chaikin Oscillator",
     color=color.orange, linewidth=2, display=plotDisplay)

plot(showCHO ? 0 : na, "Chaikin 기준선", color=color.gray, display=plotDisplay)

//=====================================================================
// ▼ 17. 트릭스 (TRIX)
//=====================================================================

g17 = "▼ 17. 트릭스 (TRIX)"

trixLen       = input.int(15, "TRIX 기간", minval=1, group=g17, display=inputDisplay)
trixSignalLen = input.int(9, "시그널 기간", minval=1, group=g17, display=inputDisplay)
trixSignalOn  = input.bool(true, "시그널 표시", group=g17, display=inputDisplay)

showTRIX = indicatorType == "TRIX INDICATOR"

trixEMA1 = ta.ema(close, trixLen)
trixEMA2 = ta.ema(trixEMA1, trixLen)
trixEMA3 = ta.ema(trixEMA2, trixLen)

trixValue = f_safeDiv(100.0 * (trixEMA3 - trixEMA3[1]), trixEMA3[1])
trixSignalRaw = ta.ema(trixValue, trixSignalLen)
trixSignal = not na(trixValue) ? trixSignalRaw : na

plot(showTRIX ? trixValue : na, "TRIX",
     color=color.blue, linewidth=2, style=plot.style_linebr, display=plotDisplay)

plot(showTRIX and trixSignalOn ? trixSignal : na, "TRIX Signal",
     color=color.orange, linewidth=2, style=plot.style_linebr, display=plotDisplay)

plot(showTRIX ? 0 : na, "TRIX 기준선", color=color.gray, display=plotDisplay)

//=====================================================================
// ▼ 18. 퍼센티지 프라이스 오실레이터 (PPO)
//=====================================================================

g18 = "▼ 18. 퍼센티지 프라이스 오실레이터 (PPO)"

ppoFast      = input.int(12, "빠른 EMA", minval=1, group=g18, display=inputDisplay)
ppoSlow      = input.int(26, "느린 EMA", minval=1, group=g18, display=inputDisplay)
ppoSignalLen = input.int(9, "시그널 기간", minval=1, group=g18, display=inputDisplay)

showPPO = indicatorType == "PPO"

ppoFastEMA = ta.ema(close, ppoFast)
ppoSlowEMA = ta.ema(close, ppoSlow)

ppoValue = f_safeDiv(100.0 * (ppoFastEMA - ppoSlowEMA), ppoSlowEMA)
ppoSignalRaw = ta.ema(ppoValue, ppoSignalLen)
ppoSignal = not na(ppoValue) ? ppoSignalRaw : na
ppoHist = ppoValue - ppoSignal

plot(showPPO ? ppoValue : na, "PPO",
     color=color.blue, linewidth=2, style=plot.style_linebr, display=plotDisplay)

plot(showPPO ? ppoSignal : na, "PPO Signal",
     color=color.orange, linewidth=2, style=plot.style_linebr, display=plotDisplay)

plot(showPPO ? ppoHist : na, "PPO Histogram",
     color=color.gray, style=plot.style_columns, display=plotDisplay)

//=====================================================================
// ▼ 19. 엘더 레이 (ELDER RAY)
//=====================================================================

g19 = "▼ 19. 엘더 레이 (ELDER RAY)"

elderLen = input.int(13, "EMA 기간", minval=1, group=g19, display=inputDisplay)

showElder = indicatorType == "ELDER RAY"

elderEMA = ta.ema(close, elderLen)
bullPower = high - elderEMA
bearPower = low - elderEMA

// 넓은 Bear 막대 위에 좁은 Bull 막대를 그려 같은 부호여도 둘 다 보이게 합니다.
plot(showElder ? bearPower : na, "Bear Power",
     color=color.red, linewidth=6, style=plot.style_histogram, display=plotDisplay)

plot(showElder ? bullPower : na, "Bull Power",
     color=color.green, linewidth=2, style=plot.style_histogram, display=plotDisplay)

plot(showElder ? 0 : na, "Elder 기준선", color=color.gray, display=plotDisplay)

//=====================================================================
// ▼ 20. 포스 인덱스 (FORCE INDEX)
//=====================================================================

g20 = "▼ 20. 포스 인덱스 (FORCE INDEX)"

forceLen = input.int(13, "EMA 기간", minval=1, group=g20, display=inputDisplay)

showForce = indicatorType == "FORCE INDEX"

forceRaw = ta.change(close) * volume
forceValue = ta.ema(forceRaw, forceLen)

plot(showForce ? forceValue : na, "Force Index",
     color=color.blue, linewidth=2, display=plotDisplay)

plot(showForce ? 0 : na, "Force Index 기준선", color=color.gray, display=plotDisplay)

//=====================================================================
// 선택한 보조지표의 설정만 검증합니다.
//=====================================================================

if barstate.isfirst
    if showRSI and not (rsiUnder < rsiMid and rsiMid < rsiOver)
        runtime.error("RSI: 과매도 < 중앙선 < 과매수 순서로 설정해 주세요.")

    if showStoch and stochUnder >= stochOver
        runtime.error("Stoch RSI: 과매도는 과매수보다 작아야 합니다.")

    if showMACD and macdFast >= macdSlow
        runtime.error("MACD: 빠른 EMA 기간은 느린 EMA 기간보다 작아야 합니다.")

    if showCCI and not (cciLower < 0 and cciUpper > 0)
        runtime.error("CCI: 하단 기준 < 0 < 상단 기준으로 설정해 주세요.")

    if showMFI and not (mfiLower < 50 and mfiUpper > 50)
        runtime.error("MFI: 과매도 < 중앙선 50 < 과매수로 설정해 주세요.")

    if showUO and not (uoFast < uoMid and uoMid < uoSlow)
        runtime.error("Ultimate Oscillator: 단기 < 중기 < 장기 순서로 설정해 주세요.")

    if showAO and aoFast >= aoSlow
        runtime.error("Awesome Oscillator: 단기 SMA 기간은 장기 SMA 기간보다 작아야 합니다.")

    if showCHO and choFast >= choSlow
        runtime.error("Chaikin Oscillator: 빠른 EMA 기간은 느린 EMA 기간보다 작아야 합니다.")

    if showPPO and ppoFast >= ppoSlow
        runtime.error("PPO: 빠른 EMA 기간은 느린 EMA 기간보다 작아야 합니다.")

코드를 붙여 넣은 다음 저장을 누르고 차트에 추가를 선택한다. 메인 코드와 보조 코드 모두 같은 방식으로 추가하면 된다.

지표 ON/OFF 및 설정 방법

차트 왼쪽 상단의 JC MAIN 또는 JC SUB 이름을 더블 클릭하거나 옆의 톱니바퀴를 누르면 설정 창이 열린다. 두 스크립트 모두 같은 방식으로 설정할 수 있으며, 입력값 탭에서 원하는 항목만 선택하면 된다.

차트 영역, 하단 패널 좌측 상단 JC MAIN, JC SUB를 더블 클릭하거나 톱니바퀴 선택
차트 영역, 하단 패널 좌측 상단 JC MAIN, JC SUB를 더블 클릭하거나 톱니바퀴 선택
JC MAIN, JC SUB 보조지표 설정 방법
인풋 탭에서 사용할 지표를 ON/OFF 기준값을 설정, 모습 탭에서 색상을 변경.

메인 차트에서는 EMA, SMA, 볼린저 밴드, VWAP, 슈퍼트렌드처럼 필요한 지표를 여러 개 함께 켤 수 있다. EMA는 기본으로 활성화돼 있고 5·20·60 기간을 사용한다. 보조 패널에서는 맨 위의 표시할 보조지표 메뉴에서 RSI, MACD, ADX / DMI, 거래량 등 한 가지를 골라 볼 수 있다. 상단 인풋 탭에서 지표를 ON/OFF, 기준값을 조정할 수 있고 모습 탭에서 색상을 변경할 수 있다.

처음부터 모든 항목을 켜기보다, 메인 차트에서는 추세와 가격 위치를 확인할 지표 두세 개를 고르고, 아래 패널에서는 지금 필요한 보조지표 하나만 선택하는 편이 차트를 읽기 편하다.

차트 우측 영역 우클릭 - 라벨 - 인디케이터 관련 라벨 모두 체크 해제하기
차트 우측 영역 우클릭 - 라벨 - 인디케이터 관련 라벨 모두 체크 해제하기

새로운 이동평균선이나 지표를 추가한 뒤 위 이미지처럼 가격 영역이 지저분해졌다면, 차트 우측 가격 영역에서 우클릭한 뒤 라벨로 들어가 인디케이터 관련 라벨의 체크를 해제하면 깔끔하게 정리할 수 있다.

※ 스크립트는 여러 환경에서 검수를 마쳤지만, 트레이딩뷰 업데이트나 종목·시간봉·설정값 등에 따라 일부 기능이 정상적으로 작동하지 않거나 오류가 발생할 수 있습니다.