はじめに
皆さん、こんにちは。
今回はTradingViewに関する話題です。TradingViewはチャートを見て分析に使えるのは勿論、トレード手法の検証に使えるのが良いですよね。
別の記事に利用にあたっての参考サイトをまとめていますので、良ければこちらもどうぞ。
www.good-investor.onhydech.com
さて、私はTradingViewでよくトレード手法の検証をします。その検証に利用されるのがPine Scriptと呼ばれるプログラミング言語です。
この言語を用いてトレーディングルールを記載することで手法のバックテストが可能になります。しかし、他のプログラミング言語と比較して少し毛色が異なるのでちょっと特殊な書き方をしないといけないことが多々あったります。
そういうこともあり、自分が躓いた気付きをまとめていきます。
※本ページは自分がTradingViewのPineスクリプトを利用してインジケータ/ストラテジーを実装する際に調べたコーディングTipsです。自身の備忘録もかねて記載していきます。
状態を保存するための変数の利用方法
Pine Scriptの仕様に関して
プログラミング言語だと、システムの状態を保存するのに変数とかを利用しますね。この変数に格納した状態に応じて処理を変える必要が多々あるからです。
他のプログラミング言語同様に変数はPine Scriptでも利用可能ですが、大きく違いがあります。
これはPine Scriptの仕様による部分なのですが、
Pine Scriptで書いたコードは、各ローソク足が確定するたびに処理が実行される
という特徴があります。
少し説明のために具体的なコードを書いてみます。
// 初期化 flag= 0 // メインロジック if condition == 1 and flag == 0 strategy.order() flag := 1
少しプログラミング言語を書いたことがあるかたは上記のように書きたくなるはずです。
まずは必要な変数の初期化を行い、その変数に値を代入する。
しかし、Pine Scriptではこのように書くと期待した通りの処理になりません。これが先に説明した「各ローソク足が確定するたびに処理が実行される」という特徴のためです。
毎回上記コードが実行されるため、初期化コードも毎回実行されてしまいます。
以上から、折角「flag」に値を入れても毎回「0」ということになります。
では、どう実装するか?
はい、解説が長いですね。では、どのように実装するかですが、以下のコードで実現できます。
// 初期化 flag = 0 flag := nz(flag[1]) // メインロジック if condition == 1 and flag == 0 strategy.order() flag := 1
では一つ一つ説明していきます。
まずは、初期化の以下の部分です。というかここが全てです。
// 初期化 flag = 0 flag := nz(flag[1])
Pine Scriptは、時系列データを扱うことを前提としているため配列が利用できます。
普段意識せずに「flag」など変数名を書いていますが、flag[0]と同じ意味になります。配列の「0」ですが、最新のローソク足時点でのデータを意味しています。flag[1]と書けば1つ前のデータです。
初期化では変数を定義した後、1つ前のデータをロードしていることになります。これにより毎回のローソク足ごとに実行されるコードを書いている中で、前回の「flag」に格納したデータを取得できます。
「flag」にデータを格納するメインロジックには変化がありません。あくまで初期化部分の処理を変えるだけです。
// メインロジック if condition == 1 and flag == 0 strategy.order() flag := 1
ちなみに、初期化部分で利用している「nz関数」に関しては、引数がNaN値であった場合に「0」に置き換えて返却する動作をします。
これは一番初めのローソク足を処理する際の例外を処理するために利用しています。※0番目のローソク足は存在しないため。
まとめ
はい、今日は久しぶりにTradingViewのPine Scriptに関してでした。
はじめは他のプログラミング言語と違い少し違和感があるかもしれませんが、一度覚えれば簡単です。