Minimum trade size

185 views
Skip to first unread message

Steven Wong

unread,
May 17, 2021, 8:10:38 PM5/17/21
to cvxpy
Hi all,

I'm trying to replicate some of the suggestions of this paper. On page 40-41, it's made the following suggestion when it comes to enforcing a minimum trade size:

As a simple example of this approach, consider the minimum nonzero trade requirement $|(z_t)_i| \ge \epsilon$ for $(z_t)i \neq 0$. We first solve the SPO problem without this  constraint, finding a solution $\tilde{z}$. We use this tentative trade vector to determine which entries of $z$ will be zero, negative, or positive (i.e., which assets we hold, sell, or buy). We now impose these sign constraints on the trade vector: We require $(z_t)_i = 0$ if $(\tilde{z}_t)_i = 0$, $(z_t)_i \ge 0$ if $(\tilde{z}_t)_i > 0$, and $(z_t)_i \le 0$ if $(\tilde{z}_t)_i < 0$. We solve the SPO again, with these sign constraints, and the minimum trade constraints as well, which are now linear, and therefore convex.

(excuse the latex notations)

In this context, z is the trade vector. When it's time for the second pass, how do you constrain on z being larger than a certain value? The reason I'm asking is that let's say the smallest positive trade in the first pass is 0.01. If the minimum trade is 0.05, this value will most likely drop to 0 (and the average value of all the other positive entries slightly higher). So I can't use u[u_bar > 0] >= min_trade.

A minimal example below (I'm using u instead of z).

import cvxpy as cp
import numpy as np

x = np.random.normal(0., 1., size=(100, 1))
u = cp.Variable((100, 1))
S = np.random.rand(100, 100)
S = np.dot(S, S.T)

prob = cp.Problem(cp.Maximize(x.T @ u - 0.1 * cp.quad_form(u, S)),
    [cp.sum(u) == 1.,
     cp.abs(u) <= 0.1])

prob.solve()

# try again with non-zero
u_bar = u.value.copy()

min_trade = 0.05
prob = cp.Problem(cp.Maximize(x.T @ u - 0.1 * cp.quad_form(u, S)),
    [cp.sum(u) == 1.,
     cp.abs(u) <= 0.1,
     u[u_bar > 0] >= 0.,
     u[u_bar == 0] == 0.,
     u[u_bar < 0] <= 0,
     % how do you constrain u to be abs(u) >= min_trade?)
prob.solve()

Cheers,
Steve

Steven Diamond

unread,
May 17, 2021, 10:44:05 PM5/17/21
to cvxpy
This is a good question. I think the paper may be in error. The heuristic here would be to set $(z_t)_i = 0$ if $|(\tilde{z}_t)_i| \leq \eps$. In other words, if you have a trade below the minimum trade size, you fix it to be zero. All other trades you fix to be above the minimum trade size, positive or negative as appropriate. I don't see any other approach that would be convex.

Steven Wong

unread,
May 17, 2021, 11:18:26 PM5/17/21
to cvxpy
Thanks Steven for the quick response. Just curious, what are the consequences on optimality when we do this? I can envisage a case where let's say minimum trade size is 0.01%. There are 10 trades at 0.001%. Using this heuristic, we will nullify all 10 trades but it could be that its more optimal to proxy the 10x 0.001% trades by 1x 0.01% of the best trade within the set? 

Steven Diamond

unread,
May 20, 2021, 1:29:21 AM5/20/21
to cvxpy
The sub-optimality will vary across problems, you can check it by solving the mixed-integer version. One way to do this is create a binary variable b_i for each trade z_i. Then add the constraints

z_i >= b_i*min trade size
z_i <= b_i*max trade size

so the trade is either 0 or in the desired range. You can add more variables to handle negative trades.
Reply all
Reply to author
Forward
0 new messages