Bibliotheken: Statistische Funktionen - Seite 3

 

Hallo, ich habe eine Frage zu einer dieser Funktionen.


Ich brauche den Standard-Dickey-Fuller-Test, um das Vorhandensein von Stationarität festzustellen. Ich habe gesehen, dass er in diesem Satz enthalten ist, aber ich weiß nicht wirklich, welchen Test er verwendet, da Dickey Fuller sowohl den Standardtest als auch den erweiterten Test hat und innerhalb dieser haben wir mehrere, die Drift, Konstante usw. einführen.

Ich habe den Code gesehen, aber die Formeln passen nicht, ich habe die Ergebnisse auch mit anderen Programmen wie R überprüft und erhalte nicht dasselbe. Ich würde also gerne wissen, ob jemand genau weiß, welcher Test verwendet wird, damit ich weiß, ob ich in allen Programmen denselben Test verwende, oder sehen kann, wo die Unterschiede liegen usw.

Herzlichen Dank!

 
//+------------------------------------------------------------------+
//|Statistik.mqh |
//|Copyright 2015, Herajika |
//|morinoherajika@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Herajika/Adam S³ucki"
#property link      "morinoherajika@gmail.com"

//+------------------------------------------------------------------+
#include <Expert/Expert.mqh>
#include <Trade/SymbolInfo.mqh>
#include <Trade/OrderInfo.mqh>
#include <Trade/HistoryOrderInfo.mqh>
#include <Trade/Trade.mqh>
#include <Trade/PositionInfo.mqh>
#include <Trade/DealInfo.mqh>
#include <Trade/TerminalInfo.mqh>  
#include <Trade/AccountInfo.mqh>  
#include <Object.mqh>
#include <MovingAverages.mqh>
#include <Arrays\ArrayObj.mqh>
#include <Math\Stat\Math.mqh>
#include <Math\Alglib\statistics.mqh>
//--------------------------------------------------------------

MqlTradeRequest mrequest;  // Used for sending our trade requests
MqlTradeResult mresult;    // Used to get our trade results
MqlRates mrate[];          // Used to store the prices, volumes and spread of each bar
CTerminalInfo terminalInfo;
                       
datetime startTime = TimeCurrent();
datetime lastCheckedTradeTime = startTime;
                       
bool sqDisplayInfoPanel = MQLInfoInteger(MQL_TESTER) != 0 && MQLInfoInteger(MQL_OPTIMIZATION) != 0;
int sqLabelCorner = 1;
int sqOffsetHorizontal = 5;
int sqOffsetVertical = 20;
color sqLabelColor = clrWhite;

int magicNumber;
int minBars = 30;
int sqMaxSlippage;
int sqVerboseMode;
int sqMaxRetries = 5;

double gPointCoef = 0;                  

int deviationPoints = 10;
int sqTicket = 1;
datetime lastBarTime;
bool mcond[100];

double initialBalance = 0;

string valueIdentificationSymbol = "";

int indicatorHandles[];
//+------------------------------------------------------------------+


bool _sqIsBarOpen;
input int OpenBarDelay = 0; // Verzögerung der Öffnung der Bar in Minuten
input int ma_period1  = 55;
input int ma_shift1  = 0 ;
input int ma_period2  = 144;
input int ma_shift2  = 0 ;
input ENUM_MA_METHOD       movavg_method=MODE_EMA;           // Art der Glättung 
input ENUM_APPLIED_PRICE   applied_price=PRICE_CLOSE;    // Typ des EMA-Preises

input string statistics = "-----------statistics analysis  -----------";

int hnd1, hnd2;
double arr1[], arr2[];
input int statSampleSize = 100; //Beschränken Sie den Stichprobenumfang auf nur 100 Werte

double detrendres[] , olsres[];
double aLinCoeff = 0.0, bLinCoeff = 0.0, cointegrationCoeff = 0.0;
double AugDF,egt,AR1forcast;

#define  EMA_1 0                   //iMA(NULL,0,ma_period1,ma_shift1,ma_method,PRICE_CLOSE)
#define  EMA_2 1                   //iMA(NULL,0,ma_period2,ma_shift2,ma_method,PRICE_CLOSE)

//+------------------------------------------------------------------+
//| Experten-Tick-Funktion|
//+------------------------------------------------------------------+
void OnTick() {


 //************************************************************************
   //--- Haben wir genug Balken, mit denen wir arbeiten können?
   if(Bars(_Symbol,_Period) < minBars) {   // wenn die Gesamtzahl der Balken kleiner als minBars ist
      Alert(StringFormat("NOT ENOUGH DATA: Less Bars than %d", minBars));
      return;
   }

   //--- Abrufen der Details der letzten 2 Takte
   if(CopyRates(_Symbol, _Period, 0, 2, mrate) < 2) {
      Alert("Error copying rates/history data - error:", GetLastError(), "!!");
      ResetLastError();
      return;
   }
     
   ZeroMemory(mrequest);      // Initialisierung der mrequest-Struktur
   
   
   // Dynamische Arrays zum Speichern von Indikatorwerten sind arr1[], arr2[]
   // Bereits oben deklariert
   
   
   // Einstellung der Indizierung in Arrays wie in Zeitreihen, d. h. Arrayelement mit Null
   // index speichert die Werte des letzten Balkens, der i-te Index ist der vorletzte, usw.
   ArraySetAsSeries(arr1, true);
   ArraySetAsSeries(arr2, true);
   
     
   // Kopieren wir mit Hilfe der Indikator-Handles die Werte des Indikators
   // Puffer zu Arrays, die speziell für diesen Zweck vorbereitet sind
   CopyBuffer(hnd1,0,0,statSampleSize,arr1);
   CopyBuffer(hnd2,0,0,statSampleSize,arr2);
   
   checkBarOpen();
   
    if (_sqIsBarOpen == true) //Um eine hohe CPU- und Speichernutzung zu vermeiden, sollten wir die Berechnung nur bei geöffneter Bar durchführen.
   {
          
      //Schritt 1: Trend aus den Beispieldaten entfernen (hat Regression in der Routine) - gibt ein Array zurück
      detrend(arr1, detrendres);      
      
      //Schritt 2 Test auf Stationarität der Stichprobe - liefert einen Wert
      AugDF = dickeyFuller(detrendres);
      
      //Schritt 3 Test auf Kointegration der Stichprobe - liefert einen Wert
      egt =  engleGrangerTest(detrendres, arr1, cointegrationCoeff);
      
      //Schritt 4 Voraussage des nächsten Wertes der Stichprobe AR1 bei Lag = 1 - Gibt einen Wert zurück
      AR1forcast = AR1(detrendres);
      
      Print("adf = ", AugDF, "  egt = ", egt , "  ar1 = ",AR1forcast);
  }
   
   
}

//+------------------------------------------------------------------+
//| Experten-Initialisierungsfunktion|
//+------------------------------------------------------------------+
int OnInit()
{
   
   //Initialisieren aller Array-Indikator-Handles
   if(!initIndicators()) return(INIT_FAILED);
   
     
   //kopierte Arrays Für mathematisch-statistische Berechnungen 
   hnd1 = indicatorHandles[EMA_1];     //iMA(NULL,0,ma_period1,ma_shift1,ma_method,applied_price)
   hnd2 = indicatorHandles[EMA_2];     //iMA(NULL,0,ma_period2,ma_shift2,ma_method,applied_price)
   
   return(INIT_SUCCEEDED);
   
}

//+------------------------------------------------------------------+
//| Experten-Deinitialisierungsfunktion|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
    writeReportFile(); 
  }


bool initIndicators(){
   
   ArrayResize(indicatorHandles, ArraySize(indicatorHandles) + 1, 10);
   indicatorHandles[EMA_1] = iMA(NULL,0,ma_period1,ma_shift1,movavg_method,applied_price) ;
   
   ArrayResize(indicatorHandles, ArraySize(indicatorHandles) + 1, 10);
   indicatorHandles[EMA_2] = iMA(NULL,0,ma_period2,ma_shift2,movavg_method,applied_price) ;
   
         
   for(int a=0; a<ArraySize(indicatorHandles); a++){
      //--- wenn der Handle nicht erstellt wird 
      if(indicatorHandles[a] == INVALID_HANDLE) { 
         //--- über den Fehler informieren und den Fehlercode ausgeben 
         Print("Failed to create handle of the indicator, error code %d", GetLastError()); 
         //--- der Indikator wird vorzeitig gestoppt 
         return(false); 
      }
   }
   
   return(true);
}             


// ANMERKUNG: 
// Wenn Sie die Größe eines Arrays auf i ändern, enthält das Array arr[0] bis arr[i-1]
// arr[i] existiert nicht, daher wird der Fehler array out of range angezeigt.

//--- Zeitreihenzerlegung (Trend entfernen)
void detrend(double &arr[],double &res[])
  {
   double regRes[];
   double iterator[];
   int length=ArraySize(arr);
   ArrayResize(regRes,length);
   ArrayResize(iterator,length);
//---
   for(int i=0; i<length; i++)
     {
      iterator[i]=i+1;
     }
//---
   regression(iterator,arr,regRes);
//---

   for(int i=0; i<length;i++)
     {
      Print("   arr = ", arr[i], "   regRes  = ", regRes[i], "    SumXY =", arr[i] - regRes[i] );
      res[i] = arr[i] - regRes[i]; // HINWEIS: HIER wird "array out of range" angezeigt

     }
  }
  
 
 //===================================================== 
//--- Rückgabe eines Arrays mit den Werten der Regressionslinie
void regression(double &tsarr1[],double &tsarr2[],double &res[])
  {
//---
   double a = 0;
   double b = 0;
//---
   int length=ArraySize(tsarr1);
//---
   ArrayResize(res,length);
//---
   double meanX = MathMean(tsarr1);
   double meanY = MathMean(tsarr2);
//---
   double sumXY=0;
   double sqSumX=0;
//---
   for(int i=0; i<length; i++)
     {
      Print("   tsarr1 = ", tsarr1[i], "   tsarr2  = ", tsarr2[i], "    SumXY =", tsarr1[i]*tsarr2[i] );
      sumXY+=tsarr1[i]*tsarr2[i];
      sqSumX+=MathPow(tsarr1[i],2);
     }
//---
   a = (sumXY - length*meanX*meanY)/(sqSumX - length*MathPow(meanX,2));
   b = meanY - a*meanX;
//---
   for(int i=0; i<length; i++)
     {
      res[i]=a*tsarr1[i]+b;
     }
  }
  
 //===================================================== 
//--- Rückgabe eines Arrays mit den Werten der Regressionsgeraden sowie den Koeffizienten der Regressionsgeraden (a und b aus y = ax+b)
void regression(double &tsarr1[],double &tsarr2[],double &res[],double &aCoeff,double &bCoeff)
  {
//---
   double a = 0;
   double b = 0;
//---
   int length=ArraySize(arr1);
//---
   ArrayResize(res,length);
//---
   double meanX = MathMean(tsarr1);
   double meanY = MathMean(tsarr2);
//---
   double sumXY=0;
   double sqSumX=0;
//---
   for(int i=0; i<length; i++)
     {
      sumXY+=tsarr1[i]*tsarr2[i];
      sqSumX+=MathPow(tsarr1[i],2);
     }
//---
   a = (sumXY - length*meanX*meanY)/(sqSumX - length*MathPow(meanX,2));
   b = meanY - a*meanX;
//---
   for(int i=0; i<length; i++)
     {
      res[i]=a*tsarr1[i]+b;
     }
   aCoeff = a;
   bCoeff = b;
  }
  
//======================Test for STATIONARITY=============================== 
//--- Augumentierter Dickey-Fuller-Test auf Stationarität
//bool dickeyFuller(double &arr[])
double dickeyFuller(double &arr[])
  {
// n=25 50 100 250 500 >500
// {-2.62, -2.60, -2.58, -2.57, -2.57, -2.57};
   double cVal;
   bool result;
   int n=ArraySize(arr);
   double tValue;
   double corrCoeff;
   double copyArr[];
   double difference[];
   ArrayResize(difference,n-1);
//---
   for(int i=0; i<n-1; i++)
     {
      difference[i]=arr[i+1]-arr[i];
     }
//---
   ArrayCopy(copyArr,arr,0,0,n-1);
   //corrCoeff=myStats.PearsonCorr2(copyArr,difference,statSampleSize);
   corrCoeff=myStats.SpearmanCorr2(copyArr,difference,statSampleSize);
   tValue=corrCoeff*MathSqrt((n-2)/(1-MathPow(corrCoeff,2)));
//---
   if(n<25)
     {
      cVal=-2.62;
        }else{
      if(n>=25 && n<50)
        {
         cVal=-2.60;
           }else{
         if(n>=50 && n<100)
           {
            cVal=-2.58;
              }else{
            cVal=-2.57;
           }
        }
     }
//Drucken(tWert);
   result=tValue>cVal;
   return(result);
   return (tValue);
  }
 
 
//====================Test for COINTEGRATION================================= 
//--- auch Beta-Parameter zurückgeben 
bool engleGrangerTest(double &tsarr1[],double &tsarr2[],double &cointCoeff)
  {
   bool result;
   int length=ArraySize(tsarr1);
   double regressionRes[];
   double residuals[];
   double copyArr1[],copyArr2[];
   double a;
   double b;
//---
   ArrayResize(regressionRes,length);
   ArrayResize(residuals,length);
   ArrayResize(copyArr1,length);
   ArrayResize(copyArr2,length);
//---
   ArrayCopy(copyArr1,tsarr1,0,0);
   ArrayCopy(copyArr2,tsarr2,0,0);
//---
   for(int i=0; i<length;i++)
     {
      copyArr1[i] = MathLog(copyArr1[i]);
      copyArr2[i] = MathLog(copyArr2[i]);
     }
//---
   regression(copyArr1,copyArr2,regressionRes,a,b);
   cointCoeff=a;
//---
   for(int i=0; i<length; i++)
     {
      residuals[i]=copyArr2[i]-regressionRes[i];
     }
//---
   result=dickeyFuller(residuals);
//---
   return(result);
  }
  
  
//===================================================== 
//--- Autoregressives Modell mit Verzögerung 1; Renditeprognose für den nächsten Zeitraum
double AR1(double &arr[])
  {
   double arrY[],arrX[],regRes[];
   double a,b,fcst;
   int n=ArraySize(arr);
   ArrayResize(arrY,n-1);
   ArrayResize(arrX,n-1);
//---
   ArrayCopy(arrY,arr,0,1,n-1);
   ArrayCopy(arrX,arr,0,0,n-1);
//---
   regression(arrX,arrY,regRes,a,b);
   fcst=arr[n-1]*a+b;
//---
   return(fcst);
  }
  
//===================================================== 
  
//--- [a -> unten, b -> oben, n -> polynomialer Grad]
double signedIntegral(double a,double b,int n)
  {
//---
   int mult;
   double h=(b-a)/n;
   double integral=foo(a);
//---
   for(int i=1; i<n; i++)
     {
      if(i%2==0) mult=4; else mult=2;
      integral+=mult*(foo(a+i*h));
     }
//---
   integral += foo(a+n*h);
   integral *= h/3;
//---
   return integral;
  }
  
//===================================================== 
  
//--- zur Verwendung mit Integral bearbeiten
double foo(double x)
  {
   return x;
  }
  
//===================================================== 

//--- Sitt Chee Keen - Credits
double erf(double x)
  {
//--- A&S Formel 7.1.26
   double a1 = 0.254829592;
   double a2 = -0.284496736;
   double a3 = 1.421413741;
   double a4 = -1.453152027;
   double a5 = 1.061405429;
   double p=0.3275911;
   x=MathAbs(x);
   double t=1/(1+p*x);
//---
   return 1 - ((((((a5 * t + a4) * t) + a3) * t + a2) * t) + a1) * t * MathExp(-1 * x * x);
  }
  
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
double normDistZ(double z)
  {
   double sign=1;
   if(z<0) sign=-1;
   return 0.5 * (1.0 + sign * erf(MathAbs(z)/MathSqrt(2)));
  }
//+------------------------------------------------------------------+

void checkBarOpen(){
   datetime currentBarTime = mrate[0].time;   
   _sqIsBarOpen = false;
   
   if(lastBarTime == 0){
      _sqIsBarOpen = true;          
      lastBarTime = currentBarTime;
   }
   else if(currentBarTime != lastBarTime){
      bool processBarOpen = true;

      if(OpenBarDelay > 0) {
         // Legen Sie fest, dass der Balken nach X Minuten nach der tatsächlichen Öffnung geöffnet wird.
         processBarOpen = false;

         int diffInSeconds = (int) (TimeCurrent() - currentBarTime);
         if(diffInSeconds >= OpenBarDelay * 60) {
            processBarOpen = true;
         }
      }

      if(processBarOpen) {
         _sqIsBarOpen = true;
         lastBarTime = currentBarTime;      
      } 
   }
}





HILFE: Ich scheine auf einen " Array out of range error" in der Detrend-Methode zu stoßen, nachdem ich versucht habe, das frühere Skript zu aktualisieren, um mit der aktualisierten MQL5 statistics.mqh übereinzustimmen. Irgendeine Idee, was ich übersehe? Jede Hilfe ist willkommen.