Breaking the For Loop cycle. - page 3

 
Amir Yacoby #: Well, I left MQL4 as well as MQL3/2.. long time ago. Sorry for that, maybe I won't reply to those posts next time. Anyway, then we are left with OnTrade aren't we, which is more complicated.. Or the hand made methods to identify new orders like changes to OrdersTotal() etc.. Anyway, the loops are clearly not the way. 

No! OnTrade is also only available on MQL5.

In MQL4, "loops" are the only way, unless you track your own data.

 
Fernando Carreiro #:

No! OnTrade is also only available on MQL5.

In MQL4, "loops" are the only way, unless you track your own data.

Interesting. Yes, I'm normally good at finding a solution, hence I seldom need to ask on here, but this has had me stumped. A few other people have suggested to use the 

break;

after the function, but no dice. The trouble is, the result is the #4025 (Out of Memory) error, which isn't ideal. I completely get why it's doing what it's doing, it's just my lack of knowledge. If I do find solution, I'll post it on here so others can see.

 
Fernando Carreiro #:

No! OnTrade is also only available on MQL5.

In MQL4, "loops" are the only way, unless you track your own data.

Mql4 is such a waste of time.

But I can think on many ways without loops, even without OnTrade.

By loops I mean, doing them at each tick.

 
TheHonestPrussian #:

Interesting. Yes, I'm normally good at finding a solution, hence I seldom need to ask on here, but this has had me stumped. A few other people have suggested to use the 

after the function, but no dice. The trouble is, the result is the #4025 (Out of Memory) error, which isn't ideal. I completely get why it's doing what it's doing, it's just my lack of knowledge. If I do find solution, I'll post it on here so others can see.

I don’t understand why it has to be so complicated. One side saying it’s a “waste of recourses” but clearly you are doing it for educational purposes. The other side is saying mql4 is a waste of time. No chance for newbies to understand properly, no wonder why many get put off. 

Change s to s= 0
Change orders total to OrdersHistoryTotal() and leave it default. Increment using s++. 
Change Period to OrderMagicNumber()
Make sure the print is matched with the for loop command. 

After all your if conditions use the print statement, you should get a print statement continuously because in fact there are no orders. Let me know if this has changed anything. 

I’ve found that using variables that store a count works well with break and continue. 

 
Adj007 #:
I don’t understand why it has to be so complicated. One side saying it’s a “waste of recourses” but clearly you are doing it for educational purposes. The other side is saying mlq4 is a waste of time. No chance for newbies to understand properly, no wonder why many get put off. 

Change s to s= 0
Change orders total to OrdersHistoryTotal() and leave it default. Increment using s++. 
Change Period to OrderMagicNumber()
Make sure the print is matched with the for loop command. 

After all your if conditions use the print statement to find if this is true. Let me know if this has changed anything. 

I know, there'll always be a divide. I'll listen to anyone on here & give anyone the opportunity to contribute their knowledge. It may be helpful or it may not be. 

However, thank you for this, I'll give this a go and I'll report back on here.

Ciao ciao!  

 
TheHonestPrussian #:

Yep, I've changed this to a continue and it's still looping crazy, this s why this is infuriating me. 

TheHonestPrussian #:

...
I am now going to walk away from this for a few hours because I can feel my blood pressure rising. I will circle back to this later. 


Hello,

Yes I understand because programmers must have experienced that.
so I want to help by giving you a little clue.

Actually, your EA has done its job exactly according to the logic you wrote in the algorithm.
including the repeated printing of :

0       09:51:59.800    hammertime_5.0.1 AUDCHF,Daily: Symbol does not match
0       09:52:00.003    hammertime_5.0.1 CADJPY,Daily: Symbol does not match

..... 
0       09:52:00.467    hammertime_5.0.1 GBPJPY,Daily: Symbol does not match
0       09:52:00.745    hammertime_5.0.1 CADJPY,Daily: Symbol does not match

.. was correct and it should have repetition as such. 

I can't expect results outside of the algorithm we write in the program.
- by this way - you will definitely get a solution faster. 

What can I expect from your code here :

  1. I see there are 2 loops.
    (edit: I'm worry that you feel the code has 1 loop in for() only).

    1.1. The 1st. loop is OnTick(), and the 2nd. loop is for().
    1.2. The process in the second loop will be executed at every tick change.
     - - - (This method will burden the computer.)
    1.3.  What if the process in the second loop hasn't ended but the tick value has changed rapidly?
     - - - You've seen the 'out of memory'.

  2. Every time the tick price changes, the process will return to the first loop, OnTick().

  3. When OrdersTotal() is already contains a number greater than 0 ,
    (which means that there are trade positions) then the process enter the second loop
    - and display a message by Print();

  4. After the second loop finishes, (even if you use  'break;'  to attempt to stop the second loop),
    - the EA will always return to the first loop 'OnTick()' and immediately - re-enter the second loop again. 

  5. So the repetition of the message from the second loop is a certainty. 
    We can't deny that result, because it's the result it should be.

My conclusion, it looks like you want to create 1 EA that manages trading positions
of various _Symbols and magic numbers simultaneously.

Unfortunately you will have to find another way to read those trading positions properly.

In such a situation, I would use OnTimer() instead of OnTick(),
and combined with each new bar change.

Feel free to experiment through different processes across multiple loops in OnTimer().
I am sure you will like it :)

Kind regards,
Yohana

 
TheHonestPrussian: Morning, So I have a function which is designed to Select an order from the ledger through the OrderSelect(..) feature. It also selects the OrderSymbol(...) as well as the Magic Number(..). If any of these return False, it's supposed to return a Print Message (for demonstration purposes as seen below). I know how the For loop works, and I get that the OnTick() function is supposed to execute a function on every incoming tick, but despite me trying the break; function, the BarTime = Time[0], with the return; function, but I still get a continuous loop of the Print(...); function on every tick. What actually is the function which breaks the loop whoever any of these conditions fail?

If you are wanting to break out of a loop when ever a condition fails, then use "break" ...

void OnTick()
{
   bool bLoopBreak   = false;
   int  nTotalOrders = OrdersTotal();

   for( int iPos = nTotalOrders - 1; iPos >= 0; iPos-- )
   {
      if( OrderSelect( iPos, SELECT_BY_POS, MODE_TRADES ) )
      {
         if( OrderSymbol() == _Symbol)
         {
            if( OrderMagicNumber() == _Period )
            {
               //Do a function
            }
            else
            {
               Print("Magic Number does not match");
               bLoopBreak = true;  // Report that the loop was broken
               break;              // Break out of for loop
            }
         }
         else
         {
            Print("Symbol does not match");
            bLoopBreak = true;  // Report that the loop was broken
            break;              // Break out of for loop
         };
      }
      else
      {
         Print("The Order was not selected");
         bLoopBreak = true;  // Report that the loop was broken
         break;              // Break out of for loop
      };
   };
   
   Print( bLoopBreak ? "Loop has been broken"
                     : "Loop has ended normally" );
};

I don't agree with your "Period" usage for Magic Number, but I have left it in there anyway.

EDIT: Please note that the above is only for explaining the functionality of the "break". As for your overall logic, I don't quite understand what you are trying to achieve so I have not tackled that. Only the "break".

 
Fernando Carreiro #:

If you are wanting to break out of a loop when ever a condition fails, then use "break" ...

I don't agree with your "Period" usage for Magic Number, but I have left it in there anyway.

EDIT: Please note that the above is only for explaining the functionality of the "break". As for your overall logic, I don't quite understand what you are trying to achieve so I have not tackled that. Only the "break".

Thanks Fernando,

Yes, that's fair enough. The //Do a function is actually a Chart Button through the ObjectCreate() function, to close any open position but the button itself wasn't relevant for this particular topic and forum guidelines state to only keep to the relevant bits of the code to other don't have to look for this. 

The button itself is fine, but the reason for the For(..) Loop originally was;

  • because the button has the profit/loss in the text of the button, as illustrated below. It also changes colour from green to red depending on whether the position is in a profit or loss. Of course, the profit/loss is continually changing do this needed to be updated on every incoming tick, hence the For() loop,
  • the button was to only appear when a position has been opened, and the OrderSelect() returns TRUE. Once the button was clicked to close the position, the OrderSelect(...) should return TRUE (else return False with Print() error code), and the button would disappear. Once no positions were in the ledger, the button would disappear. 

However, I have come up with a solution which no longer uses the For(..) loop feature when the button is implemented on the chart, so as promised I will post on here shortly. Feel free to weigh in if you wish to. 
 

Files:
button.png  13 kb
 
Yohana Parmi #:


Hello,

Yes I understand because programmers must have experienced that.
so I want to help by giving you a little clue.

Actually, your EA has done its job exactly according to the logic you wrote in the algorithm.
including the repeated printing of :

.. was correct and it should have repetition as such. 

I can't expect results outside of the algorithm we write in the program.
- by this way - you will definitely get a solution faster. 

What can I expect from your code here :

  1. I see there are 2 loops.
    (edit: I'm worry that you feel the code has 1 loop in for() only).

    1.1. The 1st. loop is OnTick(), and the 2nd. loop is for().
    1.2. The process in the second loop will be executed at every tick change.
     - - - (This method will burden the computer.)
    1.3.  What if the process in the second loop hasn't ended but the tick value has changed rapidly?
     - - - You've seen the 'out of memory'.

  2. Every time the tick price changes, the process will return to the first loop, OnTick().

  3. When OrdersTotal() is already contains a number greater than 0 ,
    (which means that there are trade positions) then the process enter the second loop
    - and display a message by Print();

  4. After the second loop finishes, (even if you use  'break;'  to attempt to stop the second loop),
    - the EA will always return to the first loop 'OnTick()' and immediately - re-enter the second loop again. 

  5. So the repetition of the message from the second loop is a certainty. 
    We can't deny that result, because it's the result it should be.

My conclusion, it looks like you want to create 1 EA that manages trading positions
of various _Symbols and magic numbers simultaneously.

Unfortunately you will have to find another way to read those trading positions properly.

In such a situation, I would use OnTimer() instead of OnTick(),
and combined with each new bar change.

Feel free to experiment through different processes across multiple loops in OnTimer().
I am sure you will like it :)

Kind regards,
Yohana

Hi there,

Thanks for taking the time to comment.

You've no need to worry, I'm well aware that the loop is for every tick, not just the one :) 

Secondly, I'm not saying the EA is incorrect, I appreciate that this is down to my lack of knowledge and whilst I have been self-taught, have been coding for a number of years and do have a fully functioning EA, this particular feature is new so it's learning curve again. However, I have found a solution which I will post on here shortly. Feel free to weigh in if you wish.

All the best :)  

 
So, as promised, the solution:

<Global Variables>

int OnInit(){




}

void OnTick(){

for(int s = OrdersTotal()-1; s>=0; s--){
      
         if(OrderSelect(SELECT_BY_POS, MODE_TRADES)){
         
            if(positionProfit + positionCommission + positionSwap > 0.01){
         
               ObjectSetInteger(0,"ClosePosition", OBJPROP_BGCOLOR, clrGreen);
               
                  ObjectSetString(0,"ClosePosition", OBJPROP_TEXT,"Close Ticket #"+IntegerToString(OrderTicket(),0)+" with profit "+AccountCurrency()+DoubleToString(positionProfit + positionCommission + positionSwap,2));
               
                     ObjectSetInteger(0,"spread_indicator", OBJPROP_COLOR,clrGreen);
                     
         
            } else {
         
               ObjectSetInteger(0,"ClosePosition", OBJPROP_BGCOLOR,clrCrimson);
               
                  ObjectSetString(0,"ClosePosition", OBJPROP_TEXT,"Close Ticket #"+IntegerToString(OrderTicket(),0)+" with loss "+AccountCurrency()+DoubleToString(positionProfit + positionCommission + positionSwap,2));
               
                     ObjectSetInteger(0,"spread_indicator", OBJPROP_COLOR,clrCrimson);
            
            }
         
            if(OrderType() == OP_BUY){
                                                      
              if(positionProfit + positionCommission + positionSwap >= 0.01){
               
                 ObjectSetString(0,"pip_indicator", OBJPROP_TEXT,Symbol()+" +"+DoubleToString(pipDisplayLong,0));
                  
                    ObjectSetText("MovingText",Symbol()+" +"+DoubleToString(pipDisplayLong,0));
               
              } else {
         
                 ObjectSetString(0,"pip_indicator", OBJPROP_TEXT,Symbol()+" -"+DoubleToString(pipDisplayLong,0));
                  
                    ObjectSetText("MovingText",Symbol()+" -"+DoubleToString(pipDisplayLong,0));
            
              }
         
            } else if (OrderType() == OP_SELL) {
      
               if(positionProfit + positionCommission + positionSwap >= 0.01){
         
                  ObjectSetString(0,"pip_indicator", OBJPROP_TEXT,Symbol()+" +"+DoubleToString(pipDisplayShort,0));
                     
                     ObjectSetText("MovingText",Symbol()+" +"+DoubleToStr(pipDisplayShort,0));
         
               } else {
               
                  ObjectSetString(0,"pip_indicator", OBJPROP_TEXT,Symbol()+" -"+DoubleToString(pipDisplayShort,0));
                     
                     ObjectSetText("MovingText",Symbol()+" -"+DoubleToStr(pipDisplayShort,0));
      
               }
      
           }
                                                      
           if (positionProfit + positionCommission + positionSwap >= 0.01){
            
              ObjectSetInteger(0,"pip_indicator", OBJPROP_COLOR,clrGreen); 
               
                 ObjectSetInteger(0,"MovingText", OBJPROP_COLOR,clrGreen); 
      
           } else {
   
              ObjectSetInteger(0,"pip_indicator", OBJPROP_COLOR,clrCrimson); 
            
                 ObjectSetInteger(0,"MovingText", OBJPROP_COLOR,clrCrimson); 
      
           }
           
         ObjectSetString(0,"spread_indicator", OBJPROP_TEXT,DoubleToString((Ask - Bid) / _Point,0)+" /                          "+DoubleToString(OrderOpenPrice(), Digits)+" / "+DoubleToString(Bid,Digits)+" / "+DoubleToString(riskPercentageDisplay,2)+"%"); 
         
         } else {
         
            Print("Position was not selected");
         
         }
   
      }   
 }

if(...)
        if(...)
                if(...)
                        if(...){

                                bool result = OrderSend(...);

                                        if(result){
                                        
                                        ObjectCreate(0,"spread_indicator",OBJ_LABEL,0,0,0 );
      
         ObjectSetInteger(0,"spread_indicator", OBJPROP_XDISTANCE, 20);
         
            ObjectSetInteger(0,"spread_indicator", OBJPROP_XSIZE, 400);
            
               ObjectSetInteger(0,"spread_indicator", OBJPROP_YDISTANCE, 150);
               
                  ObjectSetInteger(0,"spread_indicator", OBJPROP_YSIZE, 100);
                  
                     ObjectSetInteger(0,"spread_indicator", OBJPROP_CORNER,CORNER_LEFT_UPPER);
                                 
                        ObjectSetInteger(0,"spread_indicator", OBJPROP_FONTSIZE,15);
                                 
      ObjectCreate("MovingText", OBJ_TEXT, 0,0,0);
     
         ObjectCreate(0,"ClosePosition",OBJ_BUTTON,0,0,0 );
             
            ObjectSetInteger(0,"ClosePosition", OBJPROP_XDISTANCE, 0);
  
               ObjectSetInteger(0,"ClosePosition", OBJPROP_XSIZE, 400);
        
                  ObjectSetInteger(0,"ClosePosition", OBJPROP_YDISTANCE, 20);
        
                     ObjectSetInteger(0,"ClosePosition", OBJPROP_YSIZE, 50);
        
                        ObjectSetInteger(0,"ClosePosition", OBJPROP_CORNER,CORNER_LEFT_UPPER);
         
                           ObjectSetInteger(0,"ClosePosition", OBJPROP_COLOR,clrWhite);
                                                                           
                              ObjectSetInteger(0,"ClosePosition", OBJPROP_FONTSIZE,10);
                  
      ObjectCreate(0,"pip_indicator",OBJ_LABEL,0,0,0);

         ObjectSetInteger(0,"pip_indicator", OBJPROP_XDISTANCE, 20);

            ObjectSetInteger(0,"pip_indicator", OBJPROP_XSIZE, 400);

               ObjectSetInteger(0,"pip_indicator", OBJPROP_YDISTANCE, 100);

                  ObjectSetInteger(0,"pip_indicator", OBJPROP_YSIZE, 50);

                     ObjectSetInteger(0,"pip_indicator", OBJPROP_CORNER,CORNER_LEFT_UPPER);
                                          
                        ObjectSetString(0,"pip_indicator", OBJPROP_FONT,"Impact");
                     
                           ObjectSetInteger(0,"pip_indicator", OBJPROP_BGCOLOR, clrNONE);
                  
                              ObjectSetInteger(0,"pip_indicator", OBJPROP_FONTSIZE,30);
                                                                                                            
      ObjectMove("MovingText",0,Time[0],Bid);
      
         ObjectSetString(0,"MovingText", OBJPROP_FONT,"Impact");  
      
            ObjectSetInteger(0,"MovingText", OBJPROP_FONTSIZE,20);                             

}


                                        }


}




}
Essentially, if result = true, the EA will insert a button, and start calling the functions from the top o the OnTick section so you have the running order profit/loss for that position, plus it changes colour from red to green (or vice-versa) if you go from loss to profits (or vice versa).

Feel free to feedback/discuss if you have a more efficient way of doing this, but obviously no obligation.
Reason: