-
Notifications
You must be signed in to change notification settings - Fork 0
/
Measurement_study.py
233 lines (168 loc) · 7.44 KB
/
Measurement_study.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
import math
import numpy
import scipy.stats
import cPickle
MEAN_DICT={}
SD_DICT={}
SKEW_DICT={}
KURT_DICT={}
JB_DICT={}
SHARPE_DICT={}
class Fund(object):
def __init__(self, blmg_sym, mon_rtn):
self.blmg_sym=blmg_sym
self.mon_rtn=mon_rtn
def Mean(self):
global MEAN_DICT
if MEAN_DICT.has_key(self.blmg_sym):
return MEAN_DICT[self.blmg_sym]
MEAN_DICT[self.blmg_sym] = numpy.mean(self.mon_rtn.values())
return MEAN_DICT[self.blmg_sym]
def SD(self):
global SD_DICT
if SD_DICT.has_key(self.blmg_sym):
return SD_DICT[self.blmg_sym]
SD_DICT[self.blmg_sym] = numpy.std(self.mon_rtn.values())
return SD_DICT[self.blmg_sym]
def Kurt(self):
global KURT_DICT
if KURT_DICT.has_key(self.blmg_sym):
return KURT_DICT[self.blmg_sym]
KURT_DICT[self.blmg_sym] = scipy.stats.kurtosis(self.mon_rtn.values())
return KURT_DICT[self.blmg_sym]
def Skew(self):
global SKEW_DICT
if SKEW_DICT.has_key(self.blmg_sym):
return SKEW_DICT[self.blmg_sym]
#calculate the skewness
SKEW_DICT[self.blmg_sym] = scipy.stats.skew(self.mon_rtn.values())
return SKEW_DICT[self.blmg_sym]
def JB_p(self):
global JB_DICT
if JB_DICT.has_key(self.blmg_sym):
return JB_DICT[self.blmg_sym]
JB_DICT[self.blmg_sym] = scipy.stats.jarque_bera(self.mon_rtn.values())[1]
return JB_DICT[self.blmg_sym]
def Sharpe(self):
global SHARPE_DICT
if SHARPE_DICT.has_key(self.blmg_sym):
return SHARPE_DICT.has_key(self.blmg_sym)
#calculate the sharpe ratio with the risk-free rate 0.3
SHARPE_DICT[self.blmg_sym] = (self.Mean()-0.3)/self.SD()
return SHARPE_DICT[self.blmg_sym]
def Measurement_Return(self):
#calculate the accumulative return by the monthly return data
def f(x,y):
return (100+x)*(100+y)/float(100)-100
Total_return=reduce(f,self.mon_rtn.values())
return Total_return
'''
Format for new measurements
def Measurement_newMeasurementName(x):
Use x.mon_rtn.values() to calculate the new measurement
return the result
'''
def stockFundGenerator():
'''stock'''
with open("stock_fund_dict.txt","rb") as f:
Dic=cPickle.load(f)
for fund in Dic:
yield Fund(fund['blmg_sym'],fund['mon_rtn'])
def bondFundGenerator():
'''bond'''
with open("bond_fund_dict.txt","rb") as f:
Dic=cPickle.load(f)
for fund in Dic:
yield Fund(fund['blmg_sym'],fund['mon_rtn'])
def realEstateFundGenerator():
'''real_estate'''
with open("real_estate_fund_dict.txt","rb") as f:
Dic=cPickle.load(f)
for fund in Dic:
yield Fund(fund['blmg_sym'],fund['mon_rtn'])
def generateReturnDistribution(fund_gen):
fund_type=fund_gen.__doc__
print 'Generating report for '+fund_type+' funds'
with open('Stat_'+fund_type+'.csv','w') as f:
global MEAN_DICT
global SD_DICT
global SKEW_DICT
global KURT_DICT
#Clear the dictionary to receive the data of funds from the specific sector
MEAN_DICT={}
SD_DICT={}
SKEW_DICT={}
KURT_DICT={}
f.write('Time-Series Analysis by Fund Type,Mean,Median,Standard Deviation,Minimum,Maximum\n')
#add the mean value, standard deviation, skewness and kurtosis data into the corresponding dictionary
for fund in fund_gen():
fund.Mean()
fund.SD()
fund.Skew()
fund.Kurt()
#Calculate the mean value, median, standard deviation, minimum and maximum
fund_mean=MEAN_DICT.values()
f.write('Mean value (%),{},{},{},{},{}\n'.format
(numpy.mean(fund_mean), numpy.median(fund_mean), numpy.std(fund_mean), min(fund_mean), max(fund_mean)))
fund_SD=SD_DICT.values()
f.write('Standard deviation (%),{},{},{},{},{}\n'.format
(numpy.mean(fund_SD), numpy.median(fund_SD), numpy.std(fund_SD), min(fund_SD), max(fund_SD)))
fund_Skew=SKEW_DICT.values()
f.write('Skewness,{},{},{},{},{}\n'.format
(numpy.mean(fund_Skew), numpy.median(fund_Skew), numpy.std(fund_Skew), min(fund_Skew), max(fund_Skew)))
fund_Kurt=KURT_DICT.values()
f.write('Excess kurtosis,{},{},{},{},{}\n'.format
(numpy.mean(fund_Kurt), numpy.median(fund_Kurt), numpy.std(fund_Kurt), min(fund_Kurt), max(fund_Kurt)))
def generateRanking(sorted_list):
list_rank=[]
equal=[]
for rank,fund in enumerate(sorted_list):
if sorted_list[rank-1][1] != fund[1]:
if equal:
equal.append(rank)
average=sum(equal)/float(len(equal))
for i in equal:
list_rank[i-1][1]=average
equal=[]
else:
equal.append(rank)
list_rank.append([fund[0],rank+1])
if equal:
equal.append(rank+1)
average=sum(equal)/float(len(equal))
for i in equal:
list_rank[i-1][1]=average
return list_rank
#Generate the table which shows the rank correlations of the Sharpe ratio in relation to the other performance measures.
def generateRankCorrelationReport(fund_gen):
fund_type=fund_gen.__doc__
print 'Generating correlation report for '+fund_type+' funds'
with open('Rank_corr_'+fund_type+'.csv','w') as f:
f.write('Performance Measure,{}\n'.format(fund_type))
global SHARPE_DICT
SHARPE_DICT={}
measurement_dict={}
#add the data into the corresponding dictionary
for measurement in filter(lambda x:x.startswith('Measurement_'),dir(Fund)):
for fund in fund_gen():
measurement_dict[fund.blmg_sym]=getattr(fund,measurement)()
fund.Sharpe()
#Get ranks
sorted_measure=sorted(measurement_dict.iteritems(), key=lambda d:d[1], reverse = True)
sorted_sharpe=sorted(SHARPE_DICT.iteritems(), key=lambda d:d[1], reverse = True)
measure_rank=generateRanking(sorted_measure)
sharpe_rank=generateRanking(sorted_sharpe)
#Calculate the rank correlation
N=len(sorted_measure)
sigma_d=0
measure_rank_sorted=sorted(measure_rank, key=lambda d:d[0])
sharpe_rank_sorted=sorted(sharpe_rank, key=lambda d:d[0])
for i in range(N):
sigma_d+=(measure_rank_sorted[i][1]-sharpe_rank_sorted[i][1])**2
Rank_corr = 1-6*sigma_d/float(N**3-N)
f.write('{},{}\n'.format(measurement[12:], Rank_corr))
#print Rank_corr
if __name__ == "__main__":
for fund_gen in [stockFundGenerator, bondFundGenerator, realEstateFundGenerator]:
generateRankCorrelationReport(fund_gen)
#generateReturnDistribution(fund_gen)