SCR_RecycleHistory2

Price Data Components
Series array that contains close prices for each bar
Miscellaneous
Uses files from the file systemIt reads information from a fileIt reads information from a fileIt writes information to fileIt writes information to fileIt writes information to file
0 Views
0 Downloads
0 Favorites
SCR_RecycleHistory2
#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;
}

Comments