Storing Numbercode

 

I am trying to create an EA for a system that uses Bollinger Bands as one of the indicators. A problem that I am running into is that I want my code to "save" or "store" a number when certain criteria is met and than change that number when the next set of criteria is met. This is my current code:


static int BB_direction=0;

if(PriceLow<bbBottom)
{
BB_direction =1;
return(BB_direction);
}
if(PriceHigh>bbTop)
{
BB_direction=2;
return(BB_direction);
}

What I basically want to happen is for my BB_direction to remain "1" until it changes to "2" and than remain "2" until it changes to "1."


Thanks for the help!

 

What I basically want to happen is for my BB_direction to remain "1" until it changes to "2" and than remain "2" until it changes to "1."


You did.

 

Hiya Lady


Not sure about how your question to be handled because not see all code and what is there shows BB_direction as static int and:

1. when it gets set to say =1;, it will continue to have this value until any other code assigns a new value to it ie, the "high>top" condition.

2. see below, cause not really see the issue here as this is code fragment...


Using static int at EA top level scope or at function level scope effectively achieves same end - the value contained in this int is not going to disappear when the EA exits start() back to Terminal.

What is different is the visibility scope of the int ie, who can access this memory location.

see editor help - ref: MQL4 Reference - Basics - Variables - Local variables

also is help on static, global syntax.


If your code above is a function() with the static int inside the function, only the function can access it.


If is let's say at the top of your EA source file outside of any functions [including start()] it is visible by any function built into the EA.


Again, it will remain "1" until you execute code which changes it...

The EA logic decides this, yes? so if not want any code to change this int you must ensure your conditionals stop entry to the 'changing' code... until such time that you are ready to change it.


Above is bit abstract, but from your snippet, is not obvious [to me] what problem is.


Regards


(edit: hahaaa - phy [once again] has said it all succinctly too! (while I was fluffing about giving some background and my usual waffle))


hey phy - wanna tackle my timeout question?

 
int Hit(double bbTop, double bbBottom)
{
double PriceLow,PriceHigh;
static int BB_direction;
PriceLow=iLow(NULL,0,1);
PriceHigh=iHigh(NULL,0,1);
if(PriceLow<bbBottom)
{
BB_direction =1;
return(BB_direction);
}
if(PriceHigh>bbTop)
{
BB_direction=2;
return(BB_direction);
}
}


//+------------------------------------------------------------------+
//| TradingRange |
//+------------------------------------------------------------------+
int start()
{
//----
int cnt, ticket, total;
double BB_high,BB_low;


BB_high=iBands(NULL,0,BB_Period,BB_StDev,0,PRICE_CLOSE,MODE_UPPER,0);
BB_low=iBands(NULL,0,BB_Period,BB_StDev,0,PRICE_CLOSE,MODE_LOWER,0);


int isHit = Hit(BB_high,BB_low);

Here is all of the code that deals with this issue. As you can see, because I use the iBands this information changes with each close. Thus at some point my Prices are in between the bands and not above or below the bands as the code requires for the BB_direction. I don't know if this helps to explain things better or not.

 

(1)

start()

{

static int isHit; //function scope persistent memory

isHit = Hit(..);

...

}


(2)

int isHit; //EA global scope persistent memory

...

start()

{

isHit = Hit(..);

...

}


Your existing code will 'remember' BB_direction because declared static int inside Hit()
but... only code inside Hit() can 'see' BB_direction.

IF you wish to 'remember' the result of Hit() say in start() so that you can use it's value the 'next' time start() entered - you need to declare isHit as persistent
(ie, non-volatile state memory) by one of the examples shown above(1,2), it will retain it's value between calls to start()

In this case, the static declaration in Hit() is redundant, yes?


Note that not have to use iLow,iHigh,... if only using default chart symbol that EA running on.

just use {Open,Low,High,Close}[1] - see docs: MQL4 Reference - Predefined variables

for example:


#define BB_DIRLOW 1
#define BB_DIRHIGH 2


int Hit(double bbTop, double bbBottom)
{
int BB_direction;

if(Low[1]<bbBottom)
BB_direction = BB_DIRLOW;

if(High[1]>bbTop)
BB_direction = BB_DIRHIGH;

return(BB_direction);
}

ignore #defines if you not into this syntax... but for me: I hate constants! 1,2,?? means nothing to my old brain!

and is very easy to get the 1's and 2's and nn's mixed up - especially after a late nite!


hth


btw: beware that depending on timeframe used on EAs chart, a single bar can span completely BBand.top AND BBand.bot H,L range.

Can your design/system deal with this possibility?

 

Thanks ukt. I have tried the first scenario before and it still didn't do what I want it to do but I will give the global variable a shot.

Thanks for the advice on the bands as well. I am aware of this and I have another variable in place that will help distinquish this. It seems that the problem comes when both my indicators do not occur at the same time (naturally). My code will make a trade when both indicators line up (which is great), but I also want it to trade when one indicator shows a trade and a little while later the other indicator shows a trade. So basically whenever my BB_direction = 1, wait for the other indicator to show long and than buy. When BB_direction = 2, wait for the other indicator to show short, and than sell.

Right now I have my code set up so that it will look for the 2nd indicator and when it finds that I want it to see what the current BB_direction (1 or 2) is. For some reason, if the BB_direction occured two bars in the past or more, my code will not pick it up and a trade is not made. Thus I only get those trades where both indicators occur at the same time.


Again thanks for the help. I am going to try a couple of other things as well as the global and I will let you know how it turns out.

 

Well - good hunting as they say :)

Yes, keep in touch and interesting to see your results - wish could have been more help, I generally find it hard to understand what/why others actually doing (no reflection on you - just my issue, ;) - coding is not so bad an area but concepts prove more formidable for me...

I'll stay subscribed to topic then.

Vnice your lengthy replies - makes for interesting interactions.

Cheers

 
ukt:

Well - good hunting as they say :)

Yes, keep in touch and interesting to see your results - wish could have been more help, I generally find it hard to understand what/why others actually doing (no reflection on you - just my issue, ;) - coding is not so bad an area but concepts prove more formidable for me...

I'll stay subscribed to topic then.

Vnice your lengthy replies - makes for interesting interactions.

Cheers

I figured it out. I got rid of the Hit function all together and placed all of the coding into the start function with a static int on the BB_direction. So here is the code:
int start()
{
//----
int cnt, ticket, total;
double bbTop,bbBottom;

bbTop=iBands(NULL,0,BB_Period,BB_StDev,0,PRICE_CLOSE,MODE_UPPER,0);
bbBottom=iBands(NULL,0,BB_Period,BB_StDev,0,PRICE_CLOSE,MODE_LOWER,0);

static int BB_DIR;

if(High[1]>bbTop)BB_DIR=BB_High;
if(Low[1]<bbBottom)BB_DIR=BB_Low;
After doing a custom indicator to make sure that my logic does work I figured that it was the creating of the function that was messing everything up. And it was. Go figure, you try and do stuff to make the code look nicer and it goes against you :)
 

Hiya Lady - well done :))


On to the next series of enevitable hurdles then...


I'm gonna stay subscribed, maybe when you feel is right time could do the 'cast pearls to the swine' drill 'n tell all - lol!

Anyways, good going - nothing better than progress in computing.

Please do remember Lady, functions do work ;) - one day you will look back at your code and see that yes, function could have been used etc, and black boxing single function discrete code sections is well proven way to remove clutter/improve readability/understandability and more importantly allows total testing [to destruction] of the black box so that callers can rely on this function to do as expected - just like ClientTerminal functions - their only exposure to outside world is via it's published interface. The how does it do it is totally unimportant to caller - as long as the results are waranted as specified in the functions docs...

In your case Hit() returns high/low - end of story. Personally, I always 'testbed' check my functions - a simple noddy script is good enough for many to feed function(s) under test and log the results for post test analyses. In one swoop, you have documented proof that yep... it really does work as I expected it to work - yipee, another one done!!!

You may balk at idea of testing function with handfull of lines - but it is very surprising to look at test results and often start scratching head cause totally unexpected things do happen!


Another good reason in this programming environment to be paranoic is MONEY... your money is on the line here, yes?


Anyway Lady, waffle, waffle - congrats!

Reason: