def get_bab_pf_values(StockReturns): first_date = StockPrices['date'].min() last_date = StockPrices['date'].max() stock_first = StockPrices[StockPrices['date'] == first_date][['ticker']].reset_index(drop=True) stock_last = StockPrices[StockPrices['date'] == last_date][['ticker']].reset_index(drop=True) stock_universe = stock_first.merge(stock_last).merge(StockBeta) tickers = stock_universe[['ticker']] # test_dates = np.sort(StockPrices['date'].astype(datetime.datetime).unique()) build_start_date = datetime.datetime(2011, 11, 1) build_end_date = datetime.datetime(2014, 11, 7) test_start_date = datetime.datetime(2014, 11, 10) test_end_date = datetime.datetime(2015, 1, 31) decay = 0.003 prices_build = StockPrices[StockPrices['date'] == build_end_date][['ticker', 'adj_close']] (Coef, Res) = functions.wReg(StockReturns, CarhartDaily, tickers, decay, build_start_date, build_end_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 font_size = 20 # color_cycle = ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'lightblue', 'gold', 'pink'] color_cycle = [] for n in range(10): color_cycle.append((n * 0.1, 1.0 - n * 0.1, 0.0)) pfValuesAll = pd.DataFrame() for n in range(10): tmpData = sortCoef.head(N * (n + 1)).tail(N) mean_beta = tmpData['beta'].mean() wTickers = tmpData[['ticker']].reset_index(drop=True) wTickers['weight'] = 1 / np.float64(N) portfolio = wTickers.merge(prices_build).rename(columns={'adj_close': 'price'}) portfolio['nShare'] = (CAPITAL * portfolio['weight'] / portfolio['price']).map(functions.intPart) pfValues = functions.testPortfolio_simple(StockPrices, StockReturns, SP500Prices, StockBeta, portfolio, test_start_date, test_end_date) pfValues['beta group'] = n pfValues['mean beta'] = mean_beta pfValues['value'] = pfValues['value'] + CAPITAL - pfValues['value'][0] plt.plot(pfValues['date'], pfValues['value'], linewidth=2.0, color=color_cycle[n], label='mean beta %0.2f' % mean_beta) pfValuesAll = pfValuesAll.append(pfValues) matplotlib.rc('xtick', labelsize=font_size) matplotlib.rc('ytick', labelsize=font_size) # plt.title('Performance of Beta Groups', size=font_size) plt.ylabel('Account Value', size=font_size) plt.xlabel('Date', size=font_size) plt.grid() plt.legend(loc=3) plt.show() return pfValuesAll
pf_0208['price_current'] = pf_0208['price_current'].map(dollar_to_float) pf_0208['value'] = pf_0208['value'].map(dollar_to_float) * pf_0208['nShare'].map(lambda q: np.sign(q)) # single stock performance pf_0208['return'] = np.log(pf_0208['price_current'] / pf_0208['price']) * 100 * np.sign(pf_0208['nShare']) pf_0208['position'] = np.abs(pf_0208['value']) # test_end_date = last_date decay = 0.003 tickers = get_stock_universe(StockPrices) build_start_date = datetime.datetime(2012, 2, 6) build_end_date = datetime.datetime(2015, 2, 6) # prices_build = StockPrices[StockPrices['date'] == build_end_date][['ticker', 'adj_close']] (Coef, Res) = functions.wReg(StockReturns, CarhartDaily, tickers, decay, build_start_date, build_end_date) tickers_after_reg = tickers.merge(Coef[['ticker']]) tickers_industry = tickers.merge(industry_data[['ticker']]) betas = Coef.merge(tickers_industry).rename(columns={'Mkt-RF': 'beta'})[['ticker', 'beta']].reset_index(drop=True) sortCoef = betas.sort('beta').reset_index(drop=True) N = sortCoef.shape[0] / 10 # long_tickers = sortCoef.head(4*N).tail(3*N)[['ticker']].sort('ticker').reset_index(drop=True) long_tickers = sortCoef.head(4 * N)[['ticker']].sort('ticker').reset_index(drop=True) short_tickers = sortCoef.tail(4 * N)[['ticker']].sort('ticker').reset_index(drop=True) beta_bound = 0.4 position_bound = 0.02 sector_bound = 0.02 three_factor_bound = 0.01 trim = 0.002 stats, wTickers = pf_optimizer(long_tickers, short_tickers, Coef, industry_data, CarhartDaily, StockBeta,
def get_bab_pf_values(StockReturns): first_date = StockPrices['date'].min() last_date = StockPrices['date'].max() stock_first = StockPrices[StockPrices['date'] == first_date][[ 'ticker' ]].reset_index(drop=True) stock_last = StockPrices[StockPrices['date'] == last_date][[ 'ticker' ]].reset_index(drop=True) stock_universe = stock_first.merge(stock_last).merge(StockBeta) tickers = stock_universe[['ticker']] # test_dates = np.sort(StockPrices['date'].astype(datetime.datetime).unique()) build_start_date = datetime.datetime(2011, 11, 1) build_end_date = datetime.datetime(2014, 11, 7) test_start_date = datetime.datetime(2014, 11, 10) test_end_date = datetime.datetime(2015, 1, 31) decay = 0.003 prices_build = StockPrices[StockPrices['date'] == build_end_date][[ 'ticker', 'adj_close' ]] (Coef, Res) = functions.wReg(StockReturns, CarhartDaily, tickers, decay, build_start_date, build_end_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 font_size = 20 # color_cycle = ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'lightblue', 'gold', 'pink'] color_cycle = [] for n in range(10): color_cycle.append((n * 0.1, 1.0 - n * 0.1, 0.0)) pfValuesAll = pd.DataFrame() for n in range(10): tmpData = sortCoef.head(N * (n + 1)).tail(N) mean_beta = tmpData['beta'].mean() wTickers = tmpData[['ticker']].reset_index(drop=True) wTickers['weight'] = 1 / np.float64(N) portfolio = wTickers.merge(prices_build).rename( columns={'adj_close': 'price'}) portfolio['nShare'] = (CAPITAL * portfolio['weight'] / portfolio['price']).map(functions.intPart) pfValues = functions.testPortfolio_simple(StockPrices, StockReturns, SP500Prices, StockBeta, portfolio, test_start_date, test_end_date) pfValues['beta group'] = n pfValues['mean beta'] = mean_beta pfValues['value'] = pfValues['value'] + CAPITAL - pfValues['value'][0] plt.plot(pfValues['date'], pfValues['value'], linewidth=2.0, color=color_cycle[n], label='mean beta %0.2f' % mean_beta) pfValuesAll = pfValuesAll.append(pfValues) matplotlib.rc('xtick', labelsize=font_size) matplotlib.rc('ytick', labelsize=font_size) # plt.title('Performance of Beta Groups', size=font_size) plt.ylabel('Account Value', size=font_size) plt.xlabel('Date', size=font_size) plt.grid() plt.legend(loc=3) plt.show() return pfValuesAll
START_TRAIN = datetime.datetime(2011, 11, 1) END_TRAIN = datetime.datetime(2014, 11, 6) BUILD_DATE = datetime.datetime(2014,11, 7) BETA_BOUND = 0.4 WEIGHT_BOUND = 0.02 CAPITAL = 1e7 DataFolder = 'D:\Dropbox\CQA 2014\Data' (StockPrices, SP500Prices, CarhartDaily, StockBeta) = ReadData.ReadAll(DataFolder) StockReturns = ReadData.ReadReturn(DataFolder) SP500Returns = ReadData.GetSP500Return(SP500Prices) tickers = ReadData.ReadTickers(DataFolder) decay = 0.003 # Cheating...# Half-Value Period is 100 trading days (Coef, Res) = functions.wReg(StockReturns, CarhartDaily, tickers, decay, START_TRAIN, END_TRAIN) Coef.to_csv(r'%s/Coef_%s_%s_%.4f.csv' % (DataFolder, START_TRAIN.date(), END_TRAIN.date(), decay), index=False) Res.to_csv(r'%s/Res_%s_%s_%.4f.csv' % (DataFolder, START_TRAIN.date(), END_TRAIN.date(), decay), index=False) # Coef = pd.read_csv(r'%s/Coef_%s_%s_%.4f.csv' % (DataFolder, START_TRAIN.date(), END_TRAIN.date(), decay)) # Res = pd.read_csv(r'%s/Res_%s_%s_%.4f.csv' % (DataFolder, START_TRAIN.date(), END_TRAIN.date(), decay)) 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(4*N)[['ticker']].sort('ticker').reset_index(drop=True) pfTickers = pd.concat((shortTickers[['ticker']], longTickers[['ticker']]), axis=0).sort('ticker').reset_index(drop=True) # def getCovMatrix(tickers): CarhartSample = CarhartDaily[(CarhartDaily['date'] >= START_TRAIN) &
n_periods = (test_dates.shape[0] - start_index - rebalance_gap) / rebalance_gap pfValues = pd.DataFrame() # n_periods = 1 total_value = CAPITAL sp500_value = CAPITAL value_error_count = 0 diff_threshold = 0.05 for k in range(n_periods): # k = 13 back_date = test_dates[start_index - 750 + k * rebalance_gap] start_date = test_dates[start_index + k * rebalance_gap] end_date = test_dates[start_index + (k+1) * rebalance_gap] print 'end_date = %s' % end_date (Coef, Res) = functions.wReg(StockReturns, CarhartDaily, tickers, decay, back_date, start_date) # find long/short universe 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']].append(sortCoef.head(N)[['ticker']]).sort('ticker').reset_index(drop=True) shortTickersHigh = sortCoef.tail(3*N)[['ticker']].sort('ticker').reset_index(drop=True) 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,
dollar_to_float) * pf_0208['nShare'].map(lambda q: np.sign(q)) # single stock performance pf_0208['return'] = np.log(pf_0208['price_current'] / pf_0208['price']) * 100 * np.sign(pf_0208['nShare']) pf_0208['position'] = np.abs(pf_0208['value']) # test_end_date = last_date decay = 0.003 tickers = get_stock_universe(StockPrices) build_start_date = datetime.datetime(2012, 2, 6) build_end_date = datetime.datetime(2015, 2, 6) # prices_build = StockPrices[StockPrices['date'] == build_end_date][['ticker', 'adj_close']] (Coef, Res) = functions.wReg(StockReturns, CarhartDaily, tickers, decay, build_start_date, build_end_date) tickers_after_reg = tickers.merge(Coef[['ticker']]) tickers_industry = tickers.merge(industry_data[['ticker']]) betas = Coef.merge(tickers_industry).rename(columns={'Mkt-RF': 'beta'})[[ 'ticker', 'beta' ]].reset_index(drop=True) sortCoef = betas.sort('beta').reset_index(drop=True) N = sortCoef.shape[0] / 10 # long_tickers = sortCoef.head(4*N).tail(3*N)[['ticker']].sort('ticker').reset_index(drop=True) long_tickers = sortCoef.head(4 * N)[['ticker' ]].sort('ticker').reset_index(drop=True) short_tickers = sortCoef.tail(4 * N)[['ticker' ]].sort('ticker').reset_index(drop=True) beta_bound = 0.4 position_bound = 0.02 sector_bound = 0.02
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
n_periods = (test_dates.shape[0] - start_index - rebalance_gap) / rebalance_gap pfValues = pd.DataFrame() # n_periods = 1 total_value = CAPITAL sp500_value = CAPITAL value_error_count = 0 diff_threshold = 0.05 for k in range(n_periods): # k = 13 back_date = test_dates[start_index - 750 + k * rebalance_gap] start_date = test_dates[start_index + k * rebalance_gap] end_date = test_dates[start_index + (k + 1) * rebalance_gap] print 'end_date = %s' % end_date (Coef, Res) = functions.wReg(StockReturns, CarhartDaily, tickers, decay, back_date, start_date) # find long/short universe 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']].append( sortCoef.head(N)[['ticker']]).sort('ticker').reset_index(drop=True) shortTickersHigh = sortCoef.tail( 3 * N)[['ticker']].sort('ticker').reset_index(drop=True) shortTickersLow = sortCoef.head(N)[[ 'ticker' ]].sort('ticker').reset_index(drop=True)
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
END = datetime.datetime(2014, 11, 5) (StockPrices, SP500Prices, CarhartDaily, StockBeta) = ReadData.ReadAll(DataFolder) StockReturns = ReadData.ReadReturn(DataFolder) SP500Returns = ReadData.GetSP500Return(SP500Prices) tickers = ReadData.ReadTickers(DataFolder) # StockReturnsTrain = StockReturns[(StockReturns['endDate'] >= START_TRAIN) & # (StockReturns['endDate'] <= END_TRAIN)].merge(tickers) # StockReturnsTest = StockReturns[StockReturns['endDate'] >= START].merge(tickers) decayList = [0, 0.001, 0.002, 0.003, 0.004, 0.005, 0.01] # decay = functions.GetDecay(StockReturns, CarhartDaily, decayList, START_TRAIN, END_TRAIN, START, END, tickers) decay = 0.003 # Cheating... (Coef, Res) = functions.wReg(StockReturns, CarhartDaily, tickers, decay, START_TRAIN, END_TRAIN) Coef.to_csv(r'%s/Coef_%s_%s_%.4f.csv' % (DataFolder, START_TRAIN.date(), END_TRAIN.date(), decay), index=False) Res.to_csv(r'%s/Res_%s_%s_%.4f.csv' % (DataFolder, START_TRAIN.date(), END_TRAIN.date(), decay), index=False) # comp = StockBeta.merge(CoefTrain[['ticker', 'betaTrain']]).merge(CoefTest[['ticker', 'betaTest']]) # plt.figure(1) # plt.subplot(221) # plt.xlabel('cqaBeta') # plt.ylabel('betaTrain') # plt.scatter(comp['cqaBeta'], comp['betaTrain']) # plt.plot(range(4), range(4), 'r-') # plt.subplot(222)