示例#1
0
    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 = pd.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(
                time_locator(self.return_forecast, t, as_numpy=True), 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_entries(z) == 0] + constraints)

        self.prob.solve(solver=self.solver, **self.solver_opts)

        logging.error(
            f'The problem is {self.prob.status}. Defaulting to no trades')
        return self._nulltrade(portfolio)

        return pd.Series(index=portfolio.index, data=(z.value.A1 * value))
示例#2
0
    def get_trades(self, portfolio, t=pd.datetime.today()):
        prediction = time_locator(self.return_forecast, t, as_numpy=False)
        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
示例#3
0
 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) / time_locator(prices, t))[:-1]