[#5] 파인스크립트 강좌 - 조건문과 반복문
![[#5] 파인스크립트 강좌 - 조건문과 반복문](/content/images/size/w1200/2025/07/d1dca59c-e513-49eb-90b8-c5bc4ddd5e84.png)
‘연산자’ 편에 이어지는 강의입니다.
이제 값(데이터)을 어떻게 판단하고 얼마나 반복할지 배워 자동화 로직을 완성해 보겠습니다.
제어 흐름(Control Flow)이 왜 필요할까요?
가격이 목표치에 도달했을 때 매수/매도를 결정하고, N개의 봉을 스캔해 특정 패턴이 있는지 확인하려면
프로그래밍 언어가 제공하는 조건문(Conditional statement) 과 반복문(Loop) 이 필수입니다.
파인스크립트 v5부터는 if
, switch
, for
구조를 지원하므로 클래식 언어와 거의 동일한 사고방식으로 코드를 작성할 수 있습니다.
조건문(Conditional Statement)
if‧else if‧else
기본형
// 예: 캔들 색상 판단
isBull = close > open
isDoji = math.abs(close - open) < (high - low) * 0.1
if isBull
label.new(bar_index, high, "양봉", color=color.green)
else if isDoji
label.new(bar_index, high, "도지", color=color.gray)
else
label.new(bar_index, high, "음봉", color=color.red)
- 들여쓰기 4칸이 필수입니다. 틀리면 컴파일 오류가 발생합니다.
- 조건이
series<bool>
형이어야 하며,na
가 들어가면false
로 처리됩니다.
다중 분기용 switch
switch
는 가독성이 좋고, 값을 반환할 수도 있어서 트릭 컬러링에 자주 쓰입니다.
barColor = switch
close > open => color.green
close < open => color.red
=> color.gray // 나머지(동가) 처리
plotcandle(open, high, low, close, color = barColor)
=>
뒤에 표현식을 한 줄로 작성합니다.- 모든 분기가
return
을 생략하면 side-effect 용도로도 사용할 수 있습니다.
단일 라인 조건부(?:
) 다시 보기
앞 강의에서 소개했던 삼항 연산자도 조건문 계열입니다.
짧게 써야 가독성이 살아납니다.
반복문(Loop)
중요: 대부분의 지표 연산은ta.*
빌트인으로 해결할 수 있으므로,
루프는 “특수 계산”이나 “배열 조작”이 필요할 때만 사용하세요.
3-1. for
문 기본형
//@version=5
indicator("For Loop Demo", overlay = true)
len = 5
var float sumClose = 0.0
for i = 0 to len - 1
sumClose += close[i]
avgClose = sumClose / len
plot(avgClose, "5-Bar AVG", color = color.orange)
- 구조:
for <카운터> = <시작> to <끝> [by <스텝>]
<끝>
값까지 포함하며,from > to
이면 자동으로 내림(loop-down) 합니다.break
,continue
도 지원합니다. (사용 시 성능 프로파일링 권장)
배열 전용 루프
string[] tickers = array.from("AAPL", "MSFT", "TSLA")
for t in tickers
h = request.security(t, "D", high)
// ... 로직 ...
for <element> in <array>
형태.[index, value]
두 개 튜플로도 받을 수 있습니다.
while
문은 없다?
파인스크립트에는 전통적 while
이 없습니다.
무한 루프 위험을 차단하기 위한 언어 설계 철학이므로,
조건 반복이 필요하면 for
+ break
패턴이나 빌트인 함수를 사용합니다.
실전 예제 ① — 조건문으로 ‘스탑로스’ 구현
//@version=5
strategy("Stop-Loss Demo", overlay = true)
longCond = ta.crossover(close, ta.sma(close, 20))
if longCond
strategy.entry("Long", strategy.long)
stopLoss = strategy.position_avg_price * 0.97 // 3% 손절
takeProf = strategy.position_avg_price * 1.05 // 5% 익절
if strategy.position_size > 0
if close <= stopLoss
strategy.close("Long", comment = "손절")
else if close >= takeProf
strategy.close("Long", comment = "익절")
if
중첩으로도 충분히 복잡한 매매 로직을 깔끔하게 관리할 수 있습니다.
실전 예제 ② — 반복문으로 ‘마지막 N봉 패턴’ 탐색
//@version=5
indicator("Engulfing Scanner", overlay = true)
N = input.int(30, "검색 범위")
var int lastBar = na
for i = 1 to N
isBullEngulf = close[i] > open[i] and // 현재봉 상승
open[i] < close[i+1] and // 이전봉 음봉
close[i] > open[i+1] and
open[i] <= close[i+1]
if isBullEngulf
lastBar := i
break // 가장 최근 패턴만 잡고 루프 종료
plotshape(lastBar == 1 ? 1 : na, title = "Bull Engulf", style = shape.triangleup,
location = location.belowbar, color = color.lime, size = size.tiny)
break
로 첫 번째 발견 후 루프를 즉시 탈출 → CPU 절약.- 동일 로직을
ta.pattern.*
으로 대체할 수도 있으니 성능 비교해 보세요.
흔한 오류 & 최적화 팁
유형 | 원인 & 증상 | 해결책 |
---|---|---|
Unreachable code | break 다음 줄에 코드가 있는데 접근 불가 |
불필요한 코드 제거 |
Loop executes too often | 배열 길이만큼 매 봉마다 반복 → 슬로다운 | var 캐시·조건분기·Profiler 사용 |
조건에 na 포함 |
if na(x) 는 항상 false 취급 |
nz() 혹은 x != na 로 안전 처리 |
배열 크기 초과 | array.get(a, i) 에서 인덱스 오류 |
array.size(a) 체크 & min() |
7. 성능 프로파일링 한눈에 보기
- Pine Profiler (파인 에디터 우측 상단 🐢 아이콘) 으로 루프 시간과 호출 횟수를 측정하세요.
- 빌트인 함수(
ta.*
)는 내부 C++ 최적화가 되어 있어 루프보다 빠르고 메모리 안전합니다. - 조건문·반복문을 최소화하고, 결과를
var
시리즈에 캐싱하면 프레임 드랍을 줄일 수 있습니다.
오늘의 핵심 정리
- 조건문은
if
와switch
두 축이며,switch
가 가독성이 뛰어난 다중 분기용입니다. - 반복문은
for
만 존재하며, 배열·범위·튜플 반복을 지원합니다. - 루프 사용 전 빌트인 함수 대체 가능 여부를 반드시 검토하세요.
break
,continue
,Profiler
로 성능을 관리하면 차트가 가볍습니다.