Map Indicator Values to Chart Axis

 

Hello. I'd love some pointers on what I might be doing wrong with this value mapping function. I want my indicator line to always scale to the chart's Y axis (as if it had its own axis). I'm sure this is a common problem and I've looked around quite a bit to find a workable solution but I'm still struggling.


#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red 

//---- the declaration of the dynamic array
double ExtLineBuffer[]; 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+  
void OnInit()
  {
   SetIndexBuffer(0,ExtLineBuffer,INDICATOR_DATA);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(
                const int rates_total,    
                const int prev_calculated,
                const int begin,          
                const double &price[]     
                )
  {
    int first = prev_calculated == 0 ? begin : prev_calculated - 1;
    int bar;
    for(bar = first; bar < rates_total; bar++)
    {
         int rev = rates_total-bar;
         ExtLineBuffer[bar] = (iClose("EURUSD",PERIOD_CURRENT,rev)/1.07+iClose("CADJPY",PERIOD_CURRENT,rev)/95)/2;
    }
    
    double maxPrice = ChartGetDouble(0,CHART_PRICE_MAX,0);
    double minPrice = ChartGetDouble(0,CHART_PRICE_MIN,0);
    //Print("maxPrice ",DoubleToString(maxPrice));
    //Print("minPrice ",DoubleToString(minPrice));
    
    int visibleBars = ChartVisibleBars();
    if (ArraySize(ExtLineBuffer) > 10) MapBufferToChart(maxPrice, minPrice, visibleBars);
//----+     
   return(rates_total);
  }
//+----------------------------
//+------------------------------------------------------------------+
//| Function to normalize the indicator values                      |
//+------------------------------------------------------------------+
void MapBufferToChart(double chartMaxPrice, double chartMinPrice, int bars)
{
   // Find the minimum and maximum values in the indicatorBuffer (of visible chart range)
   int minBufferIdx = ArrayMinimum(ExtLineBuffer, ArraySize(ExtLineBuffer)-bars, bars);
   int maxBufferIdx = ArrayMaximum(ExtLineBuffer, ArraySize(ExtLineBuffer)-bars, bars);
   double minBufferValue = ExtLineBuffer[minBufferIdx];
   double maxBufferValue = ExtLineBuffer[maxBufferIdx];
   //Print("ArraySize(ExtLineBuffer) ", IntegerToString(ArraySize(ExtLineBuffer)));
   //Print("ArraySize(ExtLineBuffer)-bars ", IntegerToString(ArraySize(ExtLineBuffer)-bars));
   //Print("Chartbars ", DoubleToString(bars));

   // Normalize the values to fit within the current visible y-axis range
   for (int i = 0; i < bars; i++)
   {
      if (minBufferValue != maxBufferValue)
         ExtLineBuffer[i] = MapValue(ExtLineBuffer[i], minBufferValue, maxBufferValue, chartMinPrice, chartMaxPrice);
   }
}

//+------------------------------------------------------------------+
//| Function to normalize a value within a specified range          |
//+------------------------------------------------------------------+
double MapValue(double value, double minInput, double maxInput, double minOutput, double maxOutput)
{
   return (value - minInput) / (maxInput - minInput) * (maxOutput - minOutput) + minOutput;
}

//+----------------------------------------------------------------------+
//| Gets the number of bars that are displayed (visible) in chart window |
//+----------------------------------------------------------------------+
int ChartVisibleBars(const long chart_ID=0)
  {
   long result=-1;
   ResetLastError();
   if(!ChartGetInteger(chart_ID,CHART_VISIBLE_BARS,0,result))
     {
      Print(__FUNCTION__+", Error Code = ",GetLastError());
     }
   return((int)result);
  }
 
Your topic has been moved to the section: Technical Indicators
Please consider which section is most appropriate — https://www.mql5.com/en/forum/172166/page6#comment_49114893