In [1]:
import pandas as pd
import numpy as np


C:\Users\sspug\Anaconda2\lib\site-packages\matplotlib\__init__.py:1034: UserWarning: Illegal line #45
	"backend.qt4 PyQt4
"
	in file "C:\Users\sspug\Anaconda2\lib\site-packages\matplotlib\mpl-data\matplotlibrc"
  warnings.warn('Illegal %s' % error_details)

In [12]:
# Sharp Ratio(夏普率)
year_list = []
month_list = []
rtn_list = []
# 随机生成收益率,以半年为周期
for year in range(2006,2017):
    for month in [6,12]:
        year_list.append(year)
        month_list.append(month)
        rtn = round((-1)**(month/6)*(month/6/10), 3) + (np.random.random()-0.5)*0.1
        rtn_list.append(rtn)

# 生成半年为周期收益率的二维表df
df = pd.DataFrame()
df['year'] = year_list
df['month'] = month_list
df['rtn'] = rtn_list
# 收益率要乘以2,波动率要乘以根号2
sr = round(df['rtn'].mean()/df['rtn'].std() * np.sqrt(2), 3)
print df
print sr

# 直接以年为周期计算夏普率
df_year = df.groupby(['year']).sum()
del df_year['month']
print df_year
sr = round(df['rtn'].mean()/df['rtn'].std(), 3)
print sr


    year  month       rtn
0   2006      6  0.007221
1   2006     12 -0.008833
2   2007      6 -0.016339
3   2007     12  0.020307
4   2008      6  0.012800
5   2008     12  0.046814
6   2009      6 -0.049496
7   2009     12  0.020304
8   2010      6  0.016820
9   2010     12  0.042686
10  2011      6 -0.041726
11  2011     12  0.044138
12  2012      6  0.025679
13  2012     12 -0.015108
14  2013      6  0.002754
15  2013     12 -0.038787
16  2014      6  0.023664
17  2014     12  0.033232
18  2015      6 -0.043792
19  2015     12 -0.009686
20  2016      6  0.014787
21  2016     12  0.002536
0.199
           rtn
year          
2006 -0.001612
2007  0.003969
2008  0.059613
2009 -0.029192
2010  0.059506
2011  0.002412
2012  0.010571
2013 -0.036034
2014  0.056896
2015 -0.053478
2016  0.017323
0.141

In [23]:
spy = pd.Series([1, 5, 3, 6, 7, 3, 2, 5, 6, 4, 9], index=[5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55])
def drawdown(pnl):
    """
    pnl is a pandas Series
    calculate max drawdown and duration
    Returns:
        drawdown : vector of drawdwon values
        duration : vector of drawdown duration
    """
    cumret = pnl
    highwatermark = [0]
 
    idx = pnl.index
    drawdown = pd.Series(index = idx)
    drawdowndur = pd.Series(index = idx)
    drawdown.values[0] = 0
    drawdowndur.values[0] = 0
    
    for t in range(1, len(idx)) :
        highwatermark.append(max(highwatermark[t-1], cumret.values[t]))
        cur = cumret.index[t]
        drawdown[cur] = (highwatermark[t] - cumret.values[t])
        drawdowndur[cur] = (0 if drawdown[cur] == 0 else drawdowndur[cumret.index[t - 1]] + 1)

    print highwatermark
    return drawdown, drawdowndur

drawdown, drawdowndur = drawdown(spy)
print drawdown.values
print drawdowndur.values
print "The maximum drawdown is : %.2f!" % (drawdown.values.max())
print "The maximum drawdown duration is : %d!" % (drawdowndur.values.max())


[0, 5, 5, 6, 7, 7, 7, 7, 7, 7, 9]
[ 0.  0.  2.  0.  0.  4.  5.  2.  1.  3.  0.]
[ 0.  0.  1.  0.  0.  1.  2.  3.  4.  5.  0.]
The maximum drawdown is : 5.00!
The maximum drawdown duration is : 5!

In [3]:
spy = pd.Series([1, 5, 3, 6, 7, 3, 2, 5, 6, 4, 9], index=[5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55])

def dd(s):
    ''' 
    simple drawdown function 
    '''
    
    highwatermark = np.zeros(len(s))
    drawdown = np.zeros(len(s))
    drawdowndur = np.zeros(len(s))
 
    for t in range(1, len(s)):
        highwatermark[t] = max(highwatermark[t-1], s[t])
        drawdown[t] = (highwatermark[t] - s[t])
        drawdowndur[t]= (0 if drawdown[t] == 0 else drawdowndur[t-1] + 1)
        
    return drawdown, drawdowndur

drawdown, drawdowndur = dd(spy.values)
print drawdown
print '---------------'
print drawdowndur


[ 0.  0.  2.  0.  0.  4.  5.  2.  1.  3.  0.]
---------------
[ 0.  0.  1.  0.  0.  1.  2.  3.  4.  5.  0.]