Type/to search
8
Follow
1364
Followers
Inventor Quantitative PINE 言語入門チュートリアル
Tutorials
Created 2022-05-30 16:23:43  Updated 2022-09-28 17:10:21
 0
 12336

Inventor Quantitative PINE 言語入門チュートリアル

ビデオチュートリアル:
トレーディングビューでPine言語を導入するのは難しいのか?

発明者量化取引プラットフォームは,Pine言語の策略作成をサポートし,反省をサポートし,Pine言語の策略を实体的に実行し,Pine言語の低バージョンを互換性がある. 発明者量化取引プラットフォームのFMZ.COMで戦略スクエア複数のPine戦略 (脚本) が集まって移植されています.

FMZは,Pine言語だけでなく,Pine言語の強力なグラフ機能をサポートしています.FMZプラットフォームのさまざまな機能,豊富な実用的なツール,高効率で簡単な管理,さらにPine戦略の実用性を強化しています.FMZは,Pine言語の互換性に基づいています.同時に,Pine言語の拡張,最適化,裁剪を一定程度に行っています.公式にチュートリアルに入る前に,FMZのPine言語と元のPineの変更点を見てみましょう.

簡単な例を挙げると,

  • 1 FMZ上のPine戦略,コードの先頭にバージョンの識別//@versionプログラムで開始します.strategyindicator文は書き込みの必要性がないので,FMZは一時的にサポートしません.import輸入するlibrary関数。

    戦略のいくつかはこう書かれています.

    pine
    //@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)

    ツイッターにはこんな記事があります.

    pine
    //@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では以下のように簡略化できます.

    pine
    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)

    答えは"はい"です

    pine
    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言語取引類別庫のテンプレートのパラメータを設定します.

      img

    • 戦略の実行時の価格,下位注文量などの数値の精度制御は,FMZ上で指定する必要がある.
      トレーディングビューでは模擬テストしかできないため,実物での注文時刻の精度問題はありません.FMZでは実物でのPine戦略を実行できます.その場合は,取引品種の価格精度,注文数精度を柔軟に指定できる戦略が必要です.これらの精度設定は,関連するデータの小数値を制御し,データが取引所報告書要求事項に適合しないことを避け,注文ができないことを防ぐことです.

    • 期貨契約のコード
      FMZ上の取引品種は,契約である場合,2つの属性がある.分別は"取引ペア"と"契約コード"であり,実盤と回測時に取引ペアを明確に設定する必要に加えて",Pine言語取引類別庫"のテンプレートのパラメータ"品種コード"で具体的な契約コードを設定する必要があります.例えば,永続契約は記入します.swap契約コードは,取引所がそのような契約を持っているかどうかによって異なります.例えば,取引所のすべての四半期契約は,ここに記入できます.quarter┃ これらの契約コードは,FMZのJavascript/python/c++言語API文書で定義された期貨契約コードと一致する。

    他の設定は,最小の単数,デフォルトの単数など,Pine言語のドキュメントを参照してください."Pine言語の交換クラスデータベース"パラメータの紹介

  • 3、runtime.debugruntime.logruntime.errorFMZの拡張関数で,デビュケーションに使用する。

    FMZプラットフォームでは,デビューするための3つの関数が追加されました.

    • runtime.debug: コントロールで変数情報をプリントするには,一般的にこの関数は使用できません。

    • runtime.log: 日記で出力する内容。FMZ PINE言語特有の関数。

      pine
      runtime.log(1, 2, 3, close, high, ...),可以传多个参数。
    • runtime.error: を呼び出すと,実行時にエラーが発生し,messageパラメータで指定されたエラーメッセージが付きます.

      pine
      runtime.error(message)
  • 4 図の部分に拡張されたoverlayパラメータ

    FMZ上のPine言語,図形関数plotplotshapeplotchar増えたoverlayパラメータのサポートにより,主図または副図に指定することができます.overlay設定true主図に描かれたfalse副図で描く.FMZ上のPine戦略が実行される時に主図と副図を同時に描くことができる.

  • 5、syminfo.mintick組み込み変数の取値

    syminfo.mintick組み込み変数は,現在の品種の最小測定値として定義される.確定オファー/バックテストインタフェースの"Pine言語の取引クラスデータベース"のテンプレートパラメータの価格設定精度は,この値を制御できます.価格設定精度は2です.これは,取引時の価格が小数点2位まで正確であり,このとき価格の最小変動単位は0.01です.syminfo.mintick0.01 でした.

    1. FMZ PINE Scriptの平均価格は手数料を含む価格である

    例えば:下落価格は8000,販売方向,数量1枚 ((1枚),取引後の平均価格は8000,以下 ((費用には手数料が含まれている) 。

パイン言語の基礎

パイン言語の基礎を習い始めたとき,おそらくいくつかの例の命令,コードの文法には慣れていないだろう。理解できないのは問題ない,まずは概念に慣れ,テストの目的を理解し,FMZのパイン言語のドキュメントを閲覧することもできます。それからチュートリアルにステップ・ステップで慣れていく.

モデル実行

パイン言語のスクリプトの実行プロセスなどの関連概念を理解することが非常に必要である. パイン言語の策略は,グラフに基づいて動作し,グラフ上で時間序列の先後順序でグラフに既にロードされている最早のデータから実行される一連の計算と操作として理解できる. グラフに最初にロードされるデータの量は有限である. リアルディスクでは通常このデータ制限は,取引所インターフェースに戻された最大データ量に基づいて決定され,戻った時測定データの制限は,回測システムデータソースから提供されたデータに基づいて決定される. グラフの最左の最初の行,すなわちグラフのデータセットの1つであるKBarは,Pine言語の内置変数によってインデックスされる値が0である.bar_indexPineスクリプトの実行時に現在のKラインBarのインデックス値を参照する.

pine
plot(bar_index, "bar_index")

img

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回しか実行されません.
    策略を"実値モデル"として設定すると,実時バーの計算と歴史バーは全く異なる.実物バーの動きごとに策略コードが実行される.例えば,内置変数highlowclose歴史バーでは確定し,リアルタイムバーでは,状況が変化するたびにこれらの値が変化する.したがって,これらの値に基づいて計算された指標などのデータもリアルタイムで変化する.リアルタイムバーではclose価格が常に最新の価格で表示され,highそしてlow常に,現在のリアルバーが開始されてから到達した最高値と最低値を表します.これらの内置変数は,リアルバーが最後に更新された時の最終値を表します.

    リアルタイム・バーで戦略を実行する時の回転メカニズム (リアルタイム・価格モデル):
    リアルタイムバーの実行では,戦略の各新しいエデーションが実行される前に,ユーザ定義の変数をリセットする.これは,リロールと呼ばれる.リロールの仕組みを理解するために,以下のテストコードを例として説明します.

    知らせ:

    /*backtest ... .. . */

    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")

    img

    img

    リアルタイムバーで実行される場面のみを研究したので,not barstate.ishistory表現の制限は,リアルタイムBarでのみ変数nに積分され,積分操作を行う前後に使用されるruntime.log関数出力情報は,策略日誌にあります.plot描いた曲線nは,戦略が歴史バーで実行されているとき,nが常に0であったことがわかります.リアルタイムバーに実行されたとき,nの累積1の操作が引き起こされ,リアルタイムバーで実行された戦略の各ラウンドで,nの累積1の操作が実行されます.ロジ情報から,毎回再実行された戦略コードのnが,前回のBar実行戦略の最終的なコミットメントの値にリセットされていることがわかります.リアルタイムバーは,最後に実行された戦略コードの更新時にnの値を提出します.したがって,グラフ上では,リアルタイムBarから始まり,曲線nは,Barの曲線を増加するたびにnの値が増加していることがわかります.

    結論から言うと

    1. 策略がリアルタイムバーで実行される時,状況更新ごとに策略コードが実行されます.
      2 リアルタイムバーで実行する際には,ポリシーコードが実行される前に変数が回転する.
    2. リアルタイムバーで実行すると,変数はクローズオフ更新時に 1 回提出されます.

    グラフ上の曲線などの描画操作は,データローリングによって再描画される可能性があります.例えば,テストコードを修正して,リールディスクテスト:

    pine
    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のスクリーンショット
    img

    Bのスクリーンショット
    img

    翻訳者は,この文を修正しただけです.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で実行されたテストコードで,この問題を解くことにしました.

    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"}] */ 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)

    回測の動作のスクリーンショット

    img

    テストコードは比較的シンプルで,主に以下の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 <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk>f(close)返される値は

    • plotchar(oneBarInTwo ? f2() : na, title = "f2()", color = color.green, location = location.absolute, style = shape.circle, overlay = true, char = "B")
      文字をB<unk>で,緑色で描いて, 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]

    img

    変数のインデックスを入力します.bar_index"A"と"B"の標識を描画するかどうかを計算する。"A"と"B"の標識は,各 K 線Bar に描画されない。f(a) => a[1]この方法で引用される値は,関数がすべてのBarに呼び出されない場合,関数と関係します.f2() => close[1]この方法では,引用の値が異なる場合でも,[1]のような同じインデックス) 。

  • いくつかの内置関数は,結果を正しく計算するために,各バーで計算する必要があります.

    簡単な例を挙げてみましょう.

    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。を返します.

    図に示すように:

    img

    グラフを描くとき,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)

    img

タイムライン

タイムシーケンスという概念は,Pine言語において非常に重要であり,私たちがPine言語を学ぶときに理解しなければならない概念である.タイムシーケンスとはタイプではなく,時間とともに変数を保存する連続的な値の基本構造である.Pineスクリプトはグラフに基づいていることが分かっているが,グラフで示される最も基本的なものは,K線図である.タイムシーケンス,それぞれの値は,K線Barのタイム<unk>に関連している.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

    テストコード:

    pine
    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には対応するデータがあることがわかります.このテストコードは",リアルタイム価格モデル"と"閉店価格モデル"の区別は,グラフにリアルバーが表示されるかどうかだけではありません.速度を回測するために",閉店価格モデル"の回測テストを使用しています.

    img

    変数 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_index0から始めます.bar_index + 1グラフの上の線は,K線のBarの数です.v2そしてbar_indexツイッターで投稿した記事です.

    img

    このビデオは,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の上と下に表示されていることがわかります.テストや実験の際に,しばしばグラフに情報を出力して観察する必要があるため,学習の過程でこの図のコードを保存できます.

    img

スクリプト構造

一般的な構造

このチュートリアルでは,FMZのPineとTrading ViewのPineの言語の違いについて説明しました. FMZのPineのコードは,バージョン番号を省略できます.indicator()strategy()支持は一時的に停止library()もちろん,以前のPineの脚本と互換性のために,以下のような策略を書き込みました.//@version=5indicator()strategy()設定はこちらからできます.strategy()函数内の传参の設定

<version> <declaration_statement> <code>

<version>バージョン管理情報は省略できます.

コメント

パイン語//単行注釈として,Pine言語に多行注釈がないため,FMZは注釈を拡張した./**/複数行注釈に使う.

コード

スクリプトの注釈やコンパイラ命令の行は文ではなく,スクリプトのアルゴリズムを実装する文である。文は,これらの内容のいずれかである。

  • 変数の宣言
  • 変数の再割り当て
  • 関数宣言
  • 内置関数呼び出し,ユーザ定義関数呼び出し
  • ifforwhileまたはswitch等構造

文は様々な方法で並べられます

  • 一つの行で表現できる文もあります.例えば,ほとんどの変数宣言は,関数呼び出しの1つの行のみを含む,または単行関数宣言である.他のものは,構造のように,局所的なブロックを必要とするため,常に複数の行が必要です.
  • スクリプトの全局的な文言 (つまり,局部的なブロックに属していない部分) は,空格または制表符(tab鍵) 開始。その最初の文字もその行の最初の文字でなければならない。行の最初の位置で始まる行は,定義によりスクリプトの全域の一部となる。
  • 構造または多行関数宣言には常にlocal block。 ローカルブロックは表記符または4つの空白に縮小されなければなりません。 そうでなければ,前行の連続コードとして解析され,つまり前行のコードの連続内容として判断されます。 各ローカルブロックは異なるローカル範囲を定義します。
  • 多数の単行文は,割り切符としてコマ ((,) を使って一行に並べることができる.
  • 文字列は,文字列に注釈を入れてもいいし,注釈だけでもいい.
  • 列を包み込むこともできます (複数行で続きます)

例えば,以下のコードで if 構造を使用する3つの局所ブロック,すなわち,自定義関数声明で1つ,変数声明で2つを含む.

pine
indicator("", "", true) // 声明语句(全局范围),可以省略不写 barIsUp() => // 函数声明(全局范围) close > open // 本地块(本地范围) plotColor = if barIsUp() // 变量声明 (全局范围) color.green // 本地块 (本地范围) else color.red // 本地块 (本地范围) runtime.log("color", color = plotColor) // 调用一个内置函数输出日志 (全局范围)

コードを入れ替える

長行は複数の行に分割され,または"包み"上げることができる.包み込まれた行は,4の倍数でない限り,任意の数の空間に収縮しなければならない (これらの境界は局部ブロックに収縮するために使用される).

pine
a = open + high + low + close

包装できるのは (注:各行に縮小する空白の数は4の倍数ではない):

pine
a = open + high + low + close

長いplot ((() の呼び出しは,

pine
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つ以上の縮小で始めなければならない (例えば:

pine
test(c, o) => ret = c > o ? (c > o+5000 ? 1 : 0): (c < o-5000 ? -1 : 0) a = test(close, open) plot(a, title="a")

識別子と演算子

アイデンティティ

変数を知る前に,まず<unk>の識別子<unk>の概念を理解する必要があります.関数そして変数について変数,関数,または関数の名前) について.関数<unk>の識別子である<unk>を学ぶのは,まず<unk>の識別子である<unk>を学ぶことです.

    1. 標識は大文字で(A-Z)または 小文字で(a-z)文字か下線か(_)初め,識別子の最初の文字である。
  • 2 識別子の最初の文字の次に続く文字はアルファベット下線するまたは数字について
  • 3 識別子の名前は大文字で区分する。

例えば,以下のような名称の識別子:

pine
fmzVar _fmzVar fmz666Var funcName MAX_LEN max_len maxLen 3barsDown // 错误的命名!使用了数字字符作为标识符的开头字符

ほとんどのプログラミング言語と同様に,Pine言語にも書き込みの推奨があります.通常,識別子の命名時に推奨されるのは:

  • 1、全ての文字を大文字で定数を命名する。
    1. 使用小驼峰のルール他の識別子に用いられる名称.
pine
// 命名变量、常量 GREEN_COLOR = #4CAF50 MAX_LOOKBACK = 100 int fastLength = 7 // 命名函数 zeroOne(boolValue) => boolValue ? 1 : 0

オペレーター

オペレーターは,プログラミング言語で表現を構成するために使用されるいくつかの演算符であり,表現は,策略を書き込むときに何らかの計算目的のために設計された計算規則である.Pine言語のオペレータは,機能によって次のように分類される.

代入演算子,算数演算子,比較演算子,論理演算子,? : 3次元の演算子[]引用経緯演算子

算数演算子で*例えば,Trading View上のPine言語演算子による返却結果によるタイプ問題とは異なり,以下のテストコードがあります.

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) である. その他の変数bcdFMZの反射システムでテストできる,図で結果がわかる.

:=既存の変数に値を再割り当てるために使用され,単純に:=オペレーターは,すでに宣言された,初期化された変数の値を修正するために使用される.
使用されている場合:=オペレーターは,初期化されていない変数または宣言されていない変数に値を与えると,エラーが発生します. 例えば:

pine
a := 0

ありがとうございました.:=代入演算子は,一般に,既存の変数に対する再代入に使用される.例えば:

pine
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つのキーワードを拡張する必要があります.varvarip

  • var

    このキーワードは,以前にも紹介されていたが,詳しくは説明されていない. このキーワードの説明をご覧ください.

    var は,割り当ておよび単一の初期化変数のためのキーワードである.通常,var というキーワードを含まない変数赋值の文法により,データ更新ごとに変数の値が覆われる.逆に,var というキーワードを使用すると,変数が割り当てられ,データ更新にもかかわらず,その状態は保持される.

    bの値の定義は,bの値の定義の定義と同じです.varキーワード:

    pine
    a = close > open var b = 0 if a b := b + 1 plot(b)

    varキーワードは,b変数に最初の一次赋值のみを実行させ,その後,策略論理を実行するたびにbを0に再置くことはなく,実行時に描かれた線からbを観察することができる.つまり,現在のK線BAR時に発生した陽線BARの数を測るためである.

    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")

    変数 'a' は,シリーズの最初の柱線の終値を維持する.
    変数 'b' は,シリーズで最初の<unk>緑色の<unk>の値棒の終値を維持する.
    変数 'c' は,シリーズ第10の<unk>緑の<unk>の終盤価格を維持している.

  • varip

    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線段階では, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは, リアルタイム価格モデルでは,varvarip声明の変数iii策略コードの実行毎に増加操作が実行されます。したがって,反測結果の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が表示されます.

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言語と少し違います.FMZ上のPine言語は,変数タイプの要求に対してそれほど苛酷で厳格ではありません.例えば:

pine
a = 1 * "1.1" b = "1" / "1.1" c = 5 % "A" plot(a) plot(b) plot(c)

FMZでは実行可能だが,trading viewではタイプエラーが報告される.算数演算子の両側の操作数が文字列である場合,システムは文字列を数値に変換して計算する.非数値文字列が計算できない場合,システム操作結果は空値naである.


比較演算子

比較演算子は二進数演算子である。

オペレーター例示する
<小さい
>より大きい
<=これは,この式で,
>=これは,xの2乗です.
==相当する
!=格差がある

テスト例:

pine
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

比較演算子を使うのは簡単ですが, 策略を書く時に最も多く使う演算子です. 値の比較だけでなく, 組み込み変数の比較もできます.closeopen待って。
算数操作符と同様に,FMZ上ではTrading ViewのPineと異なる.FMZには特に厳格な要求型がないので,このような文はd = "1" >= 2 FMZではエラーがなく,実行時に文字列を数値に変換し,比較操作を行う.Trading Viewではエラーが表示されます.


論理演算子
オペレーターコード記号例示する
ないnot単元オペレーター,非演算
そしてandバイナリ演算子,と (そして) 演算
またはorバイナリ演算子,または演算

論理演算子について言えば,真価表について語らなければなりません. 高校で習ったように,ここでは反射システムでテストし,学びます.

pine
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

この例は実用的にはあまり役に立たないが,簡単に説明できます.

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)

このトピックのテーマは,三元式の表現を,このトピックのトピックのトピックと,このトピックのトピックと,このトピックのトピックと,このトピックのトピックと,このトピックのトピックと,このトピックのトピックと,このトピックのトピックと,このトピックのトピックと,このトピックのトピックと,このトピックのトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと,このトピックと

pine
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 : valueWhenConditionIsFalsevalueWhenConditionIsTruevalueWhenConditionIsFalse代わりに別の三元表現を使う.


歴史演算子

過去演算子を使用する[],引用時間序列上の歴史値。これらの歴史値は,スクリプトが実行される時点の現在のKラインBAR前のKラインBAR上の変数である。[]変数,式,関数呼び出しの後に使用されるオペレータ.[]この方格括弧の値は,私たちが参照する過去データから現在のK線BARの偏移量である.例えば,私がK線BARの閉店価格を引用したい場合は,次のように書きます.close[1]

この記事では,この文の書き方について説明します.

pine
high[10] ta.sma(close, 10)[1] ta.highest(high, 10)[20] close > nz(close[1], open)

[]演算子は同じ値に1回しか使えないので,次のように書くのは誤りです.

pine
a = close[1][2] // 错误

操作は,この関数で実行されます.[]これは,数列の構造と,数列の構造とほぼ同じです.
下では,Pine言語の系列 (series) と配列 (array) の違いを例で説明する.

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]記事の内容はこうです.

pine
b = close[1] c = b[1]

文字列の定義は,文字列の定義の定義の定義の定義の定義の定義の定義の定義の定義です.b = close[1]しかし,bは,bが,bが,bが,bが,bが,bが,bが,bが,bが,bが,bが,bが,bが,bが,bが,c = b[1],b は,歴史操作で再び歴史値を引用することができる.Pine言語の系列 (series) の概念は,数列ほど単純ではないことがわかります. close の上Bar上の歴史値 (b に与えられた値) として理解できます.b は,時間序列構造 (time series) であるため,その歴史値を引用し続けることができます.

図の左端を引っ張って,最初の K 線で b と c の値が空値 ((na) であることを確認できます. それは,スクリプトが最初の K 線 BAR で実行するときに,前へ引用する 1 または 2 周期の歴史値は存在しないからです. だから,歴史データを引用するときに空値が引用されるかどうか,戦略を記述する際に常に注意する必要があります. 慎重でない場合,空値を使用すると,一連の計算の違いが生じ,実際の BAR にさえ影響を与える可能性があります. 通常,私たちはコードで使用します.nanzこの関数は,この関数と関数関数で割り切れます.nzna函数,どの章を覚えていますか?) のような空の値の扱いを具体化します.

pine
close > nz(close[1], open) // 当引用close内置变量前一个BAR的历史值时,如果不存在,则使用open内置变量

これは, null に引用される可能性のある ((na) の処理である.


オペレーターの優先順位

私たちは,Pine言語の多くの演算子を学びました.これらの演算子は,演算数と様々な組み合わせによって表現を形成します. では,表現で計算するときに,これらの演算の優先順位はどのようなものですか?

優先するオペレーター
9[]
8一元演算子で +- `` `
7*/%
6バイナリオペレータでは +、``-```
5><>=<=
4==!=
3and
2or
1?:

優先度が高い表現の部分で最初に操作し,優先度が同じなら,左から右に操作する.()この部分の式は,まずその部分の演算を強制的に行なうように包み込まれる.

変数について

変数の宣言

変数の名前として変数に名前を付けます. だから,変数は保存値の識別子です. では,変数を宣言するにはどうすればよいですか? 宣言変数はどのようなルールを持っていますか?

  • 声明の形式:
    変数を宣言するときに最初に書くのは"宣言モード"です.変数の宣言モードは以下の3種類があります.

    1. キーワードを使うvar
      2 キーワードを使うことvarip
      3つ目は何も書かないこと.

    varvarip変数の宣言パターンは何も書かない場合,例えば,文:i = 1変数を指定し,その値を与えると,K行BARで実行されます.

  • タイプ
    FMZ上のPine言語は,型に関する要求は厳格ではないため,一般的には省略できる。しかし,Trading View上のスクリプト戦略に適合するため,変数を宣言する際にも型を付けることができる。例えば:

    int i = 0 float f = 1.1

    トレーディングビューのタイプはより厳格な要求であり,以下のコードを使用すると,Trading Viewでエラーが返されます.

    baseLine0 = na // compile time error!
  • アイデンティティ
    識別子は変数名であり,識別子の名称は前章で説明されており,https://www.fmz.com/bbs-topic/9390#标识符を参照してください.

変数の定義は次のように書けます.

// [<declaration_mode>] [<type>] <identifier> = value 声明模式 类型 标识符 = 值

代入演算子を使って=変数宣言時に変数に付与する.付与時に,値は文字列,数値,式,関数呼び出し,ifforwhileまたはswitch構造等 ((これらの構造のキーワード,文の用法については,後回のレッスンで詳しく説明します.実際は,私たちは,以前のレッスンで,簡単なif文の赋值を学んできたので,見直してみてください) 。

ここで,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上のサポートされているコントロールは,現在,数値入力ボックス,テキスト入力ボックス,下落ボックス,ブール値の勾選がある.また,ポリシーパラメータのグループを設定し,パラメータを設定するための提示テキスト情報などの機能を設定することができます.

img

入力関数の主要パラメータは以下の通りです.

  • defval: パイン言語の組み込み変数,数値,文字列をサポートする,入力関数として設定されたポリシーパラメータオプションのデフォルト値
  • title: リアルディスク/反測のポリシーインターフェイスで表示されるパラメータの名前
  • tooltip: 策略パラメータの提示メッセージ,マウスが策略パラメータにハグされたときに,このパラメータの設定に関するテキスト情報が表示されます.
  • group: ポリシーのパラメータグループ名,パラメータグループに与えることができる。

単一の変数宣言,赋值に加えて,Pine言語には,変数の集合を宣言し,付与する書き方もある.

[变量A,变量B,变量C] = 函数 或者 ```if```、 ```for```、```while```或```switch```等结构

言語は 言語とは違うta.macd関数が MACD インデクタを計算するとき,MACD インデクタは多線インデクタであるため,三組のデータを計算する.したがって,次のように書ける:

pine
[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 グラフを描くことは簡単です. 組み込み関数は複数の変数を返します. 書き込み関数は複数のデータを返します.

pine
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(), plotcandle(), plotchar(), plotshape()

Trading Viewでは誤報をコンパイルする。FMZの制限はそれほど厳格ではないが,Trading Viewの規範に従って書くこともお勧めする。例えば,FMZでは誤報は行わないが,こんな書き方はお勧めしない。

pine
strategy("test", overlay=true) if close > open plot(close, title="close") else plot(open, title="open")

if 文について

ビデオの"つで

pine
var lineColor = na n = if bar_index > 10 and bar_index <= 20 lineColor := color.green else if bar_index > 20 and bar_index <= 30 lineColor := color.blue else if bar_index > 30 and bar_index <= 40 lineColor := color.orange else if bar_index > 40 lineColor := color.black else lineColor := color.red plot(close, title="close", color=n, linewidth=5, overlay=true) plotchar(true, title="bar_index", char=str.tostring(bar_index), location=location.abovebar, color=color.red, overlay=true)

重点:判断用式は,ブール値を返します。縮小注意。最大1つのelse分岐のみがあります。すべての分岐式は真ではないし,else分岐もなければ,naを返します。

pine
x = if close > open close plot(x, title="x")

K線BARが陰線であるとき,つまりclose < openであるとき,if文の後に表される式はfalseであるため,ifのローカルコードブロックは実行されません。このときもelseの分岐はありませんので,if文はnaを返します。xがnaに代入されます。この点を図面で描画することはできません.また,図面の反測でも見ることができます。

switch 文について

switch文は,また,特定の条件に応じて異なる経路を実行するように設計するために使用される分岐構造の文である. スイッチ文には,一般的に以下のいくつかの重要な知識点があります.

1 ,switch 文は if 文と同様に,値を返します。
2. 他の言語のswitch文とは異なり,switch構造を実行するときは,そのコードの1つのローカルブロックのみを実行するので,break宣言は不要である (つまり,breakなどのキーワードを書く必要はありません).
3. switch の各分支は 1 つのローカルブロックを書き込むことができます. このローカルブロックの最後の行は,返される値 ((これは 1 つの値の元群である) になります). もし,分支が実行されたローカルブロックがなければ,返されるのは na になります.
4. スイッチ構造内の表現判断位置,文字列,変数,表現または関数呼び出しを記述できる.
5. switch は,構造で他の状況がない場合に使用するデフォルト値として返される値を指定します.

switchは2つの形式に分かれていますが,例を一つずつ見ていきましょう.

1 表現されたswitch記事の内容は以下の通りです.

pine
// input.string: defval, title, options, tooltip func = input.string("EMA", title="指标名称", tooltip="选择要使用的指标函数名称", options=["EMA", "SMA", "RMA", "WMA"]) // input.int: defval, title, options, tooltip // param1 = input.int(10, title="周期参数") fastPeriod = input.int(10, title="快线周期参数", options=[5, 10, 20]) slowPeriod = input.int(20, title="慢线周期参数", options=[20, 25, 30]) data = input(close, title="数据", tooltip="选择使用收盘价、开盘价、最高价...") fastColor = color.red slowColor = color.red [fast, slow] = switch func "EMA" => fastLine = ta.ema(data, fastPeriod) slowLine = ta.ema(data, slowPeriod) fastColor := color.red slowColor := color.red [fastLine, slowLine] "SMA" => fastLine = ta.sma(data, fastPeriod) slowLine = ta.sma(data, slowPeriod) fastColor := color.green slowColor := color.green [fastLine, slowLine] "RMA" => fastLine = ta.rma(data, fastPeriod) slowLine = ta.rma(data, slowPeriod) fastColor := color.blue slowColor := color.blue [fastLine, slowLine] => runtime.error("error") plot(fast, title="fast" + fastPeriod, color=fastColor, overlay=true) plot(slow, title="slow" + slowPeriod, color=slowColor, overlay=true)

このビデオでは,inputの2つの関数について学びます.input.stringinput.int関数。
input.string文字列を返します.input.intこの関数は整数値を返します.options参数を使うことoptions参数は,選択可能な値で構成される配列に転送できます.例えば,例のoptions=["EMA", "SMA", "RMA", "WMA"]そしてoptions=[5, 10, 20](注: 1 つは文字列型, 1 つは数値型) 。 このように,ポリシーインターフェースのコントロールは,特定の数値を入力する必要がなく,コントロールは,optionsパラメータで提供されるこれらのオプションを選択する下方ドラッグボックスになります。

変数funcの値は,switchの表現である (((変数,関数呼び出し,表現) の変数funcという文字列で,switchのどの支部が実行されているかを決定します.変数funcが,switchのどの支部の表現と一致しない場合 (つまり等しい場合),デフォルトの支部コードブロックを実行し,実行されます.runtime.error("error")この関数は, 策略が例外を投げるのを停止させる.

runtime.errorの最後の行に,switchのデフォルト分岐のコードブロックに runtime.errorの最後の行に,switchのデフォルト分岐のコードブロックに runtime.errorの最後の行に,switchのデフォルト分岐のコードブロックに runtime.errorの最後の行に,switchのデフォルト分岐のコードブロックに runtime.errorの最後の行に,switchのデフォルト分岐のコードブロックに runtime.errorの最後の行に,switchのデフォルト分岐のコードブロックに runtime.errorの最後の行に runtime.errorの最後の行に,switchのデフォルト分岐のコードブロックに runtime.errorの最後の行に runtime.errorの最後の行に,switchのデフォルト分岐のコードブロックに runtime.errorの最後の行に runtime.errorの最後の行に runtime.errorの最後の行に runtime.errorの最後の行に runtime.errorの最後の行に runtime.erに runtime.[na,na] のようなコードが返値を互換にするには,trading view でこの問題を考慮する必要があり,タイプが一致しない場合はエラーが報われる。しかし,FMZ で厳格に要求されるタイプがないので,この互換性コードを省略することができます。したがって,FMZ で if,switch 分岐返値のタイプ互換性問題を考慮する必要はありません。

pine
strategy("test", overlay=true) x = if close > open close else "open" plotchar(true, title="x", char=str.tostring(x), location=location.abovebar, color=color.red)

FMZではエラーが表示されないが,Trading Viewではエラーが表示される.ifの分岐が返されるタイプが一致しないからです.

2 表現されていないswitch

このビデオでは,switch表現を伴わない書法である.

pine
up = close > open // up = close < open down = close < open var upOfCount = 0 var downOfCount = 0 msgColor = switch up => upOfCount += 1 color.green down => downOfCount += 1 color.red plotchar(up, title="up", char=str.tostring(upOfCount), location=location.abovebar, color=msgColor, overlay=true) plotchar(down, title="down", char=str.tostring(downOfCount), location=location.belowbar, color=msgColor, overlay=true)

テストコード例では,switchが実行分岐条件で実在するローカルコードブロックにマッチする事がわかります.一般的には,switch文の後に続く分岐条件は相互排斥的である必要があります.つまり,例ではupとdownが同時にtrueであることはできません.switchが1つの分岐のローカルコードブロックのみを実行できるので,興味のある方は,次の文をコードで行えます.up = close > open // up = close < open コメントの内容を書き換えて,観察した結果を反省します。switch 支部は最初の支部のみを実行することがわかります。さらに注意が必要なのは,関数呼び出しをswitch の支部に書き込まないようにすること.関数は,各 BAR に呼び出されることがないため,いくつかのデータ計算問題を引き起こす可能性があります.switch"例では,実行分岐は確定し,戦略の実行中に変更されません.

循環構造

for 文について

返回值 = for 计数 = 起始计数 to 最终计数 by 步长 语句 // 注释:语句里可以有break,continue 语句 // 注释:最后一条语句为返回值

for 文は非常にシンプルで, for ループは最終的に 1 つの値 (() を返すか,複数の値を返すか,[a,b,c] のような形式) 。上記の偽コードで"返り値"の位置に値を割り当てている変数。for文の後には,ループ回数を制御する,他の値を引用するなどに使われる"カウント"の変数。"カウント"の変数は,ループが始まる前に"初期カウント"に値が付けられ,それから"ペース"の設定に従って増加し",カウント"の変数が"最終カウント"より大きいときにループが停止する。

for ループで使用されるbreakキーワード:実行されたときbreak文が終わると,循環は止まります.
for ループで使用されるcontinueキーワード:実行されたときcontinue文の後に,ループは無視されます.continueその後のコードは,次のループを直接実行する。for 文は,最後のループの実行時に返された値を返します。もしコードが実行されていなければ, null を返します。

簡単な例を挙げてみましょう.

pine
ret = for i = 0 to 10 // 可以增加by关键字修改步长,暂时FMZ不支持 i = 10 to 0 这样的反向循环 // 可以增加条件设置,使用continue跳过,break跳出 runtime.log("i:", i) i // 如果这行不写,就返回空值,因为没有可返回的变量 runtime.log("ret:", ret) runtime.error("stop")

for ... in 文について

for ... in文には2つの形式があり,以下の偽コードで説明する。

返回值 = for 数组元素 in 数组 语句 // 注释:语句里可以有break,continue 语句 // 注释:最后一条语句为返回值
返回值 = for [索引变量, 索引变量对应的数组元素] in 数组 语句 // 注释:语句里可以有break,continue 语句 // 注释:最后一条语句为返回值

2つの形式の主な違いは,forキーワードの後に続く内容にあることがわかります.一つは,変数を使用して配列要素を引用する変数である。一つは,インデックス変数を含む配列要素変数の元組の構造を使用して引用する。もう一つは,返値ルール,break,continueなどのルールとforループに一致している。また,簡単な例で説明します。

pine
testArray = array.from(10, 20, 30, 40, 50, 60, 70, 80, 90, 100) for ele in testArray // 修改成 [i, ele]的形式:for [i, ele] in testArray , runtime.log("ele:", ele, ", i:", i) runtime.log("ele:", ele) runtime.error("stop")

インデックスを必要とする場合for [i, ele] in testArray書き方について

for 循環利用

パイン言語で提供される内置関数を使っていくつかの循環論理計算を行うとき,循環構造を使って直接書き込むことも,内置関数を使って処理することもできます. 例を2つ挙げましょう.

1 平均値を計算する

循環構造の設計では

pine
length = 5 var a = array.new(length) array.push(a, close) if array.size(a) >= length array.remove(a, 0) sum = 0 for ele in a sum += ele avg = sum / length plot(avg, title="avg", overlay=true)

この例では,for 回転加算を用いて,平均値を計算した.

平均線は,内置関数を使って直接計算します.

pine
plot(ta.sma(close, length), title="ta.sma", overlay=true)

組み込みの関数を使用するta.sma平均線指標を計算するには,明らかに平均線を計算するために内置関数を使用することがより簡単である。グラフ上の対比では,計算された結果が完全に一致していることがわかります。

2 求和する

上の例を使って説明しましょう.

循環構造の設計では

pine
length = 5 var a = array.new(length) array.push(a, close) if array.size(a) >= length array.remove(a, 0) sum = 0 for ele in a sum += ele avg = sum / length plot(avg, title="avg", overlay=true) plot(ta.sma(close, length), title="ta.sma", overlay=true)

配列のすべての要素の和を計算するには,ループを使用することもできます.array.sum計算してみましょう
組み込み関数を直接使って加算を計算する:

pine
length = 5 var a = array.new(length) array.push(a, close) if array.size(a) >= length array.remove(a, 0) plot(array.sum(a) / length, title="avg", overlay=true) plot(ta.sma(close, length), title="ta.sma", overlay=true)

計算したデータを見れば,プロット図を用いてグラフに完全に一致していることがわかります.

ループの設計は,主に以下の3つの用途に基づいています.

  1. 配列のいくつかの操作,計算について.
  2. 過去を振り返り,例えば,現在のBARの高点より過去の高点がどのくらい高いかを調べる.現在のBARの高点は,スクリプトが実行しているBARでしか知られていないので,過去BARにタイムリーで戻り,分析するためにループが必要である.
  3. パイン言語の内置関数が過去BARの計算を完了できない場合.

while 文について

while文は,ループ部分のコードが,while構造の判断条件が false (false) であるまで実行されるようにします.

返回值 = while 判断条件 语句 // 注释:语句里可以有break,continue 语句 // 注释:最后一条语句为返回值

whileの他のルールはforループに似ており,ループ体ローカルコードブロックの最後の行が返値であり,複数の値を返せます。"ループ条件"が真である場合にループを実行し,条件が偽である場合にループを停止します。ループ体内でbreak,continue文も使用できます。

平均線を計算した例で説明します.

pine
length = 10 sma(data, length) => i = 0 sum = 0 while i < 10 sum += data[i] i += 1 sum / length plot(sma(close, length), title="sma", overlay=true) plot(ta.sma(close, length), title="ta.sma", overlay=true)

循环の利用も非常に簡単であり,組み込み関数で代替できない計算論理を設計することもできます.例えば,階乗を計算する:

pine
counter = 5 fact = 1 ret = while counter > 0 fact := fact * counter counter := counter - 1 fact plot(ret, title="ret") // ret = 5 * 4 * 3 * 2 * 1

グループ

Pine言語の数列は,他のプログラミング言語の数列の定義に似ています.Pineの数列は,一次元数列である。通常,連続した一連のデータを格納するために使用される。数列の格納される単一のデータは,数列の要素と呼ばれます.これらの要素のタイプは,整型,浮点型,文字列,色値,ブル値である。FMZのPine言語は,型をあまり厳格に要求しないし,一つの数列の中に文字列と数値を同時に格納することもできます。数列の底層も連続構造であるため,もし歴史演算符を用いた場合,前 BAR上の数列の状態が引用されている。したがって,数列の特定の要素を引用するときに歴史演算子は使用されません.[]必要なものなのですarray.get()そしてarray.set()函数。 配列内の要素のインデックス順序は,配列の最初の要素のインデックスが0で,次の要素のインデックスが増加して1。

簡単なコードで説明します.

pine
var a = array.from(0) if bar_index == 0 runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1]) else if bar_index == 1 array.push(a, bar_index) runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1]) else if bar_index == 2 array.push(a, bar_index) runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1], ", 向前数2根BAR上的a,即a[2]值:", a[2]) else if bar_index == 3 array.push(a, bar_index) runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1], ", 向前数2根BAR上的a,即a[2]值:", a[2], ", 向前数3根BAR上的a,即a[3]值:", a[3]) else if bar_index == 4 // 使用array.get 按索引获取元素,使用array.set按索引修改元素 runtime.log("数组修改前:", array.get(a, 0), array.get(a, 1), array.get(a, 2), array.get(a, 3)) array.set(a, 1, 999) runtime.log("数组修改后:", array.get(a, 0), array.get(a, 1), array.get(a, 2), array.get(a, 3))

定義された配列

使用array<int> afloat[] b宣言された配列または1つの変数のみを宣言する配列が代入される,例えば:

pine
array<int> a = array.new(3, bar_index) float[] b = array.new(3, close) c = array.from("hello", "fmz", "!") runtime.log("a:", a) runtime.log("b:", b) runtime.log("c:", c) runtime.error("stop")

配列変数を初期化するために一般に使用されるarray.newそしてarray.from函数。Pine言語には,array.newに類似した,型に関連した関数がたくさんあります.array.new_int()array.new_bool()array.new_color()array.new_string()待って。

var キーワードは,配列の宣言パターンにも作用し,var キーワードで宣言された配列は,最初の BAR にのみ初期化されます.

pine
var a = array.from(0) b = array.from(0) if bar_index == 1 array.push(a, bar_index) array.push(b, bar_index) else if bar_index == 2 array.push(a, bar_index) array.push(b, bar_index) else if barstate.islast runtime.log("a:", a) runtime.log("b:", b) runtime.error("stop")

aの配列の変更は,継続的に決定され,再置かれていないことがわかります。bの配列は,各BARで初期化されます。最終的にbarstate.islastリアルタイムで印刷する場合は,数値0の要素のみが残ります.

配列の要素を読み書きする

array.get を使って,配列内のインデックス位置指定の要素を取得し,array.set を使って,配列内のインデックス位置指定の要素を変更する.

array.get の最初のパラメータは処理する配列で,第二のパラメータは指定されたインデックスである.
array.set の最初のパラメータは処理する数列,第二のパラメータは指定されたインデックス,第三のパラメータは書き込むべき要素である.

この簡単な例で説明します.

pine
lookbackInput = input.int(100) FILL_COLOR = color.green var fillColors = array.new(5) if barstate.isfirst array.set(fillColors, 0, color.new(FILL_COLOR, 70)) array.set(fillColors, 1, color.new(FILL_COLOR, 75)) array.set(fillColors, 2, color.new(FILL_COLOR, 80)) array.set(fillColors, 3, color.new(FILL_COLOR, 85)) array.set(fillColors, 4, color.new(FILL_COLOR, 90)) lastHiBar = - ta.highestbars(high, lookbackInput) fillNo = math.min(lastHiBar / (lookbackInput / 5), 4) bgcolor(array.get(fillColors, int(fillNo)), overlay=true) plot(lastHiBar, title="lastHiBar") plot(fillNo, title="fillNo")

この例では,基底色である緑を初期化し,色を保存するための配列を宣言し,初期化し,色値に異なる透明性を付与する (color.new関数を使用する).現在のBAR距離が100回レビュー周期内highの最大値の距離を計算することによって,色級を計算する.最近100回レビュー周期内highの最大値の距離が近いほど,等級が高く,対応する色値はより深い (透明度が低い).多くの類似策は,この方法で現在の価格をN回レビュー周期内レベルに表現する.

配列の要素を巡る

単に"for in"と"for in/while"を組み合わせた数列を"for in"と"while"で表すことができます.

pine
a = array.from(1, 2, 3, 4, 5, 6) for i = 0 to (array.size(a) == 0 ? na : array.size(a) - 1) array.set(a, i, i) runtime.log(a) runtime.error("stop")
pine
a = array.from(1, 2, 3, 4, 5, 6) i = 0 while i < array.size(a) array.set(a, i, i) i += 1 runtime.log(a) runtime.error("stop")
pine
a = array.from(1, 2, 3, 4, 5, 6) for [i, ele] in a array.set(a, i, i) runtime.log(a) runtime.error("stop")

この3つの巡回方法は,同じ結果が得られます.

配列は,スクリプトの全域域で宣言され,関数または if 支部のローカル範囲で宣言され得る.

歴史的データ引用

配列内の要素の使用については,次の方法が等価である.以下の例によって,図に2つの線を描くことがわかります.各グループに2つの線があり,各グループの2つの線の数値はまったく同じである。

pine
a = array.new_float(1) array.set(a, 0, close) closeA1 = array.get(a, 0)[1] closeB1 = close[1] plot(closeA1, "closeA1", color.red, 6) plot(closeB1, "closeB1", color.black, 2) ma1 = ta.sma(array.get(a, 0), 20) ma2 = ta.sma(close, 20) plot(ma1, "ma1", color.aqua, 6) plot(ma2, "ma2", color.black, 2)

配列の追加・削除関数

1 , 配列の加算操作に関連する関数:

array.unshift()array.insert()array.push()

2 配列の削除操作に関連する関数:

array.remove()array.shift()array.pop()array.clear()

この数列の加減関数をテストするには,次の例を使用します.

pine
a = array.from("A", "B", "C") ret = array.unshift(a, "X") runtime.log("数组a:", a, ", ret:", ret) ret := array.insert(a, 1, "Y") runtime.log("数组a:", a, ", ret:", ret) ret := array.push(a, "D") runtime.log("数组a:", a, ", ret:", ret) ret := array.remove(a, 2) runtime.log("数组a:", a, ", ret:", ret) ret := array.shift(a) runtime.log("数组a:", a, ", ret:", ret) ret := array.pop(a) runtime.log("数组a:", a, ", ret:", ret) ret := array.clear(a) runtime.log("数组a:", a, ", ret:", ret) runtime.error("stop")

追加・削除のアプリケーション:配列として配列

配列と配列の追加・削除関数を使って"列"のデータ構造を構成できます. 列は,tick価格の移動平均値の計算に使用できます. クラスメイトが尋ねるかもしれません:なぜ配列の構造を構成するのか?

配列は,プログラミングでよく使われる構造であり,配列の特徴は以下の通りである.

列に入ると列から出る.

この方法で,キューブ内のデータが最新のデータであることを確認し,キューブの長さが無限に膨張しないことを確認できます (無限膨張のコードは,昼間のみで書くことができます,なぜなら,<unk>早<unk>,<unk>晩<unk>が問題になるからです).

以下の例では,各ティックの価格を記録するキュー構造を用いて,ティックレベルの移動平均値を計算し,1分間のK線レベルの移動平均と比較した.

pine
strategy("test", overlay=true) varip a = array.new_float(0) var length = 10 if not barstate.ishistory array.push(a, close) if array.size(a) > length array.shift(a) sum = 0.0 for [index, ele] in a sum += ele avgPrice = array.size(a) == length ? sum / length : na plot(avgPrice, title="avgPrice") plot(ta.sma(close, length), title="ta.sma")

キーワードを指定します.varip│ │ │ │ │ │ │ │ │ │ │ │ │ │ │

よく使われる数列計算,操作関数

関連関数を計算する:

array.avg()配列の全ての要素の平均値を求めます.array.min()配列の最小の要素を探します.array.max()配列の最大の要素を探してarray.stdev()配列の全ての要素の標準差を求めます.array.sum()配列内のすべての要素の和を求めます.

関連関数操作:
array.concat()2つの配列を結合または接続する.
array.copy()配列を複製する
array.join配列内のすべての要素を 1 つの文字列に接続します.
array.sort()順序を順番上り下りして並べます.
array.reverse()逆転数列
array.slice()配列を切断する.
array.includes()判断の要素
array.indexof()参数入力された値が最初に出現したインデックスを返します. 値が見つからない場合は -1 を返します.
array.lastindexof()最後に表示された値を見つけます

配列計算に関連する関数のテスト例:

pine
a = array.from(3, 2, 1, 4, 5, 6, 7, 8, 9) runtime.log("数组a的算数平均:", array.avg(a)) runtime.log("数组a中的最小元素:", array.min(a)) runtime.log("数组a中的最大元素:", array.max(a)) runtime.log("数组a中的标准差:", array.stdev(a)) runtime.log("数组a的所有元素总和:", array.sum(a)) runtime.error("stop")

これらは,比較的によく使われる数列計算関数である。

関連関数の例:

pine
a = array.from(1, 2, 3, 4, 5, 6) b = array.from(11, 2, 13, 4, 15, 6) runtime.log("数组a:", a, ", 数组b:", b) runtime.log("数组a,数组b连接在一起:", array.concat(a, b)) c = array.copy(b) runtime.log("复制一个数组b,赋值给变量c,变量c:", c) runtime.log("使用array.join处理数组c,给每个元素中间增加符号+,连接所有元素结果为字符串:", array.join(c, "+")) runtime.log("排序数组b,按从小到大顺序,使用参数order.ascending:", array.sort(b, order.ascending)) // array.sort函数修改原数组 runtime.log("排序数组b,按从大到小顺序,使用参数order.descending:", array.sort(b, order.descending)) // array.sort函数修改原数组 runtime.log("数组a:", a, ", 数组b:", b) array.reverse(a) // 此函数修改原数组 runtime.log("反转数组a中的所有元素顺序,反转之后数组a为:", a) runtime.log("截取数组a,索引0 ~ 索引3,遵循左闭右开区间规则:", array.slice(a, 0, 3)) runtime.log("在数组b中搜索元素11:", array.includes(b, 11)) runtime.log("在数组a中搜索元素100:", array.includes(a, 100)) runtime.log("将数组a和数组b连接,搜索其中第一次出现元素2的索引位置:", array.indexof(array.concat(a, b), 2), " , 参考观察 array.concat(a, b):", array.concat(a, b)) runtime.log("将数组a和数组b连接,搜索其中最后一次出现元素6的索引位置:", array.lastindexof(array.concat(a, b), 6), " , 参考观察 array.concat(a, b):", array.concat(a, b)) runtime.error("stop")

関数

定義された関数

Pine言語は,カスタム関数を設計することができる.一般的には,Pine言語のカスタム関数は以下のルールを持つ.

  1. すべての関数は,スクリプトの全域で定義される. 一つの関数を別の関数で宣言することはできません.
  2. 函数には自前のコードで自らを呼び出すことを許さない.
    3 原則としてすべてのPINE言語に内蔵された図形関数 (()barcolor()、 fill()、 hline()、plot()、 plotbar()、 plotcandle()) は,カスタム関数の中で呼び出せない。
    4 ,関数は単行または複数行で記述できる.最後の文の返される値は,現在の関数の返される値であり,返される値は元組形式で返される.

単行で設計されたカスタム関数のようなものもあります.

pine
barIsUp() => close > open

この関数は,現在のBARが陽線であるかどうかを返します.

複数の行に指定された関数として設計:

pine
sma(data, length) => i = 0 sum = 0 while i < 10 sum += data[i] i += 1 sum / length plot(sma(close, length), title="sma", overlay=true) plot(ta.sma(close, length), title="ta.sma", overlay=true)

定義された関数で実行した SMA 均線関数です.

また,2つの変数のカスタム関数の例を返します.

pine
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)

一つの関数は,快線,慢線,二つのEMA均線指標を計算できる.

組み込み関数

任意の関数で定義できます.FMZ PINE 文書検索する

Pine言語の内置関数分類:

1 文字列処理関数str.シリーズ
2 色の値処理関数color.シリーズ
3 参数入力関数input.シリーズ
4 指標計算関数ta.シリーズ
グラフ関数plot.シリーズ
6 配列処理関数array.シリーズ
7 取引に関する関数strategy.シリーズ
8 算数関数math.シリーズ
9 ,他の関数 ((時間処理,非プロット系列画図関数,request.シリーズ関数,型処理関数など) 。

トランザクション関数

strategy.シリーズ関数は,設計策略でよく使う関数であり,この関数と策略の具体的実行時に取引操作を実行する関数に関連している.


1、strategy.entry

strategy.entry函数とは,策略を書き込む際により重要な命令関数であり,その関数のより重要な数値は以下の通りである.id, direction, qty, when待って。

パラメータ:

  • id: 特定の取引ポジションに名前を与えることを参照として使用する. このid を引用して,注文を撤回,修正,平仓する.
  • direction: 注文方向が"多めにやる (買おう) "ならこのパラメータが伝わります.strategy.longこの内置変数は,空白の場合は,strategy.shortこの変数は
  • qty: 注文量を指定し,このパラメータを転送しない場合は,デフォルトの注文量となります.
  • when実行条件: このパラメータは,現在の下位操作がトリガーされるかどうかを制御するために指定できます.
  • limit: 指定注文制限価格
  • stopストップ・ロスト・プライス

strategy.entryこの関数の実行詳細はstrategy函数呼び出しのパラメータ設定の制御は,"Pine言語の取引クラスデータベースの模擬版パラメータ"設定制御,Pine言語取引クラスのデータベースモデルのパラメータ制御の取引詳細は,リンクされたドキュメントを参照してください.

この記事では,strategyこの関数では,pyramidingdefault_qty_valueパラメータ: 次のコードでテストします.

pine
/*backtest start: 2022-07-03 00:00:00 end: 2022-07-09 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] */ strategy(title = "open long example", pyramiding = 3, default_qty_value=0.1, overlay=true) ema10 = ta.ema(close, 10) findOrderIdx(idx) => if strategy.opentrades == 0 false else ret = false for i = 0 to strategy.opentrades - 1 if strategy.opentrades.entry_id(i) == idx ret := true break ret if not findOrderIdx("long1") strategy.entry("long1", strategy.long) if not findOrderIdx("long2") strategy.entry("long2", strategy.long, 0.2, when = close > ema10) if not findOrderIdx("long3") strategy.entry("long3", strategy.long, 0.2, limit = low[1]) strategy.entry("long3", strategy.long, 0.3, limit = low[1]) if not findOrderIdx("long4") strategy.entry("long4", strategy.long, 0.2) plot(ema10, title="ema10", color=color.red)

コード開始/*backtest ... */パッケージの一部は反測設定であり,その時の反測設定時間などの情報を記録するために,デビューを容易にするために,策略コードではありません.

コードで:strategy(title = "open long example", pyramiding = 3, default_qty_value=0.1, overlay=true)指定したときにpyramidingこのパラメータが3なら,同じ方向で最大3回取引をします.strategy.entryこの操作は実行されませんでした.default_qty_value<unk>long1<unk>のIDは,この場合,この関数は0.1です.strategy.entry下の命令操作の下の命令数は,0.1。というデフォルトで設定されています.strategy.entryこの関数は,関数で定義される関数です.direction平均でstrategy.longテストの返信は,すべての注文が支払われるのです.

コードに注意してくださいstrategy.entry("long3", ...下のコマンド操作は,同じID:<unk>long3<unk>に対して,2回呼び出されます.strategy.entry下の操作は成功せず,第2回呼び出しstrategy.entry関数は,このIDの注文を修正する ((回測テストで表示されるデータも,この限度注文の下の注文量が0.3のために修正されたことを見ることができる).別の場合,例えば,最初のIDが<unk>long3<unk>の注文で取引された場合,この取引されたID<unk>long3<unk>に従って使用し続けます.strategy.entry函数が注文すると,その注文のポジションはID<unk>long3<unk>に累積されます.


2、strategy.close

strategy.closeこの関数は,平仓指定のIDの入場保有ポジションに使用されます.主なパラメータは以下のとおりです.idwhenqtyqty_percent

パラメータ:

  • idこのページでは,この2つのグループが,この2つのグループで,strategy.entry入場等下場関数開設時に指定されたID。
  • when実行条件:
  • qty:平仓数
  • qty_percent持株率について.

この関数の使い方については,以下の例で説明します.
コードでは/*backtest ... */FMZ.COMの国際ステーションの回測時の設定情報であり,削除し,自分がテストしたい市場,品種,時間範囲などの情報を設定できます.

pine
/*backtest start: 2022-07-03 00:00:00 end: 2022-07-09 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] */ strategy("close Demo", pyramiding=3) var enableStop = false if enableStop runtime.error("stop") strategy.entry("long1", strategy.long, 0.2) if strategy.opentrades >= 3 strategy.close("long1") // 多个入场订单,不指定qty参数,全部平仓 // strategy.close() // 不指定id参数,会平掉当前的持仓 // strategy.close("long2") // 如果指定一个不存在的id则什么都不操作 // strategy.close("long1", qty=0.15) // 指定qty参数平仓 // strategy.close("long1", qty_percent=50) // qty_percent设置50即为平掉long1标识仓位的50%持仓 // strategy.close("long1", qty_percent=80, when=close<open) // 指定when参数,修改为close>open就不触发了 enableStop := true

テスト戦略は,入場IDを<unk>long1<unk>とする3回連続で多入場を開始し,その後使用することを示した.strategy.close函数の異なるパラメータを平仓に設定したときに反測される異なる結果が見られます.strategy.closeこの関数は,平仓の下位注文価格を指定するパラメータがありません.この関数は,主に,即座に現在の市場価格で平仓するために使用されます.


3、strategy.close_all

strategy.close_allこの関数は,現在所有しているすべてのポジションを平らにするため,Pine言語のスクリプトはポジションを1つの方向しか持たないため,つまり,現在のポジションの方向と逆の信号がトリガーされれば,現在のポジションを平らにして,信号に基づいてポジションを開く.strategy.close_all呼び出されると,現在の方向にあるすべてのポジションをクリアする.strategy.close_allこの関数の主要パラメータは:when

パラメータ:

  • when実行条件:

この例を参考にしましょう.

pine
/*backtest start: 2022-07-03 00:00:00 end: 2022-07-09 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] */ strategy("closeAll Demo") var enableStop = false if enableStop runtime.error("stop") strategy.entry("long", strategy.long, 0.2, when=strategy.position_size==0 and close>open) strategy.entry("short", strategy.short, 0.3, when=strategy.position_size>0 and close<open) if strategy.position_size < 0 strategy.close_all() enableStop := true

テストコードは0でスタートします.strategy.position_size==0true) であるため,whenパラメータの設定条件を満たす場合のみ,IDを<unk>long<unk>として実行します.strategy.entry入場関数。多ポジション後strategy.position_size0 以上の場合,ID が short <unk> の入場関数として実行される可能性があります.このとき,多頭ポジションの位置が保持されているため,この空白反転信号が発生し,多頭ポジションの位置が平らになった後に空白を反転させます.strategy.position_size < 0持った空頭持ったとき,現在の持った方向の持った全額を平らにする. そして,マークenableStop := true≫ ≫ ≫ ≫ ≫ ≫

発見しましたstrategy.close_allこの関数は,平仓の下位注文価格を指定するパラメータがありません.この関数は,主に,即座に現在の市場価格で平仓するために使用されます.


4、strategy.exit

strategy.exitこの関数は,入場保有の平仓操作に使用され,この関数とは異なり,strategy.closeそしてstrategy.close_allこの関数は,現在の市場価格で即座に平仓する.strategy.exit関数は,パラメータ設定に基づいて計画平仓を行う.

パラメータ:

  • id: この平仓条件の注文ID.
  • from_entry: 平仓操作を指定するための入口ID。
  • qty:平仓数
  • qty_percent:平仓パーセント,範囲:0~100。
  • profit収益目標はポイントで表されます.
  • lossポイント数で表す.
  • limit収益目標,価格指定について
  • stopストップ・ロズ・ターゲットは,価格で指定する.
  • when実行条件:

各パラメータの使用を理解するためにテスト戦略を使用します.

pine
/*backtest start: 2022-07-03 00:00:00 end: 2022-07-09 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] args: [["RunMode",1,358374],["ZPrecision",0,358374]] */ strategy("strategy.exit Demo", pyramiding=3) varip isExit = false findOrderIdx(idx) => ret = -1 if strategy.opentrades == 0 ret else for i = 0 to strategy.opentrades - 1 if strategy.opentrades.entry_id(i) == idx ret := i break ret strategy.entry("long1", strategy.long, 0.1, limit=1, when=findOrderIdx("long1") < 0) strategy.entry("long2", strategy.long, 0.2, when=findOrderIdx("long2") < 0) strategy.entry("long3", strategy.long, 0.3, when=findOrderIdx("long3") < 0) if not isExit and strategy.opentrades > 0 // strategy.exit("exitAll") // 如果仅仅指定一个id参数,则该退场订单无效,参数profit, limit, loss, stop等出场条件也至少需要设置一个,否则也无效 strategy.exit("exit1", "long1", profit=50) // 由于long1入场订单没有成交,因此ID为exit1的出场订单也处于暂待状态,直到对应的入场订单成交才会放置exit1 strategy.exit("exit2", "long2", qty=0.1, profit=100) // 指定参数qty,平掉ID为long2的持仓中0.1个持仓 strategy.exit("exit3", "long3", qty_percent=50, limit=strategy.opentrades.entry_price(findOrderIdx("long3")) + 1000) // 指定参数qty_percent,平掉ID为long3的持仓中50%的持仓 isExit := true if bar_index == 0 runtime.log("每点价格为:", syminfo.mintick) // 每点价格和Pine语言模板参数上「定价货币精度」参数设置有关

リアルタイム価格モデルの反響テストを使用して,このテスト戦略は,3つの入場操作を実行し始めます.strategy.entry函数), <unk>long1 <unk>を意図的に設定したlimitパラメータは,掛札価格が1で,取引を不可能にします. そして,条件出場関数テストstrategy.exit┃ ポイント数ストップ,価格ストップ,平定定量ポジション,平定比率ストップを使用。 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃strategy.exitこの関数にはさらに複雑な追跡停止パラメータがあります.trail_pricetrail_pointstrail_offsetこの例では,その使い方をテストすることもできます.


5、strategy.cancel

strategy.cancel命令をキャンセル/停止する関数strategy.order, strategy.entry , strategy.exit入場ID を生成できます. この関数の主要パラメータは:idwhen

パラメータ:

  • id取消するID:
  • when実行条件:

この関数はよく理解されるが, 取引されていない入場命令をキャンセルするために用いられる.

pine
/*backtest start: 2022-07-03 00:00:00 end: 2022-07-09 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] */ strategy("strategy.cancel Demo", pyramiding=3) var isStop = false if isStop runtime.error("stop") strategy.entry("long1", strategy.long, 0.1, limit=1) strategy.entry("long2", strategy.long, 0.2, limit=2) strategy.entry("long3", strategy.long, 0.3, limit=3) if not barstate.ishistory and close < open strategy.cancel("long1") strategy.cancel("long2") strategy.cancel("long3") isStop := true

6、strategy.cancel_all

strategy.cancel_all機能とstrategy.cancel函数としては, ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○whenパラメータ

パラメータ:

  • when実行条件:
pine
/*backtest start: 2022-07-03 00:00:00 end: 2022-07-09 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] */ strategy("strategy.cancel Demo", pyramiding=3) var isStop = false if isStop runtime.error("stop") strategy.entry("long1", strategy.long, 0.1, limit=1) strategy.entry("long2", strategy.long, 0.2, limit=2) strategy.entry("long3", strategy.long, 0.3, limit=3) if not barstate.ishistory and close < open strategy.cancel_all() isStop := true

7、strategy.order

strategy.order機能やパラメータの設定はほとんど同じです.strategy.entry共通点として,strategy.orderこの関数は,strategyこれは,関数でpyramidingパラメータ設定の影響,下回数制限なし.

パラメータ:

  • id: 特定の取引ポジションに名前を与えることを参照として使用する. このid を引用して,注文を撤回,修正,平仓する.
  • direction: 注文方向が"多めにやる (買おう) "ならこのパラメータが伝わります.strategy.longこの内置変数は,空白の場合は,strategy.shortこの変数は
  • qty: 注文量を指定し,このパラメータを転送しない場合は,デフォルトの注文量となります.
  • when実行条件: このパラメータは,現在の下位操作がトリガーされるかどうかを制御するために指定できます.
  • limit: 指定注文制限価格
  • stopストップ・ロスト・プライス

実験をしてみましたstrategy.orderこの機能は,次回数に制限はありません.strategy.exit条件退場関数。 格子のような取引を構成するスクリプト。 例は非常に単純で,学習用にのみ:

pine
/*backtest start: 2021-03-01 00:00:00 end: 2022-08-30 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Binance","currency":"ETH_USDT"}] args: [["ZPrecision",0,358374]] */ varip beginPrice = -1 if not barstate.ishistory if beginPrice == -1 or (math.abs(close - beginPrice) > 1000 and strategy.opentrades == 0) beginPrice := close for i = 0 to 20 strategy.order("buy"+i, strategy.long, 0.01, limit=beginPrice-i*200, when=(beginPrice-i*200)<close) strategy.exit("coverBuy"+i, "buy"+i, qty=0.01, profit=200) strategy.order("sell"+i, strategy.short, 0.01, limit=beginPrice+i*200, when=(beginPrice+i*200)>close) strategy.exit("coverSell"+i, "sell"+i, qty=0.01, profit=200)

戦略の例

このチュートリアルの策略の例は,教学策略,指導策略設計アイデアのみに使用され,いかなる取引指導,勧告を行わない. 教学策略は,実用化しないでください.

超トレンド指数戦略

pine
strategy("supertrend", overlay=true) [supertrend, direction] = ta.supertrend(input(5, "factor"), input.int(10, "atrPeriod")) plot(direction < 0 ? supertrend : na, "Up direction", color = color.green, style=plot.style_linebr) plot(direction > 0 ? supertrend : na, "Down direction", color = color.red, style=plot.style_linebr) if direction < 0 if supertrend > supertrend[2] strategy.entry("entry long", strategy.long) else if strategy.position_size < 0 strategy.close_all() else if direction > 0 if supertrend < supertrend[3] strategy.entry("entry short", strategy.short) else if strategy.position_size > 0 strategy.close_all()

パイン言語でトレンド戦略を書くのはとても簡単です. ここでは,スーパートレンド指標を使ってシンプルなトレンド追跡戦略を設計します. この戦略のソースコードを分析しましょう.

まず 戦略のコードが使われますstrategyこの関数は簡単な設定をしますstrategy("supertrend", overlay=true)戦略のタイトルを設定するだけです.overlayパラメータはtrueパイン策略を設計したり, パイン策略のスクリプトを学習したりする際には,まず最初に, 策略のインタフェースパラメータの設計を見て",スーパートレンド指数策略"のソースコードを見てみましょう.input関数

[supertrend, direction] = ta.supertrend(input(5, "factor"), input.int(10, "atrPeriod"))

inputこの関数呼び出しは,ta.supertrend指数関数のパラメータは,超トレンド指数を計算するために使用される.

  • input(5, "factor")
  • input.int(10, "atrPeriod")

函数では,Pine言語のポリシーインターフェイスに2つのパラメータを設定します.

img

制御のデフォルトはinput機能とinputこれは,この関数でinput.int) の最初のパラメータは,前回の章で説明されています. この2つの関数によって,私たちは,ポリシーインターフェースで設定することができます.ta.supertrend超トレンド指数関数は,価格データを計算します.supertrend方向データとdirection│ │ │ │ │plot函数図を描画する際には,超トレンド指標の方向を描画し,現在の方向のみを描画してください.direction逆の方向に動いているとき,directionこの1時間間のトレンドは下向きです.plotグラフを描くときの判断direction0より小さい.

その後のif ... else if論理は取引信号の判断であり,direction < 0超トレンド指数の価格データで,現在の市場が上昇している状態をリアルタイムで示すsupertrend超トレンド指数値の2BARより高い値 (つまりsupertrend[2],还记得历史操作符引用某个变量历史数据吧) を多額の入場シグナルとして使う. 覚えてますか? もし現在持仓があるなら,この時点で逆下令関数呼び出しは,先の持仓を平らにして,現在の取引方向に応じてポジションを開きます.supertrend > supertrend[2]条件が満たされていない場合strategy.position_size < 0投資の利回りも 引き起こすかもしれませんstrategy.close_all()函数を実行し,全平仓を行う。

direction > 0ダウントレンドの段階でも同様で,多頭持っていれば全部平仓し,条件を満たす.supertrend < supertrend[3]"空白信号"を触発すると,[3]前数3行BARの超トレンド指数値の引用は? 策略家が意図的にそうしているのかもしれません.なぜなら,契約取引市場のような市場では,負債のリスクは,多額のリスクよりも少し大きいからです.

のためにta.supertrendこの指標は,現在のトレンドが上昇しているか下落しているかを判断する方法に,興味のある生徒はいるでしょうか?

この指標は,Pine言語のカスタム関数形式で実現できます.

pine
pine_supertrend(factor, atrPeriod) => src = hl2 atr = ta.atr(atrPeriod) upperBand = src + factor * atr lowerBand = src - factor * atr prevLowerBand = nz(lowerBand[1]) prevUpperBand = nz(upperBand[1]) lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand int direction = na float superTrend = na prevSuperTrend = superTrend[1] if na(atr[1]) direction := 1 else if prevSuperTrend == prevUpperBand direction := close > upperBand ? -1 : 1 else direction := close < lowerBand ? 1 : -1 superTrend := direction == -1 ? lowerBand : upperBand [superTrend, direction]

この関数は,この関数と,この関数と,この関数とです.ta.supertrend計算のアルゴリズムも,指数も同じです.
このカスタム関数アルゴリズムから,Pineの内蔵の超トレンド指標は,hl2組み込み変数 ((最高値,最低値が加算され,2で割られる,つまり最高値と最低値の平均値),それからatrPeriodのパラメータに基づいて一定の周期のATR指数 ((波幅) を計算する.hl2とATRを使って上線,下線を構成する.

コード内の三元表現による更新lowerBandそしてupperBand

pine
lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand

lowerBand:下線,上昇傾向が変化しているかどうかを判断する. upperBand:上線,下向き傾向が変化しているかどうかを判断する. lowerBandとupperBandは常に計算され,このカスタム関数だけが現在の傾向方向を最終的に判断する.

pine
else if prevSuperTrend == prevUpperBand direction := close > upperBand ? -1 : 1 else direction := close < lowerBand ? 1 : -1

価格が上昇すると,この値が上昇すると,この値が上昇すると,この値が上昇すると,この値が上昇すると,この値が上昇すると,この値が上昇すると,この値が上昇すると,この値が上昇すると,この値が上昇すると,この値が上昇するとprevUpperBandこの線は,現在の下向きのトレンドを示します.close超えられるupperBand価格が突破し,この時点でトレンドが変化し,上昇トレンドに変換されたと考えられます.direction方向変数は -1 (上向き) に設定されます. そうでない場合は 1 (下向き) に設定されます.if direction < 0信号条件が触発された後,さらにやる.direction > 0信号条件が発動した後に空きをする.

pine
superTrend := direction == -1 ? lowerBand : upperBand [superTrend, direction]

最後に,特定のスーパートレンドの指数値データと方向データを方向によって返します.

ダイナミック・バランス戦略

pine
/*backtest start: 2021-03-01 00:00:00 end: 2022-09-08 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Binance","currency":"ETH_USDT"}] args: [["v_input_1",4374],["v_input_2",3],["v_input_3",300],["ZPrecision",0,358374]] */ varip balance = input(50000, "balance") varip stocks = input(0, "stocks") maxDiffValue = input(1000, "maxDiffValue") if balance - close * stocks > maxDiffValue and not barstate.ishistory // more balance , open long tradeAmount = (balance - close * stocks) / 2 / close strategy.order("long", strategy.long, tradeAmount) balance := balance - tradeAmount * close stocks := stocks + tradeAmount runtime.log("balance:", balance, ", stocks:", stocks, ", tradeAmount:", tradeAmount) else if close * stocks - balance > maxDiffValue and not barstate.ishistory // more stocks , open short tradeAmount = (close * stocks - balance) / 2 / close strategy.order("short", strategy.short, tradeAmount) balance := balance + tradeAmount * close stocks := stocks - tradeAmount runtime.log("balance:", balance, ", stocks:", stocks, ", tradeAmount:", tradeAmount) plot(balance, title="balance value(quoteCurrency)", color=color.red) plot(stocks*close, title="stocks value(quoteCurrency)", color=color.blue)

img

img

ダイナミック・バランス・ストラテジー (ダイナミック・バランス・ストラテジー) とは,BaseCurrency(取引品種) の金額とQuoteCurrency(計価貨幣) の金額は常にバランス処理を行う。どの資産の相対価格が上昇し,口座に保有する価値が増加すれば,どの資産を売却する。ある種の資産の相対価格が低下し,口座に保有する価値が減少すれば,その資産を購入する。これは,ダイナミック・バランス戦略と呼ばれる。その実動的なダイナミック・バランス戦略は,振動的な状況でうまく機能するネット格子戦略となる。しかし,現在,トレンドの状況では,継続的な損失が発生し,価格が戻ってくるのを待つ必要がある.損失を徐々に減らし,利益を出すことができるが,ダイナミック・バランス戦略では,最終的に市場の振動的な動きを捕捉することができる.

欠点は,この戦略の反測グラフで示されているように,価格の大きな傾向が上昇 (または大落下) した段階で,戦略の浮動損失は比較的大きい。したがって,この戦略は現金戦略に優れている. 期貨で使用するには,リスクをよく管理する必要がある。

戦略のコードデザインを見てみましょう.

単純化された設計で 戦略の中で模擬したbalanceQCの資産数とQCの資産数stocks基本通貨の資産数 (BASECURRENCY) のバランス情報です. 口座の実際の資産数を読まないので, 模擬の金額を使って適切な買い,売りを計算するだけです. そして,この動的バランス戦略に影響するグリッドの重要なパラメータはmaxDiffValueこのパラメータはバランスを取るための判断基準です. 現在の価格では,BaseCurrencyそしてQuoteCurrency偏差はmaxDiffValue高価な資産を売り,安価な資産を購入し,資産のバランスを取り戻すのです.

策略取引シグナルのトリガーは,リアルタイムBAR段階で意味を持つ必要があります.したがって,策略取引条件は,if判断に設定されます.not barstate.ishistory価格の計算では,balance価値は超えられていますstocks価値の時に買うこと. 逆に,売る操作を行う. 取引文を実行した後に更新する.balanceそしてstocks変数,そして次のバランストリガー.

策略回帰の情報には,策略回帰の開始時の品種価格が含まれています. 価格は1458です. だから,私はパラメータを設定しました.balance変数として,*3),パラメータ設定stocks3 ◎ 資産をスタート時にバランス状態にします

超トレンドの戦略は ストップ・ロスト・ストップを 追跡する

このビデオで,私たちは,strategy.exitストップ・ストップ・ストップ・ストップ・ストップ・ストップ・ストップ・ストップ・ストップ・ストップ・ストップ・ストップstrategy.exit超トレンドの戦略を最適化するために,関数の追跡停止停止機能.

ビデオをご覧下さいstrategy.exitこの関数の追跡停止停止パラメータは:

1、trail_priceパラメータ: トリガーは,トラッキングストップストップストロー平仓のこの論理的な動作の位置 ((価格で指定した位置) を設定します.
2、trail_offsetパラメータ: ストップ・ストップ・ストップの動作を追跡した後に,置かれた平仓の単位の距離は,最高価格 ((多行時) または最低価格 ((空行時)) からの距離である.
3、trail_pointsパラメータ:trail_price参数,ただ,<unk>優位数で指定された位置である。

学習の理解が難しいかどうかは問題ありません. 学習の理解は, 戦略的な反省のシナリオから始めます. 学習の理解は簡単です.

pine
/*backtest start: 2022-09-23 00:00:00 end: 2022-09-23 08:00:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Binance","currency":"ETH_USDT"}] args: [["RunMode",1,358374],["ZPrecision",0,358374]] */ strategy("test", overlay = true) varip a = na varip highPrice = na varip isTrade = false varip offset = 30 if not barstate.ishistory and not isTrade strategy.entry("test 1", strategy.long, 1) strategy.exit("exit 1", "test 1", 1, trail_price=close+offset, trail_offset=offset) a := close + offset runtime.log("每点价格为:", syminfo.mintick, ",当前close:", close) isTrade := true if close > a and not barstate.ishistory highPrice := na(highPrice) ? close : highPrice highPrice := close > highPrice ? close : highPrice plot(a, "trail_price 触发线") plot(strategy.position_size>0 ? highPrice : na, "当前最高价") plot(strategy.position_size>0 ? highPrice-syminfo.mintick*offset : na, "移动止损触发线")

img

img

img

戦略が実行され始めると,すぐに多頭入場し,次にすぐ入場します.strategy.exit出発注文 ((は,トラッキングストップストップのパラメータを指定している),トレイル_プライストリガーラインを超えた時,トラッキングストップストップのロジックを実行し始め,ストップストップストップライン ((青色) は,最高価格の動態に合わせて調整し始め,青色のラインの位置は,ストップストップストップが平仓を触発する価格であり,最終的にトレイルストップの価格が青色の線を下回ると平仓を触発する。このように組み合わせたグラフに描かれた線は,理解が容易ではありません。

戦略の入場順序を1つだけ指定します. そして,その入場順序を1つだけ指定します.strategy.exit追跡・停止・停止機能は,出場予定表に追加できます.

pine
if not barstate.ishistory and findOrderIdx("open") >= 0 and state == 1 trail_price := strategy.position_size > 0 ? close + offset : close - offset strategy.exit("exit", "open", 1, trail_price=trail_price, trail_offset=offset) runtime.log("每点价格为:", syminfo.mintick, ",当前close:", close, ",trail_price:", trail_price) state := 2 tradeBarIndex := bar_index

完全な戦略コード:

pine
/*backtest start: 2022-05-01 00:00:00 end: 2022-09-27 00:00:00 period: 1d basePeriod: 5m exchanges: [{"eid":"Binance","currency":"ETH_USDT"}] args: [["RunMode",1,358374],["ZPrecision",0,358374]] */ varip trail_price = na varip offset = input(50, "offset") varip tradeBarIndex = 0 // 0 : idle , 1 current_open , 2 current_close varip state = 0 findOrderIdx(idx) => ret = -1 if strategy.opentrades == 0 ret else for i = 0 to strategy.opentrades - 1 if strategy.opentrades.entry_id(i) == idx ret := i break ret if strategy.position_size == 0 trail_price := na state := 0 [superTrendPrice, dir] = ta.supertrend(input(2, "atr系数"), input(20, "atr周期")) if ((dir[1] < 0 and dir[2] > 0) or (superTrendPrice[1] > superTrendPrice[2])) and state == 0 and tradeBarIndex != bar_index strategy.entry("open", strategy.long, 1) state := 1 else if ((dir[1] > 0 and dir[2] < 0) or (superTrendPrice[1] < superTrendPrice[2])) and state == 0 and tradeBarIndex != bar_index strategy.entry("open", strategy.short, 1) state := 1 // 反向信号,全平 if strategy.position_size > 0 and dir[2] < 0 and dir[1] > 0 strategy.cancel_all() strategy.close_all() runtime.log("趋势反转,多头全平") else if strategy.position_size < 0 and dir[2] > 0 and dir[1] < 0 strategy.cancel_all() strategy.close_all() runtime.log("趋势反转,空头全平") if not barstate.ishistory and findOrderIdx("open") >= 0 and state == 1 trail_price := strategy.position_size > 0 ? close + offset : close - offset strategy.exit("exit", "open", 1, trail_price=trail_price, trail_offset=offset) runtime.log("每点价格为:", syminfo.mintick, ",当前close:", close, ",trail_price:", trail_price) state := 2 tradeBarIndex := bar_index plot(superTrendPrice, "superTrendPrice", color=dir>0 ? color.red : color.green, overlay=true)
Related Recommendations
Comment
All comments (0)
No data
No data
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)