Скрипт подсчета
комбинаций японских свечей
Суть: см. статью
Metatrader. MQL4.
extern int His = 60000;
extern int Inp_count
= 0; // счетчик заполненных строк в массиве входных серий
extern int Out_count
= 0; // счетчик заполненных строк в массиве выходных серий
int Inp[][30];
// варианты входных серий
int Out[][129]; // варианты
выходных серий /// До 2^7!!
double Kross[][129]; //
пересечение входных и выходных серий
double KrossMoney[][129]; //
количество денег при пересечении
int Count[]; // количество
попаданий на данную входную серию
int temp[30]; // массив текущих
изменений Close-Open
int temp5[30]; // массив
последующих 5 ти значений
int PlusMinus[];
// массив в котором указывается разница между положительными и отрицательными
свечами в выходной серии. Т е индикатор, этот тип выхода с ростом, равенство,
минус
int inp_size_min = 3;
int inp_size = 3; // размер входной
серии
int out_size = 2; // размер выходной серии
int inp_max_size = 9; // максимальный размер при
автоматическом поиске паттерна
int out_max_size = 5;
int handle1; // указатель
на профайлер
int chainfile;
// указатель на файл с цепочками для советника
double porog = 0.61; // от
скольки % выводить в профайлер
int sentiment = 10; //
чувствительность при поиске входного (только!) патерна
int sens
= 0; // чувствительность, сколько отнимаем
double Money = 0; // в KrossMoney
string ValutFirst = "EURUSD"; // сюда
вставляем валюту по которая основная, оп которой смотрим входную серию
string ValutSecond = "EURUSD"; // по этой
валюте смотрим выходную серию
string VV[8]
= {"EURUSD","EURGBP","USDCAD","GBPUSD","USDCHF","AUDUSD","EURCAD","USDJPY"}; // перечень
валют - УЧЕСТЬ, что основная валюта, та которая на экране
int StatPeriod = 5;
int TimeFrame[4] = {60,
30, 15, 5, 1};
int smoo = 0; // смещение выходной цепочки
int start()
{
int
x,y;
handle1 = FileOpen("profiler.csv", FILE_CSV|FILE_WRITE,';');
chainfile
= FileOpen("chain.csv",
FILE_CSV|FILE_WRITE, '\t');
FileWrite(chainfile, sens); // сначала записываем
чувствительность
for(int qq=3;qq<6;qq++) // перебор смещения
{
smoo
= qq;
// первый цикл -
прогоняем валюты входа
for (int tt=0;tt<8;tt++)
{
// второй цикл -
прогоняем валюту выхода
ValutFirst = VV[tt];
for (int
ff=0;ff<8;ff++)
{
ValutSecond = VV[ff];
// третий цикл - прогоняем период
for (int uu=0;uu<5;uu++)
{
StatPeriod = TimeFrame[uu];
for(int zz=inp_size_min;zz<=inp_max_size;zz++) // делаем перебор по длине
входной и выходной серий
{
inp_size = zz;
sentiment = inp_size-sens;
for(int kk=2;kk<=out_max_size;kk++)
{
out_size = kk;
InitMassives();
Alert(ValutFirst,";",ValutSecond,";",StatPeriod,";",zz,"x",kk);
for(int i = iBars(ValutFirst,StatPeriod);i>inp_size+out_size;i--)
{
MakeTMP(i);
x = SearchInputMassive();
y = SearchOutputMassive();
Kross[x][y] = Kross[x][y] + 1;
KrossMoney[x][y] = KrossMoney[x][y] + Money;
Count[x]++;
}
PlotKrossInFile();
}
} // конец перебора длин входных и выходных
серий
} // конец перебора
периода
} // конец перебора
выходной вылюты
} // конец перебора входной валюты
}
FileClose(handle1);
FileClose(chainfile);
Alert("закончили");
return(0);
}
//+------------------------------------------------------------------+
void InitMassives()
{
int
i,j;
ArrayResize(Inp, MathPow(2,inp_size));
ArrayResize(Out, MathPow(2,out_size));
ArrayResize(Kross, MathPow(2,inp_size));
ArrayResize(Count,MathPow(2, inp_size));
ArrayResize(KrossMoney, MathPow(2,inp_size));
ArrayInitialize(Kross,0);
ArrayInitialize(KrossMoney,0);
ArrayInitialize(Inp,1);
ArrayInitialize(Out,1);
ArrayInitialize(Count,0);
ArrayInitialize(temp,0);
ArrayInitialize(temp5,0);
Inp_count=0; Out_count=0;
}
//+------------------------------------------------------------------+
int SearchInputMassive()
{
int
ss = 0; // если совпали ячейки, то +1
for (int i=0;i<=Inp_count;i++)
{
ss
= 0;
for(int j=0;j<inp_size;j++)
{
if (Inp[i][j] == temp[j]) {ss++;}
if (ss == sentiment) {return (i);}
}
}
Inp_count++;
// если не нашли комбинации, то добавляем
//Alert(Inp_count, " //
",temp[0],temp[1],temp[2],temp[3]);
i = Inp_count; // долго писать
for(j=0;j<inp_size;j++)
{
Inp[i][j]
= temp[j]; //перегоняем текущую комбинацию в Inp
}
return (i);
}
//+------------------------------------------------------------------+
int SearchOutputMassive()
{
int
ss = 0; // если совпали ячейки то ++
for(int i=0;i<=Out_count;i++)
{
ss
= 0;
for(int j=0;j<out_size;j++)
{
if(Out[i][j] == temp5[j]) {ss++;}
}
if(ss == out_size) {return (i);}
}
//Alert(Out_count);
Out_count++;
// если не нашли комбинации, то добавляем
i = Out_count; // долго писать
for(j=0;j<out_size;j++)
{
Out[i][j] = temp5[j]; //перегоняем текущую
комбинацию в Inp
}
return (i);
}
//+------------------------------------------------------------------+
int MakeTMP(int num)
{
ArrayInitialize(temp,0);
ArrayInitialize(temp5,0);
int
ss = 0;
double delta=0;
Money=0;
// делаем текущий
массив входов
for(int i=num;i>num-inp_size;i--)
{
delta = iClose(ValutFirst,StatPeriod,i) -
iOpen(ValutFirst,StatPeriod,i);
if (delta >
0) {temp[ss] = 1;}
else {temp[ss] = -1;}
ss++;
}
// делаем текущий
массив ответа на входной паттерн
ss = 0;
for(i=num-inp_size-smoo;i>num-inp_size-out_size-smoo;i--)
{
delta = iClose(ValutSecond,StatPeriod,i)
- iOpen(ValutSecond,StatPeriod,i);
if (delta >
0) {temp5[ss] = 1;}
else {temp5[ss] = -1;}
Money = Money + delta;
ss++;
}
//Alert(temp[0],temp[1],temp[2],temp[3],temp[4]);
//Alert(num,"*",Close[num],Open[num]);
return (0);
}
//+------------------------------------------------------------------+
void PlotKrossInFile()
{
Alert("Input_count=", Inp_count);
Alert("Output_count=", Out_count);
string legend
= OutLegend();
// выводим расшифровку, что есть что в выходной серии
int i,j,z,zet;
double cc = 0, tmp, tmp_money, tmp2;
double Out_Procent[3] = {0,0,0}; // здесь суммарно проценты серий,
которые +свечи, =свчеи,-свечи / В сумме три элемента равны 1 !!!
double Out_Sum[3]; // здесь суммарно деньги, которые на данной
позиции
string str1,str2,str3, str4, str5, str6,
str7;
string filename =
"/Stat/" + ValutFirst + "_" + ValutSecond + "_M"+ DoubleToStr(StatPeriod,0)
+"_"+DoubleToStr(inp_size,0) +
"x" + DoubleToStr(out_size,0) +
"-" +DoubleToStr(smoo,0) +".csv";
int
handle = FileOpen(filename, FILE_CSV|FILE_WRITE,
';');
// FileWrite(handle, "xxx", legend);
for(i=0;i<=Inp_count;i++)
{
str1 = ""; str2 = "";
z = 0; str6 =
"";
for(j=0;j<=Out_count;j++)
{
zet
= 0;
if(Kross[i][j] > 0) //if(Kross[i][j] != 0)
{
for
(z=0;z<inp_size;z++) {str1 = str1 + DoubleToStr(Inp[i][z],0) + ":" ;} // выводим
массив входных серий
for
(z=0;z<out_size;z++) {str6 = str6 + DoubleToStr(Out[j][z],0)+ ":";}
str7 = "";
for
(z=0;z<=Out_count;z++) // выводим массив выходных серий
{
if
(Count[i] != 0)
{
tmp = Kross[i][z]/Count[i];
tmp_money
= KrossMoney[i][z]/Count[i]; // временное
хранение данных о кл-ве денег на данной позиции
str2 = str2 + ";" + DoubleToStr(tmp,2);
}
else
{
tmp = 0; tmp_money=0;
str2 = str2 + ";" +
"0";
}
//if (tmp > porog)
{zet
= 1;} // если нашли большое количество повторений, то отмечаем
//
считаем процентно, сколько вверх серий, сколько вниз, сколько ровно
if (PlusMinus[z] == -1) // выходная серия вниз
{
Out_Procent[0] = Out_Procent[0] + tmp;
Out_Sum[0]=Out_Sum[0]+tmp_money;
}
else if
(PlusMinus[z] == 0)
// ровно
{
Out_Procent[1] = Out_Procent[1] + tmp;
Out_Sum[1]=Out_Sum[1]+tmp_money;
}
else if (PlusMinus[z] == 1) // выходная серия
вверх
{
Out_Procent[2] = Out_Procent[2] + tmp;
Out_Sum[2]=Out_Sum[2]+tmp_money;
}
str7 = str7 + PlusMinus[z];
}
if ((Out_Procent[0]>porog) || (Out_Procent[2]>porog)) {zet=1;}
//FileWrite(handle, Count[i], "%", str1, "*", str2);
//FileWrite(handle, Count[i]); //- для распределения
str4 = DoubleToStr(Out_Procent[0],2) + ";" + DoubleToStr(Out_Procent[1],2) + ";" + DoubleToStr(Out_Procent[2],2);
str5 = DoubleToStr(Out_Sum[0]*1000,2) + ";" + DoubleToStr(Out_Sum[1]*1000,2) + ";" + DoubleToStr(Out_Sum[2]*1000,2);
//FileWrite(handle,
TR(Count[i]),";",TR(str6),";",
TR(str2), ";",TR(str1), ";",TR(str4),";",TR(str5));
FileWrite(handle,
TR(Count[i]),TR(str6), TR(str2), TR(str1), TR(str4)
,TR(str5));
ArrayInitialize(Out_Procent,0);
ArrayInitialize(Out_Sum,0);// обнуляем
if(zet
== 1 && Count[i]>100)
// если превышает порог по процентам и количество таких фигур больше 10, то
выводим
{
str3 = DoubleToStr(inp_size,0) +
"x" + DoubleToStr(out_size,0);
FileWrite(handle1,
TR(Count[i]), TR(iBars(ValutFirst,StatPeriod)), TR(filename), TR(ValutFirst), TR(ValutSecond),
TR(str3), TR(str1), TR(str4), smoo);
// выводим в файл цепочки
для советника
FileWrite(chainfile, ValutFirst);
FileWrite(chainfile, ValutSecond);
FileWrite(chainfile, StatPeriod);
FileWrite(chainfile, str4);
FileWrite(chainfile,Count[i]);
FileWrite(chainfile, iBars(ValutFirst,StatPeriod));
FileWrite(chainfile, str1, " *",str6);
FileWrite(chainfile, smoo);
}
break;
}
}
}
FileClose(handle);
}
//+------------------------------------------------------------------+
string OutLegend()
{
// функция выводит, какой выход вверх, а какой вниз была
свеча
ArrayResize(PlusMinus, Out_count);
ArrayInitialize(PlusMinus, -2);
string str = "";
int
sea;
for(int i=0;i<=Out_count;i++)
{
sea = 0;
for(int j=0;j<out_size;j++)
{
if(Out[i][j] == 1) {sea++;}
else {sea--;}
}
if (sea > 0) {str
= str
+ "1: "; PlusMinus[i]=1;} // если в выходной серии
плюсов больше чем минусов, то 1
else if (sea == 0) {str
= str + "0: "; PlusMinus[i]=0;}
else {str = str + "-1: "; PlusMinus[i]=-1;}
//Alert(PlusMinus[i]);
}
//Alert("**************");
//Sleep(20);
return (str);
}
//+--------------------------------------------------------------------+
string
TR(string txt) // Trim
{
return (StringTrimLeft(StringTrimRight(txt)));
}