Jump to content

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


Recommended Posts

Ugar68
1 час назад, Mighty Mouse сказал:

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

 

 

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

 

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

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

  • Thanks 1

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

Link to post
Share on other sites
  • Replies 7.6k
  • Created
  • Last Reply

Top Posters In This Topic

  • AntFX

    577

  • sergey1294

    569

  • Ugar68

    517

  • Programmer

    419

Top Posters In This Topic

Popular Posts

Ну, в данном случае мне стоило бы сразу соблюдать простейшие приёмы защитного программирования, то есть проверять, не равна ли нулю переменная, оказавшаяся под знаком деления. Ведь она "чужая", то ест

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

Основной советник выставляет "сигнальный" отложенный ордер далеко от текущей цены и каждую например, минуту модифицирует у него время экспирации: это может быть текущее время плюс 1 час, или плюс 1 су

Posted Images

Mighty Mouse
15 минут назад, Ugar68 сказал:

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

 

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

 

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

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

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

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

 

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

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

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

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


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

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
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

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


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

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

 

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

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

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

  • Thanks 1

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

Link to post
Share on other sites
DVargo

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

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

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

Edited by DVargo
Link to post
Share on other sites
DVargo

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

 

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

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

Edited by DVargo
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);

...

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

 

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

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

 

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

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

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

 

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

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

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


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

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

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

 

 

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

 


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

Мне - можно.

 

Link to post
Share on other sites
DVargo

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

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

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

Link to post
Share on other sites
Mighty Mouse

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

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

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

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

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

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

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

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


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

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

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

 

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

  • Upvote 1
Link to post
Share on other sites
DVargo

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

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

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

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

StringToCharArray

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

WinExec.mq4

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

 

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

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


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

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

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

 

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

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

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

 

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

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

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


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

Link to post
Share on other sites
  • 3 weeks later...
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));
	}
}

 

Link to post
Share on other sites
Mighty Mouse

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

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

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

 

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

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

 

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


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

Мне - можно.

 

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

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

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

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

 

1. Открывая расшарить для чтения. Тогда его можно читать любым просмотрщиком.

2. После открытия перед записью новых данных перенести курсор в конец файла. Тогда его можно смело закрывать.

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

Edited by Ugar68
  • Thanks 1

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

Link to post
Share on other sites
  • 4 weeks later...
Eugeny_Iv

Доброго дня.

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

Соответственно это видно как моментальное открытие-закрытие и попадаешь на спред((( Данный глюк происходит крайне редко и что характерно по утрам (время московское). Если у кого бывало такое - буду рад любой инфе.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    No registered users viewing this page.


×
×
  • Create New...