私と私の猫の他は誰でも隠し事を持っている

野良プログラマ発、日々のアウトプット

Pandas 演習としてのテクニカル指標計算 〜 コポック買い指標の巻

10連休短けぇ… もっと色々やりたかったのに… と萎える連休最終日、ブログでも書いて締めますかね。今回は「コポック買い指標」というちょっと聞き慣れないやつを取り上げてみます。これは、月の平均株価を前年同月と比較して騰落率を算出しておき、さらにその移動平均をとって売買サインとする、というものです。月単位なので当然、中長期な売買向けの指標となりますね。

今回の株価データは10年以上程度の長期データが必要なので、いつもの日経平均プロフィルさんではなく、FRED(セントルイス連邦準備銀行)から2000年以降の日経平均を取り寄せることにします。有名所のデータソースなら Pandas DataReader が使えるので、こいつでサクッと。

df = pdt.DataReader('NIKKEI225', 'fred', '2000/1/1',  '2019/04/30')
df.dropna(how='any', inplace=True) # 欠損値を含む行を削除

取得したデータは日足(といっても終値だけですが)なので、月単位の平均に加工します。

df['year'], df['month'] = df.index.year, df.index.month # 年と月の列を追加
df_monthly = df.groupby(['year', 'month']).mean() # 年月単位で終値平均を算出
df_monthly.sort_values(by=['year', 'month'], inplace=True) # この後の集計作業に備えて年・月でソートしておく

下ごしらえができたので、コポック買い指標を計算。対前年騰落率→加重移動平均算出、という流れです。

WMA_MONTHS = 10 # 対前年騰落率の移動平均月数
WMA_WEIGHTS = np.arange(WMA_MONTHS) + 1 # 加重平均用の重み

df_monthly['prev_year_rate'] = df_monthly.rolling(13).apply(lambda x: x[-1] / x[0] - 1, raw=True) # 対前年騰落率を計算
df_monthly['prev_year_rate_wma'] = df_monthly.prev_year_rate.rolling(WMA_MONTHS).apply(lambda x: np.average(x, weights=WMA_WEIGHTS), raw=True) # 加重移動平均を計算

この指標の使い方はシンプルで、上昇に転じたら買いサイン、下降に転じたら売りサインとされるようです。という訳でこのルールで売買サインも検出しておきます。

def detect_sign(vals):
  if vals[0] > vals[1] and vals[1] < vals[2]:
    # 上昇に転じたら買いサイン
    return 1
  elif vals[0] < vals[1] and vals[1] > vals[2]:
    # 下降に転じたら売りサイン
    return -1
  return 0

df_monthly['sign'] = df_monthly.prev_year_rate_wma.rolling(3).apply(detect_sign, raw=True)

ひととおり計算が終わったので可視化を。月株価とコポック指標を上下にグラフ作画し、それぞれに売買サインに挟まれた保持期間を青く塗り潰してみます。

f:id:mariyudu:20190506172723p:plain
月次株価とコポック指標

今回も、コード一式と実行結果は Google Colaboratory で公開してまつ↓。

colab.research.google.com