def test_short_returns(): b_data = prep_data.get_data('^GSPC', '2018-05-01', '2019-05-01', 'monthly') b_transformed_data, dates = prep_data.transform_yahoo_finance_dict(b_data) b_asset_data = prep_data.generate_asset_data_array(b_transformed_data) # MSFT is a winner, X is a loser during this period data = prep_data.get_data(['MSFT', 'X'], '2018-05-01', '2019-05-01', 'monthly') transformed_data, dates = prep_data.transform_yahoo_finance_dict(data) asset_data = prep_data.generate_asset_data_array(transformed_data) msft_start = asset_data[0].price_data[-1] msft_end = asset_data[0].price_data[0] msft_ret = (msft_end - msft_start) / msft_start x_start = asset_data[1].price_data[-1] x_end = asset_data[1].price_data[0] x_ret = (x_end - x_start) / x_start # Calculate long only returns long_p_ret = PortfolioReturns(asset_data, np.array([0.5, 0.5]), b_asset_data[0]) expected_return = (msft_ret + x_ret) / 2 assert round(long_p_ret.total_return, 3) == round(expected_return, 3) # Calculate long / short returns long_short_p_ret = PortfolioReturns(asset_data, np.array([0.5, -0.5]), b_asset_data[0]) expected_return = (msft_ret - x_ret) / 2 assert round(long_short_p_ret.total_return, 3) == round(expected_return, 3)
def do_task_optimize(name, tickers, benchmark_index: str, start_date, end_date, user_id, task_id, interval='weekly'): job_start = datetime.now() # Get & prepare portfolio data data = prep_data.get_data(tickers, start_date, end_date, interval) transformed_data, dates = prep_data.transform_yahoo_finance_dict(data) asset_data = prep_data.generate_asset_data_array(transformed_data) # Get benchmark data benchmark_data = prep_data.get_data(benchmark_index, start_date, end_date, interval) benchmark_transformed_data, _ = prep_data.transform_yahoo_finance_dict( benchmark_data) benchmark_asset_data = prep_data.generate_asset_data_array( benchmark_transformed_data) benchmark_returns = PortfolioReturns(benchmark_asset_data) # Optimize portfolio matrices = prep_data.AssetMatrices(asset_data) optimizer = optimize.Optimize(matrices, benchmark_asset_data[0]) results = optimizer.optimize_all() job_end = datetime.now() job = { 'job_start': job_start, 'job_end': job_end, 'asset_data': [a.as_dict() for a in asset_data], 'matrices': matrices.as_dict(), 'price_dates': dates, 'parameters': { 'tickers': tickers, 'start_date': start_date, 'end_date': end_date, 'interval': interval }, 'benchmark_index': { 'asset_data': benchmark_asset_data[0].as_dict(), 'returns': benchmark_returns.as_dict() }, 'results': [res.as_dict() for res in results], 'user_id': user_id, 'task_id': task_id, 'published': False, 'name': name } return insert_job(job)
def test_short_returns_complex(): b_data = prep_data.get_data('^GSPC', '2018-05-13', '2019-05-13', 'weekly') b_transformed_data, dates = prep_data.transform_yahoo_finance_dict(b_data) b_asset_data = prep_data.generate_asset_data_array(b_transformed_data) data = prep_data.get_data(['MSFT', 'X', 'AA', 'SPLK'], '2018-05-13', '2019-05-13', 'weekly') transformed_data, dates = prep_data.transform_yahoo_finance_dict(data) asset_data = prep_data.generate_asset_data_array(transformed_data) long_p_ret = PortfolioReturns(asset_data, np.array([1., 0., 0., 0.]), b_asset_data[0]) long_short_p_ret = PortfolioReturns( asset_data, np.array([1., -0.3847, -0.3808, 0.7655]), b_asset_data[0]) assert 1 == 1
def test_returns_s_and_p_500(): data = prep_data.get_data('^GSPC', '2018-05-01', '2019-02-01', 'weekly') transformed_data, dates = prep_data.transform_yahoo_finance_dict(data) asset_data = prep_data.generate_asset_data_array(transformed_data) portfolio_returns = PortfolioReturns(asset_data) assert len(portfolio_returns.portfolio_returns) == len( asset_data[0].returns) assert len(portfolio_returns.portfolio_values) == len( asset_data[0].price_data)
def test_alpha_beta(): b_data = prep_data.get_data('^GSPC', '2016-05-01', '2019-05-01', 'monthly') b_transformed_data, dates = prep_data.transform_yahoo_finance_dict(b_data) b_asset_data = prep_data.generate_asset_data_array(b_transformed_data) data = prep_data.get_data(['FB', 'MSFT'], '2016-05-01', '2019-05-01', 'monthly') transformed_data, dates = prep_data.transform_yahoo_finance_dict(data) asset_data = prep_data.generate_asset_data_array(transformed_data) matrices = prep_data.AssetMatrices(asset_data) optimizer = optimize.Optimize(matrices, b_asset_data[0]) results = optimizer.optimize_all() portfolio_returns = results[0].portfolio_returns assert len(portfolio_returns.portfolio_returns) == len( asset_data[0].returns) assert len(portfolio_returns.portfolio_values) == len( asset_data[0].price_data) portfolio_returns_dict = portfolio_returns.as_dict() assert portfolio_returns_dict['total_return'] > 0
def test_optimize(): data = prep_data.get_data(sample_tickers, '2006-07-01', '2012-08-01', 'monthly') transformed_data, dates = prep_data.transform_yahoo_finance_dict(data) asset_data = prep_data.generate_asset_data_array(transformed_data) matrices = prep_data.AssetMatrices(asset_data) optimizer = optimize.Optimize(matrices, None) results = optimizer.optimize_all() # Test max sharpe test_cases = [ optimizer.equal_weights_results['sharpe_ratio'], *(opt.sharpe_ratio for opt in results if not opt.shorting_ok and opt.goal != optimize.OptimizeGoal.MAX_SHARPE) ] max_sharpe = [ opt.sharpe_ratio for opt in results if not opt.shorting_ok and opt.goal == optimize.OptimizeGoal.MAX_SHARPE ][0] for test_case in test_cases: assert max_sharpe > test_case # Test max returns max_returns = [ opt.returns for opt in results if not opt.shorting_ok and opt.goal == optimize.OptimizeGoal.MAX_RETURNS ][0] idx_of_min_std_dev = np.where( optimizer.asset_matrices.std_dev_vec == optimizer.min_std_dev)[0] assert ~idx_of_min_std_dev returns_of_min_asset = optimizer.asset_matrices.avg_returns_vec[ idx_of_min_std_dev][0] assert max_returns >= returns_of_min_asset # Test min standard deviation min_std_dev = [ opt.std_dev for opt in results if not opt.shorting_ok and opt.goal == optimize.OptimizeGoal.MIN_STD_DEV ][0] idx_of_max_returns = np.where( optimizer.asset_matrices.avg_returns_vec == optimizer.max_returns)[0] assert ~idx_of_max_returns std_dev_of_max_returns_asset = optimizer.asset_matrices.std_dev_vec[ idx_of_max_returns][0] # Add padding, this is due to "greater than" as opposed to "greater than or equal to" logic in the constraint std_dev_of_max_returns_asset = std_dev_of_max_returns_asset + 0.02 assert min_std_dev <= std_dev_of_max_returns_asset
def test_returns(): data = prep_data.get_data(sample_tickers, '2018-05-01', '2019-02-01', 'weekly') transformed_data, dates = prep_data.transform_yahoo_finance_dict(data) asset_data = prep_data.generate_asset_data_array(transformed_data) matrices = prep_data.AssetMatrices(asset_data) optimizer = optimize.Optimize(matrices) results = optimizer.optimize_all() portfolio_returns = results[0].portfolio_returns assert len(portfolio_returns.portfolio_returns) == len( asset_data[0].returns) assert len(portfolio_returns.portfolio_values) == len( asset_data[0].price_data) portfolio_returns_dict = portfolio_returns.as_dict() assert portfolio_returns_dict['total_return'] > 0
def test_matrix_data(): data = prep_data.get_data(sample_tickers, '2012-01-01', '2019-01-01') transformed_data = prep_data.transform_yahoo_finance_dict(data) asset_data = prep_data.generate_asset_data_array(transformed_data) matrices = prep_data.AssetMatrices(asset_data) assert hasattr(matrices, 'correlation_matrix')
def test_generate_asset_data_array(): data = prep_data.get_data(sample_tickers, '2012-01-01', '2019-01-01') transformed_data = prep_data.transform_yahoo_finance_dict(data) asset_data = prep_data.generate_asset_data_array(transformed_data) assert len(asset_data) == len(sample_tickers)