Pineスクリプトv5のご紹介

10 7, 2021

本日、Pineはv5に移行しました!インジケーターとストラテジーのプログラミング言語の新バージョンでは、数多くのエキサイティングな新機能と改良が施されています。Pineはこれまで以上にパワフルになり、v5での変更により、新たなレベルに進化させることができます。この記事では、最新の機能のいくつかをご紹介しています。リリースノート移行ガイドも合わせてご確認ください。

v4からv5への変換ツール

旧バージョンのPineを使用している既存のスクリプトは、引き続き変更せずに実行できますが、Pineエディタには、v4のスクリプトをv5に変換するための変換ツールが用意されています。今後のPineの改善はv5のみで展開されるため、新機能の恩恵を受けたい場合は、インジケーターやストラテジーを変換されることをお勧めします。v4からv5への変換ツールは、v4のスクリプトがエディタに読み込まれた時に、「詳細」のドロップダウンメニューから利用できます:

なお、すべてのv4のコードが自動的に変換できるわけではない事にご注意ください。変換に問題がある場合や、スクリプトを手動で変換されたい場合は、v4とv5間のすべての変更点を記載した移行ガイドをご参照ください。

ライブラリ

v5でPineに追加された主な機能はライブラリです。ライブラリは新しいタイプの投稿方法であり、カスタム関数を作成して他のスクリプトで再利用することができます。ライブラリが公開されると、他のスクリプト(インジケーター、ストラテジー、あるいは他のライブラリ)でライブラリをインポートし、その関数を使用することができます。ライブラリを使用して、それに複雑なアルゴリズムや頻繁に使用される関数を含めることで、ご自身やPineコミュニティ全体で簡単に再利用することができます。

ライブラリのご利用方法は、ユーザーマニュアルのライブラリのページをご覧ください。この記事の最後には、PineCodersチームのメンバーが公開したライブラリの例が掲載されています。公開されているライブラリは、こちらのスクリプトフィードからご覧いただけます。

ユーザー定義関数のデフォルト値

ライブラリと連動した改善点として、ユーザー定義関数のパラメーターにデフォルト値を定義することができるようになりました。これは事実上オプションになります。以下の例では、baseexp で累乗にするカスタム関数 customPow() を宣言しています。関数の呼び出し時に exp が指定されていない場合は、2が使用されます:

//@version=5
indicator("")
customPow(base, exp = 2) =>
    result = 1
    for i = 1 to exp
        result *= base
plot(customPow(11)) // 11^2
plot(customPow(11, 4)) // 11^4

Switch

新しい switch 文は、おなじみの if 文を改良したものです。大きなツリー状の if-else 文を作成したことがある方は、switch を使うことで目的の結果を得ることができ、非常に便利であることを実感されるでしょう。switchについての詳細は、リファレンスマニュアルをご覧ください。以下のコードでは実際の動作をご確認いただけます。これは、内蔵の ATR インジケーターで、switch 文を使用して、計算に異なるスムージングアルゴリズムを提供しています:

//@version=5
indicator(title="Average True Range", shorttitle="ATR", timeframe="")
lengthInput = input.int(title="Length", defval=14, minval=1)
smoothingInput = input.string(title="Smoothing", defval="RMA", options = ["RMA", "SMA", "EMA", "WMA"])

maFunction(source, length) =>
    switch smoothingInput
        "RMA" => ta.rma(source, length)
        "SMA" => ta.sma(source, length)
        "EMA" => ta.ema(source, length)
        => ta.wma(source, length)

plot(maFunction(ta.tr(true), lengthInput), title = "ATR", color=#B71C1C)

描画コレクション

Pineで描画を操作する際の利便性が大幅に向上しました。新しい内臓の配列変数 line.alllabel.allbox.alltable.all にはスクリプトで描画された特定の種類のすべての描画のIDが常に格納されています。

これらは例えば、ユーザー定義の値に基づいて、チャートに表示される描画の数をトリミングするために使用できます。以下のスクリプトでは、新しい日足のオープンごとにラインを描画します(スクリプトのデフォルトのライン数の制限に基づき50個まで)。その後、スクリプトの設定で指定したライン数を超えたかどうかをチェックし、超えた場合は最も古いラインを削除します:

//@version=5
indicator("Daily Open", overlay = true)

qtyOfLinesInput = input.int(10, "Draw only last n lines", minval = 0, maxval = 50)

if ta.change(time("1D"))
    line.new(bar_index, open, bar_index + 1, open, extend = extend.right)
    if array.size(line.all) > qtyOfLinesInput
        line.delete(array.get(line.all, 0))

While

v5で搭載されたもう一つのPineの待望の機能は、while ループです。while 文は、条件が false になるか、ループ内で break コマンドが使用されると停止するループを作成します。

例として、こちらは過去n本のバーの合計出来高に等しい上昇下降の出来高を見つけるためにさかのぼる必要がある平均期間の差を計算するインジケーターです。上昇または下降の出来高を見つけるために過去をさかのぼる必要があるほど、インジケーターの値は弱気または強気になります:

//@version=5
var int MAX_BARS_BACK = 500
indicator("Volume bias", max_bars_back = MAX_BARS_BACK)

int lookBackInput = input.int(20, "Volume Look Back (bars)", minval = 2, maxval = int(MAX_BARS_BACK / 4))

// Stop the script if the chart does not contain volume data.
bool noVol = na(volume) and nz(math.sum(nz(volume), 200) == 0, true)
if noVol
    runtime.error("No volume data.")

volumeBias(lookBack, maxLookBack) =>
    bool  barUp = ta.rising(close, 1)
    bool  barDn = ta.falling(close, 1)
    float upVolume = 0.
    float dnVolume = 0.
    float avgVolume = math.sum(nz(volume), lookBack)
    int[] upBarNos = array.new_int(0)
    int[] dnBarNos = array.new_int(0)
    int   bar = 1
    bool  volumeFound = false
    while (not volumeFound) and bar < maxLookBack
        if barUp[bar] and upVolume < avgVolume
            upVolume += nz(volume[bar])
            array.push(upBarNos, bar)
        else if barDn[bar] and dnVolume < avgVolume
            dnVolume += nz(volume[bar])
            array.push(dnBarNos, bar)
        bar += 1
        volumeFound := upVolume >= avgVolume and dnVolume >= avgVolume
    float volumeBias = bar >= maxLookBack ? na : array.avg(dnBarNos) - array.avg(upBarNos)

float bias = volumeBias(lookBackInput, MAX_BARS_BACK)
plot(bias, "Volume Bias", bias > 0 ? color.lime : color.fuchsia)
hline(0)

スクリプトの while ループは、許容される最大のバー数の範囲内で、上昇と下降の出来高の双方で必要なボリュームが見つかるまで実行されます。このスクリプトでは、Pine v5で追加されたもう一つの機能である runtime.error() もご紹介しています。

ランタイムエラー関数

runtime.error() 関数で、Pineで定義した任意の条件でスクリプトの実行を停止し、エラーメッセージを表示することができるようになりました。これは、ユーザーによるインジケーターの誤使用を防ぎたいスクリプト作成者にとって便利な機能です。また、ループ中や関数内で実行を停止させるなど、ある種のデバッグツールとしても利用できます。

この新しい関数を使用するには、条件が満たされたときに runtime.error() 関数を呼び出すだけです。この関数が実行されると、スクリプトが停止し、インジケーター名の横におなじみのビックリマークが表示されます。ユーザーがビックリマークのアイコンをクリックすると、関数の呼び出しで使用したメッセージが表示されます。

以下のコードは、2つのカスタムエラーを持つ必要最低限の VWAP インジケーターです。1つ目のエラーは、シンボルに出来高のデータがない場合に表示されます: VWAP は出来高に基づいて計算されるため、出来高がない場合はスクリプトが機能しません。2つ目のエラーは、チャートのタイムフレームが日足以上の場合に表示されます。基本的な VWAP の計算は、新しいバーごとに出来高加重移動平均のデータを蓄積し、新しい日の開始時にリセットされるため、このインジケーターは日中のタイムフレームでのみ利用できます。

//@version=5
indicator("VWAP with custom errors")
if na(volume) // Will be true on symbols with no volume data e.g. TVC:SPX
    runtime.error("There is no volume data for this symbol.")
else if timeframe.isdwm // Will be true on 1D and higher timeframes
    runtime.error("Session-based VWAP does not show meaningful data on timeframes >= 1D.
     Please switch to a lower timeframe.")
plot(ta.vwap)

新規ストラテジーパラメーター

ストラテジー開発者の方に朗報です!新しい変数や関数が多数追加され、トレードのプロパティ、統計、指標を利用できるようになりました。これらの値は、ブローカーエミュレータが注文を実行すると更新されるため、ストラテジーの実行状況に合わせて値を確認することができます。

それぞれの詳細については、こちらをクリックしてPineリファレンスマニュアルをご覧ください

strategy.closedtrades.entry_price() / strategy.opentrades.entry_price()

strategy.closedtrades.entry_bar_index() / strategy.opentrades.entry_bar_index()

strategy.closedtrades.entry_time() / strategy.opentrades.entry_time()

strategy.closedtrades.size() / strategy.opentrades.size()

strategy.closedtrades.profit() / strategy.opentrades.profit()

strategy.closedtrades.commission() / strategy.opentrades.commission()

strategy.closedtrades.max_runup() / strategy.opentrades.max_runup()

strategy.closedtrades.max_drawdown() / strategy.opentrades.max_drawdown()

strategy.closedtrades.exit_price()

strategy.closedtrades.exit_bar_index()

strategy.closedtrades.exit_time()

strategy.convert_to_account()

strategy.convert_to_symbol()

strategy.account_currency

 

新しい名前空間

Pineプログラマーのコミュニティには、ここ数年でPineに追加された前例のないペースを高く評価していただいていますので、今後も同じペースを維持する予定です。しかしその為には、新しいPine関数や内蔵変数が次々と追加されることになります。この異常な程の成長をサポートするために、Pine言語で使用されている約600の現在の名前をより適切に整理する必要がありました。その為、新しい名前空間を追加して、関数をよりその用途を反映した形でグループ化しました。また関数のパラメーター名の多くも、より理解しやすいように名前が変更されています。

新しい名前空間の例としては、テクニカル分析に関連するすべての変数と関数を含む ta. があります。これにより、リファレンスマニュアルで、一般的なインジケーターの値を返すすべての変数や関数をより簡単に見つけることができるようになりました。したがって、例えば sma() は、ta.sma() になっています。新しい名前空間を覚える必要はありません。

Pineエディターで名前空間のない古い関数名を入力して、オートコンプリートのホットキー (Ctrl + スペース、またはMacOSでは Cmd + スペース) を押すと、マッチする候補がポップアップで表示されます。

リファレンスマニュアルを検索する場合も同様で、なじみのある関数名を名前空間なしで入力すると、その新しい名称が表示されます。v5での変更の全リストは、移行ガイドでご確認いただけます。

公開されているライブラリ

以下の投稿は、Pineの新機能のテストに協力してくれているPineCodersがTradingViewで公開しているライブラリの例です:

RicardoSantos氏のColorScheme

Duyck氏のMatrix_Functions_Lib_JD

HeWhoMustNotBeNamed氏のEnchanced_ta

新機能がお役に立てば幸いです。私たちは皆様のためにTradingViewを開発していますので、プラットフォームのアップデートに関するフィードバックやご提案ををいつでもお待ちしています。

Look first Then leap

あなたのためのTradingView、その最高の機能を最大限にご活用ください
チャートを起動