資源の読み込みに... 荷物...

FMZ Quant のPINE 言語紹介チュートリアル

作者: リン・ハーンFMZ~リディア, 作成日:2022-09-23 15:23:34, 更新日:2024-02-27 16:47:41

[TOC]

img

FMZ Quant のPINE 言語紹介チュートリアル

サポートビデオチュートリアル:https://www.youtube.com/watch?v=CA3SwJQb_1g

FMZ Quant Trading PlatformはPine言語戦略の書き込み,バックテスト,およびPine言語戦略のライブ取引をサポートし,Pine言語の低バージョンと互換性があります.Pine言語に収集され移植された多くのPine戦略 (スクリプト) があります.戦略広場FMZ 量子取引プラットフォーム (FMZ.COM).

FMZはPine言語だけでなく,Pine言語の強力な描画機能もサポートしています. FMZプラットフォーム上のさまざまな機能,豊かで実用的なツール,効率的で便利な管理は,Pine戦略 (スクリプト) の実行性をさらに高めます.Pine言語との互換性に基づいて,FMZはまた,Pine言語を一定程度拡張,最適化,トリミングします.公式にチュートリアルに入れる前に,元のバージョンと比較してFMZ上のPine言語にどのような変更があったかを見てみましょう.

明らかな違いについて 簡単に説明します.

    1. FMZのPine戦略,コードの初めのバージョン識別子//@versionそしてstrategy, indicatorコードの初めの記述は,書く義務はありません FMZはサポートしませんimport輸入するlibrary今のところ機能している.

    戦略はこう書いています.

    //@version=5
    indicator("My Script", overlay = true)
    src = close
    a = ta.sma(src, 5)
    b = ta.sma(src, 50)
    c = ta.cross(a, b)
    plot(a, color = color.blue)
    plot(b, color = color.black)
    plotshape(c, color = color.red)
    

    あるいはこう書きます:

    //@version=5
    strategy("My Strategy", overlay=true)
    
    longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
    if (longCondition)
        strategy.entry("My Long Entry Id", strategy.long)
    
    shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))
    if (shortCondition)
        strategy.entry("My Short Entry Id", strategy.short)
    

    FMZでは以下のように簡略化できます.

    src = close
    a = ta.sma(src, 5)
    b = ta.sma(src, 50)
    c = ta.cross(a, b)
    plot(a, color = color.blue, overlay=true)
    plot(b, color = color.black, overlay=true)
    plotshape(c, color = color.red, overlay=true)
    

    あるいは

    longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
    if (longCondition)
        strategy.entry("My Long Entry Id", strategy.long)
    
    shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))
    if (shortCondition)
        strategy.entry("My Short Entry Id", strategy.short)
    
    1. 戦略 (スクリプト) のいくつかの取引関連の設定は,FMZ戦略インターフェイス上の"Pine Language Trading Class Library"パラメータによって設定されます.
    • 閉じる価格モデルとリアルタイム価格モデル 取引の見方では,calc_on_every_tickパラメータstrategy価格が毎回変化するときにリアルタイムで戦略ロジックを実行する戦略スクリプトを設定する機能. この時点で,calc_on_every_tickパラメータを設定する必要があります.true.....calc_on_every_tickデフォルトパラメータはfalseつまり,戦略の現在のK線 BARが完全に完了したときにのみ戦略論理が実行されます. FMZでは"Pine Language Trading Class Library"テンプレートのパラメータによって設定されます.

      img

    • 戦略を実行するときに価格と注文金額などの数値精度制御は,FMZで指定する必要があります. FMZでは,Pine戦略を実際の取引で実行することが可能である.その後,戦略は,取引品種の価格正確性と注文金額の正確性を柔軟に指定することが必要です.正確性設定は,データが取引所の注文要件を満たさないようにし,注文を入れることができないようにするために,関連するデータにおける小数点数を制御します.

    • フューチャー契約コード FMZの取引製品が契約である場合は,それぞれ2つの属性があります. Trading PairContract Codeです. 取引ペアを明示的に設定することに加えて,実際の取引とバックテスト中に,Pine Language Trading Class LibraryテンプレートのパラメータVariety Codeに特定の契約コードを設定することも必要です. たとえば,永久契約の場合,swap例えば,いくつかの取引所は四半期契約を持っています.quarterこの契約コードは,FMZの Javascript/python/c++言語 API 文書で定義された先物契約コードと一致します.

    他の設定,例えば最低注文金額,デフォルト注文金額などについては,パラメータの導入を参照してください.松の言語の商用クラス図書館のテンプレート引数パイン言語のドキュメントです

    1. FMZ拡張機能:runtime.debug , runtime.log, runtime.errorデバッグに使われる

    3つの機能が FMZ プラットフォームにデバッグに追加されました.

    • runtime.debug: この機能では通常使用されないコンソールに変数情報を印刷します.

    • runtime.logFMZでPINE言語特有の機能.

      runtime.log(1, 2, 3, close, high, ...), Multiple parameters can be passed.
      
    • runtime.error: 呼び出し時にメッセージパラメータで指定されたエラーメッセージで実行時のエラーが発生します.

      runtime.error(message)
      
    1. についてoverlayパラメータは,いくつかの図面関数で拡張されています

    FMZのPine言語では,図を描く機能がplot, plotshape, plotchar追加しました.overlayパラメータサポートで,メインチャートまたはサブチャート上の図を指定できます.overlay設定されています.trueメインチャートで描くためfalseサブチャートに描くように設定されているため,Pine戦略は FMZでメインチャートとサブチャートを同時に描くことができます.

    1. その価値syminfo.mintick内蔵変数

    組み込み変数syminfo.mintickこの値は,FMZの"Pine Language Trading Class Library"のテンプレートパラメータ価格設定通貨精度によって制御できます.ロボット/バックテスト価格通貨精度設定2は,取引時に価格が二桁の小数点まで正確であり,最低価格変化単位は0.01であることを意味します.syminfo.mintick0.01 になります

    1. FMZの平均価格 パインスクリプトは,すべての佣金を含む

    例えば:注文価格は8000ドル,販売方向は1ロット (片,シート) の量で,取引後の平均価格は8000ドルではなく,8000ドル以下です (コストには手数料が含まれます).

パイン 言語 の 基礎

パイン言語の基礎を学び始めるとき,私たちが知らない指示やコード文法の一些例があるかもしれません.あなたが理解していない場合でも,私たちは最初に概念を熟知し,テストの目的を理解することができます.または指示のためにFMZのパイン言語ドキュメントを確認することができます.その後,さまざまな文法,指示,機能,および組み込み変数に慣れるためにステップごとにチュートリアルに従ってください.

モデル実行

パイン言語学習を開始する際には,パイン言語スクリプトプログラムの実行プロセスなどの関連概念を理解することが非常に必要である. パイン言語戦略はチャートに基づいて実行される. パイン言語戦略は,チャートにロードされた最古のデータから時間系列の順序でチャート上で実行される一連の計算と演算であることが理解できる. チャートで最初にロードされるデータの量は限られている. リアルトレーディングでは,通常,最大量のデータは交換インターフェイスが返した最大データ容量に基づいて決定され,バックテストの際に最大量のデータはバックテストシステムのデータソースによって提供されたデータに基づいて決定される. チャート上の左端のK線バー,すなわちチャートの最初のデータセットは,インデックス値が0である. 現在のK線バーの値は,Pine スクリプトがビルドされた変数で参照されたときにインデックス値が0である.bar_indexパイン語です

plot(bar_index, "bar_index")

img

についてplotこの関数は,入力パラメータに従ってチャートに線を引くことです. 入力データは,bar_indexこの線はbar_index最初のバーのbar_indexという行の値は0で,バーが増加するにつれて右に1増加します.

戦略の設定が異なるため,戦略のモデル実行方法も異なるため,closing price modelそしてreal-time price modelその概念を簡潔に紹介しました

  • 閉じる価格モデル

    戦略コードが実行されると,現在のK線バーの期間が完全に実行され,K線が閉ざされると,K線期間が完了します.この時点で,Pine戦略ロジックは1回実行され,トリガーされた取引信号は次のK線バーの開始時に実行されます.

  • リアルタイム価格モデル

    戦略コードが実行されると,現在のKラインバーが閉ざされたかどうかにかかわらず,Pine戦略ロジックは,市場が毎回変化するときに実行され,トリガーされた取引信号は直ちに実行されます.

グラフ上のK線バーは2つに分かれます.Historical BarsそしてReal-time Bars:

  • 歴史的なバー

    戦略がTick Modelに設定され,実行を開始すると,チャート上のすべてのK線バーは,右端を除いてHistorical Bars. 戦略論理は1回だけ実行されるhistorical bar- わかった グラフ上のすべてのバーは Bar Model に設定され,実行を開始すると,historical bars. 戦略論理は1回だけ実行されるhistorical bar.

    歴史的なバーに基づいて計算: ストラテジーコードは,歴史バーの閉じる状態で一度実行され,その後,すべての歴史バーが一度実行されるまで,次の歴史バーで戦略コードが実行され続けます.

  • リアルタイムバー

    戦略が右端の最後のK線バーに実行されると,バーはリアルタイムバーになります.リアルタイムバーが閉ざされると,バーはリアルタイムバーになります.新しいリアルタイムバーはチャートの右端に生成されます.

    戦略がTick Modelに設定され実行が開始されると,戦略ロジックはリアルタイムバーの各市場の変化に対して1回実行されます. 戦略がBar Model に設定され実行が開始されると,リアルタイムバーはチャートに表示されません.

    リアルタイムバーによる計算: 戦略がBar Modelに設定され,チャートでリアルタイムバーが表示されない場合,現在のバーが閉まるときに戦略コードは1回のみ実行されます. 戦略がTick Modelに設定されている場合,リアルタイムバーの計算は,歴史的なバーとは完全に異なります. 戦略コードは,ライブ・トレードバーの各市場の変化に対して1回実行されます. 例えば,内蔵変数high, low, close過去のバーで決定され,これらの値は,リアルタイムバーで市場が変化するたびに変化する可能性があります.したがって,これらの値に基づいて計算された指標などのデータもリアルタイムで変化します.リアルタイムバーで,close常に現在の最新価格を表し,highそしてlow常に現在のリアルタイムバーの開始以来の最高点と最低点を表します.これらの内蔵変数は,リアルタイムバーが最後に更新された時の最終値を表します.

    リアルタイムバー (リアルタイム価格モデル) で戦略を実行する時のロールバックメカニズム: リアルタイムのバー実行中に,戦略の新しい繰り返しのたびにユーザー定義変数をリセットすることはロールバックと呼ばれます.次のテストコードの例でロールバックメカニズムを理解しましょう.

    注目してください

    /*backtest 
    ...
    ..
    .
    */
    

    パッケージの内容は,FMZプラットフォームにコードとして保存されたバックテスト構成情報です.

    /*backtest
    start: 2022-06-03 09:00:00
    end: 2022-06-08 15:00:00
    period: 1m
    basePeriod: 1m
    exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
    */
    
    var n = 0
    if not barstate.ishistory
        runtime.log("before n + 1, n:", n, " current bar_index:", bar_index)
        n := n + 1
        runtime.log("after n + 1, n:", n, " current bar_index:", bar_index)
      
    plot(n, title="n")
    

    img

リアルタイムのバーで実行されたシーンのみを調査し,not barstate.ishistory変数nの累積をリアルタイムバーにのみ制限し,runtime.log累積操作の前後戦略ログの情報を出力する関数. 描画関数を使用して描かれた曲線nからplot, 戦略が歴史的なバーで実行されているとき,nは常に0であることが見られます.リアルタイムバーが実行されるとき, nに1を加える操作が起動し,リアルタイムバーの各ラウンドで戦略が実行されるときに,nに1を加える操作が実行されます.ログメッセージから,戦略コードが各ラウンドで再実行されるときに,nが前のバー実行戦略によって最終的に送信された値にリセットされることが観察できます. n値更新は,戦略コードがリアルタイムバーで最後に実行されたときに送信されます.したがって,グラフ上のリアルタイムバーから始まるバーの増加ごとに,曲線のnの値は1増加することを見ることができます.

概要:

  1. 戦略コードは,戦略がリアルタイムバーで実行開始するたびに,市場が更新されるたびに一度実行されます.
  2. リアルタイムバーで実行すると,戦略コードを実行する前に変数は毎回ロールバックされます.
  3. リアルタイムのバーで実行すると,閉じる時に1回送信されます.

グラフ上の曲線などの描画操作も,データロールバックのため,再描画を引き起こす可能性があります.例えば,ライブ取引のテストコードを修正しましょう.

var n = 0
if not barstate.ishistory
    runtime.log("before n + 1, n:", n, " current bar_index:", bar_index)
    n := open > close ? n + 1 : n
    runtime.log("after n + 1, n:", n, " current bar_index:", bar_index)
  
plot(n, title="n")

時間Aのスクリーンショットimg

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

修飾しただけよn := open > close ? n + 1 : n,現在のリアルタイムバーがマイナス線であるとき (すなわち,開盤価格が閉盤価格よりも高いとき) にのみ1をnに追加する.最初のチャート (時間A) では,開盤価格が閉盤価格 (マイナス線) より高かったため,nが1で累積され,チャート曲線に表示されたnの値は5であった.その後,市場が変化し,価格が2番目のチャート (時間B) で示されているように更新された.この時点で,開盤価格が閉盤価格 (ポジティブライン) より低く,nの値は1増加せずに戻る.チャート内のnの曲線も直ちに再描画され,曲線上のnの値は4である.したがって,クロスダウンとリアルタイムバーで表示されるシグナルは不確実であり,変化する可能性があります.

  • 機能における変数コンテキスト

    パイン言語関数の変数を一緒に研究してみよう. パインチュートリアルのいくつかの記述によると,関数の変数は関数外の変数と以下の違いを持っています.

    パイン関数で使用されるシリーズ変数の履歴は,関数への各次呼び出しで作成される.スクリプトが実行されるすべてのバーで関数が呼び出されていない場合,この結果は,関数の内部と外部にある一連の歴史的値の不一致をもたらす.したがって,関数が各バーで呼び出されていない場合,同じインデックス値を持つ関数内外で参照されているシリーズは,同じ歴史的点を参照しない.

    FMZで実行するテストコードで解く

    /*backtest
    start: 2022-06-03 09:00:00
    end: 2022-06-08 15:00:00
    period: 1m
    basePeriod: 1m
    exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
    */
      
    f(a) => a[1]
    f2() => close[1]  
    
    oneBarInTwo = bar_index % 2 == 0
    plotchar(oneBarInTwo ? f(close) : na, title = "f(close)", color = color.red, location = location.absolute, style = shape.xcross, overlay = true, char = "A")   
    plotchar(oneBarInTwo ? f2() : na, title = "f2()", color = color.green, location = location.absolute, style = shape.circle, overlay = true, char = "B")   
    plot(close[2], title = "close[2]", color = color.red, overlay = true)
    plot(close[1], title = "close[1]", color = color.green, overlay = true)
    

    バックテスト実行のスクリーンショット

    img

    テストコードは比較的シンプルで,主に2つの方法によって参照されたデータを調べます.f(a) => a[1]そしてf2() => close[1].

    • f(a) => a[1]: パラメータを転送する方法を使用すると,関数はa[1] finally.

    • f2() => close[1]: 組み込み変数を使用するcloseこの関数は直線に戻ります.close[1] finally.

について[]この記号は,データシリーズ変数の歴史的値を参照するために使用され,Close[1]は,現在の閉値の前にバー上の閉値データを参照します.私たちのテストコードは,チャートに合計4種類のデータを描きます.

  • plotchar(oneBarInTwo ? f(close) : na, title = "f(close)", color = color.red, location = location.absolute, style = shape.xcross, overlay = true, char = "A")文字を描く 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 が true であればしか描かれず,描かれた位置 (Y軸上) は:f2().

  • plot(close[2], title = "close[2]", color = color.red, overlay = true)線を描いて,色は赤で,描かれた位置 (Y軸) は:close[2], これは現在のバー (左に2つのバーを数える) の前の2番目のバーの閉じる価格です.

  • plot(close[1], title = "close[1]", color = color.green, overlay = true)線を引いて色は緑で,描かれた位置 (Y軸) は:close[1], これは現在のバー (左に1バーをカウント) の前の最初のバーの閉じる価格です.

機能の両方もf(a) => a[1]Aマークと関数を描くために使用されます.f2() => close[1]Bマーカーは,データシリーズ上の歴史的データを参照するために使用される [1]. グラフ上のABのマーカーの位置は完全に異なります. Aマーカーの位置は常に戦略のコードが描いた線である赤線に落ちます.plot(close[2], title = "close[2]", color = color.red, overlay = true),線を描くのに使用されたデータはclose[2].

img

K線バーのインデックス,すなわち内蔵変数を通してABマーカーを引くかどうかを計算する理由ですbar_indexAB マーカーは各K線バーに描かれていません (関数計算は描くときに呼び出されます).関数で参照される値はf(a) => a[1]関数で参照される値と同じではない.f2() => close[1]もし関数がすべての Bar で呼び出されていない場合 (両方が [1] のような同じインデックスを使用している場合でも).

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

    この状況を簡単な例で説明します

    res = close > close[1] ? ta.barssince(close < close[1]) : -1
    plot(res, style = plot.style_histogram, color=res >= 0 ? color.red : color.blue)
    

    函数呼び出しコードを書きます.ta.barssince(close < close[1])三重演算子でcondition ? value1 : value2. このときのみ ta.barssince 関数が呼び出される.close > close[1]しかし...ta.barssinceこの関数は,最後の回からK線の数を計算することです.close < close[1]ta.barssince関数が呼び出されたとき,常に close > close[1],つまり,現在の閉盤価格が前の Bar の閉盤価格よりも大きい. ta.barssince関数が呼び出されたとき, close < close[1]という条件は確立されず,最近保持しているポジションはありません.

    ta.barssince: 呼び出されると,現在のK線前に条件が満たされていない場合,関数は na を返します.

図表に示されているように:

img

解析変数 (-1) の値を持つデータのみが描かれます

この問題を回避するために,ta.barssince(close < close[1])可能な条件分岐の外に書き,各K線バーで計算を行う.

a = ta.barssince(close < close[1])
res = close > close[1] ? a : -1
plot(res, style = plot.style_histogram, color=res >= 0 ? color.red : color.blue)

タイムシリーズ

パイン言語では時間系列の概念が非常に重要であり,パイン言語を学ぶときに理解しなければならない概念である.時間系列はタイプではなく,時間の経過とともに変数の連続値を保存するための基本的な構造である.パインスクリプトはチャートに基づいていることが知られており,チャートに表示される最も基本的なコンテンツはK線チャートである.各値がK線バーのタイムスタンプに関連付けられている時間系列.openパイン言語の内蔵変数であり,その構造は,各K線バーのオープニング価格の時間列を保存することです.open現在のK線グラフの初めの最初のバーから,現在のスクリプトが実行されるバーまでのすべてのK線バーのオープニング価格を表します. 現在のK線グラフが5分間の期間である場合,当社が引用 (または使用) するときopenストラテジーコードが実行されているときのK線バーの開口価格です. タイムシリアルの歴史的な値を参照したい場合は,Kラインバーの開口価格を使用する必要があります.[]パイン戦略が特定のK線バーで実行される場合,open[1]前回のK線バーの開口価格 (前回のK線期間の開口価格) を参照するopenこのK線バーがスクリプトで実行されている時間列です

  • 時間列の変数は計算に非常に便利です この関数で,ta.cum例えば:

    ta.cum
    
    Cumulative (total) sum of `source`. In other words it's a sum of all elements of `source`.
    ta.cum(source) → series float
    RETURNS
    Total sum series.
    ARGUMENTS
    source (series int/float)
    SEE ALSO
    math.sum
    

    テストコード:

    v1 = 1
    v2 = ta.cum(v1)
    plot(v1, title="v1")
    plot(v2, title="v2")
    plot(bar_index+1, title="bar_index")
    

    機能が組み込まれています.ta.cum直接データ処理できます 例えばta.cum次に理解しやすくするためにチャートを使います. このグラフは,

    戦略の運用プロセス 組み込み変数 bar_index v1 v2
    戦略は最初のK線バーで実行されます 0 1 1
    戦略は2番目のK線バーで実行されます. 1 1 2
    戦略は3番目のK線バーで実行されます. 2 1 3
    戦略はN+1thK線バーで実行されます. N 1 N+1

    v1,v2,そしてbar_indexもすべて時間列構造であり,各バーには対応するデータがあることがわかります.テストコードがBarモデルまたはTickモデルを使用するかどうか,唯一の違いはリアルタイムバーがチャートに表示されるかどうかです.迅速なバックテストのために,テストのためにTickモデルを使用します.

    img

    変数v1が1で,この変数が1で,ta.cum(v1)最初のK線バーで実行されるので,最初のバーのみがあり,計算結果は1で変数v2に割り当てられます. いつta.cum(v1)2番目のK線バーで実行される場合,すでに2つのK線バーがあります (最初のバーに対応する内蔵変数bar_indexは0で,第2の内蔵変数bar_indexは1) したがって,計算結果は2で,変数v2に割り当てられます. 実際,v2はK線バーの数であることが観察できます.bar_index0 から増加すると,bar_index + 1この図では,直線が,v2そしてbar_index実際には重なり合っています

    img

    同じように,ta.cumこのグラフのすべてのバーの閉値の合計を計算する機能です.ta.cum(close)右端のリアルタイムバーに実行すると,ta.cum(close)グラフ上のすべてのバーの閉じる価格の合計です (右端に走らない場合は,現在のバーまでのみ蓄積されます).

    時間列の変数は,以下のようなコードのような演算子を使用して計算することもできます.ta.sma(high - low, 14),内蔵変数を引くhigh(K線バーの最高値)low(K線バーの最低価格) と最後に使用します.ta.sma平均値を計算する関数です

  • 函数呼び出しの結果は,時間列に値の痕跡を残します.

    v1 = ta.highest(high, 10)[1]
    v2 = ta.highest(high[1], 10)
    plot(v1, title="v1", overlay=true)
    plot(v2, title="v2", overlay=true)
    

    テストコードはバックテスト中に実行され,v1そしてv2函数呼び出しによって計算された結果は,時間列に値の痕跡を残します.ta.highest(high, 10)コードでta.highest(high, 10)[1]. 関数コールによって計算された結果は,その歴史的値を参照するために [1] を使用することもできます.ta.highest(high, 10)現在のバーの前のバーに対応すると,計算結果はta.highest(high[1], 10)それで...ta.highest(high[1], 10)そしてta.highest(high, 10)[1]完全に等価です

    他の図解関数を用いて情報検証を出力する:

    a = ta.highest(close, 10)[1]
    b = ta.highest(close[1], 10)
    plotchar(true, title="a", char=str.tostring(a), location=location.abovebar, color=color.red, overlay=true)
    plotchar(true, title="b", char=str.tostring(b), location=location.belowbar, color=color.green, overlay=true)
    

    変数 a と変数 b の値が対応する Bars の上下で表示されていることがわかります.この図のデータをバックテストや実験の際に観測するために出力する必要があることが多いので,学習プロセス中にこの図のコードを保存することができます.

    img

スクリプト構造

一般的な構造

このチュートリアルでは,FMZとTrading ViewのPine言語の使用の違いをまとめました.indicator(), strategy()そしてlibrary()もちろん,Pine スクリプトの以前のバージョンと互換性を持つためには,以下のような戦略が必要です.//@version=5, indicator(), strategy()パラメータを入力して設定することもできます.strategy() function.

<version>
<declaration_statement>
<code>

について<version>バージョン制御情報は省略できます.

コメント

パイン語は//パイン言語には複数行のコメントシンボルがないため,単行コメントシンボルとして. FMZはコメントシンボルを拡張する./**/多行コメントについては

コード

コメントやコンパイラ指令ではないスクリプトの行は,スクリプトのアルゴリズムを実装するステートメントである.ステートメントはこれらのコンテンツの1つである.

  • 変数式申告
  • 変数の再割り当て
  • 機能宣言
  • 内蔵関数呼び出し,ユーザー定義関数呼び出し
  • if, for, whileまたはswitch構造

申告は様々な方法で整理できます.

  • いくつかの命令は,ほとんどの変数宣言,たった1つの関数呼び出しを含む行,または単行関数宣言など,1行で表現できる.他の命令は,構造のように,常に複数の行を必要とします.これはローカルブロックを必要とします.
  • スクリプトのグローバル範囲 (つまりローカルブロックの一部でない部分) のステートメントは,spaceまたは ```tab` (タブキー). その最初の文字は行の最初の文字でなければならない. 最初の位置から始まる文字は,定義上,スクリプトのグローバル範囲の一部になります.
  • 構造または多行式関数宣言には常にlocal blockローカルブロックは1つのタブまたは4つのスペースで引入されなければなりません (そうでなければ,それは前の行の連鎖コードとして解析され,つまり,前のコード行の連続的な内容であると判断されます),そして各ローカルブロックは異なるローカル範囲を定義します.
  • 複数の単行列の文は,コンマ (,) を分離符として使って単行列に連結できます.
  • 列にはコメントが含まれたり,コメントのみが含まれたりできます.
  • 線も巻き込み (複数の線で継続) することができます.

例えば,if構造を使用したカスタム関数宣言に1つ,変数宣言に2つ,以下の3つのローカルブロックを含みます.

indicator("", "", true)             // declaration statement (global scope), can be omitted

barIsUp() =>                        // function declaration (global scope)
    close > open                    // local block (local scope)

plotColor = if barIsUp()            // variable declaration (global scope)
    color.green                     // local block (local scope)
else
    color.red                       // local block (local scope)

runtime.log("color", color = plotColor)  // Call a built-in function to output the log (global scope)

ラインブレイクコード

長い線は複数の線に分けられる.また,包まれた線は4の倍数でない限り,任意のスペースでインデントしなければならない (これらの境界はローカルブロックをインデントするために使用される).

a = open + high + low + close

包装できる (一行ごとに引入されたスペースの数が4の倍数であってはならないことに注意してください):

a = open +
      high +
          low +
             close

長いプロット ((() 呼び出しは,次のように包み込むことができます:

close1 = request.security(syminfo.tickerid, "D", close)      // syminfo.tickerid daily level closing price data series for the current trading pair
close2 = request.security(syminfo.tickerid, "240", close)    // syminfo.tickerid 240-minute level closing price data series for the current trading pair
plot(ta.correlation(close, open, 100),                       // line-long plot() calls can be wrapped
   color = color.new(color.purple, 40),
   style = plot.style_area,
   trackprice = true)

ユーザ定義関数宣言のステートメントも包み込むことができる.しかし,ローカルブロックは文法でインデント (4スペースまたは1タブ) で開始されなければならないため,次の行に分割するときに,ステートメントの継続は1つ以上のインデント (4つのスペースの倍数に等しくない) で開始されなければならない.例えば:

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

マーカーと操作者

マーカー

変数を認識する前に,まず"マーカー"の概念を理解する必要があります.機能そして変数(変数と関数の名前付けに使われる).機能まず"マーカー"について学ぼう.

    1. マーカーは大文字で始まる必要があります(A-Z)小文字で(a-z)文字や下記(_)マーカーの最初の文字として
    1. マーカーの最初の文字の次の文字は,手紙, 強調する,または番号.
    1. マーカーの名前付けは 大小に敏感です

例えば次の名前のマーカー:

fmzVar
_fmzVar
fmz666Var
funcName
MAX_LEN
max_len
maxLen
3barsDown  // Wrong naming! It used a numeric character as the leading character of the marker

ほとんどのプログラミング言語と同様に,Pine言語にも書き込み提案があります.識別子命名する際には,一般的に以下のようなことを推奨します.

    1. 大文字は定数の名前で使われます
    1. 試しに下のラクダケース他のマーカー名では
// name variables, constants
GREEN_COLOR = #4CAF50
MAX_LOOKBACK = 100
int fastLength = 7

// name functions
zeroOne(boolValue) => boolValue ? 1 : 0

事業者

オペレーターとは,プログラミング言語で表現を構成するために使用されるいくつかの操作シンボルであり,表現は,戦略を書くときに特定の計算目的のために設計された計算規則である. パイン言語のオペレーターは,関数によって以下のように分類される.

割り当て演算子,算術演算子,比較演算子,論理演算子? :三次性事業者[]歴史的な参照演算子.

算術演算子を取ること*例えば,Trading View の Pine language オペレーターの返信結果によるタイプ問題とは異なります.次のテストコードが提供されています.

//@version=5
indicator("")
lenInput = input.int(14, "Length")
factor = year > 2020 ? 3 : 1
adjustedLength = lenInput * factor
ma = ta.ema(close, adjustedLength)  // Compilation error!
plot(ma)

このスクリプトを Trading View で実行すると,コンパイルエラーが発生します.adjustedLength = lenInput * factor結果としてseries int2番目のパラメータはta.emaしかし,FMZにはそのような厳格な制限はありません.上記のコードは通常実行できます.

複数の演算子の組み合わせを見てみましょう.

割り当て事業者

割り当てオペレータは2種類あります.=, :=このチュートリアルの初めの部分にいくつか例を見ました

について=初期化または宣言されたとき変数に値を代入するために使用される. 初期化,宣言および指定された変数は,=この値は,次の各バーで開始されます. これらは有効な変数宣言です:

a = close           // Use built-in variables to assign values to a
b = 10000           // Use numerical assignment
c = "test"          // Use string assignment
d = color.green     // Use color value assignment
plot(a, title="a")
plot(b, title="b")
plotchar(true, title="c", char=str.tostring(c), color=d, overlay=true)

任務の説明書にはa = close,各バーの変数 a は,バーの現在の閉じる価格 (閉じる) である.その他の変数b, c, dFMZのバックテストシステムでテストできます 結果は図に示されています

:=既存の変数に値を再割り当てするために使用されます.:=宣言され初期化された変数の値を修正するために使用されます. 実験をしてみると:=初期化されていない変数または宣言された変数に値を代入するには,エラーが発生します.例えば:

a := 0

したがって,:=割り当て演算子は通常,既存の変数を再割り当てするために使用されます.例えば:

a = close > open 
b = 0 
if a
    b := b + 1

plot(b)

判断するclose > open変数 a は true です. if 文のローカルブロックのコードは,b := b + 1実行され,割り当て操作者は:=グラフ上の各 BAR に変数 b の値を描き,直線に接続します. このグラフの各 BAR に変数 b の値を描き,直線に変換します.

この文では,b を 0 と宣言し,初期化します. この文では,b を 0 と宣言し,初期化します.b=0変数aが真であれば, b変数を0にリセットします. つまり,close > open, b はこのラウンドでコードを実行するときに 1 増やされ,b はプロット関数が引くと 1 になりますが,次のラウンドでコードを実行するときに b は 0 に再割り当てられます. これはまた,Pine 言語初心者が落とし穴に陥る傾向がある場所です.

2つのキーワードを拡大する必要があります.var, varip

  • ワール

    このキーワードの説明を見てみましょう. このキーワードの説明を見てみましょう. このキーワードの説明を見てみましょう.

    varは,変数の割り当ておよび一度の初期化に使用されるキーワードである.一般的に,キーワード var を含まない変数の割り当て文法は,データが更新されるたびに変数の値が書き換えられる.対照的に,変数がキーワード var を使用して割り当てられると,データ更新にもかかわらず状態を維持することができる.

    この例では,varここでbに値を代入するときに使うキーワードです

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

    についてvarキーワードで変数bが初期割り当てのみを実行することができ,戦略論理を実行するたびに bを0にリセットしないので,実行時に描かれた線から,bは現在のK線 BARがバックテストされたときに出現した正線 BARの数であることを観察できます.

    varで宣言された変数は,グローバル範囲だけでなく,この例のようなコードブロックでも記述できます.

    strategy(overlay=true)
    var a = close
    var b = 0.0
    var c = 0.0
    var green_bars_count = 0
    if close > open
        var x = close
        b := x
        green_bars_count := green_bars_count + 1
        if green_bars_count >= 10
            var y = close
            c := y
    plot(a, title = "a")
    plot(b, title = "b")
    plot(c, title = "c")
    

    変数 a は,一連の最初のバーの閉じる価格を保持します. 変数 bは,シリーズ内の最初の green価格バーの閉値値を保持します. 変数 cは,シリーズ内の第10の 緑色バーの閉値を保持します.

  • 変数

    キーワードはvaripこのキーワードの記述を見てみましょう

    varp (var intrabar persist) は,変数の割り当ておよび一度の初期化のためのキーワードである.varキーワードに似ているが,varipで宣言された変数は,リアルタイムKライン更新時に値を保持する.

    分かりにくいですか? 構いません 簡単な例で説明します

    strategy(overlay=true)
    
    // test var varip
    var i = 0
    varip ii = 0  
    
    // Print the i and ii changed in each round of the strategy logic on the chart
    plotchar(true, title="ii", char=str.tostring(ii), location=location.abovebar, color=color.red)
    plotchar(true, title="i", char=str.tostring(i), location=location.belowbar, color=color.green)  
    
    // Increment i and ii by 1 for each round of logic execution
    i := i + 1
    ii := ii + 1
    

    このテストコードは,Bar ModelTick Modelで異なるパフォーマンスを有します.

    バールモデル: リアルタイム BAR 段階に分かれています. Bar モデルでは,歴史的なK線段階,変数はi, ii申告したvar, varip戦略コードの実行の各ラウンドで増量操作を実行する.したがって,バックテスト結果のK線 BARに表示された数字が1ずつ増量されるのが見えます.歴史的なK線ステージが終了すると,リアルタイムK線ステージが始まります.varとvaripで宣言された変数は異なる変化を経験し始めます. Barモデルであるため,戦略コードはK線 BARの各価格変化に対して1回実行されます.i := i + 1そしてii := ii + 1i は次のラウンドで実行されると,前の値が復元されます (前回の"モデル実行"章で説明したロールバックメカニズムを覚えていますか?),そして現在のK線BARが完了するまでiの値が更新されません (つまり,次のラウンドで戦略論理を実行すると前の値が復元されません).したがって,変数iは依然として1で増加していることが見られます.しかし変数iiは各BARのために数回蓄積されます.

    チェックモデル: Tick モデルは,K ライン BAR ごとに 1 回しか戦略論理を実行しないため,閉値モデルでは,var と varip によって宣言された変数は,上記の例で,歴史的な K ライン ステージとリアルタイム K ライン ステージの間,各 K ライン BAR に対して 1 倍増してまったく同じ振る舞いをします.

算術演算子
事業者 記述
+ 追加
- 引く
* 掛け算
/ 部門
% モジュール

について+そして-他の算数演算子は,二進数演算子としてのみ使用され,もし二進数演算子として使用された場合,エラーを報告します.

  1. 算術演算子の両側も数値型で,結果は数値型,整数または浮動点数で,操作の結果によって異なります.
  2. 操作元が文字列で,操作元が文字列である場合+計算の結果は文字列で,値は文字列形式に変換され,文字列が縫合されます.他の算術演算子であれば,文字列を値に変換し,操作を続けます.
  3. オペランドの1つが na である場合,計算の結果は null valuenaであり,FMZに印刷すると NaN を表示します.
a = 1 + 1 
b = 1 + 1.1
c = 1 + "1.1"
d = "1" + "1.1"
e = 1 + na 

runtime.log("a:", a, ", b:", b, ", c:", c, ", d:", d, ", e:", e)   
// a: 2 , b: 2.1 , c: 11.1 , d: 11.1 , e: NaN

FMZのPine言語は,Trading ViewのPine言語とは少し異なります.例えば:

a = 1 * "1.1"
b = "1" / "1.1"
c = 5 % "A" 

plot(a)
plot(b)
plot(c)

FMZでは動作するが,トレーディングビューではタイプエラーを報告する.算術演算子の両方のオペランドが文字列である場合,システムは文字列を数値値に変換し,それらを計算する.数値以外の文字列が計算できない場合,システム操作の結果は null valuenaである.

比較演算子

比較演算子は全てバイナリー演算子です

事業者 記述
< <
> >
<= <=
>= >=
== ==
!= !=

試験例:

a = 1 > 2 
b = 1 < 2 
c = "1" <= 2 
d = "1" >= 2 
e = 1 == 1 
f = 2 != 1 
g = open > close 
h = na > 1 
i = 1 > na

runtime.log("a:", a, ", b:", b, ", c:", c, ", d:", d, ", e:", e, ", f:", f, ", g:", g, ", h:", h, ", i:", i)   
// a: false , b: true , c: true , d: false , e: true , f: true , g: false , h: false , i: false

比較演算子は,非常に簡単に使用できます. しかし,この演算子は,戦略を書くときに最も使用されます. 数値値と内蔵変数の両方を比較することができます.close, openなど FMZとTrading Viewの間には,パインの言語に関する違いがあります. FMZはタイプに対して特に厳しい要件を持っていません.したがって,そのような声明は,d = "1" >= 2FMZではエラーを報告しませんが,文字列を最初に値に変換して操作を比較することで実行されます.

論理演算子
事業者 コードシンボル 記述
ない ない 操作ではないユニア操作体
そして そして バイナリーオペレータと操作
または または バイナリーオペレータまたはオペレーション

論理演算子については,真の値表について語らなければなりません. 高校で学んだことと同じで,ここでテストして,バックテストシステムで学ぶだけです.

a = 1 == 1  // An expression formed by using comparison operators, the result is a Boolean value
b = 1 != 1
c = not b   // Logical not operators
d = not a   // Logical not operators

runtime.log("test the logical operator:and", "#FF0000")
runtime.log("a:", a, ", c:", c, ", a and c:", a and c)
runtime.log("a:", a, ", b:", b, ", a and b:", a and b)
runtime.log("b:", b, ", c:", c, ", b and c:", b and c)
runtime.log("d:", d, ", b:", b, ", d and b:", d and b)

runtime.log("test the logical operator:or", "#FF0000")
runtime.log("a:", a, ", c:", c, ", a or c:", a or c)
runtime.log("a:", a, ", b:", b, ", a or b:", a or b)
runtime.log("b:", b, ", c:", c, ", b or c:", b or c)
runtime.log("d:", d, ", b:", b, ", d or b:", d or b)

runtime.error("stop")

メッセージを重複しないために,我々はエラーを投げruntime.error("stop")プリントした内容が実際の値表と同じであることを確認できます. プリントした内容が実際の値表と同じであることを確認します.

ターナリー・オペレータ

ターナリー演算子を使用する三次式式? :オペランドと組み合わせたcondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalse3つの演算子があります. 3つの演算子には 3つの演算子があります.

についてcondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalse, condition判断条件である.もし真であるならば,表現の値は:valueWhenConditionIsTrueもしconditionこの式の値は false です.valueWhenConditionIsFalse.

実用的な使用はほとんどないが,便利なデモの例:

a = close > open
b = a ? "positive line" : "negative line"
c = not a ? "negative line" : "positive line"
plotchar(a, location=location.abovebar, color=color.red, char=b, overlay=true)
plotchar(not a, location=location.belowbar, color=color.green, char=c, overlay=true)

前のチュートリアルでやったように,三次式も巣を作ることができます.

a = close > open
b = a ? math.abs(close-open) > 30 ? "positive line" : "doji" : math.abs(close-open) > 30 ? "negative line" : "doji"
c = not a ? math.abs(close-open) > 30 ? "negative line" : "doji" : math.abs(close-open) > 30 ? "positive line" : "doji"
plotchar(a, location=location.abovebar, color=color.red, char=b, overlay=true)
plotchar(not a, location=location.belowbar, color=color.green, char=c, overlay=true)

代替するようなものですvalueWhenConditionIsTrueそしてvalueWhenConditionIsFalsecondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalseこの式は,他の三次式で表します.

歴史的操作者

履歴演算子を使用する[]文字列の過去値を参照する. これらの過去値は,スクリプトが実行されたときに現在のK行バーの前にK行バー上の変数の値です.[]変数,式,関数呼び出しの後で使用されます.[]例えば,最後のK線BARの閉値を引用したい場合,これを以下のように書きます.close[1].

前回のレッスンでこんなことを見ました

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

について[]同じ値で1回しか使えないので,このように書くのは間違っているので,エラーが報告されます.

a = close[1][2]   // error

操作者が[]配列の構造は,配列に似ているようです! パイン言語における数列と配列の違いを例で説明しましょう.

strategy("test", overlay=true)

a = close
b = close[1]
c = b[1]

plot(a, title="a")
plot(b, title="b")
plot(c, title="c")

a = close[1][2]エラーを報告しますが:

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

通常の配列に従って理解すると,b = close [1]b は値でなければならないが,c = b[1], b は,歴史演算子を使用して,歴史値を再び参照するためにまだ使用できます. パイン言語の連続の概念は配列のように単純ではないことがわかります. 閉じる最後のバー (b に割り当てられる) の歴史的値として理解できます. b はまた,時間系列構造 (時間系列) で,その h は,


もっと