Mean Reversion Trading with Ornstein-Uhlenbeck Process and Optimal Bands
Info
The Mean Reversion Trading with Ornstein-Uhlenbeck Process and Optimal Bands is a Script for MetaTrader 5 that meanreversion. mqh models a spread returning to its mean as an Ornstein-Uhlenbeck process, identifying optimal entry and exit points.
Usage
This tool is typically used for enhancing chart analysis and decision making.
Platform
This Script works exclusively on MetaTrader 5 (both build 600+ and newer versions).
Setup
Place the downloaded file in MQL5/Scripts folder via File ? Open Data Folder in MetaTrader 5.
How to Install and Use Mean Reversion Trading with Ornstein-Uhlenbeck Process and Optimal Bands
1. Installation: Move your script file into the MQL/Scripts directory and restart the platform.
2. Execution: Drag the script onto a chart; it will perform a one-time action, such as closing all open orders or clearing chart objects.
3. Editing: Use MetaEditor (F4) to modify code, click "Compile," and verify no errors appear in the terminal before running.
4. Removing: Scripts stop automatically, but you can remove them manually by right-clicking the chart and choosing "Remove Script."
Frequently Asked Questions
Q: How are scripts different from EAs? A: Scripts execute a single action and then stop; EAs monitor the market and trade continuously.
Q: Can I assign a hotkey to a script? A: Yes, right-click the script in the Navigator, select "Set Hotkey," and define your preferred keyboard shortcut.
Q: Why did my script stop? A: Scripts are designed to stop immediately after finishing their programmed command; this is normal behavior.
What this tool does
MeanReversion.
Typical Use Case
This Script excels in automated trading and technical analysis on MetaTrader 5.
Compatible Platform & Setup
This Script works on MetaTrader 5. Place the file in the MQL5/Scripts folder and restart the terminal.
Description & Settings
Related: Cointegration Testing and Analysis in MT5 with Pair Scanner - another powerful script for MetaTrader 5 traders.
MeanReversion.mqh models a spread returning to its mean as an Ornstein-Uhlenbeck process, identifying optimal entry and exit points. The model provides an exact maximum likelihood fit for equally spaced bars, including standard errors, half-life, and long-run standard deviation. Trading levels are based on Bertram (2010), calculating entry and exit points that maximize expected return per unit of time for a given round-trip cost, along with the expected duration of a trade cycle. No DLL required.Also recommended: Broker Session Schedule Inspector MT5 - similar script with strong performance on MetaTrader 5.
Usage
Include the library:
#include <MeanReversion\MeanReversion.mqh>
Example code snippet:
vector spread;
// ... populate spread data ...
COrnsteinUhlenbeck ou;
if(ou.Fit(spread))
{
double halfLife = ou.HalfLife(); // in bars
double zScore = ou.ZScore(spread[spread.Size() - 1]);
double entryLevel, exitLevel, tradeRate;
ou.OptimalSymmetric(0.05, entryLevel, exitLevel, tradeRate); // Example: cost 0.05 per round trip
double expectedCycleBars = ou.ExpectedCycle(entryLevel, exitLevel); // Expected bars for a trade cycle
}
Library Components
Fit
Calculates kappa (speed of reversion), theta (mean reversion level), and sigma (volatility) using maximum likelihood estimation based on the exact transition density of the Ornstein-Uhlenbeck process. Standard errors are derived from the Hessian of the exact likelihood function. LogLikelihoodAt() can evaluate the likelihood for specified parameters.
ExpectedCycle
Estimates the expected time (in bars) from entering a trade at one level to exiting at another and returning to the initial state. The formula is approximately pi / kappa, adjusted by the imaginary error function (erfi) based on entry and exit levels relative to the mean, scaled by sigma.
ReturnPerTime
Calculates the expected return per unit of time using the formula: (exitLevel - entryLevel - roundTripCost) / ExpectedCycle(entryLevel, exitLevel).
OptimalSymmetric
Finds the optimal symmetric entry and exit levels (m = -a) that maximize the ReturnPerTime for a given cost 'c'.
Optimal
Calculates the optimal (potentially asymmetric) entry and exit levels, confirming the symmetry shown by Bertram.
Erfi
Implements the imaginary error function using its series expansion.
Trading Level Insights
When levels are measured in units of the long-run standard deviation, the optimal trading bands are primarily dependent on the transaction cost. For instance, a cost of 0.1 standard deviations suggests trading bands around +/-0.54 standard deviations. A cost of 0.5 standard deviations implies bands around +/-0.96 standard deviations, and a cost of 1 standard deviation suggests bands around +/-1.26 standard deviations.
Example Script: SpreadBands.mq5
The SpreadBands.mq5 script demonstrates how to use the MeanReversion library. It constructs the spread of two symbols (using log prices and a hedge ratio determined by least squares). It then fits the Ornstein-Uhlenbeck process to this spread. The script calculates the round-trip cost, incorporating bid-ask spreads and user-defined commissions. Finally, it outputs optimal trading levels, projected number of trades, estimated annual returns for various cost multiples (1x, 2x, 5x the base cost), and the current z-score. The script also offers functionality to export spread data and trading levels to a CSV file.
Verification and Testing
The library's fitting process has been validated against 3 simulated Ornstein-Uhlenbeck processes and a real-world spread. Comparisons with scipy's maximum likelihood estimation show parameter agreement within 4e-7 and identical likelihood values. Standard errors match within 1e-5 of a numerical Hessian calculation (using statsmodels).
The erfi function was tested against scipy for values between -6 and 6, yielding results accurate within 8e-16. Cycle length calculations are accurate within 1e-15. Optimal levels derived from bounded and free searches align within 5e-8 and 3e-8 standard deviations, respectively.
The accuracy of the cycle length formula was further verified through a simulation of 60 million steps (approximately 5,000 and 1,800 cycles), showing discrepancies of 2.2% and 0.9%, within the expected error range of the simulation.
File Locations
Place MeanReversion.mqh in your MQL5\Include\MeanReversion directory.
Place SpreadBands.mq5 in your MQL5\Scripts\MeanReversion directory.
You may also like: multi buy limit orders & multi buy stop orders - excellent alternative for script users on MetaTrader 5.
Source Code
#property copyright "RobotFX"
#property version "1.00"
#property script_show_inputs
#include <MeanReversion\MeanReversion.mqh>
input string InpY = "USDCAD";
input string InpX = "NZDUSD";
input ENUM_TIMEFRAMES InpPeriod = PERIOD_D1;
input int InpBars = 1000;
input double InpExtra = 0.0;
input double InpPerYear = 252;
.......
⚠ Limitations & Risk Warning
- This tool is provided for educational and testing purposes only.
- Past performance does not guarantee future results.
- Trading involves substantial risk of loss. Use on a demo account first.
- Results may vary depending on market conditions, broker, and settings.
- We recommend thorough backtesting and forward testing before using with real funds.