switch(SymbolType()) // Determine the type of currency pair and then determine the leverage of the instrument { case 1 : CalculatedLeverage=NormalizeDouble(MarketInfo(Symbol(),MODE_LOTSIZE)/MarketInfo(Symbol(),MODE_MARGINREQUIRED),2); break; case 2 : CalculatedLeverage=NormalizeDouble(MarketInfo(Symbol(),MODE_ASK)*MarketInfo(Symbol(),MODE_LOTSIZE)/MarketInfo(Symbol(),MODE_MARGINREQUIRED),2); break; case 3 : CalculatedLeverage=NormalizeDouble(2*MarketInfo(Symbol(),MODE_LOTSIZE)/((MarketInfo(CalculatedBasePairForCross,MODE_BID)+MarketInfo(CalculatedBasePairForCross,MODE_ASK))*MarketInfo(Symbol(),MODE_MARGINREQUIRED)),2); break; case 4 : case 5 : CalculatedLeverage=NormalizeDouble(MarketInfo(Symbol(),MODE_LOTSIZE)*(MarketInfo(CalculatedBasePairForCross,MODE_BID)+MarketInfo(CalculatedBasePairForCross,MODE_ASK))/(2*MarketInfo(Symbol(),MODE_MARGINREQUIRED)),2); break; case 6 : Print("Error occurred while identifying SymbolType(), calculated SymbolType() = ",CalculatedSymbolType); break; default : Print("Error encountered in the SWITCH routine for calculating Leverage on financial instrument ",Symbol()); // The expression did not generate a case value }Note that both case 4 and case 5 would run the same statement and break at the same point out of the switch. There is no reason to repeat the statement twice.
In more complex examples, where there are many OR's, the switch case would look much cleaner than the equivalent IF code.
Regarding the speed - in most cases the 'switch/case' is slightly faster. In other programming languages the difference is usually bigger...
I guess MQL4's implementation is not as efficient. We can check your specific example (attached file) and the result for running each version 1,000,000 times:
2010.04.28 08:56:15 SpeedTest GBPUSD,H1: SWITCH time: 2547mSec 2010.04.28 08:56:12 SpeedTest GBPUSD,H1: IF time: 2687mSec // on a different chart: 2010.04.28 08:57:11 SpeedTest EURCHF,H1: SWITCH time: 3813mSec 2010.04.28 08:57:08 SpeedTest EURCHF,H1: IF time: 3906mSecNot a big difference... But faster.
Gordon, you the man! What an awesome robust answer to my question. (complete with the code for doing speed-tests, I had never seen this before, did not know it was possible)
So definitely the preference falls to using Switch instead of If in many portions of my code, certainly no reason to avoid it. And thanks for bringing the "OR" option to my attention. Code clarity always helps me save time in debug so the more whitespace the better.
Gordon, you the man!
Both of you guys 'rule' in MQL4 !
You and others like you that are a small minority here and are definitely an assert to this forum.
We're losing more and more competent people such as yourself that are the backbone of support here for us NuBs and average coders in MQL4 to, quite understandably, MQL5.
This is very significant as MQ definitely doesn't provide didily squat for support to end users.
Is it considered "bad form" or ill-advised to leave out the "default" case in a switch? For those situations in which I know the switch will always result in an explicitly defined case can I forego the "default" case and keep my code all the cleaner?
example with unncessary "default" case included:
switch(CalculatedSymbolType) // Determine the tickvalue for the financial instrument based on the instrument's SymbolType (major, cross, etc) { case 1 : Print("Calculated TICKVALUE = ",DoubleToStr(MarketInfo(Symbol(),MODE_POINT)*MarketInfo(Symbol(),MODE_LOTSIZE)/MarketInfo(Symbol(),MODE_BID),6)," (Tick value in the deposit currency - base)"); break; case 2 : Print("Calculated TICKVALUE = ",DoubleToStr(MarketInfo(Symbol(),MODE_POINT)*MarketInfo(Symbol(),MODE_LOTSIZE),6)," (Tick value in the deposit currency - counter)"); break; case 3 : Print("Calculated TICKVALUE = ",DoubleToStr(MarketInfo(Symbol(),MODE_POINT)*MarketInfo(Symbol(),MODE_LOTSIZE)/MarketInfo(CalculatedCounterPairForCross,MODE_BID),6)," (Tick value in the deposit currency - ",AccountCurrency()," is Base to Counter)"); break; case 4 : Print("Calculated TICKVALUE = ",DoubleToStr(MarketInfo(Symbol(),MODE_POINT)*MarketInfo(Symbol(),MODE_LOTSIZE)/MarketInfo(CalculatedCounterPairForCross,MODE_BID),6)," (Tick value in the deposit currency - ",AccountCurrency()," is Base to Counter)"); break; case 5 : Print("Calculated TICKVALUE = ",DoubleToStr(MarketInfo(CalculatedCounterPairForCross,MODE_BID)*MarketInfo(Symbol(),MODE_POINT)*MarketInfo(Symbol(),MODE_LOTSIZE),6)," (Tick value in the deposit currency - ",AccountCurrency()," is Counter to Counter)"); break; default : Print("Error encountered in the SWITCH routine for calculating tickvalue of financial instrument ",Symbol()); // The expression is not needed as CalculatedSymbolType is guaranteed to only ever be a value of 1 through 5 }same switch without the "default" case:
switch(CalculatedSymbolType) // Determine the tickvalue for the financial instrument based on the instrument's SymbolType (major, cross, etc) { case 1 : Print("Calculated TICKVALUE = ",DoubleToStr(MarketInfo(Symbol(),MODE_POINT)*MarketInfo(Symbol(),MODE_LOTSIZE)/MarketInfo(Symbol(),MODE_BID),6)," (Tick value in the deposit currency - base)"); break; case 2 : Print("Calculated TICKVALUE = ",DoubleToStr(MarketInfo(Symbol(),MODE_POINT)*MarketInfo(Symbol(),MODE_LOTSIZE),6)," (Tick value in the deposit currency - counter)"); break; case 3 : Print("Calculated TICKVALUE = ",DoubleToStr(MarketInfo(Symbol(),MODE_POINT)*MarketInfo(Symbol(),MODE_LOTSIZE)/MarketInfo(CalculatedCounterPairForCross,MODE_BID),6)," (Tick value in the deposit currency - ",AccountCurrency()," is Base to Counter)"); break; case 4 : Print("Calculated TICKVALUE = ",DoubleToStr(MarketInfo(Symbol(),MODE_POINT)*MarketInfo(Symbol(),MODE_LOTSIZE)/MarketInfo(CalculatedCounterPairForCross,MODE_BID),6)," (Tick value in the deposit currency - ",AccountCurrency()," is Base to Counter)"); break; case 5 : Print("Calculated TICKVALUE = ",DoubleToStr(MarketInfo(CalculatedCounterPairForCross,MODE_BID)*MarketInfo(Symbol(),MODE_POINT)*MarketInfo(Symbol(),MODE_LOTSIZE),6)," (Tick value in the deposit currency - ",AccountCurrency()," is Counter to Counter)"); break; }Is this considered broken code or bad programming for any reason?
Thanks for quick response, so it is advisable from a debug standpoint. Yeah I'll keep it then. Since I am only just now getting into using switches I figured I'd ask now so I develop the right/preferred usage habit from time-zero. I like that, "can't harm", works for me.
Some bits from wiki:
Also why haven't I seen nested Switch used ?
Regarding the speed - in most cases the 'switch/case' is slightly faster. In other programming languages the difference is usually bigger...
I guess MQL4's implementation is not as efficient. We can check your specific example (attached file) and the result for running each version 1,000,000 times:
Not a big difference... But faster.
I'm a little suspicious that your timing difference is due to variations in the speed of external calls such as MarketInfo(). I've tried a comparison of if versus switch without such external calls or activity, and I'm very unsure that I'm seeing a non-random difference between the two routes. If forced to make a declaration on the basis of my testing, I'd hazard a guess that switch is very slightly faster than your if statements, but is not as fast as the following:
if (x == 0) { } else if (x == 1) { } else if (x == 2) { } etc
But the differences I'm seeing are so tiny that I'd unquestionably prefer - subjective - readability over any notional speed gain.
EDIT: and, stating the obvious, any speed difference between if and switch is almost always going to be trivial compared to other available optimisations. For example, caching the values of MODE_LOTSIZE and MODE_MARGINREQUIRED.
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
I've long used sequential/successive "if" assessment logic in my codes but have wondered what value programming with switch/case holds over that of an "if" block.
versus the same logic implemented in switch/case coding:For example, here is a successive "if" analysis routine:
What are the benefits of implementing switch/case versus implementing successive if/else code? Is one style less expensive in terms of cpu cycles?