//+------------------------------------------------------------------+ //| base.mqh | //| Copyright 2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com" #include"..\..\np.mqh" #include"..\Utility\wald.mqh" #include"..\..\Regression\OLS.mqh" #include"..\..\Regression\utils.mqh" //--- Matrix/Vector initial allocation shortcuts #define EMPTY_VECTOR vector::Zeros(0) #define EMPTY_MATRIX matrix::Zeros(0,0) //--- Declaration of zero-length arrays for system reset states vector EMPTY_VECTOR_ARRAY[]; matrix EMPTY_MATRIX_ARRAY[]; //+------------------------------------------------------------------+ //| Covariance calculation matrix type mapping methods | //+------------------------------------------------------------------+ enum ENUM_COVAR_TYPE { COVAR_CLASSIC = 0, // Standard MLE covariance calculation assuming standard residual profiles COVAR_ROBUST // Bollerslev-Wooldridge QMLE sandwich estimator handling heteroskedastic deviations }; //+------------------------------------------------------------------+ //| Multi-step conditional value forecasting deployment states | //+------------------------------------------------------------------+ enum ENUM_FORECAST_METHOD { FORECAST_ANALYTIC = 0, // Deterministic expected value closed-form formulas calculations FORECAST_SIMULATION, // Parametric Monte Carlo generation pathways using normal/target error distributions FORECAST_BOOTSTRAP // Non-parametric path generations re-sampling directly from historical empirical residuals }; //+------------------------------------------------------------------+ //| Multi-step forecasting output coordinate system alignment | //+------------------------------------------------------------------+ enum ENUM_FORECAST_ALIGNMENT { ALIGN_ORIGIN = 0, // Output indexed relative to the forecast anchor execution origin bar time ALIGN_TARGET // Output chronologically maps directly to absolute future target calendar bars }; //+------------------------------------------------------------------+ //| Configured mean structure equations models | //+------------------------------------------------------------------+ enum ENUM_MEAN_MODEL { MEAN_CONSTANT = 0, // ConstantMean model MEAN_ZERO, // Zero Mean model MEAN_AR, // Autoregressive process tracking internal lag intervals MEAN_ARX, // Autoregressive process integrated with exogenous input features matrices MEAN_HAR, // Heterogeneous AR (Daily, Weekly, Monthly smoothed components processing) MEAN_HARX // Heterogeneous AR supported by exogenous structural metrics matrices }; //--- Text mapping descriptors matching ENUM_MEAN_MODEL entries const string MEAN_MODELS = "Constant Mean,Zero Mean,AR,AR-X,HAR,HAR-X"; //+------------------------------------------------------------------+ //| Configured conditional volatility structure models | //+------------------------------------------------------------------+ enum ENUM_VOLATILITY_MODEL { VOL_CONST = 0, // Homoskedastic variance baseline profiles VOL_ARCH, // Autoregressive Conditional Heteroskedasticity (Linear lag squares mapping) VOL_AVARCH, // Absolute Value ARCH framework configurations VOL_AVGARCH, // Absolute Value GARCH process modeling variations VOL_TARCH, // Threshold ARCH / ZARCH threshold tracking handling asymmetric volatility shocks VOL_GARCH, // Generalized ARCH processes combining structural innovations and past variance memory VOL_GJR_GARCH, // Glosten-Jagannathan-Runkle GARCH tracking sign-dependent asymmetric leverage adjustments VOL_HARCH, // Heterogeneous ARCH handling multi-scale localized aggregate time horizons VOL_FIGARCH, // Fractionally Integrated GARCH mapping long-memory long-term decay processes VOL_EGARCH // Exponential Generalized ARCH processes }; //--- Text mapping descriptors matching ENUM_VOLATILITY_MODEL entries const string VOLATILITY_MODELS = "Constant Variance,ARCH,AVARCH,AVGARCH,TARCH ZARCH,GARCH,GJR GARCH,HARCH,FIGARCH,EGARCH"; //+------------------------------------------------------------------+ //| Error distribution tracking profiles for optimization | //+------------------------------------------------------------------+ enum ENUM_DISTRIBUTION_MODEL { DIST_NORMAL = 0, // Gaussian bell-curve white noise tracking profiles DIST_STUDENT, // Standardized Student's t distribution tracking fat-tailed distributions DIST_SKEW_STUDENT, // Skewed Student's t handling both tail obesity and structural asymmetry directional trends DIST_GEN_ERROR, // Generalized Error Distribution modifying kurtosis mapping dynamically }; //--- Text mapping descriptors matching ENUM_DISTRIBUTION_MODEL entries const string DISTRIBUTIONS = "Normal,Standardized Student's t,Standardized Skew Student's t,Generalized Error Distribution"; //+------------------------------------------------------------------+ //| Rank verification check for multicollinearity constant checking | //+------------------------------------------------------------------+ bool implicit_constant(matrix &exog_data) { ulong nobs = exog_data.Rows(); matrix temp(nobs, exog_data.Cols() + 1); vector ones = vector::Ones(nobs); // Prepend a strict linear column of 1.0 scalars to the dataset copy canvas matrix temp.Col(ones, 0); for(ulong i = 1; i < temp.Cols(); ++i) temp.Col(exog_data.Col(i - 1), i); ulong rank = temp.Rank(); // If appending a constant does not alter matrix column rank, an implicit constant already exists return (rank == exog_data.Cols()); } //+------------------------------------------------------------------+ //| Reindex helper: Prepends empty values to stretch 3D matrix arrays| //+------------------------------------------------------------------+ bool _reindex(ulong actual, matrix& in[], matrix& out[]) { ulong obs = ulong(in.Size()); if(actual > obs) { ArrayResize(out, int(actual)); matrix temp = matrix::Zeros(in[0].Rows(), in[0].Cols()); temp.Fill(EMPTY_VALUE); // Pad the array head with systemic missing value constants // Chronologically shift old matrix windows forward, padding the prefix timeline space for(uint i = 0; i < uint(actual); ++i) out[i] = (i < uint(actual - obs)) ? temp : in[i - uint(actual - obs)]; } return true; } //+------------------------------------------------------------------+ //| Reindex helper: Prepends placeholder rows to matrices | //+------------------------------------------------------------------+ matrix _reindex(ulong actual, matrix& in) { ulong obs = ulong(in.Rows()); if(actual > obs) { matrix out(actual, in.Cols()); vector temp = vector::Zeros(in.Cols()); temp.Fill(EMPTY_VALUE); // Inject EMPTY_VALUE placeholder horizontal arrays to fill newly allocated historic row slots for(ulong i = 0; i < actual; ++i) out.Row((i < (actual - obs)) ? temp : in.Row(i - (actual - obs)), i); return out; } return in; } //+------------------------------------------------------------------+ //| Reindex helper: Prepends placeholder items to linear vectors | //+------------------------------------------------------------------+ vector _reindex(ulong actual, vector& in) { ulong obs = ulong(in.Size()); if(actual > obs) { vector out(actual); double temp = EMPTY_VALUE; // Backfill structural array headers with system NaN states to align mismatched sizing loops for(ulong i = 0; i < actual; ++i) out[i] = (i < (actual - obs)) ? temp : in[i - (actual - obs)]; return out; } return in; } //+------------------------------------------------------------------+ //| Generates standard optimization parameter nomenclature strings | //+------------------------------------------------------------------+ string common_names(ulong p, ulong o, ulong q) { string names = "omega"; // Baseline variance constant term label index // Map conditional variance shock lag parameters labels (ARCH) for(ulong i = 0; i < p; ++i) names += ",alpha[" + string(i + 1) + "]"; // Map asymmetric threshold shock lag parameters labels (TARCH/GJR) for(ulong i = 0; i < o; ++i) names += ",gamma[" + string(i + 1) + "]"; // Map historic variance persistence lag parameters labels (GARCH) for(ulong i = 0; i < q; ++i) names += ",beta[" + string(i + 1) + "]"; return names; } //+------------------------------------------------------------------+ //| Comprehensive specification payload structure for ARCH models | //+------------------------------------------------------------------+ struct ArchParameters { // --- Data & Core Configuration vector observations; // Vector tracking endog target returns data series matrix exog_data; // Matrix tracking exogenous external regressor blocks vector mean_lags; // Vector defining selected conditional mean lag lengths ENUM_MEAN_MODEL mean_model_type; // Specified mean structural method profile reference ENUM_VOLATILITY_MODEL vol_model_type; // Specified volatility variance framework engine reference ENUM_DISTRIBUTION_MODEL dist_type; // Specified baseline conditional probability density model ulong holdout_size; // Out-of-sample data truncation window count bounds bool is_rescale_enabled; // Scale switch flag to normalize inputs to unit variances double scaling_factor; // Internal scale factor used for numerical optimization convergence // --- Mean Model Parameters bool include_constant; // Conditional mean calculation model constant flag bool use_har_rotation; // Flag enabling volatility horizon mapping blocks rotations // --- Volatility Process Parameters (GARCH/ARCH) int vol_rng_seed; // Random initialization seeding value used for variance simulations ulong garch_p; // Shock innovations lag loop parameter allocation bounds (ARCH) ulong garch_o; // Asymmetric conditional volatility component bounds (Leverage) ulong garch_q; // Historical tracking persistence variance memory depth (GARCH) double vol_power; // Exponent index scaling term used in variance conversions ulong figarch_truncation; // Expansion step cutoff limit boundary tracking fractional integration weights vector harch_lags; // Structural lookback specification arrays targeted by HARCH processes long sample_start_idx; // Time-series array starting tracking coordinate pointer long sample_end_idx; // Time-series array termination tracking coordinate pointer ulong min_bootstrap_sims; // Paths count boundary required for empirical bootstraps execution loops // --- Distribution Parameters vector dist_init_params; // Initial parameter values array tracking distribution bounds shapes (e.g., DoF) int dist_rng_seed; // Seeding index value targeted by probability density generator paths // Default Constructor: Defines base mathematical parameter values ArchParameters(void) { observations = vector::Zeros(0); exog_data = matrix::Zeros(0,0); mean_lags = vector::Zeros(0); vol_model_type = WRONG_VALUE; dist_type = WRONG_VALUE; holdout_size = 0; scaling_factor = 1.0; is_rescale_enabled = false; mean_model_type = WRONG_VALUE; include_constant = true; use_har_rotation = false; vol_rng_seed = 0; garch_p = 1; garch_o = 0; garch_q = 1; figarch_truncation = 1000; harch_lags = vector::Ones(1); vol_power = 2.; sample_start_idx = 1; sample_end_idx = -1; min_bootstrap_sims = 100; dist_init_params = vector::Zeros(0); dist_rng_seed = 0; } // Copy Constructor: Securely replicates structural properties between instances ArchParameters(ArchParameters &other) { observations = other.observations; exog_data = other.exog_data; scaling_factor = other.scaling_factor; mean_lags = other.mean_lags; vol_model_type = other.vol_model_type; dist_type = other.dist_type; holdout_size = other.holdout_size; is_rescale_enabled = other.is_rescale_enabled; include_constant = other.include_constant; use_har_rotation = other.use_har_rotation; vol_rng_seed = other.vol_rng_seed; garch_p = other.garch_p; garch_o = other.garch_o; garch_q = other.garch_q; vol_power = other.vol_power; figarch_truncation = other.figarch_truncation; harch_lags = other.harch_lags; sample_start_idx = other.sample_start_idx; sample_end_idx = other.sample_end_idx; min_bootstrap_sims = other.min_bootstrap_sims; dist_init_params = other.dist_init_params; dist_rng_seed = other.dist_rng_seed; } // Assignment Operator: Copies structural contents safely across equal data types void operator=(ArchParameters &other) { observations = other.observations; exog_data = other.exog_data; scaling_factor = other.scaling_factor; mean_lags = other.mean_lags; vol_model_type = other.vol_model_type; dist_type = other.dist_type; holdout_size = other.holdout_size; is_rescale_enabled = other.is_rescale_enabled; include_constant = other.include_constant; use_har_rotation = other.use_har_rotation; vol_rng_seed = other.vol_rng_seed; garch_p = other.garch_p; garch_o = other.garch_o; garch_q = other.garch_q; vol_power = other.vol_power; figarch_truncation = other.figarch_truncation; harch_lags = other.harch_lags; sample_start_idx = other.sample_start_idx; sample_end_idx = other.sample_end_idx; min_bootstrap_sims = other.min_bootstrap_sims; dist_init_params = other.dist_init_params; dist_rng_seed = other.dist_rng_seed; } }; //+------------------------------------------------------------------+ //| Storage container tracking compiled Monte Carlo tracking paths | //+------------------------------------------------------------------+ struct ArchSimulation { matrix values[]; // Simulated absolute asset return target metrics paths matrix residuals[]; // Simulated mean-subtracted pure pricing error tracks matrix variances[]; // Generated actual underlying conditional variance paths matrix residual_variances[]; // Tracked variance paths modified by transformation scale factors // Default Constructor ArchSimulation(void) {} // Parameterized Constructor copying 3D grid systems cleanly via specialized utility functions ArchSimulation(matrix& _values[], matrix& _residuals[], matrix& _variances[], matrix& _residual_variances[]) { np::copy3D(_values, values); np::copy3D(_residuals, residuals); np::copy3D(_variances, variances); np::copy3D(_residual_variances, residual_variances); } // Copy Constructor ArchSimulation(ArchSimulation &other) { np::copy3D(other.values, values); np::copy3D(other.residuals, residuals); np::copy3D(other.variances, variances); np::copy3D(other.residual_variances, residual_variances); } // Assignment Operator void operator=(ArchSimulation &other) { np::copy3D(other.values, values); np::copy3D(other.residuals, residuals); np::copy3D(other.variances, variances); np::copy3D(other.residual_variances, residual_variances); } }; //+------------------------------------------------------------------+ //| Consolidated forecast results object tracking multi-step points | //+------------------------------------------------------------------+ struct ArchForecast { matrix mean; // Aggregated expected mean point projections matrix matrix variance; // Aggregated expected conditional point variance predictions matrix matrix residual_variance; // Non-transformed expected residual point variance projection matrix ArchSimulation simulation; // Internal tracking structure storing multi-path simulation properties // Default Constructor ArchForecast(void) { mean = variance = residual_variance = matrix::Zeros(0,0); } // Parameterized Constructor mapping both matrix point values and path array systems ArchForecast(ulong startindex, matrix& _mean, matrix& _variance, matrix& _res_var, matrix& _values[], matrix& _residuals[], matrix& _variances[], matrix& _residual_variances[]) { mean = _mean; variance = _variance; residual_variance = _res_var; np::copy3D(_values, simulation.values); np::copy3D(_residuals, simulation.residuals); np::copy3D(_variances, simulation.variances); np::copy3D(_residual_variances, simulation.residual_variances); } // Copy Constructor ArchForecast(ArchForecast &other) { mean = other.mean; variance = other.variance; residual_variance = other.residual_variance; simulation = other.simulation; } // Assignment Operator void operator=(ArchForecast &other) { mean = other.mean; variance = other.variance; residual_variance = other.residual_variance; simulation = other.simulation; } }; //+------------------------------------------------------------------+ //+------------------------------------------------------------------+