4
집중하다
1076
수행원

FMZ PINE 스크립트 문서

만든 날짜: 2022-05-06 14:27:06, 업데이트 날짜: 2025-01-23 10:19:06
comments   18
hits   13760

[TOC]

키워드, 문법, 설정 설명

코드 구조

Pine의 코드가 따르는 일반적인 구조는:

<version>
<declaration_statement>
<code>

참고

FMZ의 파인 언어 지원 코멘트 기호: 단일 라인 코멘트//: 여러 줄의 주석/* */예를 들어, 아래의 예제에서 코멘트를 쓰면:

[macdLine, signalLine, histLine] = ta.macd(close, 12, 26, 9)  // 计算MACD指标

/*
plot函数在图表上画出指标线
*/
plot(macdLine, color = color.blue, title='macdLine')
plot(signalLine, color = color.orange, title='signalLine')
plot(histLine, color = color.red, title='histLine')

버전

다음과 같은 형태의 컴파일러 명령어들은 컴파일러에게 스크립트가 어떤 버전의 Pine로 작성되었는지 알려줍니다:

//@version=5

기본 v5 버전으로, 코드에서 제외할 수 있습니다.//@version=5

선언문

  • indicator()
  • strategy()

선언 문장은 스크립트의 유형을 결정하며, 이것은 그 안에 무엇이 허용되는지, 그리고 어떻게 사용되고 실행되는지를 결정한다. 스크립트의 핵심 속성을 설정한다. 예를 들어, 그것의 이름, 그것이 차트에 추가되었을 때, 그것이 어디에 나타날지, 그것이 보여주는 값의 정밀도와 형식, 그리고 그것이 실행될 때 특정 행동을 관리하는 값, 예를 들어, 그것이 차트에 표시될 최대 그림 개체 수. 전략에 있어, 속성에는 초기 자본, 수수료, 슬라이드 포인트 등과 같은 역량을 제어하는 매개 변수가 포함된다.indicator()또는strategy()声明声明.

코드

스크립트의 코멘트나 컴파일러 명령어가 아닌 줄은 문장이며, 그것은 스크립트의 알고리즘을 구현한다. 문장은 이 중 하나일 수 있다.

  • 변수 선언
  • 변수의 재확인
  • 함수 선언
  • 내장 함수 호출, 사용자 정의 함수 호출
  • ifforwhile또는switch등 구조

문장은 여러 가지 방식으로 구성될 수 있습니다.

  • 어떤 문장은 한 줄로 표현할 수 있는데, 예를 들어 대부분의 변수 선언은 하나의 함수 호출 줄만 포함하고, 또는 단일 라인 함수 선언이다. 다른 것들은, 구조와 같이, 항상 여러 줄이 필요하기 때문에, 그것들은 한 지역 블록이 필요하다.
  • 스크립트의 전체 범위에 속하는 문장 (즉, 지역 블록에 속하지 않는 부분) 은空格또는制表符(tab 키) 시작 그들의 첫 번째 문자는 또한 이 줄의 첫 번째 문자가 되어야 한다 줄의 첫 번째 위치에서 시작하는 줄은, 정의에 따라 스크립트의 전체 범위의 일부가 된다
  • 구조 또는 다중 행 함수 선언은 항상local block。 한 로컬 블록은 하나의 표기符 또는 네 개의 빈 공간으로 축소되어야 한다. 그렇지 않으면, 이전 라인의 연산 코드로 해독되며, 즉, 이전 라인의 코드의 연속으로 판단된다. 각 로컬 블록은 다른 로컬 범위를 정의한다.
  • 여러 개의 단행 문장은 쉼표 ((,) 를 사용하여 분리자 (separator) 로 한 줄에 연쇄될 수 있다.
  • 한 줄에는 코멘트가 포함될 수도 있고, 그냥 코멘트일 수도 있다.
  • 이 문장은 문장과 문장 사이를 두 번 묶을 수 있습니다.

예를 들어, 세 개의 로컬 블록을 포함하고, 사용자 정의 함수 선언에서 하나, 변수 선언에서 두 개가 if 구조를 사용하며, 다음과 같은 코드입니다:

indicator("", "", true)             // 声明语句(全局范围),可以省略不写

barIsUp() =>                        // 函数声明(全局范围)
    close > open                    // 本地块(本地范围)

plotColor = if barIsUp()            // 变量声明 (全局范围)
    color.green                     // 本地块 (本地范围)
else
    color.red                       // 本地块 (本地范围)

runtime.log("color", color = plotColor)  // 调用一个内置函数输出日志 (全局范围)

코드 변경

긴 줄은 여러 줄로 나눌 수 있고, 또는 “포직”될 수 있다. 포직된 줄은 4의 배수가 아닌 한, 임의의 수의 공백으로 축소되어야 한다. (이러한 경계들은 부분 블록으로 축소하기 위해 사용된다.)

a = open + high + low + close

이렇게 포장할 수 있습니다 (각 줄에 축소되는 빈 공간의 수는 4의 배수가 아니라는 점에 유의하십시오):

a = open +
      high +
          low +
             close

하나의 긴 plot ((() 호출은 으로 포장될 수 있다.

close1 = request.security(syminfo.tickerid, "D", close)      // syminfo.tickerid 当前交易对的日线级别收盘价数据系列
close2 = request.security(syminfo.tickerid, "240", close)    // syminfo.tickerid 当前交易对的240分钟级别收盘价数据系列
plot(ta.correlation(close, open, 100),                       // 一行长的plot()调用可以被包装
   color = color.new(color.purple, 40),
   style = plot.style_area,
   trackprice = true)

사용자 정의 함수 선언의 문장도 패키지 될 수 있다. 그러나, 지역 블록은 문법적으로 축소수로 시작해야 하기 때문에 ((4개의 빈 공간 또는 1개의 기호를 만드는), 다음 줄로 분할할 때, 문장의 계속되는 부분은 하나 이상의 축소수로 시작해야 한다 (((4개의 빈 공간의 곱과 같지 않다). 예를 들어:

test(c, o) =>
    ret = c > o ?
       (c > o+5000 ? 
          1 :
              0):
       (c < o-5000 ? 
          -1 : 
              0)

a = test(close, open)
plot(a, title="a")

시간계열

시간계열은 데이터 타입이나 형식이 아니라, 시간계열은 PINE 언어의 기본 구조 개념이다. 시간적으로 연속적으로 변화하는 값을 저장하기 위해 사용되며, 각 값은 하나의 시간점과 일치한다. 시간계열이 이러한 개념의 구조는 시간이 지남에 따라 변화하는 일련의 데이터를 처리하고 기록하는 데 적합하다. 내장 변수open예를 들어,open내장된 변수는 K선 BAR의 개시값을 기록합니다.open5분 K선주기의 데이터입니다.open변수에는 5분마다 K선 BAR (대항) 의 오프닝값이 기록되어 있습니다.open즉, 현재 K선 BAR의 개장값을 인용한다. 시간계열의 이전 값을 인용하기 위해, 우리는[]역사 연산자 (history operator) 는, 어떤 K선 BAR에 정책이 실행될 때,open[1]즉, 현재 K선 BAR의 이전 K선 BAR의 오프닝 가격을 참조한다.

하지만시간계열“배열”이라는 데이터 구조를 떠올리는 것은 쉽지만, PINE 언어에도 배열 타입이 있다. 하지만 그것들은 시간계와 완전히 다른 개념이다.

PINE 언어는 이렇게 설계된 시퀀스를 사용하여 정책 코드에서 클로즈값의 누적값을 쉽게 계산할 수 있으며, for와 같은 순환 구조를 사용하지 않고 PINE 언어의 내장 함수를 사용하여 사용할 수 있습니다.ta.cum(close)또 하나의 예로, 우리는 마지막 14개의 K선 BAR (code execution 시 현재 시점의 가장 가까운 14개의 K선 BAR) 의 최대값과 최소값의 평균값을 계산해야 합니다.ta.sma(high - low, 14)

시간열에서 함수를 호출하는 결과는 시간열에 흔적을 남길 수 있습니다.[]역사 연산자는 이전 값을 참조한다. 예를 들어, 현재 K 선 BAR의 마감값이 마지막 10 K 선 BAR의 최고값의 최대값을 초과하는지 테스트한다. (현재의 K 선 BAR을 제외한다.)breach = close > ta.highest(close, 10)[1]“이봐, 이봐, 이봐”breach = close > ta.highest(close[1], 10)그래서ta.highest(close, 10)[1]그리고ta.highest(close[1], 10)그리고 그 다음에는

다음 코드로 확인할 수 있습니다.

strategy("test pine", "test", true) 

a = ta.highest(close, 10)[1]
b = ta.highest(close[1], 10)

plotchar(true, title="a", char=str.tostring(a), location=location.abovebar, color=color.red)
plotchar(true, title="b", char=str.tostring(b), location=location.belowbar, color=color.green)

위의 테스트 코드는 a와 b를 각 BAR에 대해 대응하는 시간 순서에서의 값을 출력합니다. a와 b의 값이 항상 같다는 것을 볼 수 있으므로 두 표현 방법은 동등합니다.

역사 데이터 인용 (history-referencing)

트레이딩 뷰에는 역사 데이터 인용에 대한 최대 항목 제한이 있습니다. 예를 들어, 다음과 같은 코드:

//@version=6
indicator("test")

ema = ta.ema(close, 10000)      // 报错:Error on bar 0: The 'ema'->'sum' function references too many historical candles (10000), the limit is 5000.
plot(ema, "ema")

// pre10000 = ema[10000]        // 报错:Invalid number of bars back specified in the history-referencing operator. It accepts a value between 0 and 5000.
// plot(pre10000, "pre10000")

FMZ에서 PINE 언어 정책을 사용하는 Pine 언어 거래 클래스 라이브러리의 “거래 설정”, 파라미트: “변수의 가장 긴 주기 수” 특정 설정 참조 가능한 데이터의 최대 항목.

FMZ PINE 스크립트 문서

indicator("test")

ema = ta.ema(close, 1000)  // ema = ta.ema(close, 3000) 则报错:Invalid number 3000 of bars back specified in the history-referencing operator. It accepts a value between 0 and 2000.
plot(ema, "ema")

변수 최장주기수 (variable longest cycle number) 는 너무 커 설정되어서는 안되며, 적절한 정책에서 데이터 참조 범위는 .

Pine 언어 거래 클래스 라이브러리 모드 버전 변수

PINE 정책의 내장된 템플릿 “Pine 언어 거래 클래스 라이브러리”의 파라미트 설정 설명

FMZ PINE 스크립트 문서

거래 설정

  • 실행 클로즈 가격 모델: 현재 BAR가 끝나면 모델을 실행하고, 하위 BAR가 시작될 때 거래를 실행한다. 실시간 가격 모델: 가격의 변화마다 모델을 실행하고, 신호가 있으면 즉시 거래를 실행한다.
  • 기본 포지션 수: 거래 명령이 거래 수를 지정하지 않으면, 해당 설정의 수에 따라 거래를 실행하십시오.
  • 최대 단일 거래 단위: 실제 상장량에 따라, 이 파라미터 설정과 함께, 매 매 주문의 최대 수를 결정하여 상장면을 충격을 피하십시오.
  • 점유율의 점유율:定价货币精度매개 변수와 매개 변수는 주문 시의 미끄러운 가격을 결정한다. 예를 들어, 가격화폐의 정밀도는 2로 설정되어 있고, 0.01으로 정확하다. 미끄러운 점수는 0.01의 가격 단위를 나타냅니다. 미끄러운 점수는 5로 설정되어 있으며, 주문 시의 미끄러운 가격은 0.05이다. 미끄러운 가격은 주문 시의 미끄러운 가격을 나타냅니다.
  • 변수의 최장주기 수: 그래프 K 라인 BAR의 수와javascript전략에서 호출SetMaxBarLen함수는 동일하다.

선물 옵션

  • 품종 코드: 계약 코드, 거래소 객체가 비현실 거래소 객체일 때만 설정해야 한다.
  • 최소 계약 수: 주문할 때, 계약의 최소 거래량

실제 옵션

  • 자동 복귀 진행: 자동으로 마지막 전략이 중단되기 전의 상태로 복귀한다.
  • 주문 재시험 수: 주문이 거래되지 않으면 주문을 취소하고 거래를 시도하기 위해 다시 주문합니다. 이 매개 변수는 최대 재시험 수를 제한하는 데 사용됩니다.
  • 네트워크 설문 조사 간격 ((밀리 초): REST 프로토콜에만 유효하며, 네트워크 요청 간격을 제어하여 거래소 제한을 초과하는 너무 빈번한 요청을 피한다.
  • 계정 동기화 시간 (초): 계정 데이터를 동기화 하는 시간 주기.
  • 포지션 개시 후 포지션 동기화 시간 ((밀리 초): 일부 거래소 데이터 지연으로 인한 반복 개시 포지션에만 적용되며, 동기화 시간을 더 크게 설정하면 이러한 문제를 완화 할 수 있습니다.
  • 레버리 배수: 레버리 배수를 설정한다.

현금 거래, 다른 설정

  • 일회용 거래량: 기본 일회용 거래량은 현금 거래에만 적용됩니다.
  • 최소 거래량: 최소 거래량
  • 가격의 정확성: 가격의 정확성, 즉 가격의 소수점.
  • 거래 품종 정확도: 다음 주문량 정확도, 즉 다음 주문량 소수점.
  • 수료: 이 설정에 따라 일부 데이터에 대해 계산하면, 0.002는 천분의 2을 나타냅니다.
  • 손실 통계 간격: 실 디스크에서만 손실 통계 사용.
  • 실패 재시험 ((밀리초): 네트워크 요청이 실패했을 때 재시험 간격.
  • 에이전트 사용: REST 프로토콜에서만 유효하다.
  • 일반적인 네트워크 오류를 숨기기: 로그 영역에서 일반적인 오류를 숨기기
  • 스위치 베이스 주소: REST 프로토콜에서만 유효하다.
  • 포스트 알림: 메세지를 포스트 박스에 포스트하는 것 등

주문하기

지점을 열기

strategy(title = "open long example", pyramiding = 3)                                // pyramiding 允许的同方向下单的次数
strategy.entry("long1", strategy.long, 0.01)                                         // 市价开多仓,指定分组标签为long1
strategy.entry("long2", strategy.long, 0.02, when = close > ta.ema(close, 10))       // 条件触发,执行下单,市价开多仓
strategy.entry("long3", strategy.long, 0.03, limit = 30000)                          // 指定(较低的)价格,计划下买单订单,等待成交开仓,限价开仓

평지

strategy(title = "close long example", pyramiding = 2)                              // pyramiding 允许的同方向下单的次数
strategy.entry("long1", strategy.long, 0.1)                                         // 市价开多仓,指定分组标签为long1
strategy.entry("long2", strategy.long, 0.1)                                         // 市价开多仓,指定分组标签为long2
strategy.close("long1", when = strategy.position_size > 0.1, qty_percent = 50, comment = "close buy entry for 50%")   // 平仓,指定平掉分组标签为long1的仓位的50%持仓
strategy.close("long2", when = strategy.position_size > 0.1, qty_percent = 80, comment = "close buy entry for 80%")   // 平仓,指定平掉分组标签为long2的仓位的80%持仓

거래 메커니즘

PINE 언어의 포지션 보유 메커니즘은 일방 포지션 보유와 유사하다. 예를 들어, 다방향 포지션을 보유할 때, 만약 판매하는 작업의 주문, 계획표 등이 있다 할 때 포지션 보유 방향에 대해 반대 방향의) 주문이 트리거 실행될 때, 이때 먼저 다방향 포지션을 평면화하고, 다음으로 트리거를 실행한다. 포지션 보유 방향에 대해 반대 방향의) 주문이 실행된다.

계획표

주문 명령어를 사용하여 주문할 때, 어떤 가격도 지정하지 않으면, 시가 요금이 기본으로 설정된다. 시가 요금 이외에도 계획 요금으로 주문할 수 있으며, 계획 요금은 즉시 주문을 실행하지 않는다.실판/회복시간 상태 정보 (즉, 전략이 실행되는 상태 ) 의 “계획 주문” 란 칸에서 볼 수 있습니다. 시장 실시간 가격이 조건을 충족할 때 이러한 계획 주문을 유발할 때 시스템이 실제로 주문합니다. 따라서 이러한 주문은 거래 가격에 약간의 오차가있는 것이 정상적인 상황입니다.strategy.entry함수가 주문할 때, 우리는limitstop변수

var isTrade = false 
if not barstate.ishistory and not isTrade
    isTrade := true 
    strategy.entry("test 1", strategy.long, 0.1, stop=close*1.3, comment="test 1 order")                     // stop
    strategy.entry("test 2", strategy.long, 0.2, limit=close*0.7, comment="test 2 order")                    // limit
    strategy.entry("test 3", strategy.short, 0.3, stop=close*0.6, limit=close*1.4, comment="test 3 order")   // stop-limit    
  • 제한 주문

주문의 한계 가격을 설정합니다.direction매개변수는 다음과 같습니다strategy.long), 오더는 현재 시장 가격이 그 가격보다 낮을 때만 트리거됩니다. 주문은 판매요금 (예:direction매개변수는 다음과 같습니다strategy.short), 오더는 현재 시장 가격이 그 가격보다 높을 때만 트리거됩니다.

  • 정지 명령

주문의 스톱 손실 가격을 설정합니다. 주문이 구매가 될 때, 주문은 시장의 현재 가격이 그 가격보다 높을 때만 트리거됩니다. 주문이 판매 주문일 때, 시장의 현재 가격이 그 가격보다 낮으면 주문이 트리거됩니다.

  • stop-limit 주문

동시에 설정할 수 있습니다.limitstop매개 변수, 주문이 가장 먼저 합격한 가격에 트리거된다.

지분 비율

//@version=5
strategy("Percent of Equity Order", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100)  

// 简单的均线交叉策略
longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))  

// 如果均线交叉条件满足,则买入或卖出
if (longCondition)
    strategy.entry("Long", strategy.long)  

if (shortCondition)
    strategy.entry("Short", strategy.short)
  

지정된default_qty_type=strategy.percent_of_equity후, 설정default_qty_value백분율 수로 ((0~100), 1은 1%이다. 계좌에 있는 평가 통화 수에 따라 주문을 계산한다. 예를 들어: 현재 계좌에 10000 USDT가 있고, 1%의 주문을 설정한다. 즉 100 USDT 규모의 주문을 사용한다.

선언, 논리 구조 키워드

var

var은 배분 및 일회성 초기화 변수에 사용되는 키워드이다. 일반적으로, 키워드 var을 포함하지 않는 변수 부여 문법은 데이터 업데이트를 할 때마다 변수의 값을 덮어 둡니다. 반대로, 키워드 var을 사용하여 변수를 할당할 때, 데이터 업데이트에도 불구하고, 그들은 상태 을 계속 유지할 수 있으며, if-expressions의 조건을 충족시킬 때만 변경됩니다.

var variable_name = expression

설명:

  • variable_name- 파인 스크립트에서 허용되는 사용자 변수의 이름들 중 하나인 (((는 대문자와 소문자의 라틴 문자, 숫자, 하위 선을 포함할 수 있습니다._), 하지만 숫자로 시작하지 마세요)
  • expression- 어떤 수학적 표현도, 정규 변수를 정의하는 것과 같다. 표현을 계산하고 변수에 한번만 할당한다.

예를 들어

// Var keyword example
var a = close
var b = 0.0
var c = 0.0
var green_bars_count = 0
if close > open
    var x = close
    b := x
    green_bars_count := green_bars_count + 1
    if green_bars_count >= 10
        var y = close
        c := y
plot(a, title = "a")
plot(b, title = "b")
plot(c, title = "c")

변수 ‘a’는 일련의 각 기둥의 첫 기둥의 종결값을 유지한다. 변수 ‘b’는 시리즈의 첫 번째 ?? 녹색 ?? 가격 막대의 종료 가격을 유지한다. 변수 ‘c’는 시리즈의 10번째 그린의 종전 가격을 유지한다.

FMZ에서는 실시간 가격 모델과 종결 가격 모델로 구분되어 있습니다.varvarip우리는 다음과 같은 코드를 사용하여 선언 변수를 테스트합니다.

strategy("test pine", "test 1", true) 

// 测试 var varip
var i = 0
varip ii = 0

// 将策略逻辑每轮改变的i、ii打印在图上
plotchar(true, title="ii", char=str.tostring(ii), location=location.abovebar, color=color.red)
plotchar(true, title="i", char=str.tostring(i), location=location.belowbar, color=color.green)

// 每轮逻辑执行都给i、ii递增1
if true
    i := i + 1
    ii := ii + 1
  • 실시간 가격 모델 위의 테스트 코드는 실행 시 두 단계로 나뉘어져 있습니다: 1 , 역사 K 라인 단계 ◦ 2 , 실제 K 라인 단계 ◦varvarip선언된 변수 i, ii는 정책 코드의 각 라운드 실행에 따라 증가 동작을 수행합니다.if true따라서 반드시 해당 조건 코드 블록을 실행한다) ᄒ 그래서 K선 BAR에 표시되는 숫자가 각각 1을 증가하는 것을 볼 수 있다. 역사 K선 단계가 끝나면 실시간 K선 단계가 시작된다.varvarip선언된 변수는 다른 변화가 시작된다. 실시간 가격 모델이기 때문에, K선 BAR 내의 가격 변화마다 전략 코드가 실행되고,i := i + 1그리고ii := ii + 1모두 한 번 실행한다。 차이점은 ii가 매번 수정한다。 i는 매번 수정되기도 하지만, 다음 라운드 실행 전략 논리시 이전값을 복원한다. 현재 K선 BAR가 지나가기 전까지는 i의 값을 새로 결정한다. 따라서 i의 값은 다음 라운드 실행 전략 논리시 이전값을 복원하지 않는다. 따라서 i의 값은 여전히 각 BAR 1이 증가하는 것을 볼 수 있다。 하지만, ii의 값은 각 BAR에 몇 번씩 누적된다。

  • 종가 모델 종결 가격 모형은 K선 BAR가 끝나면 한 번의 전략 논리를 수행한다. 따라서 종결 가격 모형에서는 역사적인 K선 단계와 실시간 K선 단계,varvarip선언된 변수는 위의 예제에서 증가하는 성능을 완전히 일치합니다. K줄마다 BAR 증가 1 이다.

varip

varip ((var intrabar persist) 는 배분 및 일회성 초기화 변수의 키워드이다. 이는 var 키워드와 비슷하지만, varip 선언을 사용하는 변수는 실시간 K선 업데이트 사이에 값을 유지한다.

varip variable_name = expression

설명:

  • variable_name- Pine 스크립트에서 허용되는 사용자 변수의 이름들 중 하나인 ((는 대문자 및 소문자 라틴 문자, 숫자 및 밑줄을 포함할 수 있습니다))_), 하지만 숫자로 시작하지 마세요)
  • expression- 어떤 수학적 표현도, 정규 변수를 정의할 때와 마찬가지로. 첫 번째 K 선에서, 표현은 한 번만 계산되고 변수에 한 번만 할당된다.

예를 들어

// varip
varip int v = -1
v := v + 1
plot(v)

var을 사용하면, 그림이 bar_index의 값을 반환한다. varp를 사용하면, 역사 K선에서 동일한 동작이 발생하지만, 실시간 K선에서는 그림이 각 tick에 대해 1을 증가시키는 값을 반환한다.

참고 사항 float,int,bool,string와 같은 간단한 타입과 이러한 타입의 배열과 함께만 사용할 수 있습니다.

true

부르 타입의 변수의 값을 나타내거나, 표현식에서 사용할 때비교또는논리연산자에서 계산할 수 있는 값

참고 사항 또한 참조비교연산자와논리연산자의 설명

이 부분도 참조하십시오. bool

false

부르 타입 변수의 값을 나타내며, 비교 동작, 논리 동작의 결과를 나타낸다.

참고 사항 또한 참조비교연산자와논리연산자의 설명

이 부분도 참조하십시오. bool

if

If 문장은 표현식 조건을 충족할 때 실행해야 하는 문장 블록을 정의한다. 4 버전의 파인 스크립트 언어는 ?? else if ?? 문법을 사용하도록 허용한다.

일반 코드는 다음과 같습니다:

var_declarationX = if condition
    var_decl_then0
    var_decl_then1
    ...
    var_decl_thenN
    return_expression_then
else if [optional block]
    var_decl_else0
    var_decl_else1
    ...
    var_decl_elseN
    return_expression_else
else
    var_decl_else0
    var_decl_else1
    ...
    var_decl_elseN
    return_expression_else

참고 사항 var_declarationX- 이 변수는 if 문장의 값을 가져옵니다. condition- 조건이 true라면, 문장 블록을 사용한다.then이 논리는var_decl_then0var_decl_then1만약 조건이 false라면, 문장 블록을 사용한다.else if또는else이 논리는var_decl_else0var_decl_else1 return_expression_then , return_expression_else- 모듈의 마지막 표현식 또는 블록else의 표현식은 문장의 최종값을 반환한다. 변수의 선언이 마지막에 있다면, 그 값은 결과값이 된다.

if 문장의 반환값의 종류는return_expression_then그리고return_expression_else타입。TradingView에서 실행할 때, 그들의 타입은 일치해야 한다: else 블록에 문자열 값이 있을 때, then 문장 블록에서 정수 값을 반환하는 것은 불가능하다。 FMZ에서 실행할 때, 다음 예제는 오류를 발생시키지 않으며, y 값이 “open”을 받을 때, plot 도면할 때 값은 n/a。

예를 들어

// This code compiles
x = if close > open
    close
else
    open  

// This code doesn’t compile by trading view
// y = if close > open
//     close
// else
//     "open"
plot(x)

제외할 수 있습니다.else블록. 이 경우, 조건이 false 인 경우, var_declarationX 변수에 empty 값을 할당합니다:

예를 들어

// if
x = if close > open
    close
// If current close > current open, then x = close.
// Otherwise the x = na.
plot(x)

여러 개의 else if 블록을 사용할 수 있거나 전혀 사용하지 않습니다. then, else if, else의 블록은 다음과 같이 네 개의 빈 공간으로 이동됩니다:

예를 들어

// if
x = if open > close
    5
else if high > low
    close
else
    open
plot(x)

무시할 수 있습니다.if문장의 결과값은 ((var_declarationX=를 생략할 수 있습니다) ᅲ). 표현의 부작용이 필요한 경우에 유용할 수 있습니다. 예를 들어, 전략 거래에서:

예를 들어

if (ta.crossover(high, low))
    strategy.entry("BBandLE", strategy.long, stop=low)
else
    strategy.cancel(id="BBandLE")

If 문장은 서로 포함될 수 있습니다:

예를 들어

// if
float x = na
if close > open
    if close > close[1]
        x := close
    else
        x := close[1]
else
    x := open
plot(x)

for

‘for’ 구조는 여러 문장을 반복적으로 실행할 수 있게 해줍니다.

[var_declaration =] for counter = from_num to to_num [by step_num]
    statements | continue | break
    return_expression

var_declaration- 선택 가능한 변수 선언으로 return_expression의 값으로 지정됩니다. counter- 회전 카운터 값의 변수를 저장하고, 회전의 각 반복에서 1 또는 step_num 값을 증가/감소한다. from_num- 카운터의 시작값 series int/float 값/표현을 사용할 수 있습니다 series int/float 값/표현을 사용할 수 있습니다 series int/float 값/표현을 사용할 수 있습니다 to_num- 카운터의 최종값. 카운터가 to_num보다 크거나 from_num > to_num의 경우 to_num보다 작으면 순환이 중단된다. series int/float 값/표현을 사용할 수 있지만, 그것들은 순환의 첫 번째 반복 시에만 평가된다. step_num- 카운터의 증가/감소값. 그것은 선택적입니다. 기본값은 +1 또는 -1입니다. 이는 from_num 또는 to_num 중 가장 큰 값에 따라 다릅니다. statements | continue | break- 임의의 수의 문장, 또는 ‘continue’ 또는 ‘break’ 키워드를 4개의 공백 또는 1개의 탭으로 축소하십시오. return_expression- 루프의 반환값은, 존재한다면, var_declaration의 변수에 할당된다. 만약 루프가 continue 또는 break 키워드 때문에 종료된다면, 루프의 반환값은 루프가 종료되기 전에 할당된 값의 마지막 변수의 반환값이다. continue- 회귀에서만 사용할 수 있는 키워드. 이는 회귀의 다음 반복이 실행되도록 한다. break- 회로에서 탈퇴하는 키워드.

예를 들어

// Here, we count the quantity of bars in a given 'lookback' length which closed above the current bar's close
qtyOfHigherCloses(lookback) =>
    int result = 0
    for i = 1 to lookback
        if close[i] > close
            result += 1
    result
plot(qtyOfHigherCloses(14))

이 부분도 참조하십시오. for...in while

for…in

for...in구조는 배열의 각 요소에 대해 반복적으로 여러 문장을 실행할 수 있다. 그것은 임의의 인수와 함께 사용될 수 있다:array_element, 또는 두 개의 변수와 함께 사용한다:[index, array_element]。 두 번째 형태는 순환의 기능을 영향을 주지 않는다。 그것은 모형의 첫 번째 변수에서 현재 반복의 인덱스를 추적한다。

[var_declaration =] for array_element in array_id
    statements | continue | break
    return_expression

[var_declaration =] for [index, array_element] in array_id
    statements | continue | break
    return_expression

var_declaration- 선택 가능한 변수 선언, 순환하는 것에 부여됩니다return_expression값은 index- 현재 연대된 인덱스의 선택 변수를 추적한다. 인덱스는 0에서 시작된다. 변수는 순환체에서 변하지 않는다.array_element의 모형 중 array_element- 순환에서 처리될 각 연속 배열 요소의 변수를 포함한다. 이 변수는 순환체에서 변하지 않는다. array_id- 회전 모의의 배열 ID. statements | continue | break- 임의의 수의 문장, 또는 ‘continue’ 또는 ‘break’ 키워드를 4개의 공백 또는 1개의 탭으로 축소하십시오. return_expression- 루프의 반환값은var_declaration속의 변수, 만약 존재한다면. 루프가 ‘continue’ 또는 ‘break’ 키워드 때문에 종료되면, 루프의 반환 값은 루프가 종료되기 전에 마지막으로 부여된 변수이다. continue- 회귀에서만 사용할 수 있는 키워드. 이는 회귀의 다음 반복이 실행되도록 한다. break- 회로에서 탈퇴하는 키워드.

루프 내에서 배열의 요소 또는 크기를 변경할 수 있습니다. 여기, 우리는for...in각각의 K 선에서, K 선의 OHLC 값이 ‘close’ 값의 SMA보다 얼마나 큰지를 결정하기 위한 단일 변수 형태:

예를 들어

// Here we determine on each bar how many of the bar's OHLC values are greater than the SMA of 'close' values
float[] ohlcValues = array.from(open, high, low, close)
qtyGreaterThan(value, array) =>
    int result = 0
    for currentElement in array
        if currentElement > value
            result += 1
        result
plot(qtyGreaterThan(ta.sma(close, 20), ohlcValues))

여기, for…in의 두 가지 변수를 사용해서isPos란 값이 있습니다.true우리한테 왔을 때valuesArray배열의 대응값은 정시입니다:

예를 들어

// for...in
var valuesArray = array.from(4, -8, 11, 78, -16, 34, 7, 99, 0, 55)
var isPos = array.new_bool(10, false)  

for [index, value] in valuesArray
    if value > 0
        array.set(isPos, index, true)  

if barstate.islastconfirmedhistory
    runtime.log(str.tostring(isPos))

이 부분도 참조하십시오. for while array.sum array.min array.max

while

while이 문장은 로컬 코드 블록의 조건 반복을 허용한다.

variable_declaration = while boolean_expression
    ...
    continue
    ...
    break
    ...
    return_expression

설명: variable_declaration- 선택 가능한 변수 선언.return expression이 변수에 대해 초기화 값을 제공할 수 있다. boolean_expression- 만약 true라면 실행while문장의 로컬 블록. false라면while문장과 문장 뒤에 계속 스크립트를 실행하십시오. continue - continue키워드는 순환을 다음 번으로 이어지게 합니다. break - break키워드가 루프를 종료한다.while문장 후 복귀. return_expression- 제공while문장값을 반환하는 옵션 행

예를 들어

// This is a simple example of calculating a factorial using a while loop.
int i_n = input.int(10, "Factorial Size", minval=0)
int counter   = i_n
int factorial = 1
while counter > 0
    factorial := factorial * counter
    counter   := counter - 1

plot(factorial)

참고 사항 초창기while행 뒤에 있는 로컬 코드 블록은 4개의 빈 공간이나 1개의 기호로 축소되어야 합니다. 종료합니다.while순환,while다음 Boolean 표현은 결국 false로 바뀌어야 합니다.break

switch

switch 연산자는 조건과 표현식의 값에 따라 제어권을 몇 개의 문장 중 하나에 이양한다.

[variable_declaration = ] switch expression
    value1 => local_block
    value2 => local_block
    ...
    => default_local_block

[variable_declaration = ] switch
    boolean_expression1 => local_block
    boolean_expression2 => local_block
    ...
    => default_local_block

“switch”라는 표현이 있습니다.

예를 들어

// Switch using an expression

string i_maType = input.string("EMA", "MA type", options = ["EMA", "SMA", "RMA", "WMA"])

float ma = switch i_maType
    "EMA" => ta.ema(close, 10)
    "SMA" => ta.sma(close, 10)
    "RMA" => ta.rma(close, 10)
    // Default used when the three first cases do not match.
    => ta.wma(close, 10)

plot(ma)

표현이 없는 스위치:

예를 들어

strategy("Switch without an expression", overlay = true)

bool longCondition  = ta.crossover( ta.sma(close, 14), ta.sma(close, 28))
bool shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))

switch
    longCondition  => strategy.entry("Long ID", strategy.long)
    shortCondition => strategy.entry("Short ID", strategy.short)

값을 반환합니다. 실행되는 로컬 시트먼트 블록의 마지막 표현의 값

참고 사항 실행할 수 있습니다.local_block예를 들어default_local_block첫 번째.default_local_block단지=>마크가 함께 도입되고, 이전 블록이 실행되지 않은 경우에만 실행됩니다.switch문장의 결과는 변수에 할당되고 지정되지 않습니다.default_local_block실행되지 않으면,local_block, 이 문장이 반환됩니다.naswitch문장의 결과가 변수에 할당되면, 모든local_block이 인스턴스는 같은 타입의 값을 반환해야 합니다.

이 부분도 참조하십시오. if ?:

series

series는 데이터 시리즈의 유형을 나타내는 키워드이다.series키워드는 보통 불필요합니다.

연산자

=

변수에 값을 부여하는 데 사용되지만 변수를 선언할 때만 사용된다.

:=

부여 연산자, 왼쪽 변수에 부여하는 값. 이전 선언된 변수에 부여하는 값이다.

!=

≠ ≠ ≠ ≠ ≠ ≠ ≠ ≠ ≠ ≠ ≠ ≠ ≠ ≠ ≠ ≠ ≠ ≠

expr1 != expr2

값을 반환합니다. 부르값, 또는 부르값의 일련

%

모형수 ((整数余数) . 숫자 표현에 적용된다.

expr1 % expr2

값을 반환합니다. 실수 또는 부동소수점 값, 또는 일련의 값

참고 사항 파인 스크립트에서, 정수의 여분의 계산을 할 때, 상자는 단절된다. 즉, 최소 절대값으로 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글다.

예: -1 % 9 = -1 - 9 * truncate ((-19) = -1 - 9 * truncate ((-0.111) = -1 - 9 * 0 = -1 △

%=

모들리얼 지명. 숫자 표현에 적용된다.

expr1 %= expr2

예를 들어

// Equals to expr1 = expr1 % expr2.
a = 3
b = 3
a %= b
// Result: a = 0.
plot(a)

값을 반환합니다. 실수 또는 부동소수점 값, 또는 일련의 값

*

곱셈. 숫자 표현에 적용된다.

expr1 * expr2

값을 반환합니다. 실수 또는 부동소수점 값, 또는 일련의 값

*=

곱셈을 지정한다. 숫자 표현에 적용한다.

expr1 *= expr2

예를 들어

// Equals to expr1 = expr1 * expr2.
a = 2
b = 3
a *= b
// Result: a = 6.
plot(a)

값을 반환합니다. 실수 또는 부동소수점 값, 또는 일련의 값

+

덧셈 또는 1인칭 기호. 숫자 표현식이나 문자열에 적용된다.

expr1 + expr2
+ expr

값을 반환합니다. 문자열의 이진성+expr1과 expr2의 합성을 반환합니다. 숫자는 전체 숫자 또는 플래잉 포인트 값을 반환합니다. 또는 일련의 값: 이진법 ‘+‘은 expr1 더하기 expr2 을 반환한다. 1元+은 expr를 반환한다 ((1元 연산자의 대칭에 아무 것도 추가하지 않는다)

참고 사항 숫자와 변수들의 수를 가진 수학적 연산자를 사용할 수 있다. 수를 사용하는 경우, 연산자는 요소에 적용된다.

+=

덧셈 지명 은 숫자 표현식이나 문자열에 적용된다.

expr1 += expr2

예를 들어

// Equals to expr1 = expr1 + expr2.
a = 2
b = 3
a += b
// Result: a = 5.
plot(a)

값을 반환합니다. 문자열의 경우, expr1과 expr2의 연속성을 반환한다. 숫자의 경우, 정수 또는 부동소수점 값을 반환한다. 또는 일련의 값을 반환한다.

참고 사항 숫자와 변수들의 수를 가진 수학적 연산자를 사용할 수 있다. 수를 사용하는 경우, 연산자는 요소에 적용된다.

-

빼기법 또는 일인수 음수 ᄂ. 숫자 표현식에 적용된다.

expr1 - expr2
- expr

값을 반환합니다. 전체 숫자 또는 플래잉 포인트 값을 반환합니다. 이진법 ‘+‘은 expr1 빼기 expr2을 반환한다. 1원-expr의 부정식을 반환한다.

참고 사항 숫자와 변수들의 수를 가진 수학적 연산자를 사용할 수 있다. 수를 사용하는 경우, 연산자는 요소에 적용된다.

-=

빼기법 지명. 숫자 표현에 적용된다.

expr1 -= expr2

예를 들어

// Equals to expr1 = expr1 - expr2.
a = 2
b = 3
a -= b
// Result: a = -1.
plot(a)

값을 반환합니다. 실수 또는 부동소수점 값, 또는 일련의 값

/

예외: 숫자 표현에 적용된다.

expr1 / expr2

값을 반환합니다. 실수 또는 부동소수점 값, 또는 일련의 값

/=

除法指派。 숫자 표현식에 적용한다。

expr1 /= expr2

예를 들어

// Equals to expr1 = expr1 / expr2.
a = 3
b = 3
a /= b
// Result: a = 1.
plot(a)

값을 반환합니다. 실수 또는 부동소수점 값, 또는 일련의 값

<

미만 △는 숫자 표현에 적용된다.

expr1 < expr2

값을 반환합니다. 부르값, 또는 부르값의 일련

<=

이보다 작거나 같다는 것은 숫자 표현에 적용된다.

expr1 <= expr2

값을 반환합니다. 부르값, 또는 부르값의 일련

==

모든 종류의 표현에 적용된다.

expr1 == expr2

값을 반환합니다. 부르값, 또는 부르값의 일련

=>

’=>’ 연산자는 사용자 정의 함수 선언과switch문장에서

함수 선언 문법은 다음과 같습니다.

<identifier>([<parameter_name>[=<default_value>]], ...) =>
    <local_block>
    <function_result>

하나<local_block>0개 또는 그 이상의 파인 문장이다. <function_result>변수, 표현식 또는 모형이다.

예를 들어

// single-line function
f1(x, y) => x + y
// multi-line function
f2(x, y) => 
    sum = x + y
    sumChange = ta.change(sum, 10)
    // Function automatically returns the last expression used in it
plot(f1(30, 8) + f2(1, 3))

참고 사항 사용자 설명서의 선언 함수 및 스크립트 라이브러리 페이지에서 사용자 정의 함수에 대한 자세한 정보를 얻을 수 있습니다.

>

△보다 크다. 숫자 표현에 적용된다.

expr1 > expr2

값을 반환합니다. 부르값, 또는 부르값의 일련

>=

이보다 크거나 같다. 숫자 표현에 적용된다.

expr1 >= expr2

값을 반환합니다. 부르값, 또는 부르값의 일련

?:

삼위 조건 연산자 △

expr1 ? expr2 : expr3

예를 들어

// Draw circles at the bars where open crosses close
s2 = ta.cross(open, close) ? math.avg(open,close) : na
plot(s2, style=plot.style_circles, linewidth=2, color=color.red)  

// Combination of ?: operators for 'switch'-like logic
c = timeframe.isintraday ? color.red : timeframe.isdaily ? color.green : timeframe.isweekly ? color.blue : color.gray
plot(hl2, color=c)

값을 반환합니다. 만약 expr1이 true로 평가된다면, expr2가, 그렇지 않으면 expr3이다. 0값 ((0과 NaN+, Infinity,-Infinity) 은 false로 간주되며, 다른 값들은 true이다.

참고 사항 필요 없는 경우, na를 else의 지점으로 사용하십시오. 두 개 이상의?: 연산자를 결합하여 ?? switch ?? 와 같은 문장을 구현할 수 있습니다. ( 위의 예제를 참조하십시오.) 숫자와 변수들의 수를 가진 수학적 연산자를 사용할 수 있다. 수를 사용하는 경우, 연산자는 요소에 적용된다.

이 부분도 참조하십시오. na

[]

일련의 하위 expr1 시리즈의 이전 값에 대한 액세스를 제공합니다 expr2는 지난 k 줄의 수이며, 값이어야 합니다 플로잉은 아래로 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥글게 둥

expr1[expr2]

예를 들어

// [] can be used to "save" variable value between bars
a = 0.0 // declare `a`
a := a[1] // immediately set current value to the same as previous. `na` in the beginning of history
if high == low // if some condition - change `a` value to another
    a := low
plot(a)

값을 반환합니다. 일련의 값들

이 부분도 참조하십시오. math.floor

and

논리 AND 은 표현식에 적용된다.

expr1 and expr2

값을 반환합니다. 부르값, 또는 부르값의 일련

or

논리 OR。는 부어 표현에 적용된다。

expr1 or expr2

값을 반환합니다. 부르값, 또는 부르값의 일련

not

논리 역설 ((NOT) ᄋ) ᄂ) ᄂ) ᄂ) ᄂ) ᄂ) ᄂ) ᄂ) ᄂ) ᄂ) ᄂ) ᄂ) ᄂ) ᄂ) ᄂ) ᄂ) ᄂ) ᄂ) ᄂ)

not expr1

값을 반환합니다. 부르값, 또는 부르값의 일련

데이터 타입 키워드

bool

명시적으로 선언하는 변수 또는 변수들의 bool () () () () () 류의 키워드. “Bool” 변수의 값은 true, false 또는 na이 될 수 있다.

예를 들어

// bool
bool b = true    // Same as `b = true`
b := na
plot(b ? open : close)

참고 사항 변수 선언에서 타입을 명시적으로 언급하는 것은 선택적입니다, 만약 na로 초기화되지 않는다면. 타입 시스템의 사용자 설명서 페이지에서 Pine 타입에 대한 더 많은 정보를 참조하십시오.

이 부분도 참조하십시오. var varip int float color string true false

int

int ((整数) 타입의 키워드, int () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () ()

예를 들어

// int
int i = 14    // Same as `i = 14`
i := na
plot(i)

참고 사항 변수 선언에서 타입을 명시적으로 언급하는 것은 선택적입니다, 만약 na로 초기화되지 않는다면. 타입 시스템의 사용자 설명서 페이지에서 Pine 타입에 대한 더 많은 정보를 참조하십시오.

이 부분도 참조하십시오. var varip float bool color string

float

float ((플로잉 포인트) 타입의 키워드, float ((플로잉 포인트)) 타입의 키워드, float ((플로잉 포인트)) 타입의 키워드.

예를 들어

// float
float f = 3.14    // Same as `f = 3.14`
f := na
plot(f)

참고 사항 변수 선언에서 유형을 명시적으로 언급하는 것은 선택적입니다.

이 부분도 참조하십시오. var varip int bool color string

string

“string” 타입의 키워드로서, 변수나 변수를 명시적으로 선언한다.

예를 들어

// string
string s = "Hello World!"    // Same as `s = "Hello world!"`
// string s = na // same as "" 
plot(na, title=s)

참고 사항 변수 선언에서 타입을 명시적으로 언급하는 것은 선택적입니다, 만약 na로 초기화되지 않는다면. 타입 시스템의 사용자 설명서 페이지에서 Pine 타입에 대한 더 많은 정보를 참조하십시오.

이 부분도 참조하십시오. var varip int float bool str.tostring str.format

color

“color” 타입의 키워드를 사용하여 변수나 변수를 명시적으로 선언합니다.

예를 들어

// color
color textColor = color.green
if barstate.islastconfirmedhistory
    runtime.log("test", textcolor = textColor)

참고 사항 컬러 문자에는 다음과 같은 형식이 있습니다: #RRGGBB 또는 #RRGGBBAA. 문자 쌍은 00에서 FF까지의 16진법값을 나타냅니다 ((10진법 0에서 255까지), 여기서 RR, GG 및 BB 쌍은 색상의 빨간색, 녹색 및 파란색 분량의 값입니다. AA는 색상의 투명성 (또는 알파 분량) 의 선택값입니다. 변수 선언에서 타입을 명시적으로 언급하는 것은 선택적입니다, 만약 na로 초기화되지 않는다면. 타입 시스템의 사용자 설명서 페이지에서 Pine 타입에 대한 더 많은 정보를 참조하십시오.

이 부분도 참조하십시오. var varip int float string color.rgb color.new

array

명시적으로 변수 또는 변수를 선언하는 배열 타입의 키워드 . 사용할 수 있다array.new<type>,array.from함수는 배열 객체 ((또는 ID) 를 만듭니다.

예를 들어

// array
array<float> a = na
a := array.new<float>(1, close)
plot(array.get(a, 0))

참고 사항 배열의 대상은 항상 시리즈 형태이다.

이 부분도 참조하십시오. var array.new array.from

Objects

PINE 언어의 Objects 객체는 사용자 정의 타입 (UDT) 의 예이며, 무방법 클래스로 이해될 수 있으며, 사용자가 정책에서 사용자 정의 타입을 만들어 하나의 엔티티에 다른 값을 조직할 수 있도록 해준다.

유형 정의

주문 정보를 저장하기 위해 ‘order type’를 정의해 봅시다.

type order
    float price
    float amount
    string symbol
  • 사용type키워드 선언 유형
  • type 키워드 뒤에 type 이름이다.
  • 첫 번째 줄 type는 타입 이름을 정의한 후, 네 개의 공백으로 스커닝하여 타입이 포함된 필드를 정의합니다.
  • 각 필드는 int,float,string 등의 데이터 타입을 명시해야 합니다.

객체 생성

선언된 타입을 사용하여 호출new()함수 생성 객체:

order1 = order.new()
order1 = order.new(100, 0.1, "BTC_USDT")
order1 = order.new(amount = 0.1, symbol = "BTC_USDT", price = 100)

빈 오브젝트를 만들 수도 있습니다.

order order1 = na

여기 실제 사례가 있습니다.

type order
    float price
    float amount
    string symbol

if strategy.position_size == 0 and open > close
    strategy.entry("long", strategy.long, 1)

order1 = order.new(strategy.opentrades.entry_price(strategy.opentrades - 1), strategy.opentrades.size(strategy.opentrades - 1), syminfo.ticker)
// runtime.log(order1)   // 输出 {"data":{"price":46002.8,"amount":1,"symbol":"swap"},"_meta":0,"_type":"order"}

예를 들면,

order1 = order.new(strategy.opentrades.entry_price(strategy.opentrades - 1), strategy.opentrades.size(strategy.opentrades - 1), syminfo.ticker)

이 문서는 다음과 같은 형태로 작성될 수 있습니다.

order order1 = na
order1 := order.new(strategy.opentrades.entry_price(strategy.opentrades - 1), strategy.opentrades.size(strategy.opentrades - 1), syminfo.ticker)

객체 타입 var 키워드에 대한 사용

//@version=5
indicator("Objects using `var` demo")

//@type A custom type to hold index, price, and volume information.
type BarInfo
    int   index = bar_index
    float price = close
    float vol   = volume

//@variable A `BarInfo` instance whose fields persist through all iterations, starting from the first bar.
var BarInfo firstBar = BarInfo.new()
//@variable A `BarInfo` instance declared on every bar.
BarInfo currentBar = BarInfo.new()

// Plot the `index` fields of both instances to compare the difference.
plot(firstBar.index, "firstBar")
plot(currentBar.index, "currentBar")

var 키워드 선언을 사용하여 사용자 정의 타입의 객체의 변수를 할당할 때, 그 키워드는 자동으로 그 객체의 모든 필드에 적용된다. 이것은 var 키워드 선언을 통해 선언된 객체가 각 반복 사이에 그 상태를 유지한다는 것을 의미하며, 각각의 반복에서 그 필드 값을 다시 초기화할 필요가 없다.

  • firstBar 객체는 var 키워드를 사용하여 선언되었으므로, 그 필드 (index, price, vol) 는 첫 번째 항목에서 시작하여 마지막 항목이 끝날 때까지 모든 반복에서 그 값을 유지합니다.
  • currentBar 객체는 var 키워드 선언을 사용하지 않으므로, 그 필드는 각 항목에 다시 초기화되고, 각각의 연동에 새로운 객체가 존재합니다.

두 개체의 인덱스 필드를 매핑하여 그 사이의 차이를 비교할 수 있습니다. firstBar.index는 각 반복에서 이전 설정된 값을 유지하며, currentBar.index는 각 반복에서 현재 항목의 bar_inde