Trading Systems: How to Cut an EA Code for an Easier Life and Fewer Errors

 

New article How to Cut an EA Code for an Easier Life and Fewer Errors has been published:

A simple concept described in the article allows those developing automated trading systems in MQL4 to simplify existing trading systems, as well as reduce time needed for development of new systems due to shorter codes.

Author: Roman Kramar

 
thanks for a artical this.
 I do have a question , could you please make some explanation about this sentence
int orderDirection()
{
return( 1 - 2 * ( OrderType() % 2 ) );
}

what particulary "% 2" does here?
and what value contains "OrderType()" for buy and sell orders (1 or 2 or smth else)?
 
niniu:
thanks for a artical this.
 I do have a question , could you please make some explanation about this sentence
int orderDirection()
{
return( 1 - 2 * ( OrderType() % 2 ) );
}

what particulary "% 2" does here?
and what value contains "OrderType()" for buy and sell orders (1 or 2 or smth else)?

 

Yes... very interesting article and gives many ideas and methods for reducing code size of EA. However, I have one problem with the conclusion and it is that this invariant code style makes code harder to quickly "see at a glance" what's going on - imho. I totally agree with premises put forward, yet when code becomes effectively subjectively interpretive due to application of reader's own knowledgebase - I would suggest that issues can result. Either due to misunderstandings and hence how to effectively employ code or, due to misundersandings causing reader to modify/tweak code to fit in with their 'misunderstandings'. Regardless of issue, result is predictable - failure.

I am (in the scheme of software universe) very old... Simply put, I do not (cannot or will not) bother to remember what all my code does. It makes no difference if I write pages of comment or not - bottom line is the "see at a glance" moment in which I find myself reading the code. Sure, I believe code 'works' (eg, I have distant memories of having sweated over hot keyboard-lol) but I must know in that moment that I also trully understand the code now! This statement must go against the 'black box' paradigm, yes? eg, design, code, test, fully document and... forget just how the black box really functions! - just use it. Sure, great... but this is money on the table we are talking about, yes? That will make even me constantly look over my shoulder "just in case" something has been missed, not understood, etc.

Cobol  springs to mind! Very HLL indeed, yes? I know of many systems which suffered massive issues simply because of using such a HLL as Cobol. Nobody ever thought to look under the hood occasionally to make sure system firing on all cylinders... Inevitable issues of catastrophic nature resulted... always. Similarly, this articles approach is analog (imho) to Cobol and all the [potential] issues therein.

I do not agree this is more understandable: barPeakPrice( 1, -tradeDirection );

Each and everytime I would use, I would have to take time to figure out what "minus tradeDirection" actually did - enevitably leading me to again, always finding the code and figuring out step-by-painfull-step what the heck this code was doing! This is of course for me and others may be massively fleet of mind or worse still... just assume that all is a-ok.....

Similiarly, if( MacdCurrent * tradeDirection > 0 && ( MacdCurrent - SignalCurrent ) *
   
tradeDirection < 0 && ( MacdPrevious - SignalPrevious ) * tradeDirection > 0
    &&
MathAbs( MacdCurrent ) > ( MACDCloseLevel * Point ) )
compared to, if(MacdCurrent>0 && MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious &&
     
MacdCurrent>(MACDCloseLevel*Point))
is not imho very clear. Conditionals complexity increase is comparable to mental complexity increase in likelihood of meaningful understand... bottom line: BIG if() clauses cause many (not just me) to run away faster than the proverbial 'speeding bullet'... I do not buy into the thinking that speed is all important in EA coding. Have you ever monitored how many data ticks incoming there are per period? Missing a datum is not, I would argue, hazardous to equity. However, complex statements like above invariant  if() are massively hazardous to equity. Additionally, given the serious shortcommings with MQL4's parsing of conditionals (ie, NO early exit and all the implications therein of such mishandling of a universally understood (and expectedand practiced technique) I personally stay well clear of even hint of multi-clause if()'s. Is, of course, free world and each will do as wish... just not on my watch - that's all - lol.

Notwithstanding above - I reiterate that I have found this article most interesting and I will be taking on board, those snippets which I feel can benifit my EA robustness.

Thanking you  Крамарь Роман for article ;-)

((( Babel Fish gives me Kramar' the novel  but somehow not think correct? Constantly wish had learnt Russian - .ru forum is awesome, if somewhat cryptic for non Russians!!! )))

 

Hello  niniu, May I offer my interpretation/answer to your reply?:

OrderType() returns integer from 0..5 (see: https://docs.mql4.com/trading/ordertype and specifically https://docs.mql4.com/constants/tradingconstants/orderproperties)

"% 2" is division remainder mathmatical operation (% also called the modulus operator).  Example using OrderType() is: 0%2=0, 1%2=1, 2%2=0, 3%2=1, 4%2=0, 5%2=1;  Notice how result can only ever be 0 or 1.  Now, by multiplying 0 or 1 by 2 we get 0 or 2, yes? The final part of return() statement is: 1 - 0 or 1 - 2, yes?

Which resolves to 1-0=+1=long trade direction: +1  or  1-2=-1=short trade direction: -1

Meaning BUY/LONG OrderType()'s always cause function to return +1  and  SELL/SHORT OrderType()'s always cause function to return -1

HTH

 

My approach was similar but I like your IIF better. I used a function setDIR(int op) that set global variables now.open, now.close, and DIR to Bid/Ask, Ask/Bid, and +1/-1. Thus I could use now.open in OrderSend and now.close in stop loss calculations

Additionally I used two different stop losses so I needed a max function:

stopBars    = Low[Lowest(...)]...,
stopATR     = now.close -DIR* (SL.Trail.ATR*ATR.value + SL.Trail.Pips*pips2dbl),
SL          = MathMaxDIR(stop.bars, stopATR);
double  MathMaxDIR(double a, double b, double d=0){
    if (0 == d) d = DIR;
    if (d > 0)  return( MathMax(a,b) );     else    return( MathMin(a,b) ); }
double  MathMinDIR(double a, double b, double d=0){
    if (0 == d) d = DIR;
    if (d > 0)  return( MathMin(a,b) );     else    return( MathMax(a,b) ); }