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

117 Zeilen
3,5 KiB
MQL5

//+------------------------------------------------------------------+
//| 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);
}
//+------------------------------------------------------------------+