概述
backtrader执行的策略的概念是,我们使用cerebro.adddata(data)把数据加载完成后,针对加载的数据,通过判断买卖股票的时间点,所买卖算法,以下面的代码为例子:class MyStrategy(bt.Strategy):中所写的代码,其实就是策略,下面回针对构建策略做简单的讲解
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 MyStrategy(bt.Strategy):
# 策略参数
params = dict(
period=20, # 均线周期
look_back_days=30,
printlog=False
)
def __init__(self):
self.mas = dict()
#遍历所有股票,计算20日均线
for data in self.datas:
self.mas[data._name] = bt.ind.SMA(data.close, period=self.p.period)
def next(self):
#计算截面收益率
rate_list=[]
for data in self.datas:
if len(data)>self.p.look_back_days:
p0=data.close[0]
pn=data.close[-self.p.look_back_days]
rate=(p0-pn)/pn
rate_list.append([data._name,rate])
#股票池
long_list=[]
sorted_rate=sorted(rate_list,key=lambda x:x[1],reverse=True)
long_list=[i[0] for i in sorted_rate[:10]]
# 得到当前的账户价值
total_value = self.broker.getvalue()
p_value = total_value*0.9/10
for data in self.datas:
#获取仓位
pos = self.getposition(data).size
if not pos and data._name in long_list and
self.mas[data._name][0]>data.close[0]:
size=int(p_value/100/data.close[0])*100
self.buy(data = data, size = size)
if pos!=0 and data._name not in long_list or
self.mas[data._name][0]<data.close[0]:
self.close(data = data)
def log(self, txt, dt=None,doprint=False):
if self.params.printlog 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.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.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}')
pro=ts.pro_api('cbb257058b7cb228769b4949437c27c27e5132e882747dc80f01a5a5')
def ts_get_daily_stock(code,start_dt,end_dt):
start_dt = start_dt.replace("'", "", 3);
end_dt = end_dt.replace("'", "", 3);
#start_dt = '20190101'
#end_dt=''
print(code,start_dt,end_dt)
data = pro.daily(ts_code = code,start_date = start_dt,end_date=end_dt)
print(data)
data['trade_date'] = pd.to_datetime(data['trade_date'])
data=data.sort_values(by = 'trade_date')
data.index = data['trade_date']
data['openinterest']=0
data['volume']=data['vol']
data = data[
['open','close','high','low','volume']
]
return data
#读取选股的结果
df=pd.read_csv('stock_alpha.csv')
df.columns=['ts_code','name','alpha','start_dt','end_dt']
min_a=df.sort_values(by='alpha')
min_a=min_a.iloc[:10,:]
code=[]
code=min_a['ts_code']#记录alpha最小的10支股票代码
start_dts=[]
start_dts=min_a['start_dt']#记录alpha最小的10支股票代码
end_dts=[]
end_dts=min_a['end_dt']#记录alpha最小的10支股票代码
for i in range(len(code)):
data=ts_get_daily_stock(code.iloc[i],start_dts.iloc[i],end_dts.iloc[i])#字段分别为股票代码、开始日期、结束日期
data.to_csv(code.iloc[i]+'.csv')
cerebro = bt.Cerebro()
for i in range(len(code)):#循环获取10支股票历史数据
dataframe = pd.read_csv(code.iloc[i]+'.csv', index_col=0, parse_dates=True)
dataframe['openinterest'] = 0
data = bt.feeds.PandasData(dataname=dataframe,
fromdate = datetime.datetime(2019, 1, 1),
todate = datetime.datetime(2022, 3, 22)
)
cerebro.adddata(data)
#回测设置
startcash=100000.0
cerebro.broker.setcash(startcash)
# 设置佣金为千分之一
cerebro.broker.setcommission(commission=0.001)
# 添加策略
cerebro.addstrategy(MyStrategy,printlog=True)
cerebro.run()
#获取回测结束后的总资金
portvalue = cerebro.broker.getvalue()
pnl = portvalue - startcash
#打印结果
print(f'总资金: {round(portvalue,2)}')
print(f'净收益: {round(pnl,2)}')
cerebro.plot()
量化回测说白了是使用历史数据去验证交易策略的性能,因此回测的第一步是搭建交易策略,这也是backtrader要设置的最重要和复杂的部分,策略设定好后,其余部分的代码编写是手到擒来。
01构建策略(Strategy)
交易策略类代码包含重要的参数和用于执行策略的功能,要定义的参数或函数名如下:
(1)params-全局参数,可选:更改交易策略中变量/参数的值,可用于参数调优。
(2)log:日志,可选:记录策略的执行日志,可以打印出该函数提供的日期时间和txt变量。
(3) __init__:用于初始化交易策略的类实例的代码。
(4)notify_order,可选:跟踪交易指令(order)的状态。order具有提交,接受,买入/卖出执行和价格,已取消/拒绝等状态。
(5)notify_trade,可选:跟踪交易的状态,任何已平仓的交易都将报告毛利和净利润。
(6)next,必选:制定交易策略的函数,策略模块最核心的部分
以上的策略介绍复制了
【手把手教你】入门量化回测最强神器backtrader(一) - 知乎
感谢大佬
最后
以上就是靓丽猎豹为你收集整理的量化交易4-backtrader的执行策略编写的全部内容,希望文章能够帮你解决量化交易4-backtrader的执行策略编写所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复