みなさま、明けましておめでとうございます。本年もどうぞ当ブログをよろしくお願いいたします。
ということで、新年一発目の記事は、前回記事の応用として黒三兵が出現した場合にエントリーを待つストラテジーを作成してみようと思います。
1,赤三兵・黒三兵とは?
そもそも、赤三兵・黒三兵とはなに?という方のために説明します。
赤三兵は、以下のように陽線が3つ連続で続いた状態のことです。
対して、黒三兵は以下のように陰線が3つ連続で続いた状態のことです。
私の場合、チャートの設定で陰線を赤にしているので紛らわしくなっていますが、
陽は赤・陰は黒
と覚えてください。
2、エントリー条件について整理する
では今回は、先ほどの黒三兵に注目して、こいつが出現したのをトリガーとしてエントリーするロジックを書いていきましょう。
詳細な条件は以下の通りとします。
【エントリー条件】
1,黒三兵が出現する
2,黒三兵1本目の足の始値を超える足が出現したら、その次の足の始値でロングエントリー
【クローズ条件】
1,赤三兵が出現した段階でクローズする
今回も、複数条件でエントリーする必要があるので前回の記事を読んでいないかたは、そちらから読んでいただくと頭の整理ができるかと思います。
今回のコードを組むと、以下のような出力結果を得ることができます。
黒三兵を検出した場合に★マークを描画し、かつ、エントリーする価格ラインに●マークを描画します。
では、実際に書いたコードをもとに説明していきます!
3,コード
今回記述したコードはこんな感じになりました。
分かりやすさを優先しているので「え、そここんな風に書く必要ないでしょ」的な指摘はなしでお願いします。
実際に使用する方は以下からコピペよろしくです。
(インデントなどが正しく反映されないので、ペーストしてから多少体裁を整えないとTradingViewがエラーを吐くので注意してください)
//@version=5
strategy(“黒三兵”, overlay=true, margin_long=100, margin_short=100)
//変数用意
//黒三兵の検出結果を格納する変数
bool1 = false
//黒三兵を何度も検出しないようにするために使用する変数
var bool2 = true
//黒三兵を検出した際にエントリーする価格を格納しておく変数
var open_price = 0.0
//【リセット処理部】すべての変数をリセットして次の黒三兵に備える
if strategy.position_size[1] == 1 and strategy.position_size[0] == 0
bool1 := false
bool2 := true
open_price := 0.0
//黒三兵検出部
bool1 := (open[2] – close[2]) > 0 and (open[1] – close[1]) > 0 and (open[0] – close[0]) > 0
//エントリー価格(1本目の始値)格納部
if bool1 and bool2
open_price := open[2]
//エントリー価格のマークを描画
plot(open_price > 0 ? open_price:na,”1本目の始値”,style=plot.style_circles)
//これら条件がそろった場合に黒三兵と判定する(複数判定を防ぐため)
plotchar(bool1 and bool2,”Kurosanhei”,color=color.orange,location=location.belowbar)
//【エントリー部】
//open_priceにはエントリーしたい価格が代入されているのでこれを超えたかどうか判断する
//今回は終値が超えていたらエントリーするようにしている
if open_price != 0 and close > open_price
strategy.entry(“Long”,strategy.long)
//赤三兵が現れた時点で決済する
strategy.close(“Long”,(close[2] – open[2]) > 0 and (close[1] – open[1]) > 0 and (close[0] – open[0]) > 0)
//一度しか検出しないようにする工夫
if bool1[0]==true and bool1[1]==false
bool2 := false
4,コードの解説
1,ストラテジー名を決める
今回はインジケーターではなくストラテジーを作成したいのでstrategyで書き始めます。
名前は”黒三兵”というストラテジー名にしました。
ここは対して重要なところはないです。
2,変数を用意する
ここでは、コード中で使用する変数を用意しています。
bool1は、黒三兵が出現した際にtrueを格納する変数として用意しています。
bool2は、黒三兵が出現した際に重複して検出しないようにするために用意しています。
どういうことかというと、陰線が連続で出現した場合に黒三兵を検出してしまう可能性があります。
今回のコードは黒三兵が出現した際には★マークが出るようになっていますが、bool2を用意しないと以下画像のようになります。
陰線が3本以上連続して出現した際に何度も黒三兵を検出しているのがわかるかと思います。
これを防ぐためにbool2という変数が後々役に立つわけです。
open_priceについては、黒三兵が出現した際にエントリーする価格を格納するための変数です。この変数は整数型ではなく浮動小数点型で宣言したいので、「= 0」ではなく必ず「= 0.0」と記述してください。
この辺の解説で「ん?」となった方は、以下の記事の3,4項をご参照ください。
3,リセット処理を記述する
この部分は、エントリーしてクローズする一連の流れが終わった際に、次の黒三兵の出現に備えて各種変数をリセットする役割を持っています。
strategy.position_size関数は各時点でのポジションサイズを取得できる関数で、
if strategy.position_size[1] == 1 and strategy.position_size[0] == 0
の部分は、「一つ前の処理ではポジションを1つもっていて、今回の処理ではポジションを持っていない場合に処理を実施」という意味です。
ただし、このままのコードであればstrategy.entryの際に発注サイズをqty=0.1などにした場合に、ポジションを持っているのに認識されません。
そのため、発注数量をqty=0.1などにしたい場合は、
strategy.position_size[1] > 0
と書き換えましょう。
ここについては、以前の記事の3-3項に詳しく記載していますので、ご参照ください。
4,黒三兵を検出する
ここでは、黒三兵を検出しています。
Pineスクリプトでは現在参照している足から相対的にどれだけ離れているかを数字で指定することで過去の値を参照できます。
たとえば、今の足から2つ前の足の終値は”close[2]”と書くことで参照できます。
ここでは、現在の足を含む3本の足で“始値から終値を引いた値が正”となっているかどうかを確認(要するに陰線かどうかを確認)しています。
それらを、andでつなぐことにより3本がすべて陰線の時にbool1という変数にtrueが入るようになります。
5,エントリー価格を格納する
次に、黒三兵がされたらopen_priceという変数にエントリーする価格を格納します。
現在の足を含めて黒三兵が成立している場合、2本前の足の始値をエントリーする価格にしたいという考えてストラテジーを作成しているため、2本前の足の始値を”open[2]”で取得し、open_priceという変数に代入しています。
bool2の役割については後程説明するので、ここでは無視していただいて結構です。
6,エントリーする価格を描画する
黒三兵が出現して、エントリーする価格も決まったら、チャート上にその価格を示すマークを描画する部分がここです。
描画するデータは、
open_price > 0 ? open_price : na
としています。
これは三項演算子といって、赤色部分の条件が成立する場合は青色部分が実行され、そうでない場合は緑色部分が実行される仕組みになっています。
何をしているかというと、黒三兵が出現した場合にopen_priceにエントリーする価格が格納されるわけですが、そうでない場合は常にopen_priceには0.0が格納されています。
つまり、open_priceをそのままチャート上に描画した場合、常に0ラインにマークが表示されるようになります。(以下画像参照)
これだとダサいので、三項演算子を使用し、黒三兵が出現した場合、つまりopen_priceが0より大きい際には描画を行い、それ以外の場合では描画しないようにしています。
7,黒三兵が出現した場合にマークを描画する
ここでは、黒三兵が出現した場合に星マークが出るようにplotchar関数を使用しています。
先ほどと同じく、bool2の役割については後程説明するので、ここでは無視していただいて結構です。
8,エントリーする
ここでは、open_priceよりも足の終値が超えていた場合にエントリーする処理を記述しています。
open_price != 0
を記述しないといけないということに注意しましょう。
open_priceは黒三兵が出現しない場合は常に0.0という値を持っており、
if close > open_price
という条件のみでエントリーすると、closeは常に0以上となる値なので毎回エントリーしてしまいます。
9,クローズする
エントリーした後は、ポジションをクローズしましょう。
ここでは、黒三兵の反対の赤三兵が出現した場合にクローズするようにコードを記述しています。
ここは黒三兵検出部分と大して変わらないところなので詳細は割愛します。
10,重複検出を防ぐ
最後に、黒三兵の重複検出を防ぐ部分です。
やっていることとしては、黒三兵を初めて検出したときにbool2にfalseが代入されるようにしています。こうすることで、黒三兵を初めて検出した際にのみ、bool1とbool2がともにtrueとなります。
逆に言えば、bool1とbool2が両方trueとなった場合は初めて黒三兵を検出したときのみですので、
bool1 and bool2
という条件を使用することで、黒三兵が初めて検出されたときのみ実行する命令が可能となります。
以降、詳細な処理として何を実施しているか説明します。
bool1には黒三兵の検出有無(trueなら検出、falseなら未検出)
が格納されています。また、
bool2の初期値はtrue
です。
そして、一つ前の処理でbool1がfalse、今回の処理ではbool1がtrueとなった場合は、今回の処理で初めて黒三兵を検出しているということなります。
そうなった際にbool2にfalseを代入することで、初めて黒三兵を検出したとき以外はbool1、bool2がともにtrueとならないようにしています。
この辺の処理はもっとうまい方法があるかもしれませんが、私はこれくらいしか思いつきませんでした。
5,まとめ
今回は、黒三兵を検出したのちにエントリーするロジックの作り方について考えてみました。
実際に皆さんでも組んでみるか、私のコードをコピペして改良することでつよつよロジックを作ってみてください。
また、宣伝にはなりますがPineスクリプトにて作成したストラテジーの最適化を支援するツールを販売していますので興味があれば覗いてみてくださいね!
では、また次回の記事でお会いしましょう!
本記事を気に入っていただけたらブックマークお願いします!また、ツイッターもやってるのでフォローよろしくお願いいたします!
Twitter : makoto(@Makoto_beginner)
また、記事中で不明なことや間違い等ありましたら以下のコメント欄からコメントいただけると幸いです。
皆様のコメントをもとにどこよりもわかりやすいブログを目指していきます。