今天实现一下performance计算,对于回测而言,我们最关心的几个指标:最大回撤,波动率,年化收益等。
先看效果:
代码下工程如下位置:(已经更新至星球)
import pandas as pd from datetime import datetime def year_frac(start, end): """ Similar to excel's yearfrac function. Returns a year fraction between two dates (i.e. 1.53 years). Approximation using the average number of seconds in a year. Args: * start (datetime): start date * end (datetime): end date """ if start > end: raise ValueError("start cannot be larger than end") # obviously not perfect but good enough return (end - start).total_seconds() / (31557600) def calc_stats(df_price: pd.DataFrame): if type(df_price) is pd.Series: df_price = pd.DataFrame(df_price) df_price.dropna(inplace=True) df_rates = df_price.pct_change() df_equity = (1 + df_rates).cumprod() df_equity.dropna(inplace=True) df_rates.dropna(inplace=True) # import empyrical # print('年化收益:', round(empyrical.annual_return(df_rates), 3)) count = len(df_price) start = df_price.index[0] end = df_price.index[-1] accu_return = round(df_equity.iloc[-1] - 1, 3) accu_return.name = '累计收益' annu_ret = round((accu_return + 1) ** (252 / count) - 1, 3) annu_ret.name = '年化收益' annu_ret2 = round((accu_return+1) ** (1 / year_frac(start, end)) - 1,3) annu_ret2.name = 'CAGR' # 标准差 std = round(df_rates.std() * (252 ** 0.5), 3) std.name = '年化波动率' # 夏普比 sharpe = round(annu_ret / std, 3) sharpe.name = '夏普比率' # 最大回撤 mdd = round((df_equity / df_equity.expanding(min_periods=1).max()).min() - 1, 3) mdd.name = '最大回撤' ret_2_mdd = round(annu_ret / abs(mdd), 3) ret_2_mdd.name = '卡玛比率' df_ratios = pd.concat([annu_ret, annu_ret2, mdd, ret_2_mdd, sharpe, accu_return, std], axis=1) df_ratios['开始时间'] = start.strftime('%Y-%m-%d') df_ratios['结束时间'] = end.strftime('%Y-%m-%d') return df_ratios.T
我的计算方式,与zipline类似,
bt的计算与我的略有差别:
我看了下它的代码:bt的逻辑是按照自然天数/365,我们是按照回测天数/252。从合理性而言,bt的更符合直觉。
大家可以看下对比情况:
另外可以给loguru添加全局的重定向:
def my_logger_notify(data): g.notify({'msg_type': 'LOGGER', 'message': data}) from loguru import logger logger.add(my_logger_notify)
如此,日志可以实时显示在gui的文本框里。
发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/103854
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!