Edited at

MACDのアルゴリズム #QuantX

More than 1 year has passed since last update.


MACD

MACD とは,期間の長い指数移動平均と短い指数移動平均の差を使って売買シグナルを出す指標です.



(出典:野村證券 | 株・FXに今すぐ活かせる チャートの読み方・使い方 - トレンドフォロー系指標「移動平均」と「MACD」)

計算式はこのようになります.


MACD = SlowEMA - FastEMA
MACDSignal = SMA(MACD)

ただし
 SlowEMA : 期間の長い指数移動平均
 FastEMA : 期間の短い指数移動平均
 SMA:移動平均関数


シグナル

上記の図の通り,MACDがMACDSignalを上抜いた時,ロングポジションを取ります.


手仕舞い

利益確定水準+5.0%

損切り水準 -3.0%


コード

import pandas as pd

import talib as ta
import numpy as np

def initialize(ctx):
# 設定
ctx.fastperiod = 12
ctx.slowperiod = 26
ctx.signalperiod = 9
ctx.target = 0.10
ctx.plofit = 0.05
ctx.losscut = -0.03

ctx.codes = [6758, 8316, 2914, 7267, 7182, 8058, 8411, 4063, 7751, 5411,
6981, 6902, 3382, 8766, 6367, 6752, 4911, 8001, 6301, 6503,
8031, 5108, 4519, 4578, 1925, 2502, 8801, 2503, 8750, 6273,
7741, 7270, 6971, 4901, 8053, 6869, 6502, 8113, 8725, 8267,
9843, 1605, 4612, 6702, 9021, 8308, 7309, 4188, 6762, 4528,
9202, 2413, 7181, 3402, 6586, 3092, 1878, 6988, 1801, 9502]

ctx.symbol_list = ["jp.stock.{}".format(code) for code in ctx.codes[:50]]
ctx.configure(
channels={ # 利用チャンネル
"jp.stock": {
"symbols": ctx.symbol_list,
"columns": ["close_price_adj"], # 終値(株式分割調整後)
}})

def _MACD_SIGN(data):

df_close = data["close_price_adj"].fillna(method='ffill')

d_macd = dict()
d_macdsignal = dict()
d_macdhist = dict()

# memo参照
for symbol in data.minor_axis:
macd, macdsignal, macdhist = ta.MACD(df_close[symbol].values.astype(np.double),
fastperiod=ctx.fastperiod , slowperiod=ctx.slowperiod, signalperiod=ctx.signalperiod)
d_macd[symbol] = macd
d_macdsignal[symbol] = macdsignal
d_macdhist[symbol] = macdhist

df_macd = pd.DataFrame(d_macd, index=data.major_axis)
df_macdsignal = pd.DataFrame(d_macdsignal, index=data.major_axis)
df_macdhist = pd.DataFrame(d_macdhist, index=data.major_axis)

buy_sig = (df_macd > df_macdsignal) & (df_macd.shift(1) < df_macdsignal.shift(1))

return {
"MACD": df_macd,
"MACDSignal": df_macdsignal,
"MACDHist": df_macdhist,
"buy:sig": buy_sig,
}

# シグナル登録
ctx.regist_signal("MACD_SIGN", _MACD_SIGN)

def handle_signals(ctx, date, current):

df = current.copy()

# 買いシグナル
df_long = df[df["buy:sig"]]
if not df_long.empty:
for (sym, val) in df_long.iterrows():
#ctx.logger.info(val)
sec = ctx.getSecurity(sym)
msg = "買いシグナル"
sec.order_target_percent(ctx.target, comment= msg)

# ポジションクローズ
for (sym,val) in ctx.portfolio.positions.items():
returns = val["returns"]

if returns < ctx.losscut:
sec = ctx.getSecurity(sym)
sec.order_target_percent(0, comment= "損切り")
elif returns > ctx.plofit:
sec = ctx.getSecurity(sym)
sec.order_target_percent(0, comment= "利益確定売")


メモ


TA-lib 

TA-Libは,テクニカル分析の主な指標を算出してくれるライブラリです.色々な指標計算関数が用意されているので便利なのですが,Documentがいまいちで,この返り値は一体なんなの?ということが良くあります.

macd は以下の関数を使います.

macd, macdsignal, macdhist = MACD(close, fastperiod=12, slowperiod=26, signalperiod=9)


data.minor_axis

data は,プロジェクトに最初から用意されているオブジェクトで,指定した銘柄の株価データを pd.Panel の形で保持しています.

(詳しくは,公式ドキュメントの売買シグナル生成部分にある data の説明を参照して下さい.)

data.minor_axis で,銘柄オブジェクトのリストを取得できますので,これをループに渡します.ループでは, df_close のコラム名として銘柄オブジェクト渡して,各銘柄の pd.Serise データを取得し,これを .values.astype(np.double) で ta-lib が引き取る事ができる array 型に変えて,macd に渡します.

先に用意しておいた辞書オブジェクト(d_macdなど)に追加し,ループ終了後に辞書オブジェクトを 'pd.DataFrame' 型のデータに変えています.

そうすることで, buy_sig を簡単に作成することができます.


結果

2018-07-31_17.jpg


感想


  • 7月が終わりますね・・・

  • 長期,短期,およびMACDの移動平均の期間の長さは, macd でデフォルトで使われていた期間を使用しました.

  • 今回の銘柄も東証一部上場銘柄を適当に拾ってきました.


免責注意事項


  • このコードに基づき投資した結果、損害が発生しても,一切責任を持ちません.

  • このコードが正しく機能する保証は一切致しません.

  • このアルゴリズムを勧めているわけではありません.あくまで QuantX / Python のサンプルコードとして掲載しているだけです.