使用tushare数据进行backtrader回测

        tushare是很方便的数据获取平台,提供多种金融数据,近乎包含了普通金融数据库中的所有数据,供一般学习研究使用足以。通过python接口,可以直接访问数据,无需下载,十分便捷。本人也在学校课程中初次了解到了tushare,并注册了tushare账号ID:455337。

数据获取

         使用策略进行时,需要加数据到backtrader中,backer支持csv数据,默认为来自yahoofinance的数据,但最常用的还是使用自己的csv数据。这时使用tushare进行数据获取就很方便了。

1.连接tushare接口:这里使用的是新版的tushare pro接口,注册账户后可在个人主页获取token

import tushare as ts
TOKEN = '****'
pro = ts.pro_api(token=TOKEN)

2.这里我已经进行了股票alpha的计算,令alpha最小的十只股票作为资产组合,将他们的股票代码记录到code中。

#读取选股的结果
df=pd.read_csv('stock_alpha.csv')
df.columns=['ts_code','name','alpha']
min_a=df.sort_values(by='alpha')
min_a=min_a.iloc[:10,:] 
code=[]
code=min_a['ts_code']#记录alpha最小的10支股票代码

3.定义用tushare读取数据的函数:使用pro.daily()获取股票日数据

def ts_get_daily_stock(code,start_dt,end_dt):
    data = pro.daily(ts_code = code,start_date = start_dt,end_date=end_dt)
    data['trade_date'] = pd.to_datetime(data['trade_date'])
    data=data.sort_values(by = 'trade_date')
    data.index = data['trade_date']
    data = data[
        ['ts_code', 'open', 'high', 'low', 'close', 'pre_close', 'change', 'pct_chg', 'vol', 'amount']]
    return data

 4.简单的循环获取并保存数据

for i in range(len(code)):
    data=ts_get_daily_stock(code.iloc[i],'20190101','')#字段分别为股票代码、开始日期、结束日期
    data.to_csv(code.iloc[i]+'.csv')
cerebro = bt.Cerebro()
for i in range(len(code)):#循环获取10支股票历史数据
    data = bt.feeds.GenericCSVData(
            dataname=code.iloc[i]+'.csv',
            fromdate=datetime.datetime(2019, 1, 1),
            todate=datetime.datetime(2021, 7, 15),
            dtformat='%Y-%m-%d',
            datetime=0,#定义trade_date在第0列
            open=2,
            high=3,
            low=4,
            close=5,
            volume=9,
            nullvalue=0.0,#设置空值
        )
    cerebro.adddata(data)

使用策略对数据进行回测

        使用的策略基本思路为:对股票30日的收益率并进行排序,选择前5只股票,如果某只个股满足股价位于10均线以上且没有持仓时买入;如果某只个股已持仓但判断不在选股池中或股价位于10均线以下则卖出。

策略非原创,只做了微小调整,代码详情来源于https://blog.csdn.net/ndhtou222/article/details/106416802

加载数据,进行回测

cerebro = bt.Cerebro()
for i in range(len(code)):#循环获取10支股票历史数据
    data = bt.feeds.GenericCSVData(
            dataname=code.iloc[i]+'.csv',
            fromdate=datetime.datetime(2019, 1, 1),
            todate=datetime.datetime(2021, 7, 15),
            dtformat='%Y-%m-%d',
            datetime=0,#定义trade_date在第0列
            open=2,
            high=3,
            low=4,
            close=5,
            volume=9,
            nullvalue=0.0,#设置空值
        )
    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)}')