Примеры: Особенности работы с числами типа double в MQL4 - страница 2

 

Цитата:

"Для проверки результатов расчетов и отладки программ можно использовать функцию string DoubleToStrMorePrecision(double number, int precision); стандартной библиотеки stdlib.mq4, которая позволяет проконтролировать численные значения чисел типа double до указанного знака. "
Конец цитаты.

Не нашел в справке ничего по функциям:

----------------------------------------------------------------------------

#import "user32.dll"
int MessageBoxA(int hWnd, string lpText, string lpCaption, int uType);

#import "stdlib.ex4"
string ErrorDescription(int error_code);
int RGB(int red_value, int green_value, int blue_value);
bool CompareDoubles(double number1, double number2);
string DoubleToStrMorePrecision(double number, int precision);
string IntegerToHexString(int integer_number);

---------------------------------------------------------------------------

Случайно наткнулся на эту статью. Что это за функции и с чем их едят?

У меня есть полное описание "TurboC 2.0" в пяти томах. Там всё есть, от структуры меню и команд редактора, до описания каждой функции и возможных ключей к этим функциям. Для MetaTrader4, есть полное описание одним-двумя файлами "в электронном" виде?

 

О некорректном исполнении кода.

При тестировании Эксперта выявились ошибки исполнения кода:
- исполнение оператора цикла for(i=0;i<OrdersTotal();i++) прерывается следующим тиком,
- ордера buy выбираются и закрываются в произвольном порядке.

Подскажите, пожалуйста, как установить и устранить их причину?
Код программы и отчёт из журнала тестера прилагаю.

С уважением.  Vladislav.

Код программы.

//+------------------------------------------------------------------+
//|                                                     Poligon1.mq4 |
//|                        Copyright 2012, MetaQuotes Software Corp. |
//|Тест оператора цикла.                                             |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, MetaQuotes Software Corp."
#property link      ""
//+------------------------------------------------------------------+
//|Объявленные переменные                                            |
//+------------------------------------------------------------------+
int Mn=357;//Magic number
int i;//Показатель счётчика итераций
double PriTP;//TP серии
int Tick;//Счётчик тиков
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----Установка ордеров
OrderSend(Symbol(),OP_BUY,0.5,Ask,0,Bid-350*Point,Ask+350*Point,NULL,Mn,0,CLR_NONE);//
OrderSend(Symbol(),OP_BUY,1,Ask,0,Bid-250*Point,Ask+250*Point,NULL,Mn,0,CLR_NONE);//
OrderSend(Symbol(),OP_BUY,1.5,Ask,0,Bid-150*Point,Ask+150*Point,NULL,Mn,0,CLR_NONE);//
OrderSend(Symbol(),OP_BUY,2.5,Ask,0,Bid-150*Point,Ask+150*Point,NULL,Mn,0,CLR_NONE);//
OrderSend(Symbol(),OP_BUY,3.5,Ask,0,Bid-150*Point,Ask+150*Point,NULL,Mn,0,CLR_NONE);//
OrderSend(Symbol(),OP_BUYLIMIT,1,Ask-150*Point,0,Bid-400*Point,
Ask+250*Point,NULL,Mn,0,CLR_NONE);//
OrderSend(Symbol(),OP_SELLSTOP,3,Ask-300*Point,0,Bid+150*Point,
Ask-750*Point,NULL,Mn,0,CLR_NONE);//
//----
   PriTP=Bid;//PriTP
   Print("Кс0:"," OrdersTotal=",OrdersTotal());//Сообщение
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
  
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----Счётчик Tick
   Tick++;//Tick
//----Закрываем ордера BUY
   for(i=0;i<OrdersTotal();i++)//Инициализация цикла
   {
   Print("Кс1:"," Tick=",Tick," i=",i);//Сообщение
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)//Выбор ордера i
    {
   if(OrderSymbol()==Symbol())//Символ
     {
   if(OrderMagicNumber()==Mn)//Идентификационное число
      {
   if(OrderType()==OP_BUY && OrderTakeProfit()>PriTP)//Тип операции текущего выбранного ордера
       {
   OrderClose(OrderTicket(),OrderLots(),Bid,0,CLR_NONE);//Закрытие позиции
       }//Закрыто if(OrderType()==OP_BUY && OrderTakeProfit()>PriTP)
      }//Закрыто if(OrderMagicNumber()==Mn)
     }//Закрыто if(OrderSymbol()==Symbol()
    }//Закрыто if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
   }//Закрыто for(i=0;i<OrdersTotal();i++)
//----
   return(0);
  }

Записи из журнала тестера.

2013.03.01 12:12:57 2012.09.03 00:00  Poligon1 EURUSD,M15: Кс1: Tick=5 i=1
2013.03.01 12:12:57 2012.09.03 00:00  Poligon1 EURUSD,M15: Кс1: Tick=5 i=0
2013.03.01 12:12:33 2012.09.03 00:00  Poligon1 EURUSD,M15: Кс1: Tick=4 i=1
2013.03.01 12:12:33 2012.09.03 00:00  Poligon1 EURUSD,M15: Кс1: Tick=4 i=0
2013.03.01 12:12:09 2012.09.03 00:00  Poligon1 EURUSD,M15: Кс1: Tick=3 i=1
2013.03.01 12:12:09 2012.09.03 00:00  Poligon1 EURUSD,M15: close #4 buy 2.50 EURUSD at 1.25773 sl: 1.25616 tp: 1.25923 at price 1.25770
2013.03.01 12:12:09 2012.09.03 00:00  Poligon1 EURUSD,M15: Кс1: Tick=3 i=0
2013.03.01 12:11:45 2012.09.03 00:00  Poligon1 EURUSD,M15: Кс1: Tick=2 i=2
2013.03.01 12:11:45 2012.09.03 00:00  Poligon1 EURUSD,M15: Кс1: Tick=2 i=1
2013.03.01 12:11:45 2012.09.03 00:00  Poligon1 EURUSD,M15: close #2 buy 1.00 EURUSD at 1.25773 sl: 1.25516 tp: 1.26023 at price 1.25768
2013.03.01 12:11:45 2012.09.03 00:00  Poligon1 EURUSD,M15: Кс1: Tick=2 i=0
2013.03.01 12:11:21 2012.09.03 00:00  Poligon1 EURUSD,M15: Кс1: Tick=1 i=3
2013.03.01 12:11:21 2012.09.03 00:00  Poligon1 EURUSD,M15: close #5 buy 3.50 EURUSD at 1.25773 sl: 1.25616 tp: 1.25923 at price 1.25766
2013.03.01 12:11:21 2012.09.03 00:00  Poligon1 EURUSD,M15: Кс1: Tick=1 i=2
2013.03.01 12:11:21 2012.09.03 00:00  Poligon1 EURUSD,M15: close #3 buy 1.50 EURUSD at 1.25773 sl: 1.25616 tp: 1.25923 at price 1.25766
2013.03.01 12:11:21 2012.09.03 00:00  Poligon1 EURUSD,M15: Кс1: Tick=1 i=1
2013.03.01 12:11:21 2012.09.03 00:00  Poligon1 EURUSD,M15: close #1 buy 0.50 EURUSD at 1.25773 sl: 1.25416 tp: 1.26123 at price 1.25766
2013.03.01 12:11:21 2012.09.03 00:00  Poligon1 EURUSD,M15: Кс1: Tick=1 i=0
2013.03.01 12:11:21 2012.09.03 00:00  Poligon1 EURUSD,M15: Кс0: OrdersTotal=7
2013.03.01 12:11:21 2012.09.03 00:00  Poligon1 EURUSD,M15: open #7 sell stop 3.00 EURUSD at 1.25473 sl: 1.25916 tp: 1.25023 ok
2013.03.01 12:11:21 2012.09.03 00:00  Poligon1 EURUSD,M15: open #6 buy limit 1.00 EURUSD at 1.25623 sl: 1.25366 tp: 1.26023 ok
2013.03.01 12:11:21 2012.09.03 00:00  Poligon1 EURUSD,M15: open #5 buy 3.50 EURUSD at 1.25773 sl: 1.25616 tp: 1.25923 ok
2013.03.01 12:11:21 2012.09.03 00:00  Poligon1 EURUSD,M15: open #4 buy 2.50 EURUSD at 1.25773 sl: 1.25616 tp: 1.25923 ok
2013.03.01 12:11:21 2012.09.03 00:00  Poligon1 EURUSD,M15: open #3 buy 1.50 EURUSD at 1.25773 sl: 1.25616 tp: 1.25923 ok
2013.03.01 12:11:21 2012.09.03 00:00  Poligon1 EURUSD,M15: open #2 buy 1.00 EURUSD at 1.25773 sl: 1.25516 tp: 1.26023 ok
2013.03.01 12:11:21 2012.09.03 00:00  Poligon1 EURUSD,M15: open #1 buy 0.50 EURUSD at 1.25773 sl: 1.25416 tp: 1.26123 ok
2013.03.01 12:11:21 Poligon1 test started
2013.03.01 12:11:21 Poligon1 EURUSD,M15: loaded successfully

//+------------------------------------------------------------------+

 

Внимание!

Билд 509. Функция MathModCorrect(), представленная в данной статье как замена функции MathMod(), при значениях делимого и делителя равных 0.6 и 0.2 соответственно, возвращает значение 0.2!

Происходит это из-за того, что int tmpres загадочным образом приобретает значение 2.

С другими аргументами подобного казуса не обнаружено.

Будьте бдительны!

Всем профитов!

 

Добавлю к предыдущему посту.

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

На что хочется обратить внимание авторов статей: коллеги, не пишите "всегда" (в последнем предложении), если не уверены на 100% в истинности этого утверждения.

Надеюсь, информация окажется полезной.

 
int start()
  {
   Alert(70/100);
   return(0);
  }
Для того чтобы вышло правильное деление достаточно написать 70.0/100 или 70/100.0 или 70.0/100.0
Причина обращения: