Introduction

Mean reversion trading can be as simple as forecasting the level (or spread) we want to trade, and allocating relative to the forecast, i.e., in the simple case of an AR(1) model (or Ornstein-Uhlenbeck process), we have a model such as \[ \Delta p_{t+1} = \alpha + \beta p_{t} + \epsilon_t \] where \(p_t\) is the price level (or spread) at time \(t\) and \(\Delta p_{t+1} \equiv p_{t+1} - p_{t}\), is the backward differences, \(\alpha\) is the long-term mean, \(\beta\) is the autoregressive coefficient, and \(\epsilon_t\) is a white noise error term (although we may have other terms in the model, such as a trend, or a seasonal, or some AR terms to capture the short-run dynamics).

In such a model, if we recast it as

\[\Delta p_{t+1} = \beta (p_{t} -\mu) + \epsilon_t,\]

where \(\mu = -\frac{\alpha}{\beta}\), we can see that the model is mean-reverting if \(-2<\beta <0\), and it mean reverts to the long-run level \(\mu\), with the speed of mean reversion \(\beta \).

With this model we can forecast the level as:

\[\hat{p}_{t+1} = \hat{\alpha} + (1+\hat{\beta}) p_{t},\]

where \(\hat{\alpha}\) and \(\hat{\beta}\) are the estimated coefficients from the model, (i.e., they are just found via the OLS regression of \(\Delta p_{t+1}\) on \(p_{t}\)). As we mentioned, we could have also considered adding more AR terms, or a trend or a seasonal component.

No matter how complex the model, it is possible to forecast one (as we have done above) or more periods ahead, by recursively applying the model or “bootstrapping” the forecast. We note however that forecast quality often deteriorates as we forecast further ahead.

Optimal Trading Strategies

In all of our discussions, we will assume that returns \(R_{t+1} = p_{t+1} - p_{t}\) are just the PnL of the underlying asset. We could have assumed that they were log-returns, returns, etc. It matters most in how we describe or scale our holdings since in the end whatever strategy we come up with should have PnL denominated in USD.

We define a strategy as a set of rules that determines how we allocate at time \(t\) given our forecast of the level (or spread) for time \(t+1\). A (self-financing)strategy will have a PnL at time \(T\) of:

\[\begin{eqnarray} PnL_T &=& \sum_{t=0}^{t-1} s_t + PnL_0 \\ &=&\sum_{t=0}^{T-1} R_{t+1}\cdot h_t + PnL_0 \\ &=&\sum_{t=0}^{T-1} (p_{t+1} - p_t)\cdot h_t + PnL_0 \end{eqnarray}\]

where, the strategy returns at time \(t\) are given by the holdings at time \(t\) multiplied by the return at time \(t+1\), i.e.,

\[s_t = h_t\cdot R_{t+1} = h_t\cdot (p_{t+1} - p_t)\].

The holdings at time \(t\) should depend on our expectations at time \(t\) of expected returns over the following period(s). (In more exact terminology, we would say they are adapted to the filtration at time \(t\), which is the information available at time \(t\)). Given that we let our returns be just PnL, our holdings are denominated in USD notional, and if we scale them by the point-value of the given asset, we can think of them as the number of units of the asset we hold at time \(t\).

Optimal Mean Reversion Trading with no costs

One standard (and economically justifiable) method for forming a strategy, given the forecasts, is known as mean-variance optimization (MVO). In the simplest case, we assume that we want to maximize the utility of our holdings, which is a function of the expected return and the risk (variance) of the returns.: \[U(h_t) = E[R_{t+1}] \cdot h_t - \frac{1}{2} \gamma Var(R_{t+1}) \cdot h_t^2 \]

Where:

  • \(h_t\) is the holding at time \(t\),
  • \(E[R_{t+1}]\) is the expected return for the next period,
  • \(Var(R_{t+1}) =\sigma_{\epsilon}^2 \) is the variance of the return for the next period or the risk, and
  • \(\gamma\) is the risk aversion coefficient (a higher value means more risk averse). Solutions are easily found by taking Euler conditions, where we use plug-in estimators of our coefficients, leading to the standard: \[ h_t = \frac{E[R_{t+1}]}{\gamma Var(R_{t+1})} = \frac{\hat{\beta}(p_t - \hat{\mu})}{\gamma \hat{\sigma}_{\epsilon}^2}\]

In the single-asset case the solution is not very interesting, but in the multi-asset case, it leads to portfolio allocation, used throughout the fund management industry, and is especially good for motivating the benefits of diversification. As we shall see, this framework is also one of the only ones which balances between risk and return, net of costs.


Optimal Mean Reversion Trading with an AR(1) Process and Fixed Costs

One standard method for trading given forecasts and fixed transaction costs is to apply a single-period Mean-Variance Optimization (MVO) framework and explicitly incorporates fixed transaction costs or slippage costs (i.e., assuming we can trade at the top of book – executing at the best bid or best ask without moving the market). We should note that we will use the term “transaction costs” to be synonymous with “slippage costs” in this post. In many contexts, transaction costs refer to fixed costs (custodial fees, brokerage fees, commissions, etc), while slippage costs refer to the difference between the expected price and the actual price at which a trade is executed, often due to market impact. We will instead use the term “transaction costs” to refer to both fixed and slippage costs, as they both impact the optimal trading strategy.

Asset Price Dynamics: AR(1) Process

As we have mentioned above, we model the change in the asset price,\(p_t\), using a first-order autoregressive (AR(1)) process, which captures mean reversion:

\[p_{t+1} - p_t = \beta(p_t - \mu ) + \epsilon_{t+1}\]

Where \(p_t\): The price of the asset at time \(t\).

One-Period Ahead Return & Risk

Given the price at time \(t\), the conditional expected return and variance for the next period (\(t+1\)) are:

  • Expected Return: We define the return in this instance to be the price-change, i.e., \(R_{t+1 }= p_{t+1} - p_t\) and so \(E_t[R_{t+1}] = \beta (p_t - \mu )\)
  • Variance of Return: \( Var_t(R_{t+1}) = \sigma_{\epsilon}^2 \)

Optimal Allocation with Transaction Costs

The strategy involves defining a no-trade zone around the frictionless optimal allocation. A trade is executed only when the current holding falls outside this zone. Let \(h_{t-}\) be the holding before a potential trade at time \(t\), and let \(c\) be the fixed transaction cost per unit traded (i.e., \(\frac{(ask-bid)}{2}\)). The investor’s risk aversion is given by \(\gamma\). The utility function to be maximized at each time step is:

\[U(h_t) = \underbrace{E_t[R_{t+1}] \cdot h_t - \frac{\gamma}{2} \sigma_{\epsilon}^2 h_t^2}_{\text{Mean-Variance Utility}} - \underbrace{c |h_t - h_{t-}|}_{\text{Slippage Cost}}\]

Where:

  • \(h_t\): The new position (allocation) at time \(t\)
  • \(h_{t-}\): The position held just before trading at time \(t\)
  • \( |h_t - h_{t-}| \) : The absolute value of the change in position, representing the trades in that period.
  • \(c\): The fixed transaction cost per unit traded. Maximizing this utility with respect to \(h_t\) leads to the first-order condition we describe below. We note that in the case of no transaction costs, the optimal allocation would be \(h_t = \frac{E_t[R_{t+1}]}{\gamma \sigma_{\epsilon}^2}\), which is the standard MVO based holdings.

Boundary Formulas

Optimal trading with fixed costs leads to trading up to a no-trade zone around the frictionless (i.e., no transaction cost) optimal allocation. If the current holding is outside this zone, a trade is executed to bring the holding back into the zone. If the current holding is already within the zone, no trade is executed.

The no-trade zone is an interval \([L(p_t), U(p_t)]\) defined by a lower (buy) boundary and an upper (sell) boundary.

  • Lower Boundary (Buy Threshold) \(L(p_t)\):

    \[L(p_t) = \frac{E_t[R_{t+1}] - c}{\gamma \sigma_{\epsilon}^2} = \frac{\beta(p_t - \mu) - c}{\gamma \sigma_{\epsilon}^2}\]
  • Upper Boundary (Sell Threshold) \(U(p_t)\):

    \[U(p_t) = \frac{E_t[R_{t+1}] + c}{\gamma \sigma_{\epsilon}^2} = \frac{\beta(p_t - \mu) + c}{\gamma \sigma_{\epsilon}^2}\]

The width of this no-trade zone is constant: \(U(p_t) - L(p_t) = \frac{2c}{\gamma \sigma_{\epsilon}^2}\).

Effectively, we will not trade unless the changed expected return is great enough to cover the transaction costs.

Complete Trading Rules

The optimal allocation, \(h_t\), is determined by the following rules:

  1. If the current holding is below the zone (\(h_{t-} < L(p_t)\)): The expected benefit of increasing the position outweighs the cost. Action: BUY to bring the holding up to the lower boundary . \(h_t = L(p_t)\)

  2. If the current holding is above the zone (\(h_{t-} > U(p_t)\) ): The expected benefit of decreasing the position outweighs the cost. Action: SELL to bring the holding down to the upper boundary. \(h_t = U(p_t)\)

  3. If the current holding is within the zone (\(L(p_t) \le h_{t-} \le U(p_t)\) ): The expected benefit of a trade is insufficient to cover the cost. Action: DO NOT TRADE. \(h_t = h_{t-}\)

Complete Trading Rules in Python

We can encapsulate the above rules in a simple set of formulas using the clip function (e.g., in Pandas) given that \(E_t[R_{t+1}] = \beta(p_t - \mu )\) or in code we have it as

   L_p_t = (beta * (p_t - mu) - c) / (gamma * sigma**2)

   U_p_t = (beta * (p_t - mu) + c) / (gamma * sigma**2)

   h_t = np.clip(h_t-, L_p_t, U_p_t)

Optimal Trading with Market Impact Costs

For anything but the smallest trade size it is unrealistic to assume that we can trade at the top of book without moving the market. In practice, larger trades will impact the market price, leading to non-linear transaction costs. This section discusses how to adapt the MVO framework to account for market impact costs, which are typically convex in nature. Consequently, we wish to extend the single-period Mean-Variance Optimization (MVO) framework to include non-linear transaction costs, specifically market impact. Unlike fixed costs which lead to a “no-trade” zone, convex market impact costs result in a strategy of continuous and smooth trading. (the continuous trading is also known as “partial adjustment” or “gradual trading” and is sometimes a reason why some traders will not use these models).

1. The General Utility Function

We augment the standard MVO utility by subtracting a cost term that is a function of the trade size. Let:

  • \(h_t\): The new position (allocation) at time \(t\).
  • \(h_{t-}\): The position held just before trading at time \(t\).
  • \( |h_t - h_{t-}| \): the turnover or the size of the trade.
  • \(\lambda\): A parameter representing the strength of the market impact. Higher \(\lambda\) implies higher trading costs.
  • \(\beta\): The power of the cost function (e.g., \(3/2\) or \(2\)).

The general utility function, \(U(h_t)\), to be maximized at each time step is:

\[U(h_t) = \underbrace{E_t[R_{t+1}] \cdot h_t - \frac{\gamma}{2}\sigma_{\epsilon}^2 h_t^2}_{\text{Mean-Variance Utility}} - \underbrace{\lambda |h_t - h_{t-}|^{\eta}}_{\text{Market Impact Cost}}\]

The convexity of the cost function for \(\eta> 1\) ensures that the marginal cost of trading increases with trade size, which incentivises smaller, more frequent trades over large, abrupt ones. Most commonly \(\eta\) is set to \(3/2\) (or close to that by most market participants) while economists tend to like the power of \(2\) because it can be grounded in the Kyle Model (as well as leading to closed-form solutions). These lead to different optimal trading strategies.


2. Case 1: Market Impact with \(|\text{turnover}|^{3/2}\) (Square-Root Impact Law)

As mentioned above, this model is frequently used in academic literature and is supported by empirical analysis of trade data, often referred to as the “square-root impact law.”

Utility Function

\[U(h_t) = E_t[R_{t+1}] \cdot h_t - \frac{\gamma}{2} \sigma_{\epsilon}^2 h_t^2 - \lambda |h_t - h_{t-}|^{\frac{3}{2}}\]

Characterizing the Optimal Solution

To find the optimal holding \(h_t\), we take the derivative of the utility function with respect to \(h_t\) and set it to zero. This results in a non-linear equation:

\[\frac{\partial U(h_t)}{\partial h_t} = E_t[R_{t+1}] - \gamma \sigma_{\epsilon}^2 h_t - \frac{3}{2}\lambda |h_t - h_{t-}|^{\frac{1}{2}} \cdot \text{sign}(h_t - h_{t-}) = 0\]

Strategy and Intuition:

  • No Closed-Form Solution: Due to the non-linearity, there is no simple, explicit formula for \(h_t\). The optimal allocation must be found at each step using a numerical root-finding algorithm.
  • Partial Adjustment: The optimal strategy is to always trade towards the frictionless target (\(h^* = \frac{E_t[R_{t+1}]}{\gamma \sigma_{\epsilon}^2}\)), but never to reach it in a single step (unless \(h_{t-} = h^*\)). You only close a fraction of the gap.
  • No “No-Trade” Zone: A trade is almost always optimal, however small. The only time no trade occurs is if the prior holding \(h_{t-}\) happens to be exactly at the new optimal level.
  • Solutions can be found using numerical methods in 1d. In higher dimensions, convex optimization methods can be used (see for example, CVXPY or CVXPortfolio in Python, or CVXgen in C++, as well as many paid convex optimisation packages).

3. Case 2: Market Impact with \(|\text{turnover}|^2\) (Kyle-like Model)

This model is popular in economic theory due to its mathematical tractability, which allows for a clean, closed-form solution, as well as its theoretical grounding in the Kyle model of market microstructure (which assume noise traders and informed traders, and the resulting impact of trades on the market price, see references). Most market participants will use the square-root impact law.

Utility Function

\[U(h_t) = E_t[R_{t+1}] \cdot h_t - \frac{\gamma}{2}\sigma_{\epsilon}^2 h_t^2 - \lambda (h_t - h_{t-})^2\]

Characterizing the Optimal Solution

The quadratic nature of the cost function makes the first-order condition a linear equation in \(h_t\), which is easily solved.

\[\frac{\partial U(h_t)}{\partial h_t} = E_t[R_{t+1}] - \gamma \sigma_{\epsilon}^2 h_t - 2\lambda(h_t - h_{t-}) = 0\]

Solving for \(h_t\) yields, plugging in the expected return:

\[h_t = \frac{\alpha (\mu - p_t)}{\gamma \sigma_{\epsilon}^2 + 2\lambda} + \frac{2\lambda}{\gamma \sigma_{\epsilon}^2 + 2\lambda} h_{t-}\]

Strategy and Intuition:

This solution has a very elegant and intuitive structure. If we define the frictionless target holding as \(h^* = \frac{\beta(p_t - \mu ) }{\gamma \sigma_{\epsilon}^2}\), we can rewrite the solution as:

\[h_t = \left(\frac{\gamma \sigma_{\epsilon}^2}{\gamma \sigma_{\epsilon}^2 + 2\lambda}\right) h^* + \left(\frac{2\lambda}{\gamma \sigma_{\epsilon}^2 + 2\lambda}\right) h_{t-}\]
  • Weighted Average: The optimal holding \(h_t\) is a simple weighted average of the ideal frictionless target \(h^*\) and the previous holding \(h_{t-}\).
  • Trading Speed: The fraction of the gap between the current holding and the target that is closed in each period is constant and equal to
  • \(\frac{\gamma \sigma_{\epsilon}^2}{\gamma \sigma_{\epsilon}^2 + 2\lambda}\). This term can be interpreted as the “speed of trading.”
  • Impact of Costs: As market impact costs \(\lambda\) increase, the weight shifts towards the previous holding \(h_{t-}\), leading to slower trading. If \(\lambda=0\), the formula collapses to \(h_t = h^*\), as expected.

Conclusion

In this post, we have discussed how to trade mean-reversion strategies after identifying the level or spread to trade. We have covered two main approaches: one with fixed transaction costs and another with market impact costs. The fixed costs approach leads to a no-trade zone, which has some practical benefit since most strategies are killed by over-trading, while the market impact approach results in continuous trading strategies. The latter can be modeled with either a \(|\text{turnover}|^{3/2}\) or \(|\text{turnover}|^2\) cost structure, each leading to different optimal trading behaviors. The choice of model depends on the specific characteristics of the asset being traded and the trader’s preferences regarding risk and transaction costs. In practice, traders often use a combination of these models, adjusting parameters based on empirical data and market conditions to optimize their trading strategies.

New research continues to explore more complex models and multi-period trading strategies, although in practice, most traders will use a single-period model, perhaps with adjustments for the specific asset class and the alpha decay of their given strategy.

Further results

We have also discussed the optimal trading strategies in the context of mean-reversion trading, including the use of fixed costs and market impact costs. Continued work in optimal trading rules, incorporating both transaction costs and multi-period optimizations (see, for example Boyd et al and Garleanu-Pedersen). While stops are known to be value-destroying (see Kaminski-Lo), they can be used to limit losses in practice, especially in the context of mean-reversion strategies, and optimal stop-loss and take-profit levels can be derived from the mean-reversion model (see de Prado & Lipton).

Meanwhile practical trading rules can also incorporate parameter uncertainty, and the possibility of model breakdown. In the next post, we will discuss model breakdown, and how to detect it using statistical tests, as well as how to adapt trading strategies to account for model breakdown.


References

Allocation with Fixed Costs

  • Fundamentals of Algorithmic Trading, on the WBS/Quantshub Platform. This introductory course describes the Algo Trading Sector and common roles for quants, before discussing the overall trading framework with a case study on crypto.
  • Algorithmic Trading Certificate(ATC): A Practitioner’s Guide For a much more detailed course (in total 12 weeks), the Algorithmic Trading Certificate, which is available on the WBS Platform, covers the topic in much more detail, including the statistical tests, the trading strategies, and the implementation details, amongst so much more. It is available both as a self-paced course, and a hybrid course with live sessions.

I am working on a book on Algorithmic Trading, together with Dr Brian Healy, which will cover the topic in much more detail, including the statistical tests, the trading strategies, and the implementation in far more detail.