//+------------------------------------------------------------------+ //| LogLikelihoodVerification.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 #property description "The script downloads data from the terminal" "to build a conditional volatility model using" "Pythons ARCH module. It then gets the model" "parameters and uses them to evaluate the loglikelihood" "function in MQL5 for comparison with the final" "return of the optimization procedure." #include #include #include #include //--- #define FILENAME "arch.json" #define SPACE " " #define PYFILE "\\MQL5\\Scripts\\slsqp_article\\mt5_volatility_processor.py" //--- input string Symbol_="AUDUSD"; input ENUM_TIMEFRAMES TimeFrame=PERIOD_D1; input datetime StartDate=D'2025.01.01'; input ulong HistoryLength = 1000; input double ScaleFactor=100.; input ENUM_MEAN_MODEL MeanModel = MEAN_CONSTANT; input bool MeanConstant = true; input string MeanLags =""; input ENUM_VOLATILITY_MODEL VolatilityModel = VOL_GJR_GARCH; input ENUM_DISTRIBUTION_MODEL ErrorDistribution = DIST_NORMAL; input ulong _P_ = 1; input ulong _O_ = 1; input ulong _Q_ = 1; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { string pstring = EnumToString(TimeFrame); if(StringFind(pstring,"CURRENT")>=0) { Print("Invalid parameter setting, Please do not use PERIOD_CURRENT option, be explicit. "); return; } //--- ArchParameters spec; spec.mean_model_type = MeanModel; //--- string lag_info[]; int nlags = StringSplit(MeanLags,StringGetCharacter(",",0),lag_info); if(nlags>0) { for(uint i = 0; i0) { if(spec.mean_lags.Resize(spec.mean_lags.Size()+1,3)) spec.mean_lags[spec.mean_lags.Size()-1] = StringToDouble(lag_info[i]); else { Print("error ", GetLastError()); return; } } } } //--- spec.vol_model_type = VolatilityModel; spec.garch_o = _O_; spec.garch_p = _P_; spec.garch_q = _Q_; spec.dist_type = ErrorDistribution; //---download data vector prices; if(!prices.CopyRates(Symbol_,TimeFrame,COPY_RATES_CLOSE,StartDate,HistoryLength)) { Print(" failed to get close prices for ", Symbol_,". Error ", GetLastError()); return; } //--- prices = log(prices); //---get returns vector returns = np::diff(prices); //--- if(ScaleFactor>1) returns*=ScaleFactor; //--- spec.observations = returns; //--- HARX* arma_garch = arch_model(spec); if(!arma_garch) { Print("Invalid HARX pointer"); return; } //--- ArchParameters final_spec = arma_garch.get_specification(); Print("GARCH spec"); PrintFormat("P(%d) O(%d) Q(%d) Power(%f)",final_spec.garch_p,final_spec.garch_o,final_spec.garch_q,final_spec.vol_power); //--- string cmdLine = StringFormat("%s %s%s%s","python",TerminalInfoString(TERMINAL_DATA_PATH),PYFILE,cmd_builder(Symbol_, StartDate,TimeFrame,HistoryLength,VolatilityModel, ScaleFactor,MeanModel,MeanConstant,MeanLags, ErrorDistribution,final_spec.garch_p,final_spec.garch_o,final_spec.garch_q)); //--- PROCESS_INFORMATION piProcInfo; STARTUPINFOW siStartInfo; BOOL process_run = false; //--- ZeroMemory(piProcInfo); ZeroMemory(siStartInfo); siStartInfo.cb = sizeof(STARTUPINFOW); vector parameters; //--- if(CreateProcessW(NULL,cmdLine,NULL,NULL,0,DETACHED_PROCESS,NULL,NULL,siStartInfo,piProcInfo)) { WaitForSingleObject(piProcInfo.hProcess,INFINITE); uint exitcode; GetExitCodeProcess(piProcInfo.hProcess,exitcode); if(!exitcode) { CFileTxt jfile; if(jfile.Open(FILENAME,FILE_READ|FILE_COMMON) != INVALID_HANDLE) { CJAVal js; if(js.Deserialize(jfile.ReadString())) { int jsize = js["x"].Size(); parameters = vector::Zeros(jsize); for(int i = 0; i 0) ? mlags : "0"; string out = StringFormat("%s %s %s %s %s %G %I64u %I64u %I64u %I64u %s %d %s %s %s", SPACE, FILENAME, stime, symb, tf_str, scalef, hist, P, O, Q, mmod_str, (mconst ? 1 : 0), vmod_str, edist_str, final_lags); return out; } //+------------------------------------------------------------------+