ついに、Pineスクリプト®バージョン6のリリースを発表できる日がやってきました!トレーダー向けに特化されたプログラミング言語であるPineスクリプト™がアップグレードされました。今回の新バージョンでは様々な最適化を行い、長い間要望があった各種機能の強化を図っています。プログラマーの皆様にとってPineスクリプト™がさらに効率的で実用的なものになり、新たな高みへと飛躍を遂げられるステージがいま整ったところです。
このブログ記事ではPineスクリプト®バージョン6 (Pine v6) のアップグレードの内容から注目に値するものをいくつか取り上げ、その概要を説明します。Pine v6の新機能の詳細と今後の改良についての最新情報については、「リリースノート (Release notes)」をご覧ください。
v6 変換ツール
以前のバージョン変更時と同様にPine v6に含まれるアップグレードは、プライベート/公開の区別を問わず以前のバージョンで書かれたスクリプトには影響しません。しかし、これ以降の新機能はすべて最新バージョンでのみ実装されるため、新機能にアクセスしたい場合はスクリプトをv6に変換することをお勧めします。v6への変換を最も手軽に行う方法としては、新しいv6変換ツールを利用する方法があります。Pineエディタの「スクリプトの管理」メニューから「v6にコードを変換」を選択するとこの機能を有効にできます。

ただし、すべてのスクリプトが自動的にv6へと変換されるわけではないので注意が必要です。変換後のスクリプトを想定どおりに動作させるために、手動での編集が必要な場合もあります。自動変換で問題が発生した場合や手動でスクリプトをv6に変換したい場合には、便利な「移行ガイド (Migration guide)」をご覧ください。
動的リクエスト
TradingViewでは、世界中で取引できる様々な銘柄から金融・経済指標に至るまで何万ものシンボルへのアクセスが可能です。request.*() 関数を使用すると、Pineスクリプトは、チャートで使用されているシンボルや時間足に関わりなく、利用可能なシンボルであれば、それに関するあらゆるデータを様々な時間足で取得することができます。
この関数は数多くの使い方ができる強力なユーティリティです。しかしながら、これまでは大幅な制限事項がありました。リクエストするシンボルと時間足を指定するために “simple string” 値を使用する必要があり、また最初のバーでコンテキストがわかっている必要があり、その後の変更もできませんでした。それに加え、request.*() の呼び出しには、スクリプトのグローバルスコープで厳密な実行が必要でした。つまり、コード内の単一の request.*() インスタンスは、1つのシンボルと時間足のデータしか取得できず、ループや条件構造、エクスポートされたライブラリ関数の内部では、request.*() の呼び出しができませんでした。
Pineスクリプト®バージョン6ではこうした制限がなくなりました。これによって、スクリプトでは “series string” 値を使用して request.*() 呼び出しのコンテキストを定義できるようになりました。さらに、request.*() の呼び出しがローカルスコープ内で許可されるようになりました。これらの変更により、任意の過去バー上でのシンボルの計算または変更、そのデータの動的リクエスト、シンボルのコレクション作成、ループ内でのデータ取得など、以前はできなかったことの多くを request.*() 関数で行うことができるようになりました。詳細については「ユーザーマニュアル」の「動的リクエスト (Dynamic requests)」のセクションをご覧ください。
動的リクエストで可能になることの例として、内蔵インジケーター「パフォーマンス (Performance)」の内部でどんな動作が生じているかを確認してみましょう。まず、シンボルと時間足の文字列をカンマで区切ったリストにしてそれを配列に分割します。その次にループ内で動的に request.security() を呼び出して、各データセットから値を取得します。以前はこうしたスクリプトを作成するには、複数の input.symbol() と input.timeframe() を呼び出す必要があり、シンボルと時間足の組み合わせごとにコード内で別々に request.security() を呼び出す必要がありました:

また、TradingViewアカウントで公開している下記スクリプトもご参照ください、これらのスクリプトも動的リクエストを利用して、他のコンテキストからデータを取得しています。
- Forex Heatmap — このインジケーターでは、ユーザーが指定した通貨コードのリストに基づいて通貨ペアを組み合わせたティッカーIDを作成しています。ループ内で各ペアを組み合わせたデータを動的にリクエストして、そのデータ使って色分けし表を作成します。
- Ticker Tape — このインジケーターでは、ユーザー定義のシンボルリストからティッカーIDの配列を作成します。ループ内の配列から各ティッカーIDの価格と日毎の変動についての情報を動的にリクエストして、そのデータを使って回転する「テープ」の表示を更新します。
- LibraryCOT — 以前までは、このライブラリにはCFTC Commitment of Traders (COT) のデータをリクエストするためのティッカーIDを作成するツールしかありませんでした。これはライブラリが request.*() の呼び出しを含む関数をエクスポートできなかったためです。動的リクエストではこうした制限事項はありません。現在このライブラリでは、request.security()を内部的に呼び出してCOTデータを直接取得する requestCommitmentOfTraders() 関数をエクスポートしており、プログラマーにとって便利で汎用性のあるものになっています。
さらに、以前はCFTCのレポートコードはすべて“simple”値を返す switch 文の中に保持されていたので、リクエストできるティッカーが大幅に制限されていました。動的リクエストでは、“simple string” のティッカーIDは必要なくなり、ライブラリーがレポートコードを マップに格納するようになったので、より多くのシンボルに対応できるようになりました。
ブーリアンの最適化
Pineスクリプト®バージョン6で注目すべき改良点の1つとして、表面的には現れませんがコードの効率に違いがあることにお気づきの方もいるかもしれません。Pineの “bool” 値の内部実装を見直し、ショートサーキット(または 「遅延」)評価を導入しました。and と or の演算は、結果を決定する上で必要でない場合、それ以降の式の評価を停止できるようになりました。
これらの変更によって、TradingView上にあるスクリプトのほとんどについてパフォーマンスが向上しました。オープンソースの「コミュニティスクリプト」のなかでも人気の高いものでいくつかテストした結果、比較的規模の大きいスクリプトで条件への依存度が高く、“bool” 値を多く使用するものについてはこの効率の違いが特に顕著に現れました。
以上の利点に加え、“bool” の遅延評価によって、よりクリーンで簡潔なコードが可能になる場合が多くあります。たとえば、配列からのアイテムに依存する条件があるときに、アイテムのインデックスの存在を確認するために配列サイズのチェックが必要になるケースもあるでしょう。v5では不可能でしたが、Pine v6ではこの遅延評価によって要素にアクセスする前に配列をチェックする単一の条件式を作成することができます。
//@version=6
indicator("Lazy evaluation demo")
//@variable A "bool" array without a fixed size.
array<bool> myArray = array.new<bool>()
// Push a new value into `myArray` when the `close` is above the `open`.
if close > open
myArray.push(true)
// Line 13 causes an error in v5 because `myArray.first()` always executes, even if the first expression is `false`.
// It works in v6 though because `myArray.first()` executes only if the first expression evaluates to `true`.
if myArray.size() != 0 and myArray.first()
label.new(bar_index, high, "Test")
テキストサイズと書式設定
テキストを表示する描画(ボックス (boxes)、ラベル (labels)、テーブル (tables) )のタイプすべてにおいて、テキストのフォントサイズをポイント — 標準のテキストエディタで使用されるものと同じポイント — で指定できるようになりました。これまではsize.large (24) や size.huge (36) など任意の size.* の定数から選択する必要がありましたが、この新しいポイント指定によってテキストサイズを正確に決められるようになりました。以前のPineのバージョンではできなかった巨大なサイズのテキストも作成できます。
さらに、これらの描画タイプに新しく text_formatting のパラメーターを導入しました。このパラメーターを使うと、テキストを斜体、太字、あるいはその両方にすることができます。

//@version=6
indicator("Text size showcase", overlay = true)
var t = table.new(position.bottom_center, 1, 2, bgcolor = color.yellow, frame_color = color.black, frame_width = 1)
if barstate.islastconfirmedhistory
t.cell(0, 0, "text_size = size.huge", text_size = size.huge)
t.cell(0, 1, "text_size = 60, bold & italicized", text_size = 60, text_formatting = text.format_bold + text.format_italic)
ストラテジー注文のトリミング
ストラテジースクリプトを積極的に活用されている方はご存知かもしれませんが、Pine v5では「ディープバックテスト」モードを使用しないかぎりシミュレーション可能な取引回数は9000回までで、それを超えるとストラテジーの計算が停止してエラーが発生します。こうした制限は取引のシミュレーションを頻繁に行ってアラートトリガーを作成するストラテジーにとって、とりわけ不便なものでした。
Pineスクリプト® v6では、ストラテジーが9000件の取引制限に達したからといって計算が止まったりエラーが発生することはありません。そのかわりに、ストラテジーは古い注文を削除して新しい注文のためのスペースを確保します。トリミングされた注文は ストラテジーテスター (Strategy Tester) には表示されませんが、ストラテジーは問題なく計算を続行します。トリミングされていない注文の中で最も古い取引のインデックスを確認するには、新しく用意された strategy.closedtrades.first_indexの変数を使用できます。このインデックスは、strategy.closedtrades.*() 関数呼び出しで trade_num を引数として使用できます。
負の配列インデックス
Pine v6では、array.get()、array.set()、array.insert()、および array.remove() 関数に負の index を引数として指定できるようになり、 配列の末尾から順に要素を参照できるようになりました。たとえば、array.get(myArray, -2) を呼び出すと、myArray の最後から2番目の要素が取得され、array.get(myArray, array.size(myArray) – 2) と指定した時と同じ動作になります。
Pineスクリプト®の操作について最新の改善点を知りたい場合には「ユーザーマニュアル」の「リリースノート (Release notes)」をご覧ください — v6 のセクションには、本ブログ記事で紹介しきれなかった変更内容も掲載しています。
以上の機能が私たちが考えているように皆様のお役に立つものであれば幸いです。そして、このプラットフォームをできるかぎりベストなものにしていくためにも、引き続きフィードバックやご提案をお寄せください。私たちがTradingViewを構築しているのは、ほかでもない皆様のためです。ご意見いつでもお待ちしております。
— チーム・トレーディングビュー