Optimal Portfolios: Short-Selling Constraints


Kevin Crotty
BUSI 448: Investments

Where are we?

Last time:

  • Borrowing frictions

Today:

  • Short-sales constraints

Short-selling constraints

Short-selling constraints

  • Negative investment weights involve short-selling.

  • Each position’s weight is:

\[ w_i = \frac{\text{Value of Position}}{\text{Invested Capital}} \]

  • Some investors cannot or choose not to short sell.

Short-selling and the frontier

Short-sales constraints: Efficient Frontier

##### Frontier problem with short-sale constraints
def frontier(means, cov, target):
    n = len(means)
    Q = matrix(cov, tc="d")
    p = matrix(np.zeros(n), (n, 1), tc="d")
    # Constraint: short-sales not allowed
    G = matrix(-np.identity(n), tc="d")
    h = matrix(np.zeros(n), (n, 1), tc="d")
    # Fully-invested constraint
    A = matrix(np.vstack((np.ones(n), means)), (2, n), tc="d")
    b = matrix([1, target], (2, 1), tc="d")
    sol = Solver(Q, p, G, h, A, b)
    wgts = np.array(sol["x"]).flatten() if sol["status"] == "optimal" else np.array(n * [np.nan])
    return wgts
wgts_frontier = [frontier(mns, cov, m) for m in np.linspace(mns.min(), mns.max(),5)]

Short-sales constraints: GMV

##### GMV problem with short-sale constraints
n = len(mns)
Q = matrix(cov, tc="d")
p = matrix(np.zeros(n), (n, 1), tc="d")
# Constraint: short-sales not allowed
G = matrix(-np.identity(n), tc="d")
h = matrix(np.zeros(n), (n, 1), tc="d")
# Constraint: fully-invested portfolio
A = matrix(np.ones(n), (1, n), tc="d")
b = matrix([1], (1, 1), tc="d")
sol = Solver(Q, p, G, h, A, b)
wgts_gmv = np.array(sol["x"]).flatten() if sol["status"] == "optimal" else np.array(n * [np.nan])

Short-sales constraints: Tangency Portfolio

##### Tangency Portfolio
n = len(mns)
def f(w):
    mn = w @ mns
    sd = np.sqrt(w @ cov @ w)
    return -(mn - r) / sd
# Initial guess (equal-weighted)
w0 = (1/n)*np.ones(n)
# Constraint: fully-invested portfolio
A = np.ones(n)
b = 1
cons = [{"type": "eq", "fun": lambda x: A @ x - b}]
# Short-sale constraint
bnds = [(0, None) for i in range(n)] 
# Optimization
wgts_tangency = minimize(f, w0, bounds=bnds, constraints=cons).x

Learn Investments Dashboard resources

Investment opportunity set with short-sale constraints

Industry portfolios and position constraints

Let’s look at a notebook that constructs frontiers using industry portfolios

  • allowing short selling
  • with short-sales constraints
  • with short-sales constraints and maximum position sizes

For next time: Rebalancing