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

 

Кстати, аналог Assert

#define ASSERT (STD_CAssert(__LINE__,__FUNCTION__)).Assert

class STD_CAssert{
   string function;
   int line;
public:
   STD_CAssert(int _line,string _func):line(_line),function(_func){}
   void Assert(bool condition,string text=NULL);
  };
//--------------------------------------------------------------------------
void STD_CAssert::Assert(bool condition,string reason=NULL){
   if (condition) return;
   Alert(StringFormat("Assert in line %i, function %s.\nReason: %s.",line,function,reason==NULL||reason==""?"Unknow":reason));
   int a=0;
   int b=1/a;}

void OnStart()
{
   Test();
}

void Test(){
   ASSERT(2==3,"Some reason");
}
 
Igor Makanu:

дык он то и нужОн очень!

если бы разработчики дали exit / abort штатный, тогда бы можно было корректно прерывать обработку данные если, к примеру, не готов ТФ - данные OHLC , для обработки отправки ордера на сервер тоже пригодилось бы... удобно в общем прервать код в любом месте и выйти до следующего тика не распутывая бесконечные return() к выходу из OnTick()

Так-то можно костылище изобразить, но совсем с юзабилити там плохо, даже показывать не буду, хотя должно работать.
 

Хотя и юзабилити вроде подтянуть получилось. В общем, каждый вызов функции или метода с возможным выходом, в том числе во вложенных функциях, оборачивать в макрос _call. Кому интересно, дальше сами для всех обработчиков пишите. Писано на коленке, как проверка идеи, так, что не тестилось, от слова - совсем.

#ifdef _DEBUG
   #define DELETE(dObj) do if (CheckPointer(dObj)!=POINTER_INVALID) {delete dObj; dObj=NULL;} while(false)
#else
   #define DELETE(dObj) do {delete dObj; dObj=NULL;} while(false)
#endif

#define START  class STD_CStart; void OnStart(){std_start=new STD_CStart; std_start.Main(); DELETE(std_start);}
#define ON_START  START\
static STD_CStart* std_start=NULL;  \
class STD_CStart{   \
public: void Main();   \
};                \
void STD_CStart::Main

#define DELETE_EVENTS do if (std_start!=NULL) DELETE(std_start); while(false)
#define EXIT(out) do {DELETE_EVENTS; return out;} while(false)
#define CHECK(out) do if (!std_start) EXIT(out); while(false)
#define _call(funk,out) do {funk;CHECK(out);} while(false)

ON_START()
{
   int x=0;
   Print("Start");
   _call(TestInt(4),);
   Print(++x);
   _call(TestInt(1),);
   Print(++x);
   _call(TestInt(6),);
   Print(++x);
   TestVoid();   
}

int TestInt(int a){
   static int x=0;
   Print("Func call ",++x);
   if (a<3) EXIT(NULL);
   return 0;
}

void TestVoid(){
   Print("Error");}
 

В MT5 нет никакой защиты от случайного закрытия Терминала. Недавно был такой сценарий.

  • Терминал и браузер раскрыты на все окно. Нахожусь в браузере.
  • Браузер завис, жму на крестик в правом-верхнем углу.
  • Не закрывается, жму еще несколько раз.
  • В определенный момент во время нажатий браузер закрывается - исчезает окно. И в это время крестик Терминала под курсором, куда жал.
  • Терминал закрывается, при этом настолько быстро, что это просто не заметно. Особенно, когда открыто много Терминалов.

Это очень неприятная ситуация во время, например, пакетной Оптимизации. Но еще хуже - для боевого советника. Можно тупо не заметить, что прикончил свой боевой Терминал.


Поставил такую защиту.

void OnDeinit( const int Reason )
{
  if (Reason == REASON_CLOSE)
    MessageBox("Terminal is being closed!");
}

При закрытии появляется сообщение на пять секунд. Поэтому можно понять, что на самом деле произошло. Странно, что в Терминале нет защиты.

 
fxsaber:

В MT5 нет никакой защиты от случайного закрытия Терминала. Недавно был такой сценарий.

  • Терминал и браузер раскрыты на все окно. Нахожусь в браузере.
  • Браузер завис, жму на крестик в правом-верхнем углу.
  • Не закрывается, жму еще несколько раз.
  • В определенный момент во время нажатий браузер закрывается - исчезает окно. И в это время крестик Терминала под курсором, куда жал.
  • Терминал закрывается, при этом настолько быстро, что это просто не заметно. Особенно, когда открыто много Терминалов.

Это очень неприятная ситуация во время, например, пакетной Оптимизации. Но еще хуже - для боевого советника. Можно тупо не заметить, что прикончил свой боевой Терминал.


Поставил такую защиту.

При закрытии появляется сообщение на пять секунд. Поэтому можно понять, что на самом деле произошло. Странно, что в Терминале нет защиты.

Есть несколько вариантов попроще.

  1. Боевой терминал держать свёрнутым.
  2. Боевой терминал держать на VPS
  3. Связать шаловливые ручки и не подходить к компьютеру. )))
  4. Надо думать, может чего и придумается...)))
 
Alexey Viktorov:

Есть несколько вариантов попроще.

  1. Боевой терминал держать свёрнутым.
  2. Боевой терминал держать на VPS
  3. Связать шаловливые ручки и не подходить к компьютеру. )))
  4. Надо думать, может чего и придумается...)))

На VPS тоже может закрыться. У меня там эксперты посылают Push.

А при торможении интерфейса винды действительно легко нажать не тот крестик. Я нарывался, теперь закрываю на таскбаре в контекстном меню.

 
Alexey Viktorov:

Есть несколько вариантов попроще.

Установить менеджер рабочих столов и выделить один рабочий стол под браузер и всякую муть, а для терминалов выделить другой рабочий стол.

Или установить Linux (менеджер рабочих столов идёт в комплекте :) )

 
Vladimir Simakov:

Кстати, аналог Assert

Для любой реализации утверждений на mql есть смысл использовать функцию DebugBreak для режима отладки. Очень облегчает жизнь при отладке и намного полезнее просто аварийного вылета.
 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Библиотеки: MT4Orders

fxsaber, 2020.04.07 18:47

В MT5 очень легко находить частичное исполнение.
// true - сделка в результате частичного исполнения.
bool IsPartial( const ulong TicketDeal )
{
  const ulong TicketOrder = HistoryDealGetInteger(TicketDeal, DEAL_ORDER);
  
  return((HistoryDealGetInteger(TicketDeal, DEAL_TYPE) <= DEAL_TYPE_SELL) &&
         (!TicketOrder ||
          (HistoryDealGetDouble(TicketDeal, DEAL_VOLUME) != HistoryOrderGetDouble(TicketOrder, ORDER_VOLUME_INITIAL))));
}
 

На хедже позиция может состоять из нескольких IN-сделок. Это происходит при частичном исполнении.

При этом ордер, что частично исполняется, меняет свой ORDER_TIME_SETUP(_MSC) на время исполнения первой (возможно, предпоследней) сделки. Т.е. по истории нельзя будет определить, когда, например, был выставлен BuyLimit.


Как следствие, позиция на хедже может иметь дробную цену открытия, как это часто можно наблюдать на неттинге.

Причина обращения: