Article-23435-OLS-Generaliz.../spread.mq5
alexeynikolaev2 248dccf82c new files added
2026-08-12 10:37:03 +03:00

81 lines
3.4 KiB
MQL5

//+------------------------------------------------------------------+
//| spread.mq5 |
//| Copyright 2026, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2026, MetaQuotes Ltd."
#property link "https://www.mql5.com"
//---
#property script_show_inputs
//---
input string symbol_stock1 = "GOOGL"; // First market symbol for spread
input string symbol_stock2 = "AAPL"; // Second market symbol for spread
input datetime from_t = D'2024.04.01'; // Start of quotes analysis time interval
input datetime to_t = D'2026.04.01'; // End of quotes analysis time interval
input ENUM_TIMEFRAMES tf = PERIOD_D1; // Time frame
input ulong p_ar = 1; // Order of the AR component
input ulong q_ma = 1; // Order of the MA component
//---
#include "EconometricsM.mqh" // Header file with regression_CLS() function
//---
void OnStart()
{
ulong k=p_ar+q_ma+1;
//--- quotes downloading
MqlRates rates_stock1[], rates_stock2[];
int n_rates_stock1 = CopyRates(symbol_stock1, tf, from_t, to_t, rates_stock1);
int n_rates_stock2 = CopyRates(symbol_stock2, tf, from_t, to_t, rates_stock2);
PrintFormat("Number of downloaded quotes for first stock %s: %d", symbol_stock1, n_rates_stock1);
PrintFormat("Number of downloaded quotes for second stock %s: %d", symbol_stock2, n_rates_stock2);
if(n_rates_stock1 <= int(k) || n_rates_stock2 <= int(k))
{Print("Not enough data"); return;}
//--- Formation of time-synchronized stock1/stock2 quote pairs
vector y((ulong)n_rates_stock1);
int i_stock1 = 0, i_stock2 = 0;
ulong n = 0;
for(; i_stock1 < n_rates_stock1; ++i_stock1)
{
//--- We are looking for a bar of the second instrument with time >= time of the first
while(i_stock2 < n_rates_stock2 && rates_stock2[i_stock2].time < rates_stock1[i_stock1].time)
i_stock2++;
if(i_stock2 >= n_rates_stock2)
break; // The story of the second instrument has ended
if(rates_stock2[i_stock2].time > rates_stock1[i_stock1].time)
continue; // Skip if there is no exact time match
//--- The timestamps matched, we calculate the logarithmic spread
n++;
y[n-1] = MathLog(rates_stock1[i_stock1].close / rates_stock2[i_stock2].close);
i_stock2++;
}
y.Resize(n);
if(n <= k)
{Print("Not enough data after synchronization"); return;}
Print("y length: ", n);
//--- CLS data preparation
vector y_=vector::Zeros(p_ar),e_=vector::Zeros(q_ma),e(n);
//--- Coefficient statistics
CoefficientStats stat[];
// Forecast for the next step
SPrognose prog;
//--- CLS calculation
regression_CLS(y,p_ar,q_ma,y_,e_,e,stat,prog);
//--- Result output
Print("===================================");
//--- Coefficients statistics
ArrayPrint(stat,4);
Print("===================================");
//--- Forecast metrics
prog.print();
Print("===================================");
//--- Residuals vs t
t_residuals_plot(e);
//--- ACF graph
correlogram(e);
}
//+------------------------------------------------------------------+