arbitragelab.optimal_mean_reversion.ou_model

Module Contents

Classes

OrnsteinUhlenbeck

This class implements the algorithm for solving the optimal stopping problem in

class OrnsteinUhlenbeck

This class implements the algorithm for solving the optimal stopping problem in markets with mean-reverting tendencies based on the Ornstein-Uhlenbeck model mentioned in the following publication:’Tim Leung and Xin Li Optimal Mean reversion Trading: Mathematical Analysis and Practical Applications(November 26, 2015)’ <https://www.amazon.com/Optimal-Mean-Reversion-Trading-Mathematical/dp/9814725919>`_

Constructing a portfolio with mean-reverting properties is usually attempted by simultaneously taking a position in two highly correlated or co-moving assets and is labeled as “pairs trading”. One of the most important problems faced by investors is to determine when to open and close a position.

To find the liquidation and entry price levels we formulate an optimal double-stopping problem that gives the optimal entry and exit level rules. Also, a stop-loss constraint is incorporated into this trading problem and solutions are also provided by this module.

fit(data, data_frequency, discount_rate, transaction_cost, start=None, end=None, stop_loss=None)

Fits the Ornstein-Uhlenbeck model to given data and assigns the discount rates, transaction costs and stop-loss level for further exit or entry-level calculation.

Parameters:
  • data – (np.array/pd.DataFrame) An array with time series of portfolio prices / An array with time series of of two assets prices. The dimensions should be either nx1 or nx2.

  • data_frequency – (str) Data frequency [“D” - daily, “M” - monthly, “Y” - yearly].

  • discount_rate – (float/tuple) A discount rate either for both entry and exit time or a list/tuple of discount rates with exit rate and entry rate in respective order.

  • transaction_cost – (float/tuple) A transaction cost either for both entry and exit time or a list/tuple of transaction costs with exit cost and entry cost in respective order.

  • start – (Datetime) A date from which you want your training data to start.

  • end – (Datetime) A date at which you want your training data to end.

  • stop_loss – (float/int) A stop-loss level - the position is assumed to be closed immediately upon reaching this pre-defined price level.

fit_to_portfolio(data=None, start=None, end=None)

Fits the Ornstein-Uhlenbeck model to time series for portfolio prices.

Parameters:
  • data – (np.array) All given prices of two assets to construct a portfolio from.

  • start – (Datetime) A date from which you want your training data to start.

  • end – (Datetime) A date at which you want your training data to end.

static portfolio_from_prices(prices, b_variable)

Constructs a portfolio based on two given asset prices and the relative amount of investment for one of them.

Parameters:
  • prices – (np.array) An array of prices of the two assets used to create a portfolio.

  • b_variable – (float) A coefficient representing the investment. into the second asset, investing into the first one equals one.

Returns:

(np.array) Portfolio prices. (p. 11)

half_life()

Returns the half-life of the fitted OU process. Half-life stands for the average time that it takes for the process to revert to its long term mean on a half of its initial deviation.

Returns:

(float) Half-life of the fitted OU process

fit_to_assets(data=None, start=None, end=None)

Creates the optimal portfolio in terms of Ornstein-Uhlenbeck model from two given time series for asset prices and fits the values of the model’s parameters. (p.13)

Parameters:
  • data – (np.array) All given prices of two assets to construct a portfolio from.

  • start – (Datetime) A date from which you want your training data to start.

  • end – (Datetime) A date at which you want your training data to end.

ou_model_simulation(n, theta_given=None, mu_given=None, sigma_given=None, delta_t_given=None)

Simulates values of an OU process with given parameters or parameters fitted to our data

Parameters:
  • n – (int) Number of simulated values.

  • theta_given – (float) Long-term mean.

  • mu_given – (float) Mean revesion speed.

  • sigma_given – (float) The amplitude of randomness in the system.

  • delta_t_given – (float) Delta between observations, calculated in years.

Returns:

(np.array) simulated portfolio prices.

optimal_coefficients(portfolio)

Finds the optimal Ornstein-Uhlenbeck model coefficients depending on the portfolio prices time series given.(p.13)

Parameters:

portfolio – (np.array) Portfolio prices.

Returns:

(tuple) Optimal parameters (theta, mu, sigma_square, max_LL)

check_fit()

Shows the parameters of the OU model fitted to the data and parameters achieved from the simulated process with the fitted coefficients for further assessment. The main incentive is to have simulated max log-likelihood (mll) function close to a fitted one. If the simulated mll is much greater it means that data provided to the model is not good enough to be modeled by an OU process.

Note: The check can occasionally return numbers significantly different from the fitted mll due to the random nature of the simulated process and the possibility of outliers. It is advised to perform the check multiple times and if it’s consistently showing very different values of mll you might suspect the unsuitability of your data.

Returns:

(pd.Dataframe) Values for fitted and simulated OU model parameters

description()

Returns all the general parameters of the model, training interval timestamps if provided, the goodness of fit, allocated trading costs and discount rates, stop-loss level, beta, which stands for the optimal ratio between two assets in the created portfolio, and optimal levels calculated. If the stop-loss level was given optimal levels that account for stop-loss would be added to the list.

Returns:

(pd.Series) Summary data for all model parameters and optimal levels.

plot_levels(data, stop_loss=False)

Plots the found optimal exit and entry levels on the graph alongside with the given data.

Parameters:
  • data – (np.array/pd.DataFrame) Time series of portfolio prices / time series of of two assets prices of size (n x 2).

  • stop_loss – (bool) A flag whether to take stop-loss level into account. when showcasing the results.

Returns:

(plt.Figure) Figure with optimal exit and entry levels.

V(price)

Calculates the expected discounted value of liquidation of the position. (p.23)

Parameters:

price – (float) Portfolio value.

Returns:

(float) Expected discounted liquidation value.

optimal_liquidation_level()

Calculates the optimal liquidation portfolio level. (p.23)

Returns:

(float) Optimal liquidation portfolio level.

optimal_entry_level()

Calculates the optimal entry portfolio level. (p.27)

Returns:

(float) Optimal entry portfolio level.

V_sl(price)

Calculates the expected discounted value of liquidation of the position considering the stop-loss level. (p. 31)

Parameters:

price – (float) Portfolio value.

Returns:

(float) Expected discounted value of liquidating the position considering the stop-loss level.

optimal_liquidation_level_stop_loss()

Calculates the optimal liquidation portfolio level considering the stop-loss level. (p.31)

Returns:

(float) Optimal liquidation portfolio level considering the stop-loss.

optimal_entry_interval_stop_loss()

Calculates the optimal entry portfolio interval considering the stop-loss level. (p.35)

Returns:

(tuple) Optimal entry portfolio interval considering the stop-loss.