Indicators Used
Miscellaneous
0
Views
0
Downloads
0
Favorites
Patterns_By_Correlation_v2(weekends)
#property version "1.00"
#property strict
#property indicator_chart_window
//--- input parameters
input int Forecast_Length =300; //Forecat line length, bars
extern int DaysBackTimeBased=99999; //History to check for TimeBased mode, days
extern int DaysBackTimeFree =1000; //History to check for TimeFree mode, days
input int Max_lines=10; //Max. number of forecast lines
input ENUM_APPLIED_PRICE Price_Type=PRICE_CLOSE; //Forecast based on price
input double min_corr=0.8; //Min. correlation to be shown
input int fs=14; //Font size (buttons scale)
input bool AutoColor=true; //Automatic color for forecast lines (gradient)
input color ColorTB=clrWhite; //Fixed color of TimeBased forecast lines
input color ColorTF=clrSteelBlue; //Fixed color of TimeFree forecast lines
input color Color_FR=clrWheat; //Frozen lines color
input bool LinesInRectangle=false; //Draw the lines in rectangkes (scaled history data)
input bool ZeroWhereTheStart=false; //Start at the left side of rectangle
string obj_pref ="Patt_";
string obj_pref2="pObj_";
string obj_pref_f="frz_";
struct CORR
{
datetime time;
int shift_bar;
double shift_price;
double corr;
double scale;
};
CORR days[],bars[];
int OnInit()
{
Butt2(5,"Del. rect.",clrOrange,fs,true);
Butt2(4,"Freeze line",clrBlue ,fs,true);
Butt2(3,"Del. frozen",clrRed ,fs,true);
Butt2(2,"TimeBased" ,clrGray ,fs,true);
Butt2(1,"TimeFree" ,clrGray ,fs,true);
Butt2(0,"Del. lines",clrRed ,fs,true);
DaysBackTimeBased=MathMin(DaysBackTimeBased,20000);
DaysBackTimeFree =MathMin(DaysBackTimeFree ,20000);
ArrayResize(days,DaysBackTimeBased);
if(ArraySize(days)<10) Alert("Please set other value for TimeBased days back: ",DaysBackTimeBased);
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
Comment("");
ObjectsDeleteAll(0,obj_pref);
ObjectsDeleteAll(0,obj_pref2);
}
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
return(rates_total);
}
//+------------------------------------------------------------------+
//| ChartEvent function |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//Delete lines
if(!ObjectGetInteger(0,obj_pref+"_B2_0_",OBJPROP_STATE))
{
ObjectSetInteger(0,obj_pref+"_B2_0_",OBJPROP_STATE,true);
ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_STATE,true);
ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_BGCOLOR,clrBlack);
ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_COLOR,clrGray);
ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_STATE,true);
ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_BGCOLOR,clrBlack);
ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_COLOR,clrGray);
ObjectsDeleteAll(0,obj_pref2);
//Alert("Cleaned ",_Symbol," ",StringSubstr(EnumToString(ENUM_TIMEFRAMES(_Period)),7));
}
//Delete rectangles
if(!ObjectGetInteger(0,obj_pref+"_B2_5_",OBJPROP_STATE))
{
ObjectSetInteger(0,obj_pref+"_B2_5_",OBJPROP_STATE,true);
ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_STATE,true);
ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_BGCOLOR,clrBlack);
ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_COLOR,clrGray);
ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_STATE,true);
ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_BGCOLOR,clrBlack);
ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_COLOR,clrGray);
ObjectsDeleteAll(0,"Rect");
}
//TimeBased
if(ObjectGetInteger(0,obj_pref+"_B2_2_",OBJPROP_STATE))
{
ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_BGCOLOR,clrBlack);
ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_COLOR,clrGray);
}
else
{
if(sparam==obj_pref+"_B2_2_")
{
ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_STATE,true);
ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_BGCOLOR,clrBlack);
ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_COLOR,clrGray);
}
ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_BGCOLOR,clrWhite);
ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_COLOR,clrBlack);
if(StringFind(sparam,"Rect")==0)
{
datetime Start =(datetime)MathMin(ObjectGetInteger(0,sparam,OBJPROP_TIME1),ObjectGetInteger(0,sparam,OBJPROP_TIME2));
datetime Finish=(datetime)MathMin(Time[0],
MathMax(ObjectGetInteger(0,sparam,OBJPROP_TIME1),ObjectGetInteger(0,sparam,OBJPROP_TIME2)));
ObjectSetInteger(0,sparam,OBJPROP_BACK,false);
ObjectSetInteger(0,sparam,OBJPROP_WIDTH,4);
ObjectSetInteger(0,sparam,OBJPROP_COLOR,TimeBased(Start,Finish)?clrWhite:clrRed);
ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_STATE,true);
ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_BGCOLOR,clrBlack);
ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_COLOR,clrGray);
}
}
//TimeFree
if(ObjectGetInteger(0,obj_pref+"_B2_1_",OBJPROP_STATE))
{
ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_BGCOLOR,clrBlack);
ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_COLOR,clrGray);
}
else
{
if(sparam==obj_pref+"_B2_1_")
{
ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_STATE,true);
ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_BGCOLOR,clrBlack);
ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_COLOR,clrGray);
}
ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_BGCOLOR,clrWhite);
ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_COLOR,clrBlack);
if(StringFind(sparam,"Rect")==0)
{
datetime Start =(datetime)MathMin(ObjectGetInteger(0,sparam,OBJPROP_TIME1),ObjectGetInteger(0,sparam,OBJPROP_TIME2));
datetime Finish=(datetime)MathMin(Time[0],
MathMax(ObjectGetInteger(0,sparam,OBJPROP_TIME1),ObjectGetInteger(0,sparam,OBJPROP_TIME2)));
ObjectSetInteger(0,sparam,OBJPROP_BACK,false);
ObjectSetInteger(0,sparam,OBJPROP_WIDTH,4);
ObjectSetInteger(0,sparam,OBJPROP_COLOR,TimeFree(Start,Finish)?clrWhite:clrRed);
ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_STATE,true);
ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_BGCOLOR,clrBlack);
ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_COLOR,clrGray);
}
}
//delete frozen
if(!ObjectGetInteger(0,obj_pref+"_B2_3_",OBJPROP_STATE))
{
ObjectSetInteger(0,obj_pref+"_B2_3_",OBJPROP_STATE,true);
if(StringFind(sparam,obj_pref+"_B2_3_")==0)
ObjectsDeleteAll(0,obj_pref_f);
}
//set frozen
if(ObjectGetInteger(0,obj_pref+"_B2_4_",OBJPROP_STATE))
{
ObjectSetInteger(0,obj_pref+"_B2_4_",OBJPROP_BGCOLOR,clrBlack);
ObjectSetInteger(0,obj_pref+"_B2_4_",OBJPROP_COLOR,clrGray);
}
else
{
ObjectSetInteger(0,obj_pref+"_B2_4_",OBJPROP_BGCOLOR,clrWhite);
ObjectSetInteger(0,obj_pref+"_B2_4_",OBJPROP_COLOR,clrBlack);
ObjectSetInteger(0,obj_pref+"_B2_2_",OBJPROP_STATE,true);
ObjectSetInteger(0,obj_pref+"_B2_1_",OBJPROP_STATE,true);
if(StringFind(sparam,obj_pref2)==0)
{
string pref=StringSubstr(sparam,0,StringFind(sparam,"_",StringLen(obj_pref2)+1)+1);
for(int i=0;i<ObjectsTotal(0,0,OBJ_TREND);i++)
{
string name=ObjectName(0,i,0,OBJ_TREND);
if(StringFind(name,pref)==0)
{
ObjectSetInteger(0,name,OBJPROP_COLOR,Color_FR);
ObjectSetInteger(0,name,OBJPROP_BACK,true);
ObjectSetString (0,name,OBJPROP_NAME ,obj_pref_f+name);
}
}
}
}
}
void Text(int time, double price, string text="",color CLR=clrSalmon)
{
string name=obj_pref2+"_T1_"+IntegerToString(time)+"_"+DoubleToString(price,_Digits);
if(ObjectCreate(name,OBJ_TEXT,0,0,0))
{
ObjectSetInteger(0,name,OBJPROP_ANCHOR,ANCHOR_LEFT_LOWER);
ObjectSetInteger(0,name,OBJPROP_TIME1,time>0?Time[time]:(Time[0]-_Period*60*time));
ObjectSetDouble (0,name,OBJPROP_PRICE1,price);
ObjectSetString (0,name,OBJPROP_TEXT,text);
ObjectSetInteger(0,name,OBJPROP_FONTSIZE,10);
ObjectSetString (0,name,OBJPROP_FONT,"Arial");
ObjectSetInteger(0,name,OBJPROP_COLOR,CLR);
ObjectSetInteger(0,name,OBJPROP_BACK,false);
ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
}
}
void Butt2(int row,string text="",color CLR=0,int FS=10,bool state=true,color BG=clrBlack)
{
string name=obj_pref+"_B2_"+IntegerToString(row)+"_";
if(ObjectFind(name)<0)
{
ObjectCreate(name,OBJ_BUTTON,0,0,0);
ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_RIGHT_LOWER);
ObjectSetInteger(0,name,OBJPROP_XDISTANCE,FS*9);
ObjectSetInteger(0,name,OBJPROP_YDISTANCE,row*16*FS/10+30);
ObjectSetInteger(0,name,OBJPROP_XSIZE,FS*9);
ObjectSetInteger(0,name,OBJPROP_YSIZE,16*FS/10);
ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
ObjectSetInteger(0,name,OBJPROP_ALIGN,ALIGN_LEFT);
ObjectSetString (0,name,OBJPROP_FONT,"Arial");
ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR,clrBlack);
ObjectSetInteger(0,name,OBJPROP_BACK,false);
ObjectSetInteger(0,name,OBJPROP_FONTSIZE,FS);
ObjectSetInteger(0,name,OBJPROP_ZORDER,10);
}
ObjectSetInteger(0,name,OBJPROP_BGCOLOR,BG);
ObjectSetInteger(0,name,OBJPROP_STATE,state);
ObjectSetString (0,name,OBJPROP_TEXT,text);
ObjectSetInteger(0,name,OBJPROP_COLOR,CLR);
}
double CorrelationV(double &arr1[], double &arr2[])
{
int period=ArraySize(arr1);
if(period!=ArraySize(arr2)) {Alert("Arrays are not equal!! ",period,"!=",ArraySize(arr2));return(0);}
int i;
double D1, D2;
double S1=0;
double S2=0;
double S3=0;
double M1=0;//iMAOnArray(arr1,0,period,0,MODE_SMA,shift);
double M2=0;//iMAOnArray(arr2,0,period,0,MODE_SMA,shift);
for(i=0;i<period;i++)
{
M1+=arr1[i];
M2+=arr2[i];
}
M1/=period;
M2/=period;
for(i=0;i<period;i++)
{
D1=arr1[i]-M1;
D2=arr2[i]-M2;
S1+=D1*D2;
S2+=D1*D1;
S3+=D2*D2;
}
if(S2*S3!=0)
return(S1/(MathSqrt(S2*S3)));
return(0);
}
bool TimeBased(datetime Start,datetime Finish)
{
int FinishH=TimeHour (Finish),
FinishM=TimeMinute(Finish),
finish_bar=iBarShift(_Symbol,0,Finish),
start_bar =iBarShift(_Symbol,0,Start),
depth=0;
if(_Period>15) {Alert("Period is too high! Use TimeFree method!");return(false);}
double Curr[],
Temp[];
ArrayResize(Curr,1);
ArraySetAsSeries(Curr,true);
ArraySetAsSeries(Temp,true);
//for(int j=0;j<depth;j++)
int j=0,
curr_bar=finish_bar;
while(curr_bar<start_bar)
{
ArrayResize(Curr,j+1);
int day_of_the_week=TimeDayOfWeek(Time[curr_bar]);
if(day_of_the_week>0 && day_of_the_week<6)
Curr[j]=iMA(_Symbol,0,1,0,MODE_SMA,Price_Type,curr_bar);
else {curr_bar++;continue;}
curr_bar++;
j++;
}
depth=j;
//Alert(depth);
ArrayResize(Temp,depth);
double volatility=(Curr[ArrayMaximum(Curr)]-Curr[ArrayMinimum(Curr)]);
int day=-1, cntr=0;
for(int i=finish_bar+2;i<Bars-PERIOD_D1/_Period-depth;i++)
{
if(FinishH!=TimeHour(Time[i]) || FinishM!=TimeMinute(Time[i]) || TimeDayOfWeek(Time[i])==0 || TimeDayOfWeek(Time[i])==6) continue;
day++;
if(day>=DaysBackTimeBased) break;
j=0;
curr_bar=iBarShift(_Symbol,0,Time[i]);
while(j<depth)
{
int day_of_the_week=TimeDayOfWeek(Time[curr_bar]);
if(day_of_the_week>0 && day_of_the_week<6)
Temp[j]=iMA(_Symbol,0,1,0,MODE_SMA,Price_Type,curr_bar);
else {curr_bar++;continue;}
curr_bar++;
j++;
}
//for(j=0;j<depth;j++)
// Temp[j]=iMA(_Symbol,0,1,0,MODE_SMA,Price_Type,iBarShift(_Symbol,0,Time[i]-_Period*j*60));
days[day].corr=CorrelationV(Curr,Temp);
if(fabs(days[day].corr)<min_corr) {days[day].corr=0;continue;}
days[day].time=Time[i];
days[day].shift_bar=i;
days[day].shift_price=Curr[ZeroWhereTheStart?depth-1:0]-iMA(_Symbol,0,1,0,MODE_SMA,Price_Type,ZeroWhereTheStart?i+depth:i);
if((Temp[ArrayMaximum(Temp)]-Temp[ArrayMinimum(Temp)])==0) {continue;}//Alert(Time[i]);return(false);}
days[day].scale=volatility/(Temp[ArrayMaximum(Temp)]-Temp[ArrayMinimum(Temp)]);
cntr++;
}
if(cntr==0) {Alert("Found nothing with correlation higher then ",min_corr);return(false);}
for(int i=0;i<Max_lines;i++)
{
int best_day=0;
for(j=1;j<day;j++)
{
if(fabs(days[j].corr)>fabs(days[best_day].corr)) best_day=j;
//if(days[j].corr!=0) Print(days[j].corr);
}
//Alert(days[best_day].corr);
if(fabs(days[best_day].corr)>=min_corr)
{
DrawChartU(finish_bar,depth,days[best_day],MathMax(3-i,1),ColorTB);
days[best_day].corr=0;
}
else break;
}
return(day>0);
}
bool TimeFree(datetime Start,datetime Finish)
{
uint begin=GetTickCount();
int FinishH=TimeHour (Finish),
FinishM=TimeMinute(Finish),
finish_bar=iBarShift(_Symbol,0,Finish),
start_bar =iBarShift(_Symbol,0,Start),
depth=0;
double Curr[],
Temp[];
ArrayResize(Curr,1);
ArraySetAsSeries(Curr,true);
ArraySetAsSeries(Temp,true);
//for(int j=0;j<depth;j++)
int j=0,
curr_bar=finish_bar;
while(curr_bar<start_bar)
{
ArrayResize(Curr,j+1);
int day_of_the_week=TimeDayOfWeek(Time[curr_bar]);
if(day_of_the_week>0 && day_of_the_week<6)
Curr[j]=iMA(_Symbol,0,1,0,MODE_SMA,Price_Type,curr_bar);
else {curr_bar++;continue;}
curr_bar++;
j++;
}
depth=j;
ArrayResize(Temp,depth);
double volatility=(Curr[ArrayMaximum(Curr)]-Curr[ArrayMinimum(Curr)]);
ArrayFree(bars);
ArrayResize(bars,Bars);
int cntr=0,day=0;
for(int i=finish_bar+depth;i<Bars-depth*2 && !IsStopped();i++)
{
if(0==TimeHour(Time[i]) && 0==TimeMinute(Time[i])) day++;
if(day>=DaysBackTimeFree) break;
j=0;
curr_bar=iBarShift(_Symbol,0,Time[i]);
while(j<depth)
{
int day_of_the_week=TimeDayOfWeek(Time[curr_bar]);
if(day_of_the_week>0 && day_of_the_week<6)
Temp[j]=iMA(_Symbol,0,1,0,MODE_SMA,Price_Type,curr_bar);
else {curr_bar++;continue;}
curr_bar++;
j++;
}
bars[i].corr=CorrelationV(Curr,Temp);
if(fabs(bars[i].corr)<min_corr) continue;
bars[i].time=Time[i];
bars[i].shift_bar=i;
bars[i].shift_price=Curr[ZeroWhereTheStart?depth-1:0]-iMA(_Symbol,0,1,0,MODE_SMA,Price_Type,ZeroWhereTheStart?i+depth:i);
if((Temp[ArrayMaximum(Temp)]-Temp[ArrayMinimum(Temp)])==0) {continue;}//Alert(Time[i]);return(false);}
bars[i].scale=volatility/(Temp[ArrayMaximum(Temp)]-Temp[ArrayMinimum(Temp)]);
cntr++;
}
if(cntr<1) {Alert("Found nothing with correlation higher then ",min_corr);return(false);}
for(int i=0;i<Max_lines;i++)
{
int best_day=0;
for(j=1;j<Bars-depth*2;j++)
{
if(fabs(bars[j].corr)>fabs(bars[best_day].corr)) best_day=j;
//if(days[j].corr!=0) Print(days[j].corr);
}
if(fabs(bars[best_day].corr)>=min_corr)
{
DrawChartU(finish_bar,depth,bars[best_day],MathMax(3-i,1),ColorTF);
for(int k=best_day-depth;k<best_day+depth;k++)
bars[k].corr=0;
}
else break;
}
Print("Processing time: ",DoubleToString((GetTickCount()-begin)/1000.0,1)," sec");
return(cntr>0);
}
void DrawChartU(int Finsh_bar,int depth,CORR &data,int width,color Color)
{
int reverse=data.corr>0?1:-1;
double zero=iMA(_Symbol,0,1,0,MODE_SMA,Price_Type,ZeroWhereTheStart?Finsh_bar+depth:Finsh_bar);
double Temp[];
string pref;
if(LinesInRectangle)
{
ArrayResize(Temp,depth);
for(int j=0;j<depth;j++)
Temp[j]=iMA(_Symbol,0,1,0,MODE_SMA,Price_Type,j+data.shift_bar);
pref=IntegerToString(data.shift_bar);
for(int j=0;j<depth-1;j++)
{
DrawLineU(pref,j+Finsh_bar,zero+reverse*(Temp[j ]+data.shift_price-zero)*data.scale,
zero+reverse*(Temp[j+1]+data.shift_price-zero)*data.scale);
//+shift_price,
//);
}
}
ArrayResize(Temp,Forecast_Length);
for(int j=0;j<Forecast_Length;j++)
Temp[j]=iMA(_Symbol,0,1,0,MODE_SMA,Price_Type,data.shift_bar-j);
double min=min_corr-MathMin(min_corr*0.8,0.0),
max=MathMax(fabs(data.corr),0.9),
x = (fabs(data.corr) - min)/(max-min)*255,
y = (max - fabs(data.corr))/(max-min)*255;
pref=IntegerToString(data.shift_bar);
for(int j=0;j<Forecast_Length-1;j++)
{
DrawLineU(pref,Finsh_bar-j,zero+reverse*(Temp[j+1]+data.shift_price-zero)*data.scale,
zero+reverse*(Temp[j ]+data.shift_price-zero)*data.scale,
AutoColor?StringToColor(DoubleToString(0,0)+","+DoubleToString(0,0)+","+DoubleToString(x,0)):Color,
width);
//+shift_price,
//);
}
Text(Finsh_bar-Forecast_Length,
zero+reverse*(Temp[Forecast_Length-1]+data.shift_price-zero)*data.scale,
DoubleToString(data.corr,3)+" .... "+TimeToString(Time[data.shift_bar],TIME_DATE),
AutoColor?StringToColor(DoubleToString(0,0)+","+DoubleToString(0,0)+","+DoubleToString(x,0)):Color);
}
void DrawLineU(string pref,int i,double p,double p_prev,color CLR=clrSalmon,int Width=1)//,ENUM_LINE_STYLE style=STYLE_SOLID)
{
string Name=obj_pref2+pref+"_"+IntegerToString(i);
if(ObjectCreate(0,Name,OBJ_TREND,0,i<0?Time[0]-_Period*60*i:Time[i],p,i<0?Time[0]-_Period*60*(i+1):Time[i+1],p_prev))
{
ObjectSetInteger(0,Name,OBJPROP_WIDTH,Width);
ObjectSetInteger(0,Name,OBJPROP_STYLE,STYLE_SOLID);
ObjectSetInteger(0,Name,OBJPROP_RAY_RIGHT,false);
ObjectSetInteger(0,Name,OBJPROP_COLOR,CLR);
ObjectSetInteger(0,Name,OBJPROP_HIDDEN,true);
ObjectSetInteger(0,Name,OBJPROP_SELECTABLE,false);
ObjectSetInteger(0,Name,OBJPROP_BACK,false);
}
}
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---