def get_trades(self, portfolio, t=dt.datetime.today()): prediction = values_in_time(self.return_forecast, t) sorted_ret = prediction.sort_values() short_trades = sorted_ret.index[:self.num_short] long_trades = sorted_ret.index[-self.num_long:] u = pd.Series(0., index=prediction.index) u[short_trades] = -1. u[long_trades] = 1. u /= sum(abs(u)) u = sum(portfolio) * u * self.target_turnover # import pdb; pdb.set_trace() # # # ex-post cash neutrality # old_cash = portfolio[-1] # if old_cash > 0: # u[short] = u[short] + old_cash/self.num_short # else: # u[long] = u[long] + old_cash/self.num_long return u
def get_rounded_trades(self, portfolio, prices, t): """Get trades vector as number of shares, rounded to integers.""" return np.round( self.get_trades(portfolio, t) / values_in_time(prices, t))[:-1]
def get_trades(self, portfolio, t=None): """ Get optimal trade vector for given portfolio at time t. Parameters ---------- portfolio : pd.Series Current portfolio vector. t : pd.timestamp Timestamp for the optimization. """ if t is None: t = dt.datetime.today() value = sum(portfolio) w = portfolio / value z = cvx.Variable(w.size) # TODO pass index wplus = w.values + z if isinstance(self.return_forecast, BaseReturnsModel): alpha_term = self.return_forecast.weight_expr(t, wplus) else: alpha_term = cvx.sum( cvx.multiply( values_in_time(self.return_forecast, t).values, wplus)) assert (alpha_term.is_concave()) costs, constraints = [], [] for cost in self.costs: cost_expr, const_expr = cost.weight_expr(t, wplus, z, value) costs.append(cost_expr) constraints += const_expr constraints += [ item for item in (con.weight_expr(t, wplus, z, value) for con in self.constraints) ] for el in costs: assert (el.is_convex()) for el in constraints: assert (el.is_dcp()) self.prob = cvx.Problem(cvx.Maximize(alpha_term - sum(costs)), [cvx.sum(z) == 0] + constraints) try: self.prob.solve(solver=self.solver, **self.solver_opts) if self.prob.status == 'unbounded': logging.error( 'The problem is unbounded. Defaulting to no trades') return self._nulltrade(portfolio) if self.prob.status == 'infeasible': logging.error( 'The problem is infeasible. Defaulting to no trades') return self._nulltrade(portfolio) return pd.Series(index=portfolio.index, data=(z.value * value)) except (cvx.SolverError, TypeError): logging.error('The solver %s failed. Defaulting to no trades' % self.solver) return self._nulltrade(portfolio)