Skip to content

Model MeanReversionBasedOnSpreadQuantileDemo

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

MeanReversionBasedOnSpreadQuantileDemo — execution tutorial

All model results · Pinned source · Javadoc

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 39114006111
UTC publication 2026-10-18 09:11 UTC
Source commit 0097e73c040bdaaddac570e2fe694d9836b676ee
Data mode original main defaults
Exit code 0
Elapsed seconds 21.56
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:07:03,275 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
09:07:03,276 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
09:07:03,276 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [jar:file:/home/runner/work/algoquant-examples/algoquant-examples/target/lib/algoquant-dist-3.3.0-SNAPSHOT.jar!/logback.xml]
09:07:03,307 |-INFO in ch.qos.logback.core.joran.spi.ConfigurationWatchList@34340fab - URL [jar:file:/home/runner/work/algoquant-examples/algoquant-examples/target/lib/algoquant-dist-3.3.0-SNAPSHOT.jar!/logback.xml] is not of type file
09:07:04,123 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
09:07:04,124 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
09:07:04,135 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
09:07:04,142 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
09:07:04,184 |-INFO in ch.qos.logback.core.joran.action.TimestampAction - Using current interpretation time, i.e. now, as time reference.
09:07:04,185 |-INFO in ch.qos.logback.core.joran.action.TimestampAction - Adding property to the context with key="bySecond" and value="2026.10.18,09.07.04" to the LOCAL scope
09:07:04,185 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender]
09:07:04,188 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [FILE1]
09:07:04,199 |-INFO in ch.qos.logback.core.rolling.FixedWindowRollingPolicy@2aafb23c - Will use zip compression
09:07:04,199 |-WARN in ch.qos.logback.core.rolling.FixedWindowRollingPolicy@2aafb23c - Large window sizes are not allowed.
09:07:04,199 |-WARN in ch.qos.logback.core.rolling.FixedWindowRollingPolicy@2aafb23c - MaxIndex reduced to 21
09:07:04,203 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
09:07:04,204 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[FILE1] - Active log file name: log/algoquant.2026.10.18,09.07.04.log
09:07:04,204 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[FILE1] - File property is set to [log/algoquant.2026.10.18,09.07.04.log]
09:07:04,205 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to DEBUG
09:07:04,205 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
09:07:04,205 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [FILE1] to Logger[ROOT]
09:07:04,205 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
09:07:04,205 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@2b80d80f - Registering current configuration as safe fallback point

09:07:09.221 [main] INFO  t.n.algoquant.util.config.AQConfig,194 - looking up configuration file: config.default.xml
09:07:09.224 [main] INFO  t.n.algoquant.util.config.AQConfig,194 - looking up configuration file: config/config.default.xml
09:07:09.224 [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:07:09.433 [main] INFO  t.n.algoquant.util.config.AQConfig,148 - 09:07:03,275 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
09:07:03,276 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
09:07:03,276 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [jar:file:/home/runner/work/algoquant-examples/algoquant-examples/target/lib/algoquant-dist-3.3.0-SNAPSHOT.jar!/logback.xml]
... excerpt shortened; complete stdout is in the release archive ...
09:07:16.654 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-07-02T16:00: beta = [1.000000, -0.448259] , mu = 27.257893905240085, xt = 26.032949741749942, zt = 26.455605014381945
09:07:16.655 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-07-03T16:00: beta = [1.000000, -0.460357] , mu = 26.388736646626796, xt = 25.463436442924646, zt = 25.868159800813906
09:07:16.660 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-07-07T16:00: beta = [1.000000, -0.473060] , mu = 25.47003793322977, xt = 24.74922322145876, zt = 25.114071517383643
09:07:16.702 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-04T16:00: beta = [1.000000, -0.230287] , mu = 43.63966005471094, xt = 42.335640615490924, zt = 42.78994948979074
09:07:16.707 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-05T16:00: beta = [1.000000, -0.265338] , mu = 40.954884997213256, xt = 39.00030820375053, zt = 39.455983421028165
09:07:16.709 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-06T16:00: beta = [1.000000, -0.288025] , mu = 39.24968851409593, xt = 37.546371056840826, zt = 38.1044089328356
09:07:16.721 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-07T16:00: beta = [1.000000, -0.149459] , mu = 49.66007666892713, xt = 47.673432352304104, zt = 48.06784676443486
09:07:16.724 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-08T16:00: beta = [1.000000, -0.147738] , mu = 49.883588001437325, xt = 48.17459183063194, zt = 48.888573271804056
09:07:16.727 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-11T16:00: beta = [1.000000, -0.149571] , mu = 49.71802068688871, xt = 47.99603707004836, zt = 48.567949405867544
09:07:16.730 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-12T16:00: beta = [1.000000, -0.137744] , mu = 50.619710007247775, xt = 48.72180879455232, zt = 49.37343589619013
09:07:16.739 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-13T16:00: beta = [1.000000, -0.197507] , mu = 46.11762000372084, xt = 44.39189235714558, zt = 45.150499726802394
09:07:16.743 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-14T16:00: beta = [1.000000, -0.226156] , mu = 43.96697133468787, xt = 42.24690032702272, zt = 43.05777926453985
09:07:16.748 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-15T16:00: beta = [1.000000, -0.190588] , mu = 46.65569286820627, xt = 45.03627674842615, zt = 45.6889087498827
09:07:16.750 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-18T16:00: beta = [1.000000, -0.201570] , mu = 45.820912293442234, xt = 44.32835361616391, zt = 45.129776133588635
09:07:16.754 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-20T16:00: beta = [1.000000, -0.144816] , mu = 50.08642907225125, xt = 48.68904042987687, zt = 49.44436546265582
09:07:16.769 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-08-29T16:00: beta = [1.000000, 0.192108] , mu = 75.79966137681524, xt = 74.72067927897994, zt = 75.34596880386262
09:07:16.773 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-09-02T16:00: beta = [1.000000, 0.261569] , mu = 81.0811842561594, xt = 79.06375967736685, zt = 79.86176203840046
09:07:16.779 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-09-03T16:00: beta = [1.000000, 0.196609] , mu = 76.14736709491278, xt = 74.3032286257776, zt = 75.29582527764794
09:07:16.789 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-09-04T16:00: beta = [1.000000, 0.205360] , mu = 76.7673889913621, xt = 74.45550016436205, zt = 75.38209286786048
09:07:16.790 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-09-05T16:00: beta = [1.000000, 0.128691] , mu = 70.93386299030476, xt = 69.0108923903937, zt = 70.13111511850958
09:07:16.825 [main] INFO  t.n.a.m.m.e.s.Elliott2005Strategy,26 - recalibration of strategy @ 2014-09-30T16:00: beta = [1.000000, -0.458945] , mu = 24.52457661937424, xt = 23.892396663637847, zt = 24.193388926081134
09:07:16.905 [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.29275894165039
3	2012-06-20T16:00	SELL	XOM	1.0	48.5728759765625
4	2012-06-21T16:00	BUY	XOM	1.0	46.937957763671875
5	2012-07-10T16:00	BUY	XOM	1.0	47.50959777832031
6	2012-07-11T16:00	SELL	XOM	1.0	48.2355842590332
7	2012-08-02T16:00	BUY	XOM	1.0	49.09306335449219
8	2012-08-03T16:00	SELL	XOM	1.0	50.047725677490234
9	2012-10-03T16:00	SELL	XOM	1.0	52.76072311401367
10	2012-11-09T16:00	BUY	XOM	1.0	50.49148941040039
11	2012-11-23T16:00	SELL	XOM	1.0	51.5799674987793
12	2012-11-27T16:00	BUY	XOM	1.0	50.572547912597656
13	2012-12-24T16:00	BUY	XOM	1.0	50.323604583740234
14	2013-01-02T16:00	SELL	XOM	1.0	51.359947204589844
15	2013-02-01T16:00	BUY	XOM	1.0	52.12997055053711
16	2013-02-19T16:00	SELL	XOM	1.0	52.04349899291992
17	2013-02-25T16:00	BUY	XOM	1.0	51.099571228027344
18	2013-02-27T16:00	SELL	XOM	1.0	52.165855407714844
19	2013-03-07T16:00	BUY	XOM	1.0	51.68804931640625
20	2013-03-11T16:00	SELL	XOM	1.0	51.950279235839844
21	2013-03-19T16:00	BUY	XOM	1.0	51.6123161315918
22	2013-03-22T16:00	SELL	XOM	1.0	52.025997161865234
23	2013-04-01T16:00	SELL	XOM	1.0	52.88835144042969
24	2013-04-05T16:00	BUY	XOM	1.0	51.86286544799805
25	2013-04-08T16:00	BUY	XOM	1.0	51.62397766113281
26	2013-04-11T16:00	SELL	XOM	1.0	51.98522186279297
27	2013-04-17T16:00	BUY	XOM	1.0	50.155670166015625
28	2013-04-23T16:00	SELL	XOM	1.0	52.031829833984375
29	2013-04-25T16:00	BUY	XOM	1.0	51.31515884399414
30	2013-05-03T16:00	SELL	XOM	1.0	52.45137023925781
31	2013-05-07T16:00	SELL	XOM	1.0	53.109779357910156
32	2013-05-30T16:00	BUY	XOM	1.0	54.0286750793457
33	2013-06-07T16:00	SELL	XOM	1.0	53.65317153930664
34	2013-06-11T16:00	BUY	XOM	1.0	53.072349548339844
35	2013-06-13T16:00	SELL	XOM	1.0	53.58279037475586
36	2013-06-20T16:00	BUY	XOM	1.0	52.24512481689453
37	2013-06-27T16:00	SELL	XOM	1.0	52.8259391784668
38	2013-07-16T16:00	BUY	XOM	1.0	54.73855972290039
39	2013-08-14T16:00	BUY	XOM	1.0	52.5471305847168
40	2013-11-06T16:00	BUY	CVX	1.0	70.3741455078125
41	2013-11-06T16:00	SELL	XOM	2.0	55.069644927978516
42	2013-11-21T16:00	SELL	CVX	1.0	72.32414245605469
43	2013-11-21T16:00	BUY	XOM	1.0	56.31865692138672
44	2014-05-12T16:00	SELL	XOM	1.0	61.649593353271484
45	2014-05-13T16:00	BUY	XOM	1.0	61.727989196777344
46	2014-05-29T16:00	SELL	XOM	1.0	61.070655822753906
47	2014-05-30T16:00	BUY	XOM	1.0	60.62440872192383
48	2014-06-12T16:00	BUY	XOM	1.0	61.30583953857422
49	2014-07-03T16:00	SELL	XOM	1.0	61.86668014526367
50	2014-08-05T16:00	BUY	XOM	1.0	59.219303131103516
51	2014-08-29T16:00	SELL	XOM	1.0	60.39697265625
52	2014-09-30T16:00	BUY	XOM	1.0	57.11176681518555
09:07:16.909 [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.9499969482421875	0.7071067811865476	Infinity	2.0
XOM	16.885269165039062	64.54236267042542	Infinity	50.0
Total	19.557907104492188	6.931995093846225	Infinity	52.0

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 141120
files/log/SP500-constituents.csv 21718

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