def handle(self, *args, **options): # calculate portfolios data_provider = DataProviderDjango() exec_provider = ExecutionProviderDjango() for goal in Goal.objects.all(): if goal.selected_settings is not None: try: calculate_portfolios(setting=goal.selected_settings, data_provider=data_provider, execution_provider=exec_provider) except Unsatisfiable as e: logger.warn(e)
def calculate_all_portfolios(self, request, pk=None, **kwargs): """ Called to calculate all the portfolio objects for 100 different risk scores for the supplied settings. """ goal = self.get_object() check_state(Goal.State(goal.state), Goal.State.ACTIVE) setting_str = request.query_params.get('setting', None) if not setting_str: logger.debug( 'setting parameter missing from calculate_all_portfolios query' ) raise ValidationError( "Query parameter 'setting' must be specified and a valid JSON string" ) try: setting = ujson.loads(setting_str) except ValueError: logger.debug( 'setting parameter for calculate_all_portfolios query not valid json' ) raise ValidationError( "Query parameter 'setting' must be a valid json string") # Create the settings from the dict serializer = serializers.GoalSettingStatelessSerializer(data=setting) serializer.is_valid(raise_exception=True) settings = serializer.create_stateless(serializer.validated_data, goal) # Calculate the portfolio try: data_provider = DataProviderDjango() execution_provider = ExecutionProviderDjango() data = [ self.build_portfolio_data(item[1], item[0]) for item in calculate_portfolios(setting=settings, data_provider=data_provider, execution_provider=execution_provider) ] 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 get(self, request, *args, **kwargs): portfolio_set = Goal().portfolio_set goal_pk = kwargs.get("goal_pk", None) if goal_pk: try: goal = Goal.objects.get(pk=goal_pk, account__primary_owner=self.client) except ObjectDoesNotExist: goal = None if goal: if goal.is_custom_size: if goal.portfolios in [None, "{}", "[]", ""]: try: portfolios = calculate_portfolios(goal) goal.portfolios = ujson.dumps(portfolios, double_precision=2) goal.save() except OptimizationException: goal.custom_regions = None goal.save() portfolios = ujson.loads(goal.portfolio_set.portfolios) else: portfolios = ujson.loads(goal.portfolios) else: portfolios = ujson.loads(goal.portfolio_set.portfolios) ret = [] for k in portfolios: new_pr = { "risk": int(100 * portfolios[k]["risk"]) / 100, "expectedReturn": portfolios[k]["expectedReturn"], "volatility": portfolios[k]["volatility"], 'allocations': portfolios[k]["allocations"] } ret.append(new_pr) return HttpResponse(ujson.dumps(ret), content_type="application/json") ret = [] portfolios = ujson.loads(portfolio_set.portfolios) for k in portfolios: new_pr = { "risk": int(100 * portfolios[k]["risk"]) / 100, "expectedReturn": portfolios[k]["expectedReturn"], "volatility": portfolios[k]["volatility"], 'allocations': portfolios[k]["allocations"] } ret.append(new_pr) return HttpResponse(ujson.dumps(ret), content_type="application/json")
def test_calculate_portfolios(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 portfolio = Portfolio.objects.create(id=1, er=1, stdev=2, setting=goal1.selected_settings) PortfolioItem.objects.create(asset=Ticker.objects.get(symbol='ASS'), portfolio=portfolio, weight=0.1, volatility=0.2) portfolios = calculate_portfolios(goal1.selected_settings, data_provider=self._data_provider, execution_provider=self._execution_provider) self.assertEqual(len(portfolios), 101)
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)
while setup.data_provider.move_date_forward(): print("backtesting " + str(setup.data_provider.get_current_date())) build_instruments(setup.data_provider) ''' # 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()]