959 righe
18 KiB
MQL4
959 righe
18 KiB
MQL4
|
|
#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;
|
||
|
|
}
|
||
|
|
|