Особенности языка mql4, тонкости и приёмы работы - страница 2

 
Не стесняйтесь возвращать GetPointer(this) из методов.

По крайне мере в методах сеттерах это оправдано - код может стать читабельные и компактнее, получаются а-ля именованные параметры

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(..)
};
конечно, пользоваться с осторожностью, потому как exception`s в языке нет и не предвидится

и немного мешает квалификация функций по возвращаемому типу.
 
Maxim Kuznetsov:
Не стесняйтесь возвращать GetPointer(this) из методов.
Так &this лаконичнее.
 
fxsaber:
Так &this лаконичнее.
А GetPointer() можно аккуратно переопределять, например для целей отладки.
 
Указатель взятый по GetPointer нельзя удалять, смысл в нем?
 
// После этого в 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:
Ну, давайте начну первым.

Для закрытия ордера совсем не обязательно определять тип ордера и цену соответствующую этому типу. Достаточно написать закрыть по цене 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("***********");
       }
     }
}/********************************************************************/


Прикольно! ) Спасибо.

Судя по примеру, и OrderSelect() не нужен?

 
Liza_:


Прикольно! ) Спасибо.

Судя по примеру, и OrderSelect() не нужен?

Нужен. Просто пропустил Алексей по запарке...
 
Liza_:

Прикольно! ) Спасибо.

Да, это позволяет писать совсем лаконичные скрипты уже для боевого применения
// Закрывает позиции, описание - 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);
}
сравнение с MQL5-аналогом явно не в его пользу. Интересно, а есть ситуации, когда результат сравнения обратный...
 
Artyom Trishkin:
Нужен. Просто пропустил Алексей по запарке...

Да уж... Действительно лоханулся.

Но до того как, я не встречал этих тем.

fxsaber:

Так использовать OrderClosePrice можно только СРАЗУ после соответствующего OrderSelect. Т.к. OrderSelect копирует один раз данные для Order(const)-функций, а тот же RefreshRates их обновить не в состоянии.

Т.е. если, например, по OrderClosePrice закрыть не удалось, то нужно перед следующей попыткой сделать снова OrderSelect (RefreshRates не требуется).

 

ЗЫ Это тема аж 2005 года! Здесь подробные доводы разработчиков.

Так-что пользоваться этим можно, но с пониманием что возможны неприятности.
 

Открытые ордера надо анализировать с большего номера, т.е.   for(int nom=OrdersTotal()-1; nom>=0; nom--)
Особенно это важно при удалении ордеров.
А что же будет, если сделать наоборот                        for(int nom=0; nom<OrdersTotal(); nom++) ?
Сначала индекс равен нулю и удаляется самый первый ордер под номером 0.
Потом индекс становится равным 1. В это время оставшиеся ордера сдвигаются, и тот, что был с номером 1,
занимает нулевую позицию. Бывший номер 2 занимает позицию 1. Он и будет удален.
Потом индекс становится равным 2. И будет удален ордер, бывший в начале под номером 4. ...
Таким образом, удаляются ордера, занимавшие в начале четные позиции. А нечетные остаются. Это видно по комментариям к ордерам и номерам.
Прилагаю скрипт, демонстрирующий оба варианта удаления, и скриншоты
   Создано 20 отложенных ордеров

  Удалились через один

Файлы:
PROBA-ORD.mq4  3 kb
Причина обращения: