[TOC]
지원 비디오 튜토리얼:https://www.youtube.com/watch?v=CA3SwJQb_1g
FMZ 퀀트 트레이딩 플랫폼은 파인 언어 전략 작성, 백테스팅 및 파인 언어 전략의 라이브 트레이딩을 지원하며, 파인 언어의 하위 버전과 호환됩니다.전략 광장FMZ 양자 거래 플랫폼 (FMZ.COM).
FMZ는 파인 언어뿐만 아니라 파인 언어의 강력한 그림 기능을 지원합니다. FMZ 플랫폼의 다양한 기능, 풍부하고 실용적인 도구, 효율적이고 편리한 관리는 파인 전략 (스크립트) 의 실용성을 더욱 향상시킵니다. 파인 언어와의 호환성을 기반으로 FMZ는 또한 파인 언어를 어느 정도 확장, 최적화 및 정제합니다. 공식 튜토리얼에 들어가기 전에 원래 버전과 비교하여 FMZ에서 파인 언어에 어떤 변화가 있었는지 살펴 보겠습니다.
명백한 차이점 중 일부에 대한 간략한 개요:
//@version
그리고strategy
, indicator
코드의 시작에 문장을 작성할 의무가 없습니다, FMZ는 지원하지 않습니다import
수입library
현재는 작동하지 않습니다.어떤 전략은 다음과 같이 쓰여진다는 것을 볼 수 있습니다.
//@version=5
indicator("My Script", overlay = true)
src = close
a = ta.sma(src, 5)
b = ta.sma(src, 50)
c = ta.cross(a, b)
plot(a, color = color.blue)
plot(b, color = color.black)
plotshape(c, color = color.red)
아니면 이렇게 적어보죠.
//@version=5
strategy("My Strategy", overlay=true)
longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
if (longCondition)
strategy.entry("My Long Entry Id", strategy.long)
shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))
if (shortCondition)
strategy.entry("My Short Entry Id", strategy.short)
FMZ에서는 다음과 같이 단순화 할 수 있습니다.
src = close
a = ta.sma(src, 5)
b = ta.sma(src, 50)
c = ta.cross(a, b)
plot(a, color = color.blue, overlay=true)
plot(b, color = color.black, overlay=true)
plotshape(c, color = color.red, overlay=true)
또는:
longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
if (longCondition)
strategy.entry("My Long Entry Id", strategy.long)
shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))
if (shortCondition)
strategy.entry("My Short Entry Id", strategy.short)
종료 가격 모델과 실시간 가격 모델
거래 시각에서, 우리는calc_on_every_tick
매개 변수strategy
이 시간에, 가격 변동이 있을 때 실시간으로 전략 논리를 실행하기 위해 전략 스크립트를 설정하는 기능.calc_on_every_tick
매개 변수를true
.calc_on_every_tick
기본 매개 변수는false
즉, 전략 논리는 전략의 현재 K-라인 BAR가 완전히 완료되었을 때만 실행됩니다.
FMZ에서는
전략 실행 시 가격 및 주문 금액과 같은 수치 정밀 제어 FMZ에 지정되어야 합니다. 거래 시각에서 실제 거래 주문을 할 때 정확성 문제가 없기 때문에 시뮬레이션에서만 테스트 할 수 있습니다. FMZ에서 실제 거래에서 파인 전략을 실행 할 수 있습니다. 그 다음 전략은 거래 품종의 가격 정확성과 주문 금액 정확성을 유연하게 지정 할 수 있어야합니다. 정확성 설정은 데이터가 거래소의 주문 요구 사항을 충족하지 못하여 주문을 할 수 없도록 방지하기 위해 관련 데이터의 소수점을 제어합니다.
선물 계약 코드
FMZ에서 거래 상품이 계약이라면 두 가지 속성을 가지고 있으며, 각각 swap
예를 들어, 일부 거래소에는 분기 계약이 있습니다.quarter
이 계약 코드들은 FMZ
다른 설정, 예를 들어 최소 주문 금액, 기본 주문 금액 등에 대해서는 매개 변수 입문서를 참조하십시오.
runtime.debug
, runtime.log
, runtime.error
디버깅에 사용되죠.FMZ 플랫폼에 디버깅을 위한 3개의 기능이 추가되었습니다.
runtime.debug
: 일반적으로 이 함수와 함께 사용되지 않는 콘솔에 변수 정보를 인쇄합니다.
runtime.log
: 로그에서 출력. FMZ에서 PINE 언어 특정 기능.
runtime.log(1, 2, 3, close, high, ...), Multiple parameters can be passed.
runtime.error
: 호출할 때 메시지 매개 변수에서 지정된 오류 메시지와 실행 시간 오류가 발생합니다.
runtime.error(message)
overlay
매개 변수는 도화 기능의 일부에서 확장됩니다FMZ에서 파이인 언어에서, 그림 기능은plot
, plotshape
, plotchar
, 등이 추가되었습니다.overlay
기본 차트 또는 하위 차트에서 도면을 지정할 수 있는 매개 변수 지원.overlay
설정되어 있습니다true
주요 차트에 따라 그리기 위해, 그리고false
하위 차트를 사용하도록 설정되어 있습니다. 이는 FMZ에서 파이인 전략이 주 차트와 하위 차트를 동시에 사용하도록 합니다.
syminfo.mintick
내장 변수내장 변수syminfo.mintick
현재 기호의 최소 틱 값으로 정의됩니다. 이 값은 FMZ의 syminfo.mintick
0.01입니다.
예를 들어: 주문 가격은 8000, 판매 방향, 양은 1 롯 (단위, 잎), 거래 후 평균 가격은 8000이 아니라 8000보다 낮습니다 (비용에는 처리 수수료가 포함되어 있습니다).
파이어 언어의 기초를 배우기 시작할 때, 우리가 익숙하지 않은 명령어와 코드 문법의 몇 가지 예가있을 수 있습니다. 당신이 그것을 이해하지 못해도 상관없습니다. 우리는 먼저 개념에 익숙해지고 테스트의 목적을 이해할 수 있습니다. 또는 지침을 위해 FMZ의 파이어 언어 문서를 확인할 수 있습니다. 다음 각종 문법, 명령어, 기능 및 내장 변수와 친숙해질 수 있도록 단계별로 튜토리얼을 따르십시오.
파인 언어를 배우기 시작하면 파인 언어 스크립트 프로그램의 실행 과정과 같은 관련 개념을 이해하는 것이 매우 필요합니다. 파인 언어 전략은 차트를 기반으로 실행됩니다. 파인 언어 전략은 차트에 로드 된 가장 초기 데이터에서 시간 순서로 차트에 실행되는 일련의 계산과 연산이라는 것을 이해할 수 있습니다. 차트가 처음에 로드하는 데이터의 양은 제한적입니다. 실제 거래에서 최대 양의 데이터는 일반적으로 교환 인터페이스에서 반환되는 최대 데이터 볼륨에 따라 결정되며 백테스팅 과정에서 최대 양의 데이터는 백테스팅 시스템의 데이터 소스가 제공하는 데이터에 따라 결정됩니다. 차트의 가장 왼쪽에 있는 K-라인 바, 즉 차트의 첫 번째 데이터 세트는 지수 값이 0입니다.bar_index
소나무어에서
plot(bar_index, "bar_index")
이plot
이 함수는 우리가 미래에 더 많이 사용할 함수 중 하나입니다. 사용은 매우 간단합니다. 입력 매개 변수에 따라 차트에 선을 그립니다. 입력 데이터는bar_index
, 그리고 그 선은bar_index
첫 번째 바에 bar_index라는 줄의 값이 0이고 바가 증가함에 따라 오른쪽으로 1로 증가한다는 것을 볼 수 있습니다.
전략의 설정이 다르기 때문에, 전략의 모델 실행 방법이 다르기 때문에, 그들은 다음과 같이 나눌 수 있습니다.closing price model
그리고real-time price model
우리는 또한 간단하게 전에 그들의 개념을 소개했습니다.
종료 가격 모델
전략 코드가 실행될 때, 현재 K-라인 바의 기간은 완전히 실행되고, K-라인 바가 닫히면, K-라인 기간이 완료됩니다. 이 시점에서, 파인 전략 로직은 한 번 실행되며, 트리거 트레이딩 신호는 다음 K-라인 바의 시작에서 실행됩니다.
실시간 가격 모델
전략 코드가 실행될 때, 현재 K-라인 바가 닫히거나 닫히지 않더라도, 파이인 전략 논리는 시장이 변할 때마다 실행되며, 트리거드 신호는 즉시 실행됩니다.
파인 언어 전략이 차트에서 왼쪽에서 오른쪽으로 실행될 때, 차트의 K-라인 바는Historical Bars
그리고Real-time Bars
:
히스토리컬 바
전략이 Historical Bars
. 전략 논리는 각에 한 번만 실행됩니다.historical bar
- 그래요
전략이 historical bars
. 전략 논리는 각에 한 번만 실행됩니다.historical bar
.
역사적인 바를 기반으로 계산: 전략 코드는 역사 바의 닫는 상태에서 한 번 실행되고, 그 다음 모든 역사 바가 한 번 실행될 때까지 전략 코드는 다음 역사 바에서 계속 실행됩니다.
실시간 바
전략이 오른쪽 끝에 있는 마지막 K-라인 바에 실행되면 바는 실시간 바입니다. 실시간 바가 닫히면 바는 통과된 실시간 바 (역사적 바가 됩니다.) 가 됩니다. 새로운 실시간 바는 차트의 오른쪽 끝에 생성됩니다.
전략이
실시간 바를 기반으로 계산:
만약 전략이 high
, low
, close
역사적인 바에 의해 결정되며, 이러한 값은 실시간 바에 의해 시장이 변경될 때마다 변경될 수 있습니다. 따라서 이러한 값에 기초하여 계산된 지표와 같은 데이터도 실시간으로 변경됩니다. 실시간 바에서,close
항상 최신 현재 가격을 나타냅니다.high
그리고low
항상 현재 실시간 바의 시작 이후 도달한 가장 높은 점과 가장 낮은 점을 나타냅니다. 이 내장 변수는 실시간 바가 마지막으로 업데이트되었을 때 최종 값을 나타냅니다.
롤백 메커니즘 (실시간 가격 모델) 로 전략을 실행할 때: 실시간 바 실행 중, 전략의 새로운 반복 전에 사용자 정의 변수를 재설정하는 것은 롤백 (rollback) 이라고 불린다. 다음 테스트 코드의 예를 통해 롤백 메커니즘을 이해하자.
주의:
/*backtest
...
..
.
*/
패키지의 내용은 FMZ 플랫폼에 코드 형태로 저장된 백테스트 구성 정보입니다.
/*backtest
start: 2022-06-03 09:00:00
end: 2022-06-08 15:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
var n = 0
if not barstate.ishistory
runtime.log("before n + 1, n:", n, " current bar_index:", bar_index)
n := n + 1
runtime.log("after n + 1, n:", n, " current bar_index:", bar_index)
plot(n, title="n")
우리는 실시간 바에서 실행된 장면을 검사합니다.not barstate.ishistory
n 변수의 축적을 실시간 바에서만 제한하는 표현식runtime.log
축적 작업 전 및 후 전략 로그에 정보를 출력 함수. 도화 함수를 사용하여 그려진 곡선 n에서plot
, 전략이 역사적인 바에서 실행될 때 n는 항상 0이라는 것을 볼 수 있다. 실시간 바가 실행될 때 1을 n에 더하는 동작이 트리거되고, 실시간 바의 각 라운드에서 전략이 실행될 때 1을 n에 더하는 동작이 실행된다. 로그 메시지에서 볼 수 있듯이 n은 전략 코드가 각 라운드에서 다시 실행될 때 이전 바 실행 전략이 최종적으로 제출한 값으로 리셋된다. n 값 업데이트는 전략 코드가 실시간 바에서 마지막으로 실행될 때 제출된다. 따라서 그래프의 실시간 바에서 시작하는 모든 Bar 증가에 따라 곡선 n의 값이 1으로 증가한다는 것을 볼 수 있다.
요약:
데이터 롤백으로 인해 차트에서 곡선과 같은 드로잉 작업도 재 드로잉을 유발할 수 있습니다. 예를 들어 라이브 트레이딩을 위해 테스트 코드를 수정해보겠습니다.
var n = 0
if not barstate.ishistory
runtime.log("before n + 1, n:", n, " current bar_index:", bar_index)
n := open > close ? n + 1 : n
runtime.log("after n + 1, n:", n, " current bar_index:", bar_index)
plot(n, title="n")
시간 A의 스크린샷
시간 B의 스크린샷
우리는 단지 문장을 수정했습니다.n := open > close ? n + 1 : n
, 현재 실시간 바가 마이너스 라인 (즉, 개시 가격은 종료 가격보다 높다) 이면 n에 1을 추가합니다. 첫 번째 차트 (시간 A) 에서 개시 가격이 그 당시 종료 가격 (저수선) 보다 높았기 때문에 n은 1으로 축적되었으며 차트 곡선에서 표시된 n의 값은 5이었습니다. 그 다음 시장이 변경되고 가격은 두 번째 차트 (시간 B) 에서 표시된 바와 같이 업데이트되었습니다. 이 시점에서 개시 가격이 종료 가격 (긍정 라인) 보다 낮고 n 값은 1으로 증가하지 않고 뒤로 돌립니다. 차트 내의 n의 곡선도 즉시 다시 그려지고 곡선 위의 n의 값은 4입니다. 따라서 실시간 바에서 표시되는 크로스업 및 크로스다운과 같은 신호는 불확실하며 변경될 수 있습니다.
함수에서 변수 컨텍스트
파인 언어 함수의 변수를 함께 연구해보자. 파인 튜토리얼의 일부 설명에 따르면 함수의 변수는 함수 외부 변수와 다음과 같은 차이를 가지고 있다.
파인 함수에서 사용되는 일련 변수들의 역사는 함수에 대한 각각의 연속적인 호출과 함께 생성된다. 만약 함수가 스크립트가 실행되는 모든 바에서 호출되지 않는다면, 이것은 함수
의 로컬 블록 내부와 외부의 일련의 역사적 값 사이의 불일치로 이어질 것이다. 따라서, 만약 함수가 각 바에서 호출되지 않는다면, 같은 인덱스 값으로 함수 안쪽과 바깥쪽에서 참조되는 일련은 동일한 역사적 지점에 참조되지 않을 것이다.
이해하기가 좀 어렵죠? FMZ에서 실행되는 테스트 코드로 알아낼 것입니다.
/*backtest
start: 2022-06-03 09:00:00
end: 2022-06-08 15:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
f(a) => a[1]
f2() => close[1]
oneBarInTwo = bar_index % 2 == 0
plotchar(oneBarInTwo ? f(close) : na, title = "f(close)", color = color.red, location = location.absolute, style = shape.xcross, overlay = true, char = "A")
plotchar(oneBarInTwo ? f2() : na, title = "f2()", color = color.green, location = location.absolute, style = shape.circle, overlay = true, char = "B")
plot(close[2], title = "close[2]", color = color.red, overlay = true)
plot(close[1], title = "close[1]", color = color.green, overlay = true)
백테스트 실행 화면 촬영
테스트 코드는 비교적 간단하며, 주로 두 가지 방법으로 참조 된 데이터를 검사합니다.f(a) => a[1]
그리고f2() => close[1]
.
f(a) => a[1]
: 매개 변수를 전달하는 방법을 사용 하 여, 함수는a[1]
finally.
f2() => close[1]
: 내장 변수를 사용close
바로, 그리고 함수는close[1]
finally.
이[]
이 기호는 데이터 시리즈 변수의 역사적 값을 참조하는 데 사용되며, 클로즈[1]은 현재 클로즈 가격 이전에 바의 폐쇄 가격 데이터를 참조합니다. 우리의 테스트 코드는 차트에 총 4 가지 유형의 데이터를 그리습니다.
plotchar(oneBarInTwo ? f(close) : na, title = "f(close)", color = color.red, location = location.absolute, style = shape.xcross, overlay = true, char = "A")
문자 f(close)
.
plotchar(oneBarInTwo ? f2() : na, title = "f2()", color = color.green, location = location.absolute, style = shape.circle, overlay = true, char = "B")
문자 f2()
.
plot(close[2], title = "close[2]", color = color.red, overlay = true)
선을 그어 색이 빨간색이고 그렸던 위치 (Y축) 는:close[2]
, 이는 현재 바 (왼쪽으로 2개의 바를 계산하는) 이전에 두 번째 바의 종료 가격입니다.
plot(close[1], title = "close[1]", color = color.green, overlay = true)
선을 그어 색이 초록색이고 그렸던 위치 (Y축) 는:close[1]
, 현재 바 (왼쪽으로 1 바를 계산) 에 앞서 첫 번째 바의 종료 가격입니다.
전략 백테스팅의 스크린샷에서 볼 수 있습니다.f(a) => a[1]
A 마커와 함수를 그리기 위해 사용f2() => close[1]
데이터 시리즈의 역사적 데이터를 참조하기 위해 B 마커를 사용하는 [1] 마커 위치, 차트에서 plot(close[2], title = "close[2]", color = color.red, overlay = true)
, 선을 그리는데 사용되는 데이터는close[2]
.
그 이유는 K-라인 바의 지수를 통해 bar_index
f(a) => a[1]
함수가 참조한 값과 같지 않을 것입니다f2() => close[1]
만약 함수가 모든 바에서 호출되지 않는다면 (이 둘 다 같은 인덱스를 사용하더라도 [1]처럼).
일부 내장 함수는 결과를 올바르게 계산하기 위해 각 바에 계산해야합니다.
이 상황을 간단한 예로 설명하자면:
res = close > close[1] ? ta.barssince(close < close[1]) : -1
plot(res, style = plot.style_histogram, color=res >= 0 ? color.red : color.blue)
함수 호출 코드를 작성합니다.ta.barssince(close < close[1])
세차 연산자condition ? value1 : value2
. 이것은 ta.barssince 함수를 호출할 때만close > close[1]
하지만ta.barssince
함수는 마지막 시간 이후 K-줄의 수를 계산하는 것입니다close < close[1]
ta.barssince 함수가 호출되면 항상 close > close[1], 즉, 현재 종료 가격은 이전 Bar의 종료 가격보다 크다. ta.barssince 함수가 호출되면 Close < close [1] 조건이 설정되지 않으며, 최근 위치가 없습니다.
ta.barssince: 호출될 때, 현재 K-라인 이전에 조건이 충족되지 않았다면 함수가 na를 반환합니다.
차트에서 보듯이:
그래프가 그려지면 res 변수 (-1) 의 값만 그려집니다.
이 문제를 피하기 위해, 우리는 그냥ta.barssince(close < close[1])
함수는 세차 연산자를 호출하고 가능한 조건부 분포를 제외한 곳에 적어 각 K-라인 바에 계산을 하도록 합니다.
a = ta.barssince(close < close[1])
res = close > close[1] ? a : -1
plot(res, style = plot.style_histogram, color=res >= 0 ? color.red : color.blue)
파인 언어에서 시간 시리즈의 개념은 매우 중요하며, 파인 언어를 배울 때 우리가 이해해야 할 개념입니다. 시간 시리즈는 타입이 아니라 시간이 지남에 따라 변수의 연속 값을 저장하는 기본 구조입니다. 파인 스크립트는 차트에 기반하고 있으며, 차트에 표시되는 가장 기본적인 내용은 K-라인 차트입니다. 각 값이 K-라인 바의 타임 스탬프와 연관되는 시간 시리즈.open
파이어 언어의 내장 변수 (built-in) 이며, 그 구조는 각 K-라인 바의 개시 가격의 시간 계열을 저장하는 것입니다.open
현재 K 라인 차트의 시작에서 현재 K 라인 차트가 실행되는 바에 대한 첫 번째 바에서 모든 K 라인 바의 개막 가격을 나타냅니다. 현재 K 라인 차트가 5 분 기간이라면, 우리는 인용 (또는 사용)open
파인 전략 코드에서, 그것은 현재 전략 코드가 실행될 때 K-라인 바의 시작 가격입니다. 시간 계열에서 역사적 값을 참조하려면,[]
피인 전략이 특정 K-라인 바에서 실행되면,open[1]
이전 K-라인 바 (즉, 이전 K-라인 기간의 개시 가격) 의 개시 가격을 참조하기 위해open
이 K-라인 바가 현재 스크립트에서 실행되는 시간 계열입니다.
시간 계열에 있는 변수는 계산에 매우 편리합니다.
ta.cum
예를 들어:
ta.cum
Cumulative (total) sum of `source`. In other words it's a sum of all elements of `source`.
ta.cum(source) → series float
RETURNS
Total sum series.
ARGUMENTS
source (series int/float)
SEE ALSO
math.sum
테스트 코드:
v1 = 1
v2 = ta.cum(v1)
plot(v1, title="v1")
plot(v2, title="v2")
plot(bar_index+1, title="bar_index")
많은 기능이 있습니다.ta.cum
예를 들어, 시간 계열에 대한 데이터를 직접 처리할 수 있는ta.cum
각 K-라인 바에 전달된 변수에 대응하는 값의 축적입니다. 다음으로 더 이해하기 쉽게 차트를 사용합니다.
전략 운영 과정 | 내장 변수 bar_index | v1 | v2 |
---|---|---|---|
전략은 첫 번째 K-라인 바에서 실행됩니다. | 0 | 1 | 1 |
전략은 두 번째 K-라인 바에서 실행됩니다. | 1 | 1 | 2 |
전략은 세 번째 K-라인 바에서 실행됩니다 | 2 | 1 | 3 |
… | … | … | … |
전략은 N + 1 K-라인 바에 실행 | N | 1 | N+1 |
v1, v2 및 심지어 bar_index도 모두 시간 계열 구조이며 각 바에 대응하는 데이터가 있음을 알 수 있습니다. 테스트 코드가
변수 v1이 각 바에 1이기 때문에ta.cum(v1)
이 함수는 첫 번째 K 선 Bar에 실행되면 첫 번째 Bar만 존재하기 때문에 계산 결과는 1이고 변수 v2에 할당됩니다.
언제?ta.cum(v1)
두 번째 K-라인 바에 실행되면 이미 2개의 K-라인 바가 있습니다 (첫 번째와 대응하는 내장변수 bar_index는 0이고, 내장변수 bar_index과 대응하는 두 번째는 1) 따라서 계산 결과는 2이며, 이는 변수 v2에 할당됩니다. 실제로 v2는 K-라인 바의 수이기 때문에 차트 내의 K-라인 바의 수입니다.bar_index
0에서 증가하면bar_index + 1
이 차트에서 우리는 또한 그 선들이v2
그리고bar_index
실제로 겹쳐져 있습니다.
마찬가지로, 저는 또한ta.cum
현재 차트에 있는 모든 바의 종료 가격의 합을 계산하는 기능이 있습니다.ta.cum(close)
, 전략이 오른쪽 가장자리에 있는 실시간 바에 실행되면,ta.cum(close)
차트의 모든 바의 폐쇄 가격의 합입니다. (아직 오른쪽으로 실행되지 않으면 현재 바까지 축적됩니다.)
시간 계열의 변수는 또한 코드와 같은 연산자를 사용하여 계산할 수 있습니다.ta.sma(high - low, 14)
, 내장 변수를 빼고high
(K-라인 바의 가장 높은 가격)low
(K-라인 바의 가장 낮은 가격), 그리고 마지막으로 사용ta.sma
평균값을 계산하는 함수입니다.
함수 호출의 결과 또한 시간 계열에 값의 흔적을 남길 것입니다.
v1 = ta.highest(high, 10)[1]
v2 = ta.highest(high[1], 10)
plot(v1, title="v1", overlay=true)
plot(v2, title="v2", overlay=true)
테스트 코드는 백테스팅 중에 실행되며,v1
그리고v2
함수 호출에 의해 계산된 결과는 시간 계열에 값의 흔적을 남길 것입니다.ta.highest(high, 10)
코드에서ta.highest(high, 10)[1]
. 함수 호출에 의해 계산 된 결과는 또한 그것의 역사적 값을 참조하기 위해 [1]을 사용할 수 있습니다.ta.highest(high, 10)
현재 바의 이전 바에 해당하는 계산 결과는ta.highest(high[1], 10)
그래서ta.highest(high[1], 10)
그리고ta.highest(high, 10)[1]
정확히 동등합니다.
다른 도면 함수를 사용하여 정보 검증을 출력합니다:
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, overlay=true)
plotchar(true, title="b", char=str.tostring(b), location=location.belowbar, color=color.green, overlay=true)
우리는 시간 계열의 변수 a와 변수 b의 값이 해당 바의 위와 아래로 표시되는 것을 볼 수 있습니다. 우리는 배트테스팅과 실험 중에 관찰을 위해 차트에 정보를 출력해야 할 수 있기 때문에 학습 과정에서 이 그림 코드를 유지할 수 있습니다.
튜토리얼의 시작 부분에서, 우리는 FMZ와 트레이딩 뷰에서 파인 언어를 사용하는 몇 가지 차이점을 요약했습니다. FMZ에 파인 코드를 작성할 때, 버전 번호를 생략할 수 있습니다.indicator()
, strategy()
, 그리고library()
현재는 지원되지 않습니다. 물론, 소나무 스크립트의 이전 버전과 호환되기 위해서는 다음과 같은 전략이 필요합니다.//@version=5
, indicator()
, strategy()
또한 작성될 수 있습니다. 일부 전략 설정은 또한 설정할 수 있습니다strategy()
function.
<version>
<declaration_statement>
<code>
이<version>
버전 제어 정보는 생략할 수 있습니다.
소나무 언어는//
파인 언어에는 여러 줄의 댓글 기호가 없기 때문에 단일 줄 댓글 기호로 FMZ는 댓글 기호를 확장합니다./**/
여러 줄의 언급을 위해.
코멘트 또는 컴파일러 지시가 아닌 스크립트의 줄은 스크립트의 알고리즘을 구현하는 명령어입니다. 명령어는 이러한 내용 중 하나가 될 수 있습니다.
if
, for
, while
또는switch
구조진술은 여러 가지 방법으로 구성 될 수 있습니다.
space
또는 ```tab` (tab 키). 첫 번째 문자는 또한 줄의 첫 번째 문자가어야 합니다. 첫 번째 위치에서 시작하는 문서는 정의에 따라 스크립트의 전 범위에 포함됩니다.local block
로컬 블록은 한 탭 또는 네 개의 간격으로 예를 들어, 3개의 로컬 블록을 포함합니다. 하나는 사용자 정의 함수 선언에 있고, 두 개는 if 구조를 사용하는 변수 선언에 있습니다.
indicator("", "", true) // declaration statement (global scope), can be omitted
barIsUp() => // function declaration (global scope)
close > open // local block (local scope)
plotColor = if barIsUp() // variable declaration (global scope)
color.green // local block (local scope)
else
color.red // local block (local scope)
runtime.log("color", color = plotColor) // Call a built-in function to output the log (global scope)
긴 선은 여러 선으로 나눌 수도 있고,
a = open + high + low + close
이렇게 포장할 수 있습니다. (선당 간격이 4의 배가 될 수 없다는 점에 유의하십시오.)
a = open +
high +
low +
close
긴 플롯 (plot)) 호출은 다음과 같이 포장 될 수 있습니다:
close1 = request.security(syminfo.tickerid, "D", close) // syminfo.tickerid daily level closing price data series for the current trading pair
close2 = request.security(syminfo.tickerid, "240", close) // syminfo.tickerid 240-minute level closing price data series for the current trading pair
plot(ta.correlation(close, open, 100), // line-long plot() calls can be wrapped
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")
변수를 인식하기 전에 먼저
(A-Z)
또는 소문자(a-z)
글자 또는 밑줄(_)
마커의 첫 번째 문자입니다.예를 들어, 다음의 이름 표시기:
fmzVar
_fmzVar
fmz666Var
funcName
MAX_LEN
max_len
maxLen
3barsDown // Wrong naming! It used a numeric character as the leading character of the marker
대부분의 프로그래밍 언어와 마찬가지로, 파이어 언어에도 쓰기 제안이 있습니다. 식별자를 명칭할 때 일반적으로 다음과 같이 권장됩니다.
// name variables, constants
GREEN_COLOR = #4CAF50
MAX_LOOKBACK = 100
int fastLength = 7
// name functions
zeroOne(boolValue) => boolValue ? 1 : 0
연산자는 표현식을 구성하기 위해 프로그래밍 언어에서 사용되는 몇 가지 연산 기호이며, 표현식은 전략을 작성할 때 특정 계산 목적으로 설계된 계산 규칙입니다. 파인 언어의 연산자는 함수로 분류됩니다.
할당 연산자, 수학적 연산자, 비교 연산자, 논리적 연산자? :
세차적 사업자,[]
역사적인 참조 연산자
수학적 연산자를 취하는 것*
예를 들어, 그것은 트레이딩 뷰에서 소나무 언어 연산자의 반환 결과로 인한 타입 문제와 다릅니다. 다음 테스트 코드가 제공됩니다.
//@version=5
indicator("")
lenInput = input.int(14, "Length")
factor = year > 2020 ? 3 : 1
adjustedLength = lenInput * factor
ma = ta.ema(close, adjustedLength) // Compilation error!
plot(ma)
이 스크립트를 트레이딩 뷰에서 실행할 때 컴파일 오류가 발생합니다. 이유는 곱한 후에adjustedLength = lenInput * factor
, 그 결과는series int
타입 (시리즈), 하지만 함수의 두 번째 매개 변수ta.ema
하지만 FMZ에는 그런 엄격한 제한이 없습니다. 위의 코드는 정상적으로 실행될 수 있습니다.
다양한 연산자를 함께 사용하는 방법을 살펴보겠습니다.
할당 연산자는 2가지 종류가 있습니다.=
, :=
이 튜토리얼의 시작 부분에서 몇 가지 예제에서 본 것입니다.
이=
연산자는 초기화되거나 선언될 때 변수에 값을 부여하는 데 사용됩니다.=
다음 각 바에서 그 값으로 시작됩니다. 이것들은 유효한 변수 선언입니다:
a = close // Use built-in variables to assign values to a
b = 10000 // Use numerical assignment
c = "test" // Use string assignment
d = color.green // Use color value assignment
plot(a, title="a")
plot(b, title="b")
plotchar(true, title="c", char=str.tostring(c), color=d, overlay=true)
할당 문서를 참고하십시오a = close
, 각 바의 변수 a는 바의 현재 종료 가격 (폐기) 이다. 다른 변수b
, c
, d
변하지 않고 FMZ의 백테스트 시스템에서 테스트 할 수 있으며 그 결과는 차트에서 볼 수 있습니다.
:=
기존 변수에 값을 재배정하는 데 사용됩니다.:=
이 연산자는 선언되고 초기화 된 변수의 값을 수정하는 데 사용됩니다.
만약 우리가:=
초기화되지 않은 변수 또는 선언된 변수에 값을 할당하는 연산자는 오류를 일으킬 것입니다. 예를 들어:
a := 0
따라서,:=
할당 연산자는 일반적으로 기존 변수를 다시 할당하는 데 사용됩니다. 예를 들어:
a = close > open
b = 0
if a
b := b + 1
plot(b)
만약close > open
(즉, 현재 BAR는 양직선), 변수 a는 사실입니다. if 명령어의 로컬 블록의 코드는b := b + 1
실행되고, 할당 연산자:=
b에 1을 더하면 그래프에 있는 시간열의 각 BAR에 변수 b의 값을 그려 줄 수 있습니다. 그리고 그 값을 직선으로 연결합니다.
양수 BAR가 나타났을 때 b가 1으로 계속 축적될 것이라고 생각합니까? 물론 그렇지 않습니다. 여기 우리는 변수 b를 0으로 선언하고 초기화합니다.b=0
각 BAR에서 실행되므로 이 코드의 결과는 변수 a가 true인 경우 b 변수를 0으로 재설정하는 것입니다.close > open
, b는 이 라운드에서 코드를 실행할 때 1으로 증가하고, b는 플롯 함수가 도출할 때 1이 되지만, b는 다음 라운드에서 코드를 실행할 때 0으로 재배정됩니다. 이것은 또한 파이어 언어 초보자들이 함정에 빠질 수있는 곳입니다.
할당 연산자에 관해서는 두 개의 키워드를 확장해야 합니다.var
, varip
var
사실, 우리는 이전 튜토리얼에서 이 키워드를 보았고 사용했지만, 그 당시에는 자세히 논의하지 않았습니다. 먼저 이 키워드의 설명을 살펴봅시다.
var는 변수를 할당하고 한 번 초기화하는 데 사용되는 키워드이다. 일반적으로 키워드 var를 포함하지 않는 변수 할당 문법은 데이터가 업데이트될 때마다 변수
s 값이 덮어쓰게 한다. 반대로, 키워드 var를 사용하여 변수를 할당하면 데이터 업데이트에도 불구하고 상태가 유지될 수 있다.
우리는 여전히 이 예를 사용하지만, 우리는var
여기서 b에 값을 할당할 때 키워드
a = close > open
var b = 0
if a
b := b + 1
plot(b)
이var
키워드는 변수 b가 초기 할당만을 수행하도록 허용하고, 그 다음 전략 논리가 실행될 때마다 b를 0으로 재설정하지 않습니다. 따라서 실행 시간에 그려진 선에서 b는 현재 K 선 BAR가 백테스트되었을 때 나타난 긍정적 선 BAR의 수입니다.
var에 의해 선언된 변수는 글로벌 범위뿐만 아니라 코드 블록으로도 작성될 수 있습니다. 예를 들어:
strategy(overlay=true)
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")
변수
다양성
우리는 키워드를 볼 수 있습니다.varip
이 키워드의 설명을 처음으로 볼 수 있습니다.
varp (var intrabar persist) 는 변수의 할당 및 일회 초기화를 위한 키워드이다. var 키워드와 비슷하지만, varp로 선언된 변수는 실시간 K-라인 업데이트를 할 때 값을 유지한다.
이해하기가 어렵나요? 상관없습니다. 예를 통해 설명합니다. 이해하기 쉽습니다.
strategy(overlay=true)
// test var varip
var i = 0
varip ii = 0
// Print the i and ii changed in each round of the strategy logic on the chart
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)
// Increment i and ii by 1 for each round of logic execution
i := i + 1
ii := ii + 1
이 테스트 코드는
바 모델:
앞서 설명한 전략 실행은 역사적인 BAR 단계와 실시간 BAR 단계로 나뉘어 있다는 것을 기억하시나요?i
, ii
신고된 것var
, varip
전략 코드 실행의 각 라운드에서 인크리멘탈 연산을 수행합니다. 따라서 백테스트 결과의 K-라인 BAR에 표시된 숫자가 1으로 하나씩 증가하는 것을 볼 수 있습니다. 역사적인 K-라인 단계가 끝나면 실시간 K-라인 단계가 시작됩니다. var 및 varip에 의해 선언된 변수는 다른 변화를 겪기 시작합니다. Bar 모델이기 때문에 전략 코드는 K-라인 BAR의 각 가격 변화에 대해 한 번 실행됩니다.i := i + 1
그리고ii := ii + 1
이차는 ii가 매번 수정된다는 것입니다. i가 매번 수정되기는 하지만, 이전 값은 전략 논리가 다음 라운드에서 실행될 때 복원됩니다. (이전
틱 모델: 틱 모델은 K-라인 BAR에 한 번만 전략 논리를 실행하기 때문에 종료 가격 모델에서 var와 varip에 의해 선언된 변수는 위의 예제에서 역사적인 K-라인 단계와 실시간 K-라인 단계 동안 각 K-라인 BAR에 대해 1으로 증가하여 정확히 동일하게 행동합니다.
사업자 | 설명 |
---|---|
+ | 추가 |
- | 빼기 |
* | 곱셈 |
/ | 부문 |
% | 모두로 |
이+
그리고-
연산자는 이진 연산자 또는 유니어 연산자로 사용할 수 있습니다. 다른 연산자는 이진 연산자로서만 사용할 수 있습니다.
+
, 계산의 결과는 문자열이고, 값은 문자열 형태로 변환되고, 문자열이 함께 꿰매집니다. 다른 수학적 연산자가 있다면 문자열을 값으로 변환하고 작업을 수행합니다.a = 1 + 1
b = 1 + 1.1
c = 1 + "1.1"
d = "1" + "1.1"
e = 1 + na
runtime.log("a:", a, ", b:", b, ", c:", c, ", d:", d, ", e:", e)
// a: 2 , b: 2.1 , c: 11.1 , d: 11.1 , e: NaN
FMZ의 파인 언어는 트레이딩 뷰의 파인 언어와 약간 다릅니다. FMZ의 파인 언어는 변수 유형에 대해 매우 엄격하지 않습니다. 예를 들어:
a = 1 * "1.1"
b = "1" / "1.1"
c = 5 % "A"
plot(a)
plot(b)
plot(c)
FMZ에서 작동하지만 트레이딩 뷰에서 타입 오류를 보고합니다. 만약 수학적 연산자의 두 연산자가 문자열이라면, 시스템은 문자열을 수치 값으로 변환하고 계산합니다. 만약 비 수치 문자열을 계산할 수 없다면, 시스템 연산의 결과는 null value
비교 연산자는 모두 바이너리 연산자입니다.
사업자 | 설명 |
---|---|
< | < |
> | > |
<= | <= |
>= | >= |
== | == |
!= | != |
테스트 예제:
a = 1 > 2
b = 1 < 2
c = "1" <= 2
d = "1" >= 2
e = 1 == 1
f = 2 != 1
g = open > close
h = na > 1
i = 1 > na
runtime.log("a:", a, ", b:", b, ", c:", c, ", d:", d, ", e:", e, ", f:", f, ", g:", g, ", h:", h, ", i:", i)
// a: false , b: true , c: true , d: false , e: true , f: true , g: false , h: false , i: false
우리가 볼 수 있듯이, 비교 연산자는 매우 간단하게 사용할 수 있습니다. 하지만 이것은 또한 우리가 전략을 작성 할 때 가장 많이 사용하는 연산자입니다. 숫자 값과 내장 변수 모두 비교 할 수 있습니다.close
, open
, 등등
운영자와 마찬가지로 FMZ와 트레이딩 뷰 사이에는 파이어 언어에 대한 차이가 있습니다. FMZ는 유형에 대해 특별히 엄격한 요구 사항이 없습니다. 따라서 이러한 선언은d = "1" >= 2
FMZ에서 오류를 보고하지 않고 문자열을 먼저 값으로 변환하고 그 다음 작업을 비교하여 실행됩니다.
사업자 | 코드 기호 | 설명 |
---|---|---|
아니 | 아니 | 연산이 아닌 유나리 연산자 |
그리고 | 그리고 | 바이너리 연산자 및 거래 |
또는 | 또는 | 이진 연산자 또는 연산자 |
논리 연산자에 관해서, 우리는 진정한 값 테이블에 대해 이야기해야합니다. 우리는 고등학교에서 배운 것과 동일합니다. 여기 우리는 단지 테스트하고 우리의 백테스팅 시스템에서 학습합니다.
a = 1 == 1 // An expression formed by using comparison operators, the result is a Boolean value
b = 1 != 1
c = not b // Logical not operators
d = not a // Logical not operators
runtime.log("test the logical operator:and", "#FF0000")
runtime.log("a:", a, ", c:", c, ", a and c:", a and c)
runtime.log("a:", a, ", b:", b, ", a and b:", a and b)
runtime.log("b:", b, ", c:", c, ", b and c:", b and c)
runtime.log("d:", d, ", b:", b, ", d and b:", d and b)
runtime.log("test the logical operator:or", "#FF0000")
runtime.log("a:", a, ", c:", c, ", a or c:", a or c)
runtime.log("a:", a, ", b:", b, ", a or b:", a or b)
runtime.log("b:", b, ", c:", c, ", b or c:", b or c)
runtime.log("d:", d, ", b:", b, ", d or b:", d or b)
runtime.error("stop")
메세지를 덮어쓰지 않기 위해, 우리는 오류를 던집니다runtime.error("stop")
인쇄한 후 한 번 멈추게 합니다. 그 후에 출력 정보를 관찰할 수 있습니다. 그리고 인쇄된 내용이 실제 값 테이블과 동일하다는 것을 알 수 있습니다.
삼위 연산자를 사용하는 삼위 표현식? :
연산자와 결합condition ? valueWhenConditionIsTrue : valueWhenConditionIsFalse
우리는 또한 이전 강의에서 사용했습니다. 소위 삼중 연산자, 삼중 연산자는 그 안에 세 개의 연산자가 있음을 의미합니다.
이 지역에서는condition ? valueWhenConditionIsTrue : valueWhenConditionIsFalse
, condition
판단 조건이 됩니다. 만약 그것이 사실이라면, 표현식의 값은valueWhenConditionIsTrue
만약condition
false가 되면 표현식의 값은valueWhenConditionIsFalse
.
실용적인 사용이 거의 없지만 편리한 시범 예시:
a = close > open
b = a ? "positive line" : "negative line"
c = not a ? "negative line" : "positive line"
plotchar(a, location=location.abovebar, color=color.red, char=b, overlay=true)
plotchar(not a, location=location.belowbar, color=color.green, char=c, overlay=true)
도지를 만나면 어떻게 해야 할까요? 상관없어요! 이전 튜토리얼에서 했던 것처럼 삼차원 표현식도 둥지를 틀 수 있습니다.
a = close > open
b = a ? math.abs(close-open) > 30 ? "positive line" : "doji" : math.abs(close-open) > 30 ? "negative line" : "doji"
c = not a ? math.abs(close-open) > 30 ? "negative line" : "doji" : math.abs(close-open) > 30 ? "positive line" : "doji"
plotchar(a, location=location.abovebar, color=color.red, char=b, overlay=true)
plotchar(not a, location=location.belowbar, color=color.green, char=c, overlay=true)
사실, 그것은valueWhenConditionIsTrue
그리고valueWhenConditionIsFalse
안쪽condition ? valueWhenConditionIsTrue : valueWhenConditionIsFalse
또 다른 삼각형 표현식으로
역사 연산자를 사용[]
시간 계열의 역사적 값을 참조하기 위해. 이 역사적 값은 스크립트가 실행되었을 때 현재 K-라인 바에 앞서 K-라인 바에 변수의 값입니다.[]
연산자는 변수, 표현식, 함수 호출 후에 사용됩니다.[]
제곱괄호는 현재 K-라인 BAR에서 참조하려는 역사적 데이터의 오프셋입니다. 예를 들어, 마지막 K-라인 BAR의 폐쇄 가격을 인용하고 싶다면 다음과 같이 작성합니다.close[1]
.
우리는 이전 수업에서 이와 비슷한 것을 보았습니다.
high[10]
ta.sma(close, 10)[1]
ta.highest(high, 10)[20]
close > nz(close[1], open)
이[]
연산자는 같은 값에 한 번만 사용할 수 있으므로 이렇게 쓰는 것이 잘못되어 오류가 보고됩니다.
a = close[1][2] // error
여기, 어떤 사람들은 운영자가[]
일련의 구조에 사용되는데, 일련의 구조 (series) 는 배열과 비슷해 보입니다!
파이어 언어의 일련과 배열의 차이를 설명하기 위해 예를 사용해보자.
strategy("test", overlay=true)
a = close
b = close[1]
c = b[1]
plot(a, title="a")
plot(b, title="b")
plot(c, title="c")
a = close[1][2]
오류를 보고하지만:
b = close[1]
c = b[1]
하지만 별도로 쓰면 오류를 보고하지 않습니다.b = close [1]
, b는 값이 되어야 하지만c = b[1]
, b는 여전히 역사 연산자를 사용하여 역사 값을 다시 참조하는 데 사용할 수 있습니다. 파이프 언어의 일련의 개념이 배열처럼 간단하지 않다는 것을 알 수 있습니다. 그것은 닫는 마지막 바 (b에 할당) 의 역사 값으로 이해할 수 있습니다. b는 또한 시간 시리즈 구조 (시간 시리즈) 이며, 그 h는