こんにちは。TATです。
今日のテーマは「Pythonで株価データからパーフェクトオーダーを判定してPlotlyで可視化する方法」です。
株やFXでトレンドを判定する方法として人気のあるパーフェクトオーダーをPythonで判定する方法について解説します。
さらにPlotlyでパーフェクトオーダーをチャートで可視化する方法についても解説していきます。
必要なPythonコードは全て公開していきます。是非ともご活用ください。
目次
パーフェクトオーダーとは?
まずはパーフェクトオーダーについて確認しておきましょう。
パーフェクトオーダーとは?
パーフェクトオーダーとは、複数(3つ以上)の移動平均線が順序よく並んでいる状態を指します。
3つの移動平均線が使用される場合が多く、短期>中期>長期の順番にきれいに並んでいる状態をパーフェクトオーダーと言います。
パーフェクトオーダーは、発生するとトレンドの方向性がはっきり示されるため、特に順張りで活用されることが多い指標の1つです。
短期と中期の移動平均線でゴールデンクロスが発生してパーフェクトオーダーとなったところでエントリーするなど、売買判定に利用することもできます。
Pythonでパーフェクトオーダーを判定する方法
それではここからは、Pythonを使ってパーフェクトオーダーを判定していく方法について解説していきます。
株価データの準備
まずは適当な株価データを用意します。
ここではpandas_datareaderを使ってトヨタ自動車の株価の日足データを用意しました。
株価データの取得方法についてはこちらの記事で解説しているので、ここでは簡潔にいきます。
from pandas_datareader import data
df = data.DataReader('7203.T', 'yahoo')
df.head()
期間を指定しないと、過去5年分のデータが取得されます。
これで株価データの準備はOKです。
-

【日本株対応】Pythonで株価のローソク足データを取得する方法まとめ【CSV、ライブラリ、スクレイピング】
続きを見る
移動平均線を計算する
次に移動平均線を計算します。
移動平均線を計算するためには、pandasのrolling関数を使えば1発で計算できます。
こちらの記事でも解説しています。
本記事では、移動平均線の期間として20日、50日、200日を採用しました。
df["SMA20"] = df["Close"].rolling(window=20).mean() df["SMA50"] = df["Close"].rolling(window=50).mean() df["SMA200"] = df["Close"].rolling(window=200).mean() df.tail()

これで移動平均線が計算できました。
-

【コード解説】Pythonで株価データから主要なテクニカル分析を計算して可視化する【移動平均線、MACD、RSI】
続きを見る
パーフェクトオーダーを判定する
移動平均線が用意できたので、次にパーフェクトオーダーを判定します。
パーフェクトオーダーは、短期移動平均線>中期移動平均線 かつ 中期移動平均線>長期移動平均線となっていることは判定できればOKです。
ここではSMA20>SMA50 かつ SMA50>SMA200となっているかどうかを判定していきます。
これはPythonであれば1行で実装することができます。
import numpy as np df["PerfectOrder"] = np.where((df["SMA20"]>df["SMA50"]) & (df["SMA50"] > df["SMA200"]), 1, 0) df.tail()

NumpyのWhereを使ってパーフェクトオーダーを判定しました。
SMA20>SMA50 かつ SMA50>SMA200を満たしていれば1、満たしていなければ0を返します。
結果はPerfectOrderというカラムに格納しました。
これで、PerfectOrderカラムが1であればパーフェクトオーダーの条件を満たしていると判断することができます。
結果を確認すると、全データ1233個のうち、462個でパーフェクトオーダーとなっていました。結構多いですね。
![]()
Plotlyでパーフェクトオーダーを可視化する
パーフェクトオーダーの判定ができたので、次は可視化してみます。
チャートでパーフェクトオーダーが視覚的に判別できると分析もやりやすくなります。
本記事ではPlotlyを使います。短いコードで簡単にインタラクティブなチャートが描けるのでとても便利です。
Plotlyでローソク足チャートを描く
まずはPlotlyでローソク足チャートを描いてみます。
詳細についてはこちらの記事で解説しているので、ここではコードの紹介のみにとどめます。
ついでに移動平均線も合わせて表示します。
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# Dateをカラムに加える
df.reset_index(inplace=True)
# 非表示にする日付をリストアップ
d_all = pd.date_range(start=df['Date'].iloc[0],end=df['Date'].iloc[-1])
d_obs = [d.strftime("%Y-%m-%d") for d in df['Date']]
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])
# Candlestick
fig.add_trace(
go.Candlestick(x=df["Date"], open=df["Open"], high=df["High"],low=df["Low"], close=df["Close"], showlegend=False),
row=1, col=1
)
# Volume
fig.add_trace(
go.Bar(x=df["Date"], y=df["Volume"], showlegend=False),
row=2, col=1
)
# 移動平均線
fig.add_trace(go.Scatter(x=df["Date"], y=df["SMA20"], name="SMA20", mode="lines", line=dict(width=1)), row=1, col=1)
fig.add_trace(go.Scatter(x=df["Date"], y=df["SMA50"], name="SMA50", mode="lines", line=dict(width=1)), row=1, col=1)
fig.add_trace(go.Scatter(x=df["Date"], y=df["SMA200"], name="SMA200", mode="lines", line=dict(width=1)), row=1, col=1)
# 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)],
tickformat='%Y/%m/%d',
)
fig.update(layout_xaxis_rangeslider_visible=False)
fig.show()
上記のコードでローソク足チャートと移動平均線を描くことができました。
土日祝日をスキップして営業日のみを表示するために、rangebreaksで不要な日付も指定しています。
-

PythonのPlotlyでインタラクティブな株価のローソク足チャートを描く【コード解説】
続きを見る
パーフェクトオーダーを可視化するための事前準備
ここからパーフェクトオーダーを加えていくわけですが、まずは少しデータの事前準備を行います。
今回はパーフェクトオーダーになっている期間を視覚的に判断できるように色をつけてみようと思います。
このためには、パーフェクトオーダーになっている期間の情報が必要です。
開始日と終了日のデータされあれば、Plotlyでいい感じに可視化することができます。
まずはコード公開
ということで、まずはこのパーフェクトオーダーの開始日と終了日のデータをまとめます。
# 前日との差分を計算する --> -1, 0, 1のいずれかになる df["PerfectOrder_diff"] = df["PerfectOrder"].diff() # PerfectOrder_diffが1あるいは-1のデータのみを抽出してShiftでデータを1日ずらす --> これが終了日となる df["end_date"] = df[df["PerfectOrder_diff"].isin([1, -1])]["Date"].shift(-1) # PerfectOrder_diffが1となっている部分を抽出 --> パーフェクトオーダーが始まった日のデータだけを抽出 df_po = df[df["PerfectOrder_diff"]==1] df_po.head()[["Date", "end_date"]]

上記のコードではパーフェクトオーダーの開始日と終了日をまとめることができました。
簡単にコード解説
簡単に解説しますと、まずはdiff()でPerfectOrderの差分を計算します。
これは-1, 0, 1のいずれかになり、-1なら1→0に切り替わったことを意味するので、パーフェクトオーダーの終了を意味します。
1なら0→1でパーフェクトオーダーが開始を意味します。0なら変化なしです。
この結果を利用して、PerfectOrder_diffが1か-1のデータを抽出すると1と−1が交互に出てきます。
これをShift関数で1つ前にずらしてあげると、開始日(PerfectOrder_diffが1になっている部分)には終了日のデータが格納されます。
最後にPerfectOrder_diffが1となっているデータだけを取り出して、df_poという新しいDataFrameに格納して完成です。
結果を見ると、パーフェクトオーダーの開始日と終了日がまとまっていることが確認できます。
これで事前準備は完了です。
パーフェクトオーダーをローソク足チャートに加える
それでは、パーフェクトオーダーを先ほどのローソク足チャートに加えます。
add_vrect()を使って、パーフェクトオーダーの条件を満たしている期間を色付けしました。
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# 非表示にする日付をリストアップ
d_all = pd.date_range(start=df['Date'].iloc[0],end=df['Date'].iloc[-1])
d_obs = [d.strftime("%Y-%m-%d") for d in df['Date']]
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])
# Candlestick
fig.add_trace(
go.Candlestick(x=df["Date"], open=df["Open"], high=df["High"],low=df["Low"], close=df["Close"], showlegend=False),
row=1, col=1
)
# Volume
fig.add_trace(
go.Bar(x=df["Date"], y=df["Volume"], showlegend=False),
row=2, col=1
)
# 移動平均線
fig.add_trace(go.Scatter(x=df["Date"], y=df["SMA20"], name="SMA20", mode="lines", line=dict(width=1)), row=1, col=1)
fig.add_trace(go.Scatter(x=df["Date"], y=df["SMA50"], name="SMA50", mode="lines", line=dict(width=1)), row=1, col=1)
fig.add_trace(go.Scatter(x=df["Date"], y=df["SMA200"], name="SMA200", mode="lines", line=dict(width=1)), row=1, col=1)
for i in range(len(df_po)):
row = df_po.iloc[i]
fig.add_vrect(x0=row["Date"], x1=row["end_date"], line_width=0, fillcolor="blue", opacity=0.1, row=1, col=1)
# 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)],
tickformat='%Y/%m/%d',
)
fig.update(layout_xaxis_rangeslider_visible=False)
fig.show()
ご覧の通り、パーフェクトオーダーが発生している期間が青色になりました。
これなら、チャートを見るだけでパーフェクトオーダーの条件を満たしている期間を簡単に把握することができます。
後半の上昇トレンドをうまく捉えることも確認できますね。
トヨタ自動車の結果をみた感じ、パーフェクトオーダーを加味して、短期と中期のゴールデンクロスとデッドクロスで売買したらそこそこの利益が出そうな感じがします。
まとめ
本記事では、「Pythonで株価データからパーフェクトオーダーを判定してPlotlyで可視化する方法」というテーマでお話しました。
パーフェクトオーダーはトレンドを把握するために有効なテクニカル指標です。
Pythonを使えば、移動平均線の計算はもちろん、パーフェクトオーダーの判定も簡単に実装することができます。
Plotlyを使ってパーフェクトオーダーが発生している期間を可視化することもできました。
本記事では、移動平均線の期間を20日、50日、200日としましたが、この組み合わせをいろいろと試してみて、より良いパターンを見つけていくのも楽しそうです。
是非とも本記事のコードを活用して試してみてください。
ここまで読んでくださり、ありがとうございました。








