#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; }