量化系统之benchmark绩效管理
收益率
无论是一支股票或一个股票组合,每个周期(后续我们默认是每天吧,A股不支持日内交易)结束,都可以计算出净值。就是按当前收盘价,计算持仓的市值加上剩余的现金部分。
benchmark一般就是指数,我们在一个回测周期里,是把它作为参考标的来衡量市场的,所以,就把它当一支股票buy and hold(买入并持有)即可。
为了简单,我们这里忽略那一买一卖的成本。假设我们持有一股指数。这样就很简单的。
#在加载完数据,直接计算“收益率”/净值曲线
def load_benchmark_data(self):
self.df_index_data = pd.DataFrame(data_utils.get_prices_by_code(self.benchmark_code,self.start_date,self.end_date,index=True))
self.df_index_data.index = self.df_index_data['date']
df = self.df_index_data[['close']] #净资产
df['benchmark_returns'] = df['close']/df['close'].shift(1) - 1 #收益率
df['benchmark_equity_curve'] = (1 + df['benchmark_returns']).cumprod()#1股净资产曲线
self.performance = df
至此,benchmark的数据库建设及初始化工作就完成了。
然后是主体data.py里数据加载及操作。很多策略是有股票池的概念,就是选股策略在特定的系列股票里选择,而不是全局。
有一个较常用的操作,尤其是价格驱动型的策略,会选比如指数成份股,比如上证综指,上证50或沪深300等。
#取指数成份股列表
def get_index_components(code,date = None):
if date is None:
date = datetime.datetime.today()
filter = {'name':1,'code':1,'_id':0}
items = query_docs('index_component',{'SecuCode':code,'InDate':{'$lte':date},'OutDate':{'$gt':date}},filter)
return list(items)
如下就是取到的沪深300成份股列表:
code name
0 000001 平安银行
1 000002 万科
2 000008 神州高铁
3 000060 中金岭南
4 000063 中兴通讯
5 000069 华侨城
6 000100 TCL集团
7 000157 中联重科
8 000402 金融街
9 000413 东旭光电
10 000415 渤海金控
11 000423 东阿阿胶
12 000425 徐工机械
13 000503 海虹控股
14 000538 云南白药
15 000540 中天金融
16 000559 万向钱潮
17 000568 泸州老窖
18 000623 吉林敖东
19 000625 长安汽车
20 000627 天茂集团
21 000630 铜陵有色
22 000651 格力电器
23 000671 阳光城
24 000686 东北证券
25 000709 河钢股份
26 000723 美锦能源
27 000725 京东方
28 000728 国元证券
29 000738 航发控制
.. ... ...
270 600958 东方证券
271 601198 东兴证券
272 601021 春秋航空
273 600959 江苏有线
274 601985 中国核电
275 603160 汇顶科技
276 603799 华友钴业
277 601212 白银有色
278 002797 第一创业
279 601966 玲珑轮胎
280 601611 中国核建
281 600977 中国电影
282 601878 浙商证券
283 603858 步长制药
284 002736 国信证券
285 601163 三角轮胎
286 002839 张家港行
287 601229 上海银行
288 600919 江苏银行
289 601997 贵阳银行
290 600926 杭州银行
291 601881 中国银河
292 002831 裕同科技
293 603833 欧派家居
294 002841 视源股份
295 601375 中原证券
296 601228 广州港
297 000166 申万宏源
298 601155 新城控股
299 001979 招商蛇口