#property show_inputs #define MAX_AMOUNTSYMBOLS 15 #define MAX_POINTS 100000 extern datetime StartTime = D'2010.01.01'; string SymbolsStr; int Depth, Iterations; 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; string UName; void GetConfig( string FileName ) { int handle = FileOpen(FileName, FILE_CSV|FILE_READ); SymbolsStr = FileReadString(handle); Correlation = (FileReadNumber(handle) == 1); Depth = 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); Tmp = iTime(Symbols[i], Period(), Pos); if (Tmp > StartTime) StartTime = Tmp; } 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]; Divs[i] = Cvar / Len; CvarMatrix[i][i] = Divs[i]; 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); ArrayResize(Symbols, AmountSymbols); ArrayResize(BaseMatrix, AmountSymbols); ArrayResize(MOMatrix, AmountSymbols); ArrayResize(CvarMatrix, AmountSymbols); ArrayResize(Means, AmountSymbols); ArrayResize(SVector, AmountSymbols); ArrayResize(Divs, AmountSymbols); StartTime = GetStartTime(StartTime); CurrPos = Depth; Comment(WindowExpertName() + ":\nGetting history data... (StartTime = " + TimeToStr(StartTime) + ")"); Time0 = GlobalVariableGet(UName + "LastTime"); 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); GetMOMatrix(Pos, Len); for (i = 0; i < AmountSymbols; i++) { Tmp1 = SVector[i]; Tmp2 = MOMatrix[i][Pos]; Tmp3 = MOMatrix[i][Pos2] + SVector[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 * MOMatrix[j][Pos] - Tmp3 * (MOMatrix[j][Pos2] + SVector[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; } int GetSign( double Num1, double Num2 ) { if (Num1 >= 0) { if (Num2 >= 0) return(1); } else if (Num2 < 0) return(1); return(-1); } void GetOptimalVector( double& Vector[], int Iterations, bool Correlation ) { int i, j, k; double Max, Tmp; static double Matrix[][MAX_AMOUNTSYMBOLS]; ArrayResize(Matrix, AmountSymbols); if (Correlation) { for (i = 0; i < AmountSymbols; i++) Divs[i] = MathSqrt(Divs[i]); for (i = 0; i < AmountSymbols; i++) { Matrix[i][i] = 1; if (Divs[i] != 0) for (j = i + 1; j < AmountSymbols; j++) if (Divs[j] != 0) Matrix[i][j] = CvarMatrix[i][j] / (Divs[i] * Divs[j]); else Matrix[i][j] = 0; else for (j = i + 1; j < AmountSymbols; j++) Matrix[i][j] = 0; } } else for (i = 0; i < AmountSymbols; i++) for (j = i; j < AmountSymbols; j++) Matrix[i][j] = CvarMatrix[i][j]; InvertMatrix(Matrix); while (Iterations > 0) { Max = 0; for (i = 0; i < AmountSymbols; i++) for (j = i; j < AmountSymbols; j++) { Tmp = MathAbs(Matrix[i][j]); if (Tmp > Max) Max = Tmp; } for (i = 0; i < AmountSymbols; i++) for (j = i; j < AmountSymbols; j++) Matrix[i][j] /= Max; 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--; } Max = 0; for (i = 0; i < AmountSymbols; i++) { Tmp = 0; for (j = 0; j < AmountSymbols; j++) Tmp += Matrix[i][j] * Matrix[i][j]; if (Tmp > Max) { Max = Tmp; k = i; } } j = 0; for (i = 0; i < AmountSymbols; i++) j += GetSign(Vector[i], Matrix[k][i]); if (j >= 0) Max = MathSqrt(Max); else Max = -MathSqrt(Max); for (i = 0; i < AmountSymbols; i++) Vector[i] = Matrix[k][i] / Max; return; } 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 += MOMatrix[i][Pos] * Vector[i] / Divs[i]; // Divs == StdDev } else for (i = 0; i < AmountSymbols;, i++) Recycle += MOMatrix[i][Pos] * Vector[i]; return(Recycle); } double GetDivergence( int Pos, int Len, double& Vector[], bool Correlation ) { int i, j; double Sum, Div = 0; if (Correlation) for (i = Pos; i > Pos - Len; i--) { Sum = 0; for (j = 0; j < AmountSymbols;, j++) if (Divs[j] != 0) Sum += MOMatrix[j][i] * Vector[j] / Divs[j]; // Divs == StdDev Div += Sum * Sum; } else for (i = Pos; i > Pos - Len; i--) { Sum = 0; for (j = 0; j < AmountSymbols;, j++) Sum += MOMatrix[j][i] * Vector[j]; Div += Sum * Sum; } Div /= Len; return(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 = 0, CurrentTime; double Div, Recycle, V[]; if (!Init()) return; ArrayResize(V, AmountSymbols); handle = FileOpen(UName + ".dat", FILE_BIN|FILE_WRITE); Start = GetTickCount(); while (CurrPos < MatrixRows) { if (!GlobalVariableCheck(UName)) break; GetNextCvarMatrix(CurrPos, Depth); // GetCvarMatrix(CurrPos, Depth); GetOptimalVector(V, Iterations, Correlation); Recycle = GetRecycle(CurrPos, Depth, V, Correlation); Div = GetDivergence(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; }