Ошибка Invalid Price при торговле USDRUB_TOM - страница 4

 
Karputov Vladimir:

 

Где код? Переделайте код и покажите результат.

 

При чем тут код? Докладываю - советник работает без ошибок на любом инструменте фьючерсов ФОРТС, работает без ошибок на FOREX. Проблема только с конкретными инструментами валютного рынка (USDRUB_TOM, USDRUB_TOD и т.п)...

Способ получения цены через классы или через функцию SymbolInfoDouble разницы никакой не имеет, это я тоже проверял.

 
Sergey Zhilinskiy:

При чем тут код? Докладываю - советник работает без ошибок на любом инструменте фьючерсов ФОРТС, работает без ошибок на FOREX. Проблема только с конкретными инструментами валютного рынка (USDRUB_TOM, USDRUB_TOD и т.п)...

Способ получения цены через классы или через функцию SymbolInfoDouble разницы никакой не имеет, это я тоже проверял.

А какой торговый сервер (название, демо/реал)? Чтобы знать на будущее.
 
Karputov Vladimir:
А какой торговый сервер (название, демо/реал)? Чтобы знать на будущее.
Торговый сервер Open-Broker, не демо.
 
Sergey Zhilinskiy:
Торговый сервер Open-Broker, не демо.

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

#include<Trade\Trade.mqh>
#include<Trade\AccountInfo.mqh>

CTrade trade;
CAccountInfo AccountInfo;
CDealInfo deal;
CPositionInfo Position;
//+------------------------------------------------------------------+
void OpenPosition(ENUM_ORDER_TYPE type,double volume)
  {
   if(type==WRONG_VALUE) return;
   int digits=(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);

   if(AccountInfo.FreeMarginCheck(_Symbol,type,volume,price)<=0.0)
     {
      rezult="not enough money";
      return;
     }

   if(type==ORDER_TYPE_BUY)
     {
      double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
      if(NormalizeDouble(NormalizePrice(_Symbol,ask),digits)!=NormalizeDouble(ask,digits))return;
      trade.Buy(volume,_Symbol,0,0,0,CommentOrder);
     }
   if(type==ORDER_TYPE_SELL)
     {
      double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);
      if(NormalizeDouble(NormalizePrice(_Symbol,bid),digits)!=NormalizeDouble(bid,digits))return;
      trade.Sell(volume,_Symbol,0,0,0,CommentOrder);
     }
   if(trade.ResultRetcode()==TRADE_RETCODE_DONE)
     {
      HistorySelect(0,TimeCurrent());
      deal.Ticket(trade.ResultDeal());
      tiket=deal.PositionId();
      StringConcatenate(rezult,_Symbol,": open position ",tiket," ",DoubleToString(volume,2)," ",StrToType(type));
      Print(rezult);
     }
   else
     {
      StringConcatenate(rezult,_Symbol,": error open position ",DoubleToString(volume,2)," ",StrToType(type)," № - ",trade.ResultRetcode());
      Print(rezult);
     }
  }
//+------------------------------------------------------------------+
double NormalizePrice(string symbol,double value)
  {
   double ts=SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE);
   if(ts==0)return(value);
   return(NormalizeDouble(value/ts,0)*ts);
  }
//+------------------------------------------------------------------+
string StrToType(ENUM_ORDER_TYPE type)
  {
   if(type==ORDER_TYPE_BUY)return("BUY");
   if(type==ORDER_TYPE_SELL)return("SELL");
   return((string)type);
  }
//+------------------------------------------------------------------+
 
Sergey Gritsay:

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

Думаю по этому условию

if(NormalizeDouble(NormalizePrice(_Symbol,ask),digits)!=NormalizeDouble(ask,digits))return;

 будем пропускать входы.

Все равно спасибо за конструктивный ответ, попробую отпишусь. 

 
Alexey Viktorov:

А теперь давайте посчитаем как будет нормализована цена...

Текущая цена 65.8412 разделим на 0.0025 и округлим до целого, получим 26336, затем умножим на 0.0025 и получим 65.84, что не соответствует действительности.


такой цена быть не может
 
Alexander Bereznyak:
такой цена быть не может

Ну да. Я не сразу обратил внимание на то что это открытие брокер.

Но всё равно меня смущает возможное отсутствие последнего нуля, или даже двух нулей.

Может так попробовать?

double ND(double x){
   double tickSize=SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE);
   return(NormalizeDouble(MathRound(x/tickSize)*tickSize, SymbolInfoInteger(_Symbol, SYMBOL_DIGITS)));
}
 
Alexander Bereznyak:
такой цена быть не может
Какой такой? Можете конкретно написать?
 
Sergey Gritsay:

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

Еще раз большое СПАСИБО! Идея сравнения требуемой(нормализованной) цены и текущей сработала! Иногда это происходит на 3-8 тике.
 

В стандартной библиотеке есть специальная функция на этот случай

//+------------------------------------------------------------------+
//| Normalize price                                                  |
//+------------------------------------------------------------------+
double CSymbolInfo::NormalizePrice(const double price) const
  {
   if(m_tick_size!=0)
      return(NormalizeDouble(MathRound(price/m_tick_size)*m_tick_size,m_digits));
//---
   return(NormalizeDouble(price,m_digits));
  }