Confident in my strategy - New to MQL4

 

Hello. I am having difficulty making my EA do what I want it to do. I've read the book, I've tried experimenting with the sample programs, but my own EA is producing undesired results.

My strategy is simple. I'm watching XAU in various currencies on M15 charts with a 144 period Bollinger Band. When the price goes outside the upper band, I want to go short when a new bar opens AND closes below the upper band. The inverse is true for prices that go outside the lower band, I want to go long when a new bar opens AND closes above the lower band after trades have taken place below the lower band.

Pretty simple, right?

All I've done so far with my program is that I've requested alerts when buying or selling conditions are met. But instead of getting one message saying "we're going short" or "we're going long", I get a message of "we're going short" for EVERY TICK even though, according to what I understand, I've told the program to report only once.

Once I sort that out, I plan on trying to program the trade operations in.

I've put comments beside everything, explaining what I expect each operator to do and would appreciate some help figuring out what I've done wrong here.

Thanks

Files:
 

start() is exectuted on every tick, so there's no use setting variables to 'false'.

You have to store the time last alert was sent. See attached file. lines containing 'lastalert' (5 in total).

P.S. it doesn't work quite the way you described. I'd suggest putting all conditions in one if statement, like:

if (Close[1]<iBands(NULL,0,144,2,0,PRICE_WEIGHTED,MODE_LOWER,1)  //Previous bar closed below the lower band
 && Close[0]>iBands(NULL,0,144,2,0,PRICE_WEIGHTED,MODE_LOWER,0)) //Current bar's last price is above the lower band
   {
   BuySignal=true;
   }

Better readability of the code = easier to find what's wrong.

Files:
 

erm - not quite.

Let me understand something... close[1] is the last bar, close[0] is the current bar? so close[4] would be four bars ago?

The above code does not look adequate. I need two things to happen in order before a trade decision is made...

(1) Price must go outside the bollinger bands either above or below.

(2) A new bar must open AND close back inside the bands. Just the close is not good enough.

So for a short trade, price must break above upper band, then a new bar must open and close below the upper band.

For a long trade, price must break below the lower band, then a new bar must open and close above the lower band.

I thought I had the math and boolean logic all worked out but the journal in the script tester is telling me a different story.

I'm running script tester on XAUCAD, XAUCHF, XAUEUR and XAUAUD.

 
trivates:

I thought I had the math and boolean logic all worked out but the journal in the script tester is telling me a different story.

That's why I suggested putting all conditions together - otherwise they are pretty hard to analyze at 1:00 am :)

You might want to compare lows (or highs for the upper band):

if (Low[1]<iBands(NULL,0,144,2,0,PRICE_WEIGHTED,MODE_LOWER,1)  //Price was below the lower band at some moment during the previous bar
 && Low[0]>iBands(NULL,0,144,2,0,PRICE_WEIGHTED,MODE_LOWER,0)) //Current bar is fully inside

If you want to wait for the current bar to close inside, then you have to look at the bars 1 and 2 when the next bar starts.

If you want to make sure the price was fully outside before going back in, then you probably have to cycle over 3...5 bars, because it rarely happens that one bar is fully outside and the next - fully inside.

There can be many dufferent ways to formulate the conditions - some will be more aggressive, some more cautious.

 

Ok - that's closer to what I was looking for.

int start()
{
//---- Find Buy or Sell Signals

if (Low[1]<iBands(NULL,0,144,2,0,PRICE_WEIGHTED,MODE_LOWER,1) //Price was below the lower band at some moment during the previous bar
&& Open[0]>iBands(NULL,0,144,2,0,PRICE_WEIGHTED,MODE_LOWER,0)
&& Close[0]>iBands(NULL,0,144,2,0,PRICE_WEIGHTED,MODE_LOWER,0)) //Open and close of current bar are both fully inside
{
Alert ("We are going Long. Ride that Bull!");
}

if (High[1]>iBands(NULL,0,144,2,0,PRICE_WEIGHTED,MODE_UPPER,1) //Price was above the upper band at some moment during the previous bar
&& Open[0]<iBands(NULL,0,144,2,0,PRICE_WEIGHTED,MODE_UPPER,0)
&& Close[0]<iBands(NULL,0,144,2,0,PRICE_WEIGHTED,MODE_UPPER,0)) //Open and close of Current bar are both fully inside
{
Alert ("We are going Short. Hold on Tight!");
}

It is still feeding me way too many alerts. I only want one alert as soon as the entry condition is satisfied - to simulate a trade being placed. At a later date, I can worry about putting in trading instructions but before I get all mangled up in that mess, I want to know that the computer can recognize what I'm trying to tell it to look for.

Again, if price goes even slightly outside the upper band, wait for a close and open to show up under it -> Send me an alert telling me to go short - ONCE! (simulating an order being placed)

And if price goes even slightly outside the lower band, wait for a close and open to show up above it -> Send me an alert telling me to go long - ONCE! (simulating an order being placed)

Once THAT works, I can worry about integrating trading instructions into the program

Thank you for your help so far, I think we're getting somewhere.

 
Please try not to double post. I tried what I could here. You can also find info on once per bar here.
 
trivates:
It is still feeding me way too many alerts. I only want one alert as soon as the entry condition is satisfied

  1. (2) A new bar must open AND close back inside the bands. Just the close is not good enough

    Check your conditions at the start of a new bar, don't look at bar zero.
    int     start(){      static datetime Time0;
        if (Time0 == Time[0]) return;     Time0 = Time[0];
        ...
    

  2. Let me understand something... close[1] is the last bar, close[0] is the current bar? so close[4] would be four bars ago?
    close[0] is the price now, changes every tick.
 
trivates:

Ok - that's closer to what I was looking for.

int start()
{
//---- Find Buy or Sell Signals

if (Low[1]<iBands(NULL,0,144,2,0,PRICE_WEIGHTED,MODE_LOWER,1) //Price was below the lower band at some moment during the previous bar
&& Open[0]>iBands(NULL,0,144,2,0,PRICE_WEIGHTED,MODE_LOWER,0)
&& Close[0]>iBands(NULL,0,144,2,0,PRICE_WEIGHTED,MODE_LOWER,0)) //Open and close of current bar are both fully inside
{
Alert ("We are going Long. Ride that Bull!");
}

if (High[1]>iBands(NULL,0,144,2,0,PRICE_WEIGHTED,MODE_UPPER,1) //Price was above the upper band at some moment during the previous bar
&& Open[0]<iBands(NULL,0,144,2,0,PRICE_WEIGHTED,MODE_UPPER,0)
&& Close[0]<iBands(NULL,0,144,2,0,PRICE_WEIGHTED,MODE_UPPER,0)) //Open and close of Current bar are both fully inside
{
Alert ("We are going Short. Hold on Tight!");
}

It is still feeding me way too many alerts. I only want one alert as soon as the entry condition is satisfied - to simulate a trade being placed. At a later date, I can worry about putting in trading instructions but before I get all mangled up in that mess, I want to know that the computer can recognize what I'm trying to tell it to look for.

Again, if price goes even slightly outside the upper band, wait for a close and open to show up under it -> Send me an alert telling me to go short - ONCE! (simulating an order being placed)

And if price goes even slightly outside the lower band, wait for a close and open to show up above it -> Send me an alert telling me to go long - ONCE! (simulating an order being placed)

Once THAT works, I can worry about integrating trading instructions into the program

Thank you for your help so far, I think we're getting somewhere.

whroeder1:


  1. Check your conditions at the start of a new bar, don't look at bar zero.

  2. close[0] is the price now, changes every tick.

How to code "the last bar close above of upper or low of lower band??

 

 
tasaoirse:
Please don't wrote inside the quote. It's hard to follow.
Reason: