今回はTwitterで「特定の時間を指定してエントリーやクローズするストラテジーはどのように作成したらよいか」と質問をいただいたのでその内容について実際にストラテジーを作成してみました。
コード付きでやさしく解説するので、最後までお付き合いください!
1,作成するストラテジーの条件
今回作成するストラテジーの条件は以下のように設定しました。
1,エントリーおよびクローズする時間を指定
2,エントリーする時刻の終値を取得
3,その終値に指定した値幅を足した価格に逆指値をおいてロングエントリー
4,エントリー後、1で取得した終値まで価格が下がれば損切
5,損切がない場合は、指定した時刻になったらクローズ
2,ストラテジー作成におけるポイント
今回のストラテジー作成におけるポイントは主に2つあります。
1,時刻を取得するにはhour変数とminute変数を使用する
2,逆指値注文にはstopを使用する
一つずつ解説していきます!
(1)時刻を取得するにはhour変数とminute変数を使用
Pineスクリプトにはhourとminuteというビルトイン変数が用意されています。
これらの変数は、
hour = 現在のローソク足の時間(時)を取得(UTC)
minute = 現在のローソク足の時間(分)を取得(UTC)
することができます。
labelを用いて、各ローソク足の上に時、下に分を表示するとこんな感じになります。
ここで注意すべきなのがhourとminuteで取得できるのはUTC時刻であるということ。
上記画像を見ればわかりますが、下部の時刻が20:00となっているのにhourは11となっています。
日本はUTC+9:00なので注意しましょう!
(2)逆指値注文にはstopを使用する
続いてややこしいのがこれです。結論から申し上げますと、
stopは逆指値注文注文を行うオプションである
ということに注意しましょう。
Pineスクリプトでは、ストラテジーのエントリー・クローズに使用するstrategy.entryやstrategy.exitのオプションとしてlimitやstopが存在します。
これ、ぱっと見
stop ⇒ 損切指値注文
のように感じません?
実は、stopとは損切指値ではなく逆指値注文のことなんです!
ちなみにlimitと比較すると、
limit ⇒ 通常の指値注文。ロングなら今の価格より下に、ショートなら今の価格より上に注文を置く。
stop ⇒ 逆指値注文。ロングなら今の価格より上に、ショートなら今の価格よりしたに注文を置く。(指値と言っておきながら成行で執行される)
こういった違いがあります。
今回のストラテジーの条件として、指定時刻の終値から+指定幅分上昇したらロングエントリーするので条件的に逆指値を使用せざるを得ません。
そのため、今回のストラテジーではstopのオプションを使用します♪
3,作成したコード
では、今回作成したコードを公開します。
タイトルは適当なので各自変えてください。
また、貼り付け時にインデントなどの情報が失われているので、if文などの後に適宜インデントを入れてください。(そうしないとエラーが出ます)
//@version=5
strategy(“TimeOCST”, overlay=true)
//エントリーする時間を指定する変数
entry_hour = input.int(title=”エントリータイム(時)”,defval=10,minval=0,maxval=23)
entry_minute = input.int(title=”エントリー時間(分)”,defval=20,minval=0,maxval=60)
//クローズする時間を指定する変数
close_hour = input.int(title=”クローズタイム(時)”,defval=23,minval=0,maxval=23)
close_minute = input.int(title=”クローズ時間(分)”,defval=30,minval=0,maxval=60)
//UTCとの時差を指定する変数
t_d = input.int(title=”UTCとの時差(時)”,defval=9,minval=0,maxval=23)
//終値を格納する変数
var close_price = 0
//エントリーする価格までの幅を指定する変数
width = input.float(title=”エントリー価格までの幅”,defval=100)
//エントリーと損切指値を格納する変数
var entry_price = 0.0
var stop_price = 0.0
//指定時刻になった場合にTrueとなる変数entryを定義
e = entry_hour == hour+t_d and entry_minute == minute
//エントリーと損切指値を格納する
if e
entry_price := close + width
stop_price := close
//格納している終値から指定したwidth分離れたときにエントリーする(stopは損切ではなく逆指値の意味)
strategy.entry(“Long”, strategy.long, stop=entry_price, when=e)
//あわせて、指定価格になったら決済する注文を入れておく
strategy.exit(“Stop”,”Long”,comment=”Stop”,stop=stop_price)
//指定時刻になった場合にTrueとなる変数cを定義
c = close_hour == hour+t_d and close_minute == minute
//指定時間になったとき(変数cがTrueとなったとき)にクローズする
strategy.close(“Long”,when=c,comment=”Close”)
各箇所について解説します。
(1)オープン・クローズを指定する部分
ここでは、エントリーと決済する時間を指定するためにそれぞれをentry_hourやclose_hour等の変数で受け取っています。
defvalでは適当な値をデフォルトにしているので、ここも適当に変えていただいて結構です。
また、日本時間とUTCの差を解消するためにUTCとの時差を入力する欄を設けています。しかし、基本的に日本でしか使用しないと思うので9のままで問題ないです。
(2)終値を格納する変数の用意
ここでは、終値を保存するための変数を用意しています。
あわせて、その終値からいくらの値幅離れたらエントリーするかの、幅を指定する変数widthを用意しています。
(3)指定時刻になったらTrueとなる変数を用意
ここでは、指定時刻になったらTrueとなるブール値を格納する変数eを用意しています。
このeがTrueとなった場合は指定時刻になったということなので、このeを条件として
終値を格納しエントリーしていきます。
(4)エントリー価格と逆指値価格を格納
指定時刻になったらエントリー価格(終値+自分が指定した幅)と逆指値価格(その時の終値)を変数に代入する部分です。
(5)エントリーと逆指値注文の設定
39行目でエントリーをしています。when = e なので指定時刻になったときにのみエントリーする仕組みとしています。
また、41行目で合わせて逆指値用のexit注文を出しています。
コメントアウトで書いていますがstopは逆指値の意味なので、exitではstopオプションを使用しています。
(6)クローズ注文の設定
もし損切されなければ、指定の時刻になった場合にTrueとなるような変数cを用意しています。
これがTrueになった場合は、47行目のclose注文が発動して成行で決済されます。
4,注意点
このストラテジーの注意点としては2つあります。
1,エントリーするまでの終値からの幅を小さくすると正しくバックテストできなくなること
2,UTCとの時差を9時に設定すると8時以前からのエントリーができなくなること
どういうことか説明します。
(1)エントリーまでの値幅を小さくすると正しくバックテストできなくなる
終値からエントリーするまでの値幅(以後、width)を小さくすることで、エントリーとクローズの価格差が限りなく0に近づいていきます。
以下にwidthを限りなく0にした状態でストラテジーのテストを行ったときの画像を掲載します。
いずれも同じ設定での結果になりますが、1枚目の写真はエントリー直後にクローズしていますが、2枚目の写真ではエントリーのみしかしておらずクローズされていません。
しかし、ローソク足はある一定期間の値動きの高値・安値・始値・終値を表したものでしかなく、その期間中の値動きがどうだったかの情報はわかりません。
例えば、以下の画像は上下に同じローソク足を示した図になります。また、右側にはその時の値動きのグラフを書いています。
このように同じローソク足でも値動きが異なることがあります。
では、今回のようにwidthを小さくした状態にしてエントリーとクローズの価格差が限りなく0になるとどうでしょうか。
仮に上図の上のような動きであれば無事クローズされずにエントリー可能です。
しかし問題は下の値動きです。このような値動きであれば同じローソク足の中でエントリーとクローズが出ないとおかしいはずですよね。
しかし、TradingViewの仕様上エントリーできてしまうのです。(しかもエントリーしたローソク足が陽線なら必ず)
ということは、そのローソク足が陰線か陽線かによって以下のように対応を変えているということになります。
陽線 : エントリーできる
陰線 : エントリーしても最小損失で損切
しかし、現実世界ではエントリーした際にその足が陽線になるか陰線になるかなんて先読みできません。(それができれば一瞬でお金持ちになれます)
ということで、後出しじゃんけんのロジックとなるため、値幅を小さくすることでほぼ儲かるバックテスト結果を出せるつよつよストラテジーができあがります。
しかし、現実世界では絶対に通用しないので気を付けてくださいね★
これを防ぐためにwidthは小さくしすぎないように注意しましょう!
(2)UTCとの時差を9時に設定すると8時以前からのエントリーができなくなる
これはしょうもない内容になります。
まず、ビルトイン変数hour がとりうる値は0から23です。
対して、エントリーする時間を格納する変数であるentry_hourの取りうる値も0から23までと設定しています。
ここで、エントリー条件eを見てみましょう。
UTCとの時差t_dを9に設定した状態だと、hour + t_d(UTCとの時差)がとりうる値は最小でも9にしかなりません。
つまり、entry_hourを8時以前に設定すると全くエントリーしなくなります。
正直、entry_hourの上限下限を9~32までにすれば解決しますが、少々不細工だったのでやめました。
ここは各自適当に改造して使用してください。
(※日本時間なんかきにしねぇ!って方は、そもそもUTCとの時差を0にすれば解決します)
5、まとめ
ということで、今回は特定の時間になったらエントリーとクローズするストラテジーの作成を行いました。
正直このままだと不便なところがたくさんあるので、考え方をベースにして各自改造してみてください。
では、次回の記事でお会いしましょう~
本記事を気に入っていただけたらブックマークお願いします!また、ツイッターもやってるのでフォローよろしくお願いいたします!
Twitter : makoto(@Makoto_beginner)
また、記事中で不明なことや間違い等ありましたら以下のコメント欄からコメントいただけると幸いです。
皆様のコメントをもとにどこよりもわかりやすいブログを目指していきます。