Skip to content

Model MeanReversionBasedOnSpreadQuantileDemo

github-actions[bot] edited this page Oct 18, 2026 · 8 revisions

MeanReversionBasedOnSpreadQuantileDemo — quantitative model reference

Wiki home · Quantitative model references · Execution records

This quantitative model reference is provided for study, further research and application within the AlgoQuant framework. Read the research idea and implementation choices separately from the execution record.

Tutorials and quantitative model references · Pinned source · Javadoc

Paper introduction

Robert J. Elliott, John van der Hoek and William P. Malcolm, Pairs trading (2005) treats the spread between related securities as an unobserved mean-reverting Gaussian Markov process measured with additional Gaussian noise. This separates a latent relative-value signal from noisy observations.

The paper's stated contribution is a model for estimating and tracking that spread and using it to motivate pairs-trading decisions. The intuition is to trade a deviation relative to an estimated equilibrium, rather than predict each stock's outright direction. The relationship can nevertheless break down, and spread convergence does not remove execution or financing risk.

This introduction is based on the original publisher abstract and author-institution record; full-text derivations were not available for review. The repository offers several signal customizations. Posterior-state, constant-coefficient and empirical-quantile rules must not be described as identical implementations of the paper.

How this demo connects to the idea

MeanReversionBasedOnSpreadQuantile chooses thresholds from the configured spread distribution and is passed into Elliott2005Strategy by a Yahoo template. Coefficients define the traded spread; calibration controls the distribution used for thresholds. Re-estimation and execution assumptions determine the resulting backtest.

What this example teaches

Runs a Elliott mean reversion strategy, coded up using a template.

Using this example. Chooses MeanReversionBasedOnSpreadQuantile as the customization of an Elliott2005Strategy inside a Yahoo simulation template. Quantile thresholds apply to the modeled spread, not each individual stock price. The report and chart reflect the template settings.

Model and publication. This is an Elliott-style spread strategy with a quantile-based customization. Quantile entry and exit rules are application choices, not a claim to reproduce the publication’s full estimator.

Implementation in this tutorial. MeanReversionBasedOnSpreadQuantile chooses thresholds from the configured spread distribution and is passed into Elliott2005Strategy by a Yahoo template. Coefficients define the traded spread; calibration controls the distribution used for thresholds. Re-estimation and execution assumptions determine the resulting backtest.

Verified execution record

Item Value
Status completed
Run 39114360151
UTC publication 2026-10-18 11:43 UTC
Source commit 355aa9242fc2a247b256aecc8406cbb409aa5ff3
Data mode original main defaults
Exit code 0
Elapsed seconds 16.12
Time limit seconds 180
Maximum Java heap 1200m

The original main returned successfully. Read the output and model assumptions before interpreting it.

Reproduce the calculation

Follow the repository setup for JDK 8, Maven credentials and an external NM license. From the repository root:

mvn -U -Dmaven.test.skip=true clean package
mvn exec:java -Dexec.mainClass=tech.nmfin.algoquant.demo.model.elliott2005.MeanReversionBasedOnSpreadQuantileDemo

The automated run uses scripts/ModelDemoRunner.java to initialize the external license before the unchanged main, save JFreeChart windows as PNGs, and exit after main returns. It uses an isolated working directory with the repository datasets/configuration linked in. Running directly may leave desktop windows open.

Observed output


09:12:38.722 [main] INFO  t.n.algoquant.util.config.AQConfig,194 - looking up configuration file: config.default.xml
09:12:38.725 [main] INFO  t.n.algoquant.util.config.AQConfig,194 - looking up configuration file: config/config.default.xml
09:12:38.725 [main] INFO  t.n.algoquant.util.config.AQConfig,209 - loading config file: file:/home/runner/work/algoquant-examples/algoquant-examples/target/model-results/MeanReversionBasedOnSpreadQuantileDemo/work/config/config.default.xml


09:12:38.888 [main] INFO  t.n.algoquant.util.config.AQConfig,95 - current directory: /home/runner/work/algoquant-examples/algoquant-examples/target/model-results/MeanReversionBasedOnSpreadQuantileDemo/work
09:12:38.889 [main] INFO  t.n.algoquant.util.config.AQConfig,169 - current config:
09:12:38.911 [main] INFO  t.n.algoquant.util.config.AQConfig,11 - nm.license: /home/runner/work/algoquant-examples/algoquant-examples/license/nm.lic
09:12:38.911 [main] INFO  t.n.algoquant.util.config.AQConfig,11 - DATA_FOLDER: ./test-data
09:12:38.911 [main] INFO  t.n.algoquant.util.config.AQConfig,11 - DATA_GAINCAPITAL: ${DATA_FOLDER}/processed/gaincapital/extracted-from-raw-arrange-by-dates
09:12:38.911 [main] INFO  t.n.algoquant.util.config.AQConfig,11 - DATA_BLOOMBERG: ${DATA_FOLDER}/processed/bloomberg
09:12:38.912 [main] INFO  t.n.algoquant.util.config.AQConfig,11 - DATA_YAHOO: ${DATA_FOLDER}/yahoo
09:12:38.912 [main] INFO  t.n.algoquant.util.config.AQConfig,11 - DATA_SGX: ${DATA_FOLDER}/raw/sgx
09:12:38.912 [main] INFO  t.n.algoquant.util.config.AQConfig,11 - DATA_HOLIDAYS: ./log/holidays
09:12:38.916 [main] INFO  t.n.algoquant.util.config.AQConfig,11 - DATA_COMPUSTAT_HK: ${DATA_FOLDER}/[database configuration redacted]/hk
09:12:38.916 [main] INFO  t.n.algoquant.util.config.AQConfig,11 - PDF_OUTPUT_FOLDER: ./log/
09:12:38.916 [main] INFO  t.n.algoquant.util.config.AQConfig,11 - PDF_PLOT_WIDTH: 800
09:12:38.917 [main] INFO  t.n.algoquant.util.config.AQConfig,11 - PDF_PLOT_HEIGHT: 600
09:12:40.143 [main] INFO  t.n.a.d.h.yahoo.YahooEODCacheFactory,237 - failed to load from file, reason: no data read from file; load from web
09:12:40.144 [main] INFO  t.n.a.d.h.yahoo.YahooEODCacheFactory,196 - reading Yahoo! data for XOM from the Internet from 2012-01-01T00:00 to 2014-10-01T16:00
09:12:40.309 [main] INFO  t.n.a.d.h.y.YahooEODCsvZipFileWriter,30 - writing csv.zip file ./log/Yahoo/XOM.csv.zip
09:12:40.342 [main] INFO  t.n.a.d.h.y.YahooEODCsvZipFileWriter,81 - finished writing ./log/Yahoo/XOM.csv.zip
09:12:40.348 [main] INFO  t.n.a.d.h.yahoo.YahooEODCacheFactory,237 - failed to load from file, reason: no data read from file; load from web
09:12:40.348 [main] INFO  t.n.a.d.h.yahoo.YahooEODCacheFactory,196 - reading Yahoo! data for CVX from the Internet from 2012-01-01T00:00 to 2014-10-01T16:00
09:12:40.475 [main] INFO  t.n.a.d.h.y.YahooEODCsvZipFileWriter,30 - writing csv.zip file ./log/Yahoo/CVX.csv.zip
09:12:40.491 [main] INFO  t.n.a.d.h.y.YahooEODCsvZipFileWriter,81 - finished writing ./log/Yahoo/CVX.csv.zip
09:12:43.692 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2012-05-24T16:00: beta = [1.000000, -0.298163] , mu = 30.960872472495666, xt = 30.465368214399493, zt = 30.581309474104174
09:12:43.719 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2012-05-25T16:00: beta = [1.000000, -0.314951] , mu = 29.977713985551276, xt = 29.43809168753392, zt = 29.552083383161847
09:12:43.748 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2012-05-29T16:00: beta = [1.000000, -0.346518] , mu = 28.12047988859729, xt = 27.353929700445583, zt = 27.458729238936094
... excerpt shortened; complete stdout is in the release archive ...
09:12:46.029 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-11T16:00: beta = [1.000000, -0.149566] , mu = 49.718385563177236, xt = 47.99635892793512, zt = 48.56829517883433
09:12:46.036 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-12T16:00: beta = [1.000000, -0.137747] , mu = 50.619442390342456, xt = 48.721508466995566, zt = 49.37317916349528
09:12:46.040 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-13T16:00: beta = [1.000000, -0.197505] , mu = 46.11777946335587, xt = 44.39199893800619, zt = 45.15063918562845
09:12:46.041 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-14T16:00: beta = [1.000000, -0.226152] , mu = 43.967252123911514, xt = 42.247101103434765, zt = 43.058036871827696
09:12:46.048 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-15T16:00: beta = [1.000000, -0.190587] , mu = 46.65578586380425, xt = 45.03632274224485, zt = 45.68900817192053
09:12:46.055 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-18T16:00: beta = [1.000000, -0.201563] , mu = 45.821439852424525, xt = 44.3288212288717, zt = 45.130291492383385
09:12:46.060 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-20T16:00: beta = [1.000000, -0.144814] , mu = 50.08659005175859, xt = 48.68916171054319, zt = 49.44453153995957
09:12:46.075 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-29T16:00: beta = [1.000000, 0.192106] , mu = 75.79951019445639, xt = 74.72051173702879, zt = 75.3458312553501
09:12:46.085 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-09-02T16:00: beta = [1.000000, 0.261567] , mu = 81.08103995235022, xt = 79.06358912955702, zt = 79.86163060409328
09:12:46.086 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-09-03T16:00: beta = [1.000000, 0.196615] , mu = 76.14775626080356, xt = 74.30355939316699, zt = 75.29617921864707
09:12:46.088 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-09-04T16:00: beta = [1.000000, 0.205366] , mu = 76.7678314716818, xt = 74.4559285637645, zt = 75.38253821924562
09:12:46.093 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-09-05T16:00: beta = [1.000000, 0.128688] , mu = 70.93362975195869, xt = 69.0106474039234, zt = 70.13090572558875
09:12:46.129 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-09-30T16:00: beta = [1.000000, -0.458948] , mu = 24.52430704771692, xt = 23.89215819279785, zt = 24.193154538326432
09:12:46.223 [main] INFO  t.n.a.d.m.e.MeanReversionBasedOnSpreadQuantileDemo,179 - Executions: 
#	Time	Side	Symbol	Quantity	Price
1	2012-05-29T16:00	BUY	XOM	1.0	46.8350715637207
2	2012-06-19T16:00	SELL	XOM	1.0	48.29276657104492
3	2012-06-20T16:00	SELL	XOM	1.0	48.572879791259766
4	2012-06-21T16:00	BUY	XOM	1.0	46.93795394897461
5	2012-07-10T16:00	BUY	XOM	1.0	47.509613037109375
6	2012-07-11T16:00	SELL	XOM	1.0	48.235595703125
7	2012-08-02T16:00	BUY	XOM	1.0	49.093055725097656
8	2012-08-03T16:00	SELL	XOM	1.0	50.047733306884766
9	2012-08-31T16:00	BUY	XOM	1.0	50.2291145324707
10	2012-09-05T16:00	SELL	XOM	1.0	50.24638748168945
11	2012-09-14T16:00	SELL	XOM	1.0	53.105926513671875
12	2012-09-19T16:00	BUY	XOM	1.0	52.11054992675781
13	2012-10-03T16:00	SELL	XOM	1.0	52.760711669921875
14	2012-11-09T16:00	BUY	XOM	1.0	50.49151611328125
15	2012-11-23T16:00	SELL	XOM	1.0	51.579959869384766
16	2012-11-27T16:00	BUY	XOM	1.0	50.57254409790039
17	2012-12-24T16:00	BUY	XOM	1.0	50.32360076904297
18	2013-01-02T16:00	SELL	XOM	1.0	51.35993957519531
19	2013-02-04T16:00	BUY	XOM	1.0	51.61470031738281
20	2013-02-19T16:00	SELL	XOM	1.0	52.04351806640625
21	2013-02-25T16:00	BUY	XOM	1.0	51.099586486816406
22	2013-02-27T16:00	SELL	XOM	1.0	52.16585159301758
23	2013-03-07T16:00	BUY	XOM	1.0	51.68806838989258
24	2013-03-11T16:00	SELL	XOM	1.0	51.95028305053711
25	2013-03-18T16:00	BUY	XOM	1.0	51.723026275634766
26	2013-03-22T16:00	SELL	XOM	1.0	52.026004791259766
27	2013-03-27T16:00	SELL	XOM	1.0	52.777645111083984
28	2013-04-05T16:00	BUY	XOM	1.0	51.86286544799805
29	2013-04-08T16:00	BUY	XOM	1.0	51.62397766113281
30	2013-04-11T16:00	SELL	XOM	1.0	51.9852294921875
31	2013-04-17T16:00	BUY	XOM	1.0	50.15564727783203
32	2013-04-23T16:00	SELL	XOM	1.0	52.031837463378906
33	2013-04-25T16:00	BUY	XOM	1.0	51.31517791748047
34	2013-05-03T16:00	SELL	XOM	1.0	52.45134735107422
35	2013-05-07T16:00	SELL	XOM	1.0	53.109764099121094
36	2013-05-30T16:00	BUY	XOM	1.0	54.028648376464844
37	2013-06-07T16:00	SELL	XOM	1.0	53.653167724609375
38	2013-06-11T16:00	BUY	XOM	1.0	53.072349548339844
39	2013-06-17T16:00	SELL	XOM	1.0	53.68837356567383
40	2013-06-20T16:00	BUY	XOM	1.0	52.24512481689453
41	2013-06-26T16:00	SELL	XOM	1.0	52.68513870239258
42	2013-07-16T16:00	BUY	XOM	1.0	54.73854446411133
43	2013-08-13T16:00	BUY	XOM	1.0	52.8129768371582
44	2013-11-06T16:00	BUY	CVX	1.0	70.3741226196289
45	2013-11-06T16:00	SELL	XOM	2.0	55.069618225097656
46	2013-11-21T16:00	SELL	CVX	1.0	72.32417297363281
47	2013-11-21T16:00	BUY	XOM	1.0	56.31865692138672
48	2014-05-05T16:00	SELL	XOM	1.0	61.64116287231445
49	2014-05-07T16:00	BUY	XOM	1.0	61.760955810546875
50	2014-05-12T16:00	SELL	XOM	1.0	61.649593353271484
51	2014-05-13T16:00	BUY	XOM	1.0	61.72799301147461
52	2014-06-10T16:00	BUY	XOM	1.0	61.185245513916016
53	2014-06-11T16:00	SELL	XOM	1.0	61.4807243347168
54	2014-06-12T16:00	BUY	XOM	1.0	61.30588150024414
55	2014-07-03T16:00	SELL	XOM	1.0	61.86665725708008
56	2014-08-06T16:00	BUY	XOM	1.0	59.689697265625
57	2014-08-29T16:00	SELL	XOM	1.0	60.39698791503906
58	2014-09-04T16:00	BUY	XOM	1.0	59.7289924621582
59	2014-09-05T16:00	SELL	XOM	1.0	60.27553176879883
60	2014-09-30T16:00	BUY	XOM	1.0	57.11176681518555
09:12:46.224 [main] INFO  t.n.a.d.m.e.MeanReversionBasedOnSpreadQuantileDemo,185 - Performance Report:
Product	Profit Loss	Information Ratio For Zero Investment	Omega For Periods	Execution Count
CVX	1.9500503540039062	0.7071067811865476	Infinity	2.0
XOM	17.696189880371094	9.810782373657108	Infinity	58.0
Total	20.36886978149414	17.165154232006056	Infinity	60.0

Charts from this run

Chart 1

Reported performance statistics

Products and aggregate shown exactly as reported; P/L is monetary, not percent. Currency conventions belong to the demo.

Derived from stdout.log using the precision available in that file. Download plotted data. Undefined or malformed cells are omitted, never replaced by zero.

Chart 2

Fitted distribution parameters

Parameter axes are separate. Record order is preserved; estimated parameters are not investment performance.

Derived from stdout.log using the precision available in that file. Download plotted data. Undefined or malformed cells are omitted, never replaced by zero.

Chart 3

Downloadable evidence

Download MeanReversionBasedOnSpreadQuantileDemo.zip contains stdout, stderr, the execution record, checksums and any exported CSV/chart files.

Export Bytes
files/charts/chart-01.png 142382
files/derived-charts/charts.json 1026
files/derived-charts/derived-01.csv 401
files/derived-charts/derived-01.png 89065
files/derived-charts/derived-02.csv 11772
files/derived-charts/derived-02.png 56857

Interpreting the result

Read the reported units: optimizer weights, model-fit coefficients, forecast correlations and simulated P/L are different outputs. Synthetic runs demonstrate the API rather than historical market returns. Inspect undefined values and open positions instead of replacing them with zero. Chart exports visualize exactly this run.

For model assumptions, original publications and adaptation limits, use the literature guide.

Clone this wiki locally