首页 > 技术文章 > Python计算量化指标

LazyTiming 2021-06-24 17:07 原文

def MaxDrawdown(return_list):
    '''最大回撤率'''
    i = np.argmax(
        (np.maximum.accumulate(return_list) - return_list) / np.maximum.accumulate(return_list))  # 结束位置
    if i == 0:
        return 0
    j = np.argmax(return_list[:i])  # 开始位置
    return (return_list[j] - return_list[i]) / (return_list[j])

import pandas as pd
import numpy as np
import os
import talib as ta
from datetime import datetime,timedelta
import matplotlib.pyplot as plt
from pylab import mpl
mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False

class CalculateEvaluation():
    def __strategy_calculate_evaluation(self,strategy_title,df_strategy, strategy_net_value_name, index_net_value_name=None):
        df1 = pd.DataFrame(index= pd.to_datetime(df_strategy.index))

        df1['策略净值'] = df_strategy[strategy_net_value_name]
        df1['指数净值'] = df_strategy[index_net_value_name] if index_net_value_name != None else 1

        df1['策略收益率'] = df1['策略净值'].diff(1)
        df1['指数收益率'] = df1['指数净值'].diff(1)


        # 常规指标计算
        total_ret = df1[['策略净值', '指数净值']].iloc[-1] - 1
        annual_ret = pow(1 + total_ret, 250 / len(df1)) - 1
        dd = (df1[['策略净值', '指数净值']].cummax() - df1[['策略净值', '指数净值']])/df1[['策略净值', '指数净值']].cummax()
        d = dd.max()
        beta = df1[['策略收益率', '指数收益率']].cov().iat[0, 1] / df1['指数收益率'].var()
        alpha = (annual_ret['策略净值'] - annual_ret['指数净值'] * beta)
        exReturn = df1['策略收益率'] - 0.05 / 250
        sharper_atio = np.sqrt(len(exReturn)) * exReturn.mean() / exReturn.std()
        TA1 = round(total_ret['策略净值'] * 100, 2)
        TA2 = round(total_ret['指数净值'] * 100, 2)
        AR1 = round(annual_ret['策略净值'] * 100, 2)
        AR2 = round(annual_ret['指数净值'] * 100, 2)
        MD1 = round(d['策略净值'] * 100, 2)
        MD2 = round(d['指数净值'] * 100, 2)
        S = round(sharper_atio, 2)

        fig = plt.figure()
        ax = fig.add_subplot(2,1,1)
        df1[['策略净值', '指数净值']].plot(ax=ax, figsize=(15, 7))
        plt.title(strategy_title, size=15)
        bbox = dict(boxstyle="round", fc="w", ec="0.5", alpha=0.9)
        plt.text(df1.index[int(len(df1) / 5)], df1['策略净值'].max() / 1.5, f'累计收益率:\
    策略{TA1}%,指数{TA2}%;\n年化收益率:策略{AR1}%,指数{AR2}%;\n最大回撤:  策略{MD1}%,指数{MD2}%;\n\
    策略alpha: {round(alpha, 2)},策略beta:{round(beta, 2)}; \n夏普比率:  {S}', size=13, bbox=bbox)
        plt.xlabel('')
        ax = plt.gca()
        ax.spines['right'].set_color('none')
        ax.spines['top'].set_color('none')


        ax = fig.add_subplot(2, 1, 2)
        month_df = df1["策略收益率"].resample("m").sum()
        month_df.plot(kind='bar',ax=ax)
        plt.xticks(rotation=70)
        plt.show()

    def multi_strategy_calculate_evaluation(self, list_strategy_title, df_strategy, index_net_value_name=None):
        for strategy_title in list_strategy_title:
            if strategy_title not in  df_strategy.columns:
                print("策略-->",strategy_title,"-->净值数据不存在")
                continue
            self.__strategy_calculate_evaluation(strategy_title,df_strategy,strategy_title,index_net_value_name)



if __name__ == '__main__':


    file_name = os.path.dirname(__file__)
    path = os.path.join(file_name,"分类策略净值.xlsx")
    df = pd.read_excel(path,index_col=0)
    select_strategy = df.columns
    ce = CalculateEvaluation()
    #ce.multi_strategy_calculate_evaluation(["hs300指数增强净值","中证500指数增强净值"],df,"hs300指数")
    ce.multi_strategy_calculate_evaluation(select_strategy, df, "hs300指数")



推荐阅读