前回までの投稿では、移動平均線をプロットし、ゴールデンクロスが起こったら買いシグナル、デッドクロスが起こったら売りシグナルをプロット表示するコードの書き方を説明しました。
こんな単純なトレードルールで本当に利益が出せるのでしょうか?
移動平均線を使ったトレードについては、本やネットでもいろんな意見が飛び交っていますが、大事なのは自分の目で確かめること。論より証拠です。自分でバックテストをして確かめてみるためのコードを書いてみましょう。
まずは前回書いたスクリプト例6を見てください。
(例6)
//@version=5
indicator(“移動平均2本”, overlay=true)
//移動平均線の期間を入力できるようにします
i_smaShort = input.int(defval=10, title=”Short SMA”)
i_smaLong = input.int(defval=100, title=”Long SMA”)
//移動平均線を計算します
sma_short = ta.sma(source=close, length=i_smaShort)
sma_long = ta.sma(source=close, length=i_smaLong)
//売買のシグナルを定義します
buyCondition = sma_short > sma_long and sma_short[1] <= sma_long[1] //売りのシグナルを定義します sellCondition = sma_short < sma_long and sma_short[1] >= sma_long[1]
//移動平均線をプロットします
plot(series=sma_short, color=color.green)
plot(series=sma_long, color=color.red)
//売買シグナルをプロットします
plotshape(series=buyCondition, style=shape.triangleup, color=color.green, size=size.tiny, location=location.belowbar)
plotshape(series=sellCondition, style=shape.triangledown, color=color.red, size=size.tiny, location=location.belowbar)
冒頭のスクリプトタイプの宣言文
上記のコード例6の冒頭部分を見てみましょう。
2行名が下記のようになっています。
indicator(“移動平均2本”, overlay=true)
これはスクリプトタイプを宣言するコードです。それ以下に書かれたコードがインジケーターをプロットするためのコードであることを意味しています。
バックテストをするためには、バックテストのスクリプトタイプを宣言する以下のコードに書き換えます。
strategy(“移動平均2本”, overlay=true)
こう書くことで、それ以下に書かれたコードがバックテスト用のコードであることを宣言することになります。
売買注文
バックテストを行うためには、過去のチャート上で買い注文、売り注文を出したと想定して、その結果を記録、集計する必要があります。記録、集計する部分はTradingViewのプラットフォーム上でやってくれますので、ユーザーがしなくてはならないことは、どんな時に買い注文を出し、どんな時に売り注文を出すか、をコードを書いて指示することです。
買い注文を出すコード自体は下記の通り簡単です。
買いのエントリー注文:strategy.entry(id=”long”, direction=strategy.long)
ロングポジションとは、値上がりを期待して株などを買って保有している状態のことです。
逆に値下がりを期待して空売りしている状態のことをショートポジションと言います。
引数の説明をします。
id=”” は、ポジションの識別名で、自分がわかりやすい名前であれば基本的になんでも結構です。私は単に買いのエントリーオーダーはlong, 売りのエントリーオーダーはshort としています。このid=”long”やid=”short”は、ポジションをクローズするオーダーを出すときに、どのポジションをクローズするのかを指定し、システムがそれを識別するために使われます。
direction=strategy.long は買いのエントリーオーダーの意味です。
ここを、direction=strategy.short とすると売りのエントリーオーダーになります。
ただ単に strategy.entry(id=”long”, direction=strategy.long) というコードを書くと、システム上では無条件にチャート上の最初のローソク足で買い注文が出てしまいます。
そのため、どういう条件の時に買い注文を出すのかを記述しなくてはなりません。
買い発注の条件を書く(if 条件指定)
ここでは二本の移動平均線がゴールデンクロスしたら買い注文を入れるテストをしようとしています。
すでに前回の投稿で買い発注の条件「buyCondition」というbool変数を作っていましたね。
これを活用して、「buyCondition」が true(真)になったときに買い注文 strategy.entry() をいれるコードを書きます。
日本語で書くと、
もしbuyCondition が trueであれば、
買い注文を入れる
というコードを書きます。下記のようになります。
if buyCondition
strategy.entry(id=”long”, direction=strategy.long)
if は英語で「もし何々ならば~」という意味です。
if buyCondition と書くと、もしbuyCondition の条件にチャートが合致したら、という意味になります。
改行して if buyCondition の次の行に、左側にインデントスペースを空けて、strategy.entry(id=”long”, direction=strategy.long) を書きます。TradingView のPineエディタでコードを書いている場合、if buyCondition と書いて改行するだけで、自動的に左側にインデントスペースを空けてくれるはずです。
追加コードをどこに書くか?
この買い発注の2行のコードを冒頭の例6のコードに書き加えるわけですが、どこに書き加えたらよいでしょうか?
コンピューターのプログラムは、上から下に順番に処理されていきます。
if buyCondition のように条件していしていますので、buyCondition という条件を定義している行より下に、この追加2行を書き加えます。
buyConditionを定義した後であれば、次の行でも、もう少し下の行でも、論理矛盾を起こしていない限り問題ありません。同時に、あとから追加編集するかもしれないので、見やすさにも気を付けましょう。
ここでは「//売買りシグナルをプロットします」の行の上あたりに挿入することにします。
このページの最後の例7のコードの太字部分を確認してください。
売り注文を出してポジションをクローズする
次に二本の移動平均線がデッドクロスしたら売り注文を出して、ロングポジションをクローズするコードを書きます。
バックテスト上でポジションをクローズする(手仕舞う)ためのコードは次の2種類があります。
strategy.close()
strategy.exit()
strategy.close()関数は、最も単純にポジション決済する成行注文のコードです。次のセッション(次のローソク足)のopen値段(寄付き値段)で決済注文が約定される処理をします。
strategy.exit()関数は、指値や逆指値をする際に使うコードです。
ここではstrategy.close()関数を使ってコードを書きます。
前回の投稿で、二本の移動平均線がデッドクロスしたら、売りの条件変数sellConditionが true となるコードをすでに書いてありますので、この条件変数 sellConditionをそのまま活用します。
日本語で書くと、
もし sellCondition が trueであれば
決済売り注文を入れる
という意味のコードを書きます。下記のようになります。
if sellCondition
strategy.close(id=”long”)
とてもシンプルですね。
ここでは、引数 id=”long” が重要です。買いエントリーするときも引数 id=”long”というポジションに名前を付けていたので、この名前のついている買いポジションを決済する注文を出してくれます。
この引数を書き間違えて、例えば id=”Long” と大文字で書き始めてしまったら、id=”long”のポジションのことではない、とシステム上扱われてしまうので、決済注文が出されません。
この売り注文のコードの2行をどこに追加するか?ですが、考え方は買い注文のコードの追加位置と同じです。売り注文の条件として、if sellCondition のように指定しているので、sellConditionの変数を定義している行より下に、売り注文の2行のコードを追加しなくてはなりません。
後で編集する際の見やすさも考えて、買い発注のコード2行と売り発注のコード2行を、下記の例7のように挿入してみます。
移動平均線クロスのバックテストコードの完成
これで、最もシンプルな移動平均線クロスのトレードのバックテストコードの完成です。
下記の例7のようなコードになるはずです。
例6との違いの部分を太字にしています。
1行ずつ読んでみて、理解、納得できるか確認してみてください。
(例7)
//@version=5
strategy(“移動平均2本”, overlay=true)
//移動平均線の期間を入力できるようにします
i_smaShort = input.int(defval=10, title=”Short SMA”)
i_smaLong = input.int(defval=100, title=”Long SMA”)
//移動平均線を計算します
sma_short = ta.sma(source=close, length=i_smaShort)
sma_long = ta.sma(source=close, length=i_smaLong)
//買いと売りの条件を定義します
buyCondition = sma_short > sma_long and sma_short[1] <= sma_long[1] sellCondition = sma_short < sma_long and sma_short[1] >= sma_long[1]
//買いの条件の時に買い発注を出します
if buyCondition
strategy.entry(id=”long”, direction=strategy.long)
//売りの条件の時に売り発注を出します
if sellCondition
strategy.close(id=”long”)
//移動平均線をプロットします
plot(series=sma_short, color=color.green)
plot(series=sma_long, color=color.red)
//売買シグナルをプロットします
plotshape(series=buyCondition, style=shape.triangleup, color=color.green, size=size.tiny, location=location.belowbar)
plotshape(series=sellCondition, style=shape.triangledown, color=color.red, size=size.tiny, location=location.belowbar)
保存を押すとコンパイルされます。
「チャートに追加」または「更新をチャートに反映」を押すと、チャートに上記コードが反映され、バックテストが実行されます。
バックテストの結果を確認するためには、「ストラテジーテスター」のタブを選択します。
