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