こんにちは。okometsubuです。
以前、RSIを使ったリバランスタイミング測定を検証してみました。それのRSI値を自動でメール送信する仕組みを作るのが今回の記事の目的です。
以下過去記事。全9回物のシリーズ。
RSIというテクニカル分析方法があります。以下RSIの説明についてauカブコム証券サイトより引用させて頂きます。
第8回 RSI(Relative Strength Index)|テクニカル分析ABC |ガイド・投資講座 |セミナー・マーケット情報|株のことならネット証券会社【auカブコム】
https://kabu.com/investment/guide/technical/08.html
つまり、RSIは買われ過ぎ、売られ過ぎに着目したテクニカル分析です。
株価が上昇し続ければ、即ち、買われ過ぎと判断し売りを考え、逆に下落し続ければ売られ過ぎという判断をし、買いを考えるというものです。~~~
計算式
以下の式でRSIを求めます。
最初に14日間RSIを求める式(公式1)
- A:14日間の値上がり幅の平均
B:14日間の値下がり幅の平均
RSIの計算式はauカブコムサイトより引用させて頂きました。これを検証した記事となっています。
ようするに、RSIがXX以上になったら売りリバランスを行い、RSIがYY以下になったら買いのリバランスを行うという検証を行いました。そこそこ検証結果も良かったことから、じゃあ早速実装してみようかと考えて行動に移すことにしています。
で、ここで問題だったのが、
「じゃあそのRSIの値を毎日チェックするのか!?クッソめんどい!!」
ってことです。毎日見るなんてナンセンス極まりないです。時間の無駄です。
その時考えていたのは以下の通り。
- IFTTT辺りにRSI取れるスクリプトあったらいいなぁ
- GASを使ってなんかRSIの値を取れるAPIとかあってそれを使えたらいいなぁ
- 最悪、超低電力自宅PCを定時に起動してRSIを取得するスクリプト作るかなぁ面倒だなぁ。
IFTTTの詳細はググってもらうとして、ようは色々なサービスと連携してくれる便利なサービスというものです。例えばある特定の時間になったらメールを送信するとかTwitterで教えてくれるとかそんな感じ。このサービスの中に対象銘柄のRSIがいくつになったらTwitterで教えてくれるレシピがあったら楽ちんだなぁと思っていました。
が、残念ながら見つからず。TSLA(テスラ)銘柄かつRSI80,20のレシピだけ見つけましたが、改修していいのかどうか、そもそもソースコードを入手できるのか等々がよく分からなかったので断念しました。
Google Apps Script、通称GASは存在は知っていて、何となく時間トリガーで起動してくれるし、株価の取得も自動でしてくれるっぽいことまでは知っていました。が、面倒くさがりーな私は一切手を付けづに生きてたので、今から1から調べるのも面倒だなぁ~とか思っていました。
そんな中、GASで実現可能と言う非常にありがたいコメントを頂いたため、今回ちょっと実装してみようと言う感じで実装しました。その備忘録となります。以下教えてもらった時の過去記事のあるコメント。
匿名さんのコメントで、スクリプトそのものを頂いてしまいました。超ありがたかったです!
この情報を元に、今回実装した内容を備忘録がてら残しておきます。
また、ソースは本当に匿名さんソースをちょっといじっただけなので、もし不都合ありましたらお知らせいただければ幸いです。一応コメントはインターネットで誰でも閲覧できる箇所にあるため、今回記事内容でも使わせて頂きます。
・・・といっても「匿名」なので不都合があっても本人確認できないから、何か連絡がきたらその時かんがえる!!
というわけで、早速スタートです!!
Googleスプレッドシート作成編
まずは兎にも角にもGoogleスプレッドシートを作成する必要があります。
私の場合はまず、「Googleドライブ」にWebブラウザからログインして、「新規」から作成しました。こんな感じですね。
で、ここで最初に問題が発生しました。
私のブログではRSIを取得する際、「^GSPC(※S&P500)」から取得していたのですが、なんとGoogleファイナンスからだと^GSPCが存在しませんでした!!
ということで、代わりに「.INX」というものを代用で使うことにしています。これもS&P500ですが、1927年からではなく、1970年頃からしか取得できませんでした。
ただ、こちらの.INXでRSIを確認した所、^GSPCのRSIと小数点以下の誤差しか無かったため、大きな問題は無く実装できましたので、この記事では「.INX」をRSIの指標として取り扱います。ふぅ。危ない所でした。
では改めて。
まず最初に以下をA1カラム辺りに入力します。
=GOOGLEFINANCE("INDEXSP:.INX", "price", DATE(1970,1,1), TODAY(), "DAILY")
こうすると、自動で「.INX」の登場時から本日TODAY()までの株価終値を取得してくれます。開始日がDATE(1970,1,1)の部分で終了日がTODAY()ですね。
RSIを出すため"DAILY"で終値を日々出してもらいます。
後、「XLK」の場合はこんな感じ。
=GOOGLEFINANCE("NYSEARCA:XLK", "price", DATE(1998,12,22), TODAY(), "DAILY")
適当に「XLK」でGoogle検索したら、その銘柄の名前"NYSEARCA:XLK"がでてくるのでそこを入れればOK.開始日も実際のXLKの開始日はYahoo Financeで分かるのでチェックすればよいでしょう。QQQも然り。
そうすると、こんな感じで勝手に値が自動で入力されます。便利な世の中です。
ということで、株価が分かったので次はRSIの計算式をスプレッドシートに入れていきます。
RSI算出編
今から書くことは非常に雑な実装方法です。本来は1行で書ける気がしますが、私に学が無いので、とにかく実装できれば良いや!という内容なことをお伝えしておきます。後、分かりやすい関数使うと、2,3年後に私自身が見直すときにすぐわかるので、極力簡単に実装しているというのも目的としてあります。
というか、GoogleFinance関数でRSIを取得できるものがあれば良かったんですけどねぇ・・・。Yahoo系のScriptなら関数あったりするのかな。完全に素人なので手で実装します。
ということでもう実装方法をとりあえずザックリ書きます。
C3カラムに以下を入れます。
=B3-B2
で、D3カラムにこれを入れる
=IF($C3>=0,$C3,0)
で、E3カラムにこれ
=IF($C3>=0,0,-$C3)
用意が終わったらこの3つをコピペで一気に下まで実装します。
要するに、D列には「正」の数値だけを、E列には「負」の数値の絶対値を入れるというわけです。RSIを計算するときに使う奴ですね。
で、その後、F16カラムにこれを入れる。
=SUM(D2:D16)/14
G16カラムにこれ
=SUM(E2:E16)/14
H16カラムにこれ
=(F16/(F16+G16))*100
つまり、H列で正側の平均、G列で負側の平均を出して、H列でRSIの結果を算出するというわけです。これで1回目のRSIが算出できるということです。
で、次からがまたちょっと工夫しなくてはいけません。第2回目からは、前回のRSIの結果を取り込んで平均を出す必要があるためです。
ということで、F17カラムにこれを入れます。
=(F16*13+D17)/14
G17カラムにこれ
=(G16*13+E17)/14
H17カラムにこれ
=(F17/(F17+G17))*100
こうすると、次回のRSIの結果がH列に誕生することになります。
3回目以降は2回目の計算式をそのまま使えばOKになります。
よって、後はこのF17~H17の3つのカラムをコピーして一気にしたまで張り付ければOKです。
出来上がるとこんな感じ。赤枠部分がその日のRSIの結果です。
さて、これでToday()、つまり今日の16:00までのRSIは取得できました。
しかしこれでは、その後の結果が分かりません。
Googleスプレッド(エクセル)になれていない私の苦肉の策として、寿命までの行を「追加」して、C~H列の末尾をコピーして、一気に更に貼り付けを行いました。
例えば、1年の営業日を大体250日として、後20年間スクリプトを動かしたいと思ったら、5000行の追加を行うのです。
A~B列は自動で後日計算されますので、そこは自動でドンドン追加されていきますが、C列からは空欄になるのでその対策です。あまり行を追加しすぎると重くなるので程々が良いかと思います。こんな感じ。赤線枠の中が下までずっと続いてる感じ。今日が2020/10/16 頃なので、その後ろ部分を一気に行を追加する感じですね。
さて、有限ではありますが、これで今後も自動的に値を取得してくれるようになりました。
が、これではどのRSIをアラートで送信すればいいか分かりません。なぜならRSIの結果列であるH列の末尾が当日というわけではなくなったからです。
ということで、私は適当にJ1カラムに以下の内容を入れました。
=INDIRECT("H"&counta(A:A))
counta(A:A)で、末尾のカラム数が分かります。そしてA列はGoogleスプレッドシートで自動的に算出されるカラムであり、この列の末尾が即ち、最新情報の行数となるのです。
後はINDIRECTを使って、A列の末尾の行数のHカラムの結果をJ1で表示している、と言う考えです。
いやー、我ながら力技。ま、個人でしか使わないしここに時間をかけても仕方ない。
ということでRSI自動算出スプレッドシート完成です!やったぜ!!
Google Apps Script作成編
では続いてスクリプトの作成です。
といっても、スクリプトは匿名さんに貰ったのがあるのでそれをザクッと使うだけです。本当にありがとうございました。
さて、Googleスプレッドシートの「ツール」から「スクリプトエディタ」を開きます。
そうすると、なんかエディタが開かれます。始めて使うのでよく分かってませんが、ここに関数を書けばいいと思いますので、ペタっとやります。以下頂いたソースを元にわたしが微調整したものです。以下にソース貼り付けておきます。
※はてなブログで綺麗に表示する方法あると思うけどよく分からないのでベタ打ち。
※メールアドレス部分やメール本文部分は各自修正ください。
※変数「ue」と「shita」の値も適宜修正ください。
※動作を保障するものではありませんし、将来使えなくなるかもしれません。参考程度にして頂ければと思います。
//=========以下の行からスタート===========
function checkPrice() { //1行目を書き換え
SpreadsheetApp.flush(); //シートの再描画を行い、スプレッドシート関数の再計算を実行
Utilities.sleep(120000); // シートの処理完了を待つ
const rsi = SpreadsheetApp.getActiveSheet().getRange(1,10).getDisplayValue();
var shita = 29;
var ue = 75;
if(rsi <= shita){
GmailApp.sendEmail( //メールの送信処理
"{自分のメールアドレス}",
"SP500_RSI:" + rsi, //subject
"SPXL買付用。^GSPC(S&P500)のRSIです。27以下が理想.^GSPCのRSIをチェック!)\nRSI結果:" + rsi +"\n\n確認URL:https://okometsubulog.hatenablog.com/entry/etf/rsi-201007_1\nYahoo FinanceでRSIチェック", //body
{
from: "{自分のメールアドレス}", //From欄(自分が使ってるメールアドレス)
name: "hoge", //送信者の名前
}
);
} else if(rsi >= ue){
GmailApp.sendEmail( //メールの送信処理
"{自分のメールアドレス}",
"SP500_RSI:" + rsi, //subject
"SPXL売却用。^GSPC(S&P500)のRSIです。77or78以上が理想.^GSPCのRSIをチェック!)\nRSI結果:" + rsi +"\n\n確認URL:https://okometsubulog.hatenablog.com/entry/etf/rsi-201007_1\nYahoo FinanceでRSIチェック", //body
{
from: "{自分のメールアドレス}", //From欄(自分が使ってるメールアドレス)
name: "hoge", //送信者の名前
}
);
}
}
//=========上記行まで===========
※2020/10/20 追記
"Utilities.sleep(120000); // シートの処理完了を待つ"を追加しました。スプレッドシートの更新が遅延して反映していない可能性があったため、120秒待つ、というのを含めました。
変数名「shita」にRSI下限の値を、「ue」という変数にRSIの上限の値を入れればOKです。メール送信テストするときに意図的に値を大きくしたり小さくしたりして実行してメールが受信できればOKだと思います。
うーんこの初心者丸出しの変数名。しらんしらん。英語調べるのも面倒なんです。動けばOKです。本文もハードコーディングだし別にいいやね。
しかもエラー処理は全く入れてません。もう動けばOKと言う感じにしています。GASでの入れ方も知らない。
あ、ちなみにgetRange(1,10)で「J1カラム」を指定してます。位置変える場合はここいじってください。Jが10個めの文字だから1,10です。
また、メール本文の「body」部分は適当にやってください。「\n」で改行です。
私は私が書いたRSIの調査結果のURLを私自身が忘れるので書きました。絶対忘れる。というかどういう理由でこのRSIの値にしたのか、メールを受信したら気になって調べるところからスタートするはずなので入れた。
ちなみにSPXL編、TECL編、TQQQ編のURLはこちら!!!
RSIを用いたリバランスタイミングを検証します_その7(TQQQ微調整編) - 日々の生活をがんばるブログ
https://okometsubulog.hatenablog.com/entry/etf/rsi-201004
RSIを用いたリバランスタイミングを検証します_その8(SPXL微調整編) - 日々の生活をがんばるブログ
https://okometsubulog.hatenablog.com/entry/etf/rsi-201007_1
RSIを用いたリバランスタイミングを検証します_その9(TECL微調整編) - 日々の生活をがんばるブログ
https://okometsubulog.hatenablog.com/entry/etf/rsi-201010
まー、これを使う人はそんなにいないと思うけど一応ね。流石に記事内容がニッチ過ぎる。
後はYahoo FinanceでRSI調べればいいということも文言に入れてます。RSIの値は米国のYahoo Financeで該当銘柄検索して「Chart」からRSIの14日平均線を出せばすぐ見れます。
ちなみにここ押せばスクリプトが実行されますので、メールアドレスだけは本当にご注意ください。意図せず送信されちゃうので。
というわけで、スクリプトが完成しました。後は日次でこのスクリプトが実行できるようにするだけです。毎日決められた時間に実行してくれて完成です。
トリガー作成編
スクリプト作成画面の左上の→を押すと、Google Apps Scriptのメイン画面に戻りますので、私はそこから移動してます。以下の画面の赤線枠の中です。
で、メイン画面に戻ったら、今作ったスクリプト名の右端に「・・・」と言う項目があるのでそこをクリックします。赤枠部分です。
後はそこの「トリガー」をクリックして、「トリガーを追加」というのをクリックすればOKです。以下のような画面が出るので、このように設定する感じですね。
基本的に赤枠部分を以下の様にすればOKです。
これで、毎日17~18時の間に1回、今回のスクリプトを実行してくれることになりました。画像では17~18時にしてますが、今現在は安全を見て18~19時にしています。
肝としては、毎日16:00以降に実行した方が良いです。先ほどのスプレッドシートを見て頂いて分かる通り、結果がでるのが16:00以降だからです。安全を見て私は18:00~19:00設定にしてみました。
後は、アラートが発生したらメールが飛ぶことになります。今回はアラートが発生しないと飛ばないようにしていますが、もし毎日必ずRSIの値が欲しいと言う場合は、GASのif文とelse if文を取っ払って、rsi変数の値を送信するだけにすればOKだと思います。
最初の検証タイミングではifとelse ifを意図的に外してやると良いかもしれません。送られてきたRSIの結果が本当に「本日」分のRSIかが分かるかと言う事と、本当に日次で毎日送ってくれるのかという検証もできますからね。慣らし運転してみて、問題なければifとelse if文を追加すれば良いと思います。
今の所、if文外して毎日チェックしてますが、18:00~19:00の間の適当なタイミングでメール受信できていて、RSIの値も変わってるので、多分大丈夫な気がします。
さて、RSIアラートはこれにて完成です。
このGAS、凄い使いやすいですね。メール本文に変数を入れるのが若干面倒ですが、全体的な実装自体は簡単にできました。というか株価取得のGOOGLEFINANCE関数が楽ちんです。
これならRSIだけでなくVIXのアラートとかも簡単に実装できそうですね。まぁ、VIXだったら証券会社のアラート使った方が早いかな。もしくはIFTTTでも銘柄と株価入れてメール送信してくれるレシピあったはずなのでグーグル先生で聞いてみても良いカモ。
ともあれ、本記事はあくまで私の備忘録的な位置付けであり、かなり素人な作りとなっている点ご了承ください。もしRSIを簡単に取得する方法があったらどしどしコメント頂ければ幸いです!※と言う名の丸投げ調査打ち切り
というわけで、今回はここまでと致します。