こんにちは。TATです。
今日のテーマは「【コード解説】Pythonで一目均衡表の三役好転と三役逆転を判定してチャートに表示する」です。
Pythonによる一目均衡表の計算方法とチャートによる可視化については過去の記事で解説しました。
-

【コード解説】Pythonで一目均衡表を計算してチャートで可視化する
続きを見る
本記事はこちらの続編的な扱いです。
テクニカル分析手法の1つである一目均衡表で強力な買いシグナル・売りシグナルとして知られている三役好転および三役逆転をPythonを使って判定する方法について解説します。
さらに結果をチャートで表示してシグナルを視覚的に見てみます。
目次
【コード解説】Pythonで一目均衡表の三役好転と三役逆転を判定してチャートに表示する

データの準備
まずはデータの準備です。
ここは過去記事で解説済みなのでサクッといきます。
株価データの取得
株価データはyahoo_finance_api2を使って取得します。
例として日経平均株価の過去2年分の日足データを取得します。
import sys
from yahoo_finance_api2 import share
from yahoo_finance_api2.exceptions import YahooFinanceError
import pandas as pd
my_share = share.Share('^N225')
symbol_data = None
try:
symbol_data = my_share.get_historical(
share.PERIOD_TYPE_YEAR, 2,
share.FREQUENCY_TYPE_DAY, 1)
except YahooFinanceError as e:
print(e.message)
sys.exit(1)
df = pd.DataFrame(symbol_data)
df["datetime"] = pd.to_datetime(df.timestamp, unit="ms")
これで2年分の日経平均株価が取得できます。

-

【Pythonコード解説】yahoo_finance_api2で日本株の株価データを取得する
続きを見る
一目均衡表の計算
株価データの準備ができたら次は一目均衡表の計算です。
一目均衡表を構成する5つの補助線を計算します。
また、未来26日分の雲を表示するために、日付データも追加します。
import datetime
# 未来の日付データを定義
additional_dates = pd.date_range(
start=df["datetime"].max()+datetime.timedelta(days=1),
end=df["datetime"].max()+datetime.timedelta(days=25),
)
# 株価データと結合
df = pd.concat([
df,
pd.DataFrame(additional_dates, columns=["datetime"]),
], ignore_index=True)
# 基準線
high26 = df["high"].rolling(window=26).max()
low26 = df["low"].rolling(window=26).min()
df["base_line"] = (high26 + low26) / 2
# 転換線
high9 = df["high"].rolling(window=9).max()
low9 = df["low"].rolling(window=9).min()
df["conversion_line"] = (high9 + low9) / 2
# 先行スパン1
leading_span1 = (df["base_line"] + df["conversion_line"]) / 2
df["leading_span1"] = leading_span1.shift(25)
# 先行スパン2
high52 = df["high"].rolling(window=52).max()
low52 = df["low"].rolling(window=52).min()
leading_span2 = (high52 + low52) / 2
df["leading_span2"] = leading_span2.shift(25)
# 遅行スパン
df["lagging_span"] = df["close"].shift(-25)
これで一目均衡表に必要な5本の補助線が完成です。
カラム数が増えすぎて全部収まっていませんが、きちんと計算できています。

これで必要なデータの準備は整いました。
-

【コード解説】Pythonで一目均衡表を計算してチャートで可視化する
続きを見る
Pythonで三役好転と三役逆転を判定する
データの準備ができたところで、本記事のメインである三役好転と三役逆転の判定をPythonで実装していきます。
三役好転および三役逆転とは?
まずは三役好転および三役逆転について簡単にご紹介しておきます。
それぞれ、強力な買いシグナル・売りシグナルになります。
三役好転(三役逆転)とは?
以下の3つの条件を全て満たすと三役好転(三役逆転)と呼ばれ、強力な売買シグナルとなる
- 転換線>基準線(転換線<基準線)
- ローソク足>雲(ローソク足<雲)
- 遅行線>ローソク足(遅行線<ローソク足)
上記の3つの条件を全て満たした状態が三役好転(三役逆転)と呼ばれます。
三役好転(三役逆転)をPythonで判定する
Pythonで三役好転(三役逆転)を判定するには、3つの条件をそれぞれ判定して、すべて満たされて居るかをチェックすればOKです。
三役好転および三役逆転を判定するプログラムは次の通りです。
それぞれカラムを追加します。
# 三役好転 buy_condition1 = df["conversion_line"] > df["base_line"] buy_condition2 = df["low"] > df[["leading_span1", "leading_span2"]].max(axis=1) buy_condition3 = df["lagging_span"].shift(25) > df["high"].shift(25) df["三役好転"] = buy_condition1 & buy_condition2 & buy_condition3 # 三役逆転 sell_condition1 = df["conversion_line"] < df["base_line"] sell_condition2 = df["high"] < df[["leading_span1", "leading_span2"]].min(axis=1) sell_condition3 = df["lagging_span"].shift(25) < df["low"].shift(25) df["三役逆転"] = sell_condition1 & sell_condition2 & sell_condition3
3つの条件をそれぞれ判定して、全て満たしたらTrue、1つでも満たさなければFalseとしています。
これで三役好転および三役逆転が判定できます。
シンプルなコードなので分かりやすいかと思います。
3つ目の条件の遅行スパンの判定では、26日前のデータから判定しないといけないので、shiftを使って計算しています。
Pythonで一目均衡表の三役好転および三役逆転をチャートに表示する
三役好転および三役逆転の判定ができたところでチャートに表示してみます。
ここでは2つの方法で可視化してみます。
2つの可視化方法
- 三役好転(三役逆転)になったタイミングを可視化する
- 三役好転(三役逆転)の期間を可視化する
三役好転(三役逆転)の条件を満たしたタイミングは売買ポイントになります。
また、三役好転(三役逆転)の条件を満たすと、しばらくの間条件を満たした状態が続くことがあります。
この期間を可視化すると、いつ三役好転(三役逆転)の条件を満たしているのかが一目で確認できます。
三役好転(三役逆転)になったタイミングを可視化する
まずは三役好転(三役逆転)になったタイミングをチャートに表示してみます。
これをするには、三役好転(三役逆転)になったタイミングを判定する必要があります。
いろいろなやり方がありますが、僕の場合は前日との差分で判定しました。
まず前日との差分を計算して新たなカラムに追加します。
# 1日前のデータとの差分を計算 df["三役好転_diff"] = df["三役好転"] - df["三役好転"].shift() df["三役逆転_diff"] = df["三役逆転"] - df["三役逆転"].shift()
三役好転および三役逆転のカラムはTrueかFalseの2択です。
これはBoolean型と呼ばれるデータの型で、Trueは1、Falseは0を意味します。
実際に計算すると確認できます。

この差分を利用すると、三役好転(三役逆転)になったタイミングを判定することができます。
差分が1なら0から1に切り替わったタイミングなので、三役好転(三役逆転)になったタイミングになります。
つまりこの差分が1になってるものを抽出すればOKです。
結果をチャートに表示します。
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# 非表示にする日付をリストアップ
d_all = pd.date_range(start=df['datetime'].iloc[0],end=df['datetime'].iloc[-1])
d_obs = [d.strftime("%Y-%m-%d") for d in df['datetime']]
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["datetime"], open=df["open"], high=df["high"], low=df["low"], close=df["close"], name="OHLC"),
row=1, col=1
)
# Volume
fig.add_trace(
go.Bar(x=df["datetime"], y=df["volume"], name="Volume"),
row=2, col=1
)
# 一目均衡表
fig.add_trace(go.Scatter(x=df["datetime"], y=df["base_line"], name="基準線", mode="lines", line=dict(width=1)), row=1, col=1)
fig.add_trace(go.Scatter(x=df["datetime"], y=df["conversion_line"], name="転換線", mode="lines", line=dict(width=1)), row=1, col=1)
fig.add_trace(go.Scatter(x=df["datetime"], y=df["leading_span1"], name="先行スパン1", mode="lines", line=dict(width=1)), row=1, col=1)
fig.add_trace(go.Scatter(x=df["datetime"], y=df["leading_span2"], name="先行スパン2", mode="lines", line=dict(width=1)), row=1, col=1)
fig.add_trace(go.Scatter(x=df["datetime"], y=df["lagging_span"], name="遅行スパン", mode="lines", line=dict(width=1)), row=1, col=1)
fig.add_trace(go.Scatter(x=df["datetime"], y=df["leading_span1"], name="先行スパン1", mode="lines", fill=None, line=dict(width=0, color="gray"), showlegend=False), row=1, col=1)
fig.add_trace(go.Scatter(x=df["datetime"], y=df["leading_span2"], name="先行スパン2", mode="lines", fill='tonexty', line=dict(width=0, color="gray"), showlegend=False), row=1, col=1)
# 三役好転を表示
df_signal = df[df["三役好転_diff"]==1]
fig.add_trace(go.Scatter(x=df_signal["datetime"], y=df_signal["close"], mode="markers", marker=dict(size=10), name="三役好転"), row=1, col=1)
# 三役逆転を表示
df_signal = df[df["三役逆転_diff"]==1]
fig.add_trace(go.Scatter(x=df_signal["datetime"], y=df_signal["close"], mode="markers", marker=dict(size=10), name="三役逆転"), row=1, col=1)
# Layout
fig.update_layout(
title={
"text": "日経平均の日足チャート",
"y":0.9,
"x":0.5,
}
)
# 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()
このコードで表示されるチャートがこちらです。

いい感じに可視化できてますね。
期間によっては結構シグナルが連発していることがわかります。
ボックス相場では三役好転と三役逆転がどちらも頻出することもあります。
うまく活用するにはさらにここに条件を追加しないといけなさそうな感じがしますね。
シグナルの部分はScatterチャートで表現しています。
そのままだと小さくて見えないので、目立たせるためにmarkerのサイズを10にして大きくしました。
三役好転(三役逆転)の期間を可視化する
もう1つのやり方は、三役好転(三役逆転)の期間を可視化する方法です。
三役好転(三役逆転)の条件を満たすと、しばらくの間条件を満たした状態が続くことがよくあります。
この期間を可視化すると、いつ三役好転(三役逆転)の条件を満たしているのかが一目で確認できます。
これを行うには三役好転(三役逆転)の条件を満たしている期間を算出する必要があります。
これには先ほどの差分データを活用できます。
差分が1ならば0→1になったタイミングでした。
反対に、−1であれば1→0に変わったタイミングです。
この期間を抽出することができれば可視化できます。
Pythonで実装してみます。
# 三役好転の終了期間を算出 df_buy = df[df["三役好転_diff"].isin([-1, 1])] df_buy["end_datetime"] = df_buy["datetime"].shift(-1) df_buy = df_buy[df_buy["三役好転_diff"]==1] # 三役逆転の終了期間を算出 df_sell = df[df["三役逆転_diff"].isin([-1, 1])] df_sell["end_datetime"] = df_sell["datetime"].shift(-1) df_sell = df_sell[df_sell["三役逆転_diff"]==1]
これだけを見ると分かりにくいと思うので少し解説します。
まず差分が−1か1のデータを抽出すると、0→1になったタイミング、および1→0に切り替わったタイミングを抽出することができます。
結果を見ると、当たり前ですが1と−1が交互に繰り返していることがわかります。

このデータを活用すれば、期間を求めることができます。
開始日と終了日が交互にあるので、shiftで1つずらすといい感じにまとめられます。

shift(-1)をすると、データが上に1つずれるので、差分が1の時には次の-1の時の日付がend_datetimeに格納されていることが確認できます。
これで差分が1になってるデータのみに絞ればdatetimeが開始日でend_datetimeが終了日になります。
この結果をチャートに表示してみます。
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# 非表示にする日付をリストアップ
d_all = pd.date_range(start=df['datetime'].iloc[0],end=df['datetime'].iloc[-1])
d_obs = [d.strftime("%Y-%m-%d") for d in df['datetime']]
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["datetime"], open=df["open"], high=df["high"], low=df["low"], close=df["close"], name="OHLC"),
row=1, col=1
)
# Volume
fig.add_trace(
go.Bar(x=df["datetime"], y=df["volume"], name="Volume"),
row=2, col=1
)
# 一目均衡表
fig.add_trace(go.Scatter(x=df["datetime"], y=df["base_line"], name="基準線", mode="lines", line=dict(width=1)), row=1, col=1)
fig.add_trace(go.Scatter(x=df["datetime"], y=df["conversion_line"], name="転換線", mode="lines", line=dict(width=1)), row=1, col=1)
fig.add_trace(go.Scatter(x=df["datetime"], y=df["leading_span1"], name="先行スパン1", mode="lines", line=dict(width=1)), row=1, col=1)
fig.add_trace(go.Scatter(x=df["datetime"], y=df["leading_span2"], name="先行スパン2", mode="lines", line=dict(width=1)), row=1, col=1)
fig.add_trace(go.Scatter(x=df["datetime"], y=df["lagging_span"], name="遅行スパン", mode="lines", line=dict(width=1)), row=1, col=1)
fig.add_trace(go.Scatter(x=df["datetime"], y=df["leading_span1"], name="先行スパン1", mode="lines", fill=None, line=dict(width=0, color="gray"), showlegend=False), row=1, col=1)
fig.add_trace(go.Scatter(x=df["datetime"], y=df["leading_span2"], name="先行スパン2", mode="lines", fill='tonexty', line=dict(width=0, color="gray"), showlegend=False), row=1, col=1)
for i in range(len(df_buy[df_buy["三役好転_diff"]==1])):
row = df_buy.iloc[i]
fig.add_vrect(x0=row["datetime"], x1=row["end_datetime"], line_width=0, fillcolor="blue", opacity=0.1, row=1, col=1)
for i in range(len(df_sell[df_sell["三役逆転_diff"]==1])):
row = df_sell.iloc[i]
fig.add_vrect(x0=row["datetime"], x1=row["end_datetime"], line_width=0, fillcolor="red", opacity=0.1, row=1, col=1)
# Layout
fig.update_layout(
title={
"text": "日経平均の日足チャート",
"y":0.9,
"x":0.5,
}
)
# 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)。
fig.add_vrectを使うと、指定して期間(x軸で指定)に色をつけたり、線で囲ったり、文字列を挿入できたりします。
ここでは線は入らないのでline_width=0として、fillcolorをredあるいはblueに指定して、このままだとチャートが見えなくなってしまうので、opacityで透過度を指定しています。
これを見ると三役好転(三役逆転)は連続で発生してることがよくわかりますね。
前半は三役好転が続いていますが、後半は三役好転と三役逆転が交互に繰り返されていることが一目確認できます。
これで可視化は完了です!
データの分析・可視化にはPythonが最適!
本記事で紹介したコードは、全てPythonを使って書いています。
Pythonはデータの分析や可視化を得意とするプログラミング言語で、さらにAI関連のライブラリーも豊富で昨今のAIブームで需要が急拡大しています。
→ 【いますぐ始められます】データ分析をするならPythonが最適です。
また、Pythonは比較的学びやすい言語でもあります。
実際、僕は社会人になってからPythonを独学で習得して転職にも成功し、Python独学をきっかけに人生が大きく変わりました。
→ 【実体験】ゼロからのPython独学を決意してから転職を掴み取るまでのお話。
Pythonの学習方法についてはいろいろな方法があります。
僕はUdemyを選びましたが、書籍やプログラミングスクールも選択肢になります。
→ 【決定版】Python独学ロードマップ【完全初心者からでもOKです】
→ 【まとめ】Pythonが学べるおすすめプログラミングスクール
→ プログラミングの独学にUdemyをおすすめする理由!【僕はUdemyでPythonを独学しました!】
まとめ
いかがでしたでしょうか。
ここでは「【コード解説】Pythonで一目均衡表の三役好転と三役逆転を判定してチャートに表示する」というテーマで、Pythonで三役好転と三役逆転を判定して可視化する方法について解説しました。
三役好転や三役逆転は一目均衡表で最強の売買シグナルとされています。
条件が3つもあるのでパッとチャートを見ただけでは判定が難しいのですが、Pythonを使えばきれいに可視化することができました。
結果を見ると、三役好転あるいは三役逆転になったからといってエントリーすると結構事故りそうな匂いがします。
特にボックス相場では三役好転と三役逆転がどちらも頻出するので混乱しますね。
うまく活用するにはさらに条件を追加したほうが良さそうです。
言い換えれば、三役好転と三役逆転がどちらも頻出してる時はボックス相場の可能性があるのでエントリーするべきではなく、一定期間で三役好転あるいは三役逆転のどちらか一方のみが頻出したらチャンスかもしれないですね。
これは今後詳しく検証してみても面白そうです。
また、Pythonによる一目均衡表の計算方法とチャートによる可視化については過去の記事で解説しているのでご参考ください。
-

【コード解説】Pythonで一目均衡表を計算してチャートで可視化する
続きを見る
ここまで読んでくださり、ありがとうございました。










