Price channel of 55 periods fails when it crosses with the PC of 20 periods

 

Good afternoon, I am programming an EA that needs to check whether the previous bar has crossed at anytime the Price Channel indicator or not. I'm using a PChannel indicator I downloaded as a graphical guide, but I've programmed my own in the EA. The PC I've programmed works fine, except when the PC of 55 periods is equal to PC of 20 periods, not an unusual event at all. When that happens, the graphic PC and the PC I've programmed seem to give different value, something I can''t understand because it works well the rest of the time. This is my code:


   // This is the PC55 I've programmed. It starts at the Bar 2 and ends at the Bar 56 because I'm checking the previous Bar, the 1.

   double pc55hR = NormalizeDouble(iHigh(Symbol(), BarsFrame, iHighest(Symbol(), BarsFrame, MODE_HIGH, 56,2)),4);

   double PrevBarHighest = iHigh (Symbol(), "PERIOD_M5", 1);

   Alert ("High of the bar: " +PrevBarHighest);
   Alert ("PC55hR: " +pc55hR); 
   Alert ("PC55h: " +pc55h); // Ignore this one.

   if (PrevBarHighest > pc55hR){
      Do whatever;
   }

Now I'm attaching a picture so you see what's going on in the graphic and the values it outputs. In the image, the PC55 drops just in the bar previous to the current one. I'd like it to buy it here. However, the output of the alerts show a different value. I've checked if the discontinuity between the graphic and the programmed holds but it just appears when the PC55 meet the PC20. Also, it's not a case of the NormalizeDouble because there are more than 30 micropips of distance between the graphic PC55 and the value the programmed PC55 outputs. I hope someone here can see this more clearly than I do. Thanks!

Files:
example.png  148 kb
 
  1. // This is the PC55 I've programmed. It starts at the Bar 2 and ends at the Bar 56 because I'm checking the previous Bar, the 1.
    double pc55hR = NormalizeDouble(iHigh(Symbol(), BarsFrame, iHighest(Symbol(), BarsFrame, MODE_HIGH, 56,2)),4);

    It starts at bar two and ends at bar 57, for a total of 56 bars.

  2. There is no need for NormalizeDouble when you can only read normalized prices from a chart.

    You used NormalizeDouble, It's use is usually wrong, as it is in your case.
    1. Floating point has infinite number of decimals, it's your not understanding floating point and that some numbers can't be represented exactly. (like 1/10.)
                Double-precision floating-point format - Wikipedia, the free encyclopedia

      See also The == operand. - MQL4 programming forum

    2. Print out your values to the precision you want with DoubleToString - Conversion Functions - MQL4 Reference.

    3. SL/TP (stops) need to be normalized to tick size (not Point) — code fails on metals. (On 5Digit Broker Stops are only allowed to be placed on full pip values. How to find out in mql? - MQL4 programming forum) and abide by the limits Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial and that requires understanding floating point equality Can price != price ? - MQL4 programming forum

    4. Open price for pending orders need to be adjusted. On Currencies, Point == TickSize, so you will get the same answer, but it won't work on Metals. So do it right: Trailing Bar Entry EA - MQL4 programming forum or Bid/Ask: (No Need) to use NormalizeDouble in OrderSend - MQL4 programming forum

    5. Lot size must also be adjusted to a multiple of LotStep and check against min and max. If that is not a power of 1/10 then NormalizeDouble is wrong. Do it right.

    6. MathRound() and NormalizeDouble() are rounding in a different way. Make it explicit.
                MT4:NormalizeDouble - MQL5 programming forum
                How to Normalize - Expert Advisors and Automated Trading - MQL5 programming forum

    7. Prices you get from the terminal are already normalized.

    8. PIP, Point, or Tick are all different in general.
                What is a TICK? - MQL4 programming forum 2014.08.03

 
William Roeder:
  1. It starts at bar two and ends at bar 57, for a total of 56 bars.

  2. There is no need for NormalizeDouble when you can only read normalized prices from a chart.

Thanks a lot for your answer. Great help as always. I'm working out on absorbing all the info you've given me on the second point. However, I am not sure about what you mean in the first one. The idea is that the Price Channel of 55 periods outputs the highest of the last 55 bars, not 56. If so, I want to go from 2 to 56 for a total of 55 bars, am I wrong? Thanks again, really appreciate it.


Edit: on the point 2.2: would an OrderSend accept a value in string format?

 
marclfp: , I want to go from 2 to 56 for a total of 55 bars, am I wrong?

Your want isn't wrong, your call is. You asked for 56 bars.

 
William Roeder:

Your want isn't wrong, your call is. You asked for 56 bars.

Thanks William. I have two questions. The first one is regarding to the price channel indicator. I don't know if I'm correctly programming what I want to do. I have a graphic Price Channel of 55 periods, and I obviously want my EA to follow it. I've programmed the PC with the single line you've just helped me correct. Now, what I want to do is to check if the previous Bar broke the Price Channel or not. Since in order to check if the current bar has crossed the bar or not I should call the iHighest from 1 to 20, I inferred that to check the previous Bar I had to call it from 2 to 21. But that's leading me to contradictions with the graphic indicator, so I've even tried to call it from 2 to 19, as to count the last 20 bars counting the current one. The only thing I know for sure is that I should be starting from 2. However, I can't seem to find the answer to this specific question about the indicator. The difference in code is as follows:


double pc20hR = StringToDouble(DoubleToString(iHigh(Symbol(), PERIOD_M5, iHighest(Symbol(), PERIOD_M5, MODE_HIGH, 21,2)),4));
double pc20h = StringToDouble(DoubleToString(iHigh(Symbol(), PERIOD_M5, iHighest(Symbol(), PERIOD_M5, MODE_HIGH, 19,2)),4));

if (iHigh(Symbol(), PERIOD_M5, 1) > PC20){ // Note that I don't know which pc20h should I use here.
        Do whatever;
}

The second question is regarding to the DoubleToString function you've suggested me to use instead of NormalizeDouble. As I still need a double to operate I've written this fairly-dull code: StringToDouble(DoubleToString()); Would this be the correct way to do so? Thanks again for your help.

 
marclfp: I had to call it from 2 to 21.

Your pc20hR call is from 2 through 22 for a total of 21 bars. Not 20.

What part of #1 and #3 was unclear to you?

 
William Roeder:

Your pc20hR call is from 2 through 22 for a total of 21 bars.

What part of #3 was unclear to you?

I understood, but then I don't understand why is it failing. For example, in the image I attached in this comment you can see how there's a variation in the graphic PC: it goes from 1.0577 to 1.0578. However, my programmed PC gives no change; it says it's both 1.0578. I suspect that the indicator doesn't normalize the values or something, but I'm clearly lost in this issue. Can you help me understand? This is the line of code:


   double pc55h = NormalizeDouble(iHigh(Symbol(), BarsFrame, iHighest(Symbol(), BarsFrame, MODE_HIGH, 55,1)),4); // Current bar
   double pc55hR = NormalizeDouble(iHigh(Symbol(), BarsFrame, iHighest(Symbol(), BarsFrame, MODE_HIGH, 55,2)),4); // Previous bar

Both of these lines give me 1.0578 :/

Files:
example.png  4 kb
 
marclfp: then I don't understand why is it failing.

Your posted code has nothing to do with your images.

 

So, the thing is that the code needs to know if the previous bar broke the Price Channel of 55 or not. Then it needs to know if the previous to the previous bar broke it or not as well, but I think that's giving no problems. In order to do so I've programmed a PC55 and I want to check its value at the previous bar, not the current one. Right now, and still using NormalizeDouble and after having checked that it doesn't account for the errors I'm having, the code is as follows:

   double pc55h = NormalizeDouble(iHigh(Symbol(), BarsFrame, iHighest(Symbol(), BarsFrame, MODE_HIGH, 55,1)),4);  // PC55 of the current Bar.
   double pc55hR = NormalizeDouble(iHigh(Symbol(), BarsFrame, iHighest(Symbol(), BarsFrame, MODE_HIGH, 55,2)),4); // PC55 of the previous Bar.
   double pc55hRR = NormalizeDouble(iHigh(Symbol(), BarsFrame, iHighest(Symbol(), BarsFrame, MODE_HIGH, 55,3)),4);// PC55 of the previous previous Bar.

   if( (iHigh(NULL, BarsFrame, 1) > pc55hR) && (iHigh(NULL, BarsFrame, 2) <= pc55hRR) ){
      Do nice stuff;
   }


The code seems to me logical, but when I run it it doesn't work. For example, you can see in the image above the kind of problems I'm finding. In that image the previous bar breaks the PC, but the code doesn't do what it has to do when a bar breaks the PC, it doesn't do the "nice stuff". I suspect that, in this case, it's comparing the Bar to the current PC55, e.g. to the PC55 of the next bar.

The main problem is that my PC55 isn't behaving like the graphical one, but I'm at a loss understanding what I'm doing wrong. I really hope you can help me out here. Thanks a lot.

 
Excuse the repost, but I really need a hand on this issue to keep advancing, until I solve this I'm stuck.
 
What issue? I already said “Your posted code has nothing to do with your images.”
Reason: