Features of the mql5 language, subtleties and tricks - page 190

 
Vladimir Pastushak:

Is it possible to distinguish a manually created graphical object from an object created by an indicator or EA?

In the function

OBJPROP_HIDDEN

Barring the name of a graphical object from the terminal menu "Charts" - "Objects" - "List of Objects". The value true allows to hide an unnecessary object from the list. By default true is set for objects that display calendar events, trading history, as well asthose created from MQL5 program. To see suchgraphical objects and access their properties, click "All" in the "List of Objects" window.

bool

Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Свойства объектов
Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Свойства объектов
  • www.mql5.com
Все объекты, используемые в техническом анализе, имеют привязку на графиках по координатам цены и времени – трендовая линия, каналы, инструменты Фибоначчи и т.д.  Но есть ряд вспомогательных объектов, предназначенных для улучшения интерфейса, которые имеют привязку к видимой всегда части графика (основное окно графика или подокна индикаторов...
 
Probably a known thing, but was not aware of this nuance myself.

Forum on trading, automated trading systems and testing trading strategies

Libraries: Expert

fxsaber, 2020.10.09 04:55

bool ReloadChart( const long Chart )
{
  return (ChartSaveTemplate(Chart, "\\Files\\" + __FILE__ + ".tpl") &&
          ChartApplyTemplate(Chart, "\\Files\\" + __FILE__ + ".tpl") && // Поставили задание в очередь чарта.
          ChartGetInteger(Chart, CHART_WINDOW_HANDLE));                 // Заставляем двигаться очередь.
}

I have highlighted an important place in the code. Without it there is no application of the pattern until the end of the script.

 
About the first input parameter in EventChartCustom

Forum on trading, automated trading systems and trading strategy testing

MT5 and Speed in Action

Anton, 2020.10.08 11:00

Different meaning and different execution mechanism. 0 - event in queue of "own" chart. -1 - event in its own queue.

 
Vladimir Pastushak:

At the end of the week my head is already not good.

I have a ticket of an open position on a hedge in mt5 e.g. 123456

I want to calculate a profit after the position is closed, and I cannot do it.

I do so, but I get only commission...

How do I get the profit of a closed position with a ticket?

Try to better select trades using HistorySelectByPosition().

Документация по MQL5: Торговые функции / HistorySelectByPosition
Документация по MQL5: Торговые функции / HistorySelectByPosition
  • www.mql5.com
Не следует путать между собой ордера из торговой истории и действующие отложенные ордера, которые отображаются на вкладке "Торговля" в панели "Инструменты". Список ордеров, которые были отменены или привели к проведению торговой операции, можно посмотреть  в закладке "История" на панели "Инструменты" клиентского терминала. Функция...
 

It was necessary to find out inside one mqh whether something was called before from another mqh. The mqh is not aware of each other's presence. One of them may be in and one of them may not.

All in all, the problem is unusual (for me). Solved it in a rather crutchy way.

void f1()
{
  SetUserError(0);
}

void f2()
{
  if (_LastError == ERR_USER_ERROR_FIRST)
    Print("f1() была вызвана.");
  else
    Print("f1() не была вызвана");
}

void OnStart()
{
  f1();
  f2();
}

I think it's very bad practice, but it works.

 
If someone needs to close the Alert window.
// Закрытие Alert-окна
bool CloseAlert()
{  
  const long Chart = ChartOpen(_Symbol, _Period);  
  const bool Res = Chart && !ChartSaveTemplate(Chart, NULL);
                            
  if (Chart)
    ChartClose(Chart);
    
  return(Res);  
}
 
fxsaber:

It was necessary to find out inside one mqh whether something was called before from another mqh. The mqh is not aware of each other's presence. One of them may be in and one of them may not.

All in all, the problem is unusual (for me). Solved it in a rather crutchy way.

I think it's very bad practice, but it works.

Using _LastError has one unsolvable problem, when connecting third-party libraries, there is a non-zero probability of collision of user error codes. As an alternative to maintain your own lastError. Either a global variable, wrapped in includeguard in all mqh, or a single variable.
 

Forum on trading, automated trading systems and trading strategy testing

MT5 and Speed in Action

fxsaber, 2020.10.20 12:28

Intermediate summary for a fast unloaded machine.

The relevance of price data is very ambiguous for those who trade using bars and indicators.

Ticks and tumblers are hard to be in real time.

 
In MT5 Sleep(0) == Sleep(1). For this reason there is no huge CPU load when using Sleep(0) like there is in MT4.

Forum on trading, automated trading systems and trading strategies testing

Peculiarities of mql5, tips and tricks

Slava, 2018.09.20 15:40

PS. The Sleep() function in MQL5 is not a redirect to win api function ::Sleep(). To be more exact, if the value is less than 100, it is a redirect. But above 100 it is a loop with win api slip inside it so that it can be interrupted by IsStopped.

There is one more subtle point. If milliseconds <=0, we prepend 1. That is, we never call ::Sleep(0).

It has been forgotten already. True only for MT5. In MT4 Sleep(0) can suspend the terminal.

 
I had an idea to change Virtual to pointers so that I don't have to check additional condition on each call.
  static double VirtualSymbolInfoDouble( const string Symb, const ENUM_SYMBOL_INFO_DOUBLE Property )
  {
    return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.SymbolInfoDouble(Symb, Property) : ::SymbolInfoDouble(Symb, Property));
  }


But I decided to compare performance first, using a simple example.

// Сравнение производительности функции с доп. условием и указателя на функцию.

#include <fxsaber\Benchmark\Benchmark.mqh> // https://www.mql5.com/ru/code/31279

typedef double (*TFunc)( const int ); // Определяем нужный тип указателя на функцию.

double Prices[];

double GetPrices2( const int Pos )
{
  return(Prices[Pos]);
}

double GetPrices( const int Pos )
{
  return(Pos >= 0 ? GetPrices2(Pos) : 0); // Специально введено доп. условие, чтобы уменьшить производительность.
}

void OnStart()
{
  const int Size = ArrayResize(Prices, 1 e7);
  
  double Sum1 = 0;
  double Sum2 = 0;

  TFunc Func = GetPrices2;
    
  // Замер производительности через указатель функции.
  _BV(
  for (int i = 0; i < Size; i++)
    Sum2 += Func(i);
      , 1)


  // Замер производительности через функцию с доп. условием.
  _BV(
  for (int i = 0; i < Size; i++)
    Sum1 += GetPrices(i);
      , 1)  

  Print(Sum1);
  Print(Sum2);
}


The result.

2020.10.21 01:07:00.745 Test9 (AUDCAD,H1)       Alert: Bench_Stack = 0, 1 <= Time[Test9.mq5 29 in OnStart: for(inti=0;i<Size;i++)Sum2+=Func(i);] = 33906 mcs.
2020.10.21 01:07:00.756 Test9 (AUDCAD,H1)       Alert: Bench_Stack = 0, 1 <= Time[Test9.mq5 36 in OnStart: for(inti=0;i<Size;i++)Sum1+=GetPrices(i);] = 10923 mcs.


The typedef variant loses by a factor of three. I refused to use it where it is crucial. For example, for TC the same OrdersTotal is called at least once at every tick of optimizer pass.


In debug mode the situation is reversed. So, it makes sense to use typedef in MT4 for acceleration.