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

 
Vladimir Pastushak:

Возможно ли отличить как то графический обьект созданный в ручную от обьекта который создан индикатором или советником ?

В функции 

OBJPROP_HIDDEN

Запрет на показ имени графического объекта в списке объектов из меню терминала "Графики" - "Объекты" - "Список объектов". Значение true позволяет скрыть ненужный для пользователя объект из списка. По умолчанию true устанавливается для объектов, которые отображают события календаря, историю торговли, а также для созданных из MQL5-программы. Для того чтобы увидеть такие графические объекты и получить доступ к их свойствам, нужно нажать кнопку "Все" в окне "Список объектов".

bool

Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Свойства объектов
Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Свойства объектов
  • www.mql5.com
Все объекты, используемые в техническом анализе, имеют привязку на графиках по координатам цены и времени – трендовая линия, каналы, инструменты Фибоначчи и т.д.  Но есть ряд вспомогательных объектов, предназначенных для улучшения интерфейса, которые имеют привязку к видимой всегда части графика (основное окно графика или подокна индикаторов...
 
Возможно, известная вещь, но сам такого нюанса не знал.

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

Библиотеки: 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));                 // Заставляем двигаться очередь.
}

Важное место в коде выделил. Без него применение шаблона не будет до окончания работы скрипта.

 
Про первый входной параметр в EventChartCustom

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

MT5 и скорость в боевом исполнении

Anton, 2020.10.08 11:00

Разный смысл и разный механизм выполнения. 0 - событие в очередь "своего" чарта. -1 - событие в собственную очередь.

 
Vladimir Pastushak:

Под конец недели не варит уже голова.

Есть тиккет открытой позиции на хедже в мт5 например 123456

Хочу посчитать прибыль после закрытия позиции, и что то никак не могу.

Делаю так, но получаю только комиссию...

Как получить прибыль закрытой позиции по тиккету?

Попробуйте лучше выбрать сделки с помощью  HistorySelectByPosition().

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

Надо было внутри одного mqh узнать, вызывалось ли что-то перед этим из другого mqh. При этом mqh не в курсе о наличии друг друга. Кто-то из них может быть в include, а кто-то - нет.

В общем, задача необычная (для меня). Решил ее довольно костыльным способом.

void f1()
{
  SetUserError(0);
}

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

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

Думаю, это очень плохая практика, но работает.

 
Если кому-то надо закрывать Alert-окно.
// Закрытие Alert-окна
bool CloseAlert()
{  
  const long Chart = ChartOpen(_Symbol, _Period);  
  const bool Res = Chart && !ChartSaveTemplate(Chart, NULL);
                            
  if (Chart)
    ChartClose(Chart);
    
  return(Res);  
}
 
fxsaber:

Надо было внутри одного mqh узнать, вызывалось ли что-то перед этим из другого mqh. При этом mqh не в курсе о наличии друг друга. Кто-то из них может быть в include, а кто-то - нет.

В общем, задача необычная (для меня). Решил ее довольно костыльным способом.

Думаю, это очень плохая практика, но работает.

Использование _LastError имеет одну неустранимую проблему, при подключении сторонних библиотек, имеется ненулевая вероятность коллизии пользовательских кодов ошибок. Как вариант вести свой lastError. Либо глобальную переменную заводить, обернутую в includeguard во всех mqh, либо одиночку.
 

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

MT5 и скорость в боевом исполнении

fxsaber, 2020.10.20 12:28

Промежуточный итог для быстрой не загруженной машины.

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

Тики и стаканы - тяжело быть в реал-тайме.

 
В MT5 Sleep(0) == Sleep(1). По этой причине не происходит огромной CPU-нагрузки при использовании Sleep(0), как в MT4.

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

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

Slava, 2018.09.20 15:40

PS. Функция Sleep() в MQL5 не является редиректом в win api функцию ::Sleep(). Вернее, при значении меньше 100 - это редирект. А больше 100 - уже цикл с вин апи слипом внутри, чтобы можно было прервать по IsStopped.

И ещё есть нюанс. При значении количества миллисекунд <=0 подставляется 1. То есть, мы никогда не вызываем ::Sleep(0)

Забылось уже. Верно только для MT5. В MT4 Sleep(0) может подвесить Терминал.

 
Была мысль переделать Virtual на указатели, чтобы не проверять на каждом вызове доп. условие.
  static double VirtualSymbolInfoDouble( const string Symb, const ENUM_SYMBOL_INFO_DOUBLE Property )
  {
    return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.SymbolInfoDouble(Symb, Property) : ::SymbolInfoDouble(Symb, Property));
  }


Но решил сначала сравнить производительность на простом примере.

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

#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, 1e7);
  
  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);
}


Результат.

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.


typedef-вариант проигрывает в три раза. Отказался от его использования там, где это критично. Наример, ТС тот же OrdersTotal вызывается не менее раза на каждом тике прохода в Оптимизаторе.


ЗЫ В дебаг режиме ситуация обратная. Так что под MT4 имеет смысл использовать typedef для ускорения.

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