Features of the mql4 language, subtleties and techniques - page 2

 
Feel free to return GetPointer(this) from methods.

At least in method setters this is justified - the code may become more readable and compact, you get a la named parameters

ChartObject *hline=HLine::New(1.255).Color(clrGreen).Width(2).Selectable(true); // не надо помнить очерёдность параметров и можно писать в одну строку - цепочкой

// получается вот из подобного :
class HLine:public ChartObject {
public:
   HLine(double price);
   HLine *New(double _price) { return new HLine(_price); } // это чтобы не городить (new HLine(...)).Method1
   HLine *Color(color _clr) { fgColor=_clr; return GetPointer(this); }  // а это чтобы получались цепочки obj.Method1(..).Method2(..)
};
Of course, use with caution, because there are no exception`s in the language and are not expected

and a little bit interferes with the qualification of functions by the returned type.
 
Maxim Kuznetsov:
Feel free to return GetPointer(this) from methods.
This way &this is more concise.
 
fxsaber:
This way &this is more concise.
And GetPointer() can be carefully overridden, e.g. for debugging purposes.
 
A pointer taken by GetPointer cannot be deleted, what is the point of it?
 
// После этого в MQL4 будут компилироваться все библиотеки из MQL5\Include\Math
#property strict

#ifdef __MQL4__
  #include <Math\Alglib\bitconvert.mqh>  
  
  #define  TEMP_MACROS(A) double A( double ) { return(0); }
    TEMP_MACROS(MathLog1p)
    TEMP_MACROS(MathExpm1)
    TEMP_MACROS(MathArcsinh)
    TEMP_MACROS(MathArccosh)
    TEMP_MACROS(MathArctanh)
  #undef  TEMP_MACROS
#endif
 
Alexey Viktorov:
Well, let me start first.

To close an order, we do not have to define the order type and the price that corresponds to this type. It is enough to write "close at price" in OrderClosePrice()!

/********************Script program start function********************/
void OnStart()
{
   int i, total = OrdersTotal()-1;
    for(i = total; i >= 0; i--)
     {
      if(OrderType() < OP_SELLSTOP)
       {
        if(!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100))
        printf("***********");
       }
     }
}/********************************************************************/


Pretty cool! ) Thank you.

Judging by the example, you don't need OrderSelect() either?

 
Liza_:


(Cool! ) Thanks.

Judging by the example, OrderSelect() isn't needed either?

Yes, it is. Alexey just missed it due to his laziness...
 
Liza_:

Nice! ) Thanks.

Yes, it allows to write quite concise scripts for combat use
// Закрывает позиции, описание - https://www.mql5.com/ru/code/17943
sinput int RTOTAL = 4;            // Число повторов при неудачных сделках
sinput int SLEEPTIME = 1;         // Время паузы между повторами в секундах
sinput int Deviation_ = 10;       // Отклонение цены
sinput bool exAllSymbols = false; // false - только текущий, true - все символы

#define _CS(A) ((!IsStopped()) && (A))

bool CloseAllPositions( const bool AllSymbols = true, const int Slippage = 0 )
{
  bool Res = true;
  
  for (int i = OrdersTotal() - 1; _CS(i >= 0); i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL) &&
        (AllSymbols ? true : (OrderSymbol() == Symbol())))
      Res &= OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage);
      
  return(Res);
}

void OnStart()
{
  for (int i = 0; _CS((i < RTOTAL) && (!CloseAllPositions(exAllSymbols, Deviation_))); i++)
    Sleep(SLEEPTIME * 1000);
}
The comparison with MQL5-analogue is not in its favor. I wonder if there are situations where the comparison result is opposite...
 
Artyom Trishkin:
Needed. Just missed it due to laziness...

Yeah, well... Really messed up.

But before, I didn't come across these topics.

fxsaber:

So you can use OrderClosePrice only AFTER the corresponding OrderSelect. Since OrderSelect copies the data for Order(const)-functions once, and the same RefreshRates is not able to update them.

I.e. if, for example, OrderClosePrice fails to close, then you must do OrderSelect again before the next attempt (RefreshRates is not required).

ZS This thread is from 2005! There are detailed arguments from the developers here.

So you can use it, but with the understanding that there may be trouble.
 

Open orders should be analysed from a higher number, i.e. for(int nom=OrdersTotal()-1; nom>=0; nom--)
This is especially important when deleting orders.
But what will happen if we do the opposite for(int nom=0; nom<OrdersTotal(); nom++) ?
At first, the index is equal to zero and the very first order with number 0 is deleted.
Then the index becomes equal to 1. At this point the remaining orders are shifted and the one with number 1
occupies the zero position. The former number 2 takes position 1. It will be deleted.
Then the index becomes 2. And the order which was number 4 at the beginning will be deleted.
Thus, the orders which occupy even-numbered positions at the beginning are deleted. The odd-numbered ones will remain. This can be seen in the comments to the orders and numbers.
I attach a script showing both options of deleting and screenshots
There are 20 pending orders

Deleted one by one

Files:
PROBA-ORD.mq4  3 kb
Reason: