Exemplo n.º 1
0
    def calculate_portfolio_for_selected(self):
        from portfolios.providers.data.django import DataProviderDjango
        from portfolios.providers.execution.django import ExecutionProviderDjango
        from portfolios.calculation import Unsatisfiable, calculate_portfolio, get_instruments

        data_provider = DataProviderDjango()
        execution_provider = ExecutionProviderDjango()
        idata = get_instruments(data_provider)
        try:
            weights, er, stdev = calculate_portfolio(self.selected_settings,
                                                     data_provider,
                                                     execution_provider, True,
                                                     idata)
            portfolio = Portfolio.objects.create(
                setting=self.selected_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.iteritems()
            ]
            PortfolioItem.objects.bulk_create(items)
        except Unsatisfiable:
            # We detect when loading a goal in the allocation screen if there has been no portfolio created
            # and return a message to the user. It it perfectly reasonable for a goal to be created without a
            # portfolio.
            logger.exception(
                "No suitable portfolio could be found. Leaving empty.")
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    def calculate_portfolio(self, request, pk=None, **kwargs):
        """
        Called to calculate a portfolio object for a set of supplied settings.
        """
        goal = self.get_object()

        check_state(Goal.State(goal.state),
                    [Goal.State.ACTIVE, Goal.State.INACTIVE])

        setting_str = request.query_params.get('setting', None)
        if not setting_str:
            raise ValidationError(
                "Query parameter 'setting' must be specified and a valid JSON string"
            )
        try:
            setting = ujson.loads(setting_str)
        except ValueError:
            raise ValidationError(
                "Query parameter 'setting' must be a valid json string")

        # Create the settings object from the dict
        serializer = serializers.GoalSettingStatelessSerializer(data=setting)
        serializer.is_valid(raise_exception=True)
        settings = serializer.create_stateless(serializer.validated_data, goal)

        try:
            data = self.build_portfolio_data(
                calculate_portfolio(
                    settings=settings,
                    data_provider=DataProviderDjango(),
                    execution_provider=ExecutionProviderDjango()))
            return Response(data)
        except Unsatisfiable as e:
            rdata = {'reason': "No portfolio could be found: {}".format(e)}
            if e.req_funds is not None:
                rdata['req_funds'] = e.req_funds

            return Response({'error': rdata},
                            status=status.HTTP_400_BAD_REQUEST)
 def test_calculate_portfolio(self):
     goal1 = Fixture1.goal1()
     goal1.portfolio_set.asset_classes = [
         AssetClass.objects.get(name="US_BONDS"),
         AssetClass.objects.get(name="AU_STOCKS"),
         AssetClass.objects.get(name="AU_STOCK_MUTUALS")
     ]
     goal1.selected_settings.metric_group.metrics = [GoalMetric.objects.create(group=Fixture1.metric_group1(),
                                                                               type=GoalMetric.METRIC_TYPE_RISK_SCORE,
                                                                               rebalance_type="1",
                                                                               configured_val=0.0,
                                                                               comparison=2,
                                                                               rebalance_thr=0.05)
                                                    ]
     goal1.selected_settings.SYSTEM_CURRENCY = 'USD'
     goal1.cash_balance = 1000
     idata = get_instruments(self._data_provider)
     portfolio, er, var = calculate_portfolio(settings=goal1.selected_settings,
                                              data_provider=self._data_provider,
                                              execution_provider=self._execution_provider,
                                              idata=idata)
     self.assertEqual(len(portfolio), 4)
Exemplo n.º 5
0
    def test_backtest(self):
        setup = TestSetup()

        # actually tickers are created here - we need to set proper asset class for each ticker
        self.create_goal()

        setup.create_goal(self.goal)
        setup.data_provider.initialize_tickers()
        setup.data_provider.move_date_forward()

        backtester = Backtester()

        print("backtesting " + str(setup.data_provider.get_current_date()))
        build_instruments(setup.data_provider)

        # optimization fails due to
        portfolios_stats = calculate_portfolios(
            setting=setup.goal.selected_settings,
            data_provider=setup.data_provider,
            execution_provider=setup.execution_provider)
        portfolio_stats = calculate_portfolio(
            settings=setup.goal.selected_settings,
            data_provider=setup.data_provider,
            execution_provider=setup.execution_provider)

        weights, instruments, reason = rebalance(
            idata=get_instruments(setup.data_provider),
            goal=setup.goal,
            data_provider=setup.data_provider,
            execution_provider=setup.execution_provider)

        new_positions = build_positions(setup.goal, weights, instruments)

        # create sell requests first
        mor, requests = create_request(
            setup.goal,
            new_positions,
            reason,
            execution_provider=setup.execution_provider,
            data_provider=setup.data_provider,
            allowed_side=-1)
        # process sells
        backtester.execute(mor)

        # now create buys - but only use cash to finance proceeds of buys
        mor, requests = create_request(
            setup.goal,
            new_positions,
            reason,
            execution_provider=setup.execution_provider,
            data_provider=setup.data_provider,
            allowed_side=1)

        backtester.execute(mor)

        transaction_cost = np.sum([abs(r.volume) for r in requests]) * 0.005
        # So, the rebalance could not be in place if the excecution algo might not determine how much it will cost to rebalance.

        # this does not work - make it work with Django execution provider - use EtnaOrders
        #performance = backtester.calculate_performance(execution_provider=setup.execution_provider)

        self.assertTrue(True)
Exemplo n.º 6
0
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
Exemplo n.º 7
0
        '''

        # execute orders from yesterday
        backtester.place_order(settings=setup.goal,
                               order=requests,
                               data_provider=setup.data_provider,
                               execution_provider=setup.execution_provider)
        '''

        # calculate current portfolio stats
        portfolios_stats = calculate_portfolios(
            setting=setup.goal.active_settings,
            data_provider=setup.data_provider,
            execution_provider=setup.execution_provider)
        portfolio_stats = calculate_portfolio(
            settings=setup.goal.active_settings,
            data_provider=setup.data_provider,
            execution_provider=setup.execution_provider)

        # generate orders for tomorrow
        #try:
        requests = rebalance(idata=get_instruments(setup.data_provider),
                             goal=setup.goal,
                             data_provider=setup.data_provider,
                             execution_provider=setup.execution_provider)
        #except:
        #    print("reblance not succesful")
        #    requests = [setup.execution_provider.create_empty_market_order()]

        backtester.execute_order(settings=setup.goal,
                                 order=requests,
                                 data_provider=setup.data_provider,
Exemplo n.º 8
0
    def create(self, validated_data):
        """
        Override the default create because we need to generate a portfolio.
        :param validated_data:
        :return: The created Goal
        """
        account = validated_data['account']

        data_provider = DataProviderDjango()
        execution_provider = ExecutionProviderDjango()
        idata = get_instruments(data_provider)

        with transaction.atomic():
            metric_group = GoalMetricGroup.objects.create(
                type=GoalMetricGroup.TYPE_CUSTOM)
            settings = GoalSetting.objects.create(
                target=validated_data['target'],
                completion=validated_data['completion'],
                hedge_fx=False,
                metric_group=metric_group,
            )

            portfolio_provider_id = validated_data[
                'portfolio_provider'] if 'portfolio_provider' in validated_data else get_default_provider_id(
                )

            portfolio_set_id = ''
            portfolio_providers = PortfolioProvider.objects.all()
            portfolio_provider = get_default_provider()
            for pp in portfolio_providers:
                if pp.id == portfolio_provider_id:
                    portfolio_provider = pp

            if portfolio_provider.type == constants.PORTFOLIO_PROVIDER_TYPE_KRANE:
                portfolio_set_type = constants.PORTFOLIO_SET_TYPE_KRANE
            elif portfolio_provider.type == constants.PORTFOLIO_PROVIDER_TYPE_AON:
                portfolio_set_type = constants.PORTFOLIO_SET_TYPE_AON
            elif portfolio_provider.type == constants.PORTFOLIO_PROVIDER_TYPE_LEE:
                portfolio_set_type = constants.PORTFOLIO_SET_TYPE_LEE
            else:
                raise Exception('unhandled portfolio_provider_id')

            portfolio_sets = PortfolioSet.objects.all()
            portfolio_set = account.default_portfolio_set
            for ps in portfolio_sets:
                if ps.type == portfolio_set_type:
                    portfolio_set = ps

            goal = Goal.objects.create(
                account=account,
                name=validated_data['name'],
                type=validated_data['type'],
                portfolio_set=portfolio_set,
                portfolio_provider=portfolio_provider,
                selected_settings=settings,
            )
            # Based on the risk profile, and whether an ethical profile was specified on creation, set up Metrics.
            recommended_risk = recommend_risk(settings)
            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=recommended_risk)
            if validated_data['ethical']:
                GoalMetric.objects.create(
                    group=metric_group,
                    type=GoalMetric.METRIC_TYPE_PORTFOLIO_MIX,
                    feature=AssetFeatureValue.Standard.SRI_OTHER.get_object(),
                    comparison=GoalMetric.METRIC_COMPARISON_EXACTLY,
                    rebalance_type=GoalMetric.REBALANCE_TYPE_ABSOLUTE,
                    rebalance_thr=0.05,
                    configured_val=1  # Start with 100% ethical.
                )

            # Make sure the risk score assigned is appropriate for the goal.
            try:
                validate_risk_score(settings)
            except CVE as verr:
                raise ValidationError(verr.message)

            # Add the initial deposit if specified.
            initial_dep = validated_data.pop('initial_deposit', None)
            if initial_dep is not None:
                Transaction.objects.create(reason=Transaction.REASON_DEPOSIT,
                                           to_goal=goal,
                                           amount=initial_dep)

            # Calculate the optimised portfolio
            try:
                weights, er, stdev = calculate_portfolio(
                    settings, data_provider, execution_provider, True, idata)
                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.iteritems()
                ]
                PortfolioItem.objects.bulk_create(items)
            except Unsatisfiable:
                # We detect when loading a goal in the allocation screen if there has been no portfolio created
                # and return a message to the user. It it perfectly reasonable for a goal to be created without a
                # portfolio.
                logger.exception(
                    "No suitable portfolio could be found. Leaving empty.")

        return goal