
From Basic to Intermediate: IF ELSE
Introduction
The content presented here is intended solely for educational purposes. Under no circumstances should the application be viewed for any purpose other than to learn and master the concepts presented.
In the previous article, From Basic to Intermediate: Passing by Value or by Reference, we provided a practical and objective explanation of the concepts, risks, and precautions you should take when transferring data between different programs.
Based on that discussion, as well as the content covered previously, we can now begin to explore more advanced topics. This is because, in programming itself, we do not work solely with mathematical expressions. Doing so would not only be a tremendous waste of the computational power and factorization capabilities that a computer offers but would also limit the possibilities of what we can truly achieve.
Therefore, the prerequisite for understanding what will be explained from this point forward is to have a firm grasp of the concepts presented in the previous articles. If at any point you find yourself unsure about why something is happening, refer back to those articles and study them carefully. Avoid rushing through the learning process, follow the steps as they are presented.
That being said, before we begin the first of several topics covered in this and future articles, it is necessary to explain a term that will appear frequently when discussing statements. So, let's move on to the first topic of this article.
Defining What a Routine Is
Every programming language is defined within certain terms. To ensure clear understanding and accurate interpretation of the explanations provided, we must first define an essential term.
Figure 01
A block of code, as shown in Figure 01, begins with an opening brace and ends with a closing brace. Everything within this block should be considered as a single entity. Regardless of the number of lines or what is contained between the opening and closing braces, you should think of it as one cohesive unit. This unit is what we will refer to as a routine.
Now, pay close attention! A routine can be a block of code similar to what is shown below.
{ ExtAOBuffer[i] = ExtFastBuffer[i] - ExtSlowBuffer[i]; double sumAO = 0.0; for(int j = 0; j < FAST_PERIOD; j++) sumAO+=ExtAOBuffer[i - j]; ExtSMABuffer[i] = sumAO / FAST_PERIOD; ExtACBuffer[i] = ExtAOBuffer[i] - ExtSMABuffer[i]; if ( ExtACBuffer[i] >= ExtACBuffer[i - 1]) ExtColorBuffer[i] = 0.0; // set color Green else ExtColorBuffer[i] = 1.0; // set color Red }
It can also be any expression as given below.
ExtACBuffer[i] = ExtAOBuffer[i] - ExtSMABuffer[i];
Even a call to execute a function or procedure would fall into this category. In other words, all of these elements are what we will refer to as a routine. So, whenever we mention that a routine will be executed, understand that this could refer to anything from a function or procedure call to an entire block of code. This block may contain multiple expressions, procedure or function calls, and even other routines nested within the original routine. In short, expand your mind to infinity and beyond! Now that we have defined this term, we can begin.
The IF Statement: The Ultimate Control
Before we dive in, I'd like to offer a small disclaimer. While programming statements must be given in English, you, dear reader and future programmer, are not strictly required to use English-based statements. There are ways to work around this. However, for now, let's assume that you are just starting in programming. Don't worry too much about the specific terminology, focus on understanding the concept. Mastering concepts is far more valuable than simply memorizing statement lists or syntax rules.
But why did I call the IF statement the "ultimate control" in the title of this section? And why am I starting with IF? Couldn’t we begin with another statement? Well, yes, we could. However, if you truly understand how the IF statement works and apply what has been explained in previous articles, you will be able to do almost anything in programming. I say almost because there is another important concept to cover later. But that concept will be much easier to grasp if you first build a solid foundation with simpler commands, which we will explore soon. If you master the necessary concepts and apply them correctly, you will literally be able to create any program using only the IF statements, other operators, and variables. That's it. Nothing more. Sounds impossible, doesn't it? But I assure you, it's true. And with time, you'll see that this is really so.
For now, let's begin by understanding a fundamental aspect of the IF statement. IF literally means "IF". Whenever you encounter this statement, read it exactly is IF. This will make it much easier to grasp its meaning.
When executed, the IF statement evaluates a condition. This condition must always be understood as either true or false. ALWAYS. It doesn't matter what is being tested or analyzed. What determines whether the IF executes the routine inside it is whether the test condition evaluates to true or false. As discussed in previous articles, a condition is considered false if its value is zero and true if its value is anything other than zero. Contrary to what many believe, the IF statement does not necessarily require comparison operators such as greater than, less than, or equal to. It only needs to determine whether the condition is true or false. Nothing more.
To make this concept easier to digest, let's look at a simple example in action.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. char info = 10; 07. 08. Print(__FUNCTION__, " : #1 => ", info); 09. 10. if (info) 11. Print("True condition..."); 12. 13. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 14. } 15. //+------------------------------------------------------------------+
Code 01
When you execute this code, you will see something similar like this in MetaTrader 5:
Figure 02
Here, we are applying exactly what was explained earlier. In line six, we define a variable. Immediately after, in line eight, we print a message to analyze the current state of our data. However, in line ten, we introduce a control flow statement: this is the IF statement. Now, pay close attention, dear reader. If 'info' is equal to true, the routine inside the IF statement will be executed. If 'info' is false, the routine inside the IF statement will not be executed, and execution will continue with the next routine in the code. This way we can control and direct the flow of execution of our code. The next routine in this case is in line 13.
Since the value of 'info' is different from zero, the routine inside the IF statement is executed. As a result, we see the output shown in Image 02. There are some important considerations regarding how you should write this statement. Some of these are mandatory, while others are optional. However, the basic syntax of the IF statement is as follows:
Figure 03
From this, you can clearly see how the statement is executed. The syntax is straightforward and easy to understand.
Now, what if we don't want to execute the routine inside the IF statement when the condition is true, but instead when it is false? Is that possible? That is an excellent question! And it is precisely where many beginner programmers struggle, sometimes to the point of frustration. This happens because they don't understand the underlying concept of the statement. Let me emphasize once again: The IF statement will only execute the routine inside it if and only if the condition is true. Otherwise, the routine inside the IF statement will not be executed. "But wait! I've seen code where the routine inside the IF statement was executed even when the value was false. I think you don’t know what you’re talking about." Alright, let’s not argue about this. Instead, let’s put it to the test. We will create a simple program to verify whether this can actually happen. To do this, we will deliberately force a condition where the expression in the IF statement always evaluates to true. The code for this is shown below. How is this possible? You might have seen code where the routine inside the IF statement was executed even when the value was false. And you might think then I don't know what I'm talking about.
Let's not argue about this. Instead, let's do the following: we will create a simple program to verify whether this can actually happen. To do this, we will deliberately force a condition where the expression in the IF statement is always true. The code for this is shown below:
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 07. 08. if (true) 09. Print("True condition..."); 10. 11. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 12. } 13. //+------------------------------------------------------------------+
Code 02
Now you can see that the test in line 8 will ALWAYS be true. Therefore, line 9 will ALWAYS be executed, no matter how many times the code is executed. The ninth line will ALWAYS be executed. The result can be seen below:
Figure 04
It was mentioned earlier that you have seen the IF statement to run a routine when an expression was false. Okay, let's make the expression false and see what happens. This is shown in the following code:
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 07. 08. if (false) 09. Print("True condition..."); 10. 11. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 12. } 13. //+------------------------------------------------------------------+
Code 03
Notice that the only modification I made was to the expression inside the IF statement on line eight. However, when executing the code, the output is as shown in the image below.
Figure 05
Wait… where is the other line that appeared in Figure 04? Where did it go? Well, dear reader, it is missing in Figure 05 because it was never executed. This happened because the expression tested in line eight is false. And it will always be false. Since the condition is false, the routine inside the IF statement will never be executed. However, there is a small but crucial detail here, one that many overlook. Perhaps this is why you might have thought that a false condition could still trigger the routine inside the IF statement. This misunderstanding usually occurs when the result of an expression is somehow inverted, meaning that what was previously false becomes true, and vice versa.
Pay very close attention to this. The way you write your code can determine whether the final value is true or false. This kind of issue often frustrates programmers because, at first glance, an expression might seem correct. However, due to an internal factor, usually related to operator precedence, the expression may produce an unexpected result. The issue isn't a mathematical error but rather a logical error within the context of the IF statement. This is such an important topic that it deserves an entire article of its own. However, since it involves using additional statements and operators to fully understand it, I will postpone this discussion for now.
In the meantime, you can study this topic by referring to the documentation: Precedence Rules.
Even without diving into these rules, we can make a simple modification to the code. This change will allow the routine inside the IF statement on line eight to execute, even when the expression appears to be false. This is achieved by modifying the code as shown below:
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 07. 08. if (~false) 09. Print("True condition..."); 10. 11. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 12. } 13. //+------------------------------------------------------------------+
Code 04
By making this almost imperceptible change, we get the result shown below:
Figure 06
At first glance, when looking at Code 04 carelessly, we might assume that the tested expression is false. However, take note of the symbol preceding the reserved word false. In most cases, you will see the exclamation mark being used. But there are many other ways to achieve this. For example, knowing that the test always checks whether the value is equal to zero or not, you could write something like the following:
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 07. 08. if (false | true) 09. Print("A very crazy condition always true ..."); 10. 11. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 12. } 13. //+------------------------------------------------------------------+
Code 05
Upon executing this code, you will see the output displayed below:
Figure 07
I could continue showcasing multiple variations, but nothing beats experimenting on your own while fully understanding what is happening. With that, let's consider the IF statement covered and move on to the next control structure - one that wouldn't even exist without IF. I mean the ELSE statement. We will explore this in the next section.
ELSE Statement. It Doesn't Stand Alone
A common mistake among beginners, possibly due to the type of learning material they use, is attempting to use the ELSE statement in isolation. The ELSE statement, which could be explained as "otherwise" must always be paired with another statement. The statement that precedes ELSE depends on the programming language. Many assume that ELSE is always tied to an IF statement, but in SQL, for example, ELSE can be associated with a CASE statement. This may seem odd, but it's simply how the language was designed. So, don't assume that knowing one programming language automatically qualifies you to program in another. While some concepts are transferable, every language has its own nuances that must be understood.
If you've grasped the IF statement, understanding ELSE will be much simpler. When used alongside IF, the ELSE block executes only if the IF condition is false. That's essentially all there is to it. There's not much more to say about it.
However, let's take a look at execution flow, which will make things even clearer. The flowchart is shown below:
Figure 08
Upon examining Figure 08, you will notice that whenever an ELSE statement exists, it is always linked to an IF statement. While this concept may seem simple at first, in practice, it isn't always as straightforward. There are certain precautions you, dear reader, must take when using an IF statement with an ELSE block. We will cover these later in this article. But before that, why not have some fun modifying the previous code examples to include ELSE statements? I won't modify every example since that would be unnecessary given the simplicity of what we've covered so far. Instead, let's take one of the codes and modify it by adding an ELSE block.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. int info = 10; 07. 08. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway... #1 => ", info); 09. 10. if (info) 11. Procedure(info); 12. else 13. Print("Variable info is equal to zero..."); 14. 15. if (info) 16. Print("True condition..."); 17. else 18. Print("False condition..."); 19. 20. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway... #2 => ", info); 21. } 22. //+------------------------------------------------------------------+ 23. void Procedure(int & arg1) 24. { 25. Print(__FUNCTION__, " ", __LINE__, " #1 => ", arg1); 26. arg1 = 0; 27. Print(__FUNCTION__, " ", __LINE__, " #1 => ", arg1); 28. } 29. //+------------------------------------------------------------------+
Code 06
The code 06, which seems complicated at first glance, is actually much simpler and clearer than it might seem at first. And when we run code 06, we will get the result shown below:
Figure 09
Looking at Image 09, you might think: "This is a lot of information to process!" However, that's exactly why you should be even more motivated to focus and dive deeper. Let's break things down step by step to better understand how to use the IF-ELSE combination effectively.
First, in line 6, we create a variable that will be used throughout the code. In the eighth line, the first output line in Figure 09 is printed. If you've understood the IF statement, you already know what will happen in line 10. At this point, we may or may not execute the Procedure routine. To understand what's going on here, you need to understand what was explained in previous articles where we talked about variables. Eventually, execution reaches line 15, where one of two routines may be executed. Either way, we will output a new message to the terminal. Finally, we have line 20, which prints the last message visible in the terminal.
This Code 06 will be attached so you can experiment with small modifications. Here are some suggestions for tweaking the code. You can change the value of the variable in line 6 so that the test in line 10 results in a different routine being executed. Run the code after making this change to understand its behavior. You can then modify the IF conditions to alter how messages are printed. Adjust the conditions inside the Procedure routine to make the IF statement in line 15 behave differently. Each time you make a change, observe the result and analyze why it behaves the way it does. This practice will help you develop a strong grasp of the IF statement. This is crucial for understanding the control structures covered in future articles.
However, there is a small problem when using the IF ELSE combination. To solve this problem, let's start with a new topic.
The Nesting Problem
When using the IF-ELSE combination extensively, a nesting problem often arises. It occurs when multiple IF-ELSE blocks are embedded within each other, creating a cascade of conditions. However, this issue does not occur when only IF statements are nested, it's specifically a problem that arises when ELSE is introduced. That said, experienced programmers avoid excessive nesting of IF statements as well, as it generally leads to unreadable code. This design does not make much sense.
To help you visualize what I mean by nesting and cascading, consider the following example:
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. char c1 = 10, 07. c2 = 0, 08. c3 = -6, 09. c4 = 3; 10. 11. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 12. 13. if (c1) 14. if (c2) 15. if (c3) 16. if (c4) 17. Print("True condition..."); 18. 19. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 20. } 21. //+------------------------------------------------------------------+
Code 07
Here is a typical example of nested IF statements. You might be wondering, "What's wrong with coding like this?" Technically, nothing. However, experienced programmers rarely write code this way. Instead, they typically rewrite it using logical operators, producing a functionally equivalent but more readable version. A possible alternative to Code 07 is shown below:
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. char c1 = 10, 07. c2 = 0, 08. c3 = -6, 09. c4 = 3; 10. 11. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 12. 13. if ((c1) && (c2) && (c3) && (c4)) 14. Print("True condition..."); 15. 16. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 17. } 18. //+------------------------------------------------------------------+
Code 08
Observe that the output of Code 07 and Code 08 will be identical. However, in Code 08, the nested IF statements from Code 07 have been replaced with a chain of logical operations. In this case, we use AND operations. Any other type of operation will change the behavior of code 08, causing it to not generate the same result as code 07. If you are ever uncertain whether your code is behaving as expected, try rewriting it in a different format to ensure clarity.
However, the nesting problem does not only arise with cascades of IF statements. It is especially common in the IF and ELSE combination. But how does such a problem arise? I still don't quite understand this. So to understand this, we will use something similar to code 07, but add an ELSE statement. The resulting code is shown below:
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. char c1 = 10, 07. c2 = 0, 08. c3 = -6, 09. c4 = 3; 10. 11. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 12. 13. if (c1) 14. if (c2) 15. if (c3) 16. if (c4) 17. Print("True condition..."); 18. else 19. Print("False condition..."); 20. 21. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 22. } 23. //+------------------------------------------------------------------+
Code 09
At first glance, Code 09 looks quite similar to Code 07. However, here in code 09 we have a problem, and it's a big one. If you don't yet realize the scale of the problem, then you definitely need these articles to help you better understand how to build your programs.
The problem here is precisely the ELSE that is present on line 18. Let me ask you: To which IF statement does this ELSE belong?
Due to indentation, you might assume that the ELSE on line 18 is associated with the IF on line 14. While some programming languages do interpret it this way, many do not. In reality, in the vast majority indentation is used not as part of the functional code, but as a way to organize it to make it more readable.
In MQL5, indentation does not influence code execution; it only makes the code more readable. The ELSE code on line 18 in its current form is linked to the IF on line 16.
To solve this problem without making it too complicated and to explain how to fix it, I will show two possible solutions. One of them is preferred by most programmers, while the other is used by only a few. Let's start with the first one, the favorite of most programmers. This solution consists of dividing the code into blocks, which makes it clear to the compiler - this is exactly what exactly we want to do. It also makes the program more readable and understandable. This solution is shown below:
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. char c1 = 10, 07. c2 = 0, 08. c3 = -6, 09. c4 = 3; 10. 11. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 12. 13. if (c1) 14. if (c2) 15. { 16. if (c3) 17. if (c4) 18. Print("True condition..."); 19. } 20. else 21. Print("False condition..."); 22. 23. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 24. } 25. //+------------------------------------------------------------------+
Code 10
Actually, this is a great solution. Notice that in line 14 we have an IF that we want to link to an ELSE. To make sure that the subroutine, which will execute if the expression in line 14 IF is true, is correctly defined, we place it inside a block. Since we nested the entire IF sequence, the block starting at line 15 and ending at 19 is actually a subroutine that should be executed in the IF in line 14. This block can even be placed in a function or procedure outside the OnStart block.
It is very important, dear reader, that you understand this. If the IF statement in line 14 evaluates to false, the program will jump directly to the ELSE statement to execute the subroutine it contains. Note that the subroutine being executed can be anything, so it is important to understand the statement rather than just memorize syntax or programming styles.
Please note this fact. If you really understand the IF statement and know how to combine it with the ELSE statement, you will be able to use another solution for code 09. However, this type of solution has not gained widespread acceptance because in many cases it does not make the code truly understandable. But since we are working with didactic material and explaining how to proceed, we can link the ELSE, which is in line 18, with the IF in line 14. To do this, we simply chain other ELSE statements with other IF statements, as shown below:
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. char c1 = 10, 07. c2 = 0, 08. c3 = -6, 09. c4 = 3; 10. 11. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 12. 13. if (c1) 14. if (c2) 15. if (c3) 16. if (c4) 17. Print("True condition..."); 18. else; 19. else; 20. else 21. Print("False condition..."); 22. 23. Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); 24. } 25. //+------------------------------------------------------------------+
Code 11
Notice that in code 11, identifying the connection between the IF in line 14 and the ELSE, which is now line 20, is not as simple and clear. To understand this, you need to carefully analyze the code. However, both code 10 and code 11 will produce the same result when executed. That is, if the IF in line 14 is false, then the subroutine that is present in the corresponding ELSE will be executed.
Final considerations
In this article, we introduced control flow statements. I understand that these concepts may seem confusing at first. But with patience and consistent practice, where you find new solutions to problems you encounter, you will gradually achieve mastery – something that only a few attain.
However, to achieve this, it is necessary to constantly look for the best solution to the same problem. The fact that a problem has already been solved does not mean that there is no other more effective solution. There is always a better way. You still have to learn to see beyond the obvious.
Lastly, the attachment will not have all the codes you see here, only a subset of them will be available. However, you can still make any necessary changes after studying the article so that in the end you have all the codes presented here. In addition to being great practice for learning, the material will help you find your own style. After all, even if the code is the same, the way it is written may differ depending on the programmer and their style. So, it's time to define your programming style. Look for ways to make your code usable by other programmers while helping you quickly create and modify your own solutions.
Translated from Portuguese by MetaQuotes Ltd.
Original article: https://www.mql5.com/pt/articles/15365





- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use