A little help?

 

So I'm learning mql4 after a few other languages, and I (or so I thought) just finished the first version of my first EA, a simple moving average trader. I left it to run throughout yesterday with no concerns, entry and exit were as expected, and I thought it was ready to go. This morning I have come into all sorts of issues, first, the code when I reran it would only sell regardless of position, and now, after a little fiddling, it will buy and sell in the correct positions BUT when buying the trade will close on the next tick regardless. This isn't happening when I'm selling despite holding the same format - can someone point me in the direction as to why??

(As a side note, my computer was able to run the code all day yesterday without much more of a hum (CPU averaged 12%) today its going like hells bells to run the code (~60-90%))

Code:

int total;
//+------------------------------------------------------------------+
//| expert init function                                            |
//+------------------------------------------------------------------+
int init()
  {
//---- 
   int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }
   else 
      {
      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }
   }
}
//----
   return;
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert start function                                   |
//+------------------------------------------------------------------+
int start()
  {
//----
   int p,q,z,i,L;
   while (AccountBalance()>50)                                                                                    //---- ensures an infinite loop for 1 trade a run 
   {                                                                                                              //---- (no infibuying!) (*) but always run
//---- 
RefreshRates();
//----
if ((iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)<70)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))&&(total==0))
      {                                                                                                                             //---------- ^ conditions to buy
      p=OrderSend(Symbol(),OP_BUY,0.1,Bid,0,0,0,"",z,0,Red);                                                                        //---------- Buy Order
      OrderSelect(p,SELECT_BY_TICKET);
         while (iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))                             //- whilst the above remains true
            {
            RefreshRates();                                                                                                         //- refresh then do nothing
            Sleep(1000);
         }
      OrderClose(OrderTicket(),0.1,OrderClosePrice(),0,Green);                                                                      //---when above is broken, close
         while (TimeSeconds(TimeCurrent())!=0)                                                                                      //---wait until a new minute
            {
            Sleep(1000);
         }
         continue;
      }
//-----         
if ((iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)>30)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))&&(total==0))
       {                                                                                                                            //---Same steps as above for sell
       q=OrderSend(Symbol(),OP_SELL,0.1,Ask,0,0,0,"",z,0,Blue);
       OrderSelect(q,SELECT_BY_TICKET);
         while (iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))
            {
            RefreshRates();
            Sleep(1000);
         }
      OrderClose(OrderTicket(),0.1,OrderClosePrice(),0,Green);
         while (TimeSeconds(TimeCurrent())!=0)
            {
            Sleep(1000);
         }      
         continue;
      }
if (total!=0)
   {
   L=0;
   for (i=1; i<=OrdersTotal(); i++)                                                       //--- if trades were open which werent initially closed
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- close them if now the position has change
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  L++;
               }
            }
            total=L;
         }
      }
   }
else 
   {
   Sleep(1000);
} 
}
//----
return;
}
//--------------------------------------------------------------+
 

I haven't gone too deep into your code

Why RefreshRates and then sleep for 1 second, when the market is moving swiftly, the data will be out of date!?

You are calculating on ticks, not bars, so 1 tick can trigger an order by one MA moving above/below the other by a minimal amount. If the following tick (after the sleep) reverses,the MAs cross again and the order will be closed.

 

The idea is to simply keep in the while loop whilst the conditions wait until the close conditions occur (Aka the sma's switch over) - admittedly not the best way to do so, but one of the cheapest computationally.

The SMA's swiftly moving above/below each other is one of the issues of the code - but i see no reason why, when there is currently 10 - 15 pips between the two I am running on, would lead to closing? the conditions are definitely holding for the while loop to remain in control, instead of instantly jumping to the close (my assumption is that the while loop is being ignored for the buy but not the sell - and I dont know why)

 
j.w.msb:

The idea is to simply keep in the while loop whilst the conditions wait until the close conditions occur (Aka the sma's switch over) - admittedly not the best way to do so, but one of the cheapest computationally.

The SMA's swiftly moving above/below each other is one of the issues of the code - but i see no reason why, when there is currently 10 - 15 pips between the two I am running on, would lead to closing? the conditions are definitely holding for the while loop to remain in control, instead of instantly jumping to the close (my assumption is that the while loop is being ignored for the buy but not the sell - and I dont know why)


If you are only checking if one MA is above/below the other, I doubt that it is usually 10 to 15 pips difference, it can be 0.1 pips and so the next tick can easily reverse it.

It is only my opinion, but when working with crossovers, I believe that it is best to only calculate on closed bars to avoid too many opposite signals

 

Also in your init

 int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }
   else 
      {
      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }
   }
}

your else only applies to the last if, so if the EA doesn't close an open sell order, total will be increased by 1. Why would you want this?

 
GumRai:


If you are only checking if one MA is above/below the other, I doubt that it is usually 10 to 15 pips difference, it can be 0.1 pips and so the next tick can easily reverse it.

It is only my opinion, but when working with crossovers, I believe that it is best to only calculate on closed bars to avoid too many opposite signals


was a miscalculation on my part in terms of pips! my bad! But the point is there is certainly breathing space between the two so that the is no cross over signal to force the sell. Replacing the Sleep(1000) with while (TimeSecond(TimeCurrent)!=59) {Sleep(1000)} would ensure the testing of the crossover only on closing of the candle?


I have taken out the OrderClose in the buy section and the order is still being opened upon running and then closing on the next pip :s


Next I have switched OP_BUY and OP_SELL and the sell is holding as expected when the 6SMA is above the 21SMA - am waiting for the next cross over to see what happens (obviously I'm testing this in the minute time frame for the time being)

 

There is a lot to change..... a thing to work on

What magicnumber do the trades have your EA is creating...

why don't you make it as an extern input variable so you can make it an unique number and it is not closing trades other EA's

int init()
  {

//---- 
   int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }

what happens here...

      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair

         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }

don't count up checking trades it will fail if you close trades inside the loop like you do now

Take a look here to see why you have to work and how counting down

https://www.mql5.com/en/forum/139654

(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)

this condition can change several times in a few moments when a new tick is coming in every trade you pay spread

condition is not always change once ....on a single bar

   while (AccountBalance()>50)                                                                                    //---- ensures an infinite loop for 1 trade a run 
   {                                                                                                              //---- (no infibuying!) (*) but always run
//---- 

what always run you let it sleep

and in normal ways when tick is done and new tick comes start() is called again

    while (TimeSeconds(TimeCurrent())!=0)                                                                                      //---wait until a new minute
            {
            Sleep(1000);
         }
         continue;
      }

this way running the code only when second is 0 will fail often

because it can happen often that on a second there is no new tick coming in

if first tick of the minute comes at 1 second you have to wait for new minute and hope new tick is coming at second 0 next minute

Check the function RefreshRates()

there are more things like make it work as well 4 as 5 digit broker

checking returncodes....

Slippage your value 0 why is it needed ??? to have it bigger

 
deVries:

There is a lot to change..... a thing to work on

What magicnumber do the trades have your EA is creating...

why don't you make it as an extern input variable so you can make it an unique number and it is not closing trades other EA's

what happens here...

don't count up checking trades it will fail if you close trades inside the loop like you do now

Take a look here to see why you have to work and how counting down

https://www.mql5.com/en/forum/139654

this condition can change several times in a few moments when a new tick is coming in every trade you pay spread

condition is not always change once ....on a single bar

what always run you let it sleep

and in normal ways when tick is done and new tick comes start() is called again

this way running the code only when second is 0 will fail often

because it can happen often that on a second there is no new tick coming in

if first tick of the minute comes at 1 second you have to wait for new minute and hope new tick is coming at second 0 next minute

Check the function RefreshRates()

there are more things like make it work as well 4 as 5 digit broker

checking returncodes....

Slippage your value 0 why is it needed ??? to have it bigger

thank you for your help, Im making changes now and I'll see how it goes! Silly mistakes compounded by stupid errors on my behalf! Its almost a wonder why it ran in the first place!
 

So, I stripped back the code to run in the simplest of capacities (ie crossover = reverse positions) - its causing alot of buy/sell orders when the two SMAs are close, but Im not worried about that (for now) and runs fine on a demo account. What is now concerning me is if I run my code on the Strategy Tester, it opens the first position correctly, but then fails to move forward time wise, so the SMA's never cross over. What am I doing wrong? My print list is:

2013.10.22 23:41:26 2013.09.18 00:41 Tester: order #1 is closed

2013.10.22 23:41:26 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

...

2013.10.22 23:40:53 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:40:52 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:40:51 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:56:18 SMACode3 GBPJPY,M1: loaded successfully

Code:



//+------------------------------------------------------------------+
//|                                                   SMA scripy.mq4 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
extern int z=1234;
int total;
//----

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int init()
  {
//---- 
   int i;
   total=0;
   if (OrdersTotal()!=0)
      {
      for (i=OrdersTotal()-1; i>=0; i--)                                                     
         {
         if (OrderSelect(i,SELECT_BY_POS))
            {
            if (OrderSymbol()==Symbol())
               {
               if (OrderMagicNumber()==z) 
                  {
                  if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                     { 
                     OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                  
                  }
                  if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                     {
                     OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                  
                  }
                  else 
                     {
                     total++;                                                                 
                  }
               }
           }
       }
   }
}
//----
   return;
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int start()
   {
//----
   int i,L;
   while (AccountBalance()>50)                                                                                     
   {
   RefreshRates();
//-----
double SMA6=iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0);
double SMA21=iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0);
double RSI70=iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)<70;
double RSI30=iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)>30;                                                                                                            
//-----   
if (IsTesting()==true)
{
Sleep(60000);
Print(GetLastError());
}
//----
   if (total==0)
      {
      if ((RSI70)&&(SMA6>SMA21))
         {                                                                                                                       
         OrderSend(Symbol(),OP_BUY,0.1,Ask,0,0,0,"",z,0,Red); 
         total+=1;                                                       
         continue;
      }
      if ((RSI30)&&(SMA6<SMA21))
         {
         OrderSend(Symbol(),OP_SELL,0.1,Bid,0,0,0,"",z,0,Blue);
         total+=1;
         continue;
      }  
   }
//---
if (total!=0)
   {
   L=0;
   for (i=OrdersTotal()-1; i>=0; i--)                                                    
      {
      if (OrderSelect(i,SELECT_BY_POS))
         {
         if (OrderSymbol()==Symbol())
            {
            if (OrderMagicNumber()==z) 
               {
               if ((OrderType()==OP_BUY)&&(SMA6<SMA21))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);
                     total+=-1;
                 return;
               }
               if ((OrderType()==OP_SELL)&&(SMA6>SMA21))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                 
                     total+=-1;
                  return;
               }
               else 
                  {
                  L++;                                                                  
               }
            }
            total=L;
         }
      }
   }
}
//----
}
//----
return;
}
//--------------------------------------------------------------+
 
j.w.msb: What is now concerning me is if I run my code on the Strategy Tester, it opens the first position correctly, but then fails to move forward time wise,
  1. int start(){
       while (AccountBalance()>50){
          :
    Of course not. RTFM. You only get a new tick when you return from start.
  2. if (IsTesting()==true){
        Sleep(60000);
        Print(GetLastError());
    }
    RTFM & Tester limitations you can NOT sleep in the tester
  3.         OrderSend(Symbol(),OP_SELL,0.1,Bid,0,0,0,"",z,0,Blue);
                      OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);
    
    What are Function return values ? How do I use them ? - MQL4 forum
 
RefreshRates does not change any values in the tester, so you are stuck in a while loop because it does not have any new values to work with.
Reason: