Aufbau von Volatilitätsmodellen in MQL5 (Teil I): Die erste Implementierung
Einführung
In diesem Artikel stellen wir eine MQL5-Bibliothek zur Modellierung und Prognose von Volatilität vor. Das primäre Ziel ist es, ein flexibles Werkzeug für die Spezifikation verschiedener Arten von Volatilitätsprozessen bereitzustellen. Diese Werkzeuge werden von einer Reihe von analytischen Hilfsmitteln begleitet, die zur Quantifizierung der Qualität der erstellten Modelle dienen. Wir werden die Konstruktion verschiedener Volatilitätsprozesse aus der ARCH- und GARCH-Familie in MQL5 demonstrieren.
Ein Überblick über den Code
Die hier vorgestellte Bibliothek ist vom Python-Paket arch inspiriert, einem spezialisierten Toolkit für die Finanzökonometrie, das sich auf Autoregressive Conditional Heteroskedasticity (ARCH)- und Generalized ARCH (GARCH)-Modelle konzentriert. Während die Hauptfunktion des Pakets arch in der Implementierung verschiedener Volatilitätsmodelle besteht, bietet es auch verschiedene Optionen für die Modellierung der Mittelwertgleichung, wie z. B. konstante Mittelwerte, Nullmittel oder autoregressive (AR) Modelle. Ferner können die Nutzer verschiedene Verteilungen für standardisierte Residuen angeben, einschließlich Normal-, Student's t- und Skewed Student's t-Verteilungen. Unser Ziel ist es, diese Funktionalität nativ in MQL5 abzubilden.

Die Architektur dieser nativen Implementierung ist modular und entkoppelt den Mittelwertprozess von dem Volatilitätsprozess und der Fehlerverteilung. Folglich ist ein Modell eine Zusammensetzung dieser drei unterschiedlichen Komponenten. Der Mittelwertprozess dient als primäre Komponente, an die die anderen angeschlossen sind; insbesondere wird die gemeinsame Schätzung aller Parameter ausschließlich über diese zentrale Komponente verwaltet. Jedes Element wird als Basisklasse implementiert, wobei die Unterklassen spezifische Variationen darstellen.
Alle Klassen innerhalb der Bibliothek folgen einer standardisierten Struktur. Jeder verfügt über einen parametrischen Konstruktor zusätzlich zu einem Standardkonstruktor. Außerdem enthält jede Klasse eine Methode initialize(), die aufgerufen werden muss, wenn eine Instanz über den Standardkonstruktor erstellt wird. Der Einfachheit halber wird die Methode initialize() implizit aufgerufen, wenn ein parametrischer Konstruktor verwendet wird. In den folgenden Abschnitten wird die Implementierung für die Mittelwertprozesse, die Volatilitätsprozesse und die Fehlerverteilungen erörtert.
Konfigurieren eines Modells
Der Code für die Modellierung des bedingten Mittelwerts befindet sich in mean.mqh. In dieser Datei wird die Klasse HARX als Basistyp für alle Mittelwertmodell-Implementierungen definiert. Wie bereits erwähnt, dienen Mittelwertmodelle auch als primäre Schnittstelle für ein vollständiges Volatilitätsmodell. Diese Klasse bietet die erforderlichen Funktionen für die Anpassung von Modellen an Daten und die Erstellung von Prognosen.
//+------------------------------------------------------------------+ //| Heterogeneous Autoregression (HAR) | //+------------------------------------------------------------------+ class HARX: public CArchModel { protected: bool _initialize(ArchParameters &vol_dist_params); public: HARX(void):m_extra_simulation_params(0) HARX(ArchParameters& model_specification) ~HARX(void) bool initialize(ArchParameters& vol_dist_params) matrix get_x(void) { return m_model_spec.x; } matrix get_regressors(void) { return m_regressors; } vector get_y(void) { return m_model_spec.y; } virtual vector resids(vector ¶ms, vector &y, matrix ®ressors); virtual ulong num_params(void); bool set_volatility_process(CVolatilityProcess* &vp); bool set_distribution(CDistribution* &dist); virtual matrix simulate(vector ¶ms, ulong nobs, ulong burn, vector &initial_vals,matrix &x, vector &initial_vals_vol); ArchForecast forecast(ulong horizon = 1, long start = -1, ENUM_FORECAST_METHOD method=FORECAST_ANALYTIC, ulong simulations=1000, uint seed=0); ArchForecast forecast(matrix& x[],ulong horizon = 1, long start = -1, ENUM_FORECAST_METHOD method=FORECAST_ANALYTIC, ulong simulations=1000, uint seed=0); virtual ArchForecast forecast(vector& params, matrix& x[],ulong horizon = 1, long start = -1, ENUM_FORECAST_METHOD method=FORECAST_ANALYTIC, ulong simulations=1000, uint seed=0); ArchModelFixedResult fix(vector& params,long first_obs = 0, long last_obs = -1); ArchModelResult fit(double scaling = 1.0, uint maxits = 0, ENUM_COVAR_TYPE cov_type = COVAR_ROBUST, long first = 0, long last = -1, double tol = 1e-9, bool guardsmoothness=false, double gradient_test_step = 0.0); ArchModelResult fit(vector& startingvalues,vector& backcast, double scaling = 1.0, uint maxits = 0, ENUM_COVAR_TYPE cov_type = COVAR_ROBUST, long first = 0, long last = -1, double tol = 1e-9, bool guardsmoothness=false, double gradient_test_step = 0.0); };
Variationen von Mittelwertmodellen sind als Unterklassen der Klasse HARX implementiert. Die parametrischen Konstruktoren für alle Mittelwertmodelle sowie ihre Methoden initialize() haben einen einzigen Eingabeparameter gemeinsam: eine nutzerdefinierte Struktur namens ArchParameters.
struct ArchParameters { // --- Data & Core Configuration vector observations; matrix exog_data; vector mean_lags; ENUM_MEAN_MODEL mean_model_type; ENUM_VOLATILITY_MODEL vol_model_type; ENUM_DISTRIBUTION_MODEL dist_type; ulong holdout_size; bool is_rescale_enabled; double scaling_factor; // --- Mean Model Parameters bool include_constant; bool use_har_rotation; // --- Volatility Process Parameters (GARCH/ARCH) int vol_rng_seed; ulong garch_p; ulong garch_o; ulong garch_q; double vol_power; long sample_start_idx; long sample_end_idx; ulong min_bootstrap_sims; // --- Distribution Parameters vector dist_init_params; int dist_rng_seed; };
Diese Struktur kapselt alle Variablen, die zur Instanziierung eines vollständigen Volatilitätsmodells erforderlich sind. Seine Eigenschaften sind im Folgenden aufgeführt.
| Eigenschaft | Datentyp | Beschreibung |
|---|---|---|
| observations | vector | Dieser Vektor sollte die zu modellierenden Zeitreihen enthalten. |
| exog_data | matrix | Dies ist eine optionale Matrix für alle exogenen Variablen, die in das Modell aufgenommen werden sollen. Jede Spalte steht für eine Variable, und die Anzahl der Zeilen muss der Länge der abhängigen Variable entsprechen, die in der Eigenschaft y der Struktur definiert ist. |
| mean_lags | vector | Hier können die Nutzer beliebige Verzögerungen für einen AR- oder HAR-Prozess angeben. Bei einem AR-Modell sind die Verzögerungen einfach Verweise auf frühere Werte im Verhältnis zum aktuellen Wert. Diese Verzögerungen können zusammenhängend oder nicht zusammenhängend sein. Bei einem HAR-Prozess stellen die Verzögerungswerte Periodenlängen oder Rückblicke dar, über die Durchschnittswerte berechnet werden. |
| mean_model_type | enum ENUM_MEAN_MODEL | Diese Enumeration gibt explizit das Mittelwertverfahren an, das zur Modellierung des Erwartungswertes der abhängigen Variable verwendet wird. Derzeit sind sechs Mittelwertmodelle implementiert: konstanter Mittelwert, Null-Mittelwert sowie AR- und HAR-Prozesse, jeweils mit oder ohne exogene Variablen. |
| vol_model_type | enum ENUM_VOLATILITY_MODEL | Diese Eigenschaft definiert den Volatilitätsprozess, der zur Modellierung der bedingten Varianz der abhängigen Variable y verwendet wird. Es stehen sieben Optionen zur Verfügung, die von konstanter Varianz bis zu verschiedenen ARCH- und GARCH-Familien von Volatilitätsprozessen reichen. Die Standardoption ist der Prozess der konstanten Varianz. |
| dist_type | enum ENUM_DISTRIBUTION_MODEL | Diese Eigenschaft ist eine Enumeration, die die Fehlerverteilung für das vollständige Modell festlegt. Derzeit stehen vier Verteilungen zur Auswahl: die Normalverteilung, die Student's t-Verteilung, die Skewed Student's t-Verteilung und die Generalized Error Distribution (GED). Die Standardeinstellung ist die Normalverteilung. |
| holdout_size | unsigned long | Diese Eigenschaft gibt die Anzahl der Beobachtungen an, die bei der Anpassung des Modells an die Daten nicht berücksichtigt werden. |
| is_rescale_enabled | bool | Dieses boolesche Flag gibt an, ob der Maßstab der Daten überprüft werden soll. Wenn diese Option auf „true“ gesetzt ist, bewertet das Modell die Skalierung der Daten; wenn eine Neuskalierung erforderlich ist, wird eine Warnung an das MetaTrader 5-Terminal ausgegeben, die den Nutzer auf die Skalierung der Daten hinweist, zusammen mit dem empfohlenen Skalierungsfaktor. |
| include_constant | bool | Diese boolesche Eigenschaft gibt an, ob eine Konstante in das Mittelwertmodell aufgenommen werden soll. |
| use_har_rotation | bool | Diese Eigenschaft ist nur relevant, wenn ein HAR-Mittelwertmodell mit Verzögerungen spezifiziert wird. Bei der Einstellung true wird festgelegt, dass die Mittelwertbildung über nicht überlappende Zeiträume erfolgen soll. Nehmen wir zum Beispiel an, dass die Lags {1, 5, 22} angegeben sind: Wenn diese Eigenschaft falsch ist, verwendet das Modell Durchschnittswerte über die vorherigen 1, 5 und 22 Werte der abhängigen Variable. Im umgekehrten Fall werden die Durchschnittswerte unter Verwendung von disjunkten Fenstern berechnet, und zwar für die erste Verzögerung (1), den Zeitraum von 2 bis 5 und den Zeitraum von 6 bis 22. |
| vol_rng_seed | integer | Dies ist ein optionaler Startwert für den Zufallszahlengenerator, der vom Volatilitätsprozess verwendet wird. |
| garch_p | unsigned long | Der p-Parameter für ARCH/GARCH-Prozesse. |
| garch_o | unsigned long | Der Parameter o für Prozesse vom Typ GARCH. |
| garch_q | unsigned long | Der q-Parameter für Prozesse vom Typ GARCH. |
| vol_power | double | Der Power-Parameter eines Volatilitätsprozesses vom Typ GARCH. |
| min_bootstrap_sims | unsigned long | Dies ist die Mindestanzahl der Bootstraps, die bei Prognosen mit der Bootstrap-Methode verwendet werden. |
| dist_init_params | vector | Dieser Vektor enthält die Anfangsparameter für die Fehlerverteilung. |
| dist_rng_seed | integer | Dies ist ein optionaler Startwert für den Zufallszahlengenerator, der von der angegebenen Verteilung verwendet wird. |
Eine ArchParameters-Variable muss deklariert und konfiguriert werden, bevor sie entweder an den parametrischen Konstruktor eines Mittelwertmodells oder an dessen Methode initialize() übergeben wird.
Die Methode initialize() ist für die Validierung aller Parameter zuständig, um sicherzustellen, dass sie dem ausgewählten Mittelwertprozess, Volatilitätsprozess und der Fehlerverteilung korrekt entsprechen. Kleinere Konflikte, die in dieser Phase festgestellt werden, werden in aller Ruhe korrigiert.
bool _initialize(ArchParameters &vol_dist_params) { if(m_model_spec.mean_model_type!=WRONG_VALUE && vol_dist_params.mean_model_type!=WRONG_VALUE && vol_dist_params.mean_model_type!=m_model_spec.mean_model_type) { m_initialized = false; Print(__FUNCTION__" Incorrect initialization of mean model. \nMake sure input parameters correspond with the correct class "); return false; } if(m_model_spec.mean_model_type!=WRONG_VALUE && vol_dist_params.mean_model_type==WRONG_VALUE) vol_dist_params.mean_model_type = m_model_spec.mean_model_type; m_model_spec = vol_dist_params; switch(m_model_spec.mean_model_type) { case MEAN_CONSTANT: m_model_spec.mean_lags = vector::Zeros(0); m_name = "Constant Mean"; m_model_spec.include_constant = true; m_model_spec.use_har_rotation = false; break; case MEAN_AR: m_model_spec.use_har_rotation = false; m_model_spec.exog_data = matrix::Zeros(0,0); m_name = "AR"; break; case MEAN_ARX: m_model_spec.use_har_rotation = false; m_name ="AR-X"; break; case MEAN_HAR: m_model_spec.exog_data = matrix::Zeros(0,0); m_name = "HAR"; break; case MEAN_HARX: m_name = "HAR-X"; break; case MEAN_ZERO: m_model_spec.exog_data=matrix::Zeros(0,0); m_model_spec.mean_lags = vector::Zeros(0); m_model_spec.include_constant = false; m_model_spec.use_har_rotation = false; m_name = "Zero Mean"; break; default: m_name = "HAR-X"; break; } m_fit_indices = vector::Zeros(2); m_fit_indices[1] = (m_model_spec.observations.Size())?double(m_model_spec.observations.Size()):-1.; if(m_model_spec.mean_lags.Size()) { switch(m_model_spec.mean_model_type) { case MEAN_AR: case MEAN_ARX: m_lags = matrix::Zeros(2,m_model_spec.mean_lags.Size()); m_lags.Row(m_model_spec.mean_lags,0); m_lags.Row(m_model_spec.mean_lags,1); break; case MEAN_HAR: case MEAN_HARX: m_lags = matrix::Zeros(1,m_model_spec.mean_lags.Size()); m_lags.Row(m_model_spec.mean_lags,0); break; } } else m_lags = matrix::Zeros(0,0); m_constant = m_model_spec.include_constant; m_rescale = m_model_spec.is_rescale_enabled; m_rotated = m_model_spec.use_har_rotation; m_holdback = m_model_spec.holdout_size; m_initialized = _init_model(); if(!m_initialized) return false; m_num_params = num_params(); if(CheckPointer(m_vp)==POINTER_DYNAMIC) delete m_vp; m_vp = NULL; switch(vol_dist_params.vol_model_type) { case VOL_CONST: m_vp = new CConstantVariance(m_model_spec.vol_rng_seed,m_model_spec.min_bootstrap_sims); break; case VOL_ARCH: m_vp = new CArchProcess(m_model_spec.garch_p,m_model_spec.vol_rng_seed,m_model_spec.min_bootstrap_sims); break; case VOL_GARCH: m_vp = new CGarchProcess(m_model_spec.garch_p,m_model_spec.garch_q,m_model_spec.vol_rng_seed,m_model_spec.min_bootstrap_sims); break; default: m_vp = new CConstantVariance(m_model_spec.vol_rng_seed,m_model_spec.min_bootstrap_sims); break; } if(CheckPointer(m_distribution)==POINTER_DYNAMIC) delete m_distribution; m_distribution = NULL; switch(vol_dist_params.dist_type) { case DIST_NORMAL: m_distribution = new CNormal(); break; default: m_distribution = new CNormal(); break; } m_initialized = ( m_distribution!=NULL && m_vp!=NULL && m_vp.is_initialized() && m_distribution.initialize(m_model_spec.dist_init_params, m_model_spec.dist_rng_seed) ); return m_initialized; }
Die Methode schlägt nur dann fehl, wenn es Probleme mit den Beispieldaten gibt oder wenn die angegebenen Parameter nicht mit den gelieferten Beispielreihen übereinstimmen; in solchen Fällen gibt die Methode false zurück. Wenn die Modellspezifikation gültig ist, fährt die Methode mit der Initialisierung der übrigen Komponenten des vollständigen Modells fort. Treten während dieser sekundären Phase Fehler auf, so werden diese von der Methode initialize() gekennzeichnet und geben false zurück. Sobald die Methode initialize() erfolgreich ausgeführt wurde, kann der Anpassungsprozess beginnen.
Die gemeinsame Schätzung der Parameter des Modells erfolgt durch den Aufruf einer der fit()-Methoden.
Anpassen eines Modells an die Daten
Die Anpassungsprozedur wird mithilfe des Alglib-Algorithmus für nichtlinear eingeschränkte Optimierung mit vorkonditioniertem augmentiertem Lagrangeschen Algorithmus durchgeführt, der als CMinNLC-Klasse implementiert ist. Die Funktion, die minimiert werden soll, ist die Log-Likelihood-Funktion, die als Mitglied der Klasse HARX definiert ist.
vector objective(vector& parameters, vector& sigma2, vector &backcast, matrix& varbounds, bool individual=false) { return _loglikelihood(parameters,sigma2,backcast,varbounds,individual); }
Die Eingaben für die fit()-Methoden sind in der folgenden Tabelle aufgeführt und erläutert.
| Parameter Name | Datentyp | Beschreibung |
|---|---|---|
| startingvalues | vector | Dies ist ein Vektor von Ausgangswerten für die im Optimierungsprozess verwendeten Modellparameter. Der Nutzer kann seine eigenen Werte angeben; andernfalls akzeptiert der Parameter einen leeren Vektor, wobei in diesem Fall automatisch geeignete Ausgangswerte berechnet werden. |
| backcast | vector | Dieser Vektor wird verwendet, um die Parameter eines bedingten Volatilitätsprozesses zu schätzen. Da die Gleichung für die bedingte Varianz rekursiv ist, sind Anfangswerte erforderlich, um die erste Beobachtung zu berechnen, wenn Daten vor der Stichprobe nicht verfügbar sind. Dieser Parameter akzeptiert auch einen leeren Vektor; in diesem Fall werden intern geeignete Backcast-Werte ermittelt. |
| scaling | double | Dies ist der Skalierungsfaktor, der zur Transformation der Stichprobenreihe verwendet wird. Der Optimierer arbeitet effektiver, wenn er weiß, wie die Daten transformiert wurden, wenn überhaupt. Der Standardwert ist 1. |
| cov_type | enum ENUM_COV_TYPE | Dies ist eine Enumeration, die die Methode angibt, die zur Schätzung der Kovarianzmatrix der Parameter verwendet wird. |
| maxits | unsigned long | Dieser Wert legt die maximale Anzahl der für den Optimierer zulässigen Iterationen fest. |
| first,last | integer | Bei diesen Werten handelt es sich um Indizes, die den Anfang und das Ende des Bereichs innerhalb der Stichprobenreihe angeben, die für die Schätzung der Modellparameter verwendet werden soll. |
| tol | double | Dieser Parameter gibt das Toleranzniveau oder den Schwellenwert an, der verwendet wird, um festzustellen, wann der Optimierungsprozess konvergiert hat. |
| guardsmoothness | bool | Mit diesem Wert wird der Optimierer konfiguriert, indem die Überwachung der Nicht-Glätte aktiviert oder deaktiviert wird. Wenn diese Option aktiviert ist, berücksichtigt der Optimierer Funktionen, die möglicherweise nicht perfekt differenzierbar sind; weitere Einzelheiten zu diesem Mechanismus finden Sie in der ALGLIB-Dokumentation. |
| gradient_test_step | double | Wenn diese Option aktiviert ist (auf einen Wert ungleich Null gesetzt), weist sie den Optimierer an, den angegebenen analytischen Gradienten oder die Jacobifunktion zu überprüfen. Dies gewährleistet zwar die mathematische Konsistenz und kann Fehler in der Optimierungslogik verhindern, wirkt sich aber erheblich auf die Geschwindigkeit des Prozesses aus. Schlagen Sie in der ALGLIB-Dokumentation nach, um den geeigneten Konfigurationswert für einen bestimmten Anwendungsfall zu ermitteln. |
Die Methode fit() gibt eine Struktur vom Typ ArchModelResult zurück, die das Ergebnis des Optimierungsprozesses, einschließlich der geschätzten Koeffizienten, der statistischen Signifikanz und der Modelldiagnose, kapselt.
struct ArchModelFixedResult { double loglikelihood; vector params; vector conditional_volatility; ulong nobs; vector resid; }; //+------------------------------------------------------------------+ //| arch model result | //+------------------------------------------------------------------+ struct ArchModelResult: public ArchModelFixedResult { long fit_indices[2]; matrix param_cov; double r2; ENUM_COVAR_TYPE cov_type;
Nachfolgend sind die Eigenschaften und Methoden aufgeführt, die in der Struktur ArchModelResult enthalten sind.
| Name der Eigenschaft | Datentyp | Beschreibung |
|---|---|---|
| params | vector | Dies sind die Ergebnisse des Optimierungsprozesses, die die Parameter des Volatilitätsmodells darstellen. Die Werte sind in einer bestimmten, sequenziellen Reihenfolge angeordnet: Parameter des Mittelwertmodells: Diese erscheinen zuerst (z. B. Konstante, AR/HAR-Koeffizienten, exogene Variablen). Volatilitätsparameter: Diese folgen an zweiter Stelle (z. B. Omega, Alpha und Beta in einem GARCH-Prozess). Verteilungsparameter: Diese werden zuletzt aufgelistet (z. B. Freiheitsgrade oder Schrägheitsparameter). |
| conditional_volatility | vector | Dieser Vektor enthält die bedingte Volatilität in der Stichprobe, die die Volatilitätsprognosen des Modells über den Schätzungszeitraum darstellt. |
| nobs | integer | Diese Eigenschaft gibt die Gesamtzahl der Beobachtungen aus der Stichprobenreihe an, die tatsächlich zur Anpassung der Modellparameter verwendet werden. |
| resids | vector | Dieser Vektor enthält die Residuen des vollständigen Modells, die die Differenz zwischen den beobachteten Werten und den durch die Mittelwertgleichung vorhergesagten Werten darstellen. Diese können verwendet werden, um die Qualität der Modellanpassung zu beurteilen. |
| loglikelihood | double | Dies ist der Wert der Funktion Log-Likelihood am Punkt der Konvergenz. Er stellt den Mindestwert dar, den die Zielfunktion während des Optimierungsprozesses erreicht. |
| fit_indices | vector | Dieser Vektor enthält zwei Elemente, die ausdrücklich den Indexbereich (Anfang und Ende) der bei der Modellschätzung verwendeten Stichprobenreihe festlegen. |
| param_cov | matrix | Diese Matrix enthält die geschätzte Kovarianzmatrix der Modellparameter. Es handelt sich um eine quadratische Matrix, deren Dimensionen der Gesamtzahl der geschätzten Parameter entsprechen. |
| r2 | double | Dies ist ein Maß für den Anteil der Varianz in der abhängigen Variable, der durch das Mittelwertmodell erklärt wird. |
| cov_type | enum | Diese Eigenschaft gibt die spezifische Methode oder den Schätzer an, der zur Berechnung der Kovarianzmatrix der Parameter verwendet wird. |
Die Methoden der ArchModelResult-Struktur bieten mehr statistische Tiefe, die über einfache Punktschätzungen hinausgeht, um festzustellen, ob das Modell wirklich angemessen ist. Nachstehend finden Sie die statistischen Methoden und die von ihnen gelieferten Metriken:
| tvalues(void) | Gibt einen Vektor der t-Statistik für jeden Parameter zurück. Er wird berechnet als das Verhältnis des geschätzten Koeffizienten zu seinem Standardfehler. |
vector tvalues(void) { return params/std_err(); }
| pvalues(void) | Gibt die p-Werte zurück, die mit den t-Statistiken verbunden sind. Damit lässt sich die Wahrscheinlichkeit bestimmen, dass der beobachtete Parameterwert zufällig aufgetreten ist. Ein Wert von weniger als 0,05 deutet auf statistische Signifikanz hin. |
vector pvalues(void) { vector pvals = tvalues(); for(ulong i = 0; i<pvals.Size(); ++i) pvals[i] = CAlglib::NormalCDF(-1.0*MathAbs(pvals[i]))*2.0; return pvals; }
| rsquaredadj(void) | Gibt das bereinigte R-Quadrat für das Mittelwertmodell zurück. Im Gegensatz zum Standard-R-Quadrat bestraft dieser Wert die Einbeziehung unnötiger Variablen und gibt an, wie viel Varianz durch das Modell im Verhältnis zu seiner Komplexität erklärt wird. |
double rsquared_adj(void) { return 1.0 - ((1.0-r2)*double(nobs-1)/double(nobs-num_params())); }
| stderror(void) | Gibt die Standardfehler der Parameter zurück. Diese stellen die Genauigkeit der Schätzungen dar; kleinere Fehler bedeuten zuverlässigere Parameterschätzungen. |
vector std_err(void) { return sqrt(param_cov.Diag()); }
Wenn der Optimierungsprozess nicht konvergiert, enthalten die ArchModelResult-Eigenschaften in der Regel Standardwerte und der params-Vektor ist leer. Es ist daher ratsam, zu prüfen, ob der Vektor der Parameter korrekt ist, bevor man mit einer Analyse oder Prognose fortfährt.
Vorhersagen
Sobald ein Modell erfolgreich angepasst wurde, wird die Prognose mit einer überladenen Prognosemethode durchgeführt. Diese Flexibilität ermöglicht die Erstellung von Prognosen auf der Grundlage unterschiedlicher Dateneingaben. Die folgenden Parameter werden für die verschiedenen Überlastungen der Prognosemethode verwendet, um zukünftige Volatilitäts- und Mittelwertschätzungen zu erstellen.
| Parameter Name | Datentyp | Beschreibung |
|---|---|---|
| horizon | unsigned long | Eine ganze Zahl, die den Prognosehorizont definiert. Sie bestimmt, wie viele Schritte in die Zukunft das Modell sowohl den bedingten Mittelwert als auch die bedingte Volatilität vorhersagen wird. Der Standardwert ist 1. |
| start | integer | Dieser Parameter gibt den Punkt in Ihrer Datenreihe an, der als Ursprung für die Prognose dient. Sie bestimmt, auf welche Beobachtung die zukünftigen Vorhersagen unmittelbar folgen werden. Standardmäßig wird dies auf den letzten verfügbaren Index in den Daten gesetzt. |
| method | enum ENUM_FORECAST_METHOD | Dieser Parameter bestimmt den mathematischen Ansatz, der zur Projektion der zukünftigen Volatilität verwendet wird. Während das Mittelwertmodell in der Regel einem Standardpfad folgt, kann der Volatilitätsprozess je nach Komplexität des Modells auf mehrere Arten projiziert werden. Die Optionen sind „Analytic“, „Simulation“ oder „Bootstrap“. Die Standardeinstellung ist „Analytic“. Die Methode „Analytic“ verwendet geschlossene mathematische Formeln zur Berechnung der erwarteten Varianz. Sie hat jedoch eine erhebliche Einschränkung hinsichtlich des Leistungsparameters. Wenn das Modell davon ausgeht, dass die Varianz die quadrierten Residuen sind, funktioniert die Methode „Analytic“ für jeden Horizont. Andernfalls, wenn das Modell eine andere Potenz als 2 verwendet, kann die Methode „Analytic“ nicht für Horizonte größer als eins verwendet werden. Das liegt daran, dass der Erwartungswert der nichtlinearen Transformation keine einfache rekursive Lösung hat. Bei der Simulation (Monte-Carlo-Methode) werden anhand der angenommenen Verteilung zahlreiche mögliche Pfade simuliert und gemittelt. Bootstrap hingegen zieht direkt aus den historischen Residuen Stichproben, um zukünftige Pfade zu generieren, ohne eine bestimmte Verteilung anzunehmen. |
| simulations | integer | Eine ganze Zahl, die die Anzahl der zu erzeugenden Pfade (oder Zeichnungen) angibt. Dies wird ausschließlich verwendet, wenn die Methode auf Simulation oder Bootstrap eingestellt ist. |
| seed | integer | Ein optionaler ganzzahliger Wert, der zur Initialisierung des Pseudo-Zufallszahlengenerators (RNG) verwendet wird. Sie stellt sicher, dass die bei der Simulation oder Bootstrap-Prognose erzeugten Zufallspfade reproduzierbar sind. |
| params | vector | Ein optionaler Vektor von Koeffizienten. Falls angegeben, wird die Prognose unter Verwendung dieser spezifischen Werte anstelle der Ergebnisse der internen fit()-Methode berechnet. |
| x | Array von Matrizen | Dieser Parameter ist von Bedeutung, wenn das Mittelwertmodell exogene Variablen einbezieht. Da diese Variablen außerhalb des eigentlichen Volatilitätsprozesses liegen, kann das Modell ihre zukünftigen Werte nicht „vorhersagen“; sie müssen im Voraus spezifiziert werden, um eine vollständige Prognose zu erstellen. Wenn das Modell mit k exogenen Variablen angepasst wurde, ist diese Eingabe erforderlich, um die Prognose zu berechnen. Achten Sie genau auf die Dimensionen jeder für diese Variable vorgesehenen Matrix. Die erforderliche Form hängt vom Horizont-Parameter, der Anzahl der exogenen Variablen und dem Wert des Starts im Verhältnis zum Umfang der zur Erstellung des Modells verwendeten Stichprobenreihe ab. Die Größe des Arrays (die Gesamtzahl der Matrizen) muss der Anzahl der exogenen Variablen entsprechen. Für jede Matrix muss die Anzahl der Zeilen mindestens der Differenz zwischen dem Gesamtstichprobenumfang und dem Ausgangsindex (Prognoseursprung) entsprechen. Schließlich muss die Anzahl der Spalten mit dem Parameter „Horizont“ übereinstimmen. |
Beim Aufrufen der Methode forecast() wird eine ArchForecast-Struktur zurückgegeben. In diesem Container sind die projizierten Pfade für den Mittelwert und die Volatilität enthalten. Die Struktur ist in drei Hauptmatrizen gegliedert.
//+------------------------------------------------------------------+ //| arch forecast result | //+------------------------------------------------------------------+ struct ArchForecast { matrix mean; matrix variance; matrix residual_variance;
Die Mittelwertmatrix enthält die prognostizierten Werte für den bedingten Mittelwert (den erwarteten Preis oder die erwartete Rendite). Die Varianzeigenschaft ist eine Matrix mit den Prognosewerten für die bedingte Volatilität. Die Matrix residual_variance schließlich stellt die Prognosen der bedingten Varianz der Residuen dar.
Modell-Validierung
Nach der Anpassung eines Modells ist der Test des Lagrange-Multiplikators (LM) (manchmal auch Engles ARCH-Test genannt) das verwendete Standard-Diagnoseinstrument, um zu bestätigen, ob ARCH-Effekte (Heteroskedastizität) in den Residuen verbleiben. Wenn das Modell angemessen ist, sollten die Residuen weißes Rauschen sein, d. h., der Test sollte keine signifikante Autokorrelation in den quadrierten Residuen finden. Die Funktion archlmtest() wertet dies aus, indem sie die quadrierten Residuen auf ihre eigenen Verzögerungen regressiert.
//+------------------------------------------------------------------+ //| The Lagrange multiplier test | //+------------------------------------------------------------------+ WaldTestStatistic archlmtest(vector& residuals,vector& conditional_volatility,ulong lags,bool standardized = false) { WaldTestStatistic out; vector resids = residuals; if(standardized) resids = resids/conditional_volatility; if(resids.HasNan()) { vector nresids = vector::Zeros(resids.Size() - resids.HasNan()); for(ulong i = 0, k = 0; i<resids.Size(); ++i) if(MathClassify(resids[i]) == FP_NAN) continue; else nresids[k++] = resids[i]; resids = nresids; } int nobs = (int)resids.Size(); vector resid2 = MathPow(resids,2.0); if(!lags) lags = ulong(ceil(12.0*pow(nobs/100.0,1.0/4.0))); lags = MathMax(MathMin(resids.Size()/2 - 1,lags),1); if(resid2.Size()<3) { Print(__FUNCTION__, " Test requires at least 3 non-nan observations "); return out; } matrix matres = matrix::Zeros(resid2.Size(),1); matres.Col(resid2,0); matrix lag[]; if(!lagmat(matres,lag,lags,TRIM_BOTH,ORIGINAL_SEP)) { Print(__FUNCTION__, " lagmat failed "); return out; } matrix lagout; if(!addtrend(lag[0],lagout,TREND_CONST_ONLY,true,HAS_CONST_SKIP)) { Print(__FUNCTION__, " addtrend failed "); return out; } lag[0] = lagout; OLS ols; if(!ols.Fit(lag[1].Col(0),lag[0])) { Print(__FUNCTION__, " OLS fitting failed "); return out; } out.stat = nobs*ols.Rsqe(); if(standardized) { out.null = "Standardized residuals are homoskedastic"; out.alternative = "Standardized residuals are conditionally heteroskedastic"; } else { out.null = "Residuals are homoskedastic"; out.alternative = "Residuals are conditionally heteroskedastic"; } out.df = lags; return out; }
Dazu sind die folgenden Eingaben erforderlich.
| Parameter Name | Datentyp | Beschreibung |
|---|---|---|
| residuals | vector | Der Vektor der aus dem ArchModelResult gewonnenen Residuen. Dies sind die Rohfehler des angepassten Modells. |
| conditional_volatility | vector | Dies ist die bedingte In-Sample-Volatilität für ein angepasstes Modell. |
| lags | unsigned long | Eine ganze Zahl, die die Anzahl der Verzögerungen angibt, die in die Testregression einbezogen werden sollen. |
| standardized | bool | Dieses boolesche Flag gibt an, ob die Residuen anhand der bedingten Volatilität standardisiert werden sollen. |
Der Aufruf der Funktion archlmtest() gibt eine WaldTestStatistic-Struktur zurück.
//+------------------------------------------------------------------+ //|Test statistic holder for Wald-type tests | //+------------------------------------------------------------------+ struct WaldTestStatistic { ulong df; double stat; string null; string alternative; WaldTestStatistic(void) { stat = EMPTY_VALUE; df = 0; null = alternative = NULL; } WaldTestStatistic(double _stat, ulong _df, string _null, string _alt) { stat = _stat; df = _df; null = _null; alternative = _alt; } WaldTestStatistic(WaldTestStatistic &other) { stat = other.stat; df = other.df; null = other.null; alternative = other.alternative; } void operator=(WaldTestStatistic &other) { stat = other.stat; df = other.df; null = other.null; alternative = other.alternative; } double pvalue(void) { int ecode = 0; double val = 1.- MathCumulativeDistributionChiSquare(stat,double(df),ecode); if(ecode) Print(__FUNCTION__," Chisquare cdf error ", ecode); return val; } vector critical_values(void) { vector out = {0.9,0.95,0.99}; int ecode = 0; for(ulong i = 0; i<out.Size(); ++i) out[i] = MathQuantileChiSquare(out[i],double(df),ecode); if(ecode) Print(__FUNCTION__," Chisquare cdf error ", ecode); return out; } };
Diese Struktur enthält die formalen statistischen Ergebnisse, die erforderlich sind, um festzustellen, ob das Modell die Volatilitätscluster erfolgreich aus den Daten entfernt hat.
| Name der Eigenschaft | Datentyp | Beschreibung |
|---|---|---|
| df | unsigned long | Freiheitsgrade für den Test, die der im Funktionsaufruf angegebenen Anzahl von Lags entsprechen. |
| stat | double | Die berechnete Teststatistik. Dieser Wert folgt einer Chi-Quadrat-Verteilung unter der Nullhypothese. |
| pvalue(void) | double | Die Methode pvalue() gibt die Wahrscheinlichkeit zurück, eine Teststatistik zu beobachten, die so extrem ist wie die berechnete, unter der Annahme, dass keine ARCH-Effekte verbleiben. |
| crtical(void) | vector | Die Methode critical() gibt einen Vektor der kritischen Werte für drei Konfidenzniveaus zurück: 90%, 95% und 99%. |
Um die Angemessenheit des Modells zu beurteilen, betrachten wir in erster Linie den p-Wert. Wenn der p-Wert größer als 0,05 ist, gilt die Prüfung als bestanden. Das bedeutet, dass wir die Nullhypothese nicht zurückweisen können. Dies deutet darauf hin, dass die Residuen homoskedastisch sind (konstante Varianz), was bedeutet, dass das ARCH/GARCH-Modell seine Aufgabe erfüllt hat. Ist der p-Wert hingegen kleiner oder gleich 0,05, wird die Nullhypothese verworfen. Dies deutet darauf hin, dass ARCH-Effekte in den Residuen verbleiben und das Modell wahrscheinlich unzureichend ist. Möglicherweise müssen wir die Verzögerungsreihenfolge erhöhen oder einen anderen Modelltyp ausprobieren. Der Wert steigt, wenn die Korrelation der quadrierten Residuen zunimmt. Eine sehr große Statistik führt zu einem sehr kleinen p-Wert, was darauf hindeutet, dass das Modell signifikante Volatilitätsmuster übersehen hat.
Ein Beispiel für die Einbeziehung exogener Variablen
In diesem Abschnitt wird gezeigt, wie man ein Modell mit exogenen Variablen spezifiziert. Das „X“ in ARX und HARX bezieht sich auf diese externen, unabhängigen Variablen innerhalb einer Regressionsgleichung. In diesem Rahmen dient die zu modellierende Zeitreihe als abhängige Variable, während die exogenen Prädiktoren in Form einer Matrix bereitgestellt werden, in der jede Spalte eine einzelne Variable darstellt.
Um die Flexibilität exogener Variablen zu veranschaulichen, untersuchen wir eine interessante Beziehung zwischen ARX- und heterogenen autoregressiven Modellen (HAR). Durch die Verwendung gemittelter historischer Daten als exogene Inputs in einem ARX-Modell können wir das Verhalten eines HAR-Modells nachbilden. Dieser Vergleich verdeutlicht sowohl die praktische Anwendung von exogenen Variablen als auch die zugrunde liegende Struktur von HAR-Modellen. Das HAR-Modell wurde speziell für die Modellierung der realisierten Volatilität auf den Finanzmärkten entwickelt, kann aber auch für andere Variablen angepasst werden. Sie wird „heterogen“ genannt, weil sie den Einfluss der Vergangenheit in verschiedene Zeithorizonte (kurz-, mittel- und langfristig) aufteilt und von der Annahme ausgeht, dass verschiedene Arten von Marktteilnehmern auf die Volatilität auf unterschiedlichen Zeitskalen reagieren.

Die gängigste Version des HAR-Modells verwendet realisierte Volatilitätsmessungen über drei Periodenlängen: kurz, mittel und lang. Dabei definiert jede Periode die Anzahl der Zeitpunkte, die zur Berechnung der durchschnittlichen realisierten Volatilität herangezogen werden. Das HAR-Modell erfasst das Langzeitgedächtnis der Volatilität durch die sich überschneidenden Durchschnittsterme.
Das ARX-Modell kombiniert einen autoregressiven (AR) Standardprozess mit exogenen (X) Inputs. Sie geht davon aus, dass der aktuelle Wert von ihren eigenen vergangenen Werten und den aktuellen oder vergangenen Werten externer Variablen abhängt. Die allgemeine Formel für ein ARX(p,q)-Modell lautet wie folgt.

Das Skript HAR_as_ARX_Demo.ex5 zeigt, wie ein ARX-Modell zur Nachahmung eines HAR-Modells verwendet werden kann. Das Skript führt die folgenden Schritte aus:
- Erstellt ein Standard-HAR-Modell unter Verwendung einer wählbaren Anzahl von gemittelten Termen.
- Gibt ein ARX-Modell an, das dieselben gemittelten Terme als exogene Eingabematrix verwendet.
- Vergleicht die Parameter der beiden Modelle, um ihre Gleichwertigkeit zu demonstrieren.
//+------------------------------------------------------------------+ //| HAR_as_ARX_Demo.mq5 | //| Copyright 2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property script_show_inputs #include<Arch\Univariate\mean.mqh> //--- input parameters input string Symbol_="AUDUSD"; input ENUM_TIMEFRAMES TimeFrame=PERIOD_D1; input datetime StartDate=D'2025.01.01'; input ulong HistoryLen = 504; input double ScaleFactor=100.; input bool MeanConstant = true; input string MeanLags ="1,5,22"; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //---download data vector prices; if(!prices.CopyRates(Symbol_,TimeFrame,COPY_RATES_CLOSE,StartDate,HistoryLen)) { Print(" failed to get close prices for ", Symbol_,". Error ", GetLastError()); return; } //--- prices = log(prices); //--- vector returns = np::diff(prices); //--- string lag_info[]; //--- vector lags=vector::Zeros(0); //--- int nlags = StringSplit(MeanLags,StringGetCharacter(",",0),lag_info); //--- double atod; if(nlags>0) { for(uint i = 0; i<uint(nlags); ++i) { if(StringLen(lag_info[i])>0) { atod = StringToDouble(lag_info[i]); if(atod>0 && ulong(atod)<returns.Size()-1) if(lags.Resize(lags.Size()+1,3)) lags[lags.Size()-1] = atod; } } } //--- if(lags.Size()) np::sort(lags); //---build the HAR model ArchParameters har_spec; har_spec.observations=returns*ScaleFactor; har_spec.include_constant = MeanConstant; har_spec.mean_lags = lags; har_spec.vol_model_type = VOL_CONST; //--- HAR harmodel; //--- if(!harmodel.initialize(har_spec)) return; //--- ArchModelResult har = harmodel.fit(ScaleFactor); //--- if(!har.params.Size()) { Print("Convergence failed ", GetLastError()); return; } //--- Print(" Har model parameters\n", har.params); //---Now we build an equivalent ARX model matrix exogvars = matrix::Zeros(returns.Size(),lags.Size()); //---calculate averages double sum; ulong lag,count; for(ulong i = 0; i<exogvars.Cols(); ++i) { lag = (ulong)lags[i]; count = lag; for(ulong k = lag; k<exogvars.Rows(); ++k) { sum = 0.0; for(ulong j = 0; j<count; ++j) sum+=returns[k-j-1]; exogvars[k,i] = sum/double(count); } } //--- ArchParameters arx_spec; arx_spec.observations = ScaleFactor*np::sliceVector(returns,long(lags[lags.Size()-1])); arx_spec.exog_data = ScaleFactor*np::sliceMatrixRows(exogvars,long(lags[lags.Size()-1])); arx_spec.include_constant = MeanConstant; arx_spec.vol_model_type=VOL_CONST; //--- ARX arxmodel; if(!arxmodel.initialize(arx_spec)) return; //--- ArchModelResult arx = arxmodel.fit(ScaleFactor); if(!arx.params.Size()) { Print(" convergence failed ", GetLastError()); return; } //--- Print("ARX model parameters\n", arx.params); } //+------------------------------------------------------------------+
Das Skript wurde mit den Standardparametern ausgeführt.

Das Ergebnis ist die folgende Ausgabe, die die angepassten Modellparameter zeigt.
NR 0 22:12:43.671 HAR_as_ARX_Demo (XAUUSD,D1) Har model parameters CE 0 22:12:43.672 HAR_as_ARX_Demo (XAUUSD,D1) [-0.02336784243846212,-0.04576660950059414,0.02963893847811298,-0.1589020837643845,0.3352700836173772] RE 0 22:12:43.691 HAR_as_ARX_Demo (XAUUSD,D1) ARX model parameters HN 0 22:12:43.691 HAR_as_ARX_Demo (XAUUSD,D1) [-0.02336784243846212,-0.04576660950059416,0.02963893847811294,-0.1589020837643847,0.3352700836173772]
Die Demonstration bestätigt, dass beide Ansätze identische Modellparameter liefern, wie die Ausgabe des Skripts zeigt.
Schlussfolgerung
In diesem Artikel haben wir den Grundstein für die native Volatilitätsmodellierung in MQL5 gelegt. Durch die Standardisierung der Schnittstelle über die Strukturen ArchParameters und ArchModelResult haben wir einen Arbeitsablauf geschaffen, der die Modellspezifikation, -optimierung und -validierung ermöglicht. Dieser Rahmen ermöglicht die unkomplizierte Initialisierung eines Modells, seine Anpassung an einen Datensatz und die Durchführung strenger diagnostischer Prüfungen – wie den ARCH-LM-Test –, um sicherzustellen, dass die Residuen frei von Heteroskedastizität sind.
Während die aktuelle Version der Bibliothek mehrere grundlegende Volatilitätsprozesse implementiert, ist sie derzeit auf die Annahme beschränkt, dass die Fehlerverteilungen einem Standard-Normal-Profil folgen. In einer der nächsten Ausgaben werden wir fortgeschrittenere Volatilitätsprozesse implementieren und die Bibliothek erweitern, um ein breiteres Spektrum von Fehlerverteilungen zu unterstützen. Der gesamte Code für den Artikel ist unten angegeben.
| Datei | Beschreibung |
|---|---|
| MQL5/include/Arch | Dieser Ordner enthält alle Header-Dateien für die Volatilitätsmodellierungsbibliothek. |
| MQL5/include/Regression | Dieser Ordner enthält einige Regressionshilfsprogramme, die im Code für die Volatilitätsmodellierung verwendet werden. |
| MQL5/include/np.mqh | Diese Header-Datei enthält verschiedene Hilfsprogramme für die Bearbeitung von Vektoren und Matrizen. |
| MQL5/scripts/HAR_as_ARX_Demo.mq5 | Dies ist ein Skript, das die Spezifikation eines HAR-Modells als AR-Modell mit exogenen Variablen demonstriert. |
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/20589
Warnung: Alle Rechte sind von MetaQuotes Ltd. vorbehalten. Kopieren oder Vervielfältigen untersagt.
Dieser Artikel wurde von einem Nutzer der Website verfasst und gibt dessen persönliche Meinung wieder. MetaQuotes Ltd übernimmt keine Verantwortung für die Richtigkeit der dargestellten Informationen oder für Folgen, die sich aus der Anwendung der beschriebenen Lösungen, Strategien oder Empfehlungen ergeben.
Die Übertragung der Trading-Signale in einem universalen Expert Advisor.
Larry Williams Marktgeheimnisse (Teil 4): Automatisieren von kurzfristigen hohen und tiefen Umkehrpunkten in MQL5
Eine alternative Log-datei mit der Verwendung der HTML und CSS
Aufbau von KI-gestützten Handelssystemen in MQL5 (Teil 8): UI-Polnisch mit Animationen, zeitlichen Metriken und Tools für das Reaktionsmanagement
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
Eine sehr interessante Idee!
Die Kombination der Volatilität von mehreren Zeitrahmen.
Sehr interessante Idee!
Die Kombination der Volatilität von mehreren Zeitrahmen.