Ваши вопросы по языку MQL4

star603

Новичок форума
MqlDateTime timeStruct1;//Структура даты содержит в себе восемь полей типа int.
MqlDateTime timeStruct2;//Структура даты содержит в себе восемь полей типа int.

C++:
//+------------------------------------------------------------------+
//|                                                       Sova 1.mq4 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
MqlDateTime timeStruct1;//Структура даты содержит в себе восемь полей типа int.
MqlDateTime timeStruct2;//Структура даты содержит в себе восемь полей типа int.
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(NewBar2()==true)
      Print("1");
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool NewBar()
  {
   bool new_bar = false;
   if(Open[0]==Close[0]==High[0]==Low[0])
      new_bar=true;
   else
      new_bar= false;
   return(new_bar);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool NewBar2()
  {
   bool new_bar = false;
   TimeToStruct(Time[0],timeStruct1);
   TimeToStruct(TimeCurrent(),timeStruct2);
   if(timeStruct1.day==timeStruct2.day && timeStruct1.mon== timeStruct2.mon)
      if(timeStruct1.hour== timeStruct2.hour && timeStruct1.min == timeStruct2.min && timeStruct1.sec == timeStruct2.sec)
         new_bar=true;
      else
         new_bar= false;
   return(new_bar);
  }

при втором варианте получается 9 и 11 марта 2015 по 2 раза почему-то :

C++:
2024.05.04 19:40:07.619    2015.03.19 00:00:00  Sova 1 EURUSD,Daily: 1
2024.05.04 19:40:06.599    2015.03.18 00:00:00  Sova 1 EURUSD,Daily: 1
2024.05.04 19:40:05.907    2015.03.17 00:00:00  Sova 1 EURUSD,Daily: 1
2024.05.04 19:40:04.930    2015.03.16 00:00:00  Sova 1 EURUSD,Daily: 1
2024.05.04 19:40:04.233    2015.03.13 00:00:00  Sova 1 EURUSD,Daily: 1
2024.05.04 19:40:03.524    2015.03.12 00:00:00  Sova 1 EURUSD,Daily: 1
2024.05.04 19:40:02.780    2015.03.11 00:00:00  Sova 1 EURUSD,Daily: 1
2024.05.04 19:40:02.772    2015.03.11 00:00:00  Sova 1 EURUSD,Daily: 1
2024.05.04 19:40:02.209    2015.03.10 00:00:00  Sova 1 EURUSD,Daily: 1
2024.05.04 19:40:01.775    2015.03.09 00:00:00  Sova 1 EURUSD,Daily: 1
2024.05.04 19:40:01.775    2015.03.09 00:00:00  Sova 1 EURUSD,Daily: 1

Почему так?
в первом варианте так быть должно Open[0]==Close[0] && High[0]==Low[0]
 

Ugar

Гуру форума
в первом варианте так быть должно Open[0]==Close[0] && High[0]==Low[0]
Это будет работать нестабильно.
Нельзя дробные значения сравнивать ==, <=, >= из за погрешностей вычисления и хранения double. Только < или >.
 

AlexeyVik

Программист mql4 mql5
Это будет работать нестабильно.
Нельзя дробные значения сравнивать ==, <=, >= из за погрешностей вычисления и хранения double. Только < или >.
Почему же? Нормализованную разницу можно сравнивать и на равенство нулю.
 

Ugar

Гуру форума
Почему же? Нормализованную разницу можно сравнивать и на равенство нулю.
Да, если нормализованное значение ещё нигде не хранилось. Я чаще использую немного другую формулу.
Вместо
Open[0]==Close[0]
Можно написать
NormalizeDouble(Open[0],_Digits)==NormalizeDouble(Close[0],_Digits)
А я не ищу лёгких путей и напишу так
fabs(Open[0]-Close[0])<0.5*_Point
 

AlexeyVik

Программист mql4 mql5
Да, если нормализованное значение ещё нигде не хранилось. Я чаще использую немного другую формулу.
Вместо
Open[0]==Close[0]
Можно написать
NormalizeDouble(Open[0],_Digits)==NormalizeDouble(Close[0],_Digits)
А я не ищу лёгких путей и напишу так
fabs(Open[0]-Close[0])<0.5*_Point
Нет Андрей. Эта строка
NormalizeDouble(Open[0],_Digits)==NormalizeDouble(Close[0],_Digits)
ничем не отличается от этой
Open[0]==Close[0]
В терминале все цены нормализованы и если с ними никаких математических действий не проводилось, то нормализация ничего не даст.
А вот это
fabs(Open[0]-Close[0])<0.5*_Point
совершенно правильно
Или можно написать так
if(NormalizeDouble(Open[0]-Close[0],_Digits) == 0.0)
 

star603

Новичок форума
Нет Андрей. Эта строка
NormalizeDouble(Open[0],_Digits)==NormalizeDouble(Close[0],_Digits)
ничем не отличается от этой
Open[0]==Close[0]
В терминале все цены нормализованы и если с ними никаких математических действий не проводилось, то нормализация ничего не даст.
А вот это
fabs(Open[0]-Close[0])<0.5*_Point
совершенно правильно
Или можно написать так
if(NormalizeDouble(Open[0]-Close[0],_Digits) == 0.0)
Я предлагаю такой вариант:

C++:
bool NewBar()
  {
   bool new_bar = false;
   double high = NormalizeDouble(High[0],Digits);
   double close = NormalizeDouble(Close[0],Digits);
   double low = NormalizeDouble(Low[0],Digits);
   double open = NormalizeDouble(Open[0],Digits);
   if(open==close && high==low)
      new_bar=true;
   else
      new_bar= false;
   return(new_bar);
  }
 

star603

Новичок форума
Да, если нормализованное значение ещё нигде не хранилось. Я чаще использую немного другую формулу.
Вместо
Open[0]==Close[0]
Можно написать
NormalizeDouble(Open[0],_Digits)==NormalizeDouble(Close[0],_Digits)
А я не ищу лёгких путей и напишу так
fabs(Open[0]-Close[0])<0.5*_Point
а откуда берется 0,5?
 

AlexeyVik

Программист mql4 mql5
Я предлагаю такой вариант:

C++:
bool NewBar()
  {
   bool new_bar = false;
   double high = NormalizeDouble(High[0],Digits);
   double close = NormalizeDouble(Close[0],Digits);
   double low = NormalizeDouble(Low[0],Digits);
   double open = NormalizeDouble(Open[0],Digits);
   if(open==close && high==low)
      new_bar=true;
   else
      new_bar= false;
   return(new_bar);
  }
Зря ты пытаешься мудрить. В одну миллисекунду могут прийти 2 и более тиков. Соответственно никак нельзя гарантировать, что советник сработает по первому тику. И отсюда следует, что все эти цены могут быть не равны.
Потом, постарайся объяснить, чем не устраивает общепринятый вариант с временем? Думаешь, что если разные велосипеды или автомобили это хорошо, то и функции определения нового бара тоже будет интересно?
И ещё: Я в предыдущем сообщении сказал, что в терминале все цены нормализованы и повторная нормализация, без математических действий с ними, абсолютно бесполезна и даже вредна. Лишняя нагрузка на процессор…
 

star603

Новичок форума
Подскажите как можно использовать енум переменную я думал так:

C++:
extern string period_graf == ENUM_TIMEFRAMES;

выдает вот это:

C++:
'==' - semicolon expected    Sova 1.mq4    27    27
 

AlexeyVik

Программист mql4 mql5
Подскажите как можно использовать енум переменную я думал так:

C++:
extern string period_graf == ENUM_TIMEFRAMES;

выдает вот это:

C++:
'==' - semicolon expected    Sova 1.mq4    27    27
ENUM_TIMEFRAMES это тип переменной. Такой же как int или double? только значения может принимать исключительно из перечисления.
 

star603

Новичок форума
ENUM_TIMEFRAMES это тип переменной. Такой же как int или double? только значения может принимать исключительно из перечисления.
Не подскажите как это засунуть в глобальную переменную чтобы использовать в пользовательских функциях и в коде?
 

ИванМН

Местный знаток
Дорогие программисты, это всегда так было, что функции OnDeinit() и OnTester() не вызываются в тестере МТ4 в случаях, когда прогон советника был завершён аварийно (например, при зависании советника), или это "чудесное" нововведение последней версии терминала от 1 мая? Я что-то точно не помню, но вроде подобного не замечал.

Спасибо.
 

vladradon

Программист
Дорогие программисты, это всегда так было, что функции OnDeinit() и OnTester() не вызываются в тестере МТ4 в случаях, когда прогон советника был завершён аварийно (например, при зависании советника), или это "чудесное" нововведение последней версии терминала от 1 мая? Я что-то точно не помню, но вроде подобного не замечал.
Вообще по-моему всегда так было. Если сов выскакивает аварийно при делении на 0 или при неправильной индексации массива, то он сразу прекращает работу в том месте, где произошла ошибка. В OnDeinit вообще нет варианта возврата причины при критической ошибке. А если сов завис, то он эти функции тем более не запустит, т.к. был где-то зациклен и аварийное прекращение работы будет в месте зависания и до других функций уже очередь не дойдет.
 

svitanak

Почетный гражданин
день добрый господа программисты. попросил ии написать простого советника.
при компиляции появляется ошибка и предупреждения.
подскажите пожалуйста, что не так? сам я в программировании ноль . решил что стоит попробовать определенные мысли
вот отрывок кода с ошибкой
{
for (int i = OrdersTotal() - 1; i >= 0; i--)
{
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
OrderClose(OrderTicket(), OrderLots(), Bid, 3, clrNone);
}
}
и вот сама ошибка показывается на картинке
 

Вложения

  • ошибка.jpg
    ошибка.jpg
    24 КБ · Просмотры: 20
  • ошибка 2.jpg
    ошибка 2.jpg
    39,5 КБ · Просмотры: 19

MakarFX

Элитный участник
день добрый господа программисты. попросил ии написать простого советника.
при компиляции появляется ошибка и предупреждения.
подскажите пожалуйста, что не так? сам я в программировании ноль . решил что стоит попробовать определенные мысли
вот отрывок кода с ошибкой
{
for (int i = OrdersTotal() - 1; i >= 0; i--)
{
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
OrderClose(OrderTicket(), OrderLots(), Bid, 3, clrNone);
}
}
и вот сама ошибка показывается на картинке
C++:
   for (int i = OrdersTotal() - 1; i >= 0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
         if(OrderClose(OrderTicket(), OrderLots(), Bid, 3, clrNONE)) Print("OrderClose");
        }
     }
 

star603

Новичок форума
Код:
   if(f_IsNewBar()==true)
     {
      if(Open[1]-Close[1]>0 && Open[2]-Close[2]>0 && Open[3]-Close[3]>0)
        {
         ticket2 = OrderSend(_Symbol,OP_BUY,UstLot(),Ask,Slippage,Stop(Magic),Prof(Magic),NULL,Magic,clrAqua);
         ticket1 = OrderSend(_Symbol,OP_SELL,UstLot(),Bid,Slippage,Stop(Magic),Prof(Magic),NULL,Magic,clrAqua);
         Print(ticket1,Stop(Magic),Prof(Magic));
         Print(ticket2,Stop(Magic),Prof(Magic));
        }

   OrderModyfiStop(Magic,Stop(Magic),Prof(Magic));
   if(trall==0)
      TrelingStop(Magic,Stop(Magic));
     }

Выдает:

Код:
2024.06.18 21:12:32.797    2005.02.07 00:01:00  Sova 1 EURUSD,Daily: 23
2024.06.18 21:12:32.797    2005.02.07 00:01:00  Sova 1 EURUSD,Daily: -1
2024.06.18 21:12:32.797    2005.02.07 00:01:00  Sova 1 EURUSD,Daily: OrderSend error 130
2024.06.18 21:12:32.797    2005.02.07 00:01:00  Sova 1 EURUSD,Daily: open #23 buy 0.05 EURUSD at 1.28551 ok


После того как порядок ордеров меняешь :
2024.06.18 21:03:58.386    2005.02.07 00:01:00  Sova 1 EURUSD,Daily: -1
2024.06.18 21:03:58.386    2005.02.07 00:01:00  Sova 1 EURUSD,Daily: 23
2024.06.18 21:03:58.386    2005.02.07 00:01:00  Sova 1 EURUSD,Daily: OrderSend error 130
2024.06.18 21:03:58.386    2005.02.07 00:01:00  Sova 1 EURUSD,Daily: open #23 sell 0.05 EURUSD at 1.28550 ok

сами по отдельности ордера открываются без проблем подскажите на что обратить внимание
 

Отслеживают (500) Посмотреть

Верх