Article-20589-Volatility-Mo.../Scripts/ArGarchModel_Demo.mq5

150 lines
4.6 KiB
MQL5
Raw Permalink Normal View History

2026-06-03 17:50:48 +00:00
//+------------------------------------------------------------------+
//| ArGarchModel_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 = 1504;
input double ScaleFactor=100.;
input ENUM_MEAN_MODEL MeanModel = MEAN_ARX;
input bool MeanConstant = true;
input string MeanLags ="";
input ENUM_VOLATILITY_MODEL VolatilityModel = VOL_CONST;
input ulong _P_ = 1;
input ulong _Q_ = 1;
input double Power = 2.0;
input int Volatility_Seed = 0;
input int Distribution_Seed = 0;
input ulong HoldBack = 0;
input bool UseRotated = false;
input ulong ArchLM_Lags = 30;
input bool Standardize = false;
//+------------------------------------------------------------------+
//| 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);
//---specify the model
ArchParameters model_spec;
model_spec.observations = ScaleFactor*returns;
model_spec.include_constant = MeanConstant;
model_spec.use_har_rotation = UseRotated;
model_spec.mean_model_type = MeanModel;
model_spec.mean_lags = lags;
model_spec.holdout_size = HoldBack;
model_spec.vol_model_type = VolatilityModel;
model_spec.garch_p = _P_;
model_spec.garch_q = _Q_;
model_spec.vol_power = Power;
model_spec.vol_rng_seed = Volatility_Seed;
model_spec.dist_rng_seed = Distribution_Seed;
//---
HARX* ar_garch = arch_model(model_spec);
if(!ar_garch)
return;
//---
ArchModelResult model = ar_garch.fit(ScaleFactor);
delete ar_garch;
//---
if(model.params.Size())
{
Print("Estimated model parameters\n ", model.params);
Print(" Loglikelihood : ", model.loglikelihood);
Print(" parameter pvalues\n ", model.pvalues());
Print(" parameter tvalues\n ", model.tvalues());
Print(" 95% conf intervals\n ", model.conf_int());
}
//---
WaldTestStatistic wts = archlmtest(model.resid,model.conditional_volatility,ArchLM_Lags,Standardize);
//---
Print(" ArchLM test pvalue ", wts.pvalue());
Print(" ArchLM test statistic ", wts.stat);
Print(" ArchLM test critical values \n", wts.critical_values());
//---
}
//+------------------------------------------------------------------+
HARX* arch_model(ArchParameters &archparameters)
{
HARX* out = NULL;
switch(archparameters.mean_model_type)
{
case MEAN_CONSTANT:
out = new ConstantMean();
break;
case MEAN_AR:
out = new AR();
break;
case MEAN_ARX:
out = new ARX();
break;
case MEAN_HAR:
out = new HAR();
break;
case MEAN_HARX:
out = new HARX();
break;
case MEAN_ZERO:
out = new ZeroMean();
break;
default:
out = new ConstantMean();
break;
}
if(CheckPointer(out)==POINTER_DYNAMIC)
{
if(out.initialize(archparameters))
return out;
else
{
delete out;
return NULL;
}
}
else
return out;
}
//+------------------------------------------------------------------+