# Deepwick Script

Deepwick Script는 Deepwick 차트와 백테스트의 언어입니다. Pine Script v5/v6의
**부분집합**입니다: `ta.*`, `math.*`, `str.*`, `array.*`, `map.*`, `input.*`, `plot*`, `strategy.*`
호출 대부분이 Pine에서와 똑같이 동작합니다. Deepwick는 TradingView와 제휴하지 않으며
Pine Script는 TradingView, Inc.의 상표입니다.

스크립트는 가장 오래된 봉부터 가장 최근 봉까지 한 봉에 한 번 실행되고, 모든 변수는
기록을 유지합니다. Pine과 같은 시계열 의미론입니다.

## 코드를 만들 때 중요한 규칙

- **쓰기 전에 지원하지 않는 목록을 확인하세요.** 지원하지 않는 호출이 여기서 가장 비싼 실수입니다. 대부분은 컴파일되고 조용히 `na`를 반환하므로, 스크립트가 맞아 보이는 데 아무것도 그리지 않을 수 있습니다.
- **`request.security()`는 차트에 있는 심볼 자체의 상위 타임프레임에서 동작합니다.** `request.security(syminfo.tickerid, "240", close)`는 마지막으로 마감된 4시간 종가를 주며, expression은 ta.* 호출이어도 됩니다. 다른 **심볼**은 na를 반환합니다. 엔진은 차트의 봉만 갖고 있어서 다른 심볼을 찾지 않습니다.
- **선행 표시는 없습니다.** 백테스트 브로커는 미래 데이터로 주문을 체결하지 않습니다. 시장가 주문은 *다음 봉의 시가*에 체결됩니다.
- **비용은 현실입니다.** 모든 체결에서 `strategy()`에 적은 만큼의 수수료와 슬리피지가 붙습니다. 비용이 0일 때 수익인 전략도 비용을 넣으면 손해일 수 있습니다.
- **스톱과 리밋은 봉을 따라갑니다.** 시가, 시가에 가까운 극값, 반대쪽 극값, 종가 순서입니다. 가격이 갭을 넘어 주문보다 앞질러 가면 시가에 체결됩니다.
- **선언은 `=`, 재대입은 `:=`.** 봉을 넘어 유지해야 할 상태에는 `var`를 쓰세요.
- **들여쓰기는 네 칸입니다.** Pine에는 중괄호가 없고, `if`/`for`/`while`/`switch`의 본문은 들여쓴 블록입니다.
- **이름이 붙은 인자는 맨 뒤에.** `name=`을 쓰기 시작하면 뒤따르는 모든 인자에도 이름이 있어야 합니다. `plotshape(series=x, title="t", style=shape.circle)`는 유효하지만 `plotshape(x, "t", style=…)`는 아닙니다. 이름이 붙은 인자 뒤에 위치 인자를 섞으면 구문 오류로 스크립트가 멈춥니다.
- **청산은 그것을 내린 봉에서 발동할 수 없습니다.** 시장가 `strategy.entry`는 *다음 봉의 시가*에 체결되므로, 그 봉에 쓴 `strategy.exit`는 다음 봉부터만 체결될 수 있습니다. 그 봉에서 이미 스톱 아래로 내려간 가격은 반대편으로 체결되지 않습니다.
- **두 다리 청산은 한 번만 발동합니다.** `strategy.exit(stop=…, limit=…)`의 한쪽이 체결되면 다른 쪽도 함께 취소됩니다. 거래는 한 번이지 두 번이 아닙니다. 봉이 두 수준 모두에 닿으면 봉의 움직임을 따라 먼저 닿은 쪽이 이깁니다.
- **트레일링 스톱:** `strategy.exit(trail_points=N, trail_offset=M)`. 둘 다 가격 단위가 아니라 **틱**입니다. `trail_offset`은 스톱이 발동되기 전에 확보해야 하는 이익(틱), `trail_points`는 도달한 최고가에서 유지하는 거리입니다. 스톱은 언제나 유리한 방향으로만 움직이고 마감된 봉에서만 움직입니다.

## 함수 레퍼런스

시그니처와 각각의 역할. 인자는 쓰는 순서 그대로입니다.

### 언어

Deepwick Script는 Pine Script의 일부를 실행합니다. enum, 사용자 정의 타입, 메서드, map이 포함되며 //@version 줄은 검사하지 않습니다. 스크립트는 가장 오래된 봉부터 가장 최근 봉까지 한 봉에 한 번 실행되고, 모든 변수는 자신의 기록을 유지합니다.

- `x = expr / x := expr` — 변수를 선언한 뒤 :=로 다시 대입합니다. 이름 앞에 임의의 타입(int, float, bool, string, color, series, simple, const, line, label)을 쓸 수 있습니다.
- `var / varip` — 첫 봉에서 한 번만 초기화하고 이후 봉에서도 값을 유지합니다. 스크립트는 마감된 봉 위에서 실행되므로 varip은 var와 같이 동작합니다.
- `x[n]` — 히스토리 연산자: n봉 전의 x 값(첫 봉 이전에는 na).
- `if / else` — 조건 블록. 네 칸 들여씁니다. if는 식으로도 쓸 수 있습니다.
- `cond ? a : b` — 삼항 연산자.
- `switch` — 다중 분기. 비교할 값을 넣을 수도, 넣지 않아도 됩니다.
- `for i = a to b [by step]` — 반복 횟수가 정해진 루프. break와 continue를 지원합니다.
- `while cond` — 조건이 성립하는 동안 도는 루프.
- `f(x, y) => expr` — 사용자 정의 함수. 한 줄로 쓰거나, 들여쓴 블록으로 쓰고 마지막 식을 돌려줍니다. Pine처럼 호출한 자리마다 ta.* 상태가 따로 유지됩니다.
- `[a, b] = f()` — 튜플: 함수는 여러 값을 돌려줄 수 있고, ta.macd()나 ta.bb() 같은 내장 함수도 그렇습니다.
- `and / or / not` — 논리 연산자. 산술: + - * / %; 비교: == != < <= > >=.

### 선언

- `indicator(title, shorttitle, overlay, precision)` (study) — 인디케이터를 선언합니다. 차트에 그리기만 하고 백테스트할 대상은 없습니다. study()는 별칭으로 받습니다.
- `strategy(title, overlay, initial_capital, default_qty_type, default_qty_value, commission_type, commission_value, slippage, pyramiding)` — 전략을 선언합니다. 기본값: initial_capital 100000, 주문당 계약 1개, 수수료 0, 슬리피지 0틱, pyramiding 1. process_orders_on_close 같은 다른 인자는 무시됩니다.

### 입력

입력은 편집기 옆과 인디케이터 설정에 나타나서, 코드를 건드리지 않고 값을 바꿀 수 있습니다.

- `input.int(defval, title, minval, maxval, step)` — 정수.
- `input.float(defval, title, minval, maxval, step)` — 소수.
- `input.bool(defval, title)` — 체크박스.
- `input.string(defval, title, options)` — 텍스트 또는 선택지 목록.
- `input.session(defval, title)` — "0930-1600" 같은 거래 세션, 또는 "23456" 같은 요일. session.ismarket()와 다른 session.* 판정에 넣습니다.
- `input.source(defval, title)` — 가격 소스: open, high, low, close, hl2, hlc3, ohlc4 또는 hlcc4.
- `input.color(defval, title)` — 색상 선택기.
- `input(defval, title)` — 일반 입력. 타입은 기본값을 따릅니다.

### 봉 데이터와 시간

시간은 UTC 밀리초입니다. hour()와 다른 시간 함수는 임의의 시간을 받고, hour()는 고정된 오프셋 목록에서 고른 시간대도 받습니다. 서머타임은 고려하지 않습니다.

- `open, high, low, close, volume` (open, high, low, close, volume) — 현재 봉의 가격과 거래량.
- `hl2, hlc3, ohlc4, hlcc4` (hl2, hlc3, ohlc4, hlcc4) — 대표적인 가격 평균.
- `bar_index, last_bar_index` (bar_index, last_bar_index) — 현재 봉의 인덱스(0이 가장 오래된 봉)와 마지막 봉의 인덱스.
- `time, time_close` (time, time_close) — 봉의 시작 시각과 종료 시각. 함수로는 — time("D"), time(timeframe.period, "0000-0900:23456", "UTC") — 이 봉을 포함하는 상위 타임프레임 봉의 시작(또는 끝) 시각을 돌려주고, 봉이 세션 밖에 있으면 na를 돌려줍니다. 세션: "HHMM-HHMM", 자정을 넘기는 것도 가능하고, 쉼표로 구분한 여러 구간과 콜론 뒤의 요일(1 = 일요일 … 7 = 토요일, 생략 가능), "24x7"도 됩니다.
- `timeframe.change(timeframe)` — 새로운 기간마다 첫 봉에서 true. 예를 들어 timeframe.change("D")는 매일 첫 봉에서 true입니다(주는 월요일부터).
- `timestamp(timezone?, year, month, day, hour, minute, second)` — 각 요소로부터 밀리초 단위의 시각을 만들거나, 날짜 문자열에서 가져옵니다: timestamp("2026-01-05T09:30:00Z").
- `dayofweek.sunday … dayofweek.saturday` (dayofweek.monday, dayofweek.tuesday, dayofweek.wednesday, dayofweek.thursday, dayofweek.friday, dayofweek.saturday) — dayofweek(1 … 7)과 비교할 때 쓰는 요일 상수.
- `session.ismarket, isfirstbar, islastbar, ispremarket, ispostmarket` (session.ismarket, session.isfirstbar, session.islastbar, session.ispremarket, session.ispostmarket) — 세션 상태. 이 시장은 쉬지 않고 거래되므로 모든 봉이 거래 세션에 속합니다. isfirstbar / islastbar는 각 UTC 날짜의 첫 봉과 마지막 봉을 가리킵니다.
- `year, month, weekofyear, dayofmonth, dayofweek, hour, minute, second` (year, month, weekofyear, dayofmonth, dayofweek, hour, minute, second) — 봉 시각의 달력 요소. 시각을 넘겨서 부를 수도 있습니다(예: hour(time, "America/New_York")). dayofweek: 1 = 일요일 … 7 = 토요일.
- `barstate.isfirst, islast, isnew, isconfirmed, ishistory, isrealtime` (barstate.isfirst, barstate.islast, barstate.isnew, barstate.isconfirmed, barstate.ishistory, barstate.isrealtime) — 스크립트가 봉 기록의 어느 위치에 있는지.
- `timeframe.period, multiplier, isintraday, isdaily, isweekly, ismonthly` (timeframe.period, timeframe.multiplier, timeframe.isintraday, timeframe.isdaily, timeframe.isweekly, timeframe.ismonthly) — 차트의 타임프레임.
- `syminfo.ticker, tickerid, mintick, pointvalue` (syminfo.ticker, syminfo.tickerid, syminfo.mintick, syminfo.pointvalue) — 차트의 심볼, 가격 단위, 포인트 값.

### 기술적 분석(ta.*)

Pine처럼 호출한 자리마다 상태가 따로입니다. 다른 줄에 있는 두 개의 ta.ema() 호출은 서로 독립적인 두 개의 평균입니다. 봉이 충분히 쌓일 때까지 결과는 na입니다.

- `ta.sma(source, length)` — 단순 이동평균.
- `ta.ema(source, length)` — 지수 이동평균.
- `ta.rma(source, length)` — RSI와 ATR이 쓰는 Wilder 이동평균.
- `ta.wma(source, length)` — 가중 이동평균.
- `ta.vwma(source, length)` — 거래량 가중 이동평균.
- `ta.hma(source, length)` — Hull 이동평균.
- `ta.linreg(source, length, offset)` — 선형 회귀선의 값.
- `ta.vwap(source)` — 거래량 가중 평균 가격. 매일 00:00 UTC에 다시 시작합니다.
- `ta.rsi(source, length)` — 상대강도지수, 0에서 100까지.
- `ta.macd(source, fastlen, slowlen, siglen)` — [macd, signal, histogram]을 돌려줍니다.
- `ta.stoch(source, high, low, length)` — 스토캐스틱 %K, 0에서 100까지.
- `ta.cci(source, length)` — 상품 채널 지수.
- `ta.mfi(series, length)` — 자금 흐름 지수.
- `ta.wpr(length)` — Williams %R, -100에서 0까지.
- `ta.dmi(diLength, adxSmoothing)` — [+DI, -DI, ADX]를 돌려줍니다.
- `ta.supertrend(factor, atrPeriod)` — [supertrend, direction]를 돌려줍니다. direction은 상승 추세에서 -1, 하락 추세에서 1입니다.
- `ta.sar(start, inc, max)` — 포물리 SAR.
- `ta.mom(source, length)` — 모멘텀: source에서 length봉 전의 source를 뺀 값.
- `ta.roc(source, length)` — 변화율, 퍼센트로.
- `ta.change(source, length)` — length봉 전과의 차(기본값 1).
- `ta.tr / ta.tr(handle_na)` — 진짜 범위(TR).
- `ta.atr(length)` — 평균 진짜 범위(Wilder).
- `ta.bb(series, length, mult)` — 볼린저 밴드: [middle, upper, lower]를 돌려줍니다.
- `ta.bbw(series, length, mult)` — 볼린저 밴드 폭: (upper - lower) / middle.
- `ta.kc(series, length, mult)` — 켈트너 채널: [middle, upper, lower]를 돌려줍니다. 진짜 범위의 EMA를 씁니다.
- `ta.stdev(source, length, biased)` — 표준편차.
- `ta.variance(source, length, biased)` — 분산.
- `ta.dev(source, length)` — 평균절대편차.
- `ta.median(source, length)` — 중앙값.
- `ta.highest(source, length) / ta.highest(length)` — 최근 length봉의 최댓값(기본값은 high).
- `ta.lowest(source, length) / ta.lowest(length)` — 최근 length봉의 최솟값(기본값은 low).
- `ta.highestbars(source, length)` — 최댓값에서의 오프셋: 0 또는 음수.
- `ta.lowestbars(source, length)` — 최솟값에서의 오프셋: 0 또는 음수.
- `ta.rising(source, length)` — source가 이전 length개의 값 모두보다 위에 있으면 true.
- `ta.falling(source, length)` — source가 이전 length개의 값 모두보다 아래에 있으면 true.
- `ta.crossover(source1, source2)` — source1이 source2를 넘어 위로 교차하는 봉에서 true.
- `ta.crossunder(source1, source2)` — source1이 source2를 넘어 아래로 교차하는 봉에서 true.
- `ta.cross(source1, source2)` — 어느 방향으로든 교차하면 true.
- `ta.pivothigh(source, leftbars, rightbars)` — 피벗 high 가격. 피벗에서 rightbars봉 뒤에야 알 수 있고 그때까지는 na. source는 생략할 수 있습니다(기본값은 high).
- `ta.pivotlow(source, leftbars, rightbars)` — 피벗 low 가격. 피벗에서 rightbars봉 뒤에야 알 수 있고 그때까지는 na. source는 생략할 수 있습니다(기본값은 low).
- `ta.valuewhen(condition, source, occurrence)` — condition이 true였던 봉 중 최근 occurrence번째 봉의 source 값.
- `ta.barssince(condition)` — condition이 마지막으로 true였을 때부터 지난 봉 수.
- `ta.cum(source)` — 첫 봉부터의 누적 합.

### 전략(strategy.*)

시장가 주문은 다음 봉의 시가에 체결됩니다. 손절·리밋 주문은 봉을 따라 체결됩니다: 시가, 그다음 시가에 가까운 극값, 반대쪽 극값, 종가. 가격이 갭을 넘어 주문을 건너뛰면 시가에 체결됩니다. 수수료는 체결마다 부과되고, 슬리피지는 시장가와 손절 체결에 적용됩니다.

- `strategy.entry(id, direction, qty, limit, stop, comment)` — 포지션을 새로 열거나 늘립니다. limit이나 stop을 주지 않으면 시장가 주문입니다.
- `strategy.order(id, direction, qty, limit, stop, comment)` — strategy.entry()와 같은 인자입니다.
- `strategy.exit(id, from_entry, qty_percent, profit, limit, loss, stop, trail_points, trail_offset, comment)` — 진입에 대한 익절·손절·트레일링 스톱: 익절과 손절은 틱 단위, limit과 stop은 가격입니다. trail_points는 도달한 최고가에서의 거리(틱), trail_offset는 트레일링 스톱이 발동하기 전에 확보해야 하는 이익(틱)입니다. 스톱은 언제나 유리한 방향으로만 움직이고 마감된 봉에서만 옮기므로, 어떤 봉도 자신의 고가가 걸어 놓은 스톱을 체결할 수 없습니다.
- `strategy.close(id, comment, qty_percent)` — 진입분을 다음 봉에 시장가로 청산합니다.
- `strategy.close_all(comment)` — 열린 모든 포지션을 청산합니다.
- `strategy.cancel(id) / strategy.cancel_all()` (strategy.cancel_all) — 미체결 주문을 취소합니다.
- `strategy.position_size, position_avg_price` (strategy.position_size, strategy.position_avg_price) — 현재 포지션(롱이면 양수, 숏이면 음수)과 평균 가격.
- `strategy.opentrades.entry_bar_index(n), entry_price, entry_time, entry_id, size, profit, commission, max_runup, max_drawdown` (strategy.opentrades.entry_price, strategy.opentrades.entry_time, strategy.opentrades.entry_id, strategy.opentrades.size, strategy.opentrades.profit, strategy.opentrades.commission, strategy.opentrades.max_runup, strategy.opentrades.max_drawdown) — 열린 거래 n의 세부 정보(0이 가장 오래된 것). 해당 거래가 없으면 na. 숏이면 size가 음수입니다. 예: 10봉 뒤에 청산하려면 bar_index - strategy.opentrades.entry_bar_index(0) >= 10.
- `strategy.closedtrades.entry_bar_index(n), exit_bar_index, entry_price, exit_price, entry_time, exit_time, entry_id, size, profit, commission, max_runup, max_drawdown` (strategy.closedtrades.exit_bar_index, strategy.closedtrades.entry_price, strategy.closedtrades.exit_price, strategy.closedtrades.entry_time, strategy.closedtrades.exit_time, strategy.closedtrades.entry_id, strategy.closedtrades.size, strategy.closedtrades.profit, strategy.closedtrades.commission, strategy.closedtrades.max_runup, strategy.closedtrades.max_drawdown) — 체결된 거래 n의 세부 정보(0이 가장 오래된 것. 마지막은 strategy.closedtrades - 1).
- `strategy.equity, netprofit, openprofit, grossprofit, grossloss, initial_capital` (strategy.equity, strategy.netprofit, strategy.openprofit, strategy.grossprofit, strategy.grossloss, strategy.initial_capital) — 계좌 수치.
- `strategy.closedtrades, opentrades, wintrades, losstrades` (strategy.closedtrades, strategy.opentrades, strategy.wintrades, strategy.losstrades) — 거래 건수.
- `strategy.long, strategy.short` (strategy.long, strategy.short) — 방향.
- `strategy.fixed, strategy.cash, strategy.percent_of_equity` (strategy.fixed, strategy.cash, strategy.percent_of_equity) — default_qty_type의 값.
- `strategy.commission.percent, cash_per_order, cash_per_contract` (strategy.commission.percent, strategy.commission.cash_per_order, strategy.commission.cash_per_contract) — commission_type의 값.

### 플롯과 알림

- `plot(series, title, color, linewidth, style)` — 차트 위에 또는 별도 창에 계열을 그립니다.
- `plotshape(series, title, style, location, color, text)` — series가 true인 봉에 도형을 그립니다.
- `plotchar(series, title, char, location, color)` — series가 true인 봉에 문자를 그립니다.
- `hline(price, title, color, linestyle)` — 고정된 레벨의 수평선.
- `fill(plot1, plot2, color)` — 두 플롯 또는 두 hline 사이를 채웁니다.
- `bgcolor(color)` — 봉의 배경색을 칠합니다.
- `barcolor(color)` — 봉 자체를 칠합니다.
- `alertcondition(condition, title, message)` — 이메일, Telegram, Discord, webhook 알림으로 바꿀 수 있는 조건을 선언합니다.
- `plot.style_*` (plot.style_line, plot.style_linebr, plot.style_stepline, plot.style_histogram, plot.style_columns, plot.style_circles, plot.style_cross, plot.style_area) — line, linebr, stepline, histogram, columns, circles, cross, area.
- `hline.style_*` (hline.style_solid, hline.style_dashed, hline.style_dotted) — solid, dashed, dotted.
- `shape.*` (shape.triangleup, shape.triangledown, shape.arrowup, shape.arrowdown, shape.circle, shape.xcross, shape.cross, shape.diamond, shape.square, shape.flag, shape.labelup, shape.labeldown) — triangleup, triangledown, arrowup, arrowdown, circle, xcross, cross, diamond, square, flag, labelup, labeldown.
- `location.*` (location.abovebar, location.belowbar, location.top, location.bottom, location.absolute) — abovebar, belowbar, top, bottom, absolute.
- `size.*` (size.auto, size.tiny, size.small, size.normal, size.large, size.huge) — auto, tiny, small, normal, large, huge. 받되, 도형은 모두 같은 크기로 그립니다.

### 선과 상자

- `line.new(x1, y1, x2, y2, extend, color, style, width)` — 두 봉 인덱스와 두 가격 사이에 선을 그리고 id를 돌려줍니다.
- `line.set_x1, set_y1, set_x2, set_y2, set_xy1, set_xy2, set_color, set_style, set_width` (line.set_x1, line.set_y1, line.set_x2, line.set_y2, line.set_xy1, line.set_xy2, line.set_color, line.set_style, line.set_width) — 선을 바꿉니다.
- `line.delete(id)` — 선을 지웁니다.
- `box.new(left, top, right, bottom, border_color, bgcolor, extend)` — 직사각형을 그리고 id를 돌려줍니다.
- `box.set_left, set_top, set_right, set_bottom, set_bgcolor, set_border_color, set_extend` (box.set_left, box.set_top, box.set_right, box.set_bottom, box.set_bgcolor, box.set_border_color, box.set_extend) — 상자를 바꿉니다.
- `box.delete(id)` — 상자를 지웁니다.
- `line.style_*, box.style_*` (line.style_solid, line.style_dashed, line.style_dotted, box.style_solid, box.style_dashed, box.style_dotted) — solid, dashed, dotted.
- `extend.*` (extend.none, extend.left, extend.right, extend.both) — none, left, right, both.

### 수학, 문자열, 색상

- `math.abs, ceil, floor, round(number, precision), sign, sqrt, exp, log, log10, pow(base, exponent)` (math.abs, math.ceil, math.floor, math.round, math.sign, math.sqrt, math.exp, math.log, math.log10, math.pow) — 산술 연산.
- `math.max(...), math.min(...), math.avg(...)` (math.min, math.avg) — 임의 개수의 값에 대해.
- `math.sum(source, length)` — 최근 length봉의 합.
- `math.pi, math.e` (math.pi, math.e) — 상수.
- `na, na(x), nz(x, replacement), fixnan(x)` (na, nz, fixnan) — 값이 없는 상태, 그것을 확인하는 검사, 대체값, 그리고 마지막 na가 아닌 값.
- `int(x), float(x), bool(x)` (float, bool) — 형 변환.
- `str.tostring(value, format), str.format(text, ...), str.length(s), str.contains(s, part)` (str.format, str.length, str.contains) — 문자열. str.format은 {0}, {1}…을 인자로 바꿉니다.
- `color.new(color, transp), color.rgb(red, green, blue, transp)` (color.rgb) — 색을 만듭니다. 투명도는 0에서 100까지.
- `color.*` (color.red, color.green, color.blue, color.orange, color.yellow, color.purple, color.aqua, color.lime, color.fuchsia, color.teal, color.maroon, color.navy, color.olive, color.gray, color.silver, color.white, color.black) — red, green, blue, orange, yellow, purple, aqua, lime, fuchsia, teal, maroon, navy, olive, gray, silver, white, black.

### 배열(array.*)

- `array.new_float, new_int, new_bool, new_string, new_color, new_line, new_box, new_label, new_table(size)` (array.new_float, array.new_int, array.new_bool, array.new_string, array.new_color, array.new_line, array.new_box, array.new_label, array.new_table) — 배열을 만듭니다.
- `array.get, set, insert, push, pop, shift, unshift` (array.get, array.set, array.insert, array.push, array.pop, array.shift, array.unshift) — 원소를 읽고 바꿉니다.
- `array.size, first, last, sum, avg, min, max, stdev` (array.size, array.first, array.last, array.sum, array.avg, array.min, array.max, array.stdev) — 크기와 통계.

### Map과 사용자 정의 타입

사용자 정의 타입과 `map.<fn>` 컬렉션을 지원합니다. 둘 다 최상위 선언이고, 값에 대한 인스턴스 메서드는 `obj.method(args...)` 문법으로 씁니다.

- `enum Name
    Member
    Member = N
    ...` — 최상위 enum 선언. 값을 주지 않은 멤버는 0부터 자동으로 증가합니다. 명시적인 값은 숫자나 문자열일 수 있습니다. 식이 놓이는 어느 자리에서든 `Name.Member`로 접근합니다. enum 값은 평범한 숫자(또는 문자열)이므로 비교 연산자나 변환 없는 `int()`로도 그대로 씁니다.
- `type Name
    field1
    field2: int
    field3 = default` — 최상위 사용자 정의 타입. 필드는 한 줄에 하나씩 적습니다. `: type`과 `= default` 부분은 앞으로의 호환성을 위해 받지만 아직 검사하지는 않습니다. `Type.new(arg1, arg2, ...)`로 만들고 `instance.field`로 필드를 읽습니다.
- `m = map.new<int, float>()` (map.new) — 빈 map을 만듭니다. 타입 인자 `<K, V>`는 받지만 실행 중에는 무시됩니다.
- `m = map.put(m, key, value)` (map.put) — 키를 정합니다. 호출을 이어 붙이거나 다시 대입할 수 있게 map을 돌려줍니다.
- `v = map.get(m, key)` (map.get) — 값을 읽습니다. 키가 없으면 na를 돌려줍니다.
- `n = map.size(m)` (map.size) — 항목 수.
- `keys = map.keys(m), values = map.values(m)` (map.keys, map.values) — 키나 값을 Pine 배열로 돌려줍니다(삽입 순서).
- `map.contains(m, key), map.remove(m, key)` (map.remove) — 포함 여부 확인과 삭제. 둘 다 map을 돌려줍니다.

## 아직 쓸 수 없음

엔진이 모르는 함수를 쓰면 스크립트가 "Unknown function"과 함께 줄과 열 번호에서 멈춥니다.

- `label.new(), table.new()`: 아직 쓸 수 없습니다. 선과 상자는 쓸 수 있습니다.
- `import, matrix.*, array.new<type>()`: 라이브러리, 행렬, 타입이 있는 배열 생성자는 아직 구현되지 않았습니다.
- `strategy.risk.*`: 리스크 규칙(max_position_size, max_intraday_loss, max_drawdown, allow_entry_in)은 지원하지 않습니다. strategy.exit()의 트레일링 스톱은 지원합니다: trail_points와 trail_offset을 쓰세요.

## 실행 가능한 예제

이 엔진에 맞춰 컴파일되는 내장 스크립트:

**RSI Mean Reversion**

```pine
//@version=5
strategy("RSI Mean Reversion", overlay=false, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=10, commission_type=strategy.commission.percent, commission_value=0.1)
len = input.int(14, "RSI length", minval=2)
oversold = input.float(30, "Oversold")
exitLevel = input.float(50, "Exit level")
stopPct = input.float(2, "Stop loss %", minval=0, step=0.1)
tpPct = input.float(6, "Take profit %", minval=0, step=0.1)
if strategy.position_size > 0
    strategy.exit("Risk", stop=stopPct > 0 ? strategy.position_avg_price * (1 - stopPct / 100) : na, limit=tpPct > 0 ? strategy.position_avg_price * (1 + tpPct / 100) : na)
r = ta.rsi(close, len)
if strategy.position_size == 0 and r < oversold
    strategy.entry("Long", strategy.long)
if strategy.position_size > 0 and r > exitLevel
    strategy.close("Long", comment="RSI exit")
plot(r, "RSI", color=color.purple)
hline(oversold, "Oversold", color=color.green)
hline(exitLevel, "Exit", color=color.gray)
```

**MACD Crossover**

```pine
//@version=5
strategy("MACD Crossover", overlay=false, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=10, commission_type=strategy.commission.percent, commission_value=0.1)
fast = input.int(12, "Fast", minval=1)
slow = input.int(26, "Slow", minval=2)
sig = input.int(9, "Signal", minval=1)
stopPct = input.float(2, "Stop loss %", minval=0, step=0.1)
tpPct = input.float(6, "Take profit %", minval=0, step=0.1)
if strategy.position_size > 0
    strategy.exit("Risk", stop=stopPct > 0 ? strategy.position_avg_price * (1 - stopPct / 100) : na, limit=tpPct > 0 ? strategy.position_avg_price * (1 + tpPct / 100) : na)
[m, s, h] = ta.macd(close, fast, slow, sig)
if ta.crossover(m, s)
    strategy.entry("Long", strategy.long)
if ta.crossunder(m, s)
    strategy.close("Long", comment="MACD cross")
plot(h, "Histogram", color=h >= 0 ? color.new(color.green, 40) : color.new(color.red, 40), style=plot.style_columns)
plot(m, "MACD", color=color.orange)
plot(s, "Signal", color=color.blue)
```

**Bollinger Bounce**

```pine
//@version=5
strategy("Bollinger Bounce", overlay=true, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=10, commission_type=strategy.commission.percent, commission_value=0.1)
len = input.int(20, "Length", minval=2)
mult = input.float(2, "StdDev", minval=0.5, step=0.1)
stopPct = input.float(2, "Stop loss %", minval=0, step=0.1)
tpPct = input.float(6, "Take profit %", minval=0, step=0.1)
if strategy.position_size > 0
    strategy.exit("Risk", stop=stopPct > 0 ? strategy.position_avg_price * (1 - stopPct / 100) : na, limit=tpPct > 0 ? strategy.position_avg_price * (1 + tpPct / 100) : na)
[basis, upper, lower] = ta.bb(close, len, mult)
if strategy.position_size == 0 and close <= lower
    strategy.entry("Long", strategy.long)
if strategy.position_size > 0 and close >= basis
    strategy.close("Long", comment="Back to mean")
u = plot(upper, "Upper", color=color.blue)
plot(basis, "Basis", color=color.gray)
l = plot(lower, "Lower", color=color.blue)
fill(u, l, color=color.new(color.blue, 92))
```

## Elsewhere

- Human reference: https://deepwick.com/ko/docs/script
- Try a script with no signup: https://deepwick.com/try
