How Deep (Inside the Book) Is Your Love?
An update to the Bee Gees’ hit using stochastic optimal control
Say we want to liquidate a position of q shares by the end of the trading session T, using only limit orders (so as to limit market impact). What is the optimal depth δ>0 inside the book at which we should place our orders?
That’s the kind of question which can easily be answered using a standard stochastic optimal control framework (see for instance my previous post, as well as my course on Udemy). Let’s first assume that the intensity of the Poisson-type market order flow that can eat through depth δ in the book (s + δ being the limit price of the sell order, s = mid price of the stock) is given by
(We use a power function here for computational ease, but the reasoning below would work for the usual exponentially decreasing function.) Our trader state variables are: his cash amount x, the mid price of the stock s, his inventory q, and time. He needs to maximize his utility function (expected PnL)
Under the standard assumption that the stock’s mid price s follows a diffusion with volatility σ, and assuming that all trades happen in increments of q_0, u can be shown to solve the Hamilton-Jacobi-Bellman problem
We can now make the following Ansatz
so that, to first order (assuming q_0 is small) (3) reduces to:
The optimal δ = δ* at which the sup is achieved in (5) is given by
so that (5) reduces to the first-order Hamilton-Jacobi equation
along with the same boundary conditions as in (5). Let’s look for the solution to (7) in a homogeneous form
Substituting (8) into (7), we find
so that the optimal depth at which to place our limit orders is given by
Let’s plot this optimal depth as a function of time = T - τ (T=1 below) and inventory q:
As we can see, we find that, consistent with our intuition, the optimal depth δ*
is decreasing as a function of inventory: indeed, with a large inventory, we are willing to sacrifice a bit of liquidity premium δ in order to increase the probability of getting filled so as to reduce our inventory
is decreasing in time (increasing w.r.t. τ), since we need to liquidate faster as maturity T approaches.
(Python code below for paying subscribers.)
Quantitatively Yours,
from __future__ import print_function
import numpy as np
import matplotlib.pyplot as plt
DisplayPlots = True
k = 5
c = 0.167
t0 = 0
t1 = 1
T = 300
q0 = 500
q1 = 10000
Q = 100
t_pts = np.linspace(t0,t1,T)
q_pts = np.linspace(q0,q1,Q)
delta = np.zeros((T,Q))
for i in range(T):
for j in range(Q):
tau_val = t1 - t_pts[i]
q_val = q_pts[j]
delta[i,j] = c * (tau_val/q_val)**(1/k)
if DisplayPlots:
t, q = np.meshgrid(t_pts, q_pts)
# Plot the contour
plt.figure()
lvls = 0.01*np.array([0.,1.,2.,3.,4.,5.])
contour_plot = plt.contourf(t, q, delta.T, cmap='coolwarm',levels=lvls)
plt.colorbar(contour_plot, label='depth ($)')
plt.title('optimal depth of order placement', fontsize=14)
plt.xlabel('time', fontsize=14)
plt.ylabel('inventory', fontsize=14)
plt.show()