1
1
import matplotlib .pyplot as plt
2
2
import pandas as pd
3
3
import numpy as np
4
- from sklearn .linear_model import LinearRegression
5
4
6
5
7
6
def sharpe_ratio (ret : pd .Series | pd .DataFrame , rf : float = 0.03 , freq : float = 1.0 ) -> float :
@@ -47,10 +46,20 @@ def information_ratio(ret: pd.Series | pd.DataFrame, benchmark: pd.Series | pd.D
47
46
48
47
def calculate_mdd (data : pd .Series ) -> pd .Series :
49
48
"""
50
- :param data: pd.Series
51
- :return: pd.Series
49
+ :param data: 累计收益率序列
50
+ :return: 从开始到目前的回撤
52
51
"""
53
- return data - data .cummax ()
52
+ return (data - data .cummax ()) / data .cummax ()
53
+
54
+
55
+ def annualized_return (data : pd .Series , freq : float = 1 ) -> float :
56
+ # (1 + total_ret) ** (1/years) - 1
57
+ return (1 + data .values [- 1 ]) ** (252 / (len (data ) * freq )) - 1
58
+
59
+
60
+ def annualized_volatility (data : pd .Series , freq : float = 1 ) -> float :
61
+ # ret.std()*(x **0.5), x为一年有多少tick
62
+ return data .std () * ((252 / len (data ) / freq ) ** 0.5 )
54
63
55
64
56
65
def plot (data , label , title : str = None , xlabel : str = None , ylabel : str = None , figsize = None ,
@@ -136,7 +145,7 @@ def report_all(user_account, benchmark, show_raw_value: bool = False, excess_ret
136
145
ben_ret = []
137
146
days = 0
138
147
for i in range (len (acc_val )):
139
- acc_ret .append (acc_val [i ] / init_val_acc - 1 )
148
+ acc_ret .append (acc_val [i ] / init_val_acc - 1 ) # 当前净值相对于初始值的收益率
140
149
ben_ret .append (ben_val [i ] / init_val_ben - 1 )
141
150
excess_ret = []
142
151
@@ -146,37 +155,42 @@ def report_all(user_account, benchmark, show_raw_value: bool = False, excess_ret
146
155
days += 1
147
156
days /= len (acc_ret )
148
157
149
- acc_mdd = calculate_mdd (pd .Series (acc_ret ))
150
- ben_mdd = calculate_mdd (pd .Series (ben_ret ))
158
+ acc_mdd = calculate_mdd (pd .Series (acc_ret ) + 1 )
159
+ ben_mdd = calculate_mdd (pd .Series (ben_ret ) + 1 )
151
160
152
161
ret = pd .Series (acc_ret ) # 累计收益率
153
162
ben = pd .Series (ben_ret ) # benchmark的累计收益率
154
- x = ben .values .reshape (- 1 , 1 )
155
- model = LinearRegression ().fit (x , ret )
163
+
164
+ ann_return = annualized_return (ret , freq = freq )
165
+ ann_std = annualized_volatility (ret , freq = freq )
166
+ ben_ann_return = annualized_return (ben , freq = freq )
167
+ ben_ann_std = annualized_volatility (ben , freq = freq )
168
+
169
+ beta = ret .cov (ben ) / ben .var ()
170
+ alpha = ret .mean () - beta * ben .mean ()
171
+ epsilon = pd .Series (ret - beta * ben - alpha ).std ()
156
172
157
173
sharpe = sharpe_ratio (acc_ret , rf = rf , freq = freq * 365 )
158
174
sortino = sortino_ratio (acc_ret , ben_ret )
159
175
inf_ratio = information_ratio (acc_ret , ben_ret )
160
176
161
- print ('Annualized Return:' , (1 + acc_ret [- 1 ]) ** (252 / (len (ret ) * freq )) - 1 ) # (1 + total_ret) ** (1/years) - 1
162
- print ('Annualized Return:' , (1 + acc_ret [- 1 ]) ** (252 / (len (ret ) * freq )) - 1 ) # (1 + total_ret) ** (1/years) - 1
177
+ print ('Annualized Return:' , ann_return ) # (1 + total_ret) ** (1/years) - 1
163
178
# print("years:", 252 / len(ret))
164
- print ('Annualized Volatility:' , ret .std () * ((252 / len (ret ) / freq ) ** 0.5 )) # ret.std()*(x **0.5), x为一年有多少tick
165
- print ('Annualized Return(Benchmark):' , (1 + ben_ret [- 1 ]) ** (252 / (len (ret ) * freq )) - 1 )
166
- print ('Annualized Return(Benchmark):' , (1 + ben_ret [- 1 ]) ** (252 / (len (ret ) * freq )) - 1 )
167
- print ('Annualized Volatility(Benchmark):' , ben .std () * ((252 / len (ret ) / freq ) ** 0.5 ), '\n ' )
179
+ print ('Annualized Volatility:' , ann_std ) # ret.std()*(x **0.5), x为一年有多少tick
180
+ print ('Annualized Return(Benchmark):' , ben_ann_return )
181
+ print ('Annualized Volatility(Benchmark):' , ben_ann_std , '\n ' )
168
182
print ('Cumulative Rate of Return:' , acc_ret [- 1 ])
169
183
print ('Cumulative Rate of Return(Benchmark):' , ben_ret [- 1 ])
170
184
print ('Cumulative Excess Rate of Return:' , excess_ret [- 1 ], '\n ' )
171
185
print ('Max Drawdown:' , acc_mdd .min ())
172
186
print ('Max Drawdown(Benchmark):' , ben_mdd .min ())
173
- print ('Max Drawdown(Excess Return):' , calculate_mdd (pd .Series (excess_ret )).min (), '\n ' )
187
+ print ('Max Drawdown(Excess Return):' , calculate_mdd (pd .Series (excess_ret ) + 1 ).min (), '\n ' )
174
188
print ('Sharpe Ratio:' , sharpe )
175
189
print ('Sortino Ratio:' , sortino )
176
190
print ('Information Ratio:' , inf_ratio , '\n ' )
177
- print ('Beta:' , model . coef_ [ 0 ] )
178
- print ("Alpha:" , model . intercept_ )
179
- print ("Epsilon:" , ( ret - model . predict ( x )). std () )
191
+ print ('Beta:' , beta )
192
+ print ("Alpha:" , alpha )
193
+ print ("Epsilon:" , epsilon )
180
194
print ('Profitable Days(%):' , days )
181
195
182
196
if show_raw_value :
0 commit comments