こんにちは。TATです。
今日のテーマは「Pythonで移動平均線の押し目・上放れ・下放れを自動検出する方法」です。
移動平均線の押し目、上放れ、下放れしたタイミングをプログラムで自動検出する方法について解説します。
コードも全て公開するのでご自由にパクりつつ、適宜改善しながらお使いください。
特に上昇トレンドの中では、押し目や上放れはエントリーチャンスになります。
ここをプログラムで自動検出することができれば自動売買も不可能ではありません。
株価データの準備
まずは、今回使用する株価データの準備です。
pandas_datareaderで株価データを取得
ここではpandas_datareaderを使ってサクッと取得します。
例として、銘柄はトヨタ自動車(証券コード:7203)を使っていきます。
期間は適当に2020年1月1日〜2021年12月31日とします。
from pandas_datareader import data df = data.DataReader("7203.T","yahoo", start="2020-01-01", end="2021-12-31")
これで日足の株価データが取得できます。
株価データの取得方法については、過去記事でも詳しく解説しているので気になる方はご参考ください。
【日本株対応】Pythonで株価のローソク足データを取得する方法まとめ【CSV、ライブラリ、スクレイピング】
続きを見る
rolling関数で移動平均線を計算
次に移動平均線を計算します。
pandasのrolling関数を使えば1行で完了します。
ここでは25日移動平均線を使用していきます。
df["SMA25"] = df["Close"].rolling(window=25).mean()
windowに任意の期間を指定すればOKです。
これで25日移動平均線が計算できました。
【コード解説】Pythonで株価データから主要なテクニカル分析を計算して可視化する【移動平均線、MACD、RSI】
続きを見る
移動平均線の押し目・上放れ・下放れを自動検出する
データの準備が整ったところで、ここからが本題です。
移動平均線の押し目・上放れ・下放れを自動検出していきます。
いろいろな方法があると思いますが、僕がパッと思いついたのはこんな感じです。
上放れの検出方法
- 移動平均線と株価の位置関係を判定する
- 安値>移動平均線 → 1と返す: 株価は移動平均線よりも上に位置する
- 高値<移動平均線 → -1と返す: 株価は移動平均線よりも下に位置する
- それ以外 → 0と返す:直近ローソク足は移動平均線に接触している
- 1日前のデータと比較する
- 1日前が1で当日が0 → 押し目
- 1日前が0で当日が1 → 上放れ
- 1日前が0で当日が-1 → 下放れ
他にもいろいろやり方があると思います。
もっとエレガントはやり方もあると思うのでいい方法あれば教えてくださいw
とりあえず本記事では僕がパッと思いついた上記の方法をpythonで実装していきます。
1. 移動平均線と株価の位置関係を判定する
まずは移動平均線と株価の位置関係を判定します。
ローソク足が移動平均線よりも上にいるのか、下にいるのか、接触しているのか、を判断します。
これをするために、price_positionという関数を定義してapply関数で実装しました。
def price_position(x): if x["Low"] > x["SMA25"]: return 1 elif x["High"] < x["SMA25"]: return -1 else: return 0 df["Position"] = df.apply(price_position, axis=1)
これで完了です。
Positionというカラムを追加して、株価の位置関係を示す情報を加えました。
2. 1日前のデータと比較する
次に先ほど計算したPositionカラムを1日前のデータと比較します。
shift関数で1日前のデータを追加する
これもapply関数で一気にやってしまった方が処理が早いので、そのために1日前のデータを新しいカラムとして加えます。
これにはshift関数を使います。
df["d1"] = df["Position"].shift()
d1というカラムを定義して、そこに1日前のデータを格納しました。
これで準備OKです。
(例)上放れを判定してみる
必要なカラムが揃ったので、例としてここから上放れを判定してみます。
少し関数をいじれば押し目や下放れも判定可能です。
1日前のデータ(d1)と当日のデータ(Position)を比較して、d1が0でPositionが1なら上放れと判定します。
そのほかはいったん無視します。
上放れ判定用の関数(check_up_gap)を定義して、apply関数で一気に判定します。
上放れと判定した場合には、高値を返します。その他はNoneと返します。
これはのちに可視化するときに便利だからです。
def check_up_gap(x): if x["d1"] == 0 and x["Position"] == 1: return x["High"] else: return None df["Up"] = df.apply(check_up_gap, axis=1)
これでOKです。
データを見ると2021年12月24日に上放れが発生していることが確認できます。
d1が0、Positionが1になってるのできちんと判定が機能していることが確認できます。
少しいじれば押し目や下放れの判定も可能です
押し目や下放れの判定も、先ほどの関数を少しいじれば対応できます。
d1が1でPositionが0なら押し目になります。
d1が0でPositionが-1なら下放れになります。
必要に応じて自由に改造してみてください。
チャートで可視化してみる
最後に、チャートで可視化してみます。
Plotlyで株価データを可視化
可視化用のライブラリはいろいろありますが、ここではPlotlyを使います。
Plotlyを使えばインタラクティブ(Hoverするとデータが表示されたりします)なチャートが描けるので便利です。
まずは普通にローソク足チャートを描いてみます。
今回使用する25日移動平均線も合わせて表示します。
ついでに出来高も加えます。
import pandas as pd import plotly.graph_objects as go from plotly.subplots import make_subplots # 非表示にする日付をリストアップ d_all = pd.date_range(start=df.index[0],end=df.index[-1]) d_obs = [d.strftime("%Y-%m-%d") for d in df.index] d_breaks = [d for d in d_all.strftime("%Y-%m-%d").tolist() if not d in d_obs] # figを定義 fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.05, row_width=[0.2, 0.7], x_title="Date") # Candlestick fig.add_trace( go.Candlestick( x=df.index, open=df["Open"], high=df["High"], low=df["Low"], close=df["Close"], showlegend=False, name="ローソク足", ), row=1, col=1 ) # SMA25 fig.add_trace( go.Scatter( x=df.index, y=df["SMA25"], showlegend=True, name="SMA25", mode="lines", marker=dict( color='blue') ,) ) # Volume fig.add_trace( go.Bar( x=df.index, y=df["Volume"], showlegend=False, name="出来高" ), row=2, col=1 ) # Layout fig.update_layout( title={ "text": "トヨタ自動車(7203)の日足チャート", "y":0.9, "x":0.5, }, hovermode="x unified" ) # y軸名を定義 fig.update_yaxes(title_text="株価", row=1, col=1) fig.update_yaxes(title_text="出来高", row=2, col=1) # 不要な日付を非表示にする fig.update_xaxes( rangebreaks=[dict(values=d_breaks)] ) fig.update(layout_xaxis_rangeslider_visible=False) fig.show()
綺麗にローソク足チャートが描けました。
コードは結構長いですが、一度書いてしまえばあとは必要に応じて使いまわせるので楽ちんです。
(例)上放れを追加する
ここでは、例としてローソク足チャートに上放れを追加していきます。
黄色い▼で示してみます。
import pandas as pd import plotly.graph_objects as go from plotly.subplots import make_subplots # 非表示にする日付をリストアップ d_all = pd.date_range(start=df.index[0],end=df.index[-1]) d_obs = [d.strftime("%Y-%m-%d") for d in df.index] d_breaks = [d for d in d_all.strftime("%Y-%m-%d").tolist() if not d in d_obs] # figを定義 fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.05, row_width=[0.2, 0.7], x_title="Date") # Candlestick fig.add_trace( go.Candlestick( x=df.index, open=df["Open"], high=df["High"], low=df["Low"], close=df["Close"], showlegend=False, name="ローソク足", ), row=1, col=1 ) # SMA25 fig.add_trace( go.Scatter( x=df.index, y=df["SMA25"], showlegend=True, name="SMA25", mode="lines", marker=dict( color='blue') ,) ) ############################################# # 上放れ fig.add_trace( go.Scatter( x=df.index, y=df["Up"], showlegend=True, name="上放れ", mode="markers", marker=dict( color='yellow', size=10, symbol="triangle-down", ), ) ) ############################################# # Volume fig.add_trace( go.Bar( x=df.index, y=df["Volume"], showlegend=False, name="出来高" ), row=2, col=1 ) # Layout fig.update_layout( title={ "text": "トヨタ自動車(7203)の日足チャート", "y":0.9, "x":0.5, }, hovermode="x unified" ) # y軸名を定義 fig.update_yaxes(title_text="株価", row=1, col=1) fig.update_yaxes(title_text="出来高", row=2, col=1) # 不要な日付を非表示にする fig.update_xaxes( rangebreaks=[dict(values=d_breaks)] ) fig.update(layout_xaxis_rangeslider_visible=False) fig.show()
これで上放れをチャート上で可視化することができました。
エントリーポイントとして機能するのか?
パッとみた感じ、エントリーポイントとしてはうまくいく場合とそうでない場合がありますね。
下落局面ではだまし上げみたいなパターンも結構あるので、ここでエントリーすると事故りますw
押し目と上放れは上昇局面で使うと良さそう
一方で、押し目と上放れは上昇局面で利用するとそこそこ機能しそうです。
移動平均線の最適な期間は要検討ですが、いずれの場合においても、上昇局面で使用することがとても大事になってきます。
上昇局面を判定する方法〜ミネルヴィニのトレンドテンプレート〜
上昇局面にいるかどうかを判定するにはいろいろありますが、僕の場合はトレンドテンプレートをよく使います。
トレンドテンプレートは、成長株投資で有名なミネルヴィニが考案した手法で、株価が上昇局面にいるかどうかを判定することができます。
【毎週無料公開】日本株にミネルヴィニのトレンドテンプレートを適用してスクリーニングする!
続きを見る
僕が運営している「投資でニート生活」では、このトレンドテンプレートを適用して銘柄を抽出しています。
さらに業績や売買シグナルなどを組み合わせてスクリーニングした銘柄はnoteで発信しています。
もしご興味あればご覧ください。
まとめ
本記事では「【Pythonで株式投資】移動平均線の押し目・上放れ・下放れを自動検出する方法【コード解説】」というテーマでお話してきました。
Pythonを使えば、自動売買も不可能ではありません。
ここで紹介した移動平均線の押し目・上放れ・下放れも、条件によってはエントリーポイントとして有効です。
特に押し目や上放れは上昇局面で活用すれば比較的うまく機能すると思います。
一方で、最適な移動平均線の期間とか、どうやって上昇局面にいることを判定するのか、追加で考慮すべきポイントはたくさんあります。
ぜひ、本記事で紹介したコードをいじりながらいろいろ試してみてください。
ここまで読んでくださり、ありがとうございました。