[TOC]
サポートビデオチュートリアル:https://www.youtube.com/watch?v=CA3SwJQb_1g
FMZ Quant Trading PlatformはPine言語戦略の書き込み,バックテスト,およびPine言語戦略のライブ取引をサポートし,Pine言語の低バージョンと互換性があります.Pine言語に収集され移植された多くのPine戦略 (スクリプト) があります.戦略広場FMZ 量子取引プラットフォーム (FMZ.COM).
FMZはPine言語だけでなく,Pine言語の強力な描画機能もサポートしています. FMZプラットフォーム上のさまざまな機能,豊かで実用的なツール,効率的で便利な管理は,Pine戦略 (スクリプト) の実行性をさらに高めます.Pine言語との互換性に基づいて,FMZはまた,Pine言語を一定程度拡張,最適化,トリミングします.公式にチュートリアルに入れる前に,元のバージョンと比較してFMZ上のPine言語にどのような変更があったかを見てみましょう.
明らかな違いについて 簡単に説明します.
//@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では"Pine Language Trading Class Library"テンプレートのパラメータによって設定されます.
戦略を実行するときに価格と注文金額などの数値精度制御は,FMZで指定する必要があります. FMZでは,Pine戦略を実際の取引で実行することが可能である.その後,戦略は,取引品種の価格正確性と注文金額の正確性を柔軟に指定することが必要です.正確性設定は,データが取引所の注文要件を満たさないようにし,注文を入れることができないようにするために,関連するデータにおける小数点数を制御します.
フューチャー契約コード
FMZの取引製品が契約である場合は,それぞれ2つの属性があります. swap
例えば,いくつかの取引所は四半期契約を持っています.quarter
この契約コードは,FMZ
他の設定,例えば最低注文金額,デフォルト注文金額などについては,パラメータの導入を参照してください.
runtime.debug
, runtime.log
, runtime.error
デバッグに使われる3つの機能が FMZ プラットフォームにデバッグに追加されました.
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のPine言語では,図を描く機能がplot
, plotshape
, plotchar
追加しました.overlay
パラメータサポートで,メインチャートまたはサブチャート上の図を指定できます.overlay
設定されています.true
メインチャートで描くためfalse
サブチャートに描くように設定されているため,Pine戦略は FMZでメインチャートとサブチャートを同時に描くことができます.
syminfo.mintick
内蔵変数組み込み変数syminfo.mintick
この値は,FMZの"Pine Language Trading Class Library"のテンプレートパラメータ価格設定通貨精度によって制御できます.ロボット/バックテスト価格通貨精度設定2は,取引時に価格が二桁の小数点まで正確であり,最低価格変化単位は0.01であることを意味します.syminfo.mintick
0.01 になります
例えば:注文価格は8000ドル,販売方向は1ロット (片,シート) の量で,取引後の平均価格は8000ドルではなく,8000ドル以下です (コストには手数料が含まれます).
パイン言語の基礎を学び始めるとき,私たちが知らない指示やコード文法の一些例があるかもしれません.あなたが理解していない場合でも,私たちは最初に概念を熟知し,テストの目的を理解することができます.または指示のためにFMZのパイン言語ドキュメントを確認することができます.その後,さまざまな文法,指示,機能,および組み込み変数に慣れるためにステップごとにチュートリアルに従ってください.
パイン言語学習を開始する際には,パイン言語スクリプトプログラムの実行プロセスなどの関連概念を理解することが非常に必要である. パイン言語戦略はチャートに基づいて実行される. パイン言語戦略は,チャートにロードされた最古のデータから時間系列の順序でチャート上で実行される一連の計算と演算であることが理解できる. チャートで最初にロードされるデータの量は限られている. リアルトレーディングでは,通常,最大量のデータは交換インターフェイスが返した最大データ容量に基づいて決定され,バックテストの際に最大量のデータはバックテストシステムのデータソースによって提供されたデータに基づいて決定される. チャート上の左端のK線バー,すなわちチャートの最初のデータセットは,インデックス値が0である. 現在のK線バーの値は,Pine スクリプトがビルドされた変数で参照されたときにインデックス値が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線期間が完了します.この時点で,Pine戦略ロジックは1回実行され,トリガーされた取引信号は次のK線バーの開始時に実行されます.
リアルタイム価格モデル
戦略コードが実行されると,現在のKラインバーが閉ざされたかどうかにかかわらず,Pine戦略ロジックは,市場が毎回変化するときに実行され,トリガーされた取引信号は直ちに実行されます.
グラフ上のK線バーは2つに分かれます.Historical Bars
そしてReal-time Bars
:
歴史的なバー
戦略がHistorical Bars
. 戦略論理は1回だけ実行されるhistorical bar
- わかった
グラフ上のすべてのバーは historical bars
. 戦略論理は1回だけ実行されるhistorical bar
.
歴史的なバーに基づいて計算: ストラテジーコードは,歴史バーの閉じる状態で一度実行され,その後,すべての歴史バーが一度実行されるまで,次の歴史バーで戦略コードが実行され続けます.
リアルタイムバー
戦略が右端の最後のK線バーに実行されると,バーはリアルタイムバーになります.リアルタイムバーが閉ざされると,バーはリアルタイムバーになります.新しいリアルタイムバーはチャートの右端に生成されます.
戦略が
リアルタイムバーによる計算:
戦略がhigh
, low
, close
過去のバーで決定され,これらの値は,リアルタイムバーで市場が変化するたびに変化する可能性があります.したがって,これらの値に基づいて計算された指標などのデータもリアルタイムで変化します.リアルタイムバーで,close
常に現在の最新価格を表し,high
そしてlow
常に現在のリアルタイムバーの開始以来の最高点と最低点を表します.これらの内蔵変数は,リアルタイムバーが最後に更新された時の最終値を表します.
リアルタイムバー (リアルタイム価格モデル) で戦略を実行する時のロールバックメカニズム: リアルタイムのバー実行中に,戦略の新しい繰り返しのたびにユーザー定義変数をリセットすることはロールバックと呼ばれます.次のテストコードの例でロールバックメカニズムを理解しましょう.
注目してください
/*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であることが見られます.リアルタイムバーが実行されるとき, nに1を加える操作が起動し,リアルタイムバーの各ラウンドで戦略が実行されるときに,nに1を加える操作が実行されます.ログメッセージから,戦略コードが各ラウンドで再実行されるときに,nが前のバー実行戦略によって最終的に送信された値にリセットされることが観察できます. n値更新は,戦略コードがリアルタイムバーで最後に実行されたときに送信されます.したがって,グラフ上のリアルタイムバーから始まるバーの増加ごとに,曲線の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
,現在のリアルタイムバーがマイナス線であるとき (すなわち,開盤価格が閉盤価格よりも高いとき) にのみ1をnに追加する.最初のチャート (時間A) では,開盤価格が閉盤価格 (マイナス線) より高かったため,nが1で累積され,チャート曲線に表示されたnの値は5であった.その後,市場が変化し,価格が2番目のチャート (時間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)
バックテスト実行のスクリーンショット
テストコードは比較的シンプルで,主に2つの方法によって参照されたデータを調べます.f(a) => a[1]
そしてf2() => close[1]
.
f(a) => a[1]
: パラメータを転送する方法を使用すると,関数はa[1]
finally.
f2() => close[1]
: 組み込み変数を使用するclose
この関数は直線に戻ります.close[1]
finally.
について[]
この記号は,データシリーズ変数の歴史的値を参照するために使用され,Close[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つのバーを数える) の前の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]
もし関数がすべての Bar で呼び出されていない場合 (両方が [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 を返します.
図表に示されているように:
解析変数 (-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
パイン言語の内蔵変数であり,その構造は,各K線バーのオープニング価格の時間列を保存することです.open
現在のK線グラフの初めの最初のバーから,現在のスクリプトが実行されるバーまでのすべてのK線バーのオープニング価格を表します. 現在のK線グラフが5分間の期間である場合,当社が引用 (または使用) するときopen
ストラテジーコードが実行されているときのK線バーの開口価格です. タイムシリアルの歴史的な値を参照したい場合は,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
次に理解しやすくするためにチャートを使います. このグラフは,
戦略の運用プロセス | 組み込み変数 bar_index | v1 | v2 |
---|---|---|---|
戦略は最初のK線バーで実行されます | 0 | 1 | 1 |
戦略は2番目のK線バーで実行されます. | 1 | 1 | 2 |
戦略は3番目のK線バーで実行されます. | 2 | 1 | 3 |
… | … | … | … |
戦略はN+1thK線バーで実行されます. | N | 1 | N+1 |
v1,v2,そしてbar_indexもすべて時間列構造であり,各バーには対応するデータがあることがわかります.テストコードが
変数v1が1で,この変数が1で,ta.cum(v1)
最初のK線バーで実行されるので,最初のバーのみがあり,計算結果は1で変数v2に割り当てられます.
いつta.cum(v1)
2番目のK線バーで実行される場合,すでに2つのK線バーがあります (最初のバーに対応する内蔵変数bar_indexは0で,第2の内蔵変数bar_indexは1) したがって,計算結果は2で,変数v2に割り当てられます. 実際,v2は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 の値が対応する Bars の上下で表示されていることがわかります.この図のデータをバックテストや実験の際に観測するために出力する必要があることが多いので,学習プロセス中にこの図のコードを保存することができます.
このチュートリアルでは,FMZとTrading ViewのPine言語の使用の違いをまとめました.indicator()
, strategy()
そしてlibrary()
もちろん,Pine スクリプトの以前のバージョンと互換性を持つためには,以下のような戦略が必要です.//@version=5
, indicator()
, strategy()
パラメータを入力して設定することもできます.strategy()
function.
<version>
<declaration_statement>
<code>
について<version>
バージョン制御情報は省略できます.
パイン語は//
パイン言語には複数行のコメントシンボルがないため,単行コメントシンボルとして. FMZはコメントシンボルを拡張する./**/
多行コメントについては
コメントやコンパイラ指令ではないスクリプトの行は,スクリプトのアルゴリズムを実装するステートメントである.ステートメントはこれらのコンテンツの1つである.
if
, for
, while
またはswitch
構造申告は様々な方法で整理できます.
space
または ```tab` (タブキー). その最初の文字は行の最初の文字でなければならない. 最初の位置から始まる文字は,定義上,スクリプトのグローバル範囲の一部になります.local block
ローカルブロックは1つのタブまたは4つのスペースで引入されなければなりません (そうでなければ,それは前の行の連鎖コードとして解析され,つまり,前のコード行の連続的な内容であると判断されます),そして各ローカルブロックは異なるローカル範囲を定義します.例えば,if構造を使用したカスタム関数宣言に1つ,変数宣言に2つ,以下の3つのローカルブロックを含みます.
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)
長い線は複数の線に分けられる.また,包まれた線は4の倍数でない限り,任意のスペースでインデントしなければならない (これらの境界はローカルブロックをインデントするために使用される).
a = open + high + low + close
包装できる (一行ごとに引入されたスペースの数が4の倍数であってはならないことに注意してください):
a = open +
high +
low +
close
長いプロット ((() 呼び出しは,次のように包み込むことができます:
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タブ) で開始されなければならないため,次の行に分割するときに,ステートメントの継続は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
ほとんどのプログラミング言語と同様に,Pine言語にも書き込み提案があります.識別子命名する際には,一般的に以下のようなことを推奨します.
// name variables, constants
GREEN_COLOR = #4CAF50
MAX_LOOKBACK = 100
int fastLength = 7
// name functions
zeroOne(boolValue) => boolValue ? 1 : 0
オペレーターとは,プログラミング言語で表現を構成するために使用されるいくつかの操作シンボルであり,表現は,戦略を書くときに特定の計算目的のために設計された計算規則である. パイン言語のオペレーターは,関数によって以下のように分類される.
割り当て演算子,算術演算子,比較演算子,論理演算子? :
三次性事業者[]
歴史的な参照演算子.
算術演算子を取ること*
例えば,Trading View の Pine language オペレーターの返信結果によるタイプ問題とは異なります.次のテストコードが提供されています.
//@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)
このスクリプトを Trading View で実行すると,コンパイルエラーが発生します.adjustedLength = lenInput * factor
結果としてseries int
2番目のパラメータは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
変数 a は true です. if 文のローカルブロックのコードは,b := b + 1
実行され,割り当て操作者は:=
グラフ上の各 BAR に変数 b の値を描き,直線に接続します. このグラフの各 BAR に変数 b の値を描き,直線に変換します.
この文では,b を 0 と宣言し,初期化します. この文では,b を 0 と宣言し,初期化します.b=0
変数aが真であれば, b変数を0にリセットします. つまり,close > open
, b はこのラウンドでコードを実行するときに 1 増やされ,b はプロット関数が引くと 1 になりますが,次のラウンドでコードを実行するときに b は 0 に再割り当てられます. これはまた,Pine 言語初心者が落とし穴に陥る傾向がある場所です.
2つのキーワードを拡大する必要があります.var
, varip
ワール
このキーワードの説明を見てみましょう. このキーワードの説明を見てみましょう. このキーワードの説明を見てみましょう.
varは,変数の割り当ておよび一度の初期化に使用されるキーワードである.一般的に,キーワード var を含まない変数の割り当て文法は,データが更新されるたびに変数の値が書き換えられる.対照的に,変数がキーワード 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キーワードに似ているが,varipで宣言された変数は,リアルタイム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 モデルでは,歴史的なK線段階,変数はi
, ii
申告したvar
, varip
戦略コードの実行の各ラウンドで増量操作を実行する.したがって,バックテスト結果のK線 BARに表示された数字が1ずつ増量されるのが見えます.歴史的なK線ステージが終了すると,リアルタイムK線ステージが始まります.varとvaripで宣言された変数は異なる変化を経験し始めます. Barモデルであるため,戦略コードはK線 BARの各価格変化に対して1回実行されます.i := i + 1
そしてii := ii + 1
i は次のラウンドで実行されると,前の値が復元されます (前回の"モデル実行"章で説明したロールバックメカニズムを覚えていますか?),そして現在のK線BARが完了するまでiの値が更新されません (つまり,次のラウンドで戦略論理を実行すると前の値が復元されません).したがって,変数iは依然として1で増加していることが見られます.しかし変数iiは各BARのために数回蓄積されます.
チェックモデル: Tick モデルは,K ライン BAR ごとに 1 回しか戦略論理を実行しないため,閉値モデルでは,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のPine言語は,Trading ViewのPine言語とは少し異なります.例えば:
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とTrading Viewの間には,パインの言語に関する違いがあります. 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
3つの演算子があります. 3つの演算子には 3つの演算子があります.
について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の閉値を引用したい場合,これを以下のように書きます.close[1]
.
前回のレッスンでこんなことを見ました
high[10]
ta.sma(close, 10)[1]
ta.highest(high, 10)[20]
close > nz(close[1], open)
について[]
同じ値で1回しか使えないので,このように書くのは間違っているので,エラーが報告されます.
a = close[1][2] // error
操作者が[]
配列の構造は,配列に似ているようです!
パイン言語における数列と配列の違いを例で説明しましょう.
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 は,