//+------------------------------------------------------------------+
//|                                      mn Curr Strength Meter.mq4 |
//+------------------------------------------------------------------+
#property copyright "Mn"
#property link      ""
#property  indicator_separate_window
#property indicator_buffers 8

#define mPowerLevels  20                    

extern int mCorner = 2, mPrd = 2, mTimeFrame = 5, mShift = 0;
extern int mRocShift = 20, mHist = 100, mWindow = 1;
extern bool mAlert = false;
extern color mTxtCol;
string aPair[]   = {"EURUSD","EURJPY","EURGBP","EURCHF","EURAUD","EURCAD",
                    "GBPUSD","GBPJPY","GBPCAD","GBPCHF","GBPAUD",
                    "AUDUSD","AUDJPY","AUDCAD","CHFJPY",
                    "USDJPY","USDCHF","USDCAD", };
                       
string Currency[] = {"USD","EUR","GBP","JPY","CHF","CAD","AUD"};
int    MeterXPos[] = {107, 90, 73, 56, 39, 22, 5};               
int    mTable[10]  = {0,5,10,25,40,50,60,75,90,95};  
int mPrCnt, mMeterCurrs;
double mMeter[], mHigh[], mLow[], mClose[], mRatio[], mRange[], mTabPos[], mTabPos2[];
double mRocMeter[], mC0[], mC1[], mC2[], mC3[], mC4[], mC5[], mC6[], mC7[];

//+------------------------------------------------------------------+
int init()
  {
   int x, yPos;
   mPrCnt = ArrayRange(aPair, 0);
   mMeterCurrs = ArrayRange(Currency, 0);

   SetIndexBuffer(0, mC0); SetIndexStyle(0, 12, EMPTY, EMPTY, CLR_NONE);
   SetIndexBuffer(1, mC1); SetIndexStyle(1, 12, EMPTY, EMPTY, CLR_NONE);
   SetIndexBuffer(2, mC2); SetIndexStyle(2, 12, EMPTY, EMPTY, CLR_NONE);
   SetIndexBuffer(3, mC3); SetIndexStyle(3, 12, EMPTY, EMPTY, CLR_NONE);
   SetIndexBuffer(4, mC4); SetIndexStyle(4, 12, EMPTY, EMPTY, CLR_NONE);
   SetIndexBuffer(5, mC5); SetIndexStyle(5, 12, EMPTY, EMPTY, CLR_NONE);
   SetIndexBuffer(6, mC6); SetIndexStyle(6, 12, EMPTY, EMPTY, CLR_NONE);
   SetIndexBuffer(7, mC7); SetIndexStyle(7, 12, EMPTY, EMPTY, CLR_NONE);

   ArrayResize(mMeter, mMeterCurrs);    // No currency columns
   ArrayResize(mRocMeter, mMeterCurrs);
   ArrayResize(mHigh, mPrCnt);
   ArrayResize(mLow, mPrCnt);
   ArrayResize(mClose, mPrCnt);
   ArrayResize(mRatio, mPrCnt);
   ArrayResize(mRange, mPrCnt);
   ArrayResize(mTabPos, mPrCnt);
   ArrayResize(mTabPos2, mPrCnt);

   SetIndexLabel(0, NULL);
   SetIndexLabel(1, NULL);
   SetIndexLabel(2, NULL);
   SetIndexLabel(3, NULL);
   SetIndexLabel(4, NULL);
   SetIndexLabel(5, NULL);
   SetIndexLabel(6, NULL);
   SetIndexLabel(7, NULL);
   ObjectsDeleteAll(0,OBJ_LABEL);

   for (x = 0; x < mMeterCurrs; x++)
    { 
      for(yPos = 1; yPos <= mPowerLevels; yPos++)
        {
          mCreate(Currency[x]+yPos, MeterXPos[x], 91 - yPos * 4);
          mCreate(Currency[x]+"roc"+yPos, 140 + MeterXPos[x], 91 - yPos * 4);
        }
        
        mCreate(Currency[x], MeterXPos[x]+2, 20, Currency[x], 7, "Arial Narrow", mTxtCol);   // Curr name
        mCreate(Currency[x]+"roc", 140 + MeterXPos[x]+2, 20, Currency[x], 7, "Arial Narrow", mTxtCol);   // Curr name
   }
   mCreate("Name1", 15, 2, "CURR STRENGTH", 10, "Times", mTxtCol); 
   mCreate("Name2", 175, 2, "ROC", 10, "Times", mTxtCol); 
   mCreate("line",  3, 25,"-------------------------------", 10, "Times", mTxtCol);
   mCreate("line2", 139, 25,"-------------------------------", 10, "Times", mTxtCol);  
   return(0);                                                               
  }
//+------------------------------------------------------------------+
int deinit()
  {
   ObjectsDeleteAll(0, OBJ_LABEL);
   return(0);                                  
  }
//+------------------------------------------------------------------+
int start()
  {
   double point, cmeter;
   int    i, mPrInd, z;
   string mySymbol;
   for(z = mHist; z >=0; z--)                   // Build ROC history
    {
     for(i = 0; i < mPrCnt; i++)               // values every pair into arrays
      {
        mySymbol         = aPair[i];                        
        if (StringSubstr(mySymbol,3,3) == "JPY") point = 0.001;
        else point = 0.00001;
        mHigh[i]     = iMA(mySymbol, mTimeFrame, mPrd, 0, 0, PRICE_HIGH, z);  
        mLow[i]      = iMA(mySymbol, mTimeFrame, mPrd, 0, 0, PRICE_LOW, z);    
        mClose[i]    = iMA(mySymbol, mTimeFrame, mPrd, 0, 0, PRICE_CLOSE, z);        
        mRange[i]    = MathMax((mHigh[i] - mLow[i]) / point, 1);       
        mRatio[i]    = (mClose[i] - mLow[i]) / mRange[i] / point;    
        mTabPos[i]   = mRate(mRatio[i] * 100);                        // 0-10 from Table[]
        mTabPos2[i]  = 10 - mTabPos[i];                                 
      } 
   
     CalcStrengthMeter();         
     ClearMeter(1);      // repaint the meter 
     for (mPrInd = 0; mPrInd < mMeterCurrs; mPrInd++)
      {
       mPaintMeter(mPrInd, mMeter[mPrInd]); 
       switch(mPrInd)
        {
         case 0:   {mC0[z] = mMeter[mPrInd]; break; }
         case 1:   {mC1[z] = mMeter[mPrInd]; break; }
         case 2:   {mC2[z] = mMeter[mPrInd]; break; }
         case 3:   {mC3[z] = mMeter[mPrInd]; break; }
         case 4:   {mC4[z] = mMeter[mPrInd]; break; }
         case 5:   {mC5[z] = mMeter[mPrInd]; break; }
         case 6:   {mC6[z] = mMeter[mPrInd]; break; }
         case 7:   {mC7[z] = mMeter[mPrInd]; break; }
         default: break;
        } 
      }  // for i
   } // for z 

   CalcRoc();
   ClearMeter(2);

   for (int m = 0; m < mMeterCurrs; m++)
     mPaintRocMeter(m, mRocMeter[m]); 
   return(0);
  }

//+------------------------------------------------------------------+
void CalcStrengthMeter()
 {
   int    i, mPrInd, cnt;
   double cmeter;
   for (mPrInd = 0; mPrInd < mMeterCurrs; mPrInd ++)           // For each meter currency
   { 
     cnt = 0;   cmeter = 0;
     for (i = 0; i < mPrCnt; i++)                              // For every monitored pair 
     {
       if (StringSubstr(aPair[i],0,3) == Currency[mPrInd])   
       {
        cnt++;
        cmeter = cmeter + mTabPos[i];
       }
       if (StringSubstr(aPair[i],3,3) == Currency[mPrInd])
       {
        cnt++;
        cmeter = cmeter + mTabPos2[i];
       }
       if (cnt > 0)
         mMeter[mPrInd] = NormalizeDouble(cmeter / cnt,1); 
       else 
         mMeter[mPrInd] = -1;
     }   // For i
    } 

   return(0);
 }

//+------------------------------------------------------------------+
int mRate(double ratio)               
  {                               
   int i, j = -1;
   
   if(ratio <= mTable[0])
     j = 0;
   else {
     for(i = 1; i < mPowerLevels; i++) 
       if(ratio < mTable[i])                    // returns 0-10
         {
          j = i-1; 
          break;
         }
   
   if(j == -1) j = 10;
   }
   return(j);                                                
  }
  
//+------------------------------------------------------------------+
void mCreate(string name, int x, int y, string text = "-",int size = 38,
                  string font = "Times", color colour = CLR_NONE)
  {
   ObjectCreate(name, OBJ_LABEL, mWindow, 0, 0);
   ObjectSet(name, OBJPROP_CORNER, mCorner);     
   ObjectSet(name, OBJPROP_COLOR, colour);
   ObjectSet(name, OBJPROP_XDISTANCE, x);
   ObjectSet(name, OBJPROP_YDISTANCE, y);
   ObjectSetText(name, text, size, font, colour);
  }

//+------------------------------------------------------------------+
void ClearMeter(int mMtr)
  {
   int z, y;
   
   for (z = 0; z < mMeterCurrs; z++)
   { 
     for(y = 1; y <= mPowerLevels; y++)
       if(mMtr == 1)
         ObjectSet(Currency[z]+y, OBJPROP_COLOR, CLR_NONE);
       else
         ObjectSet(Currency[z]+"roc"+y, OBJPROP_COLOR, CLR_NONE);  
         
   }
  }
  
//+------------------------------------------------------------------+
void mPaintMeter(int mPrInd, double mVal)
{
  if (mVal > 0.0) ObjectSet(Currency[mPrInd]+"20", OBJPROP_COLOR, Red);
  if (mVal > 0.5) ObjectSet(Currency[mPrInd]+"19", OBJPROP_COLOR, Red);
  if (mVal > 1.0) ObjectSet(Currency[mPrInd]+"18", OBJPROP_COLOR, OrangeRed);
  if (mVal > 1.5) ObjectSet(Currency[mPrInd]+"17", OBJPROP_COLOR, OrangeRed);
  if (mVal > 2.0) ObjectSet(Currency[mPrInd]+"16", OBJPROP_COLOR, DarkOrange);
  if (mVal > 2.5) ObjectSet(Currency[mPrInd]+"15", OBJPROP_COLOR, DarkOrange);
  if (mVal > 3.0) ObjectSet(Currency[mPrInd]+"14", OBJPROP_COLOR, Orange);
  if (mVal > 3.5) ObjectSet(Currency[mPrInd]+"13", OBJPROP_COLOR, Orange);
  if (mVal > 4.0) ObjectSet(Currency[mPrInd]+"12", OBJPROP_COLOR, Gold);
  if (mVal > 4.5) ObjectSet(Currency[mPrInd]+"11", OBJPROP_COLOR, Gold);
  if (mVal > 5.0) ObjectSet(Currency[mPrInd]+"10", OBJPROP_COLOR, Yellow);
  if (mVal > 5.5) ObjectSet(Currency[mPrInd]+"9", OBJPROP_COLOR, Yellow);
  if (mVal > 6.0) ObjectSet(Currency[mPrInd]+"8", OBJPROP_COLOR, Green);
  if (mVal > 6.5) ObjectSet(Currency[mPrInd]+"7", OBJPROP_COLOR, Green);
  if (mVal > 7.0) ObjectSet(Currency[mPrInd]+"6", OBJPROP_COLOR, Lime);
  if (mVal > 7.5) ObjectSet(Currency[mPrInd]+"5", OBJPROP_COLOR, Lime);
  if (mVal > 8.0) ObjectSet(Currency[mPrInd]+"4", OBJPROP_COLOR, PaleGreen);
  if (mVal > 8.5) ObjectSet(Currency[mPrInd]+"3", OBJPROP_COLOR, PaleGreen);   
  if (mVal > 9.0) ObjectSet(Currency[mPrInd]+"2", OBJPROP_COLOR, White);
  if (mVal > 9.5) ObjectSet(Currency[mPrInd]+"1", OBJPROP_COLOR, White);
}

//+------------------------------------------------------------------+
void mPaintRocMeter(int mm, double mRocVal)
 {
  if (mRocVal > -5.0) ObjectSet(Currency[mm]+"roc"+"20", OBJPROP_COLOR, Red);
  if (mRocVal > -4.5) ObjectSet(Currency[mm]+"roc"+"19", OBJPROP_COLOR, Red);
  if (mRocVal > -4.0) ObjectSet(Currency[mm]+"roc"+"18", OBJPROP_COLOR, OrangeRed);
  if (mRocVal > -3.5) ObjectSet(Currency[mm]+"roc"+"17", OBJPROP_COLOR, OrangeRed);
  if (mRocVal > -3.0) ObjectSet(Currency[mm]+"roc"+"16", OBJPROP_COLOR, DarkOrange);
  if (mRocVal > -2.5) ObjectSet(Currency[mm]+"roc"+"15", OBJPROP_COLOR, DarkOrange);
  if (mRocVal > -2.0) ObjectSet(Currency[mm]+"roc"+"14", OBJPROP_COLOR, Orange);
  if (mRocVal > -1.5) ObjectSet(Currency[mm]+"roc"+"13", OBJPROP_COLOR, Orange);
  if (mRocVal > -1.0) ObjectSet(Currency[mm]+"roc"+"12", OBJPROP_COLOR, Gold);
  if (mRocVal > -0.5) ObjectSet(Currency[mm]+"roc"+"11", OBJPROP_COLOR, Gold);
  if (mRocVal > 0.0) ObjectSet(Currency[mm]+"roc"+"10", OBJPROP_COLOR, Yellow);
  if (mRocVal > 0.5) ObjectSet(Currency[mm]+"roc"+"9", OBJPROP_COLOR, Yellow);
  if (mRocVal > 1.0) ObjectSet(Currency[mm]+"roc"+"8", OBJPROP_COLOR, Green);
  if (mRocVal > 1.5) ObjectSet(Currency[mm]+"roc"+"7", OBJPROP_COLOR, Green);
  if (mRocVal > 2.0) ObjectSet(Currency[mm]+"roc"+"6", OBJPROP_COLOR, Lime);
  if (mRocVal > 2.5) ObjectSet(Currency[mm]+"roc"+"5", OBJPROP_COLOR, Lime);
  if (mRocVal > 3.0) ObjectSet(Currency[mm]+"roc"+"4", OBJPROP_COLOR, PaleGreen);
  if (mRocVal > 3.5) ObjectSet(Currency[mm]+"roc"+"3", OBJPROP_COLOR, PaleGreen);   
  if (mRocVal > 4.0) ObjectSet(Currency[mm]+"roc"+"2", OBJPROP_COLOR, White);
  if (mRocVal > 4.5) ObjectSet(Currency[mm]+"roc"+"1", OBJPROP_COLOR, White);
 }

//+------------------------------------------------------------------+
void CalcRoc()
  {
   int  j;
   for (j = 0; j < mMeterCurrs; j ++)           // For each meter currency
    { 
     switch(j)
      {
       case 0:   {mRocMeter[j] = mC0[0] - mC0[mRocShift]; break; }
       case 1:   {mRocMeter[j] = mC1[0] - mC1[mRocShift]; break; }
       case 2:   {mRocMeter[j] = mC2[0] - mC2[mRocShift]; break; }
       case 3:   {mRocMeter[j] = mC3[0] - mC3[mRocShift]; break; }
       case 4:   {mRocMeter[j] = mC4[0] - mC4[mRocShift]; break; }
       case 5:   {mRocMeter[j] = mC5[0] - mC5[mRocShift]; break; }
       case 6:   {mRocMeter[j] = mC6[0] - mC6[mRocShift]; break; }
       case 7:   {mRocMeter[j] = mC7[0] - mC7[mRocShift]; break; }
       default: break;
      } 
    }
   
   return(0);
 }


