959 lines
		
	
	
	
		
			18 KiB
		
	
	
	
		
			MQL4
		
	
	
	
	
	
			
		
		
	
	
			959 lines
		
	
	
	
		
			18 KiB
		
	
	
	
		
			MQL4
		
	
	
	
	
	
#property show_inputs
 | 
						|
 | 
						|
#define MAX_AMOUNTSYMBOLS 15
 | 
						|
#define MAX_POINTS 100000
 | 
						|
 | 
						|
extern datetime StartTime = D'2010.01.01';
 | 
						|
 | 
						|
string SymbolsStr;
 | 
						|
int Depth, Iterations, Method;
 | 
						|
bool Correlation;
 | 
						|
 | 
						|
string Symbols[MAX_AMOUNTSYMBOLS];
 | 
						|
double BaseMatrix[][MAX_POINTS], MOMatrix[][MAX_POINTS];
 | 
						|
double CvarMatrix[][MAX_AMOUNTSYMBOLS];
 | 
						|
double Means[], SVector[], Divs[];
 | 
						|
int Times[MAX_POINTS];
 | 
						|
int AmountSymbols, MatrixRows, Time0;
 | 
						|
int CurrPos;
 | 
						|
 | 
						|
int AmountSymbols2;
 | 
						|
int AmountVariants, Variants[];
 | 
						|
 | 
						|
string UName;
 | 
						|
 | 
						|
double Matrix[][MAX_AMOUNTSYMBOLS], VectorTmp[];
 | 
						|
 | 
						|
void GetConfig( string FileName )
 | 
						|
{
 | 
						|
  int handle = FileOpen(FileName, FILE_CSV|FILE_READ);
 | 
						|
 | 
						|
  SymbolsStr = FileReadString(handle);
 | 
						|
  Correlation = (FileReadNumber(handle) == 1);
 | 
						|
  Depth = FileReadNumber(handle);
 | 
						|
  Method = FileReadNumber(handle);
 | 
						|
  Iterations = FileReadNumber(handle);
 | 
						|
 | 
						|
  FileClose(handle);
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
string StrDelSpaces( string Str )
 | 
						|
{
 | 
						|
  int Pos, Length;
 | 
						|
 | 
						|
  Str = StringTrimLeft(Str);
 | 
						|
  Str = StringTrimRight(Str);
 | 
						|
 | 
						|
  Length = StringLen(Str) - 1;
 | 
						|
  Pos = 1;
 | 
						|
 | 
						|
  while (Pos < Length)
 | 
						|
    if (StringGetChar(Str, Pos) == ' ')
 | 
						|
    {
 | 
						|
      Str = StringSubstr(Str, 0, Pos) + StringSubstr(Str, Pos + 1, 0);
 | 
						|
      Length--;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      Pos++;
 | 
						|
 | 
						|
  return(Str);
 | 
						|
}
 | 
						|
 | 
						|
int StrToStringS( string Str, string Razdelitel, string &Output[] )
 | 
						|
{
 | 
						|
  int Pos, LengthSh;
 | 
						|
  int Count = 0;
 | 
						|
 | 
						|
  Str = StrDelSpaces(Str);
 | 
						|
  Razdelitel = StrDelSpaces(Razdelitel);
 | 
						|
 | 
						|
  LengthSh = StringLen(Razdelitel);
 | 
						|
 | 
						|
  while (TRUE)
 | 
						|
  {
 | 
						|
    Pos = StringFind(Str, Razdelitel);
 | 
						|
    Output[Count] = StringSubstr(Str, 0, Pos);
 | 
						|
    Count++;
 | 
						|
 | 
						|
    if (Pos == -1)
 | 
						|
      break;
 | 
						|
 | 
						|
    Pos += LengthSh;
 | 
						|
    Str = StringSubstr(Str, Pos);
 | 
						|
  }
 | 
						|
 | 
						|
  return(Count);
 | 
						|
}
 | 
						|
 | 
						|
datetime GetStartTime( datetime StartTime )
 | 
						|
{
 | 
						|
  datetime Tmp;
 | 
						|
  int Pos;
 | 
						|
 | 
						|
  for (int i = 0; i < AmountSymbols; i++)
 | 
						|
  {
 | 
						|
    Pos = iBarShift(Symbols[i], Period(), StartTime);
 | 
						|
 | 
						|
    if (Pos == 0)
 | 
						|
      return(Time0);
 | 
						|
 | 
						|
    Tmp = iTime(Symbols[i], Period(), Pos);
 | 
						|
 | 
						|
    if (Tmp < StartTime)
 | 
						|
      Tmp = iTime(Symbols[i], Period(), Pos - 1);
 | 
						|
 | 
						|
    StartTime = Tmp;
 | 
						|
  }
 | 
						|
 | 
						|
  for (i = 0; i < AmountSymbols; i++)
 | 
						|
    if (StartTime > iTime(Symbols[i], Period(), 0))
 | 
						|
      return(Time0);
 | 
						|
 | 
						|
  return(StartTime);
 | 
						|
}
 | 
						|
 | 
						|
double GetPrice( string Symb, int time )
 | 
						|
{
 | 
						|
  double Price;
 | 
						|
 | 
						|
  Price = iClose(Symb, Period(), iBarShift(Symb, Period(), time));
 | 
						|
 | 
						|
  return(Price);
 | 
						|
}
 | 
						|
 | 
						|
int GetNextTime( int CurrTime )
 | 
						|
{
 | 
						|
  static int Pos[MAX_AMOUNTSYMBOLS];
 | 
						|
  int i, MinTime, Tmp = -1;
 | 
						|
 | 
						|
  for (i = 0; i < AmountSymbols; i++)
 | 
						|
  {
 | 
						|
    Pos[i] = iBarShift(Symbols[i], Period(), CurrTime) - 1;
 | 
						|
 | 
						|
    if (Pos[i] >= 0)
 | 
						|
      Tmp = i;
 | 
						|
  }
 | 
						|
 | 
						|
  if (Tmp < 0)
 | 
						|
    return(Time0);
 | 
						|
 | 
						|
  MinTime = iTime(Symbols[Tmp], Period(), Pos[Tmp]);
 | 
						|
 | 
						|
  i = Tmp - 1;
 | 
						|
 | 
						|
  while (i >= 0)
 | 
						|
  {
 | 
						|
    if (Pos[i] >= 0)
 | 
						|
    {
 | 
						|
      Tmp = iTime(Symbols[i], Period(), Pos[i]);
 | 
						|
 | 
						|
      if (Tmp < MinTime)
 | 
						|
        MinTime = Tmp;
 | 
						|
    }
 | 
						|
 | 
						|
    i--;
 | 
						|
  }
 | 
						|
 | 
						|
  return(MinTime);
 | 
						|
}
 | 
						|
 | 
						|
void GetBaseMatrix()
 | 
						|
{
 | 
						|
  int i, CurrTime = StartTime;
 | 
						|
 | 
						|
  MatrixRows = 0;
 | 
						|
 | 
						|
  while (CurrTime < Time0)
 | 
						|
  {
 | 
						|
    for (i = 0; i < AmountSymbols; i++)
 | 
						|
      BaseMatrix[i][MatrixRows] = 1000 * MathLog(GetPrice(Symbols[i], CurrTime));
 | 
						|
 | 
						|
    Times[MatrixRows] = CurrTime;
 | 
						|
 | 
						|
    MatrixRows++;
 | 
						|
 | 
						|
    CurrTime = GetNextTime(CurrTime);
 | 
						|
  }
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
void GetMeans( int Pos, int Len)
 | 
						|
{
 | 
						|
  int i, j;
 | 
						|
  double Sum;
 | 
						|
 | 
						|
  for (i = 0; i < AmountSymbols;, i++)
 | 
						|
  {
 | 
						|
    Sum = 0;
 | 
						|
 | 
						|
    for (j = Pos; j > Pos - Len; j--)
 | 
						|
      Sum += BaseMatrix[i][j];
 | 
						|
 | 
						|
    Means[i] = Sum / Len;
 | 
						|
  }
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
void GetMOMatrix( int Pos, int Len)
 | 
						|
{
 | 
						|
  int i, j;
 | 
						|
  double Sum;
 | 
						|
 | 
						|
  for (i = 0; i < AmountSymbols;, i++)
 | 
						|
    for (j = Pos; j > Pos - Len; j--)
 | 
						|
      MOMatrix[i][j] = BaseMatrix[i][j] - Means[i];
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
void GetCvarMatrix( int Pos, int Len )
 | 
						|
{
 | 
						|
  int i, j, k;
 | 
						|
  double Cvar;
 | 
						|
 | 
						|
  GetMeans(Pos, Len);
 | 
						|
  GetMOMatrix(Pos, Len);
 | 
						|
 | 
						|
  for (i = 0; i < AmountSymbols; i++)
 | 
						|
  {
 | 
						|
    Cvar = 0;
 | 
						|
 | 
						|
    for (k = Pos; k > Pos - Len; k--)
 | 
						|
      Cvar += MOMatrix[i][k] * MOMatrix[i][k];
 | 
						|
 | 
						|
    Cvar /= Len;
 | 
						|
    Divs[i] = Cvar;
 | 
						|
    CvarMatrix[i][i] = Cvar;
 | 
						|
 | 
						|
    for (j = i + 1; j < AmountSymbols; j++)
 | 
						|
    {
 | 
						|
      Cvar = 0;
 | 
						|
 | 
						|
     for (k = Pos; k > Pos - Len; k--)
 | 
						|
        Cvar += MOMatrix[i][k] * MOMatrix[j][k];
 | 
						|
 | 
						|
      CvarMatrix[i][j] = Cvar / Len;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
bool Init()
 | 
						|
{
 | 
						|
  UName = "hwnd" + WindowHandle(Symbol(), Period());
 | 
						|
 | 
						|
  if (!GlobalVariableCheck(UName))
 | 
						|
    return(FALSE);
 | 
						|
 | 
						|
  GetConfig(UName + ".ini");
 | 
						|
 | 
						|
  AmountSymbols = StrToStringS(SymbolsStr, ",", Symbols);
 | 
						|
  AmountSymbols2 = AmountSymbols * MAX_AMOUNTSYMBOLS;
 | 
						|
 | 
						|
  ArrayResize(Symbols, AmountSymbols);
 | 
						|
  ArrayResize(BaseMatrix, AmountSymbols);
 | 
						|
  ArrayResize(MOMatrix, AmountSymbols);
 | 
						|
  ArrayResize(CvarMatrix, AmountSymbols);
 | 
						|
  ArrayResize(Means, AmountSymbols);
 | 
						|
  ArrayResize(SVector, AmountSymbols);
 | 
						|
  ArrayResize(Divs, AmountSymbols);
 | 
						|
 | 
						|
  ArrayResize(Matrix, AmountSymbols);
 | 
						|
  ArrayResize(VectorTmp, AmountSymbols);
 | 
						|
 | 
						|
  if (Method == 4)
 | 
						|
    AmountVariants = GetVariants(Variants, AmountSymbols);
 | 
						|
 | 
						|
  Time0 = GlobalVariableGet(UName + "LastTime");
 | 
						|
  StartTime = GetStartTime(StartTime);
 | 
						|
 | 
						|
  CurrPos = Depth;
 | 
						|
 | 
						|
  Comment(WindowExpertName() + ":\nGetting history data... (StartTime = " + TimeToStr(StartTime) + ")");
 | 
						|
 | 
						|
  GetBaseMatrix();
 | 
						|
 | 
						|
  GetCvarMatrix(CurrPos - 1, Depth);
 | 
						|
 | 
						|
  return(TRUE);
 | 
						|
}
 | 
						|
 | 
						|
void GetNextMeans( int Pos, int Len )
 | 
						|
{
 | 
						|
  int Pos2 = Pos - Len;
 | 
						|
 | 
						|
  for (int i = 0; i < AmountSymbols; i++)
 | 
						|
  {
 | 
						|
    SVector[i] = (BaseMatrix[i][Pos2] - BaseMatrix[i][Pos]) / Len;
 | 
						|
    Means[i] -= SVector[i];
 | 
						|
  }
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
void GetNextCvarMatrix( int Pos, int Len )
 | 
						|
{
 | 
						|
  int i, j;
 | 
						|
  int Pos2 = Pos - Len;
 | 
						|
  double Tmp1, Tmp2, Tmp3;
 | 
						|
 | 
						|
  GetNextMeans(Pos, Len);
 | 
						|
 | 
						|
  for (i = 0; i < AmountSymbols; i++)
 | 
						|
  {
 | 
						|
    Tmp1 = SVector[i];
 | 
						|
    Tmp2 = BaseMatrix[i][Pos] - Means[i];
 | 
						|
    Tmp3 = BaseMatrix[i][Pos2] - Means[i];
 | 
						|
 | 
						|
    CvarMatrix[i][i] += Tmp1 * Tmp1 + (Tmp2 * Tmp2 - Tmp3 * Tmp3) / Len;
 | 
						|
 | 
						|
    if (CvarMatrix[i][i] < 0)
 | 
						|
    {
 | 
						|
      CvarMatrix[i][i] = 0;
 | 
						|
      Divs[i] = 0;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      Divs[i] = CvarMatrix[i][i];
 | 
						|
 | 
						|
    for (j = i + 1; j < AmountSymbols; j++)
 | 
						|
      CvarMatrix[i][j] += Tmp1 * SVector[j] + (Tmp2 * (BaseMatrix[j][Pos] - Means[j]) - Tmp3 * (BaseMatrix[j][Pos2] - Means[j])) / Len;
 | 
						|
  }
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
void InvertMatrix( double& Matrix[][] )
 | 
						|
{
 | 
						|
  static int rn[];
 | 
						|
  static double str[], strm[];
 | 
						|
  int j,k;
 | 
						|
  int jved;
 | 
						|
  double aved, Tmp;
 | 
						|
 | 
						|
  ArrayResize(rn, AmountSymbols);
 | 
						|
  ArrayResize(str, AmountSymbols);
 | 
						|
  ArrayResize(strm, AmountSymbols);
 | 
						|
 | 
						|
  for (j = 0; j < AmountSymbols; j++)
 | 
						|
    rn[j] = j;
 | 
						|
 | 
						|
  for (int i = 0; i < AmountSymbols; i++)
 | 
						|
  {
 | 
						|
    aved = -1;
 | 
						|
 | 
						|
    for (j = 0; j < AmountSymbols; j++)
 | 
						|
      if (rn[j] != -1)
 | 
						|
      {
 | 
						|
        Tmp = MathAbs(Matrix[j][j]);
 | 
						|
 | 
						|
        if (Tmp > aved)
 | 
						|
        {
 | 
						|
           aved = Tmp;
 | 
						|
           jved = j;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
    rn[jved] = -1;
 | 
						|
 | 
						|
    for (j = 0; j < jved; j++)
 | 
						|
    {
 | 
						|
      str[j] = Matrix[j][jved];
 | 
						|
      strm[j] = str[j] / aved;
 | 
						|
    }
 | 
						|
 | 
						|
    for (j = jved + 1; j < AmountSymbols; j++)
 | 
						|
    {
 | 
						|
      str[j] = Matrix[jved][j];
 | 
						|
      strm[j] = str[j] / aved;
 | 
						|
    }
 | 
						|
 | 
						|
    for (j = 0; j < AmountSymbols; j++)
 | 
						|
      for (k = j; k < AmountSymbols; k++)
 | 
						|
        Matrix[j][k] -= strm[j] * str[k];
 | 
						|
 | 
						|
    for (j = 0; j < jved; j++)
 | 
						|
      Matrix[j][jved] = strm[j];
 | 
						|
 | 
						|
    for (j = jved + 1; j < AmountSymbols; j++)
 | 
						|
      Matrix[jved][j] = strm[j];
 | 
						|
 | 
						|
    Matrix[jved][jved] = -1 / aved;
 | 
						|
  }
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
bool CheckVectorChange( double& V[], double& VChange[] )
 | 
						|
{
 | 
						|
  int i;
 | 
						|
  bool Res;
 | 
						|
  double Sum1 = 0, Sum2 = 0;
 | 
						|
 | 
						|
  for (i = 0; i < AmountSymbols; i++)
 | 
						|
  {
 | 
						|
    Sum1 += MathAbs(V[i] - VChange[i]);
 | 
						|
    Sum2 += MathAbs(V[i] + VChange[i]);
 | 
						|
  }
 | 
						|
 | 
						|
  Res = (Sum1 > Sum2);
 | 
						|
 | 
						|
  if (Res)
 | 
						|
    for (i = 0; i < AmountSymbols; i++)
 | 
						|
      VChange[i] = -VChange[i];
 | 
						|
 | 
						|
  return(Res);
 | 
						|
}
 | 
						|
 | 
						|
void GetOptimalVector1( double& Vector[], int Iterations )
 | 
						|
{
 | 
						|
  int i, j, k;
 | 
						|
  double Tmp, Max = 0;
 | 
						|
 | 
						|
  while (Iterations > 0)
 | 
						|
  {
 | 
						|
    for (i = 0; i < AmountSymbols; i++)
 | 
						|
      for (j = AmountSymbols - 1; j >= i; j--)
 | 
						|
      {
 | 
						|
        Tmp = 0;
 | 
						|
        k = 0;
 | 
						|
 | 
						|
        while (k < i)
 | 
						|
        {
 | 
						|
          Tmp += Matrix[k][i] * Matrix[k][j];
 | 
						|
 | 
						|
          k++;
 | 
						|
        }
 | 
						|
 | 
						|
        while (k < j)
 | 
						|
        {
 | 
						|
          Tmp += Matrix[i][k] * Matrix[k][j];
 | 
						|
 | 
						|
          k++;
 | 
						|
        }
 | 
						|
 | 
						|
        while (k < AmountSymbols)
 | 
						|
        {
 | 
						|
          Tmp += Matrix[i][k] * Matrix[j][k];
 | 
						|
 | 
						|
          k++;
 | 
						|
        }
 | 
						|
 | 
						|
        Matrix[j][i] = Tmp;
 | 
						|
      }
 | 
						|
 | 
						|
    for (i = 0; i < AmountSymbols; i++)
 | 
						|
      for (j = i + 1; j < AmountSymbols; j++)
 | 
						|
        Matrix[i][j] = Matrix[j][i];
 | 
						|
 | 
						|
    Iterations--;
 | 
						|
  }
 | 
						|
 | 
						|
  for (i = 0; i < AmountSymbols; i++)
 | 
						|
  {
 | 
						|
    Tmp = 0;
 | 
						|
 | 
						|
    for (j = 0; j < AmountSymbols; j++)
 | 
						|
      if (Matrix[i][j] < 0)
 | 
						|
        Tmp -= Matrix[i][j];
 | 
						|
      else
 | 
						|
        Tmp += Matrix[i][j];
 | 
						|
 | 
						|
    if (Tmp > Max)
 | 
						|
    {
 | 
						|
       Max = Tmp;
 | 
						|
       k = i;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  ArrayCopy(VectorTmp, Vector);
 | 
						|
 | 
						|
  for (i = 0; i < AmountSymbols; i++)
 | 
						|
    Vector[i] = Matrix[k][i] / Max;
 | 
						|
 | 
						|
  CheckVectorChange(VectorTmp, Vector);
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
double GetOptimalVector2( double& Vector[] )
 | 
						|
{
 | 
						|
  int i, j;
 | 
						|
  double Tmp, Max = 0, StDev = 0;
 | 
						|
 | 
						|
  for (i = 0; i < AmountSymbols; i++)
 | 
						|
  {
 | 
						|
    Tmp = 0;
 | 
						|
    j = 0;
 | 
						|
 | 
						|
    while (j < i)
 | 
						|
    {
 | 
						|
      Tmp -= Matrix[j][i];
 | 
						|
 | 
						|
      j++;
 | 
						|
    }
 | 
						|
 | 
						|
    while (j < AmountSymbols)
 | 
						|
    {
 | 
						|
      Tmp -= Matrix[i][j];
 | 
						|
 | 
						|
      j++;
 | 
						|
    }
 | 
						|
 | 
						|
    VectorTmp[i] = Tmp;
 | 
						|
    StDev += Tmp;
 | 
						|
 | 
						|
    if (Tmp < 0)
 | 
						|
      Max -= Tmp;
 | 
						|
    else
 | 
						|
      Max += Tmp;
 | 
						|
  }
 | 
						|
 | 
						|
  for (i = 0; i < AmountSymbols; i++)
 | 
						|
    VectorTmp[i] /= Max;
 | 
						|
 | 
						|
  CheckVectorChange(Vector, VectorTmp);
 | 
						|
 | 
						|
  ArrayCopy(Vector, VectorTmp);
 | 
						|
 | 
						|
  StDev = MathSqrt(StDev) / Max;
 | 
						|
 | 
						|
  return(StDev);
 | 
						|
}
 | 
						|
 | 
						|
double GetOptimalVector3( double& Vector[] )
 | 
						|
{
 | 
						|
  int i, j;
 | 
						|
  double Tmp, Max = 0, StDev;
 | 
						|
  static bool Flag[];
 | 
						|
 | 
						|
  ArrayResize(Flag, AmountSymbols);
 | 
						|
 | 
						|
  for (i = 0; i < AmountSymbols; i++)
 | 
						|
  {
 | 
						|
    Tmp = 0;
 | 
						|
    j = 0;
 | 
						|
 | 
						|
    Flag[i] = FALSE;
 | 
						|
 | 
						|
    while (j < i)
 | 
						|
    {
 | 
						|
      Tmp -= Matrix[j][i];
 | 
						|
 | 
						|
      j++;
 | 
						|
    }
 | 
						|
 | 
						|
    while (j < AmountSymbols)
 | 
						|
    {
 | 
						|
      Tmp -= Matrix[i][j];
 | 
						|
 | 
						|
      j++;
 | 
						|
    }
 | 
						|
 | 
						|
    VectorTmp[i] = Tmp / 2;
 | 
						|
  }
 | 
						|
 | 
						|
  i = 0;
 | 
						|
 | 
						|
  while (i < AmountSymbols)
 | 
						|
    if (VectorTmp[i] < 0)
 | 
						|
    {
 | 
						|
      Flag[i] = !Flag[i];
 | 
						|
      VectorTmp[i] = -VectorTmp[i];
 | 
						|
 | 
						|
      j = 0;
 | 
						|
 | 
						|
      while (j < i)
 | 
						|
      {
 | 
						|
        if (Flag[j] == Flag[i])
 | 
						|
          VectorTmp[j] -= Matrix[j][i];
 | 
						|
        else
 | 
						|
          VectorTmp[j] += Matrix[j][i];
 | 
						|
 | 
						|
        j++;
 | 
						|
      }
 | 
						|
 | 
						|
      while (j < AmountSymbols)
 | 
						|
      {
 | 
						|
        if (Flag[j] == Flag[i])
 | 
						|
          VectorTmp[j] -= Matrix[i][j];
 | 
						|
        else
 | 
						|
          VectorTmp[j] += Matrix[i][j];
 | 
						|
 | 
						|
        j++;
 | 
						|
      }
 | 
						|
 | 
						|
      i = 0;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      i++;
 | 
						|
 | 
						|
  for (i = 0; i < AmountSymbols; i++)
 | 
						|
    Max += VectorTmp[i];
 | 
						|
 | 
						|
  for (i = 0; i < AmountSymbols; i++)
 | 
						|
    if (Flag[i])
 | 
						|
      VectorTmp[i] /= -Max;
 | 
						|
    else
 | 
						|
      VectorTmp[i] /= Max;
 | 
						|
 | 
						|
  CheckVectorChange(Vector, VectorTmp);
 | 
						|
 | 
						|
  ArrayCopy(Vector, VectorTmp);
 | 
						|
 | 
						|
  StDev = 1 / MathSqrt(Max + Max);
 | 
						|
 | 
						|
  return(StDev);
 | 
						|
}
 | 
						|
 | 
						|
int GetVariants( int& Variants[], int Amount )
 | 
						|
{
 | 
						|
  int i, j;
 | 
						|
  int Pos = 1, Step = 2;
 | 
						|
  int AmountVariants = MathPow(2, Amount - 1) - 1;
 | 
						|
 | 
						|
  ArrayResize(Variants, AmountVariants + 1);
 | 
						|
 | 
						|
  for (i = 0; i < Amount - 1; i++)
 | 
						|
  {
 | 
						|
    for (j = Pos - 1; j < AmountVariants; j += Step)
 | 
						|
      Variants[j] = i;
 | 
						|
 | 
						|
    Pos <<= 1;
 | 
						|
    Step <<= 1;
 | 
						|
  }
 | 
						|
 | 
						|
  Variants[AmountVariants] = Amount - 2;
 | 
						|
 | 
						|
  return(AmountVariants + 1);
 | 
						|
}
 | 
						|
 | 
						|
double GetOptimalVector4( double& Vector[] )
 | 
						|
{
 | 
						|
  int i, j;
 | 
						|
  double Tmp, Max = 0, StDev;
 | 
						|
  bool FlagPositive;
 | 
						|
  static bool Flag[], BestFlag[];
 | 
						|
  static double BestVector[];
 | 
						|
 | 
						|
  ArrayResize(Flag, AmountSymbols);
 | 
						|
  ArrayResize(BestFlag, AmountSymbols);
 | 
						|
  ArrayResize(BestVector, AmountSymbols);
 | 
						|
 | 
						|
  for (i = 0; i < AmountSymbols; i++)
 | 
						|
  {
 | 
						|
    Tmp = 0;
 | 
						|
    j = 0;
 | 
						|
 | 
						|
    Flag[i] = FALSE;
 | 
						|
 | 
						|
    while (j < i)
 | 
						|
    {
 | 
						|
      Tmp -= Matrix[j][i];
 | 
						|
 | 
						|
      j++;
 | 
						|
    }
 | 
						|
 | 
						|
    while (j < AmountSymbols)
 | 
						|
    {
 | 
						|
      Tmp -= Matrix[i][j];
 | 
						|
 | 
						|
      j++;
 | 
						|
    }
 | 
						|
 | 
						|
    VectorTmp[i] = Tmp / 2;
 | 
						|
  }
 | 
						|
 | 
						|
  for (int k = 0; k < AmountVariants; k++)
 | 
						|
  {
 | 
						|
    i = Variants[k];
 | 
						|
    FlagPositive = TRUE;
 | 
						|
    StDev = 0;
 | 
						|
 | 
						|
    Flag[i] = !Flag[i];
 | 
						|
    VectorTmp[i] = -VectorTmp[i];
 | 
						|
 | 
						|
    j = 0;
 | 
						|
 | 
						|
    while (j < i)
 | 
						|
    {
 | 
						|
      if (Flag[j] == Flag[i])
 | 
						|
        VectorTmp[j] -= Matrix[j][i];
 | 
						|
      else
 | 
						|
        VectorTmp[j] += Matrix[j][i];
 | 
						|
 | 
						|
      if (FlagPositive)
 | 
						|
      {
 | 
						|
        if (VectorTmp[j] >= 0)
 | 
						|
          StDev += VectorTmp[j];
 | 
						|
        else
 | 
						|
          FlagPositive = FALSE;
 | 
						|
      }
 | 
						|
 | 
						|
      j++;
 | 
						|
    }
 | 
						|
 | 
						|
    while (j < AmountSymbols)
 | 
						|
    {
 | 
						|
      if (Flag[j] == Flag[i])
 | 
						|
        VectorTmp[j] -= Matrix[i][j];
 | 
						|
      else
 | 
						|
        VectorTmp[j] += Matrix[i][j];
 | 
						|
 | 
						|
      if (FlagPositive)
 | 
						|
      {
 | 
						|
        if (VectorTmp[j] >= 0)
 | 
						|
          StDev += VectorTmp[j];
 | 
						|
        else
 | 
						|
          FlagPositive = FALSE;
 | 
						|
      }
 | 
						|
 | 
						|
      j++;
 | 
						|
    }
 | 
						|
 | 
						|
    if (FlagPositive)
 | 
						|
      if (StDev > Max)
 | 
						|
      {
 | 
						|
        Max = StDev;
 | 
						|
 | 
						|
        ArrayCopy(BestVector, VectorTmp);
 | 
						|
        ArrayCopy(BestFlag, Flag);
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  for (i = 0; i < AmountSymbols; i++)
 | 
						|
    if (BestFlag[i])
 | 
						|
      BestVector[i] /= -Max;
 | 
						|
    else
 | 
						|
      BestVector[i] /= Max;
 | 
						|
 | 
						|
  CheckVectorChange(Vector, BestVector);
 | 
						|
 | 
						|
  ArrayCopy(Vector, BestVector);
 | 
						|
 | 
						|
  StDev = 1 / MathSqrt(Max + Max);
 | 
						|
 | 
						|
  return(StDev);
 | 
						|
}
 | 
						|
 | 
						|
double GetOptimalVector( double& Vector[], int Method, bool Correlation )
 | 
						|
{
 | 
						|
  int i, j;
 | 
						|
  double Tmp, Tmp2, StDev;
 | 
						|
 | 
						|
  ArrayCopy(Matrix, CvarMatrix, 0, 0, AmountSymbols2);
 | 
						|
 | 
						|
  if (Correlation)
 | 
						|
  {
 | 
						|
    for (i = 0; i < AmountSymbols; i++)
 | 
						|
      Divs[i] = MathSqrt(Divs[i]);
 | 
						|
 | 
						|
    for (i = 0; i < AmountSymbols; i++)
 | 
						|
    {
 | 
						|
      Matrix[i][i] = 1;
 | 
						|
      Tmp = Divs[i];
 | 
						|
 | 
						|
      if (Tmp != 0)
 | 
						|
        for (j = i + 1; j < AmountSymbols; j++)
 | 
						|
        {
 | 
						|
          Tmp2 = Tmp * Divs[j]; // if Divs[] != 0, then Divs[] * Divs[] != 0, because MathSqrt.
 | 
						|
 | 
						|
          if (Tmp2 != 0)
 | 
						|
            Matrix[i][j] /= Tmp2;
 | 
						|
          else
 | 
						|
            Matrix[i][j] = 0;
 | 
						|
        }
 | 
						|
      else
 | 
						|
        for (j = i + 1; j < AmountSymbols; j++)
 | 
						|
          Matrix[i][j] = 0;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  InvertMatrix(Matrix);
 | 
						|
 | 
						|
  switch (Method)
 | 
						|
  {
 | 
						|
    case 1:
 | 
						|
      GetOptimalVector1(Vector, Iterations);
 | 
						|
      StDev = GetDivergence(CurrPos, Depth, Vector, Correlation);
 | 
						|
      break;
 | 
						|
    case 2:
 | 
						|
      StDev = GetOptimalVector2(Vector);
 | 
						|
      break;
 | 
						|
    case 3:
 | 
						|
      StDev = GetOptimalVector3(Vector);
 | 
						|
      break;
 | 
						|
    case 4:
 | 
						|
      StDev = GetOptimalVector4(Vector);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  return(StDev);
 | 
						|
}
 | 
						|
 | 
						|
double GetRecycle( int Pos, int Len, double& Vector[], bool Correlation )
 | 
						|
{
 | 
						|
  int i;
 | 
						|
  double Recycle = 0;
 | 
						|
 | 
						|
  if (Correlation)
 | 
						|
  {
 | 
						|
    for (i = 0; i < AmountSymbols;, i++)
 | 
						|
      if (Divs[i] != 0)
 | 
						|
        Recycle += (BaseMatrix[i][Pos] - Means[i]) * Vector[i] / Divs[i]; // Divs == StdDev
 | 
						|
  }
 | 
						|
  else
 | 
						|
    for (i = 0; i < AmountSymbols;, i++)
 | 
						|
      Recycle += (BaseMatrix[i][Pos] - Means[i]) * Vector[i];
 | 
						|
 | 
						|
  return(Recycle);
 | 
						|
}
 | 
						|
 | 
						|
double GetDivergence( int Pos, int Len, double& Vector[], bool Correlation )
 | 
						|
{
 | 
						|
  int i, j;
 | 
						|
  double Sum, Div = 0, Tmp = 0;
 | 
						|
 | 
						|
  if (Correlation)
 | 
						|
  {
 | 
						|
    for (i = 0; i < AmountSymbols; i++)
 | 
						|
      if (Divs[i] != 0)
 | 
						|
      {
 | 
						|
        VectorTmp[i] = Vector[i] / Divs[i];
 | 
						|
        Tmp -= Means[i] * VectorTmp[i];
 | 
						|
      }
 | 
						|
 | 
						|
    for (i = Pos; i > Pos - Len; i--)
 | 
						|
    {
 | 
						|
      Sum = Tmp;
 | 
						|
 | 
						|
      for (j = 0; j < AmountSymbols;, j++)
 | 
						|
        if (Divs[j] != 0)
 | 
						|
          Sum += BaseMatrix[j][i] * Vector[j] / Divs[j]; // Divs == StdDev
 | 
						|
 | 
						|
      Div += Sum * Sum;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    for (i = 0; i < AmountSymbols; i++)
 | 
						|
      Tmp -= Means[i] * Vector[i];
 | 
						|
 | 
						|
    for (i = Pos; i > Pos - Len; i--)
 | 
						|
    {
 | 
						|
      Sum = Tmp;
 | 
						|
 | 
						|
      for (j = 0; j < AmountSymbols;, j++)
 | 
						|
        Sum += BaseMatrix[j][i] * Vector[j];
 | 
						|
 | 
						|
      Div += Sum * Sum;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  Div /= Len;
 | 
						|
 | 
						|
  return(MathSqrt(Div));
 | 
						|
}
 | 
						|
 | 
						|
void deinit()
 | 
						|
{
 | 
						|
  Comment("");
 | 
						|
 | 
						|
  GlobalVariableSet(UName + "Done", 0);
 | 
						|
 | 
						|
  AddTick();
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
void SetComment( int TimeInterval )
 | 
						|
{
 | 
						|
  string Str = WindowExpertName() + ":\n";
 | 
						|
 | 
						|
  Str = Str + "Depth = " + Depth + " bars, AmountSymbols = " + AmountSymbols + "\n";
 | 
						|
  Str = Str + "Ready: " + DoubleToStr(100.0 * (CurrPos - Depth) / (MatrixRows - Depth), 1) + "%";
 | 
						|
  Str = Str + " (" + TimeToStr(Times[CurrPos]) + ")\n";
 | 
						|
 | 
						|
  if (TimeInterval != 0)
 | 
						|
    Str = Str + "Performance = "  + DoubleToStr((CurrPos - Depth) * 1000 / TimeInterval, 0) + " bars/sec.\n";
 | 
						|
 | 
						|
  Str = Str + "Elapsed time: " + TimeToStr(TimeInterval / 1000, TIME_SECONDS) + "\n";
 | 
						|
  Str = Str + "Remaining time: " + TimeToStr(1.0 * (MatrixRows - CurrPos) * TimeInterval / (1000 * (CurrPos - Depth)), TIME_SECONDS);
 | 
						|
 | 
						|
  Comment(Str);
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
void start()
 | 
						|
{
 | 
						|
  int Start, handle;
 | 
						|
  int PrevTime, CurrentTime;
 | 
						|
  double Div, Recycle, V[];
 | 
						|
 | 
						|
  if (!Init())
 | 
						|
    return;
 | 
						|
 | 
						|
  ArrayResize(V, AmountSymbols);
 | 
						|
  handle = FileOpen(UName + ".dat", FILE_BIN|FILE_WRITE);
 | 
						|
 | 
						|
  Start = GetTickCount();
 | 
						|
  PrevTime = Start;
 | 
						|
 | 
						|
  while (CurrPos < MatrixRows)
 | 
						|
  {
 | 
						|
    if (!GlobalVariableCheck(UName))
 | 
						|
      break;
 | 
						|
 | 
						|
    GetNextCvarMatrix(CurrPos, Depth);
 | 
						|
//    GetCvarMatrix(CurrPos, Depth);
 | 
						|
    Div = GetOptimalVector(V, Method, Correlation);
 | 
						|
    Recycle = GetRecycle(CurrPos, Depth, V, Correlation);
 | 
						|
 | 
						|
    FileWriteInteger(handle, Times[CurrPos]);
 | 
						|
    FileWriteDouble(handle, Recycle);
 | 
						|
    FileWriteDouble(handle, Div);
 | 
						|
 | 
						|
    FileWriteArray(handle, V, 0, AmountSymbols);
 | 
						|
 | 
						|
    CurrPos++;
 | 
						|
 | 
						|
    CurrentTime = GetTickCount();
 | 
						|
 | 
						|
    if ((CurrentTime - PrevTime > 1000) || (CurrentTime - PrevTime < -1000))
 | 
						|
    {
 | 
						|
      PrevTime = CurrentTime;
 | 
						|
 | 
						|
      SetComment(CurrentTime - Start);
 | 
						|
    }
 | 
						|
 | 
						|
    if (IsStopped())
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  FileClose(handle);
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
#import "user32.dll"
 | 
						|
  int PostMessageA( int hWnd, int Msg, int wParam, int lParam );
 | 
						|
  int RegisterWindowMessageA( string lpString );
 | 
						|
#import
 | 
						|
 | 
						|
void AddTick()
 | 
						|
{
 | 
						|
  if (!IsDllsAllowed())
 | 
						|
    return;
 | 
						|
 | 
						|
  int hwnd = WindowHandle(Symbol(), Period());
 | 
						|
  int MT4InternalMsg = RegisterWindowMessageA("MetaTrader4_Internal_Message");
 | 
						|
 | 
						|
  PostMessageA(hwnd, MT4InternalMsg, 2, 1);
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 |