直近安値を取得するコードをpython3で書く
直近安値について明確な定義はないと思うが、ここでは次のように、安値を曲線と見た場合の変曲点における極小値として求める。
直近安値取得関数
import numpy as np def calc_most_recent_low(data, width=5): """ 直近安値を求める。 :param data: 対象データ列。安値のリストを想定。 :param width: 平均計算等のウィンドウ幅 :return: 最小値リスト、変曲点リスト """""" """ # widthデータからの移動平均と最小値を取得 temp = [np.array(data[width - 1:])] for n in range(width - 1): temp = np.insert(temp, 0, np.array(data[width - 1 - 1 - n:-1 - n]), axis=0) average_data = np.mean(temp, axis=0) min_data = np.min(temp, axis=0) # 要素数をdataと同じ要素数に揃える for n in range(width - 1): average_data = np.insert(average_data, 0, average_data[0]) min_data = np.insert(min_data, 0, min_data[0]) # 移動平均を曲線と見なして微分、符号が負から正に変わる変曲点を取得 diff = average_data[1:] - average_data[0:-1] inflection_point = (diff[0:-1] <= 0) * (diff[1:] > 0) # 要素数を揃える。 inflection_point = np.insert(inflection_point, 0, False) inflection_point = np.append(inflection_point, False) # 変曲点で最小値が更新される直近安値リストを生成 most_recent_low = np.zeros(len(data)) for n in range(len(most_recent_low)): if n == 0 or inflection_point[n]: most_recent_low[n] = min_data[n] else: most_recent_low[n] = most_recent_low[n - 1] return [most_recent_low, inflection_point, average_data]
結果の例
チャートで表示すると次の通りである。
ここでは青い点がその日の直近安値、赤い点が変曲点における安値を表している。
また、関数の引数widthは、安値曲線を移動平均とする場合のウィンドウ幅である。上記チャートでは安値は移動平均していないが、細かな安値を拾いたくない場合はこのwidthを2以上にして安値曲線を滑らかにしてやればいい。
widthを大きくするごとに、変曲点取得用の曲線が滑らかになり、細かな極小値を直近安値として取得しなくなることが分かる。
チャート表示関数
なお、上記で用いたローソク足、移動平均線、直近安値を図示する関数は次の通りである。
import matplotlib.pyplot as plt import mpl_finance def plot_ohlc_and_mrl(df, days = 100, width = 1): # 直近安値を取得 most_recent_low, inflection_point, aline = calc_most_recent_low(df.安値, width=width) # 表示 fig = plt.figure(figsize=[15, 5]) ax = fig.add_subplot(111) # ローソク足(データの後半をdays日分切り取り) ohlc = np.array([list(range(len(df))), list(df.始値), list(df.安値), list(df.高値), list(df.終値)]).T mpl_finance.candlestick_ohlc(ax, ohlc[-days:], width=0.7, colorup='g', colordown='r') # x軸 x_index = range(len(df) - days, len(df)) # 移動平均線 ax.plot(x_index, aline[-days:]) # 直近安値 ax.plot(x_index, most_recent_low[-days:], 'b.') # 変曲点 for i in x_index: if inflection_point[i]: ax.plot(i, most_recent_low[i], 'ro') # x軸ラベル skip = 5 x_index_skip = range(len(df) - 1 - skip*(days//skip), len(df), skip) x_label = [x for x in df.index][-1-skip*(days//skip)::skip] plt.xticks(x_index_skip, x_label) # 表示データ範囲の指定 ax.set_xlim(len(df) - days, len(df)) ax.grid() # グリッド fig.autofmt_xdate() # x軸のオートフォーマット plt.show()