파인 스크립트 v5 를 만나 보십시오

Oct 7, 2021

오늘 파인이 v5 로 버전업 되었습니다! 당사 인디케이터/스트래티지 프로그래밍 랭귀지인 파인의 새 버전이 수많은 새로운 피처를 더함과 아울러 많은 개선을 하였습니다. 파인은 더욱 더 파워풀해졌으며 v5 는 파인을 새로운 레벨로 올려 놓았습니다. 이 포스트에서는 가장 최근의 피처 두어 가지만 소개하고자 합니다; 당사 릴리즈 노트 및 마이그레이션 가이드를 읽어 보십시오.

v4 to v5 컨버터

이전 파인 버전을 쓰는 기존 파인 스크립트는 바뀜없이 돌아가지만 코더분들이 v4 스크립트를 v5 로 바꾸는 데 도움이 되도록 파인 에디터에 컨버전 툴을 만들어 놓았습니다. 앞으로 파인 개선 사항은 v5 에 대해서만 나오게 됩니다. 따라서, 앞으로 새로운 피처를 쓰고 싶다면 여러분의 인디케이터/스트래티지를 컨버트할 것을 권해 드립니다. v4 to v5 컨버전 툴은  파인 에디터에 v4 스크립트가 로드되면 더보기 드롭다운 메뉴에서 쓸 수 있습니다:

모든 v4 코드는 자동으로 컨버트할 수 있습니다. 컨버전에 문제가 있거나 매뉴얼 컨버전을 하고 싶다면, v4 에서 v5 로 바뀌는 모든 것들에 대해 마이그레이션 가이드를 보시기 바랍니다.

라이브러리

v5 에서 파인에 새로 들어간 핵심가운데 하나는 바로 라이브러리입니다. 라이브러리는 새로운 타입의 퍼블리케이션으로써 다른 스크립트에서 다시 쓸 수 있는 커스텀 펑크션을 만들 수 있게 해 줍니다. 일단 라이브러리가 퍼블리쉬되면 다른 스크립트 (인디케이터, 스트래티지, 심지어 다른 라이브러리까지) 다른 스크립트에서 그 라이브러리를 임포트해 그 라이브러리의 펑크션을 쓸 수 있습니다. 라이브리러에 복잡한 알고리즘이나 자주 쓰는 펑크션을 넣어 놓게 되면 전체 파인커뮤니티에서 그러한 것들을 쉽게 꺼내 쓸 수 있게 됩니다.

라이브러리 작업에 대한 것은 당사 라이브러리 유저 매뉴얼을 보시기 바랍니다. 이 글의 끄트머리에는 파인코더즈 팀 멤버가 퍼블리쉬한 라이브러리 보기가 나옵니다. 퍼블리쉬된 라이브러리는 여기 스크립트 피드로 부터 퍼블리쉬된 라이브러리를 볼 수 있습니다.

유저 디파인 펑크션의 디폴트 밸류

라이브러리와 더불어 나아진 것:유저 디파인 펑크션 파라미터의 디폴트 밸류를 정할 수 있어 옵셔널 파라미터로 만들 수 있습니다. 아래 보기에서,   base 의 exp 거듭제곱을 구하는커스텀 펑크션인customPow() 를 선언하고 있습니다. 이펑크션을 콜할 때 exp 가 주어지지 않으면 그 디폴트 값으로 2 를 쓰게 됩니다:

//@version=5
indicator("")
customPow(base, exp = 2) =>
    result = 1
    for i = 1 to exp
        result *= base
plot(customPow(11)) // 11^2
plot(customPow(11, 4)) // 11^4

스위치 (Switch)

switch 문은 많이 본 if 문을 여러 번 쓰는 것과 같습니다.  if-else 문으로 커다란 트리처럼 짜 본적이 있었다면 switch 같은 결과를 볼 수 있다는 것이 얼마나 편한 지에 대해 고마움을 느끼게 될 것입니다. 자세한 것은 당사 레퍼런스 매뉴얼에 나와 있습니다. 아래 코드를 돌려 보시기 바랍니다. 당사의 빌트인 Average True Range 인디케이터인데, 셈을 할 때 switch 문을 써서 서로 다른 스무딩 알로리즘을 제공합니다:

//@version=5
indicator(title="Average True Range", shorttitle="ATR", timeframe="")
lengthInput = input.int(title="Length", defval=14, minval=1)
smoothingInput = input.string(title="Smoothing", defval="RMA", options = ["RMA", "SMA", "EMA", "WMA"])

maFunction(source, length) =>
    switch smoothingInput
        "RMA" => ta.rma(source, length)
        "SMA" => ta.sma(source, length)
        "EMA" => ta.ema(source, length)
        => ta.wma(source, length)

plot(maFunction(ta.tr(true), lengthInput), title = "ATR", color=#B71C1C)

드로잉 컬렉션

파인 드로잉 작업에 대한 커다란 삶의 질 개선: 새로운 line.all, label.all, box.all, 및 table.all 빌트인 어레이 베어리어블은 언제나 여러분의 스크립트에 의해 지정된 타입의 모든 드로잉에 대한 ID 들을 담고 있습니다.

보기로, 차트에 디스플레이된 드로잉 갯수를 유저 디파인 밸류에 따라 줄일 수 있습니다. 아래 스크립트에서는 매일 그날의 시가에 하나의 라인을 그리고 있습니다 (이 스크립트의 디폴트 라인 리밋에 따라 최대 50 개까지). 이 스크립트의 인풋값으로 라인 갯수가 넘었는 지를 체크하여 넘게 되면 가장 오래된 라인을 지웁니다:

//@version=5
indicator("Daily Open", overlay = true)

qtyOfLinesInput = input.int(10, "Draw only last n lines", minval = 0, maxval = 50)

if ta.change(time("1D"))
    line.new(bar_index, open, bar_index + 1, open, extend = extend.right)
    if array.size(line.all) > qtyOfLinesInput
        line.delete(array.get(line.all, 0))

While

v5 에 새로 만들어진 또 하나의 오래 기다리던 파인 피처는 while 루프입니다. while 문은 루프를 돌며 컨디션이 폴스가 되거나 또는 break 커맨드를 만나게 되면 루프를 빠져 나가게 됩니다.

보기로, 지난 n 바의 토탈 볼륨과 같은 업/다운 볼륨을 찾기 위해 뒤돌아 보아야 할 애버리지 디스턴스 차이를 셈하는 인디케이터가 있습니다. 업/다운 볼륨을 찾으려 더 멀리 뒤돌아 보아야 할 수록, 그 값은 더 베어리쉬하거나 또는 불리쉬합니다:

//@version=5
var int MAX_BARS_BACK = 500
indicator("Volume bias", max_bars_back = MAX_BARS_BACK)

int lookBackInput = input.int(20, "Volume Look Back (bars)", minval = 2, maxval = int(MAX_BARS_BACK / 4))

// Stop the script if the chart does not contain volume data.
bool noVol = na(volume) and nz(math.sum(nz(volume), 200) == 0, true)
if noVol
    runtime.error("No volume data.")

volumeBias(lookBack, maxLookBack) =>
    bool  barUp = ta.rising(close, 1)
    bool  barDn = ta.falling(close, 1)
    float upVolume = 0.
    float dnVolume = 0.
    float avgVolume = math.sum(nz(volume), lookBack)
    int[] upBarNos = array.new_int(0)
    int[] dnBarNos = array.new_int(0)
    int   bar = 1
    bool  volumeFound = false
    while (not volumeFound) and bar < maxLookBack
        if barUp[bar] and upVolume < avgVolume
            upVolume += nz(volume[bar])
            array.push(upBarNos, bar)
        else if barDn[bar] and dnVolume < avgVolume
            dnVolume += nz(volume[bar])
            array.push(dnBarNos, bar)
        bar += 1
        volumeFound := upVolume >= avgVolume and dnVolume >= avgVolume
    float volumeBias = bar >= maxLookBack ? na : array.avg(dnBarNos) - array.avg(upBarNos)

float bias = volumeBias(lookBackInput, MAX_BARS_BACK)
plot(bias, "Volume Bias", bias > 0 ? color.lime : color.fuchsia)
hline(0)

이 스크립트의 while 루프는 찾고자 하는 업/다운 볼륨이 나올 때까지, 또한 최대 허용 바 갯수를 넘지 않을 때까지 돌게 됩니다. 이 스크립트에는 파인 v5 에 새로 더해진 또 다른 피처도 보여주고 있습니다: runtime.error().

runtime.error()

runtime.error() 펑크션으로 스크립트를 멈추고 여러분이 파인으로 정한 특정 조건 만족시 에러 메시시를 띄울 수 있습니다. 이 기능은 스크립트 크리에이터들에게 쓸모가 있는데, 이를 통해 자신들의 인디케이터를 유저들이 잘못 쓰는 것을 막을 수 있도록 해 줍니다. 또한 루프나 펑크션을 멈출 때 쓰는 등, 비공식적인 디버깅 툴로도 쓸 수 있습니다.

이 펑크션을 쓰려면 여러분의 조건이 만족될 때 간단히 runtime.error() 을 콜하기만 하면 됩니다. 이 펑크션이 실행되면 스크립트는 멈추게 되고 많이 보던 느낌표 마크가 인디케이터 네임 옆에 나오게 됩니다. 유저가 이 느낌표를 클릭하면 여러분이 이 펑크션에 넣어 두었던 메시지가 나타납니다.

아래 코드는 VWAP 인디케이터의 뼈대이며 두 가지 커스텀 에러를 갖고 있습니다. 첫번째는 심볼이 아무런 볼륨 데이터를 갖고 있지 않을 때 나옵니다: VWAP 은 볼륨을 기반으로 셈을 하므로 볼륨이 없다면 이 스크립트는 돌지 않습니다. 두번째는 차트의 타임프레임이 1D 이상이면 나옵니다. 베이직 VWAP 셈은 각각의 새로운 바에 대해 볼륨-웨이티디 애버리지 데이터를 누적하며 새 날이 오면 리셋하므로 이 인디케이터는 오로지 인트라데이 타임프레임에서만 쓸 수 있습니다.

//@version=5
indicator("VWAP with custom errors")
if na(volume) // Will be true on symbols with no volume data e.g. TVC:SPX
    runtime.error("There is no volume data for this symbol.")
else if timeframe.isdwm // Will be true on 1D and higher timeframes
    runtime.error("Session-based VWAP does not show meaningful data on timeframes >= 1D.
     Please switch to a lower timeframe.")
plot(ta.vwap)

새로운 스트래티지 파라미터

스트래티지 코더들에게 좋은 뉴스! 새로운 베어리어블 및 펑크션을 더 만들어 넣어 여러분에게 트레이드 프로퍼티, 통계, 메트릭 등에 대해 보여 줄 수 있게 되었습니다. 이러한 값들은 브로커 이뮬레이터가 여러분의 오더를 실행하자 마자 업데이트가 되므로 여러분은 여러분의 스트래티지가 진행되어 감에 따라 그 값들을 따라갈 수 있습니다..

Click here to see the Pine Reference Manual for details on each one

strategy.closedtrades.entry_price() / strategy.opentrades.entry_price()

strategy.closedtrades.entry_bar_index() / strategy.opentrades.entry_bar_index()

strategy.closedtrades.entry_time() / strategy.opentrades.entry_time()

strategy.closedtrades.size() / strategy.opentrades.size()

strategy.closedtrades.profit() / strategy.opentrades.profit()

strategy.closedtrades.commission() / strategy.opentrades.commission()

strategy.closedtrades.max_runup() / strategy.opentrades.max_runup()

strategy.closedtrades.max_drawdown() / strategy.opentrades.max_drawdown()

strategy.closedtrades.exit_price()

strategy.closedtrades.exit_bar_index()

strategy.closedtrades.exit_time()

strategy.convert_to_account()

strategy.convert_to_symbol()

strategy.account_currency

 

뉴 네임스페이스

당사 파인 코더즈 커뮤니티는 지난 몇해 동안 전례없이 많은 추가 피처 및 개선 사항을 해 준 것에 대해 우리에게 고마움을 느끼고 있습니다. 우리는 앞으로도 이러한 페이스를 이어 나갈 것입니다. 하지만 이렇게 함으로써 꾸준히 새로운 파인 펑크션 및 빌트인 베어리어블이 만들어 지고 있습니다. 이런 빠른 성장을 서포트하기 위해 랭귀지에서 쓰이는 ~600 여개의 현재 이름들을 좀 더 체계적으로 오거나이즈할 필요가 생겼습니다. 이를 위해 새로운 네임스페이스를 만들어 펑크션들을 그 쓸모에 따라 좀 더 잘 구분할 수 있도록 그룹화 하였습니다. 많은 펑크션 파라미터 네임들 또한 알아 보기 쉽게 이름을 바꾸었습니다.

새 네임스페이스가운데 하나는 ta 이며, 여기에는 테크니컬 어낼리시스에 관한 모든 베어리어블 및 펑크션을 담았습니다. 이제는 레퍼런스 매뉴얼에서 모든 베어리어블 및 공통 인디케이터들의 밸류를 리턴하는 펑크션들을 레퍼런스 매뉴얼에서 쉽게 훑어보거나 찾을 수 있게 되었습니다. 이에 따라, sma() 는 이제ta.sma() 가 되었습니다. 새 네임스페이스를 기억할 필요는 없습니다; 에디터에서 옛 펑크션 네임을 네임스페이스 없이 치고 오토콤플리트 핫키 (Ctrl + Space, or Cmd + Space on MacOS) 를 누르면, 그에 걸맞는 제안 팝업창이뜨게 됩니다:

레퍼런스 매뉴얼 서치할 때도 마찬가지입니다; 네임스페이스없이 펑크션 네임을 치면 그에 맞는 새로운 네임을 알려 줍니다. v5 에서 바뀐 모든 것은 당사 마이크레이션 가이드에 나와 있습니다.

퍼블리쉬된 라이브러리

다음 퍼블리케이션은 새로운 파인 피처를 테스트하기 위해 파인코더즈가 트레이딩뷰에서 퍼블리쉬한 라이브러리들의 보기입니다:

ColorScheme by RicardoSantos

Matrix_Functions_Lib_JD by Duyck

Enchanced_ta by HeWhoMustNotBeNamed

새로운 피처가 여러분에게 도움 및 쓸모가 있기를 바랍니다. 피드백 및 써제스쳔을 앞으로도 이어 보내 주시기 바랍니다 — 여러분을 위한 트레이딩뷰를 만들겠습니다.

Look first Then leap

트레이딩뷰는 여러분을 위해 만들어졌으므로 트레이딩뷰의 멋진 기능을 최대한 활용하세요
차트 시작