Новая версия платформы MetaTrader 5 build 4755: общие улучшения - страница 8

 
Maxim Kuznetsov #:

short GetAsyncKeyState(VK_RBUTTON); // VK_LBUTTON, VK_...

Реализовал этот вариант. EventSetMillisecondTimer с периодичностью в 100 миллисекунд. Многократные регистрации нажатий клавиш мыши отсекаю с помощью bool переменных. Задержек не вижу. Полностью устраивает.

Спасибо за подсказку.

#import "user32.dll"
short GetAsyncKeyState(int vKey);
#import

#define VK_XBUTTON1 0x05 // mouse back button
#define VK_XBUTTON2 0x06 // mouse forward button

bool forwmb, backmb;

void OnTimer()
  {
        if(GetAsyncKeyState(VK_XBUTTON2) < 0){if(!forwmb){forwmb = true; ... return;}} else forwmb = false;
        if(GetAsyncKeyState(VK_XBUTTON1) < 0){if(!backmb){backmb = true; ... return;}} else backmb = false;
  }
 
Andrei Iakovlev #:

Реализовал этот вариант.

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

bool IsChartFocused()
  {
        return(bool(ChartGetInteger(0,CHART_BRING_TO_TOP) && user32::GetAncestor((HANDLE)::ChartGetInteger(0,CHART_WINDOW_HANDLE),2) == user32::GetForegroundWindow()));
  }
 
Andrei Iakovlev #:
(HANDLE)::ChartGetInteger(0,CHART_WINDOW_HANDLE)

по хорошему надо брать C/C++ вешать сюда хук и считывать требуемое без постоянных частых опросов и лишних перепроверок

все равно ведь получатся смесь из MQL+WinAPI, так зачем останавливаться на полумерах ;-)

 
Maxim Kuznetsov #:

по хорошему надо брать C/C++ вешать сюда хук и считывать требуемое без постоянных частых опросов и лишних перепроверок

Как это сделать? Можете код показать?

 
Andrei Iakovlev #:

Как это сделать? Можете код показать?

любой поисковик, первые-же ссылки

https://www.unknowncheats.me/wiki/C%2B%2B:WindowsHookEx_Mouse

и копать далее :-)

 
b4779, компилятор пропускает ошибку. При выполнении в дебаг-режиме происходит крэш терминала.
void OnStart()
{
  MqlTick Ticks[];
  MqlTick Tick;
  
  Ticks = Tick; // OK
}

Строка для поискаOshibka 124.

 
Господа-разработчики, а нельзя никак добавить возможность, чтобы алерты сохраняли тайминг? То есть выставил я алерт и указал - срок действия до завтрашнего дня. А дальше я беру следующий алерт и тоже хочу, чтобы он действовал до завтрашнего дня. Если алертов много - каждый раз неудобно им менять тайминг. 
 
EX5_4779 в два раза медленнее EX5_4410. Для адекватной оценки оптимизаций в коде приходится пользоваться b4410 на старом компиляторе.
 
Forester #:

Если за праздники должны браться свопы, значит это тоже баг MQ.
Тогда вот примеры, когда тестер MQ не взял свопы:
Рождество:

MQ


141 281 100000139 2015.12.23 17:58:35.000 2015.12.28 00:29:23.000 4d 06:30:48.000 218 543.00 EURUSD buy 1.00 1.08839

1.09704
-2.10 (-2.10)

Среда - понедельник. Должно быть 3+1+1 = 5 свопов.
MQ взяло 3 свопа.

По fxsaber формуле

141 141 100000139 2015.12.23 17:58:35.000 2015.12.28 00:29:23.000 4d 06:30:48.000 218 543.00 EURUSD buy 1.00 1.08839

1.09704
-3.50 (-3.50)

Взято 5 свопов, т.е. правильно.

Ну там вообще куча несовпадений в декабре-январе. Проще GIF анимацией показать:

Но до этого целый год было точное совпадение свопов. И потом еще год до  2016.11.28 совпадает. 

b 4787
Что-то в расчетах тестера поменялось, но не свопы. Все так же с этими ошибками.
 

b4790, код с if-проверкой выполняется на 20% быстрее, чем без этой проверки.


Т.е. такой код

if (Func()) // always true
  Calc();


выполняется быстрее этого.

Func();
Calc();


Воспроизведение (лаконичнее не получилось).

input int inAmountTicks = 1e7; // Количество тиков

#define VIRTUAL_ALTERNATIVE // Альтернативная скорость расчетов
#define VIRTUAL_SELECTORDERS_OBJECT // Работа с выбранныым окружением без указателей, отключает мультивалютку.
#define VIRTUAL_ORDERSELECT_WITHOUT_COPY // OrderSelect без копирования ORDER-структуры, отключает мультивалютку.

#include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/ru/code/22577
  
// Эмуляция истории тиков.
const MqlTick TickBase = {0, 0.57630, 0.57635};

void OnInit2()
{
  // Создали виртуальное окружение.
  if (VIRTUAL::SelectByHandle(VIRTUAL::Create(1000.0)))
  {    
    VIRTUAL::NewTick(TickBase);

    // Открыли постоянно висящие отложки и позиции.
    for (int i = 0; i < 40; i++)
    {
      OrderSend(_Symbol, OP_BUYLIMIT, 1, TickBase.ask, 0, 0, 0);
      OrderSend(_Symbol, OP_SELLLIMIT, 1, TickBase.bid, 0, 0, 0);
      
      OrderSend(_Symbol, OP_BUY, 1, TickBase.ask, 0, 0, 0);
      OrderSend(_Symbol, OP_SELL, 1, TickBase.bid, 0, 0, 0);
    }
  }
}

// Эмуляция OnTick.
double OnTick2()
{
  double Res = 0;
  
  for (uint i = OrdersTotal(); (bool)i--;)
  {
    if (OrderSelect(i, SELECT_BY_POS)) // Всегда true.
//    OrderSelect(i, SELECT_BY_POS);
      
      // Что-то считаем на каждом тике.
      Res += OrderMagicNumber() +
             OrderOpenPrice() +
             OrderTakeProfit() +
             OrderStopLoss() +
             OrderCloseTime();
  }
      
  return(Res);
}

// Эмуляция тестера.
double OnTester2()
{
  double Res = 0;
  
  // Прогоняем OnTick на каждом тике.
  for (uint i = inAmountTicks; (bool)i--;)
  {
    VIRTUAL::NewTick(TickBase);

    Res += OnTick2();
  }
      
  return(Res);
}

void OnStart()
{ 
  Print("Compiler Version: " + (string)__MQLBUILD__ + " " + __CPU_ARCHITECTURE__);
  
  OnInit2();
  
  // Замер времени выполнения.
  const ulong StartTime = GetMicrosecondCount();
  const double Res = OnTester2();
  Print(GetMicrosecondCount() - StartTime);
  Print(Res);
}


Результаты.

С if-проверкой OrderSelect (подсвечено в коде).

Compiler Version: 4790 X64 Regular
4087719
922120000.1033736


Без if-проверки OrderSelect (подсвечено в коде).

Compiler Version: 4790 X64 Regular
4974994
922120000.1033736


Второй вариант заметно медленнее. Где-то компилятор портачит. Проверил и на b4410 - воспроизводится.


ЗЫ К сожалению, исходник применяет КБ-библиотеку. Свежую версию скачать из КБ возможно только через пофайловое скачивание.


Строка для поискаOshibka 125.