【Python】【テクニカル指標】新高値ブレイクの検出とローソク足への追加描画
「新高値」とは株価が上昇し、過去の最高値を超えたときの価格をいいます。株価がボックス圏を抜けて新高値ブレイクするタイミングで投資してトレンドに乗っていこうという新高値ブレイク投資法というのもあるようです。
ここでは株価データを取得し、mplfinanceを使用してローソク足チャートを描画し、新高値ブレイクするタイミングをローソク足チャートに追加ていきます。
なお、最低限のポイントのみの説明にするため、Pythonライブラリ、モジュール等のインストール方法については割愛させて頂きます。お使いのPC環境等に合わせてインストールしてもらえればと思います。
1.ライブラリをインポートする
まず、pandas、numpy、matplotlib、mplfinance、pandas_datareader、scipyライブラリのsignalの中にあるargrelmin, argrelmaxをインポートします。mplfinanceを使用することで簡単にローソク足チャートを描画できます。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import mplfinance as mpf
from scipy.signal import argrelmin, argrelmax
import pandas_datareader.data as web
import datetime
2.株価データを取得する
下記を参考にOHLCV(始値 / 高値 / 安値 / 終値 / 出来高)形式の日経平均株価(^NKX)データを取得します。データの取得期間は、2022年10月1日から現在の日付までです。
※stooqでデータ取得した場合、日付の降順にデータが並ぶようです。df.sort_index(inplace=True)で昇順に並び替えています。
start = '2022-10-01'
end = datetime.date.today()
df = web.DataReader('^NKX', 'stooq', start, end)
# 日付を昇順に並び替える
df.sort_index(inplace=True)
https://note.com/scilabcafe/n/n0060466ef5c3
3.極大値を検出する
ここでは、scipyライブラリのsignalの中にあるargrelmaxという関数を使って極大を判定していきます。argrelmax(df['High'].values, order)によりピーク値のインデックスを取得できます。argrelmax関数には、array形式でデータを渡す必要があるので、df['High'].valuesで配列に変換してデータを渡します。また、orderの値を変更すると、抽出する間隔が変わります。
データフレームdfにPeak_detectカラムを追加し、極大値検出時にそのカラムに1を格納します。
# 極大値をとったときのインデックスを取得
peak = argrelmax(df['High'].values, order=5)
peak_ind = df.iloc[peak].index
# 極大値検出時にPeak_detectを1に
df['Peak_detect'] = 0
df.loc[peak_ind, 'Peak_detect'] = 1
df.head(20)で先頭から20行を確認します。
df.head(20)
4.当日の高値が直近の極大値を超えた日を検出する
4.1 直前の極大値をとったときの日付と高値を格納
極大値検出時 df['Peak_detect'] == 1 のときの日付と高値をそれぞれdf['Peak_Date'] と df['Peak_Price'] に格納する。
# 極大値の日付データの追加
df['Peak_Date'] = np.nan
df.loc[(df['Peak_detect'] == 1), 'Peak_Date'] = df[df['Peak_detect'] == 1].index
# 極大値の高値データの追加
df['Peak_Price'] = np.nan
df.loc[(df['Peak_detect'] == 1), 'Peak_Price'] = df['High']
極大検出から次の極大検出までの間の df['Peak_Date'] と df['Peak_Price'] の NaN を極大検出時の日付と高値で補完する。
# Nullを直前の値で補完
df['Peak_Date'] = df['Peak_Date'].fillna(method="ffill")
df['Peak_Price'] = df['Peak_Price'].fillna(method="ffill")
df.head(20)で先頭から20行を確認します。
df.head(20)
4.2 当日の高値が直近の極大値を超えた日を検出
当日の高値が直近の極大値を超えた日を検出して、df['Break_p0'] に 1 を格納する。
df['Break_p0'] = 0
df.loc[(df['High'] > df['Peak_Price']), 'Break_p0'] = 1
4.3 ブレイクした最初の日を検出して高値を格納する
df['Break_p0'].shift() でカラムを1つ下にずらし、df['Break_p1']に格納する。df['Break_p0'] と df['Break_p1'] の差分を取り、df['Break_p0'] - df['Break_p1']) == 1 となった場合を最初の検出日として、df['Break']にそのときの高値を格納する。なお、df['Break']は、新高値ブレイクポイントをローソク足チャート上にマーキングするときに用いるためである。
df['Break_p1'] = df['Break_p0'].shift()
df['Break'] = np.nan
df.loc[((df['Break_p0'] - df['Break_p1']) == 1), 'Break'] = df['High']
df.head(20)で先頭から20行を確認します。
df.head(20)
5.ローソク足チャートに新高値ブレイクポイントを追加して描画する
mplfinanceで、新高値ブレイクの開始位置を縦方向に一点鎖線表示するため、ブレークポイントのインデックスをリスト化しておきます。
vlines_sign = df[df['Break'].isnull()==False].index.tolist()
mplfinanceで、直近の高値ポイントからブレイクポイントまでを水平に一点鎖線(青線)表示するため、リスト化しておきます。
lines = []
for d in df[df['Break'].isnull()==False].index:
if df.loc[d]['Peak_Date'] > df.index.min():
lines.append([(df.loc[d]['Peak_Date'], df.loc[d]['Peak_Price']), (df.loc[d].name, df.loc[d]['Peak_Price'])])
5日移動平均 df['SMA5']、20日移動平均 df['SMA20']、60日移動平均 df['SMA60']、100日移動平均 df['SMA100']、200日移動平均 df['SMA200']をaddplotで追加します。さらに、ブレイクポイント df['Break']をaddplotで追加します。
addplotの中には、リスト形式で表示したいデータを指定します。
panelオプションでパネル番号を指定
colorオプションでプロットの色を指定
widthオプションで描画の線の太さを設定
移動平均線は0番目のパネルに、出来高は1番目のパネルに、パーフェクトオーダーは2番目のパネルに表示されます。
# 移動平均
df['SMA5'] = df['Close'].rolling(window=5).mean()
df['SMA20'] = df['Close'].rolling(window=20).mean()
df['SMA60'] = df['Close'].rolling(window=60).mean()
df['SMA100'] = df['Close'].rolling(window=100).mean()
df['SMA200'] = df['Close'].rolling(window=200).mean()
# スタイルを定義
my_style = mpf.make_mpf_style(
base_mpf_style='binance',
rc={
'xtick.labelsize': 8,
'ytick.labelsize': 8,
'grid.alpha': 0.7,
}
)
apd = [
# 5日移動平均線
mpf.make_addplot(df['SMA5'], color='red', panel=0, width=1),
# 20日移動平均線
mpf.make_addplot(df['SMA20'], color='orange', panel=0, width=1),
# 60日移動平均線
mpf.make_addplot(df['SMA60'], color='purple', panel=0, width=1),
# 100日移動平均線
mpf.make_addplot(df['SMA100'], color='blue', panel=0, width=1),
# 200日移動平均線
mpf.make_addplot(df['SMA200'], color='green', panel=0, width=1),
# 青色▼のブレイクポイントを定義
mpf.make_addplot(df['Break'], type='scatter', markersize=50, marker='v', color='blue', panel=0),
]
# ラベルをつけてチャートを表示
fig, axes = mpf.plot(
df,
type="candle",
volume=True,
style=my_style,
addplot=apd,
returnfig=True,
figsize=(10, 8),
datetime_format="%Y/%m/%d",
tight_layout=True,
#直近の高値ポイントからブレイクポイントまでを水平に一点鎖線(青線)表示
alines=dict(alines=lines, linewidths=0.7, alpha=0.7, colors="blue", linestyle='-.'),
# 新高値ブレイクの開始位置を縦方向に一点鎖線表示
vlines=dict(vlines=vlines_sign, colors='grey', linewidths=1.0, linestyle='-.'),
)
# ラベル名とラベルサイズの定義
axes[0].set_ylabel("Price", fontsize=9)
axes[2].set_ylabel("Volume", fontsize=9)
# 罫線はy軸のみに変更
axes[0].grid(axis="y")
axes[2].grid(axis="y")
# ラベルを追加
axes[0].legend(['MA5', 'MA20', 'MA60', 'MA100', 'MA200'])
# axes[2].legend(['PerfectOrder'])
# チャートを表示
fig.show()
ローソク足チャートの描画の参考
https://note.com/scilabcafe/n/nd0719f248df0
mplfinanceを使用してローソク足チャートに株価が新高値ブレイクするタイミングを可視化できました。この方法を使えばボックス圏から株価がブレイクしたタイミングを自動検出することができるようになり、エントリーポイントの判定にも活用できます。