Jump to content
Programmer

Общие вопросы по языку MQL

Recommended Posts

Mighty Mouse

Можно ли сделать уведомление о событии заметным пользователю когда окно терминала свернуто или является фоновым?

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

  • Upvote 1

Share this post


Link to post
Share on other sites
Mighty Mouse

@Ugar68, наблюдаю в пятерке какую-то странную аномалию - при использовании MqlTick получаю нулевые значения для bid и ask.


 

Цитата

MqlTick last;

enum open_direction{Buy=0,Sell=1}; // направление позиции
input open_direction direction=0;

 

в OnTick пишу

 

      Print("last.bid = ",last.bid);
      Print("last.ask = ",last.ask);

 

   if(direction==0 && last.ask<=price_open )
      {
        if(!trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,V,price_open,0,0))
          Print("Метод PositionOpen() потерпел неудачу. Код возврата=",trade.ResultRetcode(),
            ". Описание кода: ",trade.ResultRetcodeDescription());
        else
         {
            if(trade.ResultRetcode()==10009)
               {
                  Print("Метод PositionOpen() выполнен успешно. Код возврата=",trade.ResultRetcode(),
                        " (",trade.ResultRetcodeDescription(),")");

               }
         }
      }

 

На выходе получаю 

 

Цитата

2019.07.22 15:58:42.053    position_open (EURUSDf,H1)    last.bid = 0.0
2019.07.22 15:58:42.053    position_open (EURUSDf,H1)    last.ask = 0.0
2019.07.22 15:58:42.147    position_open (EURUSDf,H1)    Метод PositionOpen() выполнен успешно. Код возврата=10009 (done at 1.12172)

 

Если проверки на ноль нет, то сов закупается на все деньги!

А если есть, то соотвественно не открывает ничего.

Проверил у двух разных ДЦ на демо, разница только в том что в Альпари в описании кода возврата так же стоит ноль, а не цена открытия

 

Цитата

2019.07.22 15:47:53.527    position_open (EURUSD,H1)    Метод PositionOpen() выполнен успешно. Код возврата=10009 (done at 0.00000)

 

Как это побороть?

 

  • Upvote 1

Share this post


Link to post
Share on other sites
Ugar68
1 час назад, Mighty Mouse сказал:

@Ugar68, наблюдаю в пятерке какую-то странную аномалию - при использовании MqlTick получаю нулевые значения для bid и ask.

 

 

Как это побороть?

 

MqlTick это всего лишь структура. То есть выделенная память для хранения, как массивы или переменные. Что то я в коде не вижу где цены помещаются в структуру. Где функция SymbolInfoTick()?

А вообще да, бывают моменты когда нет цен. Они не частые и кратковременные, но бывают. Лично я учитываю это в своих программах, когда пишу для себя или заказ платный. Но чаще всего я не видел что бы кто то учитывал это. Либо не знают об этих моментах, либо не считают нужным воротить лишний код, ведь это бывает редко. Решайте для себя, стоит ли задумываться о таких моментах.

  • Thanks 1

Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Share this post


Link to post
Share on other sites
Mighty Mouse
15 минут назад, Ugar68 сказал:

Что то я в коде не вижу где цены помещаются в структуру.

 

Я уже по справке догадался, меня удивило то что скачанный сов который я использовал для обучения работал без SymbolInfoTick и у меня раньше откуда-то актуальные цены брались, а вот откуда загадка. 

 

У меня еще выше вопрос был, что по этому поводу думаете?

Пока придумал только делать импорт MessageBoxW из user32.dll, есть ли еще какой вариант?

  • Upvote 1

Share this post


Link to post
Share on other sites
Ugar68
1 час назад, Mighty Mouse сказал:

У меня еще выше вопрос был, что по этому поводу думаете?

 

Пока придумал только делать импорт MessageBoxW из user32.dll, есть ли еще какой вариант?

Зачем лезть в dll? Чем не нравится родная MessageBox? Я попробовал скрипт их 2 строк

Sleep(5000);
MessageBox("Аууу!!!");

Запускаю скрипт сворачиваю терминал, окошко выскакивает.


Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Share this post


Link to post
Share on other sites
Mighty Mouse
31 минуту назад, Ugar68 сказал:

Чем не нравится родная MessageBox? Я попробовал скрипт их 2 строк

 

В индикаторах не работает, а в справке о том что  MessageBox там отключили не написано.

 

Еще вот подумалось после чтения кода из справки

Цитата

   if(SymbolInfoTick(Symbol(),last_tick))
     {
      Print(last_tick.time,": Bid = ",last_tick.bid,
            " Ask = ",last_tick.ask,"  Volume = ",last_tick.volume);
     }
   else 
      Print("SymbolInfoTick() failed, error = ",GetLastError());

 

может ли быть такой случай что SymbolInfoTick вернет false?

Как такой ответ правильно обработать?

 

 

  • Upvote 1

Share this post


Link to post
Share on other sites
Ugar68
3 часа назад, Mighty Mouse сказал:

Еще вот подумалось после чтения кода из справки

 

может ли быть такой случай что SymbolInfoTick вернет false?

Как такой ответ правильно обработать?

Правильно, если в справочнике написано что функция может вернуть false, значит сами метаквоты признают что может быть такая ситуация. Только в коде выше структуру зовут last, а здесь она last_tick.

И ещё, при открытии позиции, фигурирует переменная price_open, в ней должна быть Ask для Buy и Bid для Sell.

И ещё  if(direction==0 && last.ask<=price_open )  это зачем?

Думаю должно быть так

 if(direction==0)

{

price_open=last.ask;//Присвоили Ask переменной price_open для открытия Buy

дальше открывать позицию


Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Share this post


Link to post
Share on other sites
Ugar68
3 часа назад, Mighty Mouse сказал:

 

В индикаторах не работает, а в справке о том что  MessageBox там отключили не написано.

А это для индикатора. Тогда да, MessageBox не будет и не должна работать.

Если уж юзать dll я бы попытался свёрнутый терминал развернуть. Например с помощью ShellExecuteW из Shell32.dll.

  • Thanks 1

Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Share this post


Link to post
Share on other sites
DVargo
Posted (edited)

Дешевле (по затратам времени и надобностью углубления в процесс) сделать передачу нужного сообщения в советник, а из советника слать меседжи.

А с ShellExecuteW еще, возможно, разбираться придется.

Ведь не известно где MessageBoxW  была добыта.

Edited by DVargo

Share this post


Link to post
Share on other sites
DVargo
Posted (edited)

А есть еще такая вещь как алерт. Жаль что они не подходят.

 

Вообще можно придумать много всяких прибабахов - Excel интегировать с МТ, написать .ws или .vbs или куркулятор запустить и в нем написать

В конце-концов - запустить браузер и написать в нем крупными буквами

Edited by DVargo

Share this post


Link to post
Share on other sites
DVargo

Чего меня добивает с вин апи, то что функции иногда отказываются работать.

Вот ShellExecuteW работает.

А

#import "kernel32.dll"
int WinExec(string lpCmdLine,int uCmdShow);
string prg="C:\\.....exe";
#import

int start() {
if (!IsDllsAllowed()) {Alert("Вызов из библиотек (DLL) невозможен. Скрипт не может выполняться."); return(0);}
WinExec(prg,0);

...

ни как не хочет, чего поменяли, где поменяли не понятно.

 

Share this post


Link to post
Share on other sites
Mighty Mouse
23.07.2019 в 01:04, Ugar68 сказал:

Если уж юзать dll я бы попытался свёрнутый терминал развернуть. Например с помощью ShellExecuteW из Shell32.dll.

 

А сообщения в окне алерта можно как-то почистить чтобы старые не мешались?

Они ведь в каком-то массиве хранятся, только в справке не написано как это сделать.

  • Upvote 1

Share this post


Link to post
Share on other sites
Ugar68
11 часов назад, Mighty Mouse сказал:

 

А сообщения в окне алерта можно как-то почистить чтобы старые не мешались?

Они ведь в каком-то массиве хранятся, только в справке не написано как это сделать.

Никогда не интересовался этим вопросом. Судя по тому что при перезапуске терминала сообщения в алерте не сохраняются, они в файл не сохраняются.


Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Share this post


Link to post
Share on other sites
kazakov.v
23.07.2019 в 06:35, DVargo сказал:

ни как не хочет, чего поменяли, где поменяли не понятно.

 

 

Скорее всего со строками надо разбираться: str - wstr

 


Никому верить нельзя.

Мне - можно.

 

Share this post


Link to post
Share on other sites
DVargo

Я на сколько понял dll 16 битная - в 32 битной среде она работала, а в 64 битной не должна.

Главное не в этом - используя разные апи функции мы можем столкнутся с ситуацией, когда они перестанут работать, и система нам не назовет причин.

Но проблема решаема, всегда есть функции аналоги из других dll.

Share this post


Link to post
Share on other sites
Mighty Mouse

@Ugar68, хочу запилить мультивалютного индюка анализирующего несколько последних свечей на разных ТФ, самый главный из них закрытие часового бара. В OnCalculate для этого есть все что нужно, но придется ждать прихода нового тика, чего делать совсем не хочется. Если делать проверку раз в секунду в OnTimer, то возможна ситуация когда час уже начался, а бар еще не нарисован и способов прямого обращения к данным по дате у iOpen, iClose и тд нет, те возможна ошибка. 

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

Как лучше поступить?

  • Upvote 1

Share this post


Link to post
Share on other sites
Ugar68
6 часов назад, Mighty Mouse сказал:

@Ugar68, хочу запилить мультивалютного индюка анализирующего несколько последних свечей на разных ТФ, самый главный из них закрытие часового бара. В OnCalculate для этого есть все что нужно, но придется ждать прихода нового тика, чего делать совсем не хочется. Если делать проверку раз в секунду в OnTimer, то возможна ситуация когда час уже начался, а бар еще не нарисован и способов прямого обращения к данным по дате у iOpen, iClose и тд нет, те возможна ошибка. 

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

Как лучше поступить?

Не совсем понял проблему. Может она решится если сделать OnTimer чаще, например 3-5 раз в секунду? При инициализации использовать миллисекундный таймер.


Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Share this post


Link to post
Share on other sites
Mighty Mouse
6 часов назад, Ugar68 сказал:

Может она решится если сделать OnTimer чаще, например 3-5 раз в секунду? При инициализации использовать миллисекундный таймер.

 

Мне и одной секунды достаточно. Напрягает то что при начале нового часа очередная свеча появляется не сразу, а в зависимости от прихода котировок. Получается что предыдущий час уже закрыт, его можно обсчитывать, но какой у него порядковый номер 0 или 1 неизвестно. Что будет если в момент перехода рассчетов от одного бара к другому будет нарисована новая свеча? Пока не знаю как подступиться к этой теме.

  • Upvote 1

Share this post


Link to post
Share on other sites
DVargo

Да действительно проблема в строке

и нигде на это не ругается

правильная версия - решает часть поднятых проблем

На мт5 аналогично.

StringToCharArray

Посимвольно копирует преобразованную из unicode в ansi строку в указанное место массива типа uchar. Функция возвращает количество скопированных элементов.

WinExec.mq4

Share this post


Link to post
Share on other sites
Ugar68
9 часов назад, Mighty Mouse сказал:

 

Мне и одной секунды достаточно. Напрягает то что при начале нового часа очередная свеча появляется не сразу, а в зависимости от прихода котировок. Получается что предыдущий час уже закрыт, его можно обсчитывать, но какой у него порядковый номер 0 или 1 неизвестно. Что будет если в момент перехода рассчетов от одного бара к другому будет нарисована новая свеча? Пока не знаю как подступиться к этой теме.

Новый бар не открывается, пока не появился первый тик нового бара. Надо всегда сравнивать время открытия 0 бара всех символов участвующих в вычислении. Если время открытия разное, не рисовать. Либо рисовать, но когда время станет одинаковым, перерисовать на правильное.


Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Share this post


Link to post
Share on other sites
Mighty Mouse
5 часов назад, Ugar68 сказал:

Надо всегда сравнивать время открытия 0 бара всех символов участвующих в вычислении. Если время открытия разное, не рисовать.

 

По задумке индюк рисовать не должен, только делать вычисления и докладывать о результатах :)

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

Share this post


Link to post
Share on other sites
Ugar68
1 час назад, Mighty Mouse сказал:

 

По задумке индюк рисовать не должен, только делать вычисления и докладывать о результатах :)

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

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


Пишу советники и индикаторы по вашим алгоритмам. Пишите в личку.
Чужие программы не переделываю.

Share this post


Link to post
Share on other sites
ar2rk

  Привет форумчане! вопрос с работой окон через API.

  а, конкретней есть вопрос относящийся к функции GetAncestor библиотеки user32.dll

 имею следующий скрипт переинициализации индикаторов InitAllIndicators.mq4 - бросив его на график он вызывает окно "Список индикаторов" >> потом вызывает окно свойств индикатора >> нажимает кнопку "ОК" >> и закрывает.

 встала задача изменить работу скрипта так: что бы он делал тоже самое, но при условие что его бросаешь не на тот график где он должен отработать, а скажем на другой перед ним открытый(другого ТФ).

 вызов окна осуществляется импортом функции: 
   int GetAncestor(int hWnd, int gaFlags);
   #define GA_ROOT 2  
  //---------получаем дескриптор основного окна терминала с помощью MQL ф-ции WindowHandle()
    hParentWnd = GetAncestor(WindowHandle(Symbol(),Period()),GA_ROOT);

  на вид задача решалась уточнением: hParentWnd = WindowHandle(Symbol(),PERIOD_M1); но с таким вариантом я кидаю скрипт на М5 с задачей сделать переиниц-цию на М1. он вызывает окно "Список индикаторов" >> потом вызывает окно свойств индикатора >> и все дальнейшие действия не совершает.

 прошу помощи.

 

//+------------------------------------------------------------------+
//|                                            InitAllIndicators.mq4 |
//|                                 		 (C)opyright © 2008, Ilnur |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+

// Скрипт для переинициализации всех индикаторов, прикрепленных текущему окну.
// Для работы скрипта необходимо разрешить вызов функций из системных DLL:
// Сервис -> Настройки  -> Советники -> Разрешить импорт DLL.

#property copyright "(C)opyright © 2008, Ilnur"
#property link      "http://www.metaquotes.net"

#include <WinUser32.mqh>

#import "user32.dll"
	int GetAncestor(int hWnd, int gaFlags);
	int GetLastActivePopup(int hWnd);
	int GetDlgItem(int hDlg, int nIDDlgItem);
#import

#define PAUSE 4000

#define VK_HOME 0x24
#define VK_DOWN 0x28

#define GA_ROOT 2

#define TVM_GETCOUNT 0x1105

//+------------------------------------------------------------------+
//| Вызывает окно "Список индикаторов" и возвращает его дескриптор   |
//+------------------------------------------------------------------+
int GetListDialog(int hOwnedWnd)
{
	int hDlgWnd;
//---- вызываем окно "Список индикаторов"
	PostMessageA(hOwnedWnd,WM_COMMAND,35419,0);
	Sleep(PAUSE);
//---- определяем дескриптор окна
	hDlgWnd = GetLastActivePopup(hOwnedWnd);
//----
	return(hDlgWnd);
}

//+------------------------------------------------------------------+
//| Вызывает окно свойств индикатора и возвращает его дескриптор     |
//+------------------------------------------------------------------+
int GetPropertyDialog(int hOwnedWnd, int hListDlg)
{
	int hDlgWnd;
//---- вызываем окно свойств выбранного индикатора
	PostMessageA(hListDlg,WM_COMMAND,0x48B,GetDlgItem(hListDlg,0x48B));
	Sleep(PAUSE);
//---- определяем дескриптор окна
	hDlgWnd = GetLastActivePopup(hOwnedWnd);
//----
	return(hDlgWnd);
}

//+------------------------------------------------------------------+
//| Основная функция скрипта	                                     	|
//+------------------------------------------------------------------+
void start()
{
	int hParentWnd, hListDlg, hTreeView, hPropDlg;
	int nTreeCount;
//---- получаем дескриптор основного окна терминала
	hParentWnd = GetAncestor(WindowHandle(Symbol(),Period()),GA_ROOT);

	if(hParentWnd!=0)
	{
	//---- вызываем окно "Список индикаторов"
		hListDlg = GetListDialog(hParentWnd);
	//---- находим список индикаторов
		hTreeView = GetDlgItem(hListDlg,0x48C); //
	//---- определяем общую длину списка
		nTreeCount = SendMessageA(hTreeView,TVM_GETCOUNT,0,0);
	//---- устанавливаем курсор на верхней строчке списка
		PostMessageA(hTreeView,WM_KEYDOWN,VK_HOME,0);
	//---- в цикле перебираем весь список
		for(int i=1; i<nTreeCount; i++)
		{
		//---- смещаем курсор на следующую позицию списка
			PostMessageA(hTreeView,WM_KEYDOWN,VK_DOWN,0);
		//---- проверяем активность кнопки "Свойства"
			if(IsWindowEnabled(GetDlgItem(hListDlg,0x48B))==0) continue;
		//---- вызываем окно свойств выделенного индикатора
			hPropDlg = GetPropertyDialog(hParentWnd,hListDlg);
		//---- нажимаем кнопку "ОК"
			PostMessageA(hPropDlg,WM_COMMAND,0x001,GetDlgItem(hPropDlg,0x001));
		}
	//---- закрываем окно "Список индикаторов"
		PostMessageA(hListDlg,WM_COMMAND,0x001,GetDlgItem(hListDlg,0x001));
	}
}

 

Share this post


Link to post
Share on other sites
Mighty Mouse

@Ugar68, как лучше всего организовать работу с текстовым файлом?

Хочу каждый час записывать в него сообщения из индикатора, вот только просмотреть средствами винды этот лог невозможно, тк МТ блокирует файл.

Если программно закрываю лог, то при новом открытии он перезаписывается. 

 

Share this post


Link to post
Share on other sites
kazakov.v
2 часа назад, Mighty Mouse сказал:

просмотреть средствами винды этот лог невозможно, тк МТ блокирует файл.

 

Добавить флаг FILE_SHARE_READ


Никому верить нельзя.

Мне - можно.

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×