English
preview
Aufbau von Volatilitätsmodellen in MQL5 (Teil I): Die erste Implementierung

Aufbau von Volatilitätsmodellen in MQL5 (Teil I): Die erste Implementierung

MetaTrader 5Beispiele |
23 2
Francis Dube
Francis Dube

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.

Aufbau der Bibliothek

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 &params, vector &y, matrix &regressors);
   virtual ulong  num_params(void);

   bool set_volatility_process(CVolatilityProcess* &vp);
   bool set_distribution(CDistribution* &dist);

   virtual matrix simulate(vector &params, 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.

HAR-Modell-Formel

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.

ARX-Modell-Formel

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.

Skript-Parameter

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

Letzte Kommentare | Zur Diskussion im Händlerforum (2)
Osmar Sandoval Espinosa
Osmar Sandoval Espinosa | 12 Feb. 2026 in 01:05

Eine sehr interessante Idee!

Die Kombination der Volatilität von mehreren Zeitrahmen.

cemal
cemal | 12 Feb. 2026 in 09:34
Osmar Sandoval Espinosa #:

Sehr interessante Idee!

Die Kombination der Volatilität von mehreren Zeitrahmen.

Haben Sie es geschafft, einen Indikator mit Bibliotheken in dem Artikel gegeben zu schaffen?
Die Übertragung der Trading-Signale in einem universalen Expert Advisor. Die Übertragung der Trading-Signale in einem universalen Expert Advisor.
In diesem Artikel wurden die verschiedenen Möglichkeiten beschrieben, um die Trading-Signale von einem Signalmodul des universalen EAs zum Steuermodul der Positionen und Orders zu übertragen. Es wurden die seriellen und parallelen Interfaces betrachtet.
Larry Williams Marktgeheimnisse (Teil 4): Automatisieren von kurzfristigen hohen und tiefen Umkehrpunkten in MQL5 Larry Williams Marktgeheimnisse (Teil 4): Automatisieren von kurzfristigen hohen und tiefen Umkehrpunkten in MQL5
Meistern Sie die Automatisierung der kurzfristigen Umkehrmuster von Larry Williams mit MQL5. In diesem Leitfaden entwickeln wir einen vollständig konfigurierbaren Expert Advisor (EA), der nicht-zufällige Marktstrukturen ausnutzt. Wir zeigen Ihnen, wie Sie ein robustes Risikomanagement und eine flexible Ausstiegslogik integrieren und so eine solide Grundlage für die systematische Strategieentwicklung und die Backtests schaffen.
Eine alternative Log-datei mit der Verwendung der HTML und CSS Eine alternative Log-datei mit der Verwendung der HTML und CSS
In diesem Artikel werden wir eine sehr einfache, aber leistungsfähige Bibliothek zur Erstellung der HTML-Dateien schreiben, dabei lernen wir auch, wie man eine ihre Darstellung einstellen kann (nach seinem Geschmack) und sehen wir, wie man es leicht in seinem Expert Advisor oder Skript hinzufügen oder verwenden kann.
Aufbau von KI-gestützten Handelssystemen in MQL5 (Teil 8): UI-Polnisch mit Animationen, zeitlichen Metriken und Tools für das Reaktionsmanagement Aufbau von KI-gestützten Handelssystemen in MQL5 (Teil 8): UI-Polnisch mit Animationen, zeitlichen Metriken und Tools für das Reaktionsmanagement
In diesem Artikel erweitern wir das KI-gestützte Handelssystem in MQL5 um Verbesserungen der Nutzeroberfläche, einschließlich Ladeanimationen für die Vorbereitungs- und Denkphasen von Anfragen sowie Zeitmesswerte, die in den Antworten für ein besseres Feedback angezeigt werden. Wir fügen Tools zur Verwaltung von Antworten hinzu, wie z. B. Schaltflächen zum erneuten Abfragen der KI und Exportoptionen zum Speichern der letzten Antwort in einer Datei, um die Interaktion zu optimieren.