先日のMACD手法を色々な銘柄で試していて気が付いた。
これじゃちょっとシグナル出るの遅いだろ??
日足でやるのがまずいというのは置いといて、元々以下の定義であった。
MACD=12日EMA-26日EMA
Signal=MACDの9日EMA
ヒストグラム=Signal-MACD
だから、日足のデータで翌日の売買の判断が出来ればよいという程度の判断基準である。
特徴的な、出力として、いまはやりの’ZM’を見てみよう。
非常に単調に右肩上がりの絵であり、素直に上げ下げを予測できれば大儲け出来そうである。
※因みに誤解があるとバカな話に見えるので一言...
「購入してずっと持っていればこの場合は大儲けできるが、実際は資金効率でレバがそれなりに大きいので瞬時の爆下げで持ちこたえられずに損切になる状況が前提のお話です」「この銘柄だとレバ二倍で持ちこたえられているので、一倍で1月に購入してたとしても今まで持っていれば現在3倍になっています。これが安全に見えますが、下がるリスクもほぼ同じ程度あるので...」所がよく見ると、ヒストグラムの0を横切る瞬間が少しタイミング的に遅くて、下げの期間が短いとほぼ下がってしまったところで売り、逆に上げが速いと上がってしまった所で買いを出している場合がある。
これは、ちょっと勿体ない。確実に下げや上げを確認してから売買をするのであれば、ほぼ人間の目や判断と同じ意味しかない。
ここでは目指すは自動売買であり、売買の効率や精度が必須だから、やはり数値変動をシミュレートした予測能力を欲しい。
※ここはここで追求するが今日の本題ではない
そこで、理論があるわけではないが、このMACD手法を改善してもっと早い段階で売買シグナルを出す工夫をした。
今回使う定義は以下のとおりである。
※これ使うときはmu_method(ムー・メソッド)と呼んで下さい
series ;時系列データ
series2, cycle = decompose(series)
MACD2 =series2-26日EMA(series2)
Signal2=MACD2の9日EMA
ヒストグラム=Signal2-MACD2
※詳細はおまけのコード参照
すなわち、元データseriesはそのものだとちょっとノイズがあって誤差が大きすぎるので12日EMAして平滑化していた。
しかし、seriesをdecomposeするとノイズ要素が消えるのでほぼ平滑化されたデータのように扱える。
それを元として26日EMAやMACDを計算する。
その結果、12日EMAしたものに比べると、生データに近い辺りでアップダウンするseries2の方がはるかに速い売買シグナルを出してくれる。
結果は、以下のとおりである。
gifアニメにすると、以下のとおりである。
3枚の画像(MACD, trendのMACD、mu-method)を繰り返し再生しているが、タイトルにZMと出るのが今回の改善後の絵である。オリジナルのMACDに比較すると、明らかに3日以上信号が左にシフトしてこれなら売買に間に合うと思う。
※来週早々下落場面がみられるようだ
12日金曜日に下げているんだね
YahooFinance
コードはおまけに置いた。
###まとめ
・MACDの売買シグナルが実際の売買に間に合うように早く出せるように改善した
・いよいよやるかな。。
###おまけ
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import datetime as dt
from pandas_datareader import data
import statsmodels.api as sm
from statsmodels.tsa.seasonal import STL
def get_stock(stock,start,end):
df = data.DataReader(stock, 'stooq',start)["Close"]
df = df.iloc[::-1]
return df[start:end]
def EMA1(x, n):
#k = 3.45*(n+1)
a= 2/(n+1)
return pd.Series(x).ewm(alpha=a).mean()
stock0 = 'ZM'
stock = stock0 #+ '.JP'
start = dt.date(2020,1,1)
end = dt.date(2020,6,13)
df = pd.DataFrame(get_stock(stock, start, end))
date_df=df['Close'].index.tolist()
series = df['Close'].values.tolist()
bunseki = "trend" #series" #cycle" #trend
cycle, trend = sm.tsa.filters.hpfilter(series, 144)
df['Close'] = trend
series2 = df['Close'].values.tolist()
df['Close']=series #series" #cycle" #trend
df['Close2']=series2
df['y12'] = EMA1(df['Close2'], 12)
df['y26'] = EMA1(df['Close2'], 26)
df['MACD'] = df['y12'] -df['y26']
df['MACD2'] = df['Close2'] -df['y26']
df['signal2'] = EMA1(df['MACD2'], 9)
df['signal'] = EMA1(df['MACD'], 9)
df['hist_']=df['MACD2']-df['signal2']
date_df=df['Close'].index.tolist()
print(df[len(series)-10:len(series)])
fig, (ax1,ax2) = plt.subplots(2,1,figsize=(1.6180 * 8, 4*2),dpi=200)
ax1.plot(df['Close'],label="series")
ax1.plot(df['Close2'],label="series2")
ax1.plot(df['y12'],label="y12")
ax1.plot(df['y26'],label="y26")
ax2.plot(df['MACD2'],label="MACD2")
#ax2.plot(df['MACD'],label="MACD")
ax2.plot(df['signal2'],label="signal2")
#ax2.plot(df['signal'],label="signal")
ax2.bar(date_df,df['hist_'])
ax1.set_title("{}".format(stock0))
ax1.legend()
ax2.legend()
ax1.grid()
ax2.grid()
ax2.set_ylim(-5,20)
plt.savefig("./stock/{}/newck_ema_df_decompose_%5K%25D_{}_{}now{}.png".format(stock0,stock,bunseki,start))
plt.pause(1)
plt.close()