先上代码,以下代码描述了,当MACD柱大于0(红柱)且无持仓时满仓买入,当MACD柱小于0(绿柱)且持仓时全部清仓。
import tushare as ts import pandas as pd import datetime # For datetime objects import os.path # To manage paths import sys # To find out the script name (in argv[0]) # Import the backtrader platform import backtrader as bt class TestStrategy(bt.Strategy): params = (('p1', 12), ('p2', 26), ('p3', 9)) def __init__(self): self.order = None # 获取MACD柱 self.macdhist = bt.ind.MACDHisto(self.data, period_me1=self.p.p1, period_me2=self.p.p2, period_signal=self.p.p3) def next(self): pos = self.getposition(data).size if not self.position: # 得到当前的账户价值 total_value = self.broker.getcash() # 1手=100股,满仓买入 size = int((total_value / 100) / self.datas[0].close[0]) * 100 # 当MACD柱大于0(红柱)且无持仓时满仓买入 if self.macdhist > 0: print('买入,macdhist->' + ',持仓数量->' + str(pos) + ',买入数量->' + str(size)) self.order = self.buy(size=size) else: # 当MACD柱小于0(绿柱)且持仓时全部清仓 if self.macdhist < 0: print('卖出,macdhist->' + ',持仓数量->' + str(pos)) self.close() def log(self, txt, dt=None, doprint=False): if True or doprint: dt = dt or self.datas[0].datetime.date(0) print(f'{dt.isoformat()},{txt}') # 记录交易执行情况(可省略,默认不输出结果) def notify_order(self, order): # 如果order为submitted/accepted,返回空 if order.status in [order.Submitted, order.Accepted]: return # 如果order为buy/sell executed,报告价格结果 if order.status in [order.Completed]: if order.isbuy(): self.log(f'买入:\n价格:{order.executed.price:.2f},\ 成本:{order.executed.value:.2f},\ 数量:{order.executed.size:.2f},\ 手续费:{order.executed.comm:.2f}') self.buyprice = order.executed.price self.buycomm = order.executed.comm else: self.log(f'卖出:\n价格:{order.executed.price:.2f},\ 成本: {order.executed.value:.2f},\ 数量:{order.executed.size:.2f},\ 手续费{order.executed.comm:.2f}') self.bar_executed = len(self) # 如果指令取消/交易失败, 报告结果 elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.log('交易失败') self.order = None # 记录交易收益情况(可省略,默认不输出结果) def notify_trade(self, trade): if not trade.isclosed: return self.log(f'策略收益:\n毛收益 {trade.pnl:.2f}, 净收益 {trade.pnlcomm:.2f}') if __name__ == '__main__': # 加载策略 cerebro = bt.Cerebro() cerebro.addstrategy(TestStrategy) dataframe = pd.read_csv('dfqc.csv', index_col=0, parse_dates=True) dataframe['openinterest'] = 0 data = bt.feeds.PandasData(dataname=dataframe, fromdate=datetime.datetime(2006, 8, 18), todate=datetime.datetime(2007, 8, 18) ) # Add the Data Feed to Cerebro cerebro.adddata(data) # 设置初始资本为10,000 startcash = 100000 cerebro.broker.setcash(startcash) # 设置交易手续费为 0.1% cerebro.broker.setcommission(commission=0.001) print('组合期初资金: %.2f' % cerebro.broker.getvalue()) cerebro.run() #获取回测结束后的总资金 print('组合期末资金: %.2f' % cerebro.broker.getvalue()) cerebro.plot()
组合期末资金:328495.06
数据下载地址
链接:https://pan.baidu.com/s/1nWxz7hQBKIYMozgNHfIBsQ
提取码:bh1q
以上的代码中使用到了另外股票中另外一个重要的指标MACD指标,MACD的指标获取方式self.macdhist = bt.ind.MACDHisto(self.data, period_me1=self.p.p1, period_me2=self.p.p2, period_signal=self.p.p3)
backtrader所有支持的指标封装在indicators中。打开backtrader安装路径,以Anaconda为例,打开\Lib\site-packages\backtrader\,进入indicators文件夹,可以看到里面有48个py文件,文件名是各个技术指标或公示的简称
以上是包含了策略的代码,以下是没有策略的代码,只输出了 指标的代码,包括:MACD、BBands、RSI
import tushare as ts
import pandas as pd
import datetime # For datetime objects
import os.path # To manage paths
import sys # To find out the script name (in argv[0])
# Import the backtrader platform
import backtrader as bt
class TestStrategy(bt.Strategy):
def __init__(self):
bt.ind.MACD(self.data)
bt.ind.MACDHisto(self.data)
bt.ind.RSI(self.data, period=5)
bt.ind.BBands(self.data)
def next(self):
if not self.position:
print('aaa')
if __name__ == '__main__':
# 加载策略
cerebro = bt.Cerebro()
cerebro.addstrategy(TestStrategy)
dataframe = pd.read_csv('dfqc.csv', index_col=0, parse_dates=True)
dataframe['openinterest'] = 0
data = bt.feeds.PandasData(dataname=dataframe,
fromdate=datetime.datetime(2006, 8, 18),
todate=datetime.datetime(2007, 8, 18)
)
# Add the Data Feed to Cerebro
cerebro.adddata(data)
# 设置初始资本为10,000
startcash = 100000
cerebro.broker.setcash(startcash)
# 设置交易手续费为 0.1%
cerebro.broker.setcommission(commission=0.001)
print('组合期初资金: %.2f' % cerebro.broker.getvalue())
cerebro.run()
#获取回测结束后的总资金
print('组合期末资金: %.2f' % cerebro.broker.getvalue())
cerebro.plot()