Stuck on coding an EA

 

Hey there,

 

I'm currently writing an EA. First the 20 EMA needs to cross above the 50 EMA. Then the stochastic oscillator needs to cross the 80 level downwards. When the stochastic moves back to the oversold region and then crosses the 20 level upwards I want to place a buy order.

The problem poses in the folowing... I only want to place 1 buy order each cross. The buy order can only trigger the first time the stochastic crosses the 20 level upwards. Then the EA has to wait till the next cross.

I tried working with bolean frases and counts. However, due to my limited experience I'm stuck.

Heres what I created thus far. I also attached the EA.

 

if(fast>slow && fastprevious<slowprevious) bcrossovercount++;


bool uptrend=false;

if(fast>slow) uptrend=true;

if(fast<=slow)uptrend=false;


bool boverbought=false;

if(0<bcrossovercount<2 && stocurrent>stocupperlimit && stosignalcurr>stocupperlimit) boverbought=true;

if(stocurrent<stocupperlimit && stosignalcurr<stocupperlimit) boverbought=false;


if(boverbought=true && 0<bcrossovercount<2 && stocurrent<stocupperlimit && stoprevious>stocupperlimit) bdowncrosscount++;


bool boversold=false;

if(0<bcrossovercount<2 && 0<bdowncrosscount<2 && stocurrent<stoclowerlimit && stosignalcurr<stoclowerlimit) boversold=true;

if(stocurrent>stoclowerlimit && stosignalcurr>stoclowerlimit) boversold=false;


if(boversold=true && stocurrent>stoclowerlimit && stoprevious<stoclowerlimit) bupcrosscount++;


if(uptrend=true && stocurrent>stoclowerlimit && stoprevious<stoclowerlimit && 0<bcrossovercount<2 && 0<bdowncrosscount<2 && 0<bupcrosscount<2)

      {

      res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,slb,0,"",MAGICMA,0,Blue);

      return;

      }  

Files:
 
What about using the sample EA: "Moving Average.mq4" in your expert folder instead of again inventing the wheel?
 
gooly:
What about using the sample EA: "Moving Average.mq4" in your expert folder instead of again inventing the wheel?
thats what I actually did, but the trading conditions are way more complex now and can't figure out how to put them in code
 

Evilynn:

...

I only want to place 1 buy order each cross.

1) Well, if you have an open position another position is not opened no matter what kind of cross or no-cross you have:

   if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
   else                                    CheckForClose();


2) here:

if(fast>slow && fastprevious<slowprevious) bcrossovercount++;

you would need to either define fastprevious and slowprevious and bcrossovercount as local static variable or as global variables or like: (they are 0.0 as soon the function is called)

   fast=iMA(NULL,0,FastMovingPeriod,FastMovingShift,MODE_SMA,PRICE_CLOSE,0);
   slow=iMA(NULL,0,SlowMovingPeriod,SlowMovingShift,MODE_SMA,PRICE_CLOSE,0);
   fastprevious=iMA(NULL,0,FastMovingPeriod,FastMovingShift,MODE_SMA,PRICE_CLOSE,1);
   slowprevious=iMA(NULL,0,SlowMovingPeriod,SlowMovingShift,MODE_SMA,PRICE_CLOSE,1);

...

To find bugs like this it helps to start the ea in debug mode go though it line by line and check the value of each variable or to show the values by Comment() or print them out.

 

Evilynn:

I'm currently writing an EA. First the 20 EMA needs to cross above the 50 EMA. Then the stochastic oscillator needs to cross the 80 level downwards. When the stochastic moves back to the oversold region and then crosses the 20 level upwards I want to place a buy order.

The problem poses in the folowing... I only want to place 1 buy order each cross. The buy order can only trigger the first time the stochastic crosses the 20 level upwards. Then the EA has to wait till the next cross.

Heres what I created thus far. I also attached the EA.
  1. Don't paste code
    Play video
    Please edit your post.
    For large amounts of code, attach it.

  2. bool boversold=false;
    if(0<bcrossovercount<2 && 0<bdowncrosscount<2 && stocurrent<stoclowerlimit && stosignalcurr<stoclowerlimit) boversold=true;
    There is no need to write if(bool) v=true; else v=false;. Just write v=bool;
    bool boversold =( 0<bcrossovercount<2 && 0<bdowncrosscount<2 
                   && stocurrent<stoclowerlimit && stosignalcurr<stoclowerlimit
                    );

  3. 0 < bcrossovercount < 2 Always true!
    
    0 <        0        < 2
      false             < 2
       0                < 2  true
    
    0 <        1        < 2
      true              < 2
       1                < 2  true
    
    0 <        2        < 2
      true              < 2
       1                < 2  true
    
    0 <        3        < 2
      true              < 2
       1                < 2  true
    

  4. You have two problems, first, there is no point in counting crosses. If it goes back down and then up, that is the cross.
  5. Second, you have to remember stochastic went above 80 and below 20. Can't do that with one compare.

  6. // 1) First the 20 EMA needs to cross above the 50 EMA. 
    // 2) Then the stochastic oscillator needs to cross the 80 level downwards. 
    // 3) When the stochastic moves back to the oversold region 
    // 4) and then crosses the 20 level upwards I want to place a buy order.
    enum State{ EMA_BUY, STO_BUY, STO_OVERSOLD, IDLE, EMA_SELL, STO_SELL, STO_OVERBOUGHT};
    
    static State state = IDLE;
    
    // 1
    if(state >= IDLE && EMA20 > EMA50) state = EMA_BUY;
    if(state <= IDLE && EMA20 < EMA50) state = EMA_SELL;
    
    // 2
    if(state == EMA_BUY  && stoc > 80)  state = STO_BUY;
    if(state == EMA_SELL && stoc < 20)  state = STO_SELL;
    
    // 3
    if(state == STO_BUY  && stoc < 20)   state = STO_OVERSOLD;
    if(state == STO_SELL && stoc < 20)   state = STO_OVERBROUGHT;
    
    // 4
    if(state == STO_OVERSOLD    && stoc > 20)   state = IDLE; Buy();
    if(state == STO_OVERBROUGHT && stoc < 80)   state = IDLE; Sell();
    

 

Thanks a lot. I'll try to code some more and post the result tomorrow.

Greets,

Evi 

 
enum State{ EMA_BUY, STO_BUY, STO_OVERSOLD, IDLE};

static state=IDLE

// 1
if(state >= IDLE && fast>slow && fastprevious<slowprevious) state = EMA_BUY;

// 2
if(state == EMA_BUY  && stocurrent > 80) state = STO_BUY;

// 3
if(state == STO_BUY  && stocurrent < 20) state = STO_OVERSOLD;

// 4
if(state == STO_OVERSOLD && stocurrent > 20 && stoprevious < 20) state == IDLE;
      {
      res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,slb,0,"",MAGICMA,0,Blue);
      return;
      }

I folowed your advice and came up with this. However, I get a lot of buy orders when I run this.

I might be a bit more specific on my trading rules.

Rule 1) The 20 EMA Crosses above the 50 EMA. The stochastic is most likely overbought now

Rule 2) The stochastic crosses the 80 level downwards for the first time after the EMA cross.

Rule 3) The stochastic moves to the oversold region for the first time after the EMA cross, so below the 20 level 

Rule 4) The stochastic crosses the 20 level upward for the first time, exiting the oversold region (here I place my buy order)

...

The order gets closed. Until there's a new EMA crossover there should be no further orders.

 

Could you help me with this? Can't figure it out.

 

Also, not sure if you noticed this part yet or not, but this statement block could be compressed some, as one of the lines is redundant.  If you think about it, your first line sets your variable to false.  You only need to test to set it to true, otherwise it stays false, like below.

bool uptrend=false;               //var "uptrend" is set to false

if(fast>slow) uptrend=true;       //var "uptrend" is only set to true if the test passes, otherwise it is still false

if(fast<=slow)uptrend=false;      //var "uptrend" being set to false here is redundant, as it is already false because of "uptrend=false" statement above
                                  //you can delete the if(fast<=slow)uptrend=false; line

Not saying that in a different place in the code you might not need to set it to false if that test is done again, but here, in this chuck of code, it is unnecessary.

Reason: