582 lines
		
	
	
		
			No EOL
		
	
	
		
			11 KiB
		
	
	
	
		
			MQL4
		
	
	
	
	
	
			
		
		
	
	
			582 lines
		
	
	
		
			No EOL
		
	
	
		
			11 KiB
		
	
	
	
		
			MQL4
		
	
	
	
	
	
#property indicator_separate_window
 | 
						|
#property indicator_buffers 1
 | 
						|
#property indicator_color1 Red
 | 
						|
#property indicator_width1 1
 | 
						|
#property indicator_levelcolor Blue
 | 
						|
#property indicator_levelwidth 1
 | 
						|
 | 
						|
#define MAX_AMOUNTSYMBOLS 15
 | 
						|
#define MAX_POINTS 100000
 | 
						|
 | 
						|
extern color ColorText = Gray;
 | 
						|
 | 
						|
string FontName = "Arial";
 | 
						|
 | 
						|
string SymbolsStr;
 | 
						|
int Depth;
 | 
						|
bool Correlation;
 | 
						|
 | 
						|
double Buffer[];
 | 
						|
 | 
						|
string Symbols[MAX_AMOUNTSYMBOLS];
 | 
						|
double BaseMatrix[][MAX_POINTS];
 | 
						|
double Means[], Vars[], SVector[];
 | 
						|
int Times[MAX_POINTS];
 | 
						|
double Recycles[], Divs[];
 | 
						|
int AmountSymbols, MatrixRows;
 | 
						|
double Vectors[][MAX_POINTS];
 | 
						|
int StartTime;
 | 
						|
double Data[];
 | 
						|
 | 
						|
string IndName = "RecycleShowMe";
 | 
						|
string UName;
 | 
						|
 | 
						|
void GetConfig( string FileName )
 | 
						|
{
 | 
						|
  int handle = FileOpen(FileName, FILE_CSV|FILE_READ);
 | 
						|
 | 
						|
  SymbolsStr = FileReadString(handle);
 | 
						|
  Correlation = (FileReadNumber(handle) == 1);
 | 
						|
  Depth = 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( string FileName )
 | 
						|
{
 | 
						|
  int handle = FileOpen(FileName, FILE_BIN|FILE_READ);
 | 
						|
  int T[], Time0, CurrTime, Pos = 0;
 | 
						|
 | 
						|
  if (FileSize(handle) == 0)
 | 
						|
    return(0);
 | 
						|
  Time0 = FileReadInteger(handle);
 | 
						|
  FileClose(handle);
 | 
						|
 | 
						|
  ArrayResize(T, Depth);
 | 
						|
 | 
						|
  CurrTime = iTime(Symbols[0], Period(), iBarShift(Symbols[0], Period(), Time0) + Depth);
 | 
						|
 | 
						|
  while (CurrTime < Time0)
 | 
						|
  {
 | 
						|
    T[Pos] = CurrTime;
 | 
						|
 | 
						|
    if (Pos < Depth - 1)
 | 
						|
      Pos++;
 | 
						|
    else
 | 
						|
      Pos = 0;
 | 
						|
 | 
						|
    CurrTime = GetNextTime(CurrTime);
 | 
						|
  }
 | 
						|
 | 
						|
  return(T[Pos]);
 | 
						|
}
 | 
						|
 | 
						|
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(Time[0]);
 | 
						|
 | 
						|
  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 < Time[0])
 | 
						|
  {
 | 
						|
    for (i = 0; i < AmountSymbols; i++)
 | 
						|
      BaseMatrix[i][MatrixRows] = 1000 * MathLog(GetPrice(Symbols[i], CurrTime));
 | 
						|
 | 
						|
    Times[MatrixRows] = CurrTime;
 | 
						|
 | 
						|
    MatrixRows++;
 | 
						|
 | 
						|
    CurrTime = GetNextTime(CurrTime);
 | 
						|
  }
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
void GetData( string FileName )
 | 
						|
{
 | 
						|
  int i = Depth, j;
 | 
						|
  double V[];
 | 
						|
  int handle = FileOpen(FileName, FILE_BIN|FILE_READ);
 | 
						|
 | 
						|
  ArrayResize(V, AmountSymbols);
 | 
						|
 | 
						|
  while (FileTell(handle) < FileSize(handle))
 | 
						|
  {
 | 
						|
    Times[i] = FileReadInteger(handle);
 | 
						|
    Recycles[i] = FileReadDouble(handle);
 | 
						|
    Divs[i] = FileReadDouble(handle);
 | 
						|
 | 
						|
    FileReadArray(handle, V, 0, AmountSymbols);
 | 
						|
 | 
						|
    for (j = 0; j < AmountSymbols; j++)
 | 
						|
      Vectors[j][i] = V[j];
 | 
						|
 | 
						|
    i++;
 | 
						|
  }
 | 
						|
 | 
						|
  FileClose(handle);
 | 
						|
 | 
						|
  MatrixRows = i;
 | 
						|
 | 
						|
  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 GetVars( int Pos, int Len )
 | 
						|
{
 | 
						|
  int i, j;
 | 
						|
  double Cvar, Tmp;
 | 
						|
 | 
						|
  GetMeans(Pos, Len);
 | 
						|
 | 
						|
  for (i = 0; i < AmountSymbols; i++)
 | 
						|
  {
 | 
						|
    Cvar = 0;
 | 
						|
 | 
						|
    for (j = Pos; j > Pos - Len; j--)
 | 
						|
    {
 | 
						|
      Tmp = BaseMatrix[i][j] - Means[i];
 | 
						|
 | 
						|
      Cvar += Tmp * Tmp;
 | 
						|
    }
 | 
						|
 | 
						|
    Vars[i] = Cvar / Len;
 | 
						|
  }
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
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 GetNextVars( int Pos, int Len )
 | 
						|
{
 | 
						|
  int Pos2 = Pos - Len;
 | 
						|
  double Tmp1, Tmp2, Tmp3;
 | 
						|
 | 
						|
  GetNextMeans(Pos, Len);
 | 
						|
 | 
						|
  for (int i = 0; i < AmountSymbols; i++)
 | 
						|
  {
 | 
						|
    Tmp1 = SVector[i];
 | 
						|
    Tmp2 = BaseMatrix[i][Pos] - Means[i];
 | 
						|
    Tmp3 = BaseMatrix[i][Pos2] - Means[i];
 | 
						|
 | 
						|
    Vars[i] += Tmp1 * Tmp1 + (Tmp2 * Tmp2 - Tmp3 * Tmp3) / Len;
 | 
						|
 | 
						|
    if (Vars[i] < 0)
 | 
						|
      Vars[i] = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
void ChangeVectors()
 | 
						|
{
 | 
						|
  int i, CurrPos = Depth;
 | 
						|
 | 
						|
  ArrayResize(Vars, AmountSymbols);
 | 
						|
  ArrayResize(SVector, AmountSymbols);
 | 
						|
 | 
						|
  GetVars(CurrPos - 1, Depth);
 | 
						|
 | 
						|
  while (CurrPos < MatrixRows)
 | 
						|
  {
 | 
						|
    GetNextVars(CurrPos, Depth);
 | 
						|
 | 
						|
    for (i = 0; i < AmountSymbols; i++)
 | 
						|
    {
 | 
						|
      if (Vars[i] == 0)
 | 
						|
        Vectors[i][CurrPos] = 0;
 | 
						|
      else
 | 
						|
        Vectors[i][CurrPos] /= MathSqrt(Vars[i]);
 | 
						|
    }
 | 
						|
 | 
						|
    CurrPos++;
 | 
						|
  }
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
void init()
 | 
						|
{
 | 
						|
  UName = "hwnd" + WindowHandle(Symbol(), Period());
 | 
						|
 | 
						|
  if (!GlobalVariableCheck(UName))
 | 
						|
    return;
 | 
						|
 | 
						|
  IndicatorDigits(8);
 | 
						|
  SetIndexStyle(0, DRAW_LINE, DRAW_LINE);
 | 
						|
  SetIndexBuffer(0, Buffer);
 | 
						|
 | 
						|
  GetConfig(UName + ".ini");
 | 
						|
 | 
						|
  AmountSymbols = StrToStringS(SymbolsStr, ",", Symbols);
 | 
						|
 | 
						|
  ArrayResize(Symbols, AmountSymbols);
 | 
						|
  ArrayResize(BaseMatrix, AmountSymbols);
 | 
						|
  ArrayResize(Means, AmountSymbols);
 | 
						|
  ArrayResize(Vectors, AmountSymbols);
 | 
						|
 | 
						|
  StartTime = GetStartTime(UName + ".dat");
 | 
						|
 | 
						|
  GetBaseMatrix();
 | 
						|
 | 
						|
  ArrayResize(Recycles, MatrixRows);
 | 
						|
  ArrayResize(Times, MatrixRows);
 | 
						|
  ArrayResize(Divs, MatrixRows);
 | 
						|
 | 
						|
  ArrayResize(Data, MatrixRows);
 | 
						|
 | 
						|
  GetData(UName + ".dat");
 | 
						|
 | 
						|
  if (Correlation)
 | 
						|
    ChangeVectors();
 | 
						|
 | 
						|
  return(TRUE);
 | 
						|
}
 | 
						|
 | 
						|
int GetTimePos( int SearchTime )
 | 
						|
{
 | 
						|
  int LeftTime, RightTime, PosTime;
 | 
						|
  int Left, Right, Pos = 0;
 | 
						|
 | 
						|
  Left = 0;
 | 
						|
  Right = MatrixRows - 1;
 | 
						|
 | 
						|
  LeftTime = Times[Left];
 | 
						|
  RightTime = Times[Right];
 | 
						|
 | 
						|
  if (SearchTime >= RightTime)
 | 
						|
    Pos = Right;
 | 
						|
 | 
						|
  while ((LeftTime < SearchTime) && (SearchTime < RightTime))
 | 
						|
  {
 | 
						|
    Pos = (Left + Right) >> 1;
 | 
						|
    PosTime = Times[Pos];
 | 
						|
 | 
						|
    if (Pos == Left)
 | 
						|
      break;
 | 
						|
 | 
						|
    if (SearchTime >= PosTime)
 | 
						|
    {
 | 
						|
      Left = Pos;
 | 
						|
      LeftTime = PosTime;
 | 
						|
    }
 | 
						|
    else // if (SearchTime < PosTime)
 | 
						|
    {
 | 
						|
      Right = Pos;
 | 
						|
      RightTime = PosTime;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return(Pos);
 | 
						|
}
 | 
						|
 | 
						|
void DrawData( int Pos )
 | 
						|
{
 | 
						|
  int i;
 | 
						|
  string Str = ")";
 | 
						|
  double Tmp = Data[Pos];
 | 
						|
  double Max = MathAbs(Tmp);
 | 
						|
  int NullTime, NullBar, MaxBar = Pos;
 | 
						|
 | 
						|
  SetLevelValue(0, Divs[Pos]);
 | 
						|
  SetLevelValue(1, -Divs[Pos]);
 | 
						|
 | 
						|
  for (i = 0; i < MatrixRows; i++)
 | 
						|
    Buffer[iBarShift(Symbol(), Period(), Times[i])] = Data[i];
 | 
						|
 | 
						|
  for (i = Pos + 1; i < MatrixRows; i++)
 | 
						|
    if (Data[i] * Tmp <= 0)
 | 
						|
      break;
 | 
						|
    else if (MathAbs(Data[i]) > Max)
 | 
						|
    {
 | 
						|
      Max = MathAbs(Data[i]);
 | 
						|
      MaxBar = i;
 | 
						|
    }
 | 
						|
 | 
						|
  NullBar = i;
 | 
						|
 | 
						|
  if (NullBar == MatrixRows)
 | 
						|
  {
 | 
						|
    NullBar--;
 | 
						|
    Str = " - EndTime)";
 | 
						|
 | 
						|
    ObjectSet("Null1", OBJPROP_TIME1, 0);
 | 
						|
  }
 | 
						|
  else
 | 
						|
    ObjectSet("Null1", OBJPROP_TIME1, Times[NullBar]);
 | 
						|
 | 
						|
  Max = Data[MaxBar];
 | 
						|
  NullTime = Times[NullBar];
 | 
						|
  NullBar -= Pos;
 | 
						|
  MaxBar -= Pos;
 | 
						|
 | 
						|
  ModifyTextObject("NullBar1", "NullBar1 = " + NullBar + " (" + TimeToStr(NullTime) + Str);
 | 
						|
  ModifyTextObject("MaxBar1", "MaxBar1 = " + MaxBar + " (" + Max + ")");
 | 
						|
 | 
						|
  Pos -= Depth - 1;
 | 
						|
 | 
						|
  Tmp = Data[Pos];
 | 
						|
  Max = MathAbs(Tmp);
 | 
						|
  MaxBar = Pos;
 | 
						|
 | 
						|
  for (i = Pos - 1; i >= 0; i--)
 | 
						|
    if (Data[i] * Tmp <= 0)
 | 
						|
      break;
 | 
						|
    else if (MathAbs(Data[i]) > Max)
 | 
						|
    {
 | 
						|
      Max = MathAbs(Data[i]);
 | 
						|
      MaxBar = i;
 | 
						|
    }
 | 
						|
 | 
						|
  NullBar = i;
 | 
						|
 | 
						|
  if (NullBar < 0)
 | 
						|
  {
 | 
						|
    NullBar++;
 | 
						|
    Str = " - BeginTime)";
 | 
						|
 | 
						|
    ObjectSet("Null2", OBJPROP_TIME1, 0);
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    Str = ")";
 | 
						|
 | 
						|
    ObjectSet("Null2", OBJPROP_TIME1, Times[NullBar]);
 | 
						|
  }
 | 
						|
 | 
						|
  Max = Data[MaxBar];
 | 
						|
  NullTime = Times[NullBar];
 | 
						|
  NullBar = Pos - NullBar;
 | 
						|
  MaxBar = Pos - MaxBar;
 | 
						|
 | 
						|
  ModifyTextObject("NullBar2", "NullBar2 = " + NullBar + " (" + TimeToStr(NullTime) + Str);
 | 
						|
  ModifyTextObject("MaxBar2", "MaxBar2 = " + MaxBar + " (" + Max + ")");
 | 
						|
 | 
						|
  WindowRedraw();
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
void Check()
 | 
						|
{
 | 
						|
  static int PrevEndInterval = 0;
 | 
						|
  int EndInterval, Pos;
 | 
						|
  int i, j;
 | 
						|
  double Tmp, Mean = 0;
 | 
						|
 | 
						|
  EndInterval = ObjectGet("EndInterval", OBJPROP_TIME1);
 | 
						|
 | 
						|
  if (EndInterval != PrevEndInterval)
 | 
						|
  {
 | 
						|
    PrevEndInterval = EndInterval;
 | 
						|
 | 
						|
    Pos = GetTimePos(EndInterval);
 | 
						|
 | 
						|
    GetMeans(Pos, Depth);
 | 
						|
 | 
						|
    for (i = 0; i < AmountSymbols; i++)
 | 
						|
      Mean -= Means[i] * Vectors[i][Pos];
 | 
						|
 | 
						|
    for (i = 0; i < MatrixRows; i++)
 | 
						|
    {
 | 
						|
      Tmp = Mean;
 | 
						|
 | 
						|
      for (j = 0; j < AmountSymbols; j++)
 | 
						|
        Tmp += BaseMatrix[j][i] * Vectors[j][Pos];
 | 
						|
 | 
						|
      Data[i] = Tmp;
 | 
						|
   }
 | 
						|
 | 
						|
    DrawData(Pos);
 | 
						|
  }
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
void CreateObject( string Name, string Value, int FontSize, int Xcoord, int Ycoord, int Angle, bool Hide, bool Back, int Color )
 | 
						|
{
 | 
						|
  ObjectCreate(Name, OBJ_LABEL, WindowFind(IndName), 0, 0);
 | 
						|
//  HideObject(Name, Hide);
 | 
						|
  ObjectSet(Name, OBJPROP_ANGLE, Angle);
 | 
						|
  ObjectSet(Name, OBJPROP_XDISTANCE, Xcoord);
 | 
						|
  ObjectSet(Name, OBJPROP_YDISTANCE, Ycoord);
 | 
						|
  ObjectSet(Name, OBJPROP_BACK, Back);
 | 
						|
  ObjectSetText(Name, Value, FontSize, FontName, Color);
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
void ModifyTextObject( string Name, string Text )
 | 
						|
{
 | 
						|
  int Color = ObjectGet(Name, OBJPROP_COLOR);
 | 
						|
  int FontSize = ObjectGet(Name, OBJPROP_FONTSIZE);
 | 
						|
 | 
						|
  ObjectSetText(Name, Text, FontSize, FontName, Color);
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
void CreateObjects( int Xcoord, int Ycoord )
 | 
						|
{
 | 
						|
  CreateObject("NullBar1", "NullBar1", 12, Xcoord, Ycoord, 0, FALSE, FALSE, ColorText);
 | 
						|
  CreateObject("MaxBar1", "MaxBar1", 12, Xcoord, Ycoord + 20, 0, FALSE, FALSE, ColorText);
 | 
						|
  CreateObject("NullBar2", "NullBar2", 12, Xcoord, Ycoord + 60, 0, FALSE, FALSE, ColorText);
 | 
						|
  CreateObject("MaxBar2", "MaxBar2", 12, Xcoord, Ycoord + 80, 0, FALSE, FALSE, ColorText);
 | 
						|
 | 
						|
  ObjectCreate("Null1", OBJ_ARROW, WindowFind(IndName), 0, 0);
 | 
						|
  ObjectSet("Null1", OBJPROP_ARROWCODE, 3);
 | 
						|
 | 
						|
  ObjectCreate("Null2", OBJ_ARROW, WindowFind(IndName), 0, 0);
 | 
						|
  ObjectSet("Null2", OBJPROP_ARROWCODE, 3);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
void Init()
 | 
						|
{
 | 
						|
  static bool FirstRun = TRUE;
 | 
						|
 | 
						|
  if (!FirstRun)
 | 
						|
    return;
 | 
						|
 | 
						|
  IndicatorShortName(IndName);
 | 
						|
 | 
						|
  CreateObjects(5, 15);
 | 
						|
 | 
						|
  FirstRun = FALSE;
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
void start()
 | 
						|
{
 | 
						|
  Init();
 | 
						|
 | 
						|
  Check();
 | 
						|
 | 
						|
  return;
 | 
						|
} |