Package QSTK :: Package qstkstrat :: Module strategies
[hide private]
[frames] | no frames]

Source Code for Module QSTK.qstkstrat.strategies

  1  ''' 
  2  Created on Sep 27, 2011 
  3   
  4  @author: John Cornwell 
  5  @contact: JohnWCornwellV@gmail.com 
  6  @summary: Various simple trading strategies to generate allocations. 
  7  ''' 
  8   
  9  ''' Python imports ''' 
 10  import datetime as dt 
 11  from math import sqrt 
 12   
 13   
 14  ''' 3rd party imports ''' 
 15  import numpy as np 
 16  import pandas as pand 
 17   
 18  ''' QSTK imports ''' 
 19  import qstkutil.tsutil as tsu 
 20   
 21   
22 -def stratGiven( dtStart, dtEnd, dFuncArgs ):
23 """ 24 @summary Simplest strategy, weights are provided through args. 25 @param dtStart: Start date for portfolio 26 @param dtEnd: End date for portfolio 27 @param dFuncArgs: Dict of function args passed to the function 28 @return DataFrame corresponding to the portfolio allocations 29 """ 30 if not dFuncArgs.has_key('dmPrice'): 31 print 'Error: Strategy requires dmPrice information' 32 return 33 34 if not dFuncArgs.has_key('lfWeights'): 35 print 'Error: Strategy requires weight information' 36 return 37 38 dmPrice = dFuncArgs['dmPrice'] 39 lfWeights = dFuncArgs['lfWeights'] 40 41 ''' Generate two allocations, one for the start day, one for the end ''' 42 naAlloc = np.array( lfWeights ).reshape(1,-1) 43 44 dfAlloc = pand.DataFrame( index=[dtStart], data=naAlloc, columns=(dmPrice.columns) ) 45 dfAlloc = dfAlloc.append( pand.DataMatrix(index=[dtEnd], data=naAlloc, columns=dmPrice.columns)) 46 dfAlloc['_CASH'] = 0.0 47 48 return dfAlloc
49
50 -def strat1OverN( dtStart, dtEnd, dFuncArgs ):
51 """ 52 @summary Evenly distributed strategy. 53 @param dtStart: Start date for portfolio 54 @param dtEnd: End date for portfolio 55 @param dFuncArgs: Dict of function args passed to the function 56 @return DataFrame corresponding to the portfolio allocations 57 """ 58 if not dFuncArgs.has_key('dmPrice'): 59 print 'Error: Strategy requires dmPrice information' 60 return 61 62 dmPrice = dFuncArgs['dmPrice'] 63 64 lNumSym = len(dmPrice.columns) 65 66 ''' Generate two allocations, one for the start day, one for the end ''' 67 naAlloc = (np.array( np.ones(lNumSym) ) * (1.0 / lNumSym)).reshape(1,-1) 68 dfAlloc = pand.DataMatrix( index=[dtStart], data=naAlloc, columns=(dmPrice.columns) ) 69 dfAlloc = dfAlloc.append( pand.DataMatrix(index=[dtEnd], data=naAlloc, columns=dmPrice.columns)) 70 dfAlloc['_CASH'] = 0.0 71 72 return dfAlloc
73 74
75 -def stratMark( dtStart, dtEnd, dFuncArgs ):
76 """ 77 @summary Markovitz strategy, generates a curve and then chooses a point on it. 78 @param dtStart: Start date for portfolio 79 @param dtEnd: End date for portfolio 80 @param dFuncArgs: Dict of function args passed to the function 81 @return DataFrame corresponding to the portfolio allocations 82 """ 83 if not dFuncArgs.has_key('dmPrice'): 84 print 'Error:', stratMark.__name__, 'requires dmPrice information' 85 return 86 87 if not dFuncArgs.has_key('sPeriod'): 88 print 'Error:', stratMark.__name__, 'requires rebalancing period' 89 return 90 91 if not dFuncArgs.has_key('lLookback'): 92 print 'Error:', stratMark.__name__, 'requires lookback' 93 return 94 95 if not dFuncArgs.has_key('sMarkPoint'): 96 print 'Error:', stratMark.__name__, 'requires markowitz point to choose' 97 return 98 99 ''' Optional variables ''' 100 if not dFuncArgs.has_key('bAddAlpha'): 101 bAddAlpha = False 102 else: 103 bAddAlpha = dFuncArgs['bAddAlpha'] 104 105 dmPrice = dFuncArgs['dmPrice'] 106 sPeriod = dFuncArgs['sPeriod'] 107 lLookback = dFuncArgs['lLookback'] 108 sMarkPoint = dFuncArgs['sMarkPoint'] 109 110 ''' Select rebalancing dates ''' 111 drNewRange = pand.DateRange(dtStart, dtEnd, timeRule=sPeriod) + pand.DateOffset(hours=16) 112 113 dfAlloc = pand.DataMatrix() 114 ''' Go through each rebalance date and calculate an efficient frontier for each ''' 115 for i, dtDate in enumerate(drNewRange): 116 dtStart = dtDate - pand.DateOffset(days=lLookback) 117 118 if( dtStart < dmPrice.index[0] ): 119 print 'Error, not enough data to rebalance' 120 continue 121 122 naRets = dmPrice.ix[ dtStart:dtDate ].values.copy() 123 tsu.returnize1(naRets) 124 tsu.fillforward(naRets) 125 tsu.fillbackward(naRets) 126 127 ''' Add alpha to returns ''' 128 if bAddAlpha: 129 if i < len(drNewRange) - 1: 130 naFutureRets = dmPrice.ix[ dtDate:drNewRange[i+1] ].values.copy() 131 tsu.returnize1(naFutureRets) 132 tsu.fillforward(naFutureRets) 133 tsu.fillbackward(naFutureRets) 134 135 naAvg = np.mean( naFutureRets, axis=0 ) 136 137 ''' make a mix of past/future rets ''' 138 for i in range( naRets.shape[0] ): 139 naRets[i,:] = (naRets[i,:] + (naAvg*0.05)) / 1.05 140 141 142 ''' Generate the efficient frontier ''' 143 (lfReturn, lfStd, lnaPortfolios) = getFrontier( naRets, fUpper=0.2, fLower=0.01 ) 144 145 lInd = 0 146 147 ''' 148 plt.clf() 149 plt.plot( lfStd, lfReturn)''' 150 151 if( sMarkPoint == 'Sharpe'): 152 ''' Find portfolio with max sharpe ''' 153 fMax = -1E300 154 for i in range( len(lfReturn) ): 155 fShrp = (lfReturn[i]-1) / (lfStd[i]) 156 if fShrp > fMax: 157 fMax = fShrp 158 lInd = i 159 ''' 160 plt.plot( [lfStd[lInd]], [lfReturn[lInd]], 'ro') 161 plt.draw() 162 time.sleep(2) 163 plt.show()''' 164 165 elif( sMarkPoint == 'MinVar'): 166 ''' use portfolio with minimum variance ''' 167 fMin = 1E300 168 for i in range( len(lfReturn) ): 169 if lfStd[i] < fMin: 170 fMin = lfStd[i] 171 lInd = i 172 173 elif( sMarkPoint == 'MaxRet'): 174 ''' use Portfolio with max returns (not really markovitz) ''' 175 lInd = len(lfReturn)-1 176 177 elif( sMarkPoint == 'MinRet'): 178 ''' use Portfolio with min returns (not really markovitz) ''' 179 lInd = 0 180 181 else: 182 print 'Warning: invalid sMarkPoint''' 183 return 184 185 186 187 ''' Generate allocation based on selected portfolio ''' 188 naAlloc = (np.array( lnaPortfolios[lInd] ).reshape(1,-1) ) 189 dmNew = pand.DataMatrix( index=[dtDate], data=naAlloc, columns=(dmPrice.columns) ) 190 dfAlloc = dfAlloc.append( dmNew ) 191 192 dfAlloc['_CASH'] = 0.0 193 return dfAlloc
194
195 -def stratMarkSharpe( dtStart, dtEnd, dFuncArgs ):
196 """ 197 @summary Calls stratMark with sharpe ratio point. 198 @param dtStart: Start date for portfolio 199 @param dtEnd: End date for portfolio 200 @param dFuncArgs: Dict of function args passed to the function 201 @return DataFrame corresponding to the portfolio allocations 202 """ 203 dFuncArgs['sMarkPoint'] = 'Sharpe' 204 return stratMark( dtStart, dtEnd, dFuncArgs )
205
206 -def stratMarkLowVar( dtStart, dtEnd, dFuncArgs ):
207 """ 208 @summary Calls stratMark and uses lowest variance ratio point. 209 @param dtStart: Start date for portfolio 210 @param dtEnd: End date for portfolio 211 @param dFuncArgs: Dict of function args passed to the function 212 @return DataFrame corresponding to the portfolio allocations 213 """ 214 dFuncArgs['sMarkPoint'] = 'MinVar' 215 return stratMark( dtStart, dtEnd, dFuncArgs )
216
217 -def stratMarkMaxRet( dtStart, dtEnd, dFuncArgs ):
218 """ 219 @summary Calls stratMark and uses maximum returns. 220 @param dtStart: Start date for portfolio 221 @param dtEnd: End date for portfolio 222 @param dFuncArgs: Dict of function args passed to the function 223 @return DataFrame corresponding to the portfolio allocations 224 """ 225 dFuncArgs['sMarkPoint'] = 'MaxRet' 226 return stratMark( dtStart, dtEnd, dFuncArgs )
227
228 -def stratMarkMinRet( dtStart, dtEnd, dFuncArgs ):
229 """ 230 @summary Calls stratMark and uses minimum returns. 231 @param dtStart: Start date for portfolio 232 @param dtEnd: End date for portfolio 233 @param dFuncArgs: Dict of function args passed to the function 234 @return DataFrame corresponding to the portfolio allocations 235 """ 236 dFuncArgs['sMarkPoint'] = 'MinRet' 237 return stratMark( dtStart, dtEnd, dFuncArgs )
238
239 -def stratMarkSharpeAlpha( dtStart, dtEnd, dFuncArgs ):
240 """ 241 @summary Calls stratMark and chooses the highest share point, uses future knowlege (alpha). 242 @param dtStart: Start date for portfolio 243 @param dtEnd: End date for portfolio 244 @param dFuncArgs: Dict of function args passed to the function 245 @return DataFrame corresponding to the portfolio allocations 246 """ 247 dFuncArgs['sMarkPoint'] = 'Sharpe' 248 dFuncArgs['bAddAlpha'] = True 249 return stratMark( dtStart, dtEnd, dFuncArgs )
250
251 -def stratMarkMaxRetAlpha( dtStart, dtEnd, dFuncArgs ):
252 """ 253 @summary Calls stratMark chooses the highest returns point, uses future knowlege (alpha). 254 @param dtStart: Start date for portfolio 255 @param dtEnd: End date for portfolio 256 @param dFuncArgs: Dict of function args passed to the function 257 @return DataFrame corresponding to the portfolio allocations 258 """ 259 dFuncArgs['sMarkPoint'] = 'MaxRet' 260 dFuncArgs['bAddAlpha'] = True 261 return stratMark( dtStart, dtEnd, dFuncArgs )
262