Note
The following implementations and documentation closely follow the below work:
Liu, J. and Timmermann, A., 2013. Optimal convergence trade strategies.
Optimal Convergence
Introduction
Convergence trades resemble the standard long-short arbitrage strategy popular in industry and covered in academic studies. Conventionally, such strategies take positions of equal size but opposite signs either in portfolio weight or in number of shares. This seems intuitively reasonable and ensures that future liabilities offset. However, as shown in the paper, such delta neutral strategies will typically not be optimal.
The objective of optimally trading off risk and returns can lead to quite different solutions compared with the standard arbitrage objective assumed in convergence trades. Traditional arbitrage strategies and/or delta neutral convergence trades are designed to explore long-term arbitrage opportunities but usually do not exploit the short-run risk-return trade-off optimally. By placing arbitrage opportunities in the context of a portfolio maximization problem, the optimal convergence strategy accounts for both arbitrage opportunities and diversification benefits.
Modelling
In the paper, the authors assume that there is a riskless asset that pays a constant rate of return, \(r\). A risky asset trading at the price \(P_{mt}\) represents the market index. This follows a geometric random walk process,
where the market risk premium, \(\mu_{m}\), and market volatility, sigma_{m}`, are both constant, and \(B_t\) is a standard Brownian motion.
In addition to the risk-free asset and the market index, the authors assume the presence of two risky assets whose prices \(P_{it}, i = 1,2\), evolve according to the equations
where \(\lambda_1\), \(\lambda_2\), \(\beta\), \(b\), and \(\sigma\) are constant parameters. \(Z_t\) and \(Z_{it}\) are standard Brownian motions, and \(B_t\) , \(Z_t\) , and \(Z_{it}\) are all mutually independent for \(i = 1,2\).
In the above equations, \(\beta \sigma_m d B_t\) represents exposure to the market risk, whereas \(\sigma d Z_{t}+b d Z_{t}\) represents idiosyncratic risks. It is standard to assume that idiosyncratic risks are independent across different stocks with the market risk representing the only source of correlation among different assets.
\(x_t\) represents pricing errors in our model and is the difference between the logarithms of the two asset prices, \(p_{it} = \ln P_{it}\) ,
The authors make a key assumption here, that \(\lambda_1 + \lambda_2 > 0\). This implies that \(x_t\) is stationary and the logarithms of the prices are cointegrated with cointegrating vector \((1,−1)\).
The cointegration setup captures the feature that two assets with identical payoffs can trade at different prices. Examples include pairs of stocks that have the same claim to dividends and identical voting rights but are traded in different markets and two stocks with the same payoffs, such as the target and acquirer stocks in a merger.
\(−\lambda_1 x_t\) and \(\lambda_2 x_t\) capture the absolute mispricing of each asset relative to CAPM. For further information regarding the utility of \(\lambda\)’s, interested readers can refer to Section 1.1 in the paper.
Cointegration and relative mispricing
\(x_t\) represents the relative mispricing between both assets. This is considered stationary and the dynamics of this term is given by,
where,
In this paper, the authors considered two cases for both the unconstrained and constrained(delta neutral) portfolios. The first case deals with recurring arbitrage opportunities, the price differential, \(x_t\) , only spends an infinitesimally short time at zero, is characterized at all times by the dynamics in the above equation, and so follows a stationary process. In the second case (“nonrecurring arbitrage opportunities”), any price difference is temporary and gets permanently eliminated the first time the two prices converge and \(x_t = 0\). In this case, the price dynamics is subject to the additional restriction that \(x_{\tau + \delta} = 0\) for all \(\delta ≥ 0\), where \(\tau = min(t : x_t = 0)\) is a stopping time. In this case, prices remain identical after they converge. The optimal portfolio weights are different for these cases.
In the absence of intermediate consumption, the investor’s wealth, \(W_t\) , evolves according to the process,
We assume that the investor maximizes the expected value of a power utility function defined over terminal wealth, \(W_T\). The investor’s value function is given by
where \(W^{*}_T\) is the wealth at time \(T\) obtained by the optimal trading strategy with \(W_t = W\) and \(x_t = x\) at time \(t\).
Unconstrained Optimal Investment Strategies
For the continuing cointegrated price process (recurring arbitrage opportunities), we get a closed-form solutions for the optimal portfolio weights.
The optimal weights on the market portfolio, \(\phi_{m t}^{*}\) , and the individual assets, \((\phi_{1 t}^{*}, \phi_{2 t}^{*})\), are given by
Delta Neutral Strategy
In the model considered in the paper, where the two stocks are assumed to have identical market betas, delta neutrality directly translates into the constraint \(\phi_{1t} = −\phi_{2t}\). The authors suggest that the best way to achieve a delta neutral position is to use the market index to hedge away the market exposure in the mispriced assets. Using mispriced assets alone to achieve delta neutrality will necessarily underexploit opportunities offered by mispricing in the individual stocks.
For the continuing cointegrated price process (recurring arbitrage opportunities), we get closed-form solutions.
Note
The optimal strategy is delta neutral if \(\lambda_1 = \lambda_2\).
How to use this submodule
This submodule contains six public methods, of which two methods are necessary to calculate the optimal weights.
The first method fit
is for estimating the parameters of the model
using training data, and the second method is for calculating the final optimal portfolio weights using evaluation data.
Model fitting
We input the training data to the fit method, which calculates the spread and the estimators of the parameters of the model.
Implementation
Tip
To view the estimated model parameters from training data, call the describe
function.
Optimal Unconstrained Portfolio Weights with recurring arbitrage opportunities
In this step we input the evaluation data and specify the utility function parameter \(\gamma\).
Warning
Please make sure the value of gamma
is positive.
Implementation
Delta Neutral Portfolio Weights with recurring arbitrage opportunities
In this step we input the evaluation data and specify the utility function parameter \(\gamma\).
Warning
Please make sure the value of gamma
is positive.
Implementation
Wealth gain in continuous case
In this step we specify the utility function parameter \(\gamma\).
Warning
Please make sure the value of gamma
is positive.
Implementation
Plotting the total wealth of portfolio
In this step we can plot the wealth process using the calculated portfolio weights. We input the pricing data along with the calculated portfolio weights.
Implementation
Examples
We use GLD and GDX tickers from Yahoo Finance as the dataset for this example.
import yfinance as yf
data1 = yf.download("GLD GDX", start="2009-03-25", end="2019-03-25")
data2 = yf.download("GLD GDX", start="2019-03-27", end="2020-03-27")
data_train_dataframe = data1["Adj Close"][["GLD", "GDX"]]
data_test_dataframe = data2["Adj Close"][["GLD", "GDX"]]
Example 1
In the following code block, after initializing the class firstly,
we use the fit method to generate the parameters of the model.
Then, we call describe
to view the estimated parameters.
Finally, we use the out-of-sample test data to calculate the optimal portfolio weights using the fitted model.
from arbitragelab.stochastic_control_approach.optimal_convergence import OptimalConvergence
oc = OptimalConvergence()
oc.fit(data_train_dataframe, r = 0.02, mu_m = 0.05, sigma_m = 0.10)
print(oc.describe())
phi_1, phi_2, phi_m = oc.unconstrained_portfolio_weights_continuous(data_test_dataframe, gamma=4)
Example 2
In the following code block, after initializing the class firstly,
we use the fit method to generate the parameters of the model.
Then, we call describe
to view the estimated parameters.
Finally, we use the out-of-sample test data to calculate the delta neutral portfolio weights using the fitted model.
from arbitragelab.stochastic_control_approach.optimal_convergence import OptimalConvergence
oc = OptimalConvergence()
oc.fit(data_train_dataframe, r = 0.02, mu_m = 0.05, sigma_m = 0.10)
print(oc.describe())
phi_1, phi_2, phi_m = oc.delta_neutral_portfolio_weights_continuous(data_test_dataframe, gamma=4)