Is it possible to load and reload a template programmatically ?

 
I want to adjust some indicator parameter on the fly using template because structure doesn't change just the parameter values. So is it possible to load (and reload/refresh) a template programmatically ?
 

yes winapi (& what about WindowRedraw())

 
qjol:

yes winapi (& what about WindowRedraw())


Thanks very much. Not sure to understand fully: should I just use WindowRedraw() ?

By winapi do you mean low level programming win32 (I'm really not expert at that :( )

 
This has been discussed in other threads with no real consensus. Instead, what I do is drop the indicators and have the EA draw the indicator values on the chart. Thus they always match.
//+------------------------------------------------------------------+
//| EA equivalent of indicator buffers                               |
//+------------------------------------------------------------------+
/*  Example 1:
 *  if (...) Ordermodify(...);
 *  Polyline("SL"+(oo.ticket%99), oo.SL, Color.SL, 0);
 *
 *  Example 2:
 *  double  ELineCurr = iMA(NULL,0, ELine.Period, 0, MODE_EMA, PRICE_CLOSE, 1);
 *  string pln=Polyline("ELine", ELineCurr, Color.ELine, 1);
 *      ObjectSet(pln, OBJPROP_STYLE, STYLE_DOT);
 *      ObjectSetText(pln, "ELine="+DoubleToStr(ELineCurr,Digits), 10);
 ******************************************************************************/
#define POLYLINE_MAX 20 // Must match priceXX[]
string  lineName[POLYLINE_MAX]; // Common to Polyline and PolyLineDelete.
string  Polyline(string name, double price, color clr, int shift=0){
    if (!Show.Objects)  return("");         // Return the actual object name for
    static int           LRU[POLYLINE_MAX]; // further modifications, E.G. style
    for (int idx=0; idx < POLYLINE_MAX; idx++){
        bool new = lineName[idx] != name;   if (!new) break;    }
    if (new){
        for (idx=0; idx < POLYLINE_MAX; idx++)  LRU[idx]++;
        idx=ArrayMaximum(LRU);  lineName[idx]=name; }
    LRU[idx] = 0;
    double  price00[], price01[], price02[], price03[], price04[],
            price05[], price06[], price07[], price08[], price09[],
            price10[], price11[], price12[], price13[], price14[],
            price15[], price16[], price17[], price18[], price19[];
    switch (idx){
    case  0: return(PLHelper(name, price, clr, idx, new, shift, price00));
    case  1: return(PLHelper(name, price, clr, idx, new, shift, price01));
    case  2: return(PLHelper(name, price, clr, idx, new, shift, price02));
    case  3: return(PLHelper(name, price, clr, idx, new, shift, price03));
    case  4: return(PLHelper(name, price, clr, idx, new, shift, price04));
    case  5: return(PLHelper(name, price, clr, idx, new, shift, price05));
    case  6: return(PLHelper(name, price, clr, idx, new, shift, price06));
    case  7: return(PLHelper(name, price, clr, idx, new, shift, price07));
    case  8: return(PLHelper(name, price, clr, idx, new, shift, price08));
    case  9: return(PLHelper(name, price, clr, idx, new, shift, price09));
    case 10: return(PLHelper(name, price, clr, idx, new, shift, price10));
    case 11: return(PLHelper(name, price, clr, idx, new, shift, price11));
    case 12: return(PLHelper(name, price, clr, idx, new, shift, price12));
    case 13: return(PLHelper(name, price, clr, idx, new, shift, price13));
    case 14: return(PLHelper(name, price, clr, idx, new, shift, price14));
    case 15: return(PLHelper(name, price, clr, idx, new, shift, price15));
    case 16: return(PLHelper(name, price, clr, idx, new, shift, price16));
    case 17: return(PLHelper(name, price, clr, idx, new, shift, price17));
    case 18: return(PLHelper(name, price, clr, idx, new, shift, price18));
    case 19: return(PLHelper(name, price, clr, idx, new, shift, price19));
}   }
string  PLHelper( string name, double price, color clr, int idx, bool new
                , int shift,   double& mem[] ){
    datetime    t0  = Time[shift];  static datetime timeL[POLYLINE_MAX];
    if (timeL[idx] < Time[shift+1]) new = true; // Missing bar(s), leave a gap.
    /**/ if (new){  ArrayResize(mem, 2);
        mem[1]      = price;                static datetime timeF[POLYLINE_MAX];
        timeF[idx]  = Time[shift];          static color    clrLn[POLYLINE_MAX];
        clrLn[idx]  = clr;                  static int      segNo[POLYLINE_MAX];
        segNo[idx]++;       t0+=Period()*60;    }   // One bar wide to be visual
    else if (clrLn[idx] != clr){    ArrayResize(mem, 2);
        mem[1]      = mem[0];
        timeF[idx]  = timeL[idx];
        clrLn[idx]  = clr;
        segNo[idx]++;   }
    else if (timeL[idx] < t0){                      // New bar, remember point.
        if (!ResizeBuffer(mem, ArraySize(mem)+1))               return(""); }

    mem[0]      = price;        string objName  = name+"-"+segNo[idx];
    timeL[idx]  = t0;           int firstBar    = ArraySize(mem)-1;
    /**/ if(ObjectMove(objName, 1, t0,          price))
            ObjectMove(objName, 0, timeF[idx],  mem[firstBar]);
    else if (!ObjectCreate( objName, OBJ_TREND, WINDOW_MAIN     // New or tmplt.
                          , timeF[idx], mem[firstBar], t0,  price )){   Alert(
        "ObjectCreate(", objName, ",Trend) [1] failed: ",GetLastError());return;}
    else if (!ObjectSet( objName, OBJPROP_RAY, false ))                 Alert(
        "ObjectSet(", objName, ",Ray) [1] failed: ",     GetLastError());

    if (!ObjectSet( objName, OBJPROP_COLOR, clrLn[idx] ))               Alert(
        "ObjectSet(", objName, ",Color) [2] failed: ",   GetLastError());

    double maxError=0;  for (int pos=1; pos < firstBar; pos++){         double
        error=MathAbs(ObjectGetValueByShift(objName, pos+shift)-mem[pos]);
        if (error > maxError){  maxError=error; int maxBar=pos; }
    }
    if (maxError >= pips2dbl){  // Split the line into two segments at max.
        if (!ObjectMove(objName, 1, Time[shift+maxBar], mem[maxBar]))   Alert(
            "ObjectMove(", objName, ",Trend) [1] failed: ",     GetLastError());
        ArrayResize(mem, maxBar+1);     // Drop firstBar..(maxBar+1)
        timeF[idx] = Time[shift+maxBar];
        segNo[idx]++; objName=name+"-"+segNo[idx];
        /**/ if(ObjectMove(objName, 0, timeF[idx],  mem[maxBar]))
                ObjectMove(objName, 1, t0,          price);
        else if (!ObjectCreate( objName, OBJ_TREND, WINDOW_MAIN
                              , timeF[idx], mem[maxBar], t0, price ))   Alert(
            "ObjectCreate(", objName, ",Trend) [2] failed: ",   GetLastError());
        else if (!ObjectSet( objName, OBJPROP_RAY, false ))             Alert(
            "ObjectSet(", objName, ",Ray) [2] failed: ",        GetLastError());
        else if (!ObjectSet( objName, OBJPROP_COLOR, clrLn[idx] ))      Alert(
            "ObjectSet(", objName, ",Color) [3] failed: ",      GetLastError());
    }   // Split the line into two segments at the max.
    return(objName);
}   // PLHelper
void    PolyLineDelete(string name){
    for (int idx=0; idx < POLYLINE_MAX; idx++) if (lineName[idx] == name){
        lineName[idx] = ""; break;  }
    for(int obj=ObjectsTotal()-1; obj >= 0; obj--){
        string objectName = ObjectName(obj);
        if (StringFind(objectName, name) == 0)  ObjectDelete(objectName);
}   }
bool    ResizeBuffer(double buffer[], int size){
    if (ArraySize(buffer) != size){
        ArraySetAsSeries(buffer, false);    // Shift values B[2]=B[1]; B[1]=B[0]
        if (ArrayResize(buffer, size) <= 0){
            trading.disabled = "ArrayResize [1] failed: "+GetLastError();
            return(false);  }
        ArraySetAsSeries(buffer, true);
    }
    return(true);
}
//++++ These are adjusted for 5 digit brokers.
double  pips2points,    // slippage  3 pips    3=points    30=points
        pips2dbl;       // Stoploss 15 pips    0.0015      0.00150
int     Digits.pips;    // DoubleToStr(dbl/pips2dbl, Digits.pips)
int     init(){
    if (Digits == 5 || Digits == 3){    // Adjust for five (5) digit brokers.
                pips2dbl    = Point*10; pips2points = 10;   Digits.pips = 1;
    } else {    pips2dbl    = Point;    pips2points =  1;   Digits.pips = 0; }
    // OrderSend(... Slippage.Pips * pips2points, Bid - StopLossPips * pips2dbl
}
I even write separate window type indicator as a price overlay:
    /*++++ Draw STC line overlay price*/{
    PolyLineDelete(StcName);                                            double
    stcSell = 1.-STC.Buy,   buying  = MathMax(STC.Buy, stcSell),
                            selling = MathMin(STC.Buy, stcSell),
    top     = WindowPriceMax(),
    bottom  = WindowPriceMin(),                 range = top-bottom;
    top    -= range*0.05; bottom += range*0.05; range = top-bottom;
    shiftChart      =WindowFirstVisibleBar();
    shiftChartEnd   =shiftChart -WindowBarsPerChart();
    if (shiftChartEnd<0)    shiftChartEnd = 0;  // Tester/shift
            datetime TimeChartLeft = Time[shiftChart];

    for(shiftRB = 0; TimeChartLeft < Time.rb[shiftRB]; shiftRB++){} // Find RB.
    double  stcPrev = stc.buffer[shiftRB], stc = stcPrev;
    for (;shiftChart >= shiftChartEnd; shiftChart--){
        Tsc=Time[shiftChart];
        while(true){                    color clrNew, clrOld;   double cross;
            /**/ if (stc     >  buying){    clrNew=Color.Buy;   cross= buying; }
            else if (stc     < selling){    clrNew=Color.Sell;  cross=selling; }
            else                            clrNew=Color.STC;

            /**/ if (stcPrev >  buying){    clrOld=Color.Buy;   cross= buying; }
            else if (stcPrev < selling){    clrOld=Color.Sell;  cross=selling; }
            else                            clrOld=Color.STC;
            if (clrNew != clrOld && stcPrev != cross){
                double  stcOnPrice = cross * range + bottom;
                string  pln = Polyline(StcName, stcOnPrice, clrOld, shiftChart);
                    ObjectSet(pln, OBJPROP_STYLE, STYLE_DOT);
                    ObjectSetText(pln, "Stc="+DoubleToStr(stcPrev,2), 10);
                stcPrev = cross;
                continue;  }
            stcOnPrice = stc * range + bottom;
            pln=Polyline(StcName, stcOnPrice, clrNew, shiftChart);
                ObjectSet(pln, OBJPROP_STYLE, STYLE_DOT);
                ObjectSetText(pln, "Stc="+DoubleToStr(stc,2), 10);
            stcPrev = stc;

            if (shiftRB == 0 )              break;  // Last RB painted.
            if (Tsc < Time.rb[shiftRB-1])   break;  // Next RB on next chart bar
            shiftRB--;                              // Next RB on same bar.
            stc = stc.buffer[shiftRB];
    }   }
    /*---- Draw STC line overlay price*/}
 
Minor restructuring/enhancement.
string  PLHelper( string name, double price, color clr, int idx, bool new
                , int shift,   double& mem[] ){
    datetime    t0  = Time[shift];  static datetime timeL[POLYLINE_MAX];
    if (timeL[idx] < Time[shift+1]) new = true; // Missing bar(s), leave a gap.
    /**/ if (new){                  if (!ResizeBuffer(mem, 2))  return("");
        mem[1]      = price;                static datetime timeF[POLYLINE_MAX];
        timeF[idx]  = t0;                   static color    clrLn[POLYLINE_MAX];
        clrLn[idx]  = clr;                  static int      segNo[POLYLINE_MAX];
        segNo[idx]++;   }
    else if (clrLn[idx] != clr){    ArrayResize(mem, 2);        // Series==true;
        mem[1]      = mem[0];
        timeF[idx]  = timeL[idx];
        clrLn[idx]  = clr;
        segNo[idx]++;   }
    else if (timeL[idx] < t0){                      // New bar, remember point.
        if (!ResizeBuffer(mem, ArraySize(mem)+1))               return("");
    }
    mem[0]      = price;        string objName  = name+"_"+RJust(segNo[idx],3);
    timeL[idx]  = t0;           int firstBar    = ArraySize(mem)-1;
    if (t0 != timeF[idx])
            TLine(objName, timeF[idx], mem[firstBar], t0, price, clrLn[idx]);
    else    TLine(objName, t0-Period()*60, mem[firstBar]    // One bar wide 
                         , t0, price,      clrLn[idx]);     // to be visual

    double maxError=0;  for (int pos=1; pos < firstBar; pos++){         double
        error=MathAbs(ObjectGetValueByShift(objName, pos+shift)-mem[pos]);
        if (error > maxError){  maxError=error; int maxBar=pos; }
    }
    if (maxError >= pips2dbl){  // Split the line into two segments at max.
        TLine(objName,  timeF[idx],         mem[firstBar],
                        Time[shift+maxBar], mem[maxBar],    clrLn[idx]);
        ArrayResize(mem, maxBar+1);     // Drop firstBar..(maxBar+1)
        timeF[idx] = Time[shift+maxBar];
        segNo[idx]++; objName=name+"_"+RJust(segNo[idx],3);
        TLine(objName, timeF[idx], mem[maxBar], t0, price, clrLn[idx]);
    }   // Split the line into two segments at the max.
    return(objName);
}   // PLHelper
void TLine( string name, datetime T0, double P0, datetime T1, double P1
          , color clr, bool ray=false ){                #define WINDOW_MAIN 0
    if (!Show.Objects)  return;
    /**/ if(ObjectMove( name, 0, T0, P0 ))      ObjectMove(name, 1, T1, P1);
    else if(!ObjectCreate( name, OBJ_TREND, WINDOW_MAIN, T0, P0, T1, P1 ))
        Alert("ObjectCreate(",name,",TREND) failed: ", GetLastError() );
    else if (!ObjectSet( name, OBJPROP_RAY, ray ))
        Alert("ObjectSet(", name, ",Ray) failed: ", GetLastError());
    if (!ObjectSet(name, OBJPROP_COLOR, clr )) // Allow color change
        Alert("ObjectSet(", name, ",Color) [2] failed: ", GetLastError());
    string  P0t = PriceToStr(P0);           if (MathAbs(P0 - P1) >= Point)
            P0t = StringConcatenate(P0t, " to ", PriceToStr(P1));
    if (!ObjectSetText(name, P0t, 10))
        Alert("ObjectSetText(",name,") [2] failed: ", GetLastError());
}
string  PriceToStr(double p){
    string pFrc = DoubleToStr(p, Digits);       if(Digits.pips==0) return(pFrc);
    string pPip = DoubleToStr(p, Digits-1);
    if (pPip+"0" == pFrc)       return(pPip);           return(pFrc);          }
string  RJust(string s, int size, string fill="0"){
    while( StringLen(s) < size )    s = fill + s;       return(s);             }
 
WHRoeder:
Minor restructuring/enhancement.
This solution is for EA you have source code ? What if I don't ?
 
I modified the code again to allow overlays, FWIW
//+------------------------------------------------------------------+
//| EA equivalent of indicator buffers                               |
//+------------------------------------------------------------------+
/*  Example 1:
 *  if (...) Ordermodify(...);
 *  Polyline("SL"+(oo.ticket%99), oo.SL, Color.SL, 0);
 *
 *  Example 2:
 *  double  ELineCurr = iMA(NULL,0, ELine.Period, 0, MODE_EMA, PRICE_CLOSE, 1);
 *  string pln=Polyline("ELine", ELineCurr, Color.ELine, 1);
 *      ObjectSet(pln, OBJPROP_STYLE, STYLE_DOT);
 *      ObjectSetText(pln, "ELine="+DoubleToStr(ELineCurr,Digits), 10);
 ******************************************************************************/
#define POLYLINE_MAX 30 // Must match valueXX[]
string  lineName[POLYLINE_MAX]; // Common to Polyline/PolylineDelete and helper.
string  Polyline(string name, double value, color clr, int shift=0,
    double indiMin=INF, double indiMax=INF, double chrtMin=INF, double chrtMax=INF){
    if (!Show.Objects)  return("");         // Return the actual object name for
    static int           LRU[POLYLINE_MAX]; // further modifications, E.G. style
    for (int iLine=0; iLine < POLYLINE_MAX; iLine++){
        bool isNew = lineName[iLine] != name;   if (!isNew) break;  }
    if (isNew){
        for (iLine=0; iLine < POLYLINE_MAX; iLine++)  LRU[iLine]++;
        iLine=ArrayMaximum(LRU);  lineName[iLine]=name;
    }
    LRU[iLine] = 0;
    double  value00[], value01[], value02[], value03[], value04[],
            value05[], value06[], value07[], value08[], value09[],
            value10[], value11[], value12[], value13[], value14[],
            value15[], value16[], value17[], value18[], value19[],
            value20[], value21[], value22[], value23[], value24[],
            value25[], value26[], value27[], value28[], value29[];
    switch (iLine){
    case  0: return(PLHelper(value00, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case  1: return(PLHelper(value01, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case  2: return(PLHelper(value02, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case  3: return(PLHelper(value03, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case  4: return(PLHelper(value04, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case  5: return(PLHelper(value05, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case  6: return(PLHelper(value06, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case  7: return(PLHelper(value07, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case  8: return(PLHelper(value08, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case  9: return(PLHelper(value09, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 10: return(PLHelper(value10, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 11: return(PLHelper(value11, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 12: return(PLHelper(value12, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 13: return(PLHelper(value13, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 14: return(PLHelper(value14, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 15: return(PLHelper(value15, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 16: return(PLHelper(value16, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 17: return(PLHelper(value17, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 18: return(PLHelper(value18, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 19: return(PLHelper(value19, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 20: return(PLHelper(value20, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 21: return(PLHelper(value21, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 22: return(PLHelper(value22, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 23: return(PLHelper(value23, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 24: return(PLHelper(value24, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 25: return(PLHelper(value25, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 26: return(PLHelper(value26, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 27: return(PLHelper(value27, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 28: return(PLHelper(value28, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    case 29: return(PLHelper(value29, value, clr, iLine, isNew, shift,
                                        indiMin, indiMax, chrtMin, chrtMax));
    }
    /*NOTREACHED*/
}   // Polyline
string  PLHelper( double& mem[],    double value0,  color clr,      int iLine,
                  bool isNew,       int shift,      double indiMin,
                  double indiMax,   double chrtMin, double chrtMax ){
    string name = lineName[iLine];
    double  price0  = value0;                               if (indiMin < INF){
        if (chrtMin == INF) chrtMin = WindowPriceMin();
        if (chrtMax == INF) chrtMax = WindowPriceMax();
            price0  = (value0 - indiMin) / (indiMax - indiMin)
                    * (chrtMax - chrtMin) + chrtMin;                        }
    datetime    t0  = Time[shift];  static datetime timeL[POLYLINE_MAX];
    if (!isNew){
        if (timeL[iLine] < Time[shift+1]){      // Missing bar(s), leave a gap.
            isNew = true;                                                   }
        else if (Time[shift] < timeL[iLine]){   // Redrawing earlier bars.
            isNew = true;
            for(int iObj=ObjectsTotal()-1; iObj >= 0; iObj--){
                string on = ObjectName(iObj);
                if (StringFind(on, name) == 0)  ObjectDelete(on);
    }   }   }
    if (isNew){
        if (!ResizeBuffer(mem, 2))  return("");
        mem[1]        = price0;     static datetime timeF[POLYLINE_MAX];
        timeF[iLine]  = t0;         static color    clrLn[POLYLINE_MAX];
        clrLn[iLine]  = clr;        static int      segNo[POLYLINE_MAX];
        segNo[iLine]++;                                                     }
    else if (clrLn[iLine] != clr){  ArrayResize(mem, 2);    // Series==true;
        mem[1]        = mem[0];
        timeF[iLine]  = timeL[iLine];
        clrLn[iLine]  = clr;
        segNo[iLine]++;                                                     }
    else if (timeL[iLine] < t0){                    // New bar, remember point
        if (!ResizeBuffer(mem, ArraySize(mem)+1))               return(""); }
    mem[0]          = price0;   timeL[iLine]    = t0;
    int     iFirst  = ArraySize(mem)-1;
    double  priceF  = mem[iFirst],
            valueF  = priceF;                               if (indiMin < INF){
            valueF  = (priceF - chrtMin) / (chrtMax - chrtMin)
                    * (indiMax - indiMin) + indiMin;                        }
    datetime Tf = timeF[iLine];                                 // One bar wide
    if (t0 == Tf)   Tf += IfI(-1, +1, shift==0)*60*Period();    // to be visual
    string  objName = name+"_"+RJust(segNo[iLine],3);
    TLine(objName, Tf, priceF, t0, price0, clr, valueF, value0);
    double maxError=0;  for (int iMem=1; iMem < iFirst; iMem++){
        double  hight   = ObjectGetValueByShift(objName, iMem+shift),
                error   = MathAbs(hight - mem[iMem]);
        if (error > maxError){  maxError = error;   int iMaxError = iMem; }
    }
    if (maxError >= pips2dbl){  // Split the line into two segments at max.
        double  priceM  = mem[iMaxError],
                valueM  = priceM;                           if (indiMin < INF){
                valueM  = (priceM - chrtMin) / (chrtMax - chrtMin)
                        * (indiMax - indiMin) + indiMin;    }
        TLine(objName,  timeF[iLine],           priceF,
                        Time[iMaxError+shift],  priceM, clr, valueF, valueM);
        ArrayResize(mem, iMaxError+1);          // Drop iFirst..(iMaxError+1)
        timeF[iLine] = Time[iMaxError+shift];
        segNo[iLine]++; objName=name+"_"+RJust(segNo[iLine], 3);
        TLine(objName, timeF[iLine], priceM, t0, price0, clr, valueM, value0);
    }   // Split the line into two segments at the max.
    return(objName);
}   // PLHelper
 
Overlay call like this
                #define WPR_NAME  "wpr"
        double  bottom      =         WindowPriceMin(),
                top         = MathMax(WindowPriceMax(), bottom+pips2dbl),// Div0
                topQuarter  = (3*top +   bottom)/4.,
                botQuarter  = (top   + 3*bottom)/4.;
        int     iVisible    =           WindowFirstVisibleBar(),
                iVisEnd     = MathMaxI( iVisible-WindowBarsPerChart(),0);// Shft
        static bool drawOnTop = false;
        if      (Bid >= topQuarter) drawOnTop = false;  // Hysteresis - previous
        else if (Bid <= botQuarter) drawOnTop = true;   // location otherwise.
        if (drawOnTop)  bottom  = topQuarter;
        else            top     = botQuarter;
        for(iWpr = MathMinI(iWprBegin, iVisible); iWpr >= iVisEnd; iWpr--)
            Polyline( WPR_NAME, wprValue[iWpr], Color.Wpr, iWpr,
                      0., 100., bottom, top );