Loopy loop, thing runs away, little help please!

 

Hi,

I'm not a programmer, so be gentle.

I'm trying to close out trades when conditions are met, so: if (A < B) - in this case close out BuyTrades till A is no longer less than B. But the thing runs away and closes as many trades as it wants to or can - so it overshoot my targets and I get nuked. For some reason it carries on even after the condition are no longer true. I can't find the problem. Must be a return (0) or bracket or something small.

if (A < B) 

    {
      for (i = 0; i < OrdersTotal(); i++)
       {
        OrderSelect(i, SELECT_BY_POS);
        MyTicket = OrderTicket();
        if (OrderSymbol() == Symbol())
         {
          if (OrderType() == 0) 
           {
            if (TradeBusy() < 0 && OrderType() == 0) 
             {
              Print(Symbol(), " Trade is still busy when attempting to close Buy trade");
              return(0);
             }
            Slip = MarketInfo(Symbol(), MODE_SPREAD) * Point;
            RefreshRates();
            Result = OrderClose(MyTicket, 0.01, Ask, Slip, Blue);
            if (Result < 1)
             {
              Print("Error ", GetLastError(), " While Closing Ticket ", MyTicket,
                    " Lots = ", OrderLots(), " Price = ", OrderClosePrice(), " Ask = ", Ask);
              TradeNotBusy();
              return(0); 
             }
            else
             {
              TradeNotBusy();
              
             } 
           }
         }
       }
     }
   }

Tried a few remedies: I tried to delete the loop section so:

if A < B
    {
       if (OrderSymbol() == Symbol())
         {
          if (OrderType() == 0) 
           {
            if (TradeBusy() < 0 && OrderType() == 0) 
             {
              Print(Symbol(), " Trade is still busy when attempting to close Buy trade");
              return(0);
             }
            Slip = MarketInfo(Symbol(), MODE_SPREAD) * Point;
            RefreshRates();
            Result = OrderClose(MyTicket, 0.01, Ask, Slip, Blue);
            if (Result < 1)
             {
              Print("Error ", GetLastError(), " While Closing Ticket ", MyTicket,
                    " Lots = ", OrderLots(), " Price = ", OrderClosePrice(), " Ask = ", Ask);
              TradeNotBusy();
              return(0); 
             }
            else
             {
              TradeNotBusy();
              
             } 
           }
         }
      }
   } 
         

That doesn't work at all. Then I tried to change the second line like this, so it only does it once a tick. But then it really only does one and sits there.

(i = 0; i < OrdersTotal(); i++) to (i = 0; i < 1; i++)

Anyone see any obvious problem with that first block of code ? If not how do I set it so it only does that once a tick and not go into the loop.

Thanks!!

 

for reliable work the main loop should be:

for(int i=OrdersTotal()-1;i>=0;i--){
//do some stuff
}

in your example you check for the inital condition, (A<B) if that is true, you go trough all your orders an close them...

if you want to close only as many orders until ((A<B)==false) you have to insert that statement inside the loop.

for(int i=OrdersTotal()-1;i>=0;i--){
//Calculate A and B
  if(A>=B){
    return;
  }else{
    //Close The Order
 
  }
  
}

as you can see, i reversed the A<B statment to check the opposite, A>=B if that is true your initial initial statement is false, and so it return; from the function.

but you have to recalulate A and B after each turn.

-

-

i hope i was getting right what you try to do..

//z

 

I see, I was afraid so, cause that AB calculation is a mouth full. To put it in that loop is beyond me.


So how do I get rid of the loop bit and have it run only once every tick so it can go and fetch the right values? That be the easiest at this point. I tried to delete the loop bit, but I must be doing it wrong. It gets stuck. Next best option is to tell it to run the loop only once which I tried with (i = 0; i < 1; i++) That also fails, it gets stuck.


Any ideas on that?

 
PumPuiMonkey:

I see, I was afraid so, cause that AB calculation is a mouth full. To put it in that loop is beyond me.


So how do I get rid of the loop bit and have it run only once every tick so it can go and fetch the right values? That be the easiest at this point. I tried to delete the loop bit, but I must be doing it wrong. It gets stuck. Next best option is to tell it to run the loop only once which I tried with (i = 0; i < 1; i++) That also fails, it gets stuck.


Any ideas on that?




It will depend on what A and B are. If their values are dependent on information related to the ticket, then it will need to go inside the loop, if not, then it's best outside. The loop is just going through the array that holds orders. If there is only one order, it will only run once, but if there are multiple orders, you will want to test all orders so run it completely. Your logic is when it comes across an order in the loop that isn't the correct one youi use return, which effectively stops the loop. Try using continue in place of return, that way, it stops doing more with the currently selected order and moves on to test the next one.

V

 

Thanks Viffer and Zzeugg.


All of that is a bit much for me, I was hoping I can get rid of the problem by just deleting the loop or commenting it out, like so:


// for (i = 0; i < OrdersTotal(); i++)


I don't need the loop as such. What I need is: If condition is true, close the next ordertype 0 and move on to the next thing.


Basically I need someone to take a knife to that first block of code and make it a if statement that runs once for this tick. And next tick again. And if it's not true just skips it.


I'd be very grateful if someone who knows what they're doing wielded that knife, I tried a few times, but it always just gets stuck.

 

If you're just trying to remove the loop, then conceptually (ie. I've not checked the rest of your code) do the following. This will attempt to close the order in position 0 each time your condition is triggered. It's not clear if it matters to you WHICH order gets closed as you've just mentioned "the next order".

Remove:

for (i = 0; i < OrdersTotal(); i++)

and change:

OrderSelect(i, SELECT_BY_POS);

to:

OrderSelect(0, SELECT_BY_POS);

CB

 

Thanks Cloudbraker,


i tried it like so:

{
// for (i = 0; i < OrdersTotal(); i++)
{

OrderSelect(0,SELECT_BY_POS);


The moment that for statement: // for (i = 0; i < OrdersTotal(); i++) is gone EA stops dead. Doesn't get past that. I'd have thought it just get on with it as well.


I can see it come in, does it checks and calcs, then all that's left to do is close some trades. Nada. Just doesn't get to it.
 

Have you inserted Print() statements to check, line by line, how far it is getting?

CB

 

No I didn't. But I got it to work this far, but now there's a new and unexpected problem. Damn thing won't close positive trades. As far as i can see I told it to close the next buy it finds. I'm not sure about that Orderselect I put in there, probably the wrong place, but for the life of me I can't see why it's refusing to close profitable trades....


if (OrderSymbol() == Symbol())
         { 
          if (OrderType() == 0) 
           {
            if (TradeBusy() < 0 && OrderType() == 0) 
             {
              Print(Symbol(), " Trade is still busy when attempting to close Buy trade");
              return(0);
             }
            Slip = MarketInfo(Symbol(), MODE_SPREAD) * Point;
            RefreshRates();
            OrderSelect (0,SELECT_BY_TICKET);
            Result = OrderClose(OrderTicket(), 0.01, Ask, Slip, Blue);
            if (Result < 1)
             {
              Print("Error ", GetLastError(), " While Closing Ticket ", OrderTicket(),
                    " Lots = ", OrderLots(), " Price = ", OrderClosePrice(), " Ask = ", Ask);
              TradeNotBusy();
              return(0); 
             }
            else
             {
              TradeNotBusy();
              return(0);
             } 
           }
         }  
       }  
 

Well for a start - you are right that the OrderSelect() is in the wrong place. It must be used prior to OrderSymbol(), OrderType() etc. otherwise these functions have the context of the PREVIOUSLY selected order.

CB

 

Thanks for trying to help CB,


But I give up. Reckon I'll take the day off and go hit the beach. My partner be back in touch by Monday, I'm sure he can fix it in like 3 seconds, I been at it a week. Even this should work. Why it doesn't is beyond my small brain. All that's out there is the loop, so it should just close one next buy order at a time if it doesn't get a busy signal.

  {      
        OrderSelect(0, SELECT_BY_POS);
        MyTicket = OrderTicket();
        if (OrderSymbol() == Symbol())
         {
          if (OrderType() == 0)
           {
            if (TradeBusy() < 0 && OrderType() == 0)
             {
              Print(Symbol(), " Trade is still busy when attempting to close Buy trade");
              return(0);
             }
            Slip = MarketInfo(Symbol(), MODE_SPREAD) * Point;
            RefreshRates();
            Result = OrderClose(MyTicket, 0.01, Ask, Slip, Blue);
            if (Result < 1)
             {
              Print("Error ", GetLastError(), " While Closing Ticket ", MyTicket,
                    " Lots = ", OrderLots(), " Price = ", OrderClosePrice(), " Ask = ", Ask);
              TradeNotBusy();
              return(0);
             }
            else
             {
              TradeNotBusy();
             }
           }
         }
       }
    
   } 
Reason: