Problem in calling a function twice

 

Dear Coders

I have a problem with calling a custom function twice in OnTick() function. Every things are alright when i call my function once. but when i call it twice every things become messed up.

You can find my function below. i wrote this for detecting crossing a level. when i want to use it for two levels, returned values will be true for all prices between those two levels. I'm really confused with this. please help!

Thanks in advance.

//+----------------------------------------------------------------------------------------+
//| Level Cross with daily expiration Function                                                                 |
//+----------------------------------------------------------------------------------------+
  bool LevelCross(double Level)
     {
     static int CurrentDirection, LastDirection;
     bool Crossed;
     static datetime CrossTime;
     if (Bid>Level)             CurrentDirection=1;                            //UP
     if (Bid<Level)             CurrentDirection=2;                            //DOWN
     if (CurrentDirection!=LastDirection && LastDirection!=0)                  //CROSSED
        {
        Crossed=True;
        CrossTime=TimeCurrent();
        }
     LastDirection=CurrentDirection;
     if (CrossTime<(MathFloor(TimeCurrent() / 86400) * 86400))       Crossed=False;
     return (Crossed);
     }
//+--End of Function--------------------------------------------------------------------------------------+
 
//+----------------------------------------------------------------------------------------+
//| Level Cross with daily expiration Function                                                                 |
//+----------------------------------------------------------------------------------------+
  int LevelCross(double Level)
     {
     static double LastBid=Bid;
     bool Crossed=0;
     static datetime CrossTime;
     if (Bid>Level && LastBid<Level)          
        {
        Crossed=1;                 //UP
        CrossTime=TimeCurrent();
        }                  
     if (Bid<Level && LastBid>Level)         
        {
        Crossed=2;                //DOWN
        CrossTime=TimeCurrent();
        } 
     if (CrossTime<(MathFloor(TimeCurrent() / 86400) * 86400))       Crossed=False;
     LastBid=Bid;
     return (Crossed);
     }
//+--End of Function--------------------------------------------------------------------------------------+

I think that you need something like this that returns 1 for a cross up, 2 for a cross down and 0 if no cross.

Not tested.

Your code, if you check for more than 1 line LastDirection will keep alternating 

 

Thanks. Now i know where was the problem. Alternating LastDirection after calling function for 2nd Level. And your code is very helpful. You replaced LastDirection with a variable which changes by chart's data rather than given value by the function. And i think i don't need the expiration line. The function returns 1 or 2  just when crossing occurs and will be zero in other times. Because Crossed is a local variable which its initial value resets to 0 each time the function been called. Thanks again

 
Dadash:

Thanks. Now i know where was the problem. Alternating LastDirection after calling function for 2nd Level. And your code is very helpful. You replaced LastDirection with a variable which changes by chart's data rather than given value by the function. And i think i don't need the expiration line. The function returns 1 or 2  just when crossing occurs and will be zero in other times. Because Crossed is a local variable which its initial value resets to 0 each time the function been called. Thanks again

 

I used 1 and 2 as they are the values that you used.

Personally, in code like this I prefer to use -1 for down, 1 for up, and 0 for when up or down doesn't apply. I believe it avoids problems by having a negative number for down crosses and a positive number for up crosses. Of course, you stick with whatever you are happy with 

 
Yes you are right. -1 and 1 are more meaningful than 1 and 2. I will change them. Thanks.
 
Dadash: . -1 and 1 are more meaningful than 1 and 2. I will change them.
Nether are meaningful. Don't use int's when you mean an enumeration.
enum Level { Level_Up, Level_Down, Level_NoChange};
Level LevelCross(double Level) ...
:
if(LevelCross(...) == Level_Up) ...
 

I rewrote the code as follows.

int LevelCross(double Level)
     {
     static double    LastBid=Bid;
     int              Crossed;
     if (Bid>Level && LastBid<Level)             Crossed=1;                            //UP
     if (Bid<Level && LastBid>Level)             Crossed=-1;                           //DOWN
     LastBid=Bid;
     return (Crossed);
     }

 And it does not work when been called for two different levels. it works properly for first call and always returns 0 for second one! I tested this and i'm sure it's sensitive to calls sequence. This simple function is making me mad!!

 
WHRoeder:
Dadash: . -1 and 1 are more meaningful than 1 and 2. I will change them.
Nether are meaningful. Don't use int's when you mean an enumeration.

I'm really confused with your code. And what about the problem i mentioned in previous post? 
 
Dadash:

I rewrote the code as follows.

 And it does not work when been called for two different levels. it works properly for first call and always returns 0 for second one! I tested this and i'm sure it's sensitive to calls sequence. This simple function is making me mad!!

Of course, silly me.

at the first call LastBid will be set to the current bid and so any other calls will not give the correct result.

You could decare LastBid as a Global variable and reset it after all function calls in your main code 

 
GumRai:

Of course, silly me.

at the first call LastBid will be set to the current bid and so any other calls will not give the correct result.

You could decare LastBid as a Global variable and reset it after all function calls in your main code 

This issue was redirecting my concentration from coding an EA to solve one function's problem. so as a quick solution i used another copy of this function with different variables names for second call. In first look the problem solved but it seems in some situations crossing is not detected by the functions! Just i can not believe this tiny function can make these series of problems! By the way i will use your suggestion and will announce the result. thanks for your attention!
Reason: