Any rookie question, so as not to clutter up the forum. Professionals, don't pass by. Nowhere without you - 6. - page 987

 

Why does the debugger "crash" when debugging the indicator (because it accesses the array boundaries), but at the same time everything is drawn normally on the chart?

MT4 build 950, Alpari demo.

The indicator is attached.

//+------------------------------------------------------------------+
//|                                     FX5_MACD_Divergence_V1.1.mq4 |
//|                                                              FX5 |
//|                                                    hazem@uk2.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, FX5"
#property link      "hazem@uk2.net"
//----
#property indicator_separate_window
#property indicator_buffers 4
#property  indicator_color1 Green
#property  indicator_color2 Red
#property  indicator_color3 Magenta
#property  indicator_color4 Blue
//----
#define  arrowsDisplacement 0.0001
//---- input parameters
extern string separator1 = "*** MACD Settings ***";
extern int    fastEMA = 12;
extern int    slowEMA = 26;
extern int    signalSMA = 9;
extern string separator2 = "*** Indicator Settings ***";
extern bool   drawIndicatorTrendLines = true;
extern bool   drawPriceTrendLines = true;
extern bool   displayAlert = true;
//---- buffers
double bullishDivergence[];
double bearishDivergence[];
double macd[];
double signal[];
//----
static datetime lastAlertTime;
static string   indicatorName;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0, DRAW_ARROW);
   SetIndexStyle(1, DRAW_ARROW);
   SetIndexStyle(2, DRAW_LINE);
   SetIndexStyle(3, DRAW_LINE);
//----   
   SetIndexBuffer(0, bullishDivergence);
   SetIndexBuffer(1, bearishDivergence);
   SetIndexBuffer(2, macd);
   SetIndexBuffer(3, signal);   
//----   
   SetIndexArrow(0, 233);
   SetIndexArrow(1, 234);
//----
   indicatorName = "FX5_MACD_Divergence_v1.1(" + fastEMA + ", " + 
                                 slowEMA + ", " + signalSMA + ")";
   SetIndexDrawBegin(3, signalSMA);
   IndicatorDigits(Digits + 2);
   IndicatorShortName(indicatorName);

   return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   for(int i = ObjectsTotal() - 1; i >= 0; i--)
     {
       string label = ObjectName(i);
       if(StringSubstr(label, 0, 19) != "MACD_DivergenceLine")
           continue;
       ObjectDelete(label);   
     }
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int countedBars = IndicatorCounted();
   if(countedBars < 0)
       countedBars = 0;
   CalculateIndicator(countedBars);
//---- 
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CalculateIndicator(int countedBars)
  {
   for(int i = Bars - countedBars; i >= 0; i--)
     {
       CalculateMACD(i);
       CatchBullishDivergence(i + 2);
       CatchBearishDivergence(i + 2);
     }              
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CalculateMACD(int i)
  {
   macd[i] = iMACD(NULL, 0, fastEMA, slowEMA, signalSMA, 
                   PRICE_CLOSE, MODE_MAIN, i);
   
   signal[i] = iMACD(NULL, 0, fastEMA, slowEMA, signalSMA, 
                     PRICE_CLOSE, MODE_SIGNAL, i);         
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CatchBullishDivergence(int shift)
  {
   if(IsIndicatorTrough(shift) == false)
       return;  
   int currentTrough = shift;
   int lastTrough = GetIndicatorLastTrough(shift);
//----   
   if(macd[currentTrough] > macd[lastTrough] && 
      Low[currentTrough] < Low[lastTrough])
     {
       bullishDivergence[currentTrough] = macd[currentTrough] - 
                                          arrowsDisplacement;
       //----
       if(drawPriceTrendLines == true)
           DrawPriceTrendLine(Time[currentTrough], Time[lastTrough], 
                              Low[currentTrough], 
                             Low[lastTrough], Green, STYLE_SOLID);
       //----
       if(drawIndicatorTrendLines == true)
          DrawIndicatorTrendLine(Time[currentTrough], 
                                 Time[lastTrough], 
                                 macd[currentTrough],
                                 macd[lastTrough], 
                                 Green, STYLE_SOLID);
       //----
       if(displayAlert == true)
          DisplayAlert("Classical bullish divergence on: ", 
                        currentTrough);  
     }
//----   
   if(macd[currentTrough] < macd[lastTrough] && 
      Low[currentTrough] > Low[lastTrough])
     {
       bullishDivergence[currentTrough] = macd[currentTrough] - 
                                          arrowsDisplacement;
       //----
       if(drawPriceTrendLines == true)
           DrawPriceTrendLine(Time[currentTrough], Time[lastTrough], 
                              Low[currentTrough], 
                              Low[lastTrough], Green, STYLE_DOT);
       //----
       if(drawIndicatorTrendLines == true)                            
           DrawIndicatorTrendLine(Time[currentTrough], 
                                  Time[lastTrough], 
                                  macd[currentTrough],
                                  macd[lastTrough], 
                                  Green, STYLE_DOT);
       //----
       if(displayAlert == true)
           DisplayAlert("Reverse bullish divergence on: ", 
                        currentTrough);   
     }      
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CatchBearishDivergence(int shift)
  {
   if(IsIndicatorPeak(shift) == false)
       return;
   int currentPeak = shift;
   int lastPeak = GetIndicatorLastPeak(shift);
//----   
   if(macd[currentPeak] < macd[lastPeak] && 
      High[currentPeak] > High[lastPeak])
     {
       bearishDivergence[currentPeak] = macd[currentPeak] + 
                                        arrowsDisplacement;
      
       if(drawPriceTrendLines == true)
           DrawPriceTrendLine(Time[currentPeak], Time[lastPeak], 
                              High[currentPeak], 
                              High[lastPeak], Red, STYLE_SOLID);
                            
       if(drawIndicatorTrendLines == true)
           DrawIndicatorTrendLine(Time[currentPeak], Time[lastPeak], 
                                  macd[currentPeak],
                                  macd[lastPeak], Red, STYLE_SOLID);

       if(displayAlert == true)
           DisplayAlert("Classical bearish divergence on: ", 
                        currentPeak);  
     }
   if(macd[currentPeak] > macd[lastPeak] && 
      High[currentPeak] < High[lastPeak])
     {
       bearishDivergence[currentPeak] = macd[currentPeak] + 
                                        arrowsDisplacement;
       //----
       if(drawPriceTrendLines == true)
           DrawPriceTrendLine(Time[currentPeak], Time[lastPeak], 
                              High[currentPeak], 
                              High[lastPeak], Red, STYLE_DOT);
       //----
       if(drawIndicatorTrendLines == true)
           DrawIndicatorTrendLine(Time[currentPeak], Time[lastPeak], 
                                  macd[currentPeak],
                                  macd[lastPeak], Red, STYLE_DOT);
       //----
       if(displayAlert == true)
           DisplayAlert("Reverse bearish divergence on: ", 
                        currentPeak);   
     }   
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool IsIndicatorPeak(int shift)
  {
   if(macd[shift] >= macd[shift+1] && macd[shift] > macd[shift+2] && 
      macd[shift] > macd[shift-1])
       return(true);
   else 
       return(false);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool IsIndicatorTrough(int shift)
  {
   if(macd[shift] <= macd[shift+1] && macd[shift] < macd[shift+2] && 
      macd[shift] < macd[shift-1])
       return(true);
   else 
       return(false);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int GetIndicatorLastPeak(int shift)
  {
   for(int i = shift + 5; i < Bars; i++)
     {
       if(signal[i] >= signal[i+1] && signal[i] >= signal[i+2] &&
          signal[i] >= signal[i-1] && signal[i] >= signal[i-2])
         {
           for(int j = i; j < Bars; j++)
             {
               if(macd[j] >= macd[j+1] && macd[j] > macd[j+2] &&
                  macd[j] >= macd[j-1] && macd[j] > macd[j-2])
                   return(j);
             }
         }
     }
   return(-1);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int GetIndicatorLastTrough(int shift)
  {
    for(int i = shift + 5; i < Bars; i++)
      {
        if(signal[i] <= signal[i+1] && signal[i] <= signal[i+2] &&
           signal[i] <= signal[i-1] && signal[i] <= signal[i-2])
          {
            for (int j = i; j < Bars; j++)
              {
                if(macd[j] <= macd[j+1] && macd[j] < macd[j+2] &&
                   macd[j] <= macd[j-1] && macd[j] < macd[j-2])
                    return(j);
              }
          }
      }
    return(-1);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DisplayAlert(string message, int shift)
  {
   if(shift <= 2 && Time[shift] != lastAlertTime)
     {
       lastAlertTime = Time[shift];
       Alert(message, Symbol(), " , ", Period(), " minutes chart");
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DrawPriceTrendLine(datetime x1, datetime x2, double y1, 
                        double y2, color lineColor, double style)
  {
   string label = "MACD_DivergenceLine_v1.0# " + DoubleToStr(x1, 0);
   ObjectDelete(label);
   ObjectCreate(label, OBJ_TREND, 0, x1, y1, x2, y2, 0, 0);
   ObjectSet(label, OBJPROP_RAY, 0);
   ObjectSet(label, OBJPROP_COLOR, lineColor);
   ObjectSet(label, OBJPROP_STYLE, style);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DrawIndicatorTrendLine(datetime x1, datetime x2, double y1, 
                            double y2, color lineColor, double style)
  {
   int indicatorWindow = WindowFind(indicatorName);
   if(indicatorWindow < 0)
       return;
   string label = "MACD_DivergenceLine_v1.0$# " + DoubleToStr(x1, 0);
   ObjectDelete(label);
   ObjectCreate(label, OBJ_TREND, indicatorWindow, x1, y1, x2, y2, 
                0, 0);
   ObjectSet(label, OBJPROP_RAY, 0);
   ObjectSet(label, OBJPROP_COLOR, lineColor);
   ObjectSet(label, OBJPROP_STYLE, style);
  }
//+------------------------------------------------------------------+
 
r772ra:
In your question about finding the highest rate in the remainder of the day after a bullish candle, the part about the time zone of the server time was left out for some reason. The task is strictly tied to the boundary of the day, and these boundaries are different in different companies. The candlesticks belonging to different days are different. Depending on the server's time zone, the highest values you find will belong to different days. Is this normal for your case?
 
Hi all!

Not a newbie, but there is a "silly" question, as I have hardly ever encountered such a situation.

Suppose there is a pending order already set.
We use the indicator to move its price.
At one moment, the order cannot be modified because the new price has got into the prohibited range due to the stop signs like Ask/Bid +/- MarketInfo(Symbol(), MODE_STOPLEVEL / MODE_FREEZELEVEL).

But the order has to be opened "by the market".

What can we do in this case?

Can we delete the pending order and open a new one by the market?

Or, is it possible to change the pending order into an open one?
 
mt4trade:
Hi all!

Not a newbie, but there is a "silly" question, as I have hardly ever encountered such a situation.

Suppose there is a pending order already set.
We use the indicator to move its price.
At one moment, the order cannot be modified because the new price has got into the prohibited range due to the stop signs like Ask/Bid +/- MarketInfo(Symbol(), MODE_STOPLEVEL / MODE_FREEZELEVEL).

But the order has to be opened "by the market".

What can we do in this case?

Can we delete the pending order and open a new one by the market?

Or the pending order can be somehow transformed into an open one?
If it is so close to the price, the price will find it, but not, maybe it's better if it is a stop! And if it is a limit one, then patience. Try to experiment in the tester and the optimization will determine the best variant! Good luck!
 

Please help.

When I install an EA on a standalone chart, the EA does not work, because the start() function is not started.

How can I implement a chart update from an EA which builds it, or from an EA which is attached to this chart?

 
borilunad:
If in such close proximity to the price, the price will find it on its own, and if not, maybe it's for the best if it's a stop! And the limit one, then patience. Try to experiment in the tester, and the optimization will determine the best variant! Good luck!
Thank you! It's all so clear. But I want to know the answer to my question - what should I do if I absolutely need the order to trigger regardless of the direction of the price? Should I delete the pending order and open a regular one or have some other variants?
 
mt4trade:
Thank you! But I need an answer to my question - if an order has to be triggered regardless of where the price goes now, what should I do? Should I delete the pending order and open a regular one?
For me, if you follow your strategy, then do it! I would not recommend to change it half-way, otherwise without certain results (positive or negative), you cannot be sure in the rationality of your strategy. That's it!
 
borilunad:
For me, if you follow your strategy, then follow it! I don't recommend changing it halfway through, otherwise without certain results (positive or negative), you cannot be sure of the rationality of your strategy. That's it!
Again, thank you! You say the right things, but irrelevant to the question. Once again: If the calculated price of the pending order has hit the prohibited range, and it cannot be modified, but must (according to the strategy) triggered at the calculated price - how do you "turn" it into a triggered one? To delete it and open it as a normal one? Or there are other options? Please answer exactly this question.
 
mt4trade:
Thank you again! You say the right things, but irrelevant to the question. :) Once again: If the calculated price of a pending order has hit the prohibited range and it cannot be modified, but must (according to the strategy) trigger at the calculated price - how do I "turn" it into a triggered one? To delete it and open it as a normal one? Or there are other options? Please answer exactly this question.
There is inconsistency in this approach. If a position is expected to be opened already in the freeze zone (it cannot be modified) from a pending order, then the order should be initially placed at a different price, at the boundary of this freeze zone. That is why your approach is not accepted by many people.

To be specific to your question. First remove the pending order and then immediately open a position at the current price. The problem is that during these actions, the price can move out of the freeze zone (to the worse) and the position will be opened at a wrong price. Another option is not to create a pending order and store the value to open the position in a variable in the program. Compare it with the current price and if the condition is met (taking into account the freezing zone), you open a position.
 
paladin80:
There is inconsistency in this approach. If we expect to open a position already in the "freeze" zone (when modification is impossible) of a pending order, then we should have originally placed the order at another price, at the boundary of this "freeze" zone. That is why your approach is not accepted by many people.

To be specific to your question. First remove the pending order and then immediately open a position at the current price. The problem is that during these actions, the price can move out of the freeze zone (to the worse) and the position will be opened at a wrong price. Another option is not to create a pending order and store the value to open the position in a variable in the program. Compare it with the current price and if the condition is met (taking into account the freezing zone), you open a position.

Paladin80, everything you write about, I know very well. And about freezing and unfreezing and the boundary, etc.

The only question was whether the pendulum should be deleted and put a regular one, if a strategy is required (!).

That is, the pendulum at the "now" price will not work (but I want it to work and I can't afford to wait).

Thank you!