def testPortfolio2Test(): pfValues = functions.testPortfolio2(StockPrices, SP500Prices, StockBeta, wTickers, CAPITAL, START, END) plt.subplot(121) plt.title('Portfolio Value vs Date') plt.plot(pfValues['date'], pfValues['value'], label='Portfolio Value', color='b') plt.plot(pfValues['date'], pfValues['SP500'] * (pfValues['value'].iloc[0]/pfValues['SP500'].iloc[0]), label='S&P500', color='r') plt.legend() plt.grid() plt.subplot(122) plt.title('beta_CQA vs Date') plt.plot(pfValues['date'], pfValues['beta_CQA']) plt.grid() plt.show() return pfValues
def testPortfolio2Test(): pfValues = functions.testPortfolio2(StockPrices, SP500Prices, StockBeta, wTickers, CAPITAL, START, END) plt.subplot(121) plt.title('Portfolio Value vs Date') plt.plot(pfValues['date'], pfValues['value'], label='Portfolio Value', color='b') plt.plot(pfValues['date'], pfValues['SP500'] * (pfValues['value'].iloc[0] / pfValues['SP500'].iloc[0]), label='S&P500', color='r') plt.legend() plt.grid() plt.subplot(122) plt.title('beta_CQA vs Date') plt.plot(pfValues['date'], pfValues['beta_CQA']) plt.grid() plt.show() return pfValues
shortTickersLow = sortCoef.head(N)[['ticker']].sort('ticker').reset_index(drop=True) mean_smb_40 = CarhartDaily[CarhartDaily['date'] <= start_date]['SMB'].tail(40).mean() mean_smb_130 = CarhartDaily[CarhartDaily['date'] <= start_date]['SMB'].tail(130).mean() diff_mean = mean_smb_40 - mean_smb_130 try: (opt_comp, wTickers) = functions.pfOptimizer8(longTickers, shortTickersHigh, shortTickersLow, Coef, Res, CarhartDaily, StockBeta, BETA_BOUND, WEIGHT_BOUND, back_date, start_date, diff_mean, diff_threshold) except ValueError: value_error_count += 1 pass wTickers = wTickers[(wTickers['weight'] >= 0.001) | (wTickers['weight'] <= -0.001)] # test portfolio pfValues = pfValues.append( functions.testPortfolio2(StockPrices, SP500Prices, StockBeta, Coef, wTickers, total_value, sp500_value, start_date, end_date)) total_value = pfValues['value'].iloc[-1] sp500_value = pfValues['SP500value'].iloc[-1] pfValues.reset_index(drop=True) # analyze portfolio performance in each month def pfValuesPlot(pfValues, BETA_BOUND): line_width = 1.0 plt.subplot(221) plt.plot(pfValues['date'], pfValues['value'], label='Portfolio Value', color='r', linewidth=line_width) plt.plot(pfValues['date'], pfValues['SP500value'], label='S&P500', color='b', linewidth=line_width) plt.title('Portfolio Value vs S&P500') plt.legend(bbox_to_anchor=(0.2, 1)) plt.grid() plt.subplot(222)
def risk_return_expectation(): back_date = datetime.datetime(2010, 11, 1) start_date = datetime.datetime(2013, 11, 1) end_date = datetime.datetime(2014, 10, 31) tickers = ReadData.ReadTickers(DataFolder) BETA_BOUND = 0.4 WEIGHT_BOUND = 0.02 decay = 0.003 (Coef, Res) = functions.wReg(StockReturns, CarhartDaily, tickers, decay, back_date, start_date) betas = Coef.merge(tickers).rename(columns={'Mkt-RF': 'beta'})[[ 'ticker', 'beta' ]].reset_index(drop=True) sortCoef = betas.sort('beta').reset_index(drop=True) N = sortCoef.shape[0] / 10 longTickers = sortCoef.head(4 * N).tail( 3 * N)[['ticker']].sort('ticker').reset_index(drop=True) shortTickers = sortCoef.tail( 3 * N)[['ticker']].sort('ticker').reset_index(drop=True) wTickers = functions.pfOptimizer(longTickers, shortTickers, Coef, StockBeta, BETA_BOUND, WEIGHT_BOUND) wTickers = wTickers[(wTickers['weight'] >= 0.001) | (wTickers['weight'] <= -0.001)] total_value = 1e7 sp500_value = 1e7 # Initial Exposures Exposure = wTickers.merge(Coef) ini_beta = (Exposure['weight'] * Exposure['Mkt-RF']).sum() ini_smb = (Exposure['weight'] * Exposure['SMB']).sum() ini_hml = (Exposure['weight'] * Exposure['HML']).sum() ini_umd = (Exposure['weight'] * Exposure['UMD']).sum() print 'ini_beta = %.2f' % ini_beta print 'ini_smb = %.2f' % ini_smb print 'ini_hml = %.2f' % ini_hml print 'ini_umd = %.2f' % ini_umd # test portfolio pfValues = functions.testPortfolio2( StockPrices, SP500Prices, StockBeta, Coef, wTickers, total_value, sp500_value, start_date, end_date).rename(columns={'SP500value': 'sp500value'}) pfValues['return'] = (pfValues['value'] - total_value) / total_value pfValues['sp500return'] = (pfValues['sp500value'] - total_value) / total_value fig = plt.figure() ax = fig.add_subplot(1, 1, 1) matplotlib.rc('xtick', labelsize=36) matplotlib.rc('ytick', labelsize=36) plt.plot(pfValues['date'], pfValues['return'] * 100, color=cit_color, linewidth=6, label='Portfolio Value') plt.plot(pfValues['date'], pfValues['sp500return'] * 100, color='b', linewidth=6, label='S&P 500') plt.legend(loc=2, prop={'size': 36}) fmt = '%.2f%%' # Format you want the ticks, e.g. '40%' yticks = mtick.FormatStrFormatter(fmt) plt.xticks(rotation=25) ax.yaxis.set_major_formatter(yticks) plt.gcf().subplots_adjust(bottom=0.18) plt.grid() plt.show() breakpoints = [ datetime.datetime(2013, 11, 30), datetime.datetime(2013, 12, 31), datetime.datetime(2014, 1, 31), datetime.datetime(2014, 2, 28), datetime.datetime(2014, 3, 31), datetime.datetime(2014, 4, 30), datetime.datetime(2014, 5, 31), datetime.datetime(2014, 6, 30), datetime.datetime(2014, 7, 31), datetime.datetime(2014, 8, 31), datetime.datetime(2014, 9, 30), datetime.datetime(2014, 10, 31), ] comparison = pd.DataFrame() tmp_start = datetime.datetime(2013, 10, 30) for tmp_end in breakpoints: print tmp_end tmp_pfValues = pfValues[(pfValues['date'] > tmp_start) & (pfValues['date'] <= tmp_end)] # tmp_return = tmp_pfValues['return'].sum() # tmp_sp500_return = tmp_pfValues['sp500return'].sum() start_value = tmp_pfValues['value'].iloc[0] end_value = tmp_pfValues['value'].iloc[-1] tmp_return = ((end_value - start_value) / start_value) * 100 start_sp500 = tmp_pfValues['sp500value'].iloc[0] end_sp500 = tmp_pfValues['sp500value'].iloc[-1] tmp_sp500_return = ((end_sp500 - start_sp500) / start_value) * 100 comparison = comparison.append( pd.DataFrame([{ 'return': tmp_return, 'sp500return': tmp_sp500_return }])) tmp_start = tmp_end comparison pfReturns = pfValues[['date', 'value', 'sp500value']] pfReturns['daily_return'] = ( pfReturns['value'] - pfReturns['value'].shift(1)) / pfReturns['value'].shift(1) pfReturns['daily_sp500return'] = ( pfReturns['sp500value'] - pfReturns['sp500value'].shift(1)) / pfReturns['value'].shift(1) pfReturns = pfReturns[1:] # Annualized volatility vol_portfolio = pfReturns['daily_return'].std() * math.sqrt(252) vol_sp500 = pfReturns['daily_sp500return'].std() * math.sqrt(252) n_days = np.float(pfReturns.shape[0]) ave_return = ((pfValues['value'].iloc[-1] / pfValues['value'].iloc[0])** (1 / n_days) - 1) * 100 ave_sp500_return = ( (pfValues['sp500value'].iloc[-1] / pfValues['sp500value'].iloc[0])** (1 / n_days) - 1) * 100 cum_return = (pfValues['value'].iloc[-1] - pfValues['value'].iloc[0]) / pfValues['value'].iloc[0] * 100 cum_sp500return = ( pfValues['sp500value'].iloc[-1] - pfValues['sp500value'].iloc[0]) / pfValues['sp500value'].iloc[0] * 100 print 'cum_return = %.2f' % cum_return print 'cum_sp500return = %.2f' % cum_sp500return print 'vol_portfolio = %.4f' % vol_portfolio print 'vol_sp500 = %.4f' % vol_sp500 sharpe_portfolio = pfReturns['daily_return'].mean() / vol_portfolio * 252 sharpe_sp500 = pfReturns['daily_sp500return'].mean() / vol_sp500 * 252 down_dev_portfolio = math.sqrt( pfReturns[pfReturns['daily_return'] < 0]['daily_return'].map( lambda x: x**2).sum() / n_days) down_dev_sp500 = math.sqrt( pfReturns[pfReturns['daily_sp500return'] < 0]['daily_sp500return'].map( lambda x: x**2).sum() / n_days) print 'down_dev_portfolio = %.4f' % down_dev_portfolio print 'down_dev_sp500 = %.4f' % down_dev_sp500 max_drawdown = 0 max_drawdown_sp500 = 0 for i in range(pfValues.shape[0] - 1): for j in range(i + 1, pfValues.shape[0]): tmp_drawdown = ( pfValues['value'].iloc[j] - pfValues['value'].iloc[i]) / pfValues['value'].iloc[i] * 100 tmp_drawdown_sp500 = (pfValues['sp500value'].iloc[j] - pfValues['sp500value'].iloc[i] ) / pfValues['sp500value'].iloc[i] * 100 max_drawdown = min(max_drawdown, tmp_drawdown) max_drawdown_sp500 = min(max_drawdown_sp500, tmp_drawdown_sp500) print 'max_drawdown = %.2f' % max_drawdown print 'max_drawdown_sp500 = %.2f' % max_drawdown_sp500 pfReturns = pfReturns.merge(CarhartDaily, on='date') y = pfReturns['daily_return'] * 100 - pfReturns['RF'] X = sm.add_constant(pfReturns[['Mkt-RF', 'SMB', 'HML', 'UMD']]) model = sm.OLS(y, X).fit() print model.params
CarhartDaily['date'] <= start_date]['SMB'].tail(130).mean() diff_mean = mean_smb_40 - mean_smb_130 try: (opt_comp, wTickers) = functions.pfOptimizer8( longTickers, shortTickersHigh, shortTickersLow, Coef, Res, CarhartDaily, StockBeta, BETA_BOUND, WEIGHT_BOUND, back_date, start_date, diff_mean, diff_threshold) except ValueError: value_error_count += 1 pass wTickers = wTickers[(wTickers['weight'] >= 0.001) | (wTickers['weight'] <= -0.001)] # test portfolio pfValues = pfValues.append( functions.testPortfolio2(StockPrices, SP500Prices, StockBeta, Coef, wTickers, total_value, sp500_value, start_date, end_date)) total_value = pfValues['value'].iloc[-1] sp500_value = pfValues['SP500value'].iloc[-1] pfValues.reset_index(drop=True) # analyze portfolio performance in each month def pfValuesPlot(pfValues, BETA_BOUND): line_width = 1.0 plt.subplot(221) plt.plot(pfValues['date'], pfValues['value'], label='Portfolio Value', color='r', linewidth=line_width)
def risk_return_expectation(): back_date = datetime.datetime(2010, 11, 1) start_date = datetime.datetime(2013, 11, 1) end_date = datetime.datetime(2014, 10, 31) tickers = ReadData.ReadTickers(DataFolder) BETA_BOUND = 0.4 WEIGHT_BOUND = 0.02 decay = 0.003 (Coef, Res) = functions.wReg(StockReturns, CarhartDaily, tickers, decay, back_date, start_date) betas = Coef.merge(tickers).rename(columns={'Mkt-RF': 'beta'})[['ticker', 'beta']].reset_index(drop=True) sortCoef = betas.sort('beta').reset_index(drop=True) N = sortCoef.shape[0] / 10 longTickers = sortCoef.head(4*N).tail(3*N)[['ticker']].sort('ticker').reset_index(drop=True) shortTickers = sortCoef.tail(3*N)[['ticker']].sort('ticker').reset_index(drop=True) wTickers = functions.pfOptimizer(longTickers, shortTickers, Coef, StockBeta, BETA_BOUND, WEIGHT_BOUND) wTickers = wTickers[(wTickers['weight'] >= 0.001) | (wTickers['weight'] <= -0.001)] total_value = 1e7 sp500_value = 1e7 # Initial Exposures Exposure = wTickers.merge(Coef) ini_beta = (Exposure['weight']*Exposure['Mkt-RF']).sum() ini_smb = (Exposure['weight']*Exposure['SMB']).sum() ini_hml = (Exposure['weight']*Exposure['HML']).sum() ini_umd = (Exposure['weight']*Exposure['UMD']).sum() print 'ini_beta = %.2f' % ini_beta print 'ini_smb = %.2f' % ini_smb print 'ini_hml = %.2f' % ini_hml print 'ini_umd = %.2f' % ini_umd # test portfolio pfValues = functions.testPortfolio2(StockPrices, SP500Prices, StockBeta, Coef, wTickers, total_value, sp500_value, start_date, end_date).rename(columns={'SP500value': 'sp500value'}) pfValues['return'] = (pfValues['value']-total_value)/total_value pfValues['sp500return'] = (pfValues['sp500value']-total_value)/total_value fig = plt.figure() ax = fig.add_subplot(1,1,1) matplotlib.rc('xtick', labelsize=36) matplotlib.rc('ytick', labelsize=36) plt.plot(pfValues['date'], pfValues['return']*100, color=cit_color, linewidth=6, label='Portfolio Value') plt.plot(pfValues['date'], pfValues['sp500return']*100, color='b', linewidth=6, label='S&P 500') plt.legend(loc=2, prop={'size': 36}) fmt = '%.2f%%' # Format you want the ticks, e.g. '40%' yticks = mtick.FormatStrFormatter(fmt) plt.xticks(rotation=25) ax.yaxis.set_major_formatter(yticks) plt.gcf().subplots_adjust(bottom=0.18) plt.grid() plt.show() breakpoints = [datetime.datetime(2013, 11, 30), datetime.datetime(2013, 12, 31), datetime.datetime(2014, 1, 31), datetime.datetime(2014, 2, 28), datetime.datetime(2014, 3, 31), datetime.datetime(2014, 4, 30), datetime.datetime(2014, 5, 31), datetime.datetime(2014, 6, 30), datetime.datetime(2014, 7, 31), datetime.datetime(2014, 8, 31), datetime.datetime(2014, 9, 30), datetime.datetime(2014, 10, 31), ] comparison = pd.DataFrame() tmp_start = datetime.datetime(2013, 10, 30) for tmp_end in breakpoints: print tmp_end tmp_pfValues = pfValues[(pfValues['date'] > tmp_start) & (pfValues['date'] <= tmp_end)] # tmp_return = tmp_pfValues['return'].sum() # tmp_sp500_return = tmp_pfValues['sp500return'].sum() start_value = tmp_pfValues['value'].iloc[0] end_value = tmp_pfValues['value'].iloc[-1] tmp_return = ((end_value - start_value) / start_value) * 100 start_sp500 = tmp_pfValues['sp500value'].iloc[0] end_sp500 = tmp_pfValues['sp500value'].iloc[-1] tmp_sp500_return = ((end_sp500 - start_sp500) / start_value) * 100 comparison = comparison.append(pd.DataFrame([{'return': tmp_return, 'sp500return': tmp_sp500_return }])) tmp_start = tmp_end comparison pfReturns = pfValues[['date', 'value', 'sp500value']] pfReturns['daily_return'] = (pfReturns['value']-pfReturns['value'].shift(1))/pfReturns['value'].shift(1) pfReturns['daily_sp500return'] = (pfReturns['sp500value']-pfReturns['sp500value'].shift(1))/pfReturns['value'].shift(1) pfReturns = pfReturns[1:] # Annualized volatility vol_portfolio = pfReturns['daily_return'].std()*math.sqrt(252) vol_sp500 = pfReturns['daily_sp500return'].std()*math.sqrt(252) n_days = np.float(pfReturns.shape[0]) ave_return = ((pfValues['value'].iloc[-1]/pfValues['value'].iloc[0])**(1/n_days)-1)*100 ave_sp500_return = ((pfValues['sp500value'].iloc[-1]/pfValues['sp500value'].iloc[0])**(1/n_days)-1)*100 cum_return = (pfValues['value'].iloc[-1]-pfValues['value'].iloc[0])/pfValues['value'].iloc[0]*100 cum_sp500return = (pfValues['sp500value'].iloc[-1]-pfValues['sp500value'].iloc[0])/pfValues['sp500value'].iloc[0]*100 print 'cum_return = %.2f' % cum_return print 'cum_sp500return = %.2f' % cum_sp500return print 'vol_portfolio = %.4f' % vol_portfolio print 'vol_sp500 = %.4f' % vol_sp500 sharpe_portfolio = pfReturns['daily_return'].mean()/vol_portfolio * 252 sharpe_sp500 = pfReturns['daily_sp500return'].mean()/vol_sp500 * 252 down_dev_portfolio = math.sqrt(pfReturns[pfReturns['daily_return']<0]['daily_return'].map(lambda x: x**2).sum()/n_days) down_dev_sp500 = math.sqrt(pfReturns[pfReturns['daily_sp500return']<0]['daily_sp500return'].map(lambda x: x**2).sum()/n_days) print 'down_dev_portfolio = %.4f' % down_dev_portfolio print 'down_dev_sp500 = %.4f' % down_dev_sp500 max_drawdown = 0 max_drawdown_sp500 = 0 for i in range(pfValues.shape[0]-1): for j in range(i+1, pfValues.shape[0]): tmp_drawdown = (pfValues['value'].iloc[j]-pfValues['value'].iloc[i])/pfValues['value'].iloc[i]*100 tmp_drawdown_sp500 = (pfValues['sp500value'].iloc[j]-pfValues['sp500value'].iloc[i])/pfValues['sp500value'].iloc[i]*100 max_drawdown = min(max_drawdown, tmp_drawdown) max_drawdown_sp500 = min(max_drawdown_sp500, tmp_drawdown_sp500) print 'max_drawdown = %.2f' % max_drawdown print 'max_drawdown_sp500 = %.2f' % max_drawdown_sp500 pfReturns = pfReturns.merge(CarhartDaily, on='date') y = pfReturns['daily_return'] * 100 - pfReturns['RF'] X = sm.add_constant(pfReturns[['Mkt-RF', 'SMB', 'HML', 'UMD']]) model = sm.OLS(y, X).fit() print model.params