def test_calculate_portfolio_complete(self): # tickers for testing portfolio calculations in goals endpoint # otherwise, No valid instruments found TickerFactory.create(symbol='IAGG', asset_class=self.bonds_asset_class) TickerFactory.create(symbol='ITOT', asset_class=self.stocks_asset_class) TickerFactory.create(symbol='IPO') fund = TickerFactory.create(symbol='rest') self.portfolio_set.asset_classes.add(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()) account = ClientAccountFactory.create(primary_owner=Fixture1.client1()) # setup some inclusive goal settings goal_settings = GoalSettingFactory.create() # Create a risk score metric for the settings GoalMetricFactory.create(group=goal_settings.metric_group, type=GoalMetric.METRIC_TYPE_RISK_SCORE) goal = GoalFactory.create(account=account, selected_settings=goal_settings, portfolio_set=self.portfolio_set, active_settings=goal_settings) goal_settings.completion_date = timezone.now().date() - timedelta(days=365) serializer = GoalSettingSerializer(goal_settings) url = '/api/v1/goals/{}/calculate-all-portfolios?setting={}'.format(goal.id, json.dumps(serializer.data)) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.client.force_authenticate(user=Fixture1.client1().user) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_calculate_portfolio(self): """ expects the setting parameter to be a json dump of the goal settings to use for the portfolio calculation """ # tickers for testing portfolio calculations in goals endpoint # otherwise, No valid instruments found TickerFactory.create(symbol='IAGG', asset_class=self.bonds_asset_class) TickerFactory.create(symbol='AGG', asset_class=self.bonds_asset_class) TickerFactory.create(symbol='ITOT', asset_class=self.stocks_asset_class) TickerFactory.create(symbol='GRFXX', asset_class=self.stocks_asset_class) TickerFactory.create(symbol='IPO') fund = TickerFactory.create(symbol='rest') self.portfolio_set.asset_classes.add(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()) account = ClientAccountFactory.create(primary_owner=Fixture1.client1()) # setup some inclusive goal settings goal_settings = GoalSettingFactory.create() # Create a risk score metric for the settings GoalMetricFactory.create(group=goal_settings.metric_group, type=GoalMetric.METRIC_TYPE_RISK_SCORE) portfolio_provider = PortfolioProvider( type=constants.PORTFOLIO_PROVIDER_TYPE_KRANE) portfolio_provider.save() goal = GoalFactory.create(account=account, portfolio_provider=portfolio_provider, selected_settings=goal_settings, portfolio_set=self.portfolio_set) serializer = GoalSettingSerializer(goal_settings) url = '/api/v1/goals/{}/calculate-portfolio?setting={}'.format( goal.id, json.dumps(serializer.data)) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.client.force_authenticate(user=Fixture1.client1().user) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK)
def create_settings(plan): """ Creates some settings that can be used to create a real retirement goal if desired. :param plan: The retirement plan to create settings for. :return: A GoalSetting object that has been saved in the database. The caller needs to destroy it if it is no longer required :raises Unsatisfiable if no suitable portfolio could be found for the plan. """ metric_group = GoalMetricGroup.objects.create(type=GoalMetricGroup.TYPE_CUSTOM) settings = GoalSetting.objects.create( target=0, completion=timezone.now().date(), hedge_fx=False, metric_group=metric_group, ) risk_metric = GoalMetric.objects.create(group=metric_group, type=GoalMetric.METRIC_TYPE_RISK_SCORE, comparison=GoalMetric.METRIC_COMPARISON_EXACTLY, rebalance_type=GoalMetric.REBALANCE_TYPE_ABSOLUTE, rebalance_thr=0.05, configured_val=plan.desired_risk) # Create a mock goal so we can call calculate_portfolio class MockGoal(object): portfolio_set = plan.client.advisor.default_portfolio_set id = 0 available_balance = 100000 current_balance = 100000 def __str__(self): return "Retiresmartz calculation Goal for plan: {}".format(plan) # Create a dummy settings object for the calculation. # We need to do this because we are using a fake goal, as we don't have a real goal yet. settings_data = GoalSettingSerializer(instance=settings).data calc_settings = GoalSettingStatelessSerializer.create_stateless(settings_data, MockGoal()) data_provider = DataProviderDjango() idata = get_instruments(data_provider) weights, er, stdev = calculate_portfolio( settings=calc_settings, idata=idata, data_provider=data_provider, execution_provider=ExecutionProviderDjango() ) portfolio = Portfolio.objects.create( setting=settings, stdev=stdev, er=er, ) items = [PortfolioItem(portfolio=portfolio, asset=Ticker.objects.get(id=tid), weight=weight, volatility=idata[0].loc[tid, tid]) for tid, weight in weights.items()] PortfolioItem.objects.bulk_create(items) return settings