【入門編】Pineスクリプトで大事な変数/関数はこの3つ!(サンプルコード付き)

この記事には広告・プロモーションが含まれています

ヘッダー

TradingViewのPineスクリプトは、カスタムインジケーターやストラテジーを作成するためのスクリプト言語です。価格データやテクニカル指標を使用して取引のシグナルを生成したり、独自のテクニカルインジケーターを作成したりするために使用されます。

JavaScriptやPythonに似た構文を採用しており、比較的読みやすく理解しやすいです。逆にシンプルであるからこそ、MQL4/MQL5で作ってきた者として、難しく感じるときがあります。

Pineスクリプトで大事な変数/関数の使い方を3つ解説

そこで普段からインジケーターを制作しているプログラマーが実際に作る上で押さえておきたい変数/関数を3つ選んでみました。Pineスクリプトをこれから学んでいこうという方は参考にしてみてください。

bar_indexの使い方

bar_indexは、Pineスクリプトで非常に重要な変数であり、どのバー(ローソク足)を指しているのかを示す値です。

TradingViewチャートの仕組み

チャートを左にスクロールしたときに対応するデータがチャートに読み込まれます。読み込みの限界は過去データがないか、アカウントタイプで許可する最大のローソク足の数となります。

bar_indexの位置

過去のローソク足で表示に対応される最初のローソク足から計算がスタートされ、その最初のローソク足が基準となります。その基準が0となり、bar_indexが0です。その次のローソク足がbar_index=1となります。

現在のローソク足が何番目か分からなくてもbar_indexを使えば分かるので優れモノです。

bar_indexを使う機会はいつ?

個人的な使い方としてはbar_indexはラインやラベルのオブジェクトを作成するときに使います。




bar_indexのサンプルコード、具体例

//@version=5
indicator("bar_indexとbarstate.isfirst/barstate.islast", overlay=true)

//20期間の最高値
highest_price = ta.highest(20)
//20期間の最安値
lowest_price = ta.lowest(20)

//最初に表示
if (barstate.isfirst)

	//ラベルで表示
    var label first_lable = label.new(bar_index, low, str.tostring(bar_index), yloc=yloc.belowbar, style=label.style_none)

//最後に表示
if (barstate.islast)

    //ラベルで表示
    var label last_lable = label.new(bar_index, high, str.tostring(bar_index), yloc=yloc.abovebar, style=label.style_none)

    //20期間の最高値ラインを作成
    var line high_line = line.new(na, na, na, na, width=2, color=color.aqua)

    //現在のバーの位置から-20の位置
    line.set_xy1(high_line, bar_index - 20, highest_price)
    
    //現在のバーの位置から+5の位置
    line.set_xy2(high_line, bar_index + 5, highest_price)

    //20期間の最安値ラインを作成
    var line low_line = line.new(na, na, na, na, width=2, color=color.orange)

    //現在のバーの位置から-20の位置
    line.set_xy1(low_line, bar_index - 20, lowest_price)
    //現在のバーの位置から+5の位置
    line.set_xy2(low_line, bar_index + 5, lowest_price)

ここが使い方のポイント

bar_indexがどうなっているのか、他の値は?そうなったときはlabel.new()でラベル作成がいちばんです。もちろんログでの出力でもいいのですが、扱いやすさ見やすさではこちらに軍配が上がります。

 

barstateの使い方

2つ目はbarstateです。どのローソク足の状態かを示します。

なぜこれが重要かというと、特定のローソク足のときに実行する必要があるからです。そうでないと計算量が大きくなり、遅くなります。ブラウザで実行するのでできるだけ軽く処理をすることを求められます。

ローソク足の状態を示すものは7種類あります。

barstate.isconfirmed スクリプトが現在のバーの終値(バーの確定時)で計算された場合に true を返します。次にスクリプトが計算されるのは新しいバーのデータです。
barstate.isfirst 現在のバーがバーセットの最初のバーなら true を返し、そうでない場合は false を返します。
barstate.ishistory 現在のバーが過去バーの場合は true を返し、そうでない場合は false を返します。
barstate.islast 現在のバーがバーセットの最後のバーの場合はtrueを返し、そうでない場合はfalseを返します。この条件はバーセットのすべてのリアルタイムバーでtrueです。
barstate.islastconfirmedhistory 市場がクローズしている場合、スクリプトがデータセットの最後のバーで実行されていれば true を返します。市場がオープンの時は、スクリプトがリアルタイムバーの直前のバーで実行されていれば true を返します。それ以外の場合は false を返します。
barstate.isnew スクリプトが新しいバーで現在計算している場合はtrueを返し、そうでない場合はfalseを返します。この変数は、過去バーで計算される時または新しく生成されたリアルタイムバーの最初の更新時に計算される時にtrueです。
barstate.isrealtime 現在のバーがリアルタイムバーである場合はtrueを返し、そうでない場合はfalseを返します。

この中でよく使われるものは、barstate.isfirstとbarstate.islastです。インジケーターをセットしたときの最初と最後になります。

barstate.isfirstの使い方

データの内、いちばん左端(bar_indexが0のとき)にbarstate.isfirstがtrueとなります。最初の変数を初期化するときに使います。
(MQL4/MQL5ではvoid OnInit()です)

barstate.islastの使い方

最後のローソク足(最新のローソク足、bar_indexが最大値)まで到達したときに、barstate.islastはtrueとなります。最後にまとめてラインやラベルを描きたいときによく使います。

ここが使い方のポイント

barstate.islastが実行されるのは最後のローソク足(最新のローソク足)となります。下のコードではまずはラベルを表示し、新しいローソク足ができるごとに最新のローソク足へと位置を変更しています。チャートが更新されるごとにどこが計算されて、再度計算してから再描写しなければいけないかを考えながらコードを作っていきましょう。

barstate.isfirstとbarstate.islast

barstateのサンプルコード、具体例

//@version=5
indicator("barstate.isfirstとbarstate.islast", overlay=true)

// 最初のバーでだけメッセージをプロット
if barstate.isfirst
    label.new(bar_index, low, text="barstate.isfirst", color=color.new(color.silver, 0), style=label.style_label_upper_left)

var label islast_label = label.new(bar_index, high, text="barstate.islast", color=color.new(color.silver, 0), style=label.style_label_lower_right)

// 最後のバーで位置を修正
if barstate.islast
    label.set_xy(islast_label, bar_index, high)

barstate.ishistoryとbarstate.isrealtime

現在のローソク足がリアルタイムで更新されているかを判定するのが、barstate.isrealtime

確定している過去のチャートかを判定するのが、barstate.ishistory

ということで、インジケーターでは使う頻度は高くないかもしれませんが、ストラテジーでは結構使うことが多いです。

リペイントしないインジケーターの特徴

確定した状態になったことを表すのがbarstate.isconfirmedになります。要するにすべてのチャートの終値が確定した状態です。barstate.isconfirmedもオープンソースのインジケーター内でよく使われているのを見かけます。

barstate.isconfirmedとなって、計算されたものは確定した結果となります。barstate.isconfirmed内で計算されたものは基本リペイントしません。逆にbarstate.isconfirmedが使われていないからといってリペイントするというわけでもありません。

barstate.isconfirmedがどこで使われているか、コードを見る上で重要なポイントとなります。要チェックです。

 

request.security()の使い方

Pineスクリプトでよく使うのがrequest.security()です。上位足の状態や他の銘柄もこの関数によって簡単に取得できます。

他にもrequestの種類がありますが、request.security()だけでも十分です。

request.currency_rate() 引数 from の通貨を引数 to の通貨へと変換する際に使用されるレートの値を与えます。
request.dividends() 指定したシンボルの配当データをリクエストします。
request.earnings() 指定したシンボルの収益データをリクエストします。
request.economic() シンボルの経済データをリクエストします。経済データには、国の経済状態 (GDPやインフレ率など) や特定の産業 (鉄鋼生産量やICUベッド数など) の情報が含まれます。
request.financial() シンボルの財務系列をリクエストします。
request.quandl() Nasdaq Data Link (旧Quandl) のシンボルのデータをリクエストします。
request.security() 他のシンボルおよび/または時間足からのデータをリクエストします。
request.security_lower_tf() 指定したシンボルのデータを、チャートよりも下位の時間足からリクエストします。この関数は、現在のチャートのバー内で、それよりも下位の時間足のバーがクローズするごとに1つの要素を含んだ配列を返します。5分足チャートで timeframe の引数を “1” とすると、配列のサイズは通常5となり、配列の各要素は1分足のバー内にある expression の値を時間順に並べたものとなります。
request.seed() ユーザー管理のGitHubリポジトリにデータをリクエストして、それを1つの系列として返します。新しくデータを追加する方法については here に詳しいチュートリアルがあります。
request.splits() 指定したシンボルの株式分割データをリクエストします。
ここが使い方のポイント

MQL4/MQL5ではマルチタイムフレームをするときにひと手間必要なのですが、Pineスクリプトではrequest.security()で一発で出てきます。インジケーターを作ってて思ういちばん便利な機能です。

request.security()を使ったインジケーター

実際にrequest.security()を使ったインジケーターを公開してます。




request.security()のサンプルコード、具体例

//@version=5
indicator('MTF Heikinashi Bar', overlay=false)

mtf = input.timeframe(title='MTF', defval='1D')

heikin_open = request.security(ticker.heikinashi(syminfo.tickerid), mtf, open)
heikin_close = request.security(ticker.heikinashi(syminfo.tickerid), mtf, close)

p = plot(0, color=color.new(color.gray, 0), editable=false)
p1 = plot(1, color=color.new(color.gray, 0), editable=false)

fill(p, p1, color=heikin_open <= heikin_close ? color.green : color.red, title='Heikin color', transp=0)

MQL4/MQL5だと大変な行となりますが、Pineスクリプトでしたら数行でできてしまいます。

ここがポイント

実はrequest.security()は作る上で神経を使う関数です。まずはデータがあるのかどうか、現在の時刻と照らして正しいデータなのか、取得した先のデータが更新されたら?など、頭に入れておきたいです。

コメント