트레이딩뷰는 2024년 말 파인스크립트 v6를 공개했고, 새 기능은 v6에만 추가되고 있습니다.
이 글에서는 v5 코드를 v6로 옮길 때 꼭 알아야 할 변경점과, 변환 후 나는 오류를 고치는 방법을 예제로 정리합니다.

이 글에서 배우는 것
  • v5 코드를 v6로 자동 변환하는 방법
  • 변환 후 오류가 나기 쉬운 변경점 7가지
  • 전략(strategy) 동작이 달라지는 부분

※ 전체 변경 내용은 트레이딩뷰 공식 문서 To Pine Script version 6에서 확인할 수 있습니다.

꼭 v6로 옮겨야 할까?

v5 스크립트도 지금처럼 계속 동작합니다. 다만 새 함수와 기능은 v6에만 추가되므로, 새로 만드는 스크립트는 v6로 쓰고 수정할 일이 있는 스크립트부터 차례로 옮기는 것을 추천합니다.

1. 자동 변환 기능 사용하기

  1. Pine 에디터에서 v5 스크립트를 엽니다.
  2. 에디터 위쪽 메뉴(⋯)에서 “v6로 변환(Convert code to v6)” 을 선택합니다.
  3. 첫 줄이 //@version=6 으로 바뀌고, 자동으로 고칠 수 있는 부분은 고쳐집니다.
  4. 저장 후 에디터 아래 콘솔에 오류가 있으면 아래 변경점을 참고해 직접 고칩니다.

※ 변환 전에 원본 코드를 복사해 두세요. 전략이라면 변환 전후 백테스트 결과가 같은지도 꼭 비교해 주세요.

2. 오류가 나기 쉬운 변경점

① bool 값은 더 이상 na가 될 수 없습니다

v6에서 bool 은 true 와 false 두 값만 가집니다. na(), nz(), fixnan() 에 bool 값을 넣을 수 없습니다.

// v5
var bool isLong = na
if na(isLong)
    ...

// v6
var bool isLong = false
if not isLong
    ...

② 숫자를 bool 로 자동 변환하지 않습니다

v5에서는 0 이나 na 가 아닌 숫자를 조건에 그대로 쓸 수 있었지만, v6에서는 비교식으로 직접 써야 합니다.

// v5
if strategy.position_size
    ...

// v6
if strategy.position_size != 0
    ...

③ and / or 는 필요할 때만 오른쪽을 계산합니다

v6의 and, or 는 지연 평가됩니다. a and b 에서 a 가 false 이면 b 는 계산하지 않습니다.

// v6에서는 배열이 비어 있으면 array.first() 를 호출하지 않으므로 오류가 나지 않습니다
if array.size(prices) > 0 and array.first(prices) > close
    ...

※ 반대로 오른쪽 식에 ta.sma() 같은 과거 값이 필요한 함수가 있으면, 매 봉 계산되지 않아 결과가 달라질 수 있습니다. 이런 함수는 조건문 밖에서 변수로 먼저 계산해 두세요.

// 권장: 매 봉 계산한 뒤 조건에 사용
rsi = ta.rsi(close, 14)
if useFilter and rsi > 50
    ...

④ 정수끼리 나눠도 소수점이 남습니다

v5에서는 상수 정수끼리 나누면 소수점이 버려졌지만(5 / 2 = 2), v6에서는 2.5 가 됩니다. 정수가 필요하면 int() 나 math.floor() 를 씁니다.

half = int(length / 2)    // v5의 결과와 같게 하려면

⑤ 주문 함수의 when 인수가 삭제되었습니다

strategy.entry(), strategy.close(), strategy.exit(), strategy.order() 등의 when 인수는 v6에서 없어졌습니다. if 문으로 바꿉니다.

// v5
strategy.entry("Long", strategy.long, when = longCondition)

// v6
if longCondition
    strategy.entry("Long", strategy.long)

⑥ timeframe.period 는 항상 숫자가 붙습니다

v6에서 timeframe.period 는 일봉을 "D" 가 아닌 "1D" 로 돌려줍니다. 문자열을 직접 비교하는 코드는 고쳐 주세요.

// v5
isDaily = timeframe.period == "D"

// v6 (어느 버전에서도 안전한 방법)
isDaily = timeframe.isdaily

⑦ request.security() 를 조건문과 반복문 안에서도 쓸 수 있습니다

v6는 기본으로 동적 요청을 허용합니다. 여러 심볼을 반복문에서 불러오는 코드가 가능해졌습니다.

//@version=6
indicator("여러 코인 종가")
symbols = array.from("BINANCE:BTCUSDT", "BINANCE:ETHUSDT", "BINANCE:SOLUSDT")
var table t = table.new(position.top_right, 2, 3)
if barstate.islast
    for [i, s] in symbols
        c = request.security(s, timeframe.period, close)
        table.cell(t, 0, i, s)
        table.cell(t, 1, i, str.tostring(c))

3. 전략(strategy) 동작이 달라지는 부분

항목v5v6
margin_long / margin_short 기본값0 (증거금 무시)100 (자산 이상 매수 불가)
주문 9,000건 초과오류로 멈춤오래된 거래부터 지우고 계속 계산
strategy.exit() 에 profit 과 limit 을 함께 지정limit 등 절대 가격 우선먼저 도달하는 가격 사용
  • 증거금 기본값이 바뀌어, v5에서 자산보다 큰 수량으로 주문하던 전략은 v6에서 주문이 줄거나 강제 청산될 수 있습니다. 레버리지를 쓰려면 margin_long = 10 (10배)처럼 직접 지정합니다.
  • 변환 후 전략 테스터의 거래 횟수와 순이익이 달라졌다면 위 항목부터 확인해 보세요.

4. v6에서 새로 쓸 수 있는 편리한 기능

  • 배열 음수 인덱스: array.get(a, -1) 로 마지막 요소를 가져옵니다.
  • 글자 서식: 라벨·박스·테이블에 text_formatting = text.format_bold 로 굵게, 기울임을 적용합니다.
  • 동적 요청: 위 ⑦처럼 여러 심볼·시간봉을 반복문으로 불러옵니다.

5. 변환 체크리스트

  • ☐ 원본 v5 코드를 백업했다
  • ☐ 자동 변환 후 콘솔 오류를 모두 고쳤다
  • ☐ na 로 초기화한 bool 변수를 false 로 바꿨다
  • ☐ 숫자를 조건으로 쓰던 곳을 비교식으로 바꿨다
  • ☐ when = 을 if 문으로 바꿨다
  • ☐ 전략이라면 변환 전후 백테스트 결과(거래 횟수, 순이익)를 비교했다
  • ☐ 스크립트를 바꿨으니 트레이딩뷰 얼러트를 다시 만들었다

※ 얼러트는 만든 시점의 스크립트로 동작합니다. v6로 바꾼 스크립트로 자동매매하려면 기존 얼러트를 지우고 새로 만들어 주세요.


v6로 전략을 처음 만든다면 지표를 전략으로 바꾸는 방법을 따라 해 보세요.