Beyond GARCH (Part VIII): The MMAR Library And Putting it to Work in an Expert Advisor
Introduction
Over the past four articles, we built the MMAR library from the ground up. Part 4 covered partition analysis and scaling extraction; Part 5, spectrum fitting and cascade distribution selection; Part 6, the simulation engine; and Part 7, Monte Carlo volatility forecasting with confidence intervals. Each module was developed, tested, and validated independently. Now we bring them together.
This article completes the series by delivering two components: (1) the CMMAR facade class, which exposes a Fit-and-Forecast API over the four modules; and (2) a working Expert Advisor for MetaTrader 5 that loads data, fits the model, generates a volatility forecast, and reports results. By the end of this article, you will have a complete, self-contained library that any EA can include with a single line and use with three function calls.
We will cover:
- The CMMAR Facade Class
- The Fit Pipeline
- Forecasting and Path Simulation
- The Demo Expert Advisor
- Results and Interpretation
- Conclusion
The CMMAR Facade Class
The facade pattern gives users a single entry point to a complex subsystem. Our CMMAR class wraps CPartitionAnalysis, CSpectrumFitter, CMonteCarlo, and CSimulationEngine behind an interface that requires no knowledge of the internal module interactions. The user provides returns, calls Fit(), then calls Forecast(). Everything else — the tau(q) extraction, the Legendre transform, the distribution competition, the adaptive cascade depth — happens internally:
#ifndef MMAR_MQH #define MMAR_MQH #include "MMARConstants.mqh" #include "PartitionAnalysis.mqh" #include "SpectrumFitter.mqh" #include "MonteCarlo.mqh" //+------------------------------------------------------------------+ //| CMMAR class | //+------------------------------------------------------------------+ class CMMAR { private: CPartitionAnalysis m_partition; CSpectrumFitter m_spectrum; MMARParams m_params; ENUM_MMAR_STATUS m_status; int m_cascade_b; double m_dt_spacing; public: CMMAR(void); ~CMMAR(void); //--- Configuration (call before Fit) void SetPartitionConfig(int dt_min, int dt_max, double spacing = 1.1); void SetMomentConfig(double q_min, double q_max, double q_step); void SetCascadeBase(int b) { m_cascade_b = MathMax(2, b); } void SetSeed(int seed) { MathSrand(seed); } //--- Main pipeline bool Fit(const double &returns[], int n_returns); //--- Forecasting bool Forecast(int horizon_bars, int n_simulations, MMARForecast &result); //--- Single path generation bool SimulatePath(int n_points, double &path[], double &returns[]); //--- Diagnostics MMARParams GetParams(void) { return m_params; } ENUM_MMAR_STATUS GetStatus(void) { return m_status; } bool IsFitted(void) { return m_status == MMAR_STATUS_FITTED; } bool IsMultifractal(void) { return m_params.is_multifractal; } string GetDistributionName(void); };
The public interface has three layers. The configuration layer (SetPartitionConfig, SetMomentConfig, SetCascadeBase, SetSeed) allows fine-tuning before fitting — all parameters have sensible defaults, so this layer is optional. Note that SetCascadeBase and SetSeed are simple inline methods: SetCascadeBase clamps the branching factor to a minimum of 2, and SetSeed delegates directly to MathSrand for reproducible random number generation. The pipeline layer (Fit, Forecast, SimulatePath) is where the work happens. The diagnostics layer (GetParams, GetStatus, IsFitted, IsMultifractal, GetDistributionName) exposes the internal state for logging, decision-making, or display.
It is worth emphasizing that the facade and all underlying modules rely exclusively on MetaTrader 5's Standard Library. Partition analysis uses native matrix and vector types for OLS regression. Spectrum fitting uses ALGLIB's BLEIC optimizer for bounded nonlinear fitting. The simulation engine uses ALGLIB's FFT and Cholesky implementations, along with the Math\Stat library for random number generation. No external DLLs, Python bridges, or third-party dependencies are required. Everything ships with every MetaTrader 5 installation. This makes the library fully portable across any broker and any VPS — if MetaTrader 5 runs, the MMAR library runs.
The class maintains state through the ENUM_MMAR_STATUS enum, which tracks progress through the pipeline:
- MMAR_STATUS_NOT_FITTED — initial state, no data has been processed.
- MMAR_STATUS_PARTITION_ONLY — partition analysis succeeded but spectrum fitting failed. The Hurst exponent and multifractality diagnostics are available, but forecasting is not possible.
- MMAR_STATUS_FITTED — full pipeline succeeded. Both partition analysis and spectrum fitting completed. Forecasting is available.
- MMAR_STATUS_ERROR — a fatal error occurred during partition analysis. No results are available.
This graduated status system means the class degrades gracefully. If the spectrum fitting fails (perhaps because the data is strongly monofractal and the Legendre transform produces too few valid points), the user still has access to the Hurst exponent and the multifractality diagnostics from the partition analysis stage.
Figure 1 animates how the CMMAR facade wraps the four internal modules and how data flows through each API call:

Fig. 1. The CMMAR facade wraps four modules behind a simple API. Fit() orchestrates partition analysis and spectrum fitting; Forecast() delegates to CMonteCarlo, which internally creates CSimulationEngine instances. The user interacts only with the top-level CMMAR class.
The Fit Pipeline
The Fit() method orchestrates the two analytical stages in sequence: partition analysis to extract tau(q) and H, then spectrum fitting to select the cascade distribution. It populates the MMARParams structure with everything downstream modules need:
//+------------------------------------------------------------------+ //| Fit - Run partition analysis + spectrum fitting | //+------------------------------------------------------------------+ bool CMMAR::Fit(const double &returns[], int n_returns) { m_status = MMAR_STATUS_NOT_FITTED; ZeroMemory(m_params); //--- Stage 1: Partition Analysis if(!m_partition.Init(returns, n_returns)) { Print("MMAR::Fit - partition init failed"); m_status = MMAR_STATUS_ERROR; return false; } if(!m_partition.Analyze()) { Print("MMAR::Fit - partition analysis failed"); m_status = MMAR_STATUS_ERROR; return false; } m_params.H = m_partition.GetH(); m_params.sample_volatility = m_partition.GetSampleVolatility(); m_params.mean_r_squared = m_partition.GetMeanRSquared(); m_params.multifractal_score = m_partition.GetMultifractalScore(); m_params.is_multifractal = m_partition.IsMultifractal(); m_partition.GetTauQ(m_params.tau_q, m_params.q_values); //--- Stage 2: Spectrum Fitting double tau[], q_vals[]; m_partition.GetTauQ(tau, q_vals); int n_q = m_partition.GetNumQ(); if(!m_spectrum.Init(q_vals, tau, n_q, m_params.H)) { Print("MMAR::Fit - spectrum init failed (partition results available)"); m_status = MMAR_STATUS_PARTITION_ONLY; return false; } if(!m_spectrum.ComputeSpectrum()) { Print("MMAR::Fit - spectrum computation failed (partition results available)"); m_status = MMAR_STATUS_PARTITION_ONLY; return false; } if(!m_spectrum.FitAllDistributions()) { Print("MMAR::Fit - distribution fitting failed (partition results available)"); m_status = MMAR_STATUS_PARTITION_ONLY; return false; } m_params.dist_type = m_spectrum.GetBestDistribution(); m_spectrum.GetBestParams(m_params.dist_params); //--- Find alpha_0 (spectrum peak) double alpha[], f_alpha[]; m_spectrum.GetSpectrum(alpha, f_alpha); int n_spec = m_spectrum.GetSpectrumSize(); m_params.alpha_0 = alpha[0]; double f_max = f_alpha[0]; for(int i = 1; i < n_spec; i++) { if(f_alpha[i] > f_max) { f_max = f_alpha[i]; m_params.alpha_0 = alpha[i]; } } m_status = MMAR_STATUS_FITTED; return true; }
The method fills the MMARParams structure progressively. After partition analysis, we have H, sample_volatility, mean_r_squared, and the multifractality diagnostics. After spectrum fitting, we add the distribution type, its parameters, and the peak alpha_0 value. The alpha_0 extraction at the end (finding the alpha where f(alpha) is maximum) provides a summary statistic that is useful for reporting but is not strictly needed for forecasting — the distribution parameters already encode everything the cascade generator needs.
Notice how each spectrum-stage failure sets the status to MMAR_STATUS_PARTITION_ONLY rather than MMAR_STATUS_ERROR. This means an EA can check the status and decide: "the data is not strongly multifractal and the spectrum fit failed, but I still have the Hurst exponent — perhaps I should use a simpler model for this period."
Figure 2 visualizes the two-stage pipeline. Stage 1 maps raw returns to H, sample volatility, R², and the multifractal score, and also produces the tau(q) curve. Stage 2 fits four candidate distributions and selects the best one (Binomial in the EURUSD run) to populate MMARParams. The animation also shows the status progression: ERROR if Stage 1 fails; PARTITION_ONLY if only Stage 2 fails; and FITTED if both stages succeed.

Fig. 2. The Fit() pipeline: Stage 1 extracts scaling properties, Stage 2 selects the best cascade distribution, and the status degrades gracefully if either stage fails
Forecasting and Path Simulation
Once the model is fitted, the Forecast() method delegates directly to the CMonteCarlo class we built in Part 7:
//+------------------------------------------------------------------+ //| Forecast - Monte Carlo volatility forecast | //+------------------------------------------------------------------+ bool CMMAR::Forecast(int horizon_bars, int n_simulations, MMARForecast &result) { if(m_status != MMAR_STATUS_FITTED) { Print("MMAR::Forecast - model not fitted"); return false; } CMonteCarlo mc; if(!mc.Init(m_params.H, m_params.dist_type, m_params.dist_params, m_params.sample_volatility, n_simulations, horizon_bars, m_cascade_b)) { Print("MMAR::Forecast - Monte Carlo init failed"); return false; } if(!mc.Run()) { Print("MMAR::Forecast - Monte Carlo run failed"); return false; } result = mc.GetForecast(); return true; }
The method creates a fresh CMonteCarlo instance, passes it all the fitted parameters, runs the simulations, and copies the forecast result to the caller's structure. The status check at the top ensures we never attempt to forecast with an unfitted model.
For users who need individual synthetic paths (for visualization, scenario analysis, or feeding into other models), the SimulatePath() method provides direct access to the simulation engine:
//+------------------------------------------------------------------+ //| SimulatePath - Generate a single MMAR sample path | //+------------------------------------------------------------------+ bool CMMAR::SimulatePath(int n_points, double &path[], double &returns[]) { if(m_status != MMAR_STATUS_FITTED) { Print("MMAR::SimulatePath - model not fitted"); return false; } int cascade_k = (int)MathCeil(MathLog((double)(n_points + 1)) / MathLog((double)m_cascade_b)); int actual_n = (int)MathPow(m_cascade_b, cascade_k); CSimulationEngine engine; if(!engine.Init(m_params.H, m_params.dist_type, m_params.dist_params, m_params.sample_volatility, m_cascade_b, cascade_k)) return false; if(!engine.Generate()) return false; engine.GetProcess(path); int n_ret; engine.GetReturns(returns, n_ret); if(actual_n > n_points) { ArrayResize(path, n_points); ArrayResize(returns, MathMax(0, n_points - 1)); } return true; }
This method uses the same adaptive cascade depth logic as the Monte Carlo module: find the minimum k that covers the requested number of points, generate the full b^k path, then truncate to the requested length. The caller receives both the price-level process and the log-returns, and can use either for their purposes.
The GetDistributionName() utility converts the enum to a human-readable string for logging:
//+------------------------------------------------------------------+ //| GetDistributionName - Human-readable name of fitted distribution | //+------------------------------------------------------------------+ string CMMAR::GetDistributionName(void) { switch(m_params.dist_type) { case MMAR_DIST_NORMAL: return "Normal"; case MMAR_DIST_BINOMIAL: return "Binomial"; case MMAR_DIST_POISSON: return "Poisson"; case MMAR_DIST_GAMMA: return "Gamma"; } return "Unknown"; }
The Demo Expert Advisor
With the facade in place, building an EA that uses the MMAR library is straightforward. The demo EA fits the model on initialization and runs a full volatility forecast. In a production setting, you would refit periodically (e.g., daily or weekly) and use the forecast to adjust position sizing, stop-loss distances, or trading frequency:
//+------------------------------------------------------------------+ //| MMAR Demo EA | //| Copyright 2026, MMQ - Muhammad Minhas Qamar | //| https://www.mql5.com/en/articles/22539 | //+------------------------------------------------------------------+ #property copyright "Copyright 2026, Muhammad Minhas Qamar - MMQ" #property link "https://www.mql5.com/en/articles/22539" #property version "1.00" #property strict #include <MMAR\MMAR.mqh> input int InpBars = 50000; input int InpForecastBars = 7200; input int InpSimulations = 1000; input int InpCascadeB = 2; input int InpSeed = 42; input double InpQMin = 0.01; input double InpQMax = 30.0; input double InpQStep = 0.5; input int InpDtMin = 1; input int InpDtMax = 150; input double InpDtSpacing = 1.1; CMMAR mmar; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ void OnInit() { PrintFormat("========================================"); PrintFormat(" MMAR Demo EA"); PrintFormat(" Symbol: %s | Period: %s", _Symbol, EnumToString(_Period)); PrintFormat("========================================"); //--- Load historical data double close[]; int copied = CopyClose(_Symbol, _Period, 0, InpBars, close); if(copied < 1000) { PrintFormat("Not enough bars: %d (need 1000+)", copied); return; } PrintFormat("Loaded %d bars", copied); //--- Compute log returns double returns[]; int n_returns = copied - 1; ArrayResize(returns, n_returns); for(int i = 0; i < n_returns; i++) returns[i] = MathLog(close[i + 1] / close[i]); //--- Configure and fit mmar.SetSeed(InpSeed); mmar.SetPartitionConfig(InpDtMin, InpDtMax, InpDtSpacing); mmar.SetMomentConfig(InpQMin, InpQMax, InpQStep); mmar.SetCascadeBase(InpCascadeB); uint t0 = GetTickCount(); if(!mmar.Fit(returns, n_returns)) { if(mmar.GetStatus() == MMAR_STATUS_PARTITION_ONLY) { MMARParams params = mmar.GetParams(); PrintFormat("\nPartial fit (spectrum fitting failed):"); PrintFormat(" H = %.4f", params.H); PrintFormat(" Sample vol = %.6f", params.sample_volatility); PrintFormat(" Mean R2 = %.4f", params.mean_r_squared); PrintFormat(" Score = %d/9 | Multifractal: %s", params.multifractal_score, params.is_multifractal ? "YES" : "NO"); Print("Cannot forecast without distribution fit."); } else Print("MMAR fitting failed completely."); return; } uint t_fit = GetTickCount() - t0; //--- Print fit results MMARParams params = mmar.GetParams(); PrintFormat("\n--- Model Fit (%u ms) ---", t_fit); PrintFormat("H (Hurst): %.4f", params.H); PrintFormat("Distribution: %s", mmar.GetDistributionName()); PrintFormat("Alpha_0: %.4f", params.alpha_0); PrintFormat("Sample vol: %.6f", params.sample_volatility); PrintFormat("Mean R2: %.4f", params.mean_r_squared); PrintFormat("Multifractal: %s (score %d/9)", params.is_multifractal ? "YES" : "NO", params.multifractal_score); PrintFormat("Dist params:"); switch(params.dist_type) { case MMAR_DIST_NORMAL: PrintFormat(" alpha_0 = %.6f", params.dist_params[0]); break; case MMAR_DIST_BINOMIAL: PrintFormat(" alpha_min = %.6f", params.dist_params[0]); PrintFormat(" alpha_max = %.6f", params.dist_params[1]); break; case MMAR_DIST_POISSON: PrintFormat(" alpha_0 = %.6f", params.dist_params[0]); break; case MMAR_DIST_GAMMA: PrintFormat(" alpha_0 = %.6f", params.dist_params[0]); PrintFormat(" gamma = %.6f", params.dist_params[1]); break; } //--- Forecast t0 = GetTickCount(); MMARForecast forecast; if(!mmar.Forecast(InpForecastBars, InpSimulations, forecast)) { Print("Forecast failed"); return; } uint t_forecast = GetTickCount() - t0; PrintFormat("\n--- Volatility Forecast (%u ms) ---", t_forecast); PrintFormat("Horizon: %d bars", forecast.forecast_horizon); PrintFormat("Simulations: %d", forecast.n_simulations); PrintFormat("Mean vol: %.6f", forecast.mean_volatility); PrintFormat("Median vol: %.6f", forecast.median_volatility); PrintFormat("Std vol: %.6f", forecast.std_volatility); PrintFormat("95%% CI: [%.6f, %.6f]", forecast.ci_lower, forecast.ci_upper); PrintFormat("Historical: %.6f", params.sample_volatility); PrintFormat("Ratio: %.2f (forecast / historical)", forecast.mean_volatility / params.sample_volatility); //--- Summary PrintFormat("\n========================================"); PrintFormat(" Total time: %u ms", t_fit + t_forecast); PrintFormat("========================================"); } //+------------------------------------------------------------------+
The EA structure is intentionally minimal. All the work happens in OnInit() — the model fits once when the EA is loaded. The CMMAR class cleans up through its destructor. In a production EA, you would store the forecast, refit periodically (perhaps on the first tick of each new day), and use the forecast values to inform trade decisions in OnTick().
The usage pattern reduces to five lines of meaningful code:
//--- Minimal MMAR usage pattern CMMAR mmar; mmar.Fit(returns, n_returns); MMARForecast forecast; mmar.Forecast(7200, 1000, forecast); //--- forecast.mean_volatility is now your estimate
Everything else happens behind those two calls: data loading (50,000 bars), partition-function computation (61 moment orders), the Legendre transform, distribution selection, and 1,000 Monte Carlo simulations generating 8,192-point paths.
Results and Interpretation
Running the Demo EA on EURUSD M10 with 50,000 bars, a 7,200-bar horizon, and 1,000 simulations produces:
========================================
MMAR Demo EA
Symbol: EURUSD | Period: PERIOD_M10
========================================
Loaded 50000 bars
Multifractality check: concavity=1 linearity=1 variation=1 total=3/9
SpectrumFitter: 58 spectrum points, alpha=[0.1351, 0.5149],
peak at alpha_0=0.5149 f=0.9923
Fitting spectrum to 4 distributions...
Normal: SSE=69.033271 alpha_0=0.514942
Binomial: SSE=0.123991 alpha_min=0.188628 alpha_max=0.772413
Poisson: SSE=10.212081 alpha_0=0.514942
Gamma: SSE=0.178587 alpha_0=0.514942 gamma=1.244125
BEST FIT: Binomial (SSE=0.123991, RMSE=0.046236)
--- Model Fit (422 ms) ---
H (Hurst): 0.4817
Distribution: Binomial
Alpha_0: 0.5149
Sample vol: 0.000419
Mean R2: 0.8838
Multifractal: NO (score 3/9)
Dist params:
alpha_min = 0.188628
alpha_max = 0.772413
MonteCarlo: 1000 simulations, horizon=7200 bars, k=13, N=8192
MonteCarlo complete: 1000 sims in 8984 ms
Mean vol: 0.000339 | Std: 0.000008 | Median: 0.000339
95% CI: [0.000322, 0.000353]
--- Volatility Forecast (8984 ms) ---
Horizon: 7200 bars
Simulations: 1000
Mean vol: 0.000339
Median vol: 0.000339
Std vol: 0.000008
95% CI: [0.000322, 0.000353]
Historical: 0.000419
Ratio: 0.81 (forecast / historical)
========================================
Total time: 9406 ms
======================================== Let us interpret these results in terms of what they mean for a trading system:
Model Diagnostics. The Hurst exponent of 0.4817 is slightly below 0.5, suggesting very mild anti-persistence — past trends have a weak tendency to reverse at the M10 level. The multifractal score of 3/9 is below the threshold of 5, meaning this particular 50,000-bar window does not exhibit strong multifractal behavior. However, the spectrum fit still succeeds (the Binomial model achieves an excellent RMSE of 0.046), which means the model can still produce meaningful forecasts. The multifractal flag is a diagnostic, not a gate — the library proceeds with fitting regardless.
The Forecast. The MMAR predicts a forward volatility of 0.000339 (per bar), 19% lower than the historical 0.000419. The 95% confidence interval [0.000322, 0.000353] is tight — the model is highly confident in its estimate. In practical terms, if you were sizing positions based on expected volatility, the MMAR would suggest you can take slightly larger positions than a naive historical-volatility approach would recommend, because it predicts the near future will be calmer than the recent past.
Performance. The total time of 9.4 seconds is dominated by the 1,000 Monte Carlo simulations (8.98 seconds, or about 9 ms per simulation). The fitting stage takes only 422 ms. For a live EA that refits daily, this is perfectly acceptable — even on a modest VPS, a 9-second computation once per day is invisible. If you need faster turnaround (say, refitting hourly), reducing to 100 simulations cuts the Monte Carlo time to under 1 second while still producing a reasonably tight confidence interval.
The Ratio. A forecast/historical ratio of 0.81 means the model believes recent volatility was above-average relative to the structural norm. This is the MMAR's key advantage over GARCH: because it derives its estimate from the scaling structure of the data (a long-run property) rather than from recent squared returns (a short-run property), it is less reactive to volatility spikes. A GARCH model that just witnessed high volatility would forecast continued high volatility (mean-reverting slowly). The MMAR instead says: "the structural properties of this data imply a lower long-run volatility level."
Figure 3 makes this comparison visual. The historical volatility and the MMAR forecast stand side by side — the 19% drop is immediate. The tight 95% confidence interval shows the model is highly confident, and the conceptual contrast at the bottom captures the fundamental difference: GARCH reacts to recent shocks, while the MMAR anchors its estimate to the long-run scaling structure of the data.

Fig. 3. Historical volatility vs. MMAR forecast: the model predicts 19% lower volatility with a tight confidence interval, reflecting its structural rather than reactive approach to estimation
Conclusion
This article completes the Beyond GARCH series. Over eight parts, we have traveled from the theoretical foundations of multifractal analysis (Part 1), through empirical validation and Python prototyping (Parts 2-3), to a complete native MQL5 library (Parts 4-8). The result is a self-contained system that:
- Detects. Multifractal structure in market data using partition function analysis with rigorous statistical diagnostics (Parts 4).
- Fits. The singularity spectrum to four theoretical distributions using bounded nonlinear optimization (Part 5).
- Simulates. Synthetic MMAR paths via multiplicative cascades and Fractional Brownian Motion, using both FFT and Cholesky methods (Part 6).
- Forecasts. Volatility with Monte Carlo simulation, producing point estimates with uncertainty bounds (Part 7).
- Packages. Everything in a clean facade with a three-call API: configure, fit, forecast (this article).
The library is designed for extensibility. Some natural next steps:
- Periodic refitting: Call Fit() on a rolling window (e.g., daily) to track how the model parameters evolve over time. Monitor whether H is stable, whether the winning distribution changes, and whether the multifractal score fluctuates.
- Position sizing: Use the forecast confidence interval to dynamically adjust lot sizes — smaller positions when the CI is wide (high uncertainty), larger when it is narrow.
- Regime detection: Use the multifractal score and Hurst exponent as regime indicators. A jump from H=0.48 to H=0.55 might signal a shift from mean-reversion to trend-following behavior.
- Multi-timeframe: Run partition analysis on multiple timeframes simultaneously and compare their Hurst exponents and multifractal scores for a richer market characterization.
The MMAR is not a trading strategy — it is a volatility model. It tells you how much the market is likely to move, not which direction. Combining it with a directional model (trend filters, mean-reversion signals, or machine learning classifiers) is where the real edge emerges. The volatility forecast provides the denominator: given my directional conviction, how much risk should I take? That question is what this library answers.
The programs presented in this series are intended for educational purposes only. They are not designed for use in live trading and are not optimized for performance in real-market conditions. The MMAR library serves as a foundation for volatility research; always validate thoroughly on demo accounts and consider the computational cost of Monte Carlo simulation before deploying in production.
Getting the Source Code via MQL5 Algo Forge
All source files are attached to this article below, but the full repository is also available on MQL5 Algo Forge, the community's Git-based platform for sharing and collaborating on trading projects.
The table below lists every file in the complete MMAR library, accumulated across all eight parts of this series:
| File name | Description |
|---|---|
| MQL5\Include\MMAR\MMARConstants.mqh | Shared enumerations, structures, and type definitions for the MMAR library (Part 4) |
| MQL5\Include\MMAR\OLS.mqh | Ordinary Least Squares regression via SVD pseudo-inverse with full diagnostics (Part 4) |
| MQL5\Include\MMAR\HurstGHE.mqh | Generalized Hurst Exponent estimator, fallback method (Part 4) |
| MQL5\Include\MMAR\PartitionAnalysis.mqh | Multifractal partition function analysis with scaling diagnostics (Part 4) |
| MQL5\Include\MMAR\SpectrumFitter.mqh | Multifractal spectrum computation and four-distribution fitting via BLEIC optimization (Part 5) |
| MQL5\Include\MMAR\SimulationEngine.mqh | MMAR simulation engine: multiplicative cascade, FBM generation (Davies-Harte and Cholesky), and time-deformation composition (Part 6) |
| MQL5\Include\MMAR\MonteCarlo.mqh | Monte Carlo volatility forecasting: runs N MMAR simulations and produces mean, median, std, and 95% CI (Part 7) |
| MQL5\Include\MMAR\MMAR.mqh | Top-level facade class: Fit() and Forecast() API (Part 8) |
| MQL5\Scripts\MMAR\MMAR_PartitionTest.mq5 | Test script for partition analysis on live market data (Part 4) |
| MQL5\Scripts\MMAR\MMAR_SpectrumTest.mq5 | Test script for the full partition + spectrum pipeline on live market data (Part 5) |
| MQL5\Scripts\MMAR\MMAR_SimulationTest.mq5 | Test script validating cascade invariants, FBM properties, and multi-run consistency (Part 6) |
| MQL5\Scripts\MMAR\MMAR_MonteCarloTest.mq5 | End-to-end test script: partition analysis + spectrum fitting + Monte Carlo forecasting (Part 7) |
| MQL5\Experts\MMAR\MMAR_Demo_EA.mq5 | Demo Expert Advisor demonstrating the complete MMAR pipeline (Part 8) |
Warning: All rights to these materials are reserved by MetaQuotes Ltd. Copying or reprinting of these materials in whole or in part is prohibited.
This article was written by a user of the site and reflects their personal views. MetaQuotes Ltd is not responsible for the accuracy of the information presented, nor for any consequences resulting from the use of the solutions, strategies or recommendations described.
OrderSend retries and circuit breaker in MQL5
Market Simulation (Part 24): Position View (II)
Strategy Configuration via External JSON Files in MQL5: Replacing Input Parameters with a Runtime Config Loader
From Basic to Intermediate: Object Events (IV)
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use