以前,Backtesting.pyを使って2本のSMAのゴールデンクロス,デッドクロスによる売買をバックテストしてみました.
今回は,MACDによる売買をバックテストしてみます.
分からないところがあれば,以前の記事もしくは,もう少しだけ詳しく書いたこちらの記事を見てください.
また,まとめコード(実行すれば動くはずのコード)は本記事の一番下にあります.
#株価データの取得
今回は,2018/1/1~現在までのAAPL(Apple)の株価で行いたいと思います.
import pandas_datareader.data as web
import datetime
start = datetime.date(2018,1,1)
end = datetime.date.today()
data = web.DataReader('AAPL', 'yahoo', start, end)
#MACDの計算
TA-Libを用います.詳しくはこちらの記事をご覧ください.
import talib as ta
def MACD(close, n1, n2, ns):
macd, macdsignal, macdhist = ta.MACD(close, fastperiod=n1, slowperiod=n2, signalperiod=ns)
return macd, macdsignal
#MACDによる売買
とりあえずは,
短期EMA : 12日
長期EMA : 26日
シグナル(MACDのSMA) : 9日
でやってみます.
class MACDCross(Strategy):
n1 = 12 #短期EMAの期間
n2 = 26 #長期EMAの期間
ns = 9 #シグナル(MACDのSMA)の期間
def init(self):
self.macd, self.macdsignal = self.I(MACD, self.data.Close, self.n1, self.n2, self.ns)
def next(self): # チャートデータの行ごとに呼び出される
if crossover(self.macd, self.macdsignal): #macdがsignalを上回った時
self.buy() # 買い
elif crossover(self.macdsignal, self.macd): #signalがmacdを上回った時
self.position.close() # 売り
#バックテスト実行
# バックテストを設定
bt = Backtest(
data, # チャートデータ
MACDCross, # 売買戦略
cash=1000, # 最初の所持金
commission=0.00495, # 取引手数料
margin=1.0, # レバレッジ倍率の逆数(0.5で2倍レバレッジ)
trade_on_close=True, # True:現在の終値で取引,False:次の時間の始値で取引
exclusive_orders=True #自動でポジションをクローズ(オープン)
)
output = bt.run() # バックテスト実行
print(output) # 実行結果(データ)
bt.plot() # 実行結果(グラフ)
#結果
Start 2018-01-02 00:00:00
End 2021-04-16 00:00:00
Duration 1200 days 00:00:00
Exposure Time [%] 55.9179
Equity Final [$] 2124.93
Equity Peak [$] 2248.02
Return [%] 112.493
Buy & Hold Return [%] 211.529
Return (Ann.) [%] 25.7844
Volatility (Ann.) [%] 25.3374
Sharpe Ratio 1.01764
Sortino Ratio 1.93756
Calmar Ratio 0.920809
Max. Drawdown [%] -28.0019
Avg. Drawdown [%] -3.60268
Max. Drawdown Duration 314 days 00:00:00
Avg. Drawdown Duration 35 days 00:00:00
# Trades 30
Win Rate [%] 50
Best Trade [%] 27.7723
Worst Trade [%] -9.20929
Avg. Trade [%] 2.61761
Max. Trade Duration 68 days 00:00:00
Avg. Trade Duration 21 days 00:00:00
Profit Factor 2.80024
Expectancy [%] 2.90723
SQN 1.99739
_strategy MACDCross
_equity_curve ...
_trades Size EntryB...
資産額1000 → 2124,リターン+112%という結果がでました.
しかし,Appleの株はこんなもんじゃないということで,手法を最適化してみます.
#手法最適化
MACDやそのシグナルの期間を変えることで,最終資産額が大きくなるように最適化してみたいと思います.
#最適化
output2=bt.optimize(n1=range(10, 100, 10),n2=range(10, 300, 10),ns=range(10, 50, 5), maximize='Equity Final [$]', method='grid')
print(output2)
bt.plot()
##結果
Start 2018-01-02 00:00:00
End 2021-04-16 00:00:00
Duration 1200 days 00:00:00
Exposure Time [%] 54.9517
Equity Final [$] 3521.92
Equity Peak [$] 3648.8
Return [%] 252.192
Buy & Hold Return [%] 211.529
Return (Ann.) [%] 46.6936
Volatility (Ann.) [%] 29.6495
Sharpe Ratio 1.57485
Sortino Ratio 3.74247
Calmar Ratio 2.83619
Max. Drawdown [%] -16.4635
Avg. Drawdown [%] -2.67232
Max. Drawdown Duration 175 days 00:00:00
Avg. Drawdown Duration 21 days 00:00:00
# Trades 11
Win Rate [%] 72.7273
Best Trade [%] 71.0948
Worst Trade [%] -3.82849
Avg. Trade [%] 12.3665
Max. Trade Duration 161 days 00:00:00
Avg. Trade Duration 59 days 00:00:00
Profit Factor 17.9512
Expectancy [%] 14.4032
SQN 1.88405
_strategy MACDCross(n1=40,...
_equity_curve ...
_trades Size EntryB...
資産額1000 → 3521,リターン+252%となりました.さすがApple株ですね.
最適化したMACDでは,短期EMA=40日,長期EMA=50日,シグナル=25日で,取引回数は先ほどの30回から11回に減っています.
#他の銘柄でもやってみた
Appleがいいのか,MACDで売買するのがいいのかイマイチ分からないので,他の銘柄でもやってみます.ただし,最適化はなしで全て以下の条件で行います(先ほどと同じです).
短期EMA:12日
長期EMA:26日
シグナル(MACDのSMA):9日
ただし,日本株の場合は最初の所持金を100倍の100000にします(1ドル=100円と仮定).
他の条件に付いては同じです.
ソースコードは省略し,結果の一部分だけ紹介します.
#テスラ(TSLA)
Equity Final [$] 5785.32
Equity Peak [$] 6173.32
Return [%] 478.532
Buy & Hold Return [%] 1053.99
Return (Ann.) [%] 70.6132
資産:1000 → 5785
強いですね.
#日経平均株価
Equity Final [$] 113223
Equity Peak [$] 119930
Return [%] 13.2232
Buy & Hold Return [%] 26.2867
Return (Ann.) [%] 3.9794
資産:100000 → 113223
日経でもプラスとなりました.
#キヤノン(7751)
Equity Final [$] 55815
Equity Peak [$] 101633
Return [%] -44.185
Buy & Hold Return [%] -38.131
Return (Ann.) [%] -16.4616
資産:100000 → 55815
さすがに2018年からのキヤノンはMACDでも厳しいですね.
結局,長期的に弱い株はどんな手法を使っても駄目だということですね.銘柄選定が大事なわけです.MACDの効果を知るには,資産額ではない別の指標で比べる必要があります.
#まとめコード
import pandas_datareader.data as web
import datetime
start = datetime.date(2018,1,1)
end = datetime.date.today()
data = web.DataReader('AAPL', 'yahoo', start, end)
from backtesting import Backtest, Strategy # バックテスト、ストラテジー
from backtesting.lib import crossover
import talib as ta
def MACD(close, n1, n2, ns):
macd, macdsignal, macdhist = ta.MACD(close, fastperiod=n1, slowperiod=n2, signalperiod=ns)
return macd, macdsignal
class MACDCross(Strategy):
n1 = 12 #短期EMAの期間
n2 = 26 #長期EMAの期間
ns = 9 #シグナル(MACDのSMA)の期間
def init(self):
self.macd, self.macdsignal = self.I(MACD, self.data.Close, self.n1, self.n2, self.ns)
def next(self): # チャートデータの行ごとに呼び出される
if crossover(self.macd, self.macdsignal): #macdがsignalを上回った時
self.buy() # 買い
elif crossover(self.macdsignal, self.macd): #signalがmacdを上回った時
self.position.close() # 売り
# バックテストを設定
bt = Backtest(
data, # チャートデータ
MACDCross, # 売買戦略
cash=1000, # 最初の所持金
commission=0.00495, # 取引手数料
margin=1.0, # レバレッジ倍率の逆数(0.5で2倍レバレッジ)
trade_on_close=True, # True:現在の終値で取引,False:次の時間の始値で取引
exclusive_orders=True #自動でポジションをクローズ(オープン)
)
output = bt.run() # バックテスト実行
print(output) # 実行結果(データ)
bt.plot() # 実行結果(グラフ)
#最適化
output2=bt.optimize(n1=range(10, 100, 10),n2=range(10, 300, 10),ns=range(10, 50, 5), maximize='Equity Final [$]', method='grid')
print(output2)
bt.plot()
投資に関する免責事項
プログラムや考え方の情報の提供・作業代行を目的としており,投資勧誘を目的とするものではありません.また,この記事は投資成績を保証するものではありません.投資はあくまで自己責任でお願いします.