"""
Author: Charmve yidazhang1@gmail.com
Date: 2023-02-13 23:24:15
LastEditors: Charmve yidazhang1@gmail.com
LastEditTime: 2023-03-10 00:01:54
FilePath: /Qbot/pytrader/doc/02.easy_macd_strategy/macd.py
Version: 1.0.1
Blogs: charmve.blog.csdn.net
GitHub: https://github.com/Charmve
Description:
Copyright (c) 2023 by Charmve, All Rights Reserved.
"""
import datetime
import os.path
import sys
import backtrader as bt
from backtrader.indicators import EMA
class TestStrategy(bt.Strategy):
params = (("maperiod", 15),)
def log(self, txt, dt=None):
"""Logging function fot this strategy"""
dt = dt or self.datas[0].datetime.date(0)
print("%s, %s" % (dt.isoformat(), txt))
@staticmethod
def percent(today, yesterday):
return float(today - yesterday) / today
def __init__(self):
self.dataclose = self.datas[0].close
self.volume = self.datas[0].volume
self.order = None
self.buyprice = None
self.buycomm = None
me1 = EMA(self.data, period=12)
me2 = EMA(self.data, period=26)
self.macd = me1 - me2
self.signal = EMA(self.macd, period=5)
bt.indicators.MACDHisto(self.data)
def notify_order(self, order):
if order.status in [order.Submitted, order.Accepted]:
return
if order.status in [order.Completed]:
if order.isbuy():
self.log(
"BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f"
% (order.executed.price, order.executed.value, order.executed.comm)
)
self.buyprice = order.executed.price
self.buycomm = order.executed.comm
self.bar_executed_close = self.dataclose[0]
else:
self.log(
"SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f"
% (order.executed.price, order.executed.value, order.executed.comm)
)
self.bar_executed = len(self)
elif order.status in [order.Canceled, order.Margin, order.Rejected]:
self.log("Order Canceled/Margin/Rejected")
self.order = None
def notify_trade(self, trade):
if not trade.isclosed:
return
self.log("OPERATION PROFIT, GROSS %.2f, NET %.2f" % (trade.pnl, trade.pnlcomm))
def next(self):
self.log("Close, %.2f" % self.dataclose[0])
if self.order:
return
if not self.position:
condition1 = self.macd[-1] - self.signal[-1]
condition2 = self.macd[0] - self.signal[0]
if condition1 < 0 and condition2 > 0:
self.log("BUY CREATE, %.2f" % self.dataclose[0])
self.order = self.buy()
else:
condition = (self.dataclose[0] - self.bar_executed_close) / self.dataclose[
0
]
if condition > 0.1 or condition < -0.1:
self.log("SELL CREATE, %.2f" % self.dataclose[0])
self.order = self.sell()
if __name__ == "__main__":
cerebro = bt.Cerebro()
cerebro.addstrategy(TestStrategy)
modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
datapath = os.path.join(modpath, "603186.csv")
data = bt.feeds.GenericCSVData(
dataname=datapath,
fromdate=datetime.datetime(2010, 1, 1),
todate=datetime.datetime(2020, 4, 12),
dtformat="%Y%m%d",
datetime=2,
open=3,
high=4,
low=5,
close=6,
volume=10,
reverse=True,
)
cerebro.adddata(data)
cerebro.broker.setcash(10000)
cerebro.addsizer(bt.sizers.FixedSize, stake=100)
cerebro.broker.setcommission(commission=0.005)
print("Starting Portfolio Value: %.2f" % cerebro.broker.getvalue())
cerebro.run()
print("Final Portfolio Value: %.2f" % cerebro.broker.getvalue())
cerebro.plot()