Five-file library (scenarios, priors, dual solver, views, posterior), closed-form checks, a demo with replay, a walk-forward forecast test, the EP_ViewCost indicator and the EP_Sizer expected-shortfall sizing EA, with a README covering the method, the evidence and the layout.
92 lines
5.6 KiB
Markdown
92 lines
5.6 KiB
Markdown
# EntropyPooling
|
|
|
|
Entropy pooling in native MQL5: keep every historical scenario, change only
|
|
the probability attached to each one, and let today's volatility and your own
|
|
views decide the weights instead of the length of a lookback array.
|
|
|
|
Companion code for the MQL5 article: https://www.mql5.com/en/articles/24757
|
|
|
|
## What it does
|
|
|
|
A 250-bar volatility or a historical VaR is a probability vector over the
|
|
history: weight 1/250 on the last 250 bars and exactly zero on everything
|
|
older. That choice forgets stress during calm periods, and it cannot take in
|
|
information the history does not contain. Entropy pooling, from Attilio
|
|
Meucci's *Fully Flexible Views*, replaces it with an explicit one. Choose the
|
|
probabilities closest to a prior, in relative entropy, that satisfy what you
|
|
want to be true: that today's volatility regime applies, that USDJPY
|
|
volatility is 50% higher, that a Swiss franc shock has at least a 1% chance.
|
|
|
|
`CEpSolver` solves the problem through its dual, so it works on one
|
|
multiplier per view rather than one unknown per scenario. The posterior is an
|
|
exponential tilt of the prior, found by projected Newton with a backtracking
|
|
line search, and inequality views are handled as bounds on their multipliers.
|
|
Each multiplier is also a price: the relative entropy a view costs per prior
|
|
standard deviation of its target, which shows which statement is fighting the
|
|
data hardest. `CEpViews` turns means, spreads, tail probabilities, volatilities
|
|
and correlations into the matrix the solver needs, re-solving volatility and
|
|
correlation views as second moments until they hold on their own terms.
|
|
|
|
The most useful statement for risk is not a subjective view at all. It is a
|
|
single mean view on a trailing-volatility state, solved exactly by a bracketed
|
|
scalar Newton iteration. On its own that condition collapses at the edge of
|
|
history: on 20 March 2020 a Gaussian kernel on the same state answers with 4
|
|
effective scenarios. `EpConditionState` gives conditioning a budget, pulling
|
|
the target back towards the prior mean until a minimum number of effective
|
|
scenarios survives, and reports the target it actually used.
|
|
|
|
`EP_Checks.mq5` tests the library against closed-form results on 200,000
|
|
Gaussian scenarios: the exponential tilt, its relative entropy of z^2/2, the
|
|
Black-Litterman mean, the unchanged covariance, the marginal cost against a
|
|
finite difference, and the budget. `EP_WalkForward.mq5` forecasts a five-pair
|
|
basket's next-day VaR and ES on 3,655 days using only the rows before each
|
|
one. Budgeted conditioning has the lowest joint VaR-ES loss and calibrated
|
|
coverage, beats the rolling window significantly, and improves on its own
|
|
decay prior only modestly, at the edge of significance. Against a Gaussian
|
|
kernel it is not significantly better: a mean and variance view on the state
|
|
is mathematically a kernel. What entropy pooling adds is that conditioning and
|
|
any number of views are one problem with one solution.
|
|
|
|
`EP_Sizer.mq5` holds the basket at a fixed daily expected-shortfall budget
|
|
sized by `EP_ViewCost`'s forecast. From 2011 to 2025, realised ES over budget
|
|
was closer to 1 under conditioned sizing than under the rolling window in 13
|
|
of 15 years, with a mean miss of 0.103 against 0.218. The window overshot by
|
|
more than 20% in the years when stress followed calm, 1.68 times the budget in
|
|
2020, when it entered March holding 1.70 times equity in gross notional.
|
|
|
|
## Layout
|
|
|
|
```
|
|
Include/EntropyPooling/Scenarios.mqh joint scenario matrix: shared bar times, book and state columns, replay
|
|
Include/EntropyPooling/Probabilities.mqh priors (uniform, rolling, decay, kernel), effective scenarios, relative entropy
|
|
Include/EntropyPooling/MinRelEntropy.mqh CEpSolver: dual Newton solver with equality and inequality views
|
|
Include/EntropyPooling/Views.mqh CEpViews, the scalar state tilt and budgeted state conditioning
|
|
Include/EntropyPooling/Posterior.mqh weighted moments, exact weighted VaR and ES, blending, indicator buffer map
|
|
Scripts/EP/EP_Checks.mq5 closed-form checks on synthetic Gaussian scenarios
|
|
Scripts/EP/EP_Demo.mq5 priors, conditioning and three views on a basket, with a replay date
|
|
Scripts/EP/EP_WalkForward.mq5 walk-forward VaR and ES: coverage, FZ0 loss, Diebold-Mariano tests
|
|
Indicators/EP/EP_ViewCost.mq5 conditioned VaR and ES per bar, with a forming-bar panel
|
|
Experts/EP/EP_Sizer.mq5 sizes a basket to an expected-shortfall budget from the indicator
|
|
```
|
|
|
|
Run `EP_Checks.mq5` first: every check should pass before anything else is
|
|
worth reading. `EP_Demo.mq5` then prints the book under each probability
|
|
vector for today, or for any past date through its replay input, and
|
|
`EP_WalkForward.mq5` produces the forecast comparison. `EP_Sizer.mq5` loads
|
|
`EP_ViewCost` through `iCustom`, so compile the indicator before the EA.
|
|
|
|
To use your own book, change the symbol list and the signed weights in the
|
|
inputs; the basket defaults to EURUSD, GBPUSD, AUDUSD, USDJPY and USDCHF on
|
|
D1. Any other state variable can replace trailing volatility by adding it as a
|
|
column with `AddColumn`, and any statement expressible as an expectation over
|
|
scenarios can be added as a view.
|
|
|
|
## Disclaimer
|
|
|
|
Educational code. `EP_Sizer` sizes a book; it does not choose one. The default
|
|
book is short the US dollar against the majors, the dollar rose for most of
|
|
the test period, and the account balance falls in every sizing mode. The
|
|
evidence concerns how closely the size keeps its risk budget, not
|
|
profitability. The views mode is not scored, because replaying the same fixed
|
|
views over sixteen years says nothing about them. Test on your own data and
|
|
broker conditions before drawing conclusions.
|