AD:(本人录制的backtrader视频课程,大家多多支持哦~ https://edu.youkuaiyun.com/course/detail/9040)
无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。教程链接:https://www.cbedai.net/qtlyx
我们知道,有时候我们要测试的可不仅仅是一个标的,但是之前backtrader的教程中,我们都是针对的是一个标的的回测。如果接触过优矿、ricequant这样的平台的同学,可能觉得backtrader不适合做这样的portfolio层面的回测。确实,似乎backtrader整个官方教程里面,没有任何讲到这种全市场、组合的回测demo,但是backtrader其实也是可以胜任这样的任务的。
前段时间,笔者就做了这样的一个事情,让backtrader能够完成我们想要的组合层面的回测。
1.最终的效果
和一般的portfolio层面的回测平台一样,我们希望,最后我们实现一个策略只要进行一些设置就可以了。笔者利用backtrader封装了一个函数,实现了几乎和优矿一样的功能。
使用的时候,笔者的函数只需要如下的设置:
start_date = "2017-04-01"
end_date = "2017-06-20"
trading_csv_name = 'trading_data_two_year.csv'
portfolio_csv_name = 'port_two_year.csv'
benchmark_csv_name = None
然后我们就可以回测了。笔者把回测的类封装了起来,只要调用笔者的回测类就可以了。
begin = datetime.datetime.now()
result_dict = bt_backtest.backtrader_backtest(start_date=start_date, end_date=end_date, trading_csv_name=trading_csv_name, \
portfolio_csv_name=portfolio_csv_name, bechmark_csv_name=benchmark_csv_name)
然后,回测结束后输出评价指标。
end = datetime.datetime.now()
print "time elapse:", (end - begin)
print 'Start Portfolio Value: %.2f' % result_dict['start_cash']
print 'Final Portfolio Value: %.2f' % result_dict['final_value']
print 'Total Return:', result_dict['total_return']
print 'Sharpe Ratio :', result_dict['sharpe_ratio'] #* 2 # todo there should be consider!
print 'Max Drowdown:', result_dict['max_drowdown'] * 2
print 'Max Drowdown Money:', result_dict['max_drowdown_money']
print "Trade Information", result_dict['trade_info']
result = pd.read_csv('result.csv', index_col=0)
result.plot()
plt.show()
position_info = pd.read_csv('position_info.csv', index_col=0)
接下来说一下我们要输入的这些csv文件吧。
trading_csv_name = 'trading_data_two_year.csv'
portfolio_csv_name = 'port_two_year.csv'
benchmark_csv_name = None
第一个是交易行情的数据,数据格式如下:
tradingdate,ticker,_open,_high,_low,_close,_volume
20070104,000001,14.65,15.32,13.83,14.11,69207082.0
20070104,000002,15.7,16.56,15.28,15.48,75119519.0
20070104,000004,4.12,4.12,3.99,4.06,1262915.0
20070104,000005,2.51,2.53,2.46,2.47,14123749.0
20070104,000006,13.5,14.07,13.39,13.7,15026054.0
20070104,000007,2.44,2.44,2.35,2.36,3014956.0
20070104,000008,4.16,4.24,4.15,4.16,818282.0
20070104,000009,0.0,0.0,0.0,4.23,0.0
20070104,000010,0.0,0.0,0.0,5.37,0.0
20070104,000011,5.78,5.85,5.42,5.45,4292318.0
20070104,000012,11.15,11.3,10.66,10.95,6934903.0
所以,这一部分的数据会相当的大,一天就会有3000条左右的记录,毕竟,A股的股票数目就是这样。如果是用的更小级别的数据,那么数据量必然更大了。
portfolio_csv_name = 'port_two_year.csv'
这是我们调仓日的目标仓位,只需要sigdate,secucode,weight三个字段就行。
benchmark_csv_name自然就是benchmark的daily return数据文件了。这里可以不设置。
2.回测函数
接下来就是核心的回测的函数了。
# -*- coding: utf-8 -*-
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import datetime
import backtrader as bt
from backtrader import Order
import pandas as pd
import matplotlib.pyplot as plt
# Create a Stratey
class AlphaPortfolioStrategy(bt.Strategy):
def log(s