[TOC]
ビデオチュートリアル: トレーディングビューでPine言語を導入するのは難しいのか?
発明者量化取引プラットフォームは,Pine言語の策略作成をサポートし,反省をサポートし,Pine言語の策略を实体的に実行し,Pine言語の低バージョンを互換性がある. 発明者量化取引プラットフォームのFMZ.COMで戦略スクエア複数のPine戦略 (脚本) が集まって移植されています.
FMZは,Pine言語だけでなく,Pine言語の強力なグラフ機能をサポートしています.FMZプラットフォームのさまざまな機能,豊富な実用的なツール,高効率で簡単な管理,さらにPine戦略の実用性を強化しています.FMZは,Pine言語の互換性に基づいています.同時に,Pine言語の拡張,最適化,裁剪を一定程度に行っています.公式にチュートリアルに入る前に,FMZのPine言語と元の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)
2 , 策略 ((スクリプト) 取引に関連するいくつかの設定は,FMZ策略インターフェースの”Pine言語取引クラスリバ”パラメータによって設定されています.
strategy
これは,関数でcalc_on_every_tick
パラメータは,価格の変更ごとにリアルタイムで戦略の論理を実行する戦略スクリプトを設定します.calc_on_every_tick
このパラメータはtrue
標準でcalc_on_every_tick
参数として,false
策略の論理は,策略の現在のKラインBARが完全に終了したときに実行されます.
FMZでは,Pine言語取引類別庫のテンプレートのパラメータを設定します.戦略の実行時の価格,下位注文量などの数値の精度制御は,FMZ上で指定する必要がある. トレーディングビューでは模擬テストしかできないため,実物での注文時刻の精度問題はありません.FMZでは実物でのPine戦略を実行できます.その場合は,取引品種の価格精度,注文数精度を柔軟に指定できる戦略が必要です.これらの精度設定は,関連するデータの小数値を制御し,データが取引所報告書要求事項に適合しないことを避け,注文ができないことを防ぐことです.
期貨契約のコード
FMZ上の取引品種は,契約である場合,2つの属性がある.分別は”取引ペア”と”契約コード”であり,実盤と回測時に取引ペアを明確に設定する必要に加えて”,Pine言語取引類別庫”のテンプレートのパラメータ”品種コード”で具体的な契約コードを設定する必要があります.例えば,永続契約は記入します.swap
契約コードは,取引所がそのような契約を持っているかどうかによって異なります.例えば,取引所のすべての四半期契約は,ここに記入できます.quarter
┃ これらの契約コードは,FMZのJavascript/python/c++言語API文書で定義された期貨契約コードと一致する。
他の設定は,最小の単数,デフォルトの単数など,Pine言語のドキュメントを参照してください.“Pine言語の交換クラスデータベース”パラメータの紹介
runtime.debug
、runtime.log
、runtime.error
FMZの拡張関数で,デビュケーションに使用する。FMZプラットフォームでは,デビューするための3つの関数が追加されました.
runtime.debug
: コントロールで変数情報をプリントするには,一般的にこの関数は使用できません。
runtime.log
: 日記で出力する内容。FMZ PINE言語特有の関数。
runtime.log(1, 2, 3, close, high, ...),可以传多个参数。
runtime.error
: を呼び出すと,実行時にエラーが発生し,messageパラメータで指定されたエラーメッセージが付きます.
runtime.error(message)
4 図の部分に拡張されたoverlay
パラメータ
FMZ上のPine言語,図形関数plot
、plotshape
、plotchar
増えたoverlay
パラメータのサポートにより,主図または副図に指定することができます.overlay
設定true
主図に描かれたfalse
副図で描く.FMZ上のPine戦略が実行される時に主図と副図を同時に描くことができる.
syminfo.mintick
組み込み変数の取値syminfo.mintick
組み込み変数は,現在の品種の最小測定値として定義される.確定オファー/バックテストインタフェースの”Pine言語の取引クラスデータベース”のテンプレートパラメータの価格設定精度は,この値を制御できます.価格設定精度は2です.これは,取引時の価格が小数点2位まで正確であり,このとき価格の最小変動単位は0.01です.syminfo.mintick
0.01 でした.
例えば:下落価格は8000,販売方向,数量1枚 ((1枚),取引後の平均価格は8000,以下 ((費用には手数料が含まれている) 。
パイン言語の基礎を習い始めたとき,おそらくいくつかの例の命令,コードの文法には慣れていないだろう。理解できないのは問題ない,まずは概念に慣れ,テストの目的を理解し,FMZのパイン言語のドキュメントを閲覧することもできます。それからチュートリアルにステップ・ステップで慣れていく.
パイン言語のスクリプトの実行プロセスなどの関連概念を理解することが非常に必要である. パイン言語の策略は,グラフに基づいて動作し,グラフ上で時間序列の先後順序でグラフに既にロードされている最早のデータから実行される一連の計算と操作として理解できる. グラフに最初にロードされるデータの量は有限である. リアルディスクでは通常このデータ制限は,取引所インターフェースに戻された最大データ量に基づいて決定され,戻った時測定データの制限は,回測システムデータソースから提供されたデータに基づいて決定される. グラフの最左の最初の行,すなわちグラフのデータセットの1つであるKBarは,Pine言語の内置変数によってインデックスされる値が0である.bar_index
Pineスクリプトの実行時に現在のKラインBarのインデックス値を参照する.
plot(bar_index, "bar_index")
plot
この関数は,将来,もっと多くの関数として使用されるでしょう. 簡単なことです. 入力されたパラメータに基づいてグラフに線を引いて,入力されたデータはbar_index
線はbar_index
△ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △
戦略の設定によって,戦略のモデルが実行される方法も異なります.收盘价模型
そして实时价模型
閉店価格モデル,リアルタイム価格モデルの概念は,以前にも簡潔に紹介されていました.
策略コードの実行時に,現在のK線Barの周期は完全に実行され,K線が閉じると,K線周期は終了している.この時点で,Pine策略の論理が実行され,誘発された取引信号は,次のK線Barの開始時に実行されます.
策略コードの実行時に,現在のK線Barは,閉じたか否かにかかわらず,動きの変更ごとにPine策略の論理を繰り返し実行し,誘発された取引信号は即座に実行する.
グラフ上のK線Barは,Pine言語の策略がグラフ上で左から右に実行されたとき,历史Bar
そして实时Bar
ありがとうございました.
策略が”実値モデル”に設定され,実行を開始すると,グラフ上のK線バーは,右端のK線バーを除いてすべて历史Bar
戦略の論理は,历史Bar
実行は”回しかありません.
策略が”閉店価格モデル”に設定され,実行が開始されたとき,グラフ上のすべてのBarは历史Bar
戦略の論理は,历史Bar
実行は”回しかありません.
歴史バーによる計算: 策略コードは,ヒストリーバーの閉じる状態で1回実行され,その後,すべてのヒストリーバーが1回実行されるまで,次のヒストリーバーで実行され続ける.
策略が最右の最後のK行Barに実行されると,BarはリアルタイムBarである.RealTimeBarが閉じた後,Barは過去のRealTimeBarになり (歴史Barになる).図の最右側は新しいRealTimeBarを生成する.
策略が”リアルタイム価格モデル”に設定され,実行を開始すると,リアルタイムバーの動きごとに策略ロジックは実行されます. 策略が”閉店価格モデル”に設定され,実行が開始されたとき,グラフにはリアルタイムBarが表示されません.
リアルタイムでのBarによる計算:
策略を”閉店価格モデル”のグラフに設定すると,リアルバーが表示されない場合,策略コードは,現在のバーの閉店時に1回しか実行されません.
策略を”実値モデル”として設定すると,実時バーの計算と歴史バーは全く異なる.実物バーの動きごとに策略コードが実行される.例えば,内置変数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("n + 1之前, n:", n, " 当前bar_index:", bar_index)
n := n + 1
runtime.log("n + 1之后, n:", n, " 当前bar_index:", bar_index)
plot(n, title="n")
リアルタイムバーで実行される場面のみを研究したので,not barstate.ishistory
表現の制限は,リアルタイムBarでのみ変数nに積分され,積分操作を行う前後に使用されるruntime.log
関数出力情報は,策略日誌にあります.plot
描いた曲線nは,戦略が歴史バーで実行されているとき,nが常に0であったことがわかります.リアルタイムバーに実行されたとき,nの累積1の操作が引き起こされ,リアルタイムバーで実行された戦略の各ラウンドで,nの累積1の操作が実行されます.ロジ情報から,毎回再実行された戦略コードのnが,前回のBar実行戦略の最終的なコミットメントの値にリセットされていることがわかります.リアルタイムバーは,最後に実行された戦略コードの更新時にnの値を提出します.したがって,グラフ上では,リアルタイムBarから始まり,曲線nは,Barの曲線を増加するたびにnの値が増加していることがわかります.
結論から言うと 1. 策略がリアルタイムバーで実行される時,状況更新ごとに策略コードが実行されます. 2 リアルタイムバーで実行する際には,ポリシーコードが実行される前に変数が回転する. 3. リアルタイムバーで実行すると,変数はクローズオフ更新時に 1 回提出されます.
グラフ上の曲線などの描画操作は,データローリングによって再描画される可能性があります.例えば,テストコードを修正して,リールディスクテスト:
var n = 0
if not barstate.ishistory
runtime.log("n + 1之前, n:", n, " 当前bar_index:", bar_index)
n := open > close ? n + 1 : n
runtime.log("n + 1之后, n:", n, " 当前bar_index:", bar_index)
plot(n, title="n")
Aのスクリーンショット
Bのスクリーンショット
翻訳者は,この文を修正しただけです.n := open > close ? n + 1 : n
現時点のリアルタイムBarが陰線 (開盤価格が閉盤価格より高い) であったときのみnに累加1を与える.最初の図 (時刻A) に見られるように,開盤価格が閉盤価格より高いため,nが累加1されたので,グラフ曲線nの表示値は5である.そして,動きが変化し,価格更新は第2図 (時刻B) に見られるように.この時点で開盤価格が閉盤価格より低い (陽線),n値はロールバックし,累加1もされていない.このグラフ値の曲線nもすぐに再描画され,このとき曲線上のnは4である.したがって,リアルタイムBarに表示される金叉,死叉などの信号は不確定であり,変化する可能性がある.
以下では,Pine言語の関数の変数について研究してみましょう.いくつかのPineチュートリアルでの説明によると,関数の変数と関数の外の変数の違いは次のとおりです.
Pine関数で使用されるシリーズ変数の履歴は,関数に対する毎回の連続呼び出しによって作成される.もしスクリプトが実行される各列に関数が呼び出されなければ,これは関数の本体ブロック内と外部シリーズの履歴値の間の差を生じさせるだろう.したがって,もし関数が各列に呼び出されなければ,同じインデックス値を使用して関数の内部と外部に引用されるシリーズは,同じ履歴点を引用しないだろう.
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]
。
f2() => close[1]
変数を直接使用します.close
この関数で,close[1]
。
[]
記号は,データシリーズ変数の履歴値への引用操作,close[1]は,現在のクローズアップ価格の前のバーのクローズアップ価格データを引用する. 私たちのテストコードは,グラフに4種類のデータを描きます.
plotchar(oneBarInTwo ? f(close) : na, title = "f(close)", color = color.red, location = location.absolute, style = shape.xcross, overlay = true, char = "A")
文字を A f(close)
返される値は
plotchar(oneBarInTwo ? f2() : na, title = "f2()", color = color.green, location = location.absolute, style = shape.circle, overlay = true, char = "B")
文字をBで,緑色で描いて, oneBarInTwoが真であると描いて,描いた位置 (Y軸上) は:f2()
返される値は
plot(close[2], title = "close[2]", color = color.red, overlay = true)
線は赤色で,描いた位置は (Y軸上) は:close[2]
つまり,現在のBar前数2根の (左数2根の) Bar上の閉算価格である.
plot(close[1], title = "close[1]", color = color.green, overlay = true)
緑色で描いた線は,下記のように描かれています.close[1]
Bar の前数 1 番目 (左数 1 番目) の Bar の閉盘価格である.
図 A が使用されている関数にマークされています.f(a) => a[1]
グラフBのマークを使用した関数f2() => close[1]
デザインは[1] データシリーズの過去のデータを引用する,しかしグラフ上の”A”と”B”のマークの位置は全く異なります. “A”マークの位置は常に赤い線,つまり戦略中のコードの上にあります.plot(close[2], title = "close[2]", color = color.red, overlay = true)
線が描かれていて,その線はclose[2]
。
変数のインデックスを入力します.bar_index
“A”と”B”の標識を描画するかどうかを計算する。”A”と”B”の標識は,各 K 線Bar に描画されない。f(a) => a[1]
この方法で引用される値は,関数がすべてのBarに呼び出されない場合,関数と関係します.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
この結果として,close > close[1]
この関数で ta.barssince を呼び出します.ta.barssince
この関数は,この関数から計算されます.close < close[1]
成立時の K 線数. ta.barssince 関数呼び出しは close > close になります.[1],つまり,現在の閉じる値が前のBarの閉じる値より大きい,関数ta.barssinceが呼び出されるとその条件close < close[1] 成立していないので,最近成立した場所も無い。
ta.barssince: 呼び出されると,現在のK行以前にこの条件が満たされていない場合,この関数はna。を返します.
図に示すように:
グラフを描くとき,res変数 ((-1)) があるときのデータしか描かない.
この問題を回避するために,ta.barssince(close < close[1])
関数呼び出しは三元関数から取り出して,可能な条件分岐の外部に書き込む. K 線Bar 上のすべての計算を実行するようにする.
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)
タイムシーケンスという概念は,Pine言語において非常に重要であり,私たちがPine言語を学ぶときに理解しなければならない概念である.タイムシーケンスとはタイプではなく,時間とともに変数を保存する連続的な値の基本構造である.Pineスクリプトはグラフに基づいていることが分かっているが,グラフで示される最も基本的なものは,K線図である.タイムシーケンス,それぞれの値は,K線Barのタイムに関連している.open
これはPine言語の内蔵変数である (built-in),その構造は,各K線Barの開盤価格を保存する時間序列である.open
このタイムシーケンスの構造は,現在の K 線図が開始した最初の Bar から現在のスクリプトで実行されたこの Bar までの K 線図Bar の開値を表します. もし現在の K 線図が5分周期であれば,Pine 戦略のコードで引用する (または使用する)open
策略コードの現在の実行時に K 線Bar の開拓価格である. タイムシーケンスの歴史値を引用するには使用する必要があります.[]
オペレーター: K 線バーでPine 策略が実行されたとき,open[1]
引用表示open
時間序列上では,現在のスクリプトが実行しているこのK線Barの前のK線Barの開盘価格 ((つまり,前の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線1で実行されます. 策略は2番目のK線で実行されます. 策略は3番目のK線で実行されます. |…|…|…|…| 戦略は,N+1のK線で実行されます.
実際,v1,v2,さらにはbar_indexは時間序列構造であり,各Barには対応するデータがあることがわかります.このテストコードは”,リアルタイム価格モデル”と”閉店価格モデル”の区別は,グラフにリアルバーが表示されるかどうかだけではありません.速度を回測するために”,閉店価格モデル”の回測テストを使用しています.
変数 v1 は 1 です.ta.cum(v1)
函数が最初のK行Bar上で実行されたとき,最初のBarしか存在しないので,計算結果は1で,変数v2に値を付与する.
したta.cum(v1)
2番目のK行Barで実行すると,すでに2つのK行Barがある ((最初の対応する内置変数bar_indexは0で,第二の対応する内置変数bar_indexは1),したがって,計算結果は2で,変数v2に値を与えられ,こうして続きます.実際にv2はグラフ内のK行Barの数であることが観察できます.bar_index
0から始めます.bar_index + 1
グラフの上の線は,K線のBarの数です.v2
そしてbar_index
ツイッターで投稿した記事です.
このビデオは,ta.cum
この内置関数は,現在のグラフ上のすべてのBarの収束値の和を計算し,次のように書きます.ta.cum(close)
策略が右端のリアルタイムバーに実行されたときta.cum(close)
計算された結果は,グラフ上のすべてのBarの閉盘価格の合計である (右端まで動かずに,現在のBarに累積するだけです).
時系列上の変数は,オペレーターを使用して計算することもできます.例えば,コード:ta.sma(high - low, 14)
変数を入力します.high
値が上がったとき,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)[1]
その中でもta.highest(high, 10)
この関数では,関数呼び出しで得られた結果が[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の値は,対応するBarの上と下に表示されていることがわかります.テストや実験の際に,しばしばグラフに情報を出力して観察する必要があるため,学習の過程でこの図のコードを保存できます.
このチュートリアルでは,FMZのPineとTrading ViewのPineの言語の違いについて説明しました. FMZのPineのコードは,バージョン番号を省略できます.indicator()
、strategy()
支持は一時的に停止library()
もちろん,以前のPineの脚本と互換性のために,以下のような策略を書き込みました.//@version=5
,indicator()
,strategy()
設定はこちらからできます.strategy()
函数内の传参の設定
<version>
<declaration_statement>
<code>
<version>
バージョン管理情報は省略できます.
パイン語//
単行注釈として,Pine言語に多行注釈がないため,FMZは注釈を拡張した./**/
複数行注釈に使う.
スクリプトの注釈やコンパイラ命令の行は文ではなく,スクリプトのアルゴリズムを実装する文である。文は,これらの内容のいずれかである。
if
,for
,while
またはswitch
等構造文は様々な方法で並べられます
空格
または制表符
(tab鍵) 開始。その最初の文字もその行の最初の文字でなければならない。行の最初の位置で始まる行は,定義によりスクリプトの全域の一部となる。local block
。 ローカルブロックは表記符または4つの空白に縮小されなければなりません。 そうでなければ,前行の連続コードとして解析され,つまり前行のコードの連続内容として判断されます。 各ローカルブロックは異なるローカル範囲を定義します。例えば,以下のコードで if 構造を使用する3つの局所ブロック,すなわち,自定義関数声明で1つ,変数声明で2つを含む.
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)
ユーザ定義の関数声明の文も包装できる。しかし,局部ブロックは文法的に縮小で始めなければならないので,次の行に分割すると,文の継続部分は1つ以上の縮小で始めなければならない (例えば:
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 // 错误的命名!使用了数字字符作为标识符的开头字符
ほとんどのプログラミング言語と同様に,Pine言語にも書き込みの推奨があります.通常,識別子の命名時に推奨されるのは:
// 命名变量、常量
GREEN_COLOR = #4CAF50
MAX_LOOKBACK = 100
int fastLength = 7
// 命名函数
zeroOne(boolValue) => boolValue ? 1 : 0
オペレーターは,プログラミング言語で表現を構成するために使用されるいくつかの演算符であり,表現は,策略を書き込むときに何らかの計算目的のために設計された計算規則である.Pine言語のオペレータは,機能によって次のように分類される.
代入演算子,算数演算子,比較演算子,論理演算子,? :
3次元の演算子[]
引用経緯演算子
算数演算子で*
例えば,Trading View上のPine言語演算子による返却結果によるタイプ問題とは異なり,以下のテストコードがあります.
//@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
種類 (シリーズ)ta.ema
函数の2番目のパラメータは,このタイプをサポートしません。しかし,FMZでは,このような厳格な制限はありません.上記のコードは正常に動作します。
演算子の使い方について,以下で説明します.
代入演算子には 2 つの種類があります.=
、:=
ビデオでは,このトピックのテーマは, ウェブのコンテンツの管理と管理について説明しています.
=
変数を初期化または宣言する際に使用するオペレータ.=
初期化,宣言の付与後の変数は,その後の各バーでその値で始まる. これらは有効な変数宣言である:
a = close // 使用内置变量赋值给a
b = 10000 // 使用数值赋值
c = "test" // 使用字符串赋值
d = color.green // 使用颜色值赋值
plot(a, title="a")
plot(b, title="b")
plotchar(true, title="c", char=str.tostring(c), color=d, overlay=true)
知らせa = close
赋值文,各バーの変数aは,そのバーの現在の閉店価格 ((close) である. その他の変数b
、c
、d
FMZの反射システムでテストできる,図で結果がわかる.
:=
既存の変数に値を再割り当てるために使用され,単純に:=
オペレーターは,すでに宣言された,初期化された変数の値を修正するために使用される.
使用されている場合:=
オペレーターは,初期化されていない変数または宣言されていない変数に値を与えると,エラーが発生します. 例えば:
a := 0
ありがとうございました.:=
代入演算子は,一般に,既存の変数に対する再代入に使用される.例えば:
a = close > open
b = 0
if a
b := b + 1
plot(b)
判断するclose > open
(つまり,現在のBARは陽線),aの変数は真値 ((true)) である.b := b + 1
, 指定操作を使用する:=
b を再定義し,1 を加える. そして, plot 関数を使用して,時間序列の各 BAR の変数b の値をグラフに描き,線状にします.
陽線BARが出ると,bが1を累乗し続けると考えられるでしょうか? もちろんそうではありません. ここで,bの変数を宣言し, 0で初期化する際に, キーワードを指定していません.b=0
このコードの実行結果は,bの変数を0に設定し,aの変数が真ならば,close > open
この回の実行コードでは,b は 1 を累乗し,プロット関数で b は 1 になりますが,次の回の実行コードでは,b は 0 に再代入されます. これは,Pine 言語の初心者にとって容易な問題です.
代入演算子については,次の2つのキーワードを拡張する必要があります.var
、varip
このキーワードは,以前にも紹介されていたが,詳しくは説明されていない. このキーワードの説明をご覧ください.
var は,割り当ておよび単一の初期化変数のためのキーワードである.通常,var というキーワードを含まない変数赋值の文法により,データ更新ごとに変数の値が覆われる.逆に,var というキーワードを使用すると,変数が割り当てられ,データ更新にもかかわらず,その状態は保持される.
bの値の定義は,bの値の定義の定義と同じです.var
キーワード:
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")
変数 ‘a’ は,シリーズの最初の柱線の終値を維持する. 変数 ‘b’ は,シリーズで最初の緑色のの値棒の終値を維持する. 変数 ‘c’ は,シリーズ第10の緑のの終盤価格を維持している.
varip
このキーワードの説明はこうです.
varip ((var intrabar persist) は,分配および単発初期化変数用のキーワードである。それはvarキーワードに似ているが,varip宣言を使用した変数は,リアルタイムK行更新の間にその値を保持する。
分かりにくいですか? いいえ,例で説明すると分かりやすいでしょう.
strategy(overlay=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
i := i + 1
ii := ii + 1
このテストコードは”閉店価格モデル”と”リアルタイム価格モデル”で異なる動作をします.
リアルタイム価格モデル:
リアルタイム価格モデルでは,歴史のK線段階では, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは,var
、varip
声明の変数i
、ii
策略コードの実行毎に増加操作が実行されます。したがって,反測結果のK行BARに表示される数字は1つずつ増加していることがわかります。歴史K行段階が終了し,リアルタイムK行段階が始まる。var,varip宣言の変数は異なる変化が始まる。リアルタイム価格モデルであるため,K行BAR内の価格の変化ごとに策略コードが実行され,i := i + 1
そしてii := ii + 1
すべての実行は 1 回である。 違いは,ii が毎回修正されている。 i は毎回修正されているが,次の実行戦略の論理では,以前の値が復元される (前回の”モデル実行”章で説明した回転メカニズムを覚えていますか?),現在の KBAR 行が終了するまで,確定i の値が更新されない (つまり,次の実行戦略の論理では,以前の値が復元されない). したがって,i 変数は,BAR 根毎に 1 ずつ増加している。 しかし,i 変数は,BAR 根毎に何度か増加している。
閉店価格モデル: 閉じる価格モデルは,K線BARが走るごとに1回の戦略ロジックを実行するからである.したがって,閉じる価格モデルでは,歴史的K線段階とリアルタイムK線段階,var,varip宣言の変数は,上記の例で完全一致して増加し,K線BARが1回増加する.
オペレーター | 例示する |
---|---|
+ | 加法 |
- | 減算法 |
* | 乗算法 |
/ | 法律の廃止 |
% | 模範を求める |
+
、-
オペレーターは,二進数オペレータとしても,1進数オペレータとしても使用できます.他の算数オペレータは二進数オペレータとしてのみ使用できます.一進数オペレータとして使用するとエラーになります.
1 ,算数演算子は両側が数値型であり,結果として数値型,整型または浮点数具体的には演算結果である.
2 文字列に操作数がある場合,その操作は+
計算結果が文字列で,数値は文字列形式に変換され,文字列が拼写されます. 他の算数演算子であれば,文字列を数値に変換して操作しようとします.
3. 操作数にnaがある場合,計算結果はn0で,FMZで印刷するとNaNが表示されます.
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言語と少し違います.FMZ上のPine言語は,変数タイプの要求に対してそれほど苛酷で厳格ではありません.例えば:
a = 1 * "1.1"
b = "1" / "1.1"
c = 5 % "A"
plot(a)
plot(b)
plot(c)
FMZでは実行可能だが,trading viewではタイプエラーが報告される.算数演算子の両側の操作数が文字列である場合,システムは文字列を数値に変換して計算する.非数値文字列が計算できない場合,システム操作結果は空値naである.
比較演算子は二進数演算子である。
オペレーター | 例示する |
---|---|
< | 小さい |
> | より大きい |
<= | これは,この式で, |
>= | これは,xの2乗です. |
== | 相当する |
!= | 格差がある |
テスト例:
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のPineと異なる.FMZには特に厳格な要求型がないので,このような文はd = "1" >= 2
FMZではエラーがなく,実行時に文字列を数値に変換し,比較操作を行う.Trading Viewではエラーが表示されます.
オペレーター | コード記号 | 例示する |
---|---|---|
ない | not | 単元オペレーター,非演算 |
そして | and | バイナリ演算子,と (そして) 演算 |
または | or | バイナリ演算子,または演算 |
論理演算子について言えば,真価表について語らなければなりません. 高校で習ったように,ここでは反射システムでテストし,学びます.
a = 1 == 1 // 使用比较运算符构成的表达式,结果为布尔值
b = 1 != 1
c = not b // 逻辑非操作符
d = not a // 逻辑非操作符
runtime.log("测试逻辑操作符: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("测试逻辑操作符: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")
文は,プリントを1回実行した後,反測を停止させる異常エラーを投げる.その後,出力情報を観察して,プリントの内容と真値表が実際には同じであることを発見することができます.
三元演算子を使用? :
操作数と組み合わせた三元式condition ? valueWhenConditionIsTrue : valueWhenConditionIsFalse
前回のレッスンでもよく知っていました. 三元式,三元演算子というのは,その操作数は合計3つということです.
condition ? valueWhenConditionIsTrue : valueWhenConditionIsFalse
中にはcondition
判定条件は,もし真則表現の値が:valueWhenConditionIsTrue
│ │condition
この式は,valueWhenConditionIsFalse
。
この例は実用的にはあまり役に立たないが,簡単に説明できます.
a = close > open
b = a ? "阳线" : "阴线"
c = not a ? "阴线" : "阳线"
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 ? "阳线" : "十字星" : math.abs(close-open) > 30 ? "阴线" : "十字星"
c = not a ? math.abs(close-open) > 30 ? "阴线" : "十字星" : math.abs(close-open) > 30 ? "阳线" : "十字星"
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)
石油の価値が上がるのですcondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalse
でvalueWhenConditionIsTrue
、valueWhenConditionIsFalse
代わりに別の三元表現を使う.
過去演算子を使用する[]
,引用時間序列上の歴史値。これらの歴史値は,スクリプトが実行される時点の現在のKラインBAR前のKラインBAR上の変数である。[]
変数,式,関数呼び出しの後に使用されるオペレータ.[]
この方格括弧の値は,私たちが参照する過去データから現在のK線BARの偏移量である.例えば,私が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] // 错误
操作は,この関数で実行されます.[]
これは,数列の構造と,数列の構造とほぼ同じです.
下では,Pine言語の系列 (series) と配列 (array) の違いを例で説明する.
”`pine