Скачать MetaTrader 5

Ошибка, связанная с точностью представления данных. Прошу разработчиков обратить внимание!

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Forex Trader
114269
Forex Trader  
Уважаемые разработчики ПО и коллеги-трейдеры!
В последних версиях торгового терминала MetaTrader4 (4.00 build 210) часто сталкиваюсь со следующей ошибкой. При выполнении команды
OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,Ask-Point*StopLoss,Ask+Point*TakeProfit,"",16384,0,CLR_NONE);


либо

OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,Bid+Point*StopLoss,Bid-Point*TakeProfit,"",16384,0,CLR_NONE);


в ряде случаев возникает ошибка


2007.10.10 11:10:09 2005.07.21 01:56 proba EURUSD,M1: OrderSend error 4107
2007.10.10 11:10:09 2005.07.21 01:56 proba EURUSD,M1: invalid price 1.21405002 for OrderSend function

а при выполнении команды

OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,CLR_NONE);


либо

OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,CLR_NONE);


возникает ошибка


2007.10.10 11:09:56 2005.01.13 04:00 proba EURUSD,M1: OrderClose error 4107
2007.10.10 11:09:56 2005.01.13 04:00 proba EURUSD,M1: invalid price 1.32475007 for OrderClose function

Исходя из этого, можно предположить, что предопределенные переменные Ask и Bid иногда принимают значение с точностью 8 знаков после десятичной точки, вместо четырех, несмотря на то, что в исторических данных все котировки имеют четыре знака после десятичной точки (и количество цифр после десятичной точки в цене финансового инструмента согласно его свойствам тоже равно четрем).

При выполнении следующего фрагмента программы

            if(Bid>=OrderOpenPrice()+Point*Level1 && OrderOpenPrice()>OrderStopLoss())
              {
               Print("Buy order, OpenPrice: ",OrderOpenPrice(),", StopLoss: ",OrderStopLoss());
               OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0);
               return(0);
              }


либо

            if(Ask<=OrderOpenPrice()-Point*Level1 && OrderOpenPrice()<OrderStopLoss())
              {
               Print("Sell order, OpenPrice: ",OrderOpenPrice(),", StopLoss: ",OrderStopLoss());
               OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0);
               return(0);
              }


в log-файле видим следующее


2007.10.10 11:30:47 2004.09.09 09:21 proba EURUSD,M1: OrderModify error 1
2007.10.10 11:30:47 2004.09.09 09:21 proba EURUSD,M1: Buy order, OpenPrice: 1.2172, StopLoss: 1.2172

либо

2007.10.10 11:34:40 2005.01.06 16:14 proba EURUSD,M1: OrderModify error 1
2007.10.10 11:34:40 2005.01.06 16:14 proba EURUSD,M1: Sell order, OpenPrice: 1.3206, StopLoss: 1.3206

То есть, выполняется условие OrderOpenPrice() БОЛЬШЕ OrderStopLoss() или OrderOpenPrice() МЕНЬШЕ OrderStopLoss(), а команда Print() выводит одинаковые значения для них и команда OrderModify() воспринимает их как равные и дает ошибку.

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

Forex Trader
114269
Forex Trader  
Если Вы подозреваете, что точность значений,выводимых в лог, больше 4, то используйте не просто
Print(A);

, а

Print(DoubleToString(A,8));


Кроме того, ошибка с кодом один возникает, когда новое и старое значение StopLoss или TakeProfit равны с точностью до пункта. Почитайте ветку "MQL4: Automated Trading Championship 2007: распространенные ошибки в экспертах"

Forex Trader
114269
Forex Trader  
Так как MarketInfo(symbol,MODE_DIGITS) = 4, то и значения OrderOpenPrice(), OrderStopLoss() и OrderTakeProfit() должны иметь точность до 4-х знаков после десятичной точки. Откуда берутся значения значения более высокой точности, откуда берутся дробные пункты?

Логично предположить, что при подаче команды
Print(A);

результат будет выводиться с точностью переменной A, то есть, если A имеет 8 значащих знаков после десятичной точки - будут выводиться все восемь.

Forex Trader
114269
Forex Trader  
Вы проверьте, у меня есть своя теория на сей счет.
Forex Trader
114269
Forex Trader  
Меня больше волнует проблема с ошибкой "invalid price 1.21405002 for OrderSend " при комманде "OrderSend(...,Bid,...);" и "invalid price 1.32475007 for OrderClose" при комманде "OrderClose(...,Bid,...);", но ответа я пока так и не получил...
Может быть это MetaTrader4 так иммитирует Requote? :-)
Forex Trader
114269
Forex Trader  
какая-то логика в твоих суждениях есть, но еще есть другие технические аспекты касающиеся хранения вещественных чисел, если тебе интересно можно хотябы этот форум покопать, вот недавно, показывал как правильно обрабатывать твою ситуацию, на первой страничке еще висит, а если порыть, то наверно уже немерянно раз отвечали по этому поводу
"OrderModify error 1"
Forex Trader
114269
Forex Trader  
Проблема в том, что хранятся не нормализованные данные, которые не нравятся тестеру. При этом автор сначала делал проверку простым выводом подозрительного значения в Print(). После того, как вывод стал делаться через DoubleToStr() с точностью до восьми занков, это стало очевидно. Следующий шаг :

- либо номализовать предварительно свою историю
- либо загрузить нормализованную историю
- либо предварительно нормализовать в эксперте все исторические данные перед вызовом торговых функций.
Forex Trader
114269
Forex Trader  
Это мы сейчас проверим.
Напишем простой скрипт, читающий данные из файла EURUSD1.hst и записывающий их в текстовый файл:
int start()
  {
   int handle_rd,handle_wr,cnt;
   
   handle_wr=FileOpen("OutHistory.txt",FILE_BIN|FILE_WRITE);
   handle_rd=FileOpenHistory("EURUSD1.hst",FILE_BIN);

   FileWrite(handle_wr,"Version: "+FileReadInteger(handle_rd,LONG_VALUE));
   FileWrite(handle_wr,"Copyright: "+FileReadString(handle_rd,64));
   FileWrite(handle_wr,"Symbol: "+FileReadString(handle_rd,12));
   FileWrite(handle_wr,"Period: "+FileReadInteger(handle_rd,LONG_VALUE));
   FileWrite(handle_wr,"Digits: "+FileReadInteger(handle_rd,LONG_VALUE));
   FileWrite(handle_wr,"TimeSign: "+TimeToStr(FileReadInteger(handle_rd,LONG_VALUE)));
   FileWrite(handle_wr,"LastSync: "+TimeToStr(FileReadInteger(handle_rd,LONG_VALUE)));

   for(cnt=1;cnt<=13;cnt++)
     {FileReadInteger(handle_rd,LONG_VALUE);}

   FileWrite(handle_wr,"   Date    Time     Open       Low        High       Close      Volume");

   for(;FileIsEnding(handle_rd)==0;)
     {FileWrite(handle_wr,TimeToStr(FileReadInteger(handle_rd,LONG_VALUE))+" "+FileReadDouble(handle_rd,DOUBLE_VALUE)+" "+FileReadDouble(handle_rd,DOUBLE_VALUE)+" "+FileReadDouble(handle_rd,DOUBLE_VALUE)+" "+FileReadDouble(handle_rd,DOUBLE_VALUE)+" "+FileReadDouble(handle_rd,DOUBLE_VALUE));}


   FileClose(handle_rd);
   FileClose(handle_wr);
   return(0);
  }


Запускаем. Смотрим результат:

Version: 400
Copyright: (C)opyright 2003, MetaQuotes Software Corp.
Symbol: EURUSD
Period: 1
Digits: 4
TimeSign: 2007.10.09 20:47
LastSync: 1970.01.01 00:00
   Date    Time     Open       Low        High       Close      Volume
2004.06.16 10:55 1.21130002 1.21120000 1.21150005 1.21149993 15.00000000
2004.06.16 10:56 1.21149993 1.21140003 1.21160007 1.21149993 10.00000000
2004.06.16 10:57 1.21149993 1.21089995 1.21150005 1.21089995 21.00000000
2004.06.16 10:58 1.21099997 1.21010005 1.21100008 1.21019995 23.00000000
2004.06.16 10:59 1.21009994 1.21000004 1.21040010 1.21019995 15.00000000
2004.06.16 11:00 1.21019995 1.20990002 1.21030009 1.21009994 24.00000000
2004.06.16 11:01 1.20999992 1.20990002 1.21040010 1.21039999 21.00000000
2004.06.16 11:02 1.21039999 1.21019995 1.21050000 1.21050000 15.00000000
2004.06.16 11:03 1.21039999 1.21019995 1.21060002 1.21019995 14.00000000 


Действительно, вы правы, Rosh. Интересно, почему известный ДЦ выкладывает историю в таком виде (ненормализированно). Кстати, текущие данные и данные, загружаемые с сервера при перемещении по графику, нормализированные:

Version: 400
Copyright: (C)opyright 2003, MetaQuotes Software Corp.
Symbol: EURUSD
Period: 1
Digits: 4
TimeSign: 2007.10.12 18:30
LastSync: 1970.01.01 00:00
   Date    Time     Open       Low        High       Close      Volume
2007.10.10 07:23 1.41080000 1.41070000 1.41080000 1.41080000 5.00000000
2007.10.10 07:25 1.41070000 1.41070000 1.41080000 1.41080000 2.00000000
2007.10.10 07:26 1.41070000 1.41070000 1.41090000 1.41090000 5.00000000
2007.10.10 07:27 1.41080000 1.41080000 1.41090000 1.41090000 2.00000000
2007.10.10 07:28 1.41100000 1.41090000 1.41110000 1.41110000 4.00000000
2007.10.10 07:29 1.41120000 1.41110000 1.41120000 1.41110000 6.00000000


Было бы разумно, чтобы значения предопределенных переменных и функций, содержащих цену (Ask, Bid, OrderOpenPrice(), OrderStopLoss(), OrderTakeProfit(), ...) округлялись путем
NormalizeToDouble(переменная,Digits);
автоматически.

Forex Trader
114269
Forex Trader  
Forex Trader
114269
Forex Trader  
Почитайте про Ask, Bid , и по каким ценам открываются отложенные ордера и закрываются рыночные. Лучше самостоятельно.
Forex Trader
114269
Forex Trader  
Уважаемый Rosh.
Обратите, пожалуйста, внимание на то, что на прилагаемом рисунке цена Bid=0.6567, Ask=0.6569. TakeProfit короткой позиции (#4) имеет значение 0.6569 и при этой цене он должен был исполнен. Цена открытия ордера BuyLimit (#5) имеет значение 0.6569, при указаной выше цене он тоже должен был открыться.
12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий