Нужна помощь

 

Здравствуйте! Нужно вывести в журнал значение Bid с 5 знаками после запятой с задержкой 20 мин.

Вот мой код:


void OnTimer() {

         Sleep(20000);

         start();

      }


int start() {

         RefreshRates();

         int price = DoubleToStr(Bid, 5);

         Print("Цена - ", price);

        }


Выводит значение: Цена - 1. Хотя должно быть 1.23253

Как правильно сделать?

 

int это целое число, потому и округляет до единицы цену 1.23253

вам нужно число типа double тогда будет без округления 1.23253

https://docs.mql4.com/ru/basis/types/double

Вещественные типы (double, float) - Типы данных - Основы языка - Справочник MQL4
Вещественные типы (double, float) - Типы данных - Основы языка - Справочник MQL4
  • docs.mql4.com
Вещественные типы (или типы с плавающей точкой) представляют значения, имеющие дробную часть. В языке MQL4 есть два типа для чисел с плавающей точкой. Способ представления вещественных чисел в машинной памяти определен стандартом IEEE 754 и не зависит от платформ, операционных систем и языков программирования. Константы с плавающей точкой...
 
Vladimir Zubov:

int это целое число, потому и округляет до единицы цену 1.23253

вам нужно число типа double тогда будет без округления 1.23253

https://docs.mql4.com/ru/basis/types/double

нужен не дабл, а стринг)

 string price = DoubleToStr(Bid, 5);
 

Еще проще написать так. Функция Print() сама преобразует данные к нужному типу.

int start() 
{
    RefreshRates();
    Print("Цена - ", Bid);
}
 
labvic:

Здравствуйте! Нужно вывести в журнал значение Bid с 5 знаками после запятой с задержкой 20 мин.

Вот мой код:


void OnTimer() {

         Sleep(20000);

         start();

      }


int start() {

         RefreshRates();

         int price = DoubleToStr(Bid, 5);

         Print("Цена - ", price);

        }


Выводит значение: Цена - 1. Хотя должно быть 1.23253

Как правильно сделать?

Я думаю правильнее не использовать Sleep потому, что он "замораживает" программу. Мой вариант:

int OnInit()
  {
//--- create timer
   EventSetTimer(60*20);
      
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
      
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   RefreshRates();
   PrintFormat("Цена - %.5f",Bid);
  }
 
Dmitriy Gizlyk:

Я думаю правильнее не использовать Sleep потому, что он "замораживает" программу. Мой вариант:

Если можно, уточните, пожалуйста, что значит "замораживает"? И что делает OnTimer, который, выходит, что-то не замораживает тогда, когда Sleep замораживает. В чем преимущество OnTimer?

 
Vladimir:

Если можно, уточните, пожалуйста, что значит "замораживает"? И что делает OnTimer, который, выходит, что-то не замораживает тогда, когда Sleep замораживает. В чем преимущество OnTimer?

OnTimer функция, вызываемая по времени. Вызывается терминалом через время заданное при инициализации таймера функцией EventSetTimer. При этом, во время ожидания назначенного времени могут выполняться другие функции программы. Функция Sleep останавливает выполнение программы на заданное время. При этом останавливается выполнение и, соответственно, всех функций программы. Если это единственный функционал данной программы, то такой подход возможен в советнике, т.к. советники выполняются каждый в своём потоке. Индикаторы исполняются в общем потоке, и такой подход в индикатора может затормозить работу терминала. 
 
Dmitriy Gizlyk:
OnTimer функция, вызываемая по времени. Вызывается терминалом через время заданное при инициализации таймера функцией EventSetTimer. При этом, во время ожидания назначенного времени могут выполняться другие функции программы. Функция Sleep останавливает выполнение программы на заданное время. При этом останавливается выполнение и, соответственно, всех функций программы. Если это единственный функционал данной программы, то такой подход возможен в советнике, т.к. советники выполняются каждый в своём потоке. Индикаторы исполняются в общем потоке, и такой подход в индикатора может затормозить работу терминала. 

Спасибо, понятно и дельно.

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

А в случае Sleep как? Я всегда думал, что эта команда не связана с ситуацией в самом терминале, поток советника будет запущен по правилам ОС для очередей потоков за процессорным временем. Или основной поток терминала и в этом случае имеет какие-то особые права?

 
Vladimir:

Спасибо, понятно и дельно.

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

А в случае Sleep как? Я всегда думал, что эта команда не связана с ситуацией в самом терминале, поток советника будет запущен по правилам ОС для очередей потоков за процессорным временем. Или основной поток терминала и в этом случае имеет какие-то особые права?

Терминал всегда прав!!!

 
STARIJ:

Терминал всегда прав!!!

Пока не отвечает Dmitriy Gizlyk, попробую Выяснить вашу позицию. При запущенных 25 терминалах как исполняется OnTimer, если каждый экземпляр вправе его отложить по своим нуждам? Плюс ОС дает процессорное время время каждому терминалу только по очереди. Выходит, никакой он не OnTimer, срабатывает когда-нибудь? А как со Sleep? Понимаю, что других вариантов нет все равно, Windows вовсе не ОС реального времени и OnTimer  вне очереди никуда не влезет, но все же есть ли разница между использованием OnTimer и Sleep?

 
Vladimir:

Пока не отвечает Dmitriy Gizlyk, попробую Выяснить вашу позицию. При запущенных 25 терминалах как исполняется OnTimer, если каждый экземпляр вправе его отложить по своим нуждам? Плюс ОС дает процессорное время время каждому терминалу только по очереди. Выходит, никакой он не OnTimer, срабатывает когда-нибудь? А как со Sleep? Понимаю, что других вариантов нет все равно, Windows вовсе не ОС реального времени и OnTimer  вне очереди никуда не влезет, но все же есть ли разница между использованием OnTimer и Sleep?

Sleep полностью останавливает работу эксперта. То есть эксперт в это время ни как не реагирует на внешние раздражители (не обрабатывает приход новых тиков OnTick()). Если для вашего эксперта это не критично , и если учесть, что эксперт работает в отдельном потоке то можете применить Sleep. Если вы используете Sleep в индикаторе то  он остановит работу всех индикаторов, так как для индикатора отдельный поток не выделяется. И при больших значениях Sleep возникнет впечатление  что терминал завис.