《TradingView》インジケーター自作⑥:某人気投資系Youtuber提唱の「-5%ルール投資法」。購入タイミング自動判定し、表示するインディケーターを作ってみた!
おはこんばんわ!たこやきです。
今回は、無料チャートアプリ「TradingView」のインジケーター自作第6弾。
「前の週の終値から、今週の終値がー5%以上下落した場合にラベルを表示する」
というインディケーターを作ってみました。
更新履歴
コードを一部、修正しました。
以前のVerをお使いの方は、コピペしなおしていただけると幸いです。
2022/9/1 ・「設定」にて、判定元を ①S&P500 ②NASDAQ100 ③表示中の株価 から選べるようにコードを修正。また、現在選択中の判定元を、右上テーブルに表示するよう修正。
2022/8/15 ・本記事作成
今回作成した、インディケータのコード
最初に、今回作成したインディケータのコードを、下に記しておきます。
そのままコピペで使えるはずです。
下の解説はすっ飛ばし、速攻使用したい方は、こちらをコピペしてご使用下さい。
//@version=5
indicator("-5%ルール判定", shorttitle="-5%", overlay=true)
//判定に用いる株価指数を選択
string sym = input.string(title="判定元指数", defval="S&P500", options=["S&P500", "NASDAQ100", "表示中の株価"])
//-何%でラベル表示するか設定可能
float p = input(5.0,"下落%")
//最終日から何日さかのぼって判定するか
int maxLabelD = input(500,"判定範囲:日足")
int maxLabelW = input(200,"判定範囲:週足")
//内部変数
int beforeSunday = 0
int beforeMonday = 0
int beforeTuesday = 0
int beforeWednesday = 0
int beforeThursday = 0
int beforeFriday = 0
int beforeSaturday = 0
int weekNumber = 0
bool isNoFriday = false
//ラベル
label label1 = na
var label labelLast = na
//テーブル
var cautionTable1 = table.new(position = position.top_right, columns = 1, rows = 2, bgcolor = color.orange, border_width = 1)
//判定と表示
symblo_func() => //判定元指数を出力するユーザー定義関数
string symbol = ""
if(sym == "S&P500")
symbol := "SPX"
else if(sym == "NASDAQ100")
symbol := "NDX"
else
symbol := str.tostring(syminfo.ticker)
symbol
float closeday = request.security(symblo_func(), "D", close)
float closeweek = request.security(symblo_func(), "W", close)
if(timeframe.isdaily == true) //日足なら
//前の金曜日の確認
for i = 1 to 14
if ( (weekofyear[i] == weekofyear - 1) and (dayofweek[i] == dayofweek.friday) )
beforeFriday := i
if ( (weekofyear[i] == weekofyear - 1) and (dayofweek[i] == dayofweek.saturday) )
beforeSaturday := i
if ( (weekofyear[i] == weekofyear - 1) and (dayofweek[i] == dayofweek.sunday) )
beforeSunday := i
if ( (weekofyear[i] == weekofyear - 1) and (dayofweek[i] == dayofweek.monday) )
beforeMonday := i
if ( (weekofyear[i] == weekofyear - 1) and (dayofweek[i] == dayofweek.tuesday) )
beforeTuesday := i
if ( (weekofyear[i] == weekofyear - 1) and (dayofweek[i] == dayofweek.wednesday) )
beforeWednesday := i
if ( (weekofyear[i] == weekofyear - 1) and (dayofweek[i] == dayofweek.thursday) )
beforeThursday := i
if (beforeFriday == 0) //金曜日がなかった場合
isNoFriday := true
if (beforeThursday != 0 )
beforeFriday := beforeThursday
else if (beforeWednesday != 0 )
beforeFriday := beforeWednesday
else if (beforeTuesday != 0 )
beforeFriday := beforeTuesday
else if (beforeMonday != 0 )
beforeFriday := beforeMonday
//判定範囲以前のラベルを削除
label.delete(label1[maxLabelD + 1])
//判定範囲最終日のラベル作成
if(na(labelLast))
labelLast:= label.new(bar_index, high * 1.07, style=label.style_label_down, text = "判定範囲", color=color.red, textcolor = color.white)
else
label.set_x(labelLast, bar_index[maxLabelD]) //ラベルの移動
label.set_y(labelLast, high[maxLabelD] * 1.07)
//前足のラベル削除
if(beforeFriday != 1) //直近金曜日(もしくは金曜が休場なら、その前の曜日)が前日でなければ
label.delete(label1[1]) //一つ前のラベルを削除
//前日のラベルが消えてない、すなわち金曜日(もしくは金曜が休場なら、その前の曜日)で、かつ休場ならオレンジラベルに変更
if( (na(label1[1]) == false) and (dayofweek[1] != dayofweek.friday) )
label.set_color(label1[1], color=color.orange)
//ラベル表示
if (closeday <= (closeday[beforeFriday] * (1.0 - (p / 100.0) ) ) )
label1 := label.new(bar_index, high * 1.05, style=label.style_label_down, text = str.tostring(year) + "/" + str.tostring(month) + "/" + str.tostring(dayofmonth) + "\n"+ str.tostring(math.round(closeday,2)) + "\n-" + str.tostring(math.round( (1 - (closeday/closeday[beforeFriday]) )*100 ,2) ) + "%", color=color.blue, textcolor = color.white) //青ラベル
if(isNoFriday) //前の金曜日が休場だった場合、紫ラベル
label.set_color(label1, color=color.purple)
table.cell(table_id = cautionTable1, column = 0, row = 0, text = "判定元指数 : " + sym, bgcolor = color.blue, text_color = color.white)
else if(timeframe.isweekly == true) //週足なら
//判定範囲以前のラベルを削除
label.delete(label1[maxLabelW + 1])
//判定範囲最終日のラベル作成
if(na(labelLast))
labelLast:= label.new(bar_index, high * 1.07, style=label.style_label_down, text = "判定範囲", color=color.red, textcolor = color.white)
else
label.set_x(labelLast, bar_index[maxLabelW]) //ラベルの移動
label.set_y(labelLast, high[maxLabelW] * 1.07)
if (closeweek <= (closeweek[1] * (1.0 - (p / 100.0) ) ) )
label1 := label.new(bar_index, high * 1.05, style=label.style_label_down, text = str.tostring(year) + "/" + str.tostring(month(time_close)) + "/" + str.tostring(dayofmonth(time_close)) + "\n"+ str.tostring(math.round(closeweek,2)) + "\n-" + str.tostring(math.round( (1 - (closeweek/closeweek[1]) )*100 ,2) ) + "%", color=color.blue, textcolor = color.white)
table.cell(table_id = cautionTable1, column = 0, row = 0, text = "判定元指数 : " + sym, bgcolor = color.blue, text_color = color.white)
else
table.cell(table_id = cautionTable1, column = 0, row = 0, text = "注意:日足・週足以外は-5%ルール判定されません", bgcolor = color.orange, text_color = color.white)
投資系Youtubeチャンネル「【投資塾】」の「-5%ルール」を、自動で計算・表示したかった…。
このインディケーターの元ネタは、投資系Youtuber「ゆう」様のチャンネル、「【投資塾】知らないより知っていた方が役立つ話」にあります。
上の動画が、複数に渡り解説されている
「-5%ルール」
シリーズの第1弾です。
こちらのチャンネル、決して他のチャンネルを否定したり煽ったりせず、丁寧な口調で淡々と解説してくれるので、大変好感がもてます。
分析内容も長期にわたるバックテスト結果をチャート、グラフを用いて説明しており、客観的・冷静な分析結果であり、信用できる内容になっております。
まだ未視聴の方は、ぜひ一通り視聴してみて下さい。
-5%ルールの、簡単な説明!
こちらの動画で解説してある、「-5%ルール」について、簡単に説明しないといけませんね。
詳しくは動画を視聴していただきたいのですが、ざっくりいうと
① 下落時に、一括もしくは追加購入するための手法
② 長期運用を前提としている。状況によっては、購入後の下落に耐える必要がある
③ 見るチャートは、どのETFを購入する場合でも基本、「S&P500指数」を見る。QQQやレバナスなどNASDAQ100連動の商品に関しては、「NASDAQ100指数」の方が良い
④ 「先週の金曜日の終値」から、「今週の金曜日の終値」が「-5%以上」下落した場合、購入サイン点灯とする(週足で言い換えると、「先週終値~今週終値で-5%」)
⑤ 長期投資なので、「今週金曜日の取引時間終了ギリギリ」で買う必要はない。次の月曜日に購入でも、長期成績に影響はほぼない
といったところ。
動画には、数十年にわたるバックテストの結果、比較的下落の大底付近で買えることが多い、と紹介されています。
大暴落時には、多い場合で7回ほどサイン点灯してから大底、というパターンもあったのですが、そういったケースは非常にまれです。
追加投資の手法として、かなり優れた方法ではないかと思います。
・・・ですが、毎週これを計算するのって、地味に面倒ですよね。
年に数回の出来事ですので、計算し忘れて、せっかくのチャンスを見過ごしてしまう可能性もあります。
まあ、暴落中のみ気を付けてればいいのかもしれませんが、できれば自動計算・自動表示して欲しいですよね?
じゃあ、作っちゃいましょう。
それでは、TradingViewのインディケーターを自作していきます!
さて、さっそくインディケーターを作っていきましょう。
必要なのは、今まで通りチャートアプリ「TradingView」になります。
今まで5回に渡って「TradingView」におけるインディケーター自作解説をしてきました。
もし、まだ過去の記事を見ていない方は、ぜひ見てみて下さい。
今記事の一番下にも、全記事のリンクを貼っておきますね。
【TradingView インディケーター 自作】-5%ルール自動判定:① 空のスクリプトを表示する
ではまず、画面下部、「PINEエディター」をクリックしてください。
下のように、ほとんど何も記載されていない、「名前なしのスクリプト」が出てくるはずです。
ここにコードを入力していきます。
*もし既存のインディケーターのコードが表示されてしまう場合は、
「開く」→「新規作成 インディケーター」をクリックしてください。
【TradingView インディケーター 自作】-5%ルール自動判定:② コードをコピペする
今回も、コピーして少し直すことで使えるような既存のインディケーターが見つかりませんでした。
新規作成しましたので、下のコードをコピペして使ってください。
//@version=5
indicator("-5%ルール判定", shorttitle="-5%", overlay=true)
//判定に用いる株価指数を選択
string sym = input.string(title="判定元指数", defval="S&P500", options=["S&P500", "NASDAQ100", "表示中の株価"])
//-何%でラベル表示するか設定可能
float p = input(5.0,"下落%")
//最終日から何日さかのぼって判定するか
int maxLabelD = input(500,"判定範囲:日足")
int maxLabelW = input(200,"判定範囲:週足")
//内部変数
int beforeSunday = 0
int beforeMonday = 0
int beforeTuesday = 0
int beforeWednesday = 0
int beforeThursday = 0
int beforeFriday = 0
int beforeSaturday = 0
int weekNumber = 0
bool isNoFriday = false
//ラベル
label label1 = na
var label labelLast = na
//テーブル
var cautionTable1 = table.new(position = position.top_right, columns = 1, rows = 2, bgcolor = color.orange, border_width = 1)
//判定と表示
symblo_func() => //判定元指数を出力するユーザー定義関数
string symbol = ""
if(sym == "S&P500")
symbol := "SPX"
else if(sym == "NASDAQ100")
symbol := "NDX"
else
symbol := str.tostring(syminfo.ticker)
symbol
float closeday = request.security(symblo_func(), "D", close)
float closeweek = request.security(symblo_func(), "W", close)
if(timeframe.isdaily == true) //日足なら
//前の金曜日の確認
for i = 1 to 14
if ( (weekofyear[i] == weekofyear - 1) and (dayofweek[i] == dayofweek.friday) )
beforeFriday := i
if ( (weekofyear[i] == weekofyear - 1) and (dayofweek[i] == dayofweek.saturday) )
beforeSaturday := i
if ( (weekofyear[i] == weekofyear - 1) and (dayofweek[i] == dayofweek.sunday) )
beforeSunday := i
if ( (weekofyear[i] == weekofyear - 1) and (dayofweek[i] == dayofweek.monday) )
beforeMonday := i
if ( (weekofyear[i] == weekofyear - 1) and (dayofweek[i] == dayofweek.tuesday) )
beforeTuesday := i
if ( (weekofyear[i] == weekofyear - 1) and (dayofweek[i] == dayofweek.wednesday) )
beforeWednesday := i
if ( (weekofyear[i] == weekofyear - 1) and (dayofweek[i] == dayofweek.thursday) )
beforeThursday := i
if (beforeFriday == 0) //金曜日がなかった場合
isNoFriday := true
if (beforeThursday != 0 )
beforeFriday := beforeThursday
else if (beforeWednesday != 0 )
beforeFriday := beforeWednesday
else if (beforeTuesday != 0 )
beforeFriday := beforeTuesday
else if (beforeMonday != 0 )
beforeFriday := beforeMonday
//判定範囲以前のラベルを削除
label.delete(label1[maxLabelD + 1])
//判定範囲最終日のラベル作成
if(na(labelLast))
labelLast:= label.new(bar_index, high * 1.07, style=label.style_label_down, text = "判定範囲", color=color.red, textcolor = color.white)
else
label.set_x(labelLast, bar_index[maxLabelD]) //ラベルの移動
label.set_y(labelLast, high[maxLabelD] * 1.07)
//前足のラベル削除
if(beforeFriday != 1) //直近金曜日(もしくは金曜が休場なら、その前の曜日)が前日でなければ
label.delete(label1[1]) //一つ前のラベルを削除
//前日のラベルが消えてない、すなわち金曜日(もしくは金曜が休場なら、その前の曜日)で、かつ休場ならオレンジラベルに変更
if( (na(label1[1]) == false) and (dayofweek[1] != dayofweek.friday) )
label.set_color(label1[1], color=color.orange)
//ラベル表示
if (closeday <= (closeday[beforeFriday] * (1.0 - (p / 100.0) ) ) )
label1 := label.new(bar_index, high * 1.05, style=label.style_label_down, text = str.tostring(year) + "/" + str.tostring(month) + "/" + str.tostring(dayofmonth) + "\n"+ str.tostring(math.round(closeday,2)) + "\n-" + str.tostring(math.round( (1 - (closeday/closeday[beforeFriday]) )*100 ,2) ) + "%", color=color.blue, textcolor = color.white) //青ラベル
if(isNoFriday) //前の金曜日が休場だった場合、紫ラベル
label.set_color(label1, color=color.purple)
table.cell(table_id = cautionTable1, column = 0, row = 0, text = "判定元指数 : " + sym, bgcolor = color.blue, text_color = color.white)
else if(timeframe.isweekly == true) //週足なら
//判定範囲以前のラベルを削除
label.delete(label1[maxLabelW + 1])
//判定範囲最終日のラベル作成
if(na(labelLast))
labelLast:= label.new(bar_index, high * 1.07, style=label.style_label_down, text = "判定範囲", color=color.red, textcolor = color.white)
else
label.set_x(labelLast, bar_index[maxLabelW]) //ラベルの移動
label.set_y(labelLast, high[maxLabelW] * 1.07)
if (closeweek <= (closeweek[1] * (1.0 - (p / 100.0) ) ) )
label1 := label.new(bar_index, high * 1.05, style=label.style_label_down, text = str.tostring(year) + "/" + str.tostring(month(time_close)) + "/" + str.tostring(dayofmonth(time_close)) + "\n"+ str.tostring(math.round(closeweek,2)) + "\n-" + str.tostring(math.round( (1 - (closeweek/closeweek[1]) )*100 ,2) ) + "%", color=color.blue, textcolor = color.white)
table.cell(table_id = cautionTable1, column = 0, row = 0, text = "判定元指数 : " + sym, bgcolor = color.blue, text_color = color.white)
else
table.cell(table_id = cautionTable1, column = 0, row = 0, text = "注意:日足・週足以外は-5%ルール判定されません", bgcolor = color.orange, text_color = color.white)
こんな感じになったかと思います。
【TradingView インディケーター 自作】-5%ルール自動判定:③ インディケーターを保存する
最後に、画面真ん中の右側、「保存」をクリックし、完成です。
スクリプトの名前は、自動でインディケーター名が入るはずですし、好きな名前に変更しても結構です。
【TradingView インディケーター 自作】-5%ルール自動判定:④ インディケーターを表示する
これで、インディケーターの用意はできました。
ですがこのままだと、まだ何も表示されません。作成したインディケーターが選択されていないからですね。
いったん、「_」(パネルを非表示)をクリックして、PINEエディターを下に落としてください。
画面上部、「インジケーター」をクリックし…
「マイスクリプト」の一番下にある、先ほど作ったスクリプト名をクリック。
下のように、見事に表示されました!
作成したインディケーターの解説
作成したインディケータの表示内容について、解説していきます。
「先週の終値より-5%以上下落」した場合・・・すなわち、「買い場」が発生した場合、バーの上部に、「青」のラベルで表示されるようになっています。
表示内容は、以下の通り。
上段:金曜日の日付
中段:終値価格(今が金曜日なら、現在価格)
下段:先週の終値からの下落率(%)
なお、先週金曜日が休日などで休場の場合、先週の木曜日の終値で判定しています。その場合、ラベルは「紫色」です。
今週金曜日が休場の場合、ラベルは「オレンジ色」です。
ラベルの表示数に上限があるため、過去にさかのぼって大量に表示することはできません。
よって、「ここまで過去にさかのぼって表示してるよ!」と分かるように、最古の判定日が赤ラベルで表示されます。
また、「設定」をクリックして、設定を変更することもできます。
① -5%下落を判定する、判定元となる指数(S&P500,NASDAQ100、現在の株価から選択可)
② 何%下落したらラベル表示するか
③ 日足で何日分さかのぼって表示するか
③ 週足で何週分さかのぼって表示するか
①で選択した判定元指数は、チャート右上の部分に表示されます。
さらに、日足・週足以外の時間足を選択している場合、右上にラベルが表示されない旨の警告を表示させます。
インディケーターの動作確認
今回のインディケーター、すんなり完成したわけではないので、イマイチ自信がないです…。
少し、動作確認してみたいと思います。
下の画像は、情報元のYoutubeチャンネル、「【投資塾】知らないより知っていた方が役立つ話」の動画スクショです。
動画内にて、「スクショを自由に使ってよい、ブログ等に載せてもよい」と明言していただいていたので、さっそく使わせていただきます。
「ゆう」様には、この場を借りてお礼申し上げます。
まずは左上のチャート。S&P500指数のチャートです。2015年~2018年の中で発生した、-5%ルール発動を確認します。
一応、下の表にまとめてみました。
① ▲5.77%(2015年8月)
① ▲5.96%(2016年1月)
① ▲5.16%(2018年2月)
② ▲5.95%(2018年3月)
③ ▲7.05%(2018年12月)
左下のチャートの-5%ルール発動も、表に直してみました。
① ▲11.49%(2020年2月)
② ▲8.79%(2020年3月)
③ ▲14.98%(2020年3月)
④ ▲5.64%(2020年10月)
① ▲5.68%(2022年1月)
② ▲5.06%(2022年6月)
そして、下の画像が、TradingViewにて自作した、今回のインディケーターが判定・表示してくれる-5%ルール発動です。
まずはYoutubeスクショ画像の左上との比較検証。
発動月、下落%、完全にぴったり一致していますね。
お次は、スクショ画像の左下との比較検証。
こちらもピッタリ一致しています!
ほぼ、間違いはないでしょう。安心しました。
《!》注意点《!》
今回作成したインディケータですが、いくつか注意点がございます。
①label関数に表示数上限があるため、何年もさかのぼって表示できない!=過去の検証には使いにくい!
②「日足」の「先物・CFD・仮想通貨」はラベル表示されない(週足なら表示される)
➀に関しては、ラベルを表示させる関数、「label関数」に表示数の上限があるため、いかんともし難いです。
十数個は表示されるようなので、2〜3年は表示できると思いますが、数十年分の過去検証とかには使いにくいです。
一応、「リプレイ」機能を使うと、最後の足を過去日にできるので、少しずつさかのぼる事で過去検証は可能です…少しメンドくさいですが。
➁に関しては、はっきりした原因は分かりません…。
おそらくは、これらは株式とは違い土曜・日曜・月曜も取引があるため、曜日判定に狂いが生じるからだと推測します。
・・・週足のチャートでしたら、「先物・CFD・仮想通貨」のチャートでもラベル表示されます。曜日関係ないですからね。
まあとりあえず良しとして、いつか改善したいと思います。
また、私たこやき、別にプログラマー・SE等プログラムの専門家ではありません。
趣味で、試行錯誤しながらイジって作っております。動作確認は一応しておりますが、今回のインディケーター、正しく計算・表示されない可能性もあることはご承知ください。
コードのご利用はご自由に使っていただいて結構ですが、あくまで自己責任でご利用ください。
また、間違いのご指摘や改善案・感想などありましたら、ぜひコメント欄にお願いします!
《Trading Viewで最高値からのー5%ごとの価格を表示するインディケーターを自作する:まとめ》
・ TradingViewは、見やすくて多機能、優秀なチャートツールです!
・ TradingViewの無料会員は、同時に3つまでしかインジケーターの表示ができない・・・・。
・ TradingViewは、オリジナルのインジケーターが作れる!
・ 先週終値から今週終値まで、5%下落すると買い増ししたいけど、価格を計算するのがメンドクサイ… → チャートに表示させよう!!
・ 今回は、一から作ってみました。試行錯誤の末、素人でもどうにか出来ました♪
・ 日足チャート・週足チャートにて、-5%ルールが発動するとラベルが表示!
・ コードのコピペ使用、改造などはご自由に!
・ コードにエラー・誤りがある可能性もあり。使用はあくまで自己責任でお願いします! 苦情は受け付けません!
・ ご指摘・改善点・アドバイスはぜひコメント欄にお願いします!
・ 注意:無料会員は、オリジナルのインジケーターは一つまでしか同時表示できません。
《広告》
《あわせて読みたい!関連リンク》
⇒《米国株》ハイリスク・ハイリターンなレバレッジETF、「SOXL」!過去の暴落率を調べてみました。
⇒《米国株》レバレッジETFシリーズ、第2弾!「TECL」と「SOXL」のリターンと暴落率について、比較しました!
⇒米国株》レバレッジETFシリーズ、第3弾!「TECL」と「SOXL」の、各年別リターンを調べてみました!
⇒《米国株 レバレッジETF 第4弾》レバレッジETFの長期運用!元指数との倍率を比較し、何倍になっているのか調べてみました!《SPXL・TECL・SOXL・TNA》
⇒毎月定額しか予算無し!でも「-5%投資法」をやりたい!!「ドルコスト平均法」とどっちが良い!?S&P500、NASDAQ100、レバナス(QLDで代用)、TECL、SOXLで調べてみました!