//+------------------------------------------------------------------+
//|                              Support and Resistance Heat Map.mq4 |
//|                                  Copyright c 2009, Ronald Raygun |
//|   Modifactions by Spinnaker 2-15-09                              |
//+------------------------------------------------------------------+
#property copyright "Copyright c 2009, Ronald Raygun"
#property link      ""

#property indicator_chart_window
//---- input parameters

extern double    Threshold = 0.75;
extern double    MaxPriceUsed = 0.0;
extern double    MinPriceUsed = 0.0;
extern int       MaxBars = 0;
extern int       BarsShift = 0;
extern int       Step = 1; // value to control roughness (to reduce hline-step)

double Ratio = 0.0;

int DQ_ADJUST []  = { 0 , 0 , 1 , 10 , 1 , 10 , 100 };
int DQADJ;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   DQADJ = DQ_ADJUST [ Digits ]; // DQADJ is adjustment for deci-quotes (3-5 digits) brokers

   start();
   return(0);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   for (int j = ObjectsTotal(); j >= 0; j--) {
   string OriginalName = ObjectName(j);  
   if(0 == StringFind(OriginalName, StringConcatenate("S/R EA: ", Symbol(), " ", Period()))) {
      ObjectDelete(ObjectName(j));
   }
   }  
   ObjectDelete("StartingBar");
//----
   return(0);
  }
  
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{
   int counted_bars=IndicatorCounted();

   double MaxPrice;
   double MinPrice;
   int BarsUsed;

   if(MaxPriceUsed == 0) MaxPrice = WindowPriceMax();
   else MaxPrice = MaxPriceUsed;

   if(MinPriceUsed == 0) MinPrice = WindowPriceMin();
   else MinPrice = MinPriceUsed;

   if(MaxBars == 0) BarsUsed = WindowBarsPerChart() + BarsShift;
   else BarsUsed = MaxBars + BarsShift;

   ObjectDelete("StartingBar");
   ObjectCreate("StartingBar", OBJ_VLINE, 0, Time[BarsUsed], 0);
   ObjectSet("StartingBar", OBJPROP_COLOR, Aqua);
   ObjectSet("StartingBar", OBJPROP_STYLE, STYLE_DASH);
   
    
   ObjectDelete("ShiftBar");
   ObjectCreate("ShiftBar", OBJ_VLINE, 0, Time[BarsShift], 0);
   ObjectSet("ShiftBar", OBJPROP_COLOR, Aqua);
   ObjectSet("ShiftBar", OBJPROP_STYLE, STYLE_DASH);
   
   
   if(BarsShift == 0) ObjectDelete("ShiftBar");

   int CrossCount = 0;
   int MaxCrosses = 0;
   Ratio = 0.0;
   
   int Roughness = DQADJ*Step;

   double PriceStep = ( (MaxPrice - MinPrice) / Point )/Roughness;   

   Print( "PriceStep = "+PriceStep );

 // Find the highest number of crosses in the range
   for (int j=0; j<PriceStep; j++)
   {
      double Price_j = MinPrice + (j *Roughness * Point);
      for (int l=0; l<BarsUsed; l++)
      {
         if(High[l] >= Price_j && Low[l] <= Price_j ) CrossCount++;
      }
      if (CrossCount > MaxCrosses) MaxCrosses = CrossCount;
      CrossCount = 0;
   }   

// Find and draw the current colour bar
   for (int i=0; i<PriceStep; i++)
   {
      double Price_i = MinPrice + (i *Roughness * Point);
      string ObjName = StringConcatenate("S/R EA: ", Symbol(), " ", Period(), " ", D2STR(Price_i));
      ObjectCreate(ObjName, OBJ_HLINE, 0, 0, Price_i);

      for (int k=0; k<BarsUsed; k++)
      {
         if(High[k] >= Price_i && Low[k] <= Price_i ) CrossCount++;
      }

      double CC = CrossCount*Step;

      Ratio = CC / MaxCrosses;
      if (Ratio > Threshold) Ratio = 1;
      Print("Ratio: ", DoubleToStr(Ratio,2));
      Print("CrossCount: ", CrossCount);
      Print("BarsUsed: ", BarsUsed);

      double d_RedValue = 255 * Ratio;
      int RedValue = d_RedValue;
      if(Ratio > 1) RedValue = 255;
  
      int GreenValue = 255 - RedValue;
      
      color LineColor = (RedValue + GreenValue * 256);

      ObjectSet(ObjName, OBJPROP_COLOR, LineColor);
      ObjectSet(ObjName, OBJPROP_STYLE, STYLE_SOLID);
      ObjectSet(ObjName, OBJPROP_BACK, true);
      Ratio = 0;     
      CrossCount = 0;
   }
   
   return(0);
}

//+------------------------------------------------------------------+
//| D2STR
//+------------------------------------------------------------------+
string D2STR(double Price)
{
   return( DoubleToStr(Price,Digits) );
}