I_CloseDifference_v-08

Author: Luca Spinello
I_CloseDifference_v-08
Price Data Components
Series array that contains close prices for each barSeries array that contains open prices of each bar
Miscellaneous
Implements a curve of type %1
0 Views
0 Downloads
0 Favorites
I_CloseDifference_v-08
//+------------------------------------------------------------------+
//|                                       I_CloseDifference_v-08.mq4 |
//|                                                    Luca Spinello |
//|                                https://mql4tradingautomation.com |
//+------------------------------------------------------------------+
#property copyright "Luca Spinello"
#property link      "https://mql4tradingautomation.com"
#property version   "0.8"
#property strict
#property description "This indicator analyses the price difference" 
#property description "comparing different values across multiple pairs"


#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1  clrBlue
#property indicator_color2  clrRed
#property indicator_color3  clrDeepSkyBlue
#property indicator_color4  clrMagenta
#property indicator_width1  2
#property indicator_width2  2
#property indicator_width3  2
#property indicator_width4  2
//--- indicator parameters

enum Enum_CalculationMode{
   Mode_CurrentOpen=0,                 //CURR CLOSE vs CURR OPEN
   Mode_PreviousClose=1,               //CURR CLOSE vs PREVIOUS CLOSE
};

string CalculationModeDesc[]={
   "CURR CLOSE vs CURR OPEN",
   "CURR CLOSE vs PREVIOUS CLOSE",
};

input string comment_0="==========";               //Comparator Indicator
input string IndicatorName="CloseDifference";      //Indicator's Name

input string comment_1="==========";   //Currencies to Analyse
input bool UseEUR=true;                //EUR
input bool UseUSD=true;                //USD
input bool UseGBP=true;                //GBP
input bool UseJPY=true;                //JPY
input bool UseCAD=true;                //CAD
input bool UseAUD=true;                //AUD
input bool UseNZD=true;                //NZD
input bool UseCHF=true;                //CHF

input string comment_2="==========";   //Value to compare
input Enum_CalculationMode CalculationMode=Mode_CurrentOpen;        //Compare Method

input string comment_3="==========";   //Threshold for Strength
input int PairsToCount=7;              //Pairs in favor/against to be considered Strong/Weak

input string comment_4="==========";   //Show All Values
input bool ShowPartial=false;          //Show Detailed Pairs

input string comment_1b="==========";  //Positive and Negative Colors
input color PositiveColor=clrGreen;    //Positive Color
input color NegativeColor=clrRed;      //Negative Color

string Font="Lucida Console";

//List all the pairs
string AllPairs[]= 
{
   "AUDCAD",
   "AUDCHF",
   "AUDJPY",
   "AUDNZD",
   "AUDUSD",
   "CADCHF",
   "CADJPY",
   "CHFJPY",
   "EURAUD",
   "EURCAD",
   "EURCHF",
   "EURGBP",
   "EURJPY",
   "EURNZD",
   "EURUSD",
   "GBPAUD",
   "GBPCAD",
   "GBPCHF",
   "GBPJPY",
   "GBPNZD",
   "GBPUSD",
   "NZDCAD",
   "NZDCHF",
   "NZDJPY",
   "NZDUSD",
   "USDCAD",
   "USDCHF",
   "USDJPY"
};      


//List all the currencies
string AllCurrencies[]=
{
   "EUR",
   "USD",
   "GBP",
   "JPY",
   "AUD",
   "NZD",
   "CAD",
   "CHF"
};


//Define working variables
string CurrBase_Pairs[7];
string CurrQuote_Pairs[7];
double CurrBase_Diff[7];
double CurrQuote_Diff[7];
string CurrBase="";
string CurrQuote="";
double CurrBase_Strength[1];           //1-Strong, 0-Neutral, -1-Weak
double CurrQuote_Strength[1];          //1-Strong, 0-Neutral, -1-Weak


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(void)
  {
   IndicatorDigits(4);
//--- 
   IndicatorShortName(IndicatorName);
   SetIndexStyle(0,DRAW_NONE);
   SetIndexBuffer(0,CurrBase_Strength);      //1-Strong, 0-Neutral, -1-Weak
   SetIndexLabel(0,"BaseStrength");
   SetIndexStyle(1,DRAW_NONE);
   SetIndexBuffer(1,CurrQuote_Strength);     //1-Strong, 0-Neutral, -1-Weak
   SetIndexLabel(1,"QuoteStrength");
   //Clean the chart from existing objects
   CleanChart();


//--- check for input parameters
//--- initialization done
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence                           |
//+------------------------------------------------------------------+

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[])
{
   PopulatePairs();
   DetectCurrencies();
   PopulateDiffValues();
   CleanChart();
   UpdateLabels();

   return(0);
}
//+------------------------------------------------------------------+


//Remove existing labels
void CleanChart(){
   int Window=0;
   for(int i=0;i<ObjectsTotal(ChartID(),Window,-1);i++){
      if(StringFind(ObjectName(ChartID(),i,Window,OBJ_LABEL),IndicatorName,0)!=-1) ObjectDelete(ChartID(),ObjectName(ChartID(),i,Window,OBJ_LABEL));
   }
}


//Create and update the labels
void UpdateLabels(){
   int LabelsBase=0;
   int LabelsQuote=0;
   int Window=0;
   if(ShowPartial){
      for(int i=0;i<7;i++){
         if(CurrBase_Pairs[i]!=NULL){
            CreateLabel("BASE",CurrBase_Pairs[i],CurrBase_Diff[i],Window,LabelsBase);
            LabelsBase++;
         }
         else{
            DeleteLabel("BASE",CurrBase_Pairs[i]);
         }
         if(CurrQuote_Pairs[i]!=NULL){
            CreateLabel("QUOTE",CurrQuote_Pairs[i],CurrQuote_Diff[i],Window,LabelsQuote);
            LabelsQuote++;
         }
         else{
            DeleteLabel("QUOTE",CurrQuote_Pairs[i]);
         }
      }
   }
   string CalcModeLabel=StringConcatenate(IndicatorName,"CalculationMode");
   if(ObjectFind(ChartID(),CalcModeLabel)>=0) ObjectDelete(ChartID(),CalcModeLabel);
   ObjectCreate(ChartID(),CalcModeLabel,OBJ_LABEL,Window,0,0);
   ObjectSet(CalcModeLabel,OBJPROP_XDISTANCE,5);
   ObjectSet(CalcModeLabel,OBJPROP_YDISTANCE,20);
   ObjectSetText(CalcModeLabel,"Period : "+Period()+" - Compare : "+CalculationModeDesc[CalculationMode],8,Font,clrDimGray);
   string BaseCurrLabel=StringConcatenate(IndicatorName,"BaseLabel");
   string BaseTitle=CurrBase;
   color BaseTitleColor=clrDimGray;
   string StrTmp;
   if(MathRound(CurrBase_Strength[0])==1){
      StrTmp=" is Strong";
      BaseTitleColor=PositiveColor;
   }
   if(MathRound(CurrBase_Strength[0])==0){
      StrTmp=" is Neutral";
      BaseTitleColor=clrDimGray;
   }
   if(MathRound(CurrBase_Strength[0])==-1){
      StrTmp=" is Weak";
      BaseTitleColor=NegativeColor;
   }
   BaseTitle=StringConcatenate(BaseTitle,StrTmp);
   ObjectCreate(ChartID(),BaseCurrLabel,OBJ_LABEL,Window,0,0);
   ObjectSet(BaseCurrLabel,OBJPROP_XDISTANCE,5);
   ObjectSet(BaseCurrLabel,OBJPROP_YDISTANCE,40);
   ObjectSetText(BaseCurrLabel,BaseTitle,8,Font,BaseTitleColor);
   string QuoteCurrLabel=StringConcatenate(IndicatorName,"QuoteLabel");
   string QuoteTitle=CurrQuote;
   color QuoteTitleColor=clrDimGray;
   if(MathRound(CurrQuote_Strength[0])==1){
      StrTmp=" is Strong";
      QuoteTitleColor=PositiveColor;
   }
   if(MathRound(CurrQuote_Strength[0])==0){
      StrTmp=" is Neutral";
      QuoteTitleColor=clrDimGray;
   }
   if(MathRound(CurrQuote_Strength[0])==-1){
      StrTmp=" is Weak";
      QuoteTitleColor=NegativeColor;
   }   
   QuoteTitle=StringConcatenate(QuoteTitle,StrTmp);
   ObjectCreate(ChartID(),QuoteCurrLabel,OBJ_LABEL,Window,0,0);
   ObjectSet(QuoteCurrLabel,OBJPROP_XDISTANCE,120);
   ObjectSet(QuoteCurrLabel,OBJPROP_YDISTANCE,40);
   ObjectSetText(QuoteCurrLabel,QuoteTitle,8,Font,QuoteTitleColor);
}


//Create individual label
void CreateLabel(string Type, string Pair, double Value, int Window, int L){
   string LabelName=StringConcatenate(IndicatorName,"Label",Type,Pair);
   int Xoff;
   int Yoff=L*15;
   if(Type=="BASE") Xoff=5;
   if(Type=="QUOTE") Xoff=120;
   string LabelString=StringConcatenate(Pair," ",Value>=0 ? "+":"",DoubleToStr(Value,4));
   color Color;
   if(Value>=0) Color=PositiveColor;
   else Color=NegativeColor;
   ObjectCreate(ChartID(),LabelName,OBJ_LABEL,Window,0,0);
   ObjectSet(LabelName,OBJPROP_XDISTANCE,Xoff);
   ObjectSet(LabelName,OBJPROP_YDISTANCE,Yoff+60);
   ObjectSetText(LabelName,LabelString,8,Font,Color);
}


void DeleteLabel(string Type, string Pair){
   int Window=0;
   ObjectsDeleteAll(ChartID(),IndicatorName,Window);
}


//Calculate the pairs to analyze
void PopulatePairs(){
   int j=0;
   int k=0;
   for(int i=0;i<ArraySize(AllPairs);i++){
      if(StringFind(AllPairs[i],CurrBase,0)!=-1){
         if(UseEUR && StringFind(AllPairs[i],"EUR",0)!=-1 && CurrBase!="EUR") CurrBase_Pairs[j]=AllPairs[i];
         if(UseAUD && StringFind(AllPairs[i],"AUD",0)!=-1 && CurrBase!="AUD") CurrBase_Pairs[j]=AllPairs[i];
         if(UseGBP && StringFind(AllPairs[i],"GBP",0)!=-1 && CurrBase!="GBP") CurrBase_Pairs[j]=AllPairs[i];
         if(UseUSD && StringFind(AllPairs[i],"USD",0)!=-1 && CurrBase!="USD") CurrBase_Pairs[j]=AllPairs[i];
         if(UseNZD && StringFind(AllPairs[i],"NZD",0)!=-1 && CurrBase!="NZD") CurrBase_Pairs[j]=AllPairs[i];
         if(UseCAD && StringFind(AllPairs[i],"CAD",0)!=-1 && CurrBase!="CAD") CurrBase_Pairs[j]=AllPairs[i];
         if(UseCHF && StringFind(AllPairs[i],"CHF",0)!=-1 && CurrBase!="CHF") CurrBase_Pairs[j]=AllPairs[i];
         if(UseJPY && StringFind(AllPairs[i],"JPY",0)!=-1 && CurrBase!="JPY") CurrBase_Pairs[j]=AllPairs[i];
         j++;
      }
      //Print(UseCAD);
      if(StringFind(AllPairs[i],CurrQuote,0)!=-1){
         if(UseEUR && StringFind(AllPairs[i],"EUR",0)!=-1 && CurrQuote!="EUR") CurrQuote_Pairs[k]=AllPairs[i];
         if(UseAUD && StringFind(AllPairs[i],"AUD",0)!=-1 && CurrQuote!="AUD") CurrQuote_Pairs[k]=AllPairs[i];
         if(UseGBP && StringFind(AllPairs[i],"GBP",0)!=-1 && CurrQuote!="GBP") CurrQuote_Pairs[k]=AllPairs[i];
         if(UseUSD && StringFind(AllPairs[i],"USD",0)!=-1 && CurrQuote!="USD") CurrQuote_Pairs[k]=AllPairs[i];
         if(UseNZD && StringFind(AllPairs[i],"NZD",0)!=-1 && CurrQuote!="NZD") CurrQuote_Pairs[k]=AllPairs[i];
         if(UseCAD && StringFind(AllPairs[i],"CAD",0)!=-1 && CurrQuote!="CAD") CurrQuote_Pairs[k]=AllPairs[i];
         if(UseCHF && StringFind(AllPairs[i],"CHF",0)!=-1 && CurrQuote!="CHF") CurrQuote_Pairs[k]=AllPairs[i];
         if(UseJPY && StringFind(AllPairs[i],"JPY",0)!=-1 && CurrQuote!="JPY") CurrQuote_Pairs[k]=AllPairs[i];
         k++;
      }
   }
}


//Detect current currencies in the chart
void DetectCurrencies(){
   string Curr1="";
   string Curr2="";
   int Curr1Pos,Curr2Pos;
   for(int i=0;i<ArraySize(AllCurrencies);i++){
      int Curr1PosTmp=StringFind(Symbol(),AllCurrencies[i],0);
      int Curr2PosTmp=StringFind(Symbol(),AllCurrencies[i],0);
      if(Curr1=="" && Curr1PosTmp!=-1){
         Curr1=AllCurrencies[i];
         Curr1Pos=Curr1PosTmp;
      }
      if(Curr1!="" && Curr2PosTmp!=-1){
         Curr2=AllCurrencies[i];
         Curr2Pos=Curr2PosTmp;
      }
   }
   if(Curr1Pos<Curr2Pos){
      CurrBase=Curr1;
      CurrQuote=Curr2;
   }
   else{
      CurrBase=Curr2;
      CurrQuote=Curr1;
   }
}


//Populate the current values
void PopulateDiffValues(){
   int BaseStrong=0;
   int QuoteStrong=0;
   int BaseWeak=0;
   int QuoteWeak=0;
   for(int i=0;i<7;i++){
      if(CurrBase_Pairs[i]!=NULL){
         CurrBase_Diff[i]=CalculateDiff(CurrBase_Pairs[i]);
         if((StringFind(CurrBase_Pairs[i],CurrBase,0)==0 && CurrBase_Diff[i]>=0) || (StringFind(CurrBase_Pairs[i],CurrBase,0)>0 && CurrBase_Diff[i]<0)) BaseStrong++;
         if((StringFind(CurrBase_Pairs[i],CurrBase,0)==0 && CurrBase_Diff[i]<0) || (StringFind(CurrBase_Pairs[i],CurrBase,0)>0 && CurrBase_Diff[i]>=0)) BaseWeak++;
      }
      if(CurrQuote_Pairs[i]!=NULL){
         CurrQuote_Diff[i]=CalculateDiff(CurrQuote_Pairs[i]);
         if((StringFind(CurrQuote_Pairs[i],CurrQuote,0)==0 && CurrQuote_Diff[i]>=0) || (StringFind(CurrQuote_Pairs[i],CurrQuote,0)>0 && CurrQuote_Diff[i]<0)) QuoteStrong++;
         if((StringFind(CurrQuote_Pairs[i],CurrQuote,0)==0 && CurrQuote_Diff[i]<0) || (StringFind(CurrQuote_Pairs[i],CurrQuote,0)>0 && CurrQuote_Diff[i]>=0)) QuoteWeak++;
      }
   }
   if(BaseStrong>=PairsToCount) CurrBase_Strength[0]=1;
   else if(BaseWeak>=PairsToCount) CurrBase_Strength[0]=-1;
   else CurrBase_Strength[0]=0;
   if(QuoteStrong>=PairsToCount) CurrQuote_Strength[0]=1;
   else if(QuoteWeak>=PairsToCount) CurrQuote_Strength[0]=-1;
   else CurrQuote_Strength[0]=0;
}


//Calculate individual value
double CalculateDiff(string Pair){
   double Evalue=iClose(Pair,0,0);
   double Svalue=0;
   switch(CalculationMode){
      case 0:
         Svalue=iOpen(Pair,0,0);
         break;
      case 1:
         Svalue=iClose(Pair,0,1);
         break;
   }
   double Diff=NormalizeDouble((Evalue*1000/Svalue)-1000,4);
   return Diff;
}

Comments