【答读者问31】在分钟级别的策略运行后如何获取每日的收益率?
作者:yunjinqi   类别:    日期:2021-12-23 18:12:28    阅读:1121 次   消耗积分:0 分    

backtrader自带了很多的analyzer,可以满足很多的策略分析的需要。在以前的教程中,详细介绍了如何使用analyzer以及如何创建新的analyzer以满足各种不同的需要。

14、backtrader的一些基本概念-如何使用analyzer和创建新的analyzer(1)

15、backtrader的一些基本概念-如何使用analyzer和创建新的analyzer(2)

16、backtrader的一些基本概念-如何使用analyzer和创建新的analyzer(3)—及backtrader交流群

17、backtrader的一些基本概念—如何使用analyzer及创建新的analyzer(4)—策略绩效评价模块pyfolio的使用

注:backtrader的QQ群很早就开通了,只有一少部分能答对题目,成功加入。我的CSDN博客主页有二维码,可以加我微信,拉您进backtrader量化交流微信群。

今天有读者咨询,如果策略运行在颗粒度比较低的分钟级别上,如果取得策略的以天为单位的收益率序列?

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)from collections import OrderedDictfrom backtrader import Analyzerimport numpy as np 
import pandas as pd 

class TotalValue(Analyzer):
    '''This analyzer will get total value from every next.

    Params:
    Methods:

      - get_analysis

        Returns a dictionary with returns as values and the datetime points for
        each return as keys
    '''

    params = ( )

    def start(self):
        super(TotalValue, self).start()
        self.rets = OrderedDict()

    def next(self):
        # Calculate the return
        super(TotalValue, self).next()
        self.rets[self.datas[0].datetime.datetime()] = self.strategy.broker.getvalue()
        
    def get_analysis(self):
        return self.rets    
class DayReturn(Analyzer):
    '''用于获取每个交易日的收益率,使用的是自然日的时间来划分交易日
    '''

    params = ( )

    def start(self):
        super(DayReturn, self).start()
        self.rets = OrderedDict()
        self.day_ret_df = None

    def next(self):
        # Calculate the return
        super(DayReturn, self).next()
        self.rets[self.datas[0].datetime.datetime()] = self.strategy.broker.getvalue()
        
        
    def stop(self):
        # 根据获取的每个bar的value,基于pandas计算每个交易日的收益率
        df = pd.DataFrame([self.rets]).T 
        df.columns =["value"]
        df['datetime']=df.index        # print(self.rets)
        
        df['date']=[i.date() for i in df['datetime']]
        new_df = df.drop_duplicates("date",keep="last")
        # 保留原来数据的第一行和后面每个自然日的最后一个数据
        df = df.iloc[:1,::].append(new_df)
        df['ret']=np.log(df['value'])- np.log(df['value'].shift(1))
        df.index = df['date']
        self.day_ret_df = df[['value',"ret"]].dropna()
        
    def get_analysis(self):
        return self.day_ret_df

使用方法:

cerebro.addanalyzer(bt.analyzers.DayReturn, _name='my_DayReturn')
# 运行回测
results = cerebro.run()
day_ret_df = results[0].analyzers.my_DayReturn.get_analysis()
print(day_ret_df.head(20))
# 返回数据如下:
                   value       ret
date                              
2013-11-08  50000.000000  0.000000
2013-11-11  50000.000000  0.000000
2013-11-12  50000.000000  0.000000
2013-11-13  50000.000000  0.000000
2013-11-14  50000.000000  0.000000
2013-11-15  50000.000000  0.000000
2013-11-18  50000.000000  0.000000
2013-11-19  50000.000000  0.000000

智慧、心灵、财富,总要有一个在路上,愿我们能在人生的道路上,不断成长、不断成熟~~~

感兴趣可以关注我的专栏:

my_quant_study_note:分享一些关于量化投资、量化交易相关的思考

backtrader量化投资回测与交易:本专栏免费,分享backtrader相关的内容。

量化投资神器-backtrader源码解析-从入门到精通:本专栏目前收费299元,预计更新100篇策略(更新中)+36篇backtrader讲解(已完成)+backtrader源码分析。


版权所有,转载本站文章请注明出处:云子量化, http://www.woniunote.com/article/59
上一篇:【答读者问30】关于backtrader计算的指标与其他平台不一致的若干问题
下一篇:【答读者问32】如何基于期货基本面数据(库存、基差、利润等)进行回测