[TOC]
ビデオ・チュートリアル:取引の量化への入門は難しいですか? trading view Pine を使って,小白からQuant 大神社まで,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 Language Transaction Library"のパラメータによって設定されます.
strategy
この関数は,calc_on_every_tick
パラグマーは,価格の変化ごとにリアルタイムで戦略ロジックを実行する戦略スクリプトを設定します.calc_on_every_tick
このパラメータは,true
│ │ │calc_on_every_tick
この式は,false
実行する. 実行する. 実行する.
FMZでは",Pine言語取引庫"のテンプレートのパラメータで設定します.策略実行時の価格,下位単位量などの数値精度制御はFMZで指定する必要がある. トレーディングビューでは,模擬テストのみが可能であるため,実盤下注の精度の問題はない. FMZでは,実盤でPine戦略を実行できる.その場合,戦略が柔軟に取引品種の価格精度,下注数量精度を指定できる.これらの精度設定は,関連データの小数値を制御し,データが取引所の表記要求を満たさないので下注ができないことを防ぐ.
フューチャー契約コード
FMZにおける取引品種は,契約である場合,2つの属性がある. "取引対"と"契約コード"はそれぞれである.実盤と復習では,取引対を明確に設定するだけでなく",Pine Language Trade Library"テンプレートのパラメータ"種コード"に特定の契約コードを設定する必要がある.例えば,永続契約は記入される.swap
契約コードは,取引所がそのような契約を持っているかどうかを特定します.例えば,取引のすべての四半期契約は,ここで記入できます.quarter
■これらの契約コードは,FMZのJavaScript/python/c++言語API文書で定義されたフューチャー契約コードと一致する.
他の設定は,例えば,最小単位の量,デフォルト単位の量などについては,Pine 言語のドキュメントを参照してください."Pine Language Exchange Library (パイヌ言語取引データベース) "というサイトを立ち上げましたパラメータの紹介.
runtime.debug
、runtime.log
、runtime.error
FMZの拡張機能は,デビューに使用される.FMZプラットフォームには3つの機能が追加されました.
runtime.debug
: コントロールで変数情報をプリントするには,この関数は一般的に使用できません.
```pine
runtime.log(1, 2, 3, close, high, ...),可以传多个参数。
```pine
runtime.error(message)
4 図解関数の一部を拡張しましたoverlay
パラメータ
FMZのPine言語,図形関数plot
、plotshape
、plotchar
増えたのですoverlay
パラグマサポート,主図または副図で絵を指定することを許可します.overlay
設定するtrue
絵は主題に設定されています.false
副図で描画する. FMZ上のPineのポリシーが実行されているときに主題,副図を同時に描画する.
syminfo.mintick
内蔵変数の取值
- 6、FMZ PINE Script中的均价均为包含手续费的价格
例如:下单价格为8000,卖出方向,数量1手(个、张),成交后均价不是8000,低于8000(成本中包含了手续费)。
## Pine语言基础
开始学习Pine语言基础时,可能有些例子中的指令、代码语法我们并不熟悉。看不懂没关系,我们可以先熟悉概念,理解测试目的,也可以查询FMZ的Pine语言文档查看说明。然后跟随教程一步一步循序渐进熟悉各种语法、指令、函数、内置变量。
### 模型执行
在入门学习Pine语言时,是非常有必要了解Pine语言脚本程序执行过程等相关概念的。Pine语言策略是基于图表运行的,可以理解为Pine语言策略为一系列的计算和操作,在图表上以时间序列的先后顺序从图表已经加载的最早数据开始执行。图表初始加载的数据量是有限的。实盘时通常这个数据量上限是基于交易所接口返回的最大数据量决定,回测时数据量上限是基于回测系统数据源提供的数据决定。图表上最左边的第一个K线Bar,即图表数据集的第一个数据,其索引值为0。可以通过Pine语言的内置变量```bar_index```引用到Pine脚本执行时当前的K线Bar的索引值。
```pine
plot(bar_index, "bar_index")
根据策略的设置不同,策略的模型执行方式也不同,分为```收盘价模型```和```实时价模型```。收盘价模型、实时价模型的概念在之前我们也简单介绍过。
- 收盘价模型
策略代码执行时,当前K线Bar的周期完全执行完成,K线闭合时即K线周期已经走完。此时执行一遍Pine策略逻辑,触发的交易信号将在下一根K线Bar开始时执行。
- 实时价模型
策略代码执行时,当前K线Bar不论是否闭合,每次行情变动就执行一遍Pine策略逻辑,触发的交易信号立即执行。
当Pine语言策略在图表上从左至右执行时,图表上的K线Bar是分为```历史Bar```和```实时Bar```的:
- 历史Bar
策略设置为「实盘价模型」开始执行时,图表上除了最右侧的那一根K线Bar之外所有K线Bar都是```历史Bar```。策略逻辑在每根```历史Bar```上仅执行一次。
策略设置为「收盘价模型」开始执行时,图表上所有Bar都是```历史Bar```。策略逻辑在每根```历史Bar```上仅执行一次。
基于历史Bar的计算:
策略代码在历史Bar收盘状态下执行一次,然后策略代码继续在下一个历史Bar执行,直到所有历史Bar都执行一次。
- 实时Bar
当策略执行到最右边的最后一根K线Bar上时,该Bar为实时Bar。当实时Bar闭合之后,这根Bar就变成了一个经过的实时Bar(变成了历史Bar)。图表最右侧会产生新的实时Bar。
策略设置为「实时价模型」开始执行时,在实时Bar上每次行情变动都会执行一次策略逻辑。
策略设置为「收盘价模型」开始执行时,图表上不显示实时Bar。
基于实时Bar的计算:
如果设置策略为「收盘价模型」图表不显示实时Bar,策略代码只在当前Bar收盘时执行一次。
如果设置策略为「实盘价模型」在实时Bar上的计算和历史Bar就完全不同了,在实盘Bar上每次行情变动都会执行一次策略代码。例如内置变量```high```、```low```、```close```在历史Bar上是确定的,在实时Bar上可能每次行情变动时这些值是会发生变化的。所以基于这些值计算的指标等数据也是会实时变动的。在实时Bar上```close```始终代表当前最新价格,```high```和```low```始终代表自当前实时Bar开始以来达到的最高高点和最低低点。这些内置变量代表实时Bar最后一次更新时的最终值。
实时Bar上执行策略时的回滚机制(实时价模型):
在实时Bar执行时,策略的每次新迭代执行前重置用户定义的变量称为回滚。我们来以一个例子理解回滚机制,如下测试代码。
注意:
/*バックテスト ... ほら わかった - わかった */
包裹的内容为FMZ平台上以代码形式保存的回测配置信息。
```pine
/*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は,ポリシーが歴史Barで実行されているとき nが0であったことがわかります. リアルバーまで実行するとn加1の操作が引き起こされ,リアルバーで実行する毎回策略でn加1の操作が実行されます. ログ情報から,毎回策略コードを再実行するたびにnが前の策略Barが最終的に提出した値にリセットされていることが観察できます. リアルバーで実行した最後の策略コードが n値更新を提出しているとき,グラフはリアルバーから始まり,Barがタイムカーブnの値を1に増加するたびに曲線nが表示されていることがわかります.
概要はこうです 1, ポリシーがリアルタイムBarで実行開始時に,行事更新ごとに 1 つのポリシーコードが実行される. 2, リアルタイムバーで実行すると,ポリシーコードを実行するたびに変数をロールバックします. 3、リアルタイムBarで実行すると,変数は閉盘更新時に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を与えます. 第1図 (とき A) では,開盤価格が閉盤価格より高いのでn+1が加えられ,グラフ曲線nが表示される値は5です. その後,行情の変化,価格更新が2図 (とき B) のように表示されます. このとき開盤価格が閉盤価格より低いとき (とき B) はn回転し,1も加算されません. グラフの曲線nも即座に再描画され,このとき曲線上のnは4です. したがって,リアルタイムBarで表示される金
以下は,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]
。
- ```plotchar(oneBarInTwo ? f(close) : na, title = "f(close)", color = color.red, location = location.absolute, style = shape.xcross, overlay = true, char = "A")```
画一个字符“A”,颜色为红色,当oneBarInTwo为真时才画出,画出的位置(Y轴上)为:```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)```
画线,颜色为绿色,画出的位置(Y轴上)为:```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]```。
![发明者量化PINE语言入门教程](/upload/asset/16453fe4ca019e172f4a.png)
原因就是通过K线Bar的索引,即内置变量```bar_index```计算是否画"A"和"B"标记。"A"和"B"标记并不是在每根K线Bar上都画图(画图时调用函数计算)。函数```f(a) => a[1]```这种方式引用的值,如果函数不是每根Bar上都调用就会与函数```f2() => close[1]```这种方式引用的值不相同(即使都使用[1]这样相同的索引)。
- 一些内置函数需要在每个Bar上计算才能正确计算其结果
以一个简单例子说明这种情况:
```pine
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が値を持つときのデータしか描かれない.
この問題を解消するために,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 線図である.open
パイン言語の内蔵変数である.その構造は,各K線Barの開盤価格の時間列を保存するものである.open
この時間配列構造は,現在のK文字列の最初のBarから,現在のスクリプトが実行されるこのBarまでのすべてのK文字列の開示値を表します. もし現在のK文字列が5分周期である場合,我々はPine策略コードで引用 (または使用) します.open
time は,策略コードを使用して現在実行されている時にK線Barの開示値である.[]
オペレーター、Pine ポリシーが K 線Bar で実行される時,使用する.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
伝達された変数の値が各K線Barに合致する値を加算します. 次に,理解を助けるグラフを使用します.
実行中の内蔵変数 bar_index v1 で v2 で ありがとうございました 戦略はK線1で実行されます. 戦略は第2のK線で実行されます 戦略は3番目のK線で実行されます. ほら ほら ほら ほら この戦略はN+1のK線で実行されます.
v1,v2,そしてbar_indexは,実際には各Barに対応するデータを持つ時間序列構造である.このテストコードは",リアルタイム価格モデル"と"閉値モデル"を区別するだけでなく,チャート上でリアルタイムBarを表示するかどうかによって区別する.回転速度を測るために",閉値モデル"回転テストを使用する.
変数v1は1で,この変数v1は1で,この変数v1は1です.ta.cum(v1)
函数が最初のK線Barで実行されたとき,最初のBarのみがあるため,計算結果は1,変数v2を代入します.
どこにいるのかta.cum(v1)
2番目のK線Barで実行すると,既に2つのK線Barがある (最初の対応する内置変数bar_indexは0で,第2の対応する内置変数bar_indexは1) のため,計算結果は2で,変数v2に代入される.bar_index
この式は,この式を0から始めると,bar_index + 1
線を観察するグラフでも線が見えます.v2
そしてbar_index
コンピュータの使い方についてta.cum
このグラフのすべてのBarの閉じる価格の合計を計算する内蔵関数は,以下のように書くことができます.ta.cum(close)
実行するときに,右端のリアルタイムバーta.cum(close)
計算の結果は,グラフ上のすべてのBarの閉じる価格の和である (右端まで走らないとき,ただ現在のBarに足すだけです).
タイムシーケンス上の変数は,オペレータを使用して処理することもできます.例えばコード:ta.sma(high - low, 14)
変数から変数に変換します.high
低価格で購入したものですlow
(K線Bar 最低価格) 最後の使用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)
函数呼び出しで計算された結果は,また,現在のBarの前のBarに対応した値に基づいて,その歴史値を参照するために使用できます.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言語の使用の違いをまとめました.indicator()
、strategy()
支持していない.library()
もちろん,Pineの初期のバージョンとの互換性のために,策略は以下のように記述されます.//@version=5
,indicator()
,strategy()
策略設定は,このページでご利用いただけます.strategy()
函数内のパラメータ設定を入力します.
<version>
<declaration_statement>
<code>
#### 注释
Pine语言使用```//```作为单行注释符,由于Pine语言没有多行注释符。FMZ扩展了注释符```/**/```用于多行注释。
#### 代码
脚本中不是注释或编译器指令的行是语句,它实现了脚本的算法。一个语句可以是这些内容之一。
- 变量声明
- 变量的重新赋值
- 函数声明
- 内置函数调用,用户定义的函数调用
- ```if```,```for```,```while```或```switch```等结构
**语句可以以多种方式排列**
- 有些语句可以用一行来表达,比如大多数变量声明、只包含一个函数调用的行或单行函数声明。其他的,像结构,总是需要多行,因为它们需要一个局部的块。
- 脚本的全局范围内的语句(即不属于局部块的部分)不能以```空格```或```制表符```(tab键)开始。它们的第一个字符也必须是该行的第一个字符。在行的第一个位置开始的行,根据定义成为脚本的全局范围的一部分。
- 结构或多行函数声明总是需要一个```local block```。一个本地块必须缩进一个制表符或四个空格(否则,会被解析为上一行的串联代码,即被判定为上一行代码的连续内容),每个局部块定义了一个不同的局部范围。
- 多个单行语句可以通过使用逗号(,)作为分隔符在一行中串联起来。
- 一行中可以包含注释,也可以只是注释。
- 行也可以被包起来(在多行上继续)。
例如,包括三个局部块,一个在自定义函数声明中,两个在变量声明中使用if结构,如下代码:
```pine
indicator("", "", true) // 声明语句(全局范围),可以省略不写
barIsUp() => // 函数声明(全局范围)
close > open // 本地块(本地范围)
plotColor = if barIsUp() // 变量声明 (全局范围)
color.green // 本地块 (本地范围)
else
color.red // 本地块 (本地范围)
runtime.log("color", color = plotColor) // 调用一个内置函数输出日志 (全局范围)
長い行は複数の行に分けられる,または,
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)
ユーザー定義された関数宣言内の文言も包み込むことができる.しかし,局所が文法的に縮小で始まる (四つのスペースまたは一つの表記符) のために,次の行に分割すると,文言の続続は"つ以上の縮小で始まる (四つのスペースの倍数に等しくない) "である.例えば:
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
オペレーターとは,プログラミング言語で表現を構成するために使用されるいくつかの操作符号であり,表現は,私たちが策略を書いているとき,何らかの計算目的のために設計された計算規則である.
配分演算子,計算演算子,比較演算子,論理演算子,? :
この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 =
注意```a = close```赋值语句,在每个Bar上变量a都是当前该Bar的收盘价(close)。其它的变量```b```、```c```、```d```是不变的,可以在FMZ上的回测系统中测试,由画图可以看出结果。
```:=```用于将值重新赋值给现有变量,可以简单理解为使用```:=```操作符是用来修改已经声明过、初始化过的变量值。
如果使用```:=```操作符给未初始化或者声明的变量赋值会引发错误,例如:
```pine
a := 0
メディアは,:=
赋值演算子は,一般的に,既にある変数の再赋值に使用される.例えば:
a = close > open
b = 0
if a
b := b + 1
plot(b)
判断するclose > open
変数 a は true です. if 文のローカルブロック内のコードを実行します.b := b + 1
割り当て操作を使用します.:=
b に対して値を再指定し,1 を加える. そして, plot 関数を使用して,時間列の各BARの値に変数 b を線形に図を描く.
陽線BARが表示され,bが1を継続的に加算すると考えますか? もちろんそうではありません. ここで変数bを宣言します.b=0
このコードの実行結果は,aが真値である場合,bを0にリセットする毎回です. aが真値である場合,aが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,bが真値である場合,close > open
この回実行するときにbは1,plot関数図を描くときに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声明的变量不仅可以写在全局范围,也可以写在代码块中,例如这个例子:
```pine
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(var intrabar persist)是用于分配和一次性初始化变量的关键词。它与var关键词相似,但是使用varip声明的变量在实时K线更新之间保留其值。
是不是比较难以理解?没关系,我们通过例子来讲解,就很容易明白了。
戦略 (overlay=true)
// var varip をテストする 変数 i = 0 変数2は0です.
// 戦略ロジックが毎回変化するi、iiを図に印刷する
plotchar ((true, title=
// i,iiは毎回の論理実行で 1 を増やします i: = i + 1 これは,x+1です.
这个测试代码在「收盘价模型」、「实时价模型」上有不同表现:
实时价模型:
还记得我们之前讲解的策略执行时分为历史BAR阶段,实时BAR阶段吗?当在实时价模型,历史K线阶段时```var```、```varip```声明的变量```i```、```ii```在策略代码每轮执行时都会执行递增操作。所以可以看到回测结果K线BAR上显示的数字逐个都是递增1的。当历史K线阶段结束,开始实时K线阶段。var、varip声明的变量则开始发生不同的变化。因为是实时价模型,在一根K线BAR内每次价格变动都会执行一遍策略代码,```i := i + 1```和```ii := ii + 1```都会执行一次。区别是ii每次都修改。i虽然每次也修改,但是下一轮执行策略逻辑时会恢复之前的值(记得之前「模型执行」章节我们讲解的回滚机制吗?),直到当前K线BAR走完才更新确定i的值(即下一轮执行策略逻辑时不再恢复之前的值)。所以可以看到变量i依然是每根BAR增加1。但是变量ii每根BAR就累加了好几次。
收盘价模型:
由于收盘价模型是每根K线BAR走完时才执行一次策略逻辑。所以在收盘价模型时,历史K线阶段和实时K线阶段,var、varip声明的变量在以上例子中递增表现完全一致,都是每根K线BAR递增1。
---------------------------
##### 算数运算符
|运算符|说明|
|-|-|
|+|加法|
|-|减法|
|*|乘法|
|/|除法|
|%|求模|
```+```、```-```操作符可以用作二元操作符,也可以当做一元操作符。其它的算数运算符只能用作二元操作符,如果用作一元操作符会报错。
1、算数运算符两侧都是数值类型,结果为数值类型,整型还是浮点数具体看运算结果。
2、如果其中有操作数是字符串,操作符是```+```,则计算结果为字符串,数值会转换成字符串形式,然后字符串拼接在一起。如果是其它算数运算符,则会尝试将字符串转换为数值,然后运算。
3、如果其中有操作数是na,则计算结果为空值na,在FMZ上打印的时候会显示NaN。
```pine
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では実行できますが,トレードビューではタイプエラーを表示します. 算数演算子の両側が文字列である場合,システムは文字列を数値に変換して計算します. 非数値文字列が計算できない場合,システム演算結果は空値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ではエラーが返されない.実行時に文字を数値に変換し,比較操作を行う.
演算子 | コードマーク | 解説 |
---|---|---|
できない | ない | 単元操作符,非操作 |
そして | そして | 双進演算子,と () を操作する |
あるいは | または | バイナリーオペレータ,または演算 |
論理演算子について言えば,真値表について話す必要があります. 高校で習ったように,ただ,ここでテストを行います.
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")
文句は,一回プリントを実行した後,異常なエラーを投げて復習を停止させ,その後,出力された情報を観察し,印刷された内容と真値表が実際には同じであることを確認することができます.
3つの演算子を使用する? :
操作数と組み合わせた三元式condition ? valueWhenConditionIsTrue : valueWhenConditionIsFalse
この式は,3つの関数で成り立っています.この式は,3つの関数で成り立っています.
虽然没什么实际用途,但是方便演示的例子:
```pine
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)
```pine
a = close[1][2] // 错误
操作者は,この操作の実行を表示します.[]
列の構造は,列と数列の構造に似ています.
この例では,Pine言語の行列と配列の違いを説明します.
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 は b よりも大きいです.c = b[1]
b はまだ歴史操作で歴史値への引用ができます. わかるように,Pine のseries の概念は行列ほど単純ではありません. 前のBar の歴史値が,b に代入された close として理解できる. b はまた,時間系列構造であり,その歴史値への引用が続けられます. そこで,描かれた3つの線 a,b,c の間で,b 線は a 線の 1 BAR,c 線は b 線の 1 BAR,c 線は a 線の 2 BARよりも遅い.
グラフを左に引っ張って,最初のK行に b と c の値が空値であることに注意することができます. それは,スクリプトが最初のK行 BAR で実行されるときに,前向きに引用する1つの,または2つの周期の歴史値が存在しないからです. だから,戦略を書くときに,私たちは頻繁に注意する必要があります.na
、nz
この関数は,この関数と関数の両方をnz
、na
空白値について具体的に扱っている例は,例えば:
close > nz(close[1], open) // 当引用close内置变量前一个BAR的历史值时,如果不存在,则使用open内置变量
これは,空値 ((na) に参照する可能性がある処理である.
パイン言語の操作符は,様々な組み合わせと操作数の組み合わせによって表記を形成する. 計算する際の優先順位は? 学校で習った4つの式と同じで,掛け算が優先順位で,掛け算が優先順位で,減算が優先順位で. パイン言語の表記も同じです.
優先順位 | 演算子 |
---|---|
9 | [] |
8 | 単元演算子では,+ 、- そしてnot |
7 | * 、/ 、% |
6 | バイナリー演算子では+ 、- |
5 | > 、< 、>= 、<= |
4 | == 、!= |
3 | and |
2 | or |
1 | ?: |
優先度が高い表現の部分は最初に処理され,優先度が同じ場合は左から右に処理される. 強制的に一部を最初に処理する場合は使用できます.()
この部分式は,この部分式を最初に処理することを強制する式に包まれています.
変数の名前として変数に名前を付ける. だから,変数は保存値の識別子です. では,変数を宣言するにはどうすればいいですか? 変数を宣言するルールは何ですか?
var
│ │ │
2 キーワードを使用するvarip
│ │
3 何も書いてない.
- 类型
FMZ上的Pine语言对于类型要求并不严苛,一般可以省略。不过为了兼容Trading View上的脚本策略,声明变量时也是可以带类型的。例如:
int i = 0 浮遊物 f = 1.1
在Trading View上的类型是要求比较严苛的,如果使用以下代码在Trading View上则会报错:
baseLine0 = na //コンパイル時のエラー!
- 标识符
标识符即变量名称,标识符的命名在之前章节已经讲过,可以回看:https://www.fmz.com/bbs-topic/9390#%E6%A0%87%E8%AF%86%E7%AC%A6
总结一下,声明一个变量可以写作:
変数値の定義は 宣言パターン タイプ アイデンティティ = 値
这里使用赋值运算符:```=```在变量声明时给变量赋值。赋值时,值可以是字符串、数值、表达式、函数调用、```if```、 ```for```、```while```或```switch```等结构(这些结构关键字、语句用法我们后续课程中会详细讲解,其实我们已经在之前的课程里学会了简单的if语句赋值,可以回顾看看)。
这里我们着重讲解一下input函数,这个函数是我们在设计编写策略时会很频繁用到的一个函数。也是设计策略时非常关键的函数。
**input函数:**
input関数,参数defval,title,tooltip,inline,group
在FMZ上的input函数和在Trading View上的有些不同,不过该函数都是作为策略参数的赋值输入使用。下面我们来通过一个例子详细说明input函数在FMZ上的使用:
```pine
param1 = input(10, title="参数1名称", tooltip="参数1的描述信息", group="分组名称A")
param2 = input("close", title="参数2名称", tooltip="参数2的描述信息", group="分组名称A")
param3 = input(color.red, title="参数3名称", tooltip="参数3的描述信息", group="分组名称B")
param4 = input(close, title="参数4名称", tooltip="参数4的描述信息", group="分组名称B")
param5 = input(true, title="参数5名称", tooltip="参数5的描述信息", group="分组名称C")
ma = ta.ema(param4, param1)
plot(ma, title=param2, color=param3, overlay=param5)
変数を宣言する際に変数赋值に通常使用されるのは,input関数である.FMZ上のinput関数は,FMZのポリシーインターフェイスで,ポリシーパラメータを設定するためのコントロールを自動的に描画する.FMZでサポートされているコントローラは,現在数値入力ボックス,テキスト入力ボックス,ドラッグボックス,ブル値チェックなどがあります.また,ポリシーパラメータを分割,パラメータを設定する提示テキスト情報などの機能を設定することができます.
インタラクティブの関数について説明します
単一の変数宣言,赋值に加えて,Pineには変数集合宣言と赋值の書き方もあります:
[变量A,变量B,变量C] = 函数 或者 ```if```、 ```for```、```while```或```switch```等结构
言語の多様性やta.macd
函数が MACD 指標を計算するとき,MACD 指標は多行指標であるため,三つのデータセットを計算します.
[dif,dea,column] = ta.macd(close, 12, 26, 9)
plot(dif, title="dif")
plot(dea, title="dea")
plot(column, title="column", style=plot.style_histogram)
上記のコードを使ってMACDグラフを描くのは簡単です. 組み込み関数で複数の変数を返すだけでなく,書き込みされたカスタム関数で複数のデータを返すこともできます.
twoEMA(data, fastPeriod, slowPeriod) =>
fast = ta.ema(data, fastPeriod)
slow = ta.ema(data, slowPeriod)
[fast, slow]
[ema10, ema20] = twoEMA(close, 10, 20)
plot(ema10, title="ema10", overlay=true)
plot(ema20, title="ema20", overlay=true)
ifのような構造を複数の変数に代入する記述は,上記のカスタム関数と類似しており,試してみることも興味があります.
[ema10, ema20] = if true
fast = ta.ema(close, 10)
slow = ta.ema(close, 20)
[fast, slow]
plot(ema10, title="ema10", color=color.fuchsia, overlay=true)
plot(ema20, title="ema20", color=color.aqua, overlay=true)
いくつかの関数は条件ブランチに記述できない本来のコードブロックに含まれています.
バークローラ (barcolor)) 記号 (fill)) 線 (hline)) 指示 (indicator)) 図 (plot)) 図 (candle)) 図表 (plotchar)) 図形 (plotshape))
Trading Viewではエラー報告をまとめます.FMZでは制限がそれほど厳しくありませんが,Trading Viewの記述規範に従うこともお勧めします.例えば,FMZではエラー報告はしませんが,このように書くことはお勧めしません.
strategy("test", overlay=true)
if close > open
plot(close, title="close")
else
plot(open, title="open")