//+------------------------------------------------------------------+
//|                                                  CM_Strength.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+

#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      ""//https://www.mql5.com
#property version   "1.00"
#property strict
#property indicator_chart_window
#define BullColor Lime
#define BearColor Red
#define NONE 0
#define DOWN -1
#define UP 1
extern int    Corner        = 1;
input string  Corner_Note   = "Left_Upper =0, Right_Upper =1, Left_Lower =2, Right_Lower =3";
input string  Left_Side     = "Positions =10, Strength =30, Pairs =60, Arrows_Side =100";
input string  Right         = "Positions =110, Strength =30, Pairs =73, Arrows_Side =93";
input int     Vertical_Y    =20,
Positions     =135,
Strength      =35,
Pairs         =87,
Arrows_Side   =115;

bool   UseDefaultPairs=true;// Use the default 28 pairs
string OwnPairs="",
DefaultPairs[]={"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"},
TradePairs[],
curr[8]= {"USD","EUR","GBP","JPY","AUD","NZD","CAD","CHF"},
EUR[7] = {"EURAUD","EURCAD","EURCHF","EURGBP","EURJPY","EURNZD","EURUSD"},
GBP[6] = {"GBPAUD","GBPCAD","GBPCHF","GBPJPY","GBPNZD","GBPUSD"},
GBP_R[1]={"EURGBP"},
CHF[1]={"CHFJPY"},
CHF_R[6]={"AUDCHF","CADCHF","EURCHF","GBPCHF","NZDCHF","USDCHF"},
USD[3]={"USDCAD","USDCHF","USDJPY"},
USD_R[4]={"AUDUSD","EURUSD","GBPUSD","NZDUSD"},
CAD[2]={"CADCHF","CADJPY"},
CAD_R[5]={"AUDCAD","EURCAD","GBPCAD","NZDCAD","USDCAD"},
NZD[4]={"NZDCAD","NZDCHF","NZDJPY","NZDUSD"},
NZD_R[3]={"AUDNZD","EURNZD","GBPNZD"},
AUD[5]={"AUDCAD","AUDCHF","AUDJPY","AUDNZD","AUDUSD"},
AUD_R[2] = {"EURAUD","GBPAUD"},
JPY_R[7] = {"AUDJPY","CADJPY","CHFJPY","EURJPY","GBPJPY","NZDJPY","USDJPY"},
postfix=StringSubstr(Symbol(),6,6);//postfix=StringSubstr(Symbol(),6,6);
double currstrength[8],
prevstrength[8];
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
struct pairinf
  {
   double            PairPip,Pips,PipsSig,Pipsprev,Spread,point;
   int               pipsfactor;
  }
; pairinf pairinfo[];
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
struct currency
  {
   string            curr;
   double            strength,prevstrength,crs;
   int               sync;
   datetime          lastbar;
  }
; currency currencies[8];
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
struct signal
  {
   string            symbol;
   double            range,range1,ratio,ratio1,bidratio,fact,strength,strength1,strength2,calc,strength3,strength4,strength5,strength6,strength7,strength8,strength_Gap,hi,lo,prevratio,prevbid,open,close,bid,point,Signalperc,SigRatio,SigRelStr,SigBSRatio,SigCRS,SigGap,SigGapPrev,SigRatioPrev,Signalrsi;
   int               shift;

  }
; signal signals[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {

//--- indicator buffers mapping
   string s,name;

   for(int i=ObjectsTotal()-1; i>=0; i--)
     {
      name=ObjectName(i);
      if(StringSubstr(name,0,StringLen(s))==s)
        {
         ObjectDelete(name);
        }
     }
   if(UseDefaultPairs==true)
      ArrayCopy(TradePairs,DefaultPairs);
   else
      StringSplit(OwnPairs,',',TradePairs);

   for(int i=0;i<8;i++)
      currencies[i].curr=curr[i];

   if(ArraySize(TradePairs)<=0)
     {
      Print("No pairs to trade");
      return(INIT_FAILED);
     }

   ArrayResize(pairinfo,ArraySize(TradePairs));

   for(int i=0;i<ArraySize(TradePairs);i++)
     {
      TradePairs[i]=TradePairs[i]+postfix;

      if(MarketInfo(TradePairs[i],MODE_DIGITS)==4 || MarketInfo(TradePairs[i],MODE_DIGITS)==2)
        {
         pairinfo[i].PairPip=MarketInfo(TradePairs[i],MODE_POINT);
         pairinfo[i].pipsfactor=1;
           } else {
         pairinfo[i].PairPip=MarketInfo(TradePairs[i],MODE_POINT)*10;
         pairinfo[i].pipsfactor=10;
        }
     }
   EventSetTimer(6);//EventSetTimer(2);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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 value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ObjectDelete("AUDcurr");ObjectDelete("AUDcurrdig");ObjectDelete("AUDpos");
   ObjectDelete("CADcurr");ObjectDelete("CADcurrdig");ObjectDelete("CADpos");
   ObjectDelete("CHFcurr");ObjectDelete("CHFcurrdig");ObjectDelete("CHFpos");
   ObjectDelete("EURcurr");ObjectDelete("EURcurrdig");ObjectDelete("EURpos");
   ObjectDelete("GBPcurr");ObjectDelete("GBPcurrdig");ObjectDelete("GBPpos");
   ObjectDelete("JPYcurr");ObjectDelete("JPYcurrdig");ObjectDelete("JPYpos");
   ObjectDelete("NZDcurr");ObjectDelete("NZDcurrdig");ObjectDelete("NZDpos");
   ObjectDelete("USDcurr");ObjectDelete("USDcurrdig");ObjectDelete("USDpos");
   ObjectDelete("AUDcurr");ObjectDelete("AUDcurrdig");ObjectDelete("AUDpos");
   ObjectDelete("Sdir0");ObjectDelete("Sdir1");ObjectDelete("Sdir2");
   ObjectDelete("Sdir3");ObjectDelete("Sdir4");ObjectDelete("Sdir5");
   ObjectDelete("Sdir6");ObjectDelete("Sdir7");
   return;
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   GetSignals();
   displayMeter();
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)

  {
//---
  }
//+------------------------------------------------------------------+ 
void displayMeter()
  {
   double arrt[8][3];
   int arr2,arr3;
   arrt[0][0] = currency_strength(curr[0]); arrt[1][0] = currency_strength(curr[1]); arrt[2][0] = currency_strength(curr[2]);
   arrt[3][0] = currency_strength(curr[3]); arrt[4][0] = currency_strength(curr[4]); arrt[5][0] = currency_strength(curr[5]);
   arrt[6][0] = currency_strength(curr[6]); arrt[7][0] = currency_strength(curr[7]);
   arrt[0][2] = old_currency_strength(curr[0]); arrt[1][2] = old_currency_strength(curr[1]);arrt[2][2] = old_currency_strength(curr[2]);
   arrt[3][2] = old_currency_strength(curr[3]); arrt[4][2] = old_currency_strength(curr[4]);arrt[5][2] = old_currency_strength(curr[5]);
   arrt[6][2] = old_currency_strength(curr[6]);arrt[7][2] = old_currency_strength(curr[7]);
   arrt[0][1] = 0; arrt[1][1] = 1; arrt[2][1] = 2; arrt[3][1] = 3; arrt[4][1] = 4;arrt[5][1] = 5; arrt[6][1] = 6; arrt[7][1] = 7;
   ArraySort(arrt,WHOLE_ARRAY,0,MODE_DESCEND);

   for(int m=0; m<8; m++)
     {
      arr2=(int)arrt[m][1];
      arr3=(int)arrt[m][2];
      currstrength[m] = arrt[m][0];
      prevstrength[m] = arrt[m][2];
      SetText(curr[arr2]+"pos",IntegerToString(m+1),Positions,(m*30)+Vertical_Y,color_for_profit(arrt[m][0]),12);
      SetText(curr[arr2]+"curr",curr[arr2],Pairs,(m*30)+Vertical_Y,color_for_profit(arrt[m][0]),12);
      SetText(curr[arr2]+"currdig",DoubleToStr(arrt[m][0],1),Strength,(m*30)+Vertical_Y,color_for_profit(arrt[m][0]),12);

      if(currstrength[m]>prevstrength[m]){SetObjText("Sdir"+IntegerToString(m),CharToStr(233),Arrows_Side,(m*30)+Vertical_Y,BullColor,12);}
      else if(currstrength[m]<prevstrength[m]){SetObjText("Sdir"+IntegerToString(m),CharToStr(234),Arrows_Side,(m*31)+Vertical_Y,BearColor,12);}
      else {SetObjText("Sdir"+IntegerToString(m),CharToStr(243),Arrows_Side,(m*31)+Vertical_Y,clrYellow,12);}
     }
   ChartRedraw();
   return;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
color color_for_profit(double total)
  {
   if(total<1.2)
      return (clrRed);
   if(total<2.4)
      return (clrOrangeRed);
   if(total<3.8)
      return (clrGold);
   if(total<5.0)
      return (clrOrange);
   if(total<6.2)
      return (clrForestGreen);
   if(total<7.6)
      return (clrLimeGreen);
   if(total<8.8)
      return (clrLime);
   if(total<100.0)
      return (clrAqua);
   return(0);//return(100.0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double currency_strength(string pair)
  {
   string sym;
   double range,ratio,strength=0;
   int fact,cnt1=0;

   for(int x=0; x<ArraySize(TradePairs); x++)
     {
      fact= 0;
      sym = TradePairs[x];
      if(pair==StringSubstr(sym,0,3) || pair==StringSubstr(sym,3,3))
        {
         range=(MarketInfo(sym,MODE_HIGH)-MarketInfo(sym,MODE_LOW));
         if(range!=0.0)
           {
            ratio=100.0 *((MarketInfo(sym,MODE_BID)-MarketInfo(sym,MODE_LOW))/range);
            if(ratio > 0.0  ) fact = 0;
            if(ratio > 3.0  ) fact = 1;
            if(ratio > 8.0  ) fact = 2;
            if(ratio > 11.8 ) fact = 3;
            if(ratio > 23.6 ) fact = 4;
            if(ratio > 38.2 ) fact = 5;
            if(ratio > 50.0 ) fact = 6;
            if(ratio > 61.8 ) fact = 7;
            if(ratio > 76.4 ) fact = 8;
            if(ratio > 88.2 ) fact = 9;
            cnt1++;
            if(pair==StringSubstr(sym,3,3)) fact=10-fact;
            strength+=fact;
           }
        }
     }
   if(cnt1!=0)strength/=cnt1;
   return(strength);
  }
//-----------------------------------------------------------------------------------+
double old_currency_strength(string pair)
  {
   string sym;
   double range,ratio,strength=0;
   int cnt1=0,fact;

   for(int x=0; x<ArraySize(TradePairs); x++)
     {
      fact= 0;
      sym = TradePairs[x];
      int bar=iBarShift(TradePairs[x],PERIOD_M15,TimeCurrent()-1440);
      double prevbid=iClose(TradePairs[x],PERIOD_M15,bar);

      if(pair==StringSubstr(sym,0,3) || pair==StringSubstr(sym,3,3))
        {
         // sym = sym + tempsym;
         range=(MarketInfo(sym,MODE_HIGH)-MarketInfo(sym,MODE_LOW));
         if(range!=0.0)
           {
            ratio=100.0 *((prevbid-MarketInfo(sym,MODE_LOW))/range);

            if(ratio > 0.0  ) fact = 0;
            if(ratio > 3.0  ) fact = 1;
            if(ratio > 8.0  ) fact = 2;
            if(ratio > 11.8 ) fact = 3;
            if(ratio > 23.6 ) fact = 4;
            if(ratio > 38.2 ) fact = 5;
            if(ratio > 50.0 ) fact = 6;
            if(ratio > 61.8 ) fact = 7;
            if(ratio > 76.4 ) fact = 8;
            if(ratio > 88.2 ) fact = 9;

            cnt1++;

            if(pair==StringSubstr(sym,3,3)) fact=10-fact;
            strength+=fact;
           }
        }
     }
   if(cnt1!=0)strength/=cnt1;
   return (strength);
  }
//-----------------------------------------------------------------------------------------------+ 
void GetSignals()
  {
   int cnt=0;
   ArrayResize(signals,ArraySize(TradePairs));
   for(int i=0;i<ArraySize(signals);i++)
     {
      signals[i].symbol=TradePairs[i];
      signals[i].point=MarketInfo(signals[i].symbol,MODE_POINT);
      signals[i].open=iOpen(signals[i].symbol,PERIOD_D1,0);
      signals[i].close=iClose(signals[i].symbol,PERIOD_D1,1);
      signals[i].hi=MarketInfo(signals[i].symbol,MODE_HIGH);
      signals[i].lo=MarketInfo(signals[i].symbol,MODE_LOW);
      signals[i].bid=MarketInfo(signals[i].symbol,MODE_BID);
      signals[i].range=(signals[i].hi-signals[i].lo);
      signals[i].shift= iBarShift(signals[i].symbol,PERIOD_M15,TimeCurrent()-1440);
      signals[i].prevbid=iClose(signals[i].symbol,PERIOD_M15,signals[i].shift);

      if(signals[i].range!=0)
        {
         signals[i].ratio=MathMin(((signals[i].bid-signals[i].lo)/signals[i].range*100),100);
         signals[i].prevratio=MathMin(((signals[i].prevbid-signals[i].lo)/signals[i].range*100),100);

         for(int j=0; j<9; j++)
           {
            if(signals[i].ratio > 0.0  ) signals[i].fact = 0;
            if(signals[i].ratio > 3.0  ) signals[i].fact = 1;
            if(signals[i].ratio > 8.0  ) signals[i].fact = 2;
            if(signals[i].ratio > 11.8 ) signals[i].fact = 3;
            if(signals[i].ratio > 23.6 ) signals[i].fact = 4;
            if(signals[i].ratio > 38.2 ) signals[i].fact = 5;
            if(signals[i].ratio > 50.0 ) signals[i].fact = 6;
            if(signals[i].ratio > 61.8 ) signals[i].fact = 7;
            if(signals[i].ratio > 76.4 ) signals[i].fact = 8;
            if(signals[i].ratio > 88.2 ) signals[i].fact = 9;
            cnt++;

            if(curr[j]==StringSubstr(signals[i].symbol,3,3))
               signals[i].fact=10-signals[i].fact;

            if(curr[j]==StringSubstr(signals[i].symbol,0,3))
              {
               signals[i].strength1=signals[i].fact;
              }
            else
              {
               if(curr[j]==StringSubstr(signals[i].symbol,3,0))
                  signals[i].strength2=signals[i].fact;
              }

            signals[i].calc=signals[i].strength1-signals[i].strength2;
            signals[i].strength=currency_strength(curr[j]);

            if(curr[j]==StringSubstr(signals[i].symbol,3,3))
               signals[i].fact=9-signals[i].fact;

            if(curr[j]==StringSubstr(signals[i].symbol,0,3))
              {
               signals[i].strength3=signals[i].strength;
              }
            else
              {
               if(curr[j]==StringSubstr(signals[i].symbol,3,0))
                  signals[i].strength4=signals[i].strength;
              }

            signals[i].strength5=(signals[i].strength3-signals[i].strength4);
            signals[i].strength=old_currency_strength(curr[j]);

            if(curr[j]==StringSubstr(signals[i].symbol,3,3))
               signals[i].fact=9-signals[i].fact;

            if(curr[j]==StringSubstr(signals[i].symbol,0,3))
              {
               signals[i].strength6=signals[i].strength;
              }
            else
              {
               if(curr[j]==StringSubstr(signals[i].symbol,3,0))
                  signals[i].strength7=signals[i].strength;
              }

            signals[i].strength8=(signals[i].strength6-signals[i].strength7);
            signals[i].strength_Gap=signals[i].strength5-signals[i].strength8;

            if(signals[i].ratio>signals[i].prevratio)
              {
               signals[i].SigRatioPrev=UP;
              }
            else
              {
               if(signals[i].ratio<signals[i].prevratio)
                  signals[i].SigRatioPrev=DOWN;
              }

            if(signals[i].strength5>signals[i].strength8)
              {
               signals[i].SigGapPrev=UP;
              }
            else
              {
               if(signals[i].strength5<signals[i].strength8)
                  signals[i].SigGapPrev=DOWN; return;
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+

void SetText(string name,string text,int x,int y,color colour,int fontsize=12)
  {
   if(ObjectFind(0,name)<0)
      ObjectCreate(0,name,OBJ_LABEL,0,0,0);
   ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x);
   ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y);
   ObjectSetInteger(0,name,OBJPROP_COLOR,colour);
   ObjectSetInteger(0,name,OBJPROP_FONTSIZE,fontsize);
   ObjectSetInteger(0,name,OBJPROP_CORNER,Corner);
   ObjectSetString (0,name,OBJPROP_TEXT,text); return;
  }
//+------------------------------------------------------------------+

void SetObjText(string name,string CharToStr,int x,int y,color colour,int fontsize=12)
  {
   if(ObjectFind(0,name)<0)
      ObjectCreate(0,name,OBJ_LABEL,0,0,0);
   ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x);
   ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y);
   ObjectSetInteger(0,name,OBJPROP_COLOR,colour);
   ObjectSetInteger(0,name,OBJPROP_FONTSIZE,fontsize);
   ObjectSetInteger(0,name,OBJPROP_CORNER,Corner);
   ObjectSetString(0,name,OBJPROP_TEXT,CharToStr);
   ObjectSetString (0,name,OBJPROP_FONT,"Wingdings"); return;
  }
//+------------------------------------------------------------------+
