def __init__(self): self._covars = self._samples = self._instruments = self._masks = None self.data_provider = DataProviderBacktest(sliding_window_length=250 * 5, dir='/backtesting/') self.execution_provider = ExecutionProviderDjango() MarkowitzScaleFactory.create() self.data_provider.get_goals() self.goal = None
def setUp(self): self.t1 = TickerFactory.create(symbol='SPY', unit_price=5) self.t2 = TickerFactory.create(symbol='VEA', unit_price=5) self.t3 = TickerFactory.create(symbol='TIP', unit_price=100) self.t4 = TickerFactory.create(symbol='IEV', unit_price=100) self.t5 = TickerFactory.create(symbol='IEV2', unit_price=100, asset_class=self.t4.asset_class) self.equity = AssetFeatureValueFactory.create( name='equity', assets=[self.t1, self.t2]) self.bond = AssetFeatureValueFactory.create(name='bond', assets=[self.t3, self.t4]) self.goal_settings = GoalSettingFactory.create() asset_classes = [ self.t1.asset_class, self.t2.asset_class, self.t3.asset_class, self.t4.asset_class ] portfolio_set = PortfolioSetFactory.create(name='set', risk_free_rate=0.01, asset_classes=asset_classes) self.goal = GoalFactory.create(approved_settings=self.goal_settings, active_settings=self.goal_settings, cash_balance=100, portfolio_set=portfolio_set) self.tickers = [self.t1, self.t2, self.t3, self.t4, self.t4] self.prices = [4, 4, 90, 90, 95] self.quantities = [5, 5, 5, 5, 5] self.executed = [ date(2015, 1, 1), date(2016, 1, 1), date(2015, 1, 1), date(2016, 1, 1), date(2016, 1, 1) ] self.execution_details = [] for i in range(5): execution = Fixture1.create_execution_details( self.goal, self.tickers[i], self.quantities[i], self.prices[i], self.executed[i]) self.execution_details.append(execution) self.data_provider = DataProviderDjango(mocked_now.date()) self.execution_provider = ExecutionProviderDjango() MarkowitzScaleFactory.create() self.setup_performance_history() self.idata = get_instruments(self.data_provider) self.portfolio = PortfolioFactory.create(setting=self.goal_settings) self.current_weights = get_held_weights(self.goal)
def setUp(self): self.t1 = TickerFactory.create(symbol='SPY', unit_price=5) self.t2 = TickerFactory.create(symbol='VEA', unit_price=5) self.t3 = TickerFactory.create(symbol='TIP', unit_price=100) self.t4 = TickerFactory.create(symbol='IEV', unit_price=100) self.equity = AssetFeatureValueFactory.create( name='equity', assets=[self.t1, self.t2]) self.bond = AssetFeatureValueFactory.create(name='bond', assets=[self.t3, self.t4]) self.goal_settings = GoalSettingFactory.create() asset_classes = [ self.t1.asset_class, self.t2.asset_class, self.t3.asset_class, self.t4.asset_class ] portfolio_set = PortfolioSetFactory.create(name='set', risk_free_rate=0.01, asset_classes=asset_classes) self.goal = GoalFactory.create(approved_settings=self.goal_settings, cash_balance=100, portfolio_set=portfolio_set) Fixture1.create_execution_details(self.goal, self.t1, 5, 4, date(2016, 1, 1)) Fixture1.create_execution_details(self.goal, self.t2, 5, 4, date(2016, 1, 1)) Fixture1.create_execution_details(self.goal, self.t3, 5, 90, date(2016, 1, 1)) Fixture1.create_execution_details(self.goal, self.t4, 5, 90, date(2016, 1, 1)) Fixture1.create_execution_details(self.goal, self.t4, 5, 90, date(2016, 1, 1)) self.data_provider = DataProviderDjango() self.execution_provider = ExecutionProviderDjango() MarkowitzScaleFactory.create() self.setup_performance_history() self.idata = get_instruments(self.data_provider)
def test_calculate_portfolio_old(self): fund0 = TickerFactory.create(symbol='IAGG') fund1 = TickerFactory.create(symbol='ITOT') fund5 = TickerFactory.create(symbol='GRFXX') fund2 = TickerFactory.create(symbol='VEA') fund0 = TickerFactory.create(symbol='IPO') fund3 = TickerFactory.create(symbol='EEM') fund4 = TickerFactory.create(symbol='AGG') AssetFeatureValueFactory.create( assets=[fund1, fund2, fund3, fund4, fund5]) ps1 = PortfolioSetFactory \ .create(asset_classes=[fund1.asset_class, fund2.asset_class, fund3.asset_class, fund4.asset_class, fund5.asset_class]) # Create a settings object with a metric for a feature with no instruments in the current portfolio set. feature = AssetFeatureValueFactory.create() settings = GoalSettingFactory.create() risk_metric = GoalMetricFactory.create(group=settings.metric_group) mix_metric = GoalMetricFactory.create( group=settings.metric_group, type=GoalMetric.METRIC_TYPE_PORTFOLIO_MIX, feature=feature, comparison=GoalMetric.METRIC_COMPARISON_MAXIMUM, configured_val=.3) goal = GoalFactory.create(selected_settings=settings, portfolio_set=ps1) # The below fund has the desired feature, but is not in the goal's portfolio set. feature.assets.add(fund1) # Create some instrument data for the two assets self.m_scale = MarkowitzScaleFactory.create() # populate the data needed for the prediction # We need at least 500 days as the cycles go up to 70 days and we need at least 7 cycles. populate_prices(500, asof=mocked_now.date()) populate_cycle_obs(500, asof=mocked_now.date()) populate_cycle_prediction(asof=mocked_now.date()) data_provider = DataProviderDjango() execution_provider = ExecutionProviderDjango() idata = build_instruments(data_provider) result = calculate_portfolio_old(settings=settings, data_provider=data_provider, execution_provider=execution_provider, idata=idata) self.assertTrue(True)
def test_calculate_portfolio(self): # TODO # constraints -> limit them -> maximum minimum value of 5%, maximum max value of 95% asset_class1 = AssetClassFactory.create(name='US_TOTAL_BOND_MARKET') asset_class2 = AssetClassFactory.create(name='HEDGE_FUNDS') fund0 = TickerFactory.create(symbol='IAGG', asset_class=asset_class1) fund0 = TickerFactory.create(symbol='GRFXX', asset_class=asset_class1) fund1 = TickerFactory.create(symbol='ITOT', asset_class=asset_class2) fund0 = TickerFactory.create(symbol='IPO') fund0 = TickerFactory.create(symbol='AGG', asset_class=asset_class1) fund6 = TickerFactory.create(symbol='rest') ps1 = PortfolioSetFactory \ .create(asset_classes=[asset_class1, asset_class2, fund6.asset_class]) feature = AssetFeatureValueFactory.create() feature.assets.add(fund6) settings = GoalSettingFactory.create() risk_metric = GoalMetricFactory.create( group=settings.metric_group, type=GoalMetric.METRIC_TYPE_RISK_SCORE) mix_metric = GoalMetricFactory.create( group=settings.metric_group, type=GoalMetric.METRIC_TYPE_PORTFOLIO_MIX, feature=feature, comparison=GoalMetric.METRIC_COMPARISON_MINIMUM, configured_val=0.5) goal = GoalFactory.create(selected_settings=settings, portfolio_set=ps1) # Create some instrument data for the two assets self.m_scale = MarkowitzScaleFactory.create() populate_prices(500, asof=mocked_now.date()) populate_cycle_obs(500, asof=mocked_now.date()) populate_cycle_prediction(asof=mocked_now.date()) data_provider = DataProviderDjango() execution_provider = ExecutionProviderDjango() idata = build_instruments(data_provider) result = calculate_portfolio(settings=settings, data_provider=data_provider, execution_provider=execution_provider, idata=idata) self.assertTrue(True)
def test_calc_opt_inputs_no_assets_for_constraint(self): """ Makes sure when we have no assets filling a constraint, we behave appropriately. """ # This fund has a different feature to the one in the mix metric, but it is in the correct portfolio set. fund1 = TickerFactory.create() AssetFeatureValueFactory.create(assets=[fund1]) ps1 = PortfolioSetFactory.create(asset_classes=[fund1.asset_class]) # Create a settings object with a metric for a feature with no instruments in the current portfolio set. feature = AssetFeatureValueFactory.create() settings = GoalSettingFactory.create() risk_metric = GoalMetricFactory.create(group=settings.metric_group) mix_metric = GoalMetricFactory.create( group=settings.metric_group, type=GoalMetric.METRIC_TYPE_PORTFOLIO_MIX, feature=feature, comparison=GoalMetric.METRIC_COMPARISON_MAXIMUM, configured_val=.3) goal = GoalFactory.create(selected_settings=settings, portfolio_set=ps1) # The below fund has the desired feature, but is not in the goal's portfolio set. fund2 = TickerFactory.create() feature.assets.add(fund2) # Create some instrument data for the two assets self.m_scale = MarkowitzScaleFactory.create() # populate the data needed for the prediction # We need at least 500 days as the cycles go up to 70 days and we need at least 7 cycles. populate_prices(500, asof=mocked_now.date()) populate_cycle_obs(500, asof=mocked_now.date()) populate_cycle_prediction(asof=mocked_now.date()) data_provider = DataProviderDjango() idata = build_instruments(data_provider) execution_provider = ExecutionProviderDjango() # Get the opt inputs, there should be no constraint for the max for the feature with no funds. result = calc_opt_inputs(settings=settings, idata=idata, data_provider=data_provider, execution_provider=execution_provider) xs, lam, constraints, settings_instruments, settings_symbol_ixs, lcovars = result self.assertEqual(len(constraints), 3) # All positive, and sum to 1 # Then create a fund in the portfolio I want. We should get a constraint for the maximum for the feature. fund3 = TickerFactory.create(asset_class=fund1.asset_class) feature.assets.add(fund3) delete_data() populate_prices(500, asof=mocked_now.date()) populate_cycle_obs(500, asof=mocked_now.date()) populate_cycle_prediction(asof=mocked_now.date()) idata = build_instruments(data_provider) result = calc_opt_inputs(settings=settings, idata=idata, data_provider=data_provider, execution_provider=execution_provider) xs, lam, constraints, settings_instruments, settings_symbol_ixs, lcovars = result self.assertEqual(len(constraints), 4) # All positive, sum to 1, and the max constraint
def test_retirement_plan_calculate(self): plan = RetirementPlanFactory.create(income=100000, desired_income=81000, btc=4000, retirement_home_price=250000, paid_days=1, retirement_age=67, selected_life_expectancy=85) # some tickers for portfolio bonds_asset_class = AssetClassFactory.create( name='US_TOTAL_BOND_MARKET') stocks_asset_class = AssetClassFactory.create(name='HEDGE_FUNDS') TickerFactory.create(symbol='IAGG', asset_class=bonds_asset_class) TickerFactory.create(symbol='ITOT', asset_class=stocks_asset_class) TickerFactory.create(symbol='IPO') fund = TickerFactory.create(symbol='rest') # Add the asset classes to the advisor's default portfolio set plan.client.advisor.default_portfolio_set.asset_classes.add( bonds_asset_class, stocks_asset_class, fund.asset_class) # Set the markowitz bounds for today self.m_scale = MarkowitzScaleFactory.create() # populate the data needed for the optimisation # We need at least 500 days as the cycles go up to 70 days and we need at least 7 cycles. populate_prices(500, asof=mocked_now.date()) populate_cycle_obs(500, asof=mocked_now.date()) populate_cycle_prediction(asof=mocked_now.date()) populate_inflation(asof=mocked_now.date()) self.assertIsNone(plan.goal_setting) old_settings = GoalSetting.objects.all().count() old_mgroups = GoalMetricGroup.objects.all().count() old_metrics = GoalMetric.objects.all().count() url = '/api/v1/clients/{}/retirement-plans/{}/calculate'.format( plan.client.id, plan.id) self.client.force_authenticate(user=plan.client.user) # First try and calculate without a client date of birth. Make sure we get the correct 400 old_dob = plan.client.date_of_birth plan.client.date_of_birth = None plan.client.save() response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) # Now set the date of birth plan.client.date_of_birth = old_dob plan.client.save() # We should be ready to calculate properly response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue('portfolio' in response.data) self.assertTrue('projection' in response.data) self.assertEqual(len(response.data['projection']), 50) # Make sure the goal_setting is now populated. plan.refresh_from_db() self.assertIsNotNone(plan.goal_setting.portfolio) self.assertEqual(old_settings + 1, GoalSetting.objects.all().count()) self.assertEqual(old_mgroups + 1, GoalMetricGroup.objects.all().count()) self.assertEqual(old_metrics + 1, GoalMetric.objects.all().count()) old_id = plan.goal_setting.id # Recalculate and make sure the number of settings, metric groups and metrics in the system is the same # Also make sure the setting object is different response = self.client.get(url) plan.refresh_from_db() self.assertEqual(old_settings + 1, GoalSetting.objects.all().count()) self.assertEqual(old_mgroups + 1, GoalMetricGroup.objects.all().count()) self.assertEqual(old_metrics + 1, GoalMetric.objects.all().count()) self.assertNotEqual(old_id, plan.goal_setting.id)