Ошибка Invalid price в тестере стратегий

 

Подскажите, кто знает. Возникает постоянно ошибка 10015 invalid price при работе в тестере стратегий.

написал простенький пример в пять строк, который выдаёт эту ошибку:

   MqlTick Tick;
   SymbolInfoTick (_Symbol, Tick);
    MqlTradeRequest Req={0};
    MqlTradeResult Res={0};
    ZeroMemory(Req);
   
    Req.action=TRADE_ACTION_DEAL;
    Req.symbol=_Symbol;
    Req.volume=1;
    Req.price=NormalizeDouble(Tick.ask, 1);
    Req.deviation = 10;
    Req.type=ORDER_TYPE_BUY;
    Req.type_filling=ORDER_FILLING_RETURN;
    ResetLastError();
    OrderSend(Req, Res);
 

кажется всё просто, отсылка ордера на покупку, по рыночной цене, откуда ошибка? Примерно через 20 попыток, ордер исполняется без ошибок

Всю голову сломал, помогите плиз! 

 
mao17:

Подскажите, кто знает. Возникает постоянно ошибка 10015 invalid price при работе в тестере стратегий.

написал простенький пример в пять строк, который выдаёт эту ошибку:

   MqlTick Tick;
   SymbolInfoTick (_Symbol, Tick);
    MqlTradeRequest Req={0};
    MqlTradeResult Res={0};
    ZeroMemory(Req);
   
    Req.action=TRADE_ACTION_DEAL;
    Req.symbol=_Symbol;
    Req.volume=1;
    Req.price=NormalizeDouble(Tick.ask, 1);
    Req.deviation = 10;
    Req.type=ORDER_TYPE_BUY;
    Req.type_filling=ORDER_FILLING_RETURN;
    ResetLastError();
    OrderSend(Req, Res);
 

кажется всё просто, отсылка ордера на покупку, по рыночной цене, откуда ошибка? Примерно через 20 попыток, ордер исполняется без ошибок

Всю голову сломал, помогите плиз! 

Попробуй так, А вообще подробностей побольше на каком инструменте, сервер счета

 

   MqlTick Tick;
   SymbolInfoTick (_Symbol, Tick);
    MqlTradeRequest Req={0};
    MqlTradeResult Res={0};
    ZeroMemory(Req);
    
    Req.action=TRADE_ACTION_DEAL;
    Req.symbol=_Symbol;
    Req.volume=1;
    Req.price=NormalizeDouble(Tick.ask,SymbolInfoInteger(_Symbol,SYMBOL_DIGITS));
    Req.deviation = 10;
    Req.type=ORDER_TYPE_BUY;
    Req.type_filling=ORDER_FILLING_RETURN;
    ResetLastError();
    OrderSend(Req, Res);

11 

 

Всем привет! Новую тему не стал создавать так как эта по названию совпадает. Проблема такая постоянно получаем ошибку в тестере по инструментам XAUUSD, XAGUSD

10015

TRADE_RETCODE_INVALID_PRICE

Неправильная цена в запросе

10016

TRADE_RETCODE_INVALID_STOPS

Неправильные стопы в запросе

 

МТ5 сервер MetaQuotes-Demo. У других брокеров на данных инструментах не наблюдаю. Хочется выяснить это баг тестера или все таки кода.


 
Sergey Gritsay:

Всем привет! Новую тему не стал создавать так как эта по названию совпадает. Проблема такая постоянно получаем ошибку в тестере по инструментам XAUUSD, XAGUSD

10015

TRADE_RETCODE_INVALID_PRICE

Неправильная цена в запросе

10016

TRADE_RETCODE_INVALID_STOPS

Неправильные стопы в запросе

 

МТ5 сервер MetaQuotes-Demo. У других брокеров на данных инструментах не наблюдаю. Хочется выяснить это баг тестера или все таки кода.


В коде.
 
Vitalii Ananev:
В коде.
Можете подсказать как решить, а то я уже голову сломал.
 
Sergey Gritsay:
Можете подсказать как решить, а то я уже голову сломал.

Нет. Я не экстрасенс не могу удаленно видеть ваш код. 

Но могу только предположить, что пытаетесь установить ордер бай стоп ниже цены или селл стоп выше цены. Или селл лимит ниже цены, или бай лимит выше цены.

Возможно еще, что вы ставите ордер стоп лосс не верно. К примеру у ордера бай ставите стоп лосс выше цены открытия ордера, или слишком близко к текущей цене. 

Вот тут еще посмотрите https://www.mql5.com/ru/forum/76084/page11 

Проверка минимального стопа в советниках, публикуемых в маркете.
Проверка минимального стопа в советниках, публикуемых в маркете.
  • www.mql5.com
Проверка минимального стопа в советниках, публикуемых в маркете. - Страница 11 - Категория: общее обсуждение
 
Vitalii Ananev:

Нет. Я не экстрасенс не могу удаленно видеть ваш код. 

Но могу только предположить, что пытаетесь установить ордер бай стоп ниже цены или селл стоп выше цены. Или селл лимит ниже цены, или бай лимит выше цены.

Возможно еще, что вы ставите ордер стоп лосс не верно. К примеру у ордера бай ставите стоп лосс выше цены открытия ордера, или слишком близко к текущей цене. 

Вот тут еще посмотрите https://www.mql5.com/ru/forum/76084/page11 

Сейчас набросаю тестовый код
 

Вот тестовый код

//+------------------------------------------------------------------+
//|                                                      Test_04.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <Trade\Trade.mqh>
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(NewBar(_Symbol,0))
     {
      if(!PositionSelect(_Symbol))
        {
         trade.Buy(0.1,_Symbol);
        }
     }

   Modify(_Symbol,10000,10000);
   Trailing_Stop(_Symbol,10000);
  }
//+------------------------------------------------------------------+
bool NewBar(string symbol,ENUM_TIMEFRAMES  period)
  {
   static datetime lastbar;
   datetime curbar=(datetime) SeriesInfoInteger(symbol,period,SERIES_LASTBAR_DATE);

   if(lastbar==0)lastbar=(datetime)SeriesInfoInteger(symbol,period,SERIES_LASTBAR_DATE);
   if(lastbar!=curbar)
     {
      lastbar=curbar;
      return(true);
     }
   return(false);
  }
//+------------------------------------------------------------------+
void Modify(string symbol,double sl,double tp)
  {
   if(sl<0 || tp<0)return;

   double bid=SymbolInfoDouble(symbol,SYMBOL_BID);
   double ask=SymbolInfoDouble(symbol,SYMBOL_ASK);
   double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
   int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);

   if(bid<=0.0 || ask<=0.0)return;

   if(PositionSelect(symbol))
     {
      if(PositionGetDouble(POSITION_SL)==0 && PositionGetDouble(POSITION_TP)==0)
        {
         if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
           {
            tp=NormalizeDouble(bid+sl*point,digits);
            sl=NormalizeDouble(bid-sl*point,digits);
           }
         if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
           {
            tp=NormalizeDouble(ask-sl*point,digits);
            sl=NormalizeDouble(ask+sl*point,digits);
           }
         if(sl<0 || tp<0)return;
         trade.PositionModify(symbol,sl,tp);
        }
     }
  }
//+------------------------------------------------------------------+
void Trailing_Stop(string symbol,double Stop_Loss)
  {
   if(Stop_Loss<=0)return;
   double sl=0.0;
   double tp=0.0;
   double bid=SymbolInfoDouble(symbol,SYMBOL_BID);
   double ask=SymbolInfoDouble(symbol,SYMBOL_ASK);
   double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
   int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);

   if(bid<=0.0 || ask<=0.0)return;

   if(PositionSelect(symbol))
     {
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
        {
         tp=PositionGetDouble(POSITION_TP);
         sl=NormalizeDouble(bid-Stop_Loss*point,digits);
         if(sl<=PositionGetDouble(POSITION_SL))return;
        }
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
        {
         tp=PositionGetDouble(POSITION_TP);
         sl=NormalizeDouble(ask+Stop_Loss*point,digits);
         if(sl>=PositionGetDouble(POSITION_SL))return;
        }
      if(sl<0 || tp<0)return;
      trade.PositionModify(symbol,sl,tp);
     }
  }
//+------------------------------------------------------------------+
 
Sergey Gritsay:

Вот тестовый код

Вы вставьте в ваш код обработку ошибок и выводите тестовую информацию в журнал.

if (GetLastError()>0)
{
 Print(....)

}
 

А для какой цели, я и так знаю какие ошибки вылетают 10015 и 10016. Дело в том что в спецификации инструмента XAUUSD и XAGUSD указан шаг цены 0,01 а тики в тестере генерируются с шагом 0,001. Ошибку 10016 Неправильные стопы в запросе я вроде победил, а вот ошибку 10015 Неправильная цена в запросе победить не могу.

//+------------------------------------------------------------------+
//|                                                      Test_04.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <Trade\Trade.mqh>
CTrade trade;
int m_atr=0;
int Period_ATR=21;
ENUM_TIMEFRAMES TF_ATR=PERIOD_CURRENT;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double price=0.0;
   double volume=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
   //int digits=(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);
   //double ts=SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE);
   //double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);
   //double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   //if(bid<=0.0 || ask<=0.0)return;

   if(!PositionSelect(_Symbol))
     {
      trade.Buy(volume,_Symbol);
     }

   double SL=Dynamic_Stop(_Symbol,3);
   double TP=Dynamic_Stop(_Symbol,6);

   Modify(_Symbol,SL,TP);
   Trailing_Stop(_Symbol,SL);
  }
//+------------------------------------------------------------------+
bool NewBar(string symbol,ENUM_TIMEFRAMES  period)
  {
   static datetime lastbar;
   datetime curbar=(datetime) SeriesInfoInteger(symbol,period,SERIES_LASTBAR_DATE);

   if(lastbar==0)lastbar=(datetime)SeriesInfoInteger(symbol,period,SERIES_LASTBAR_DATE);
   if(lastbar!=curbar)
     {
      lastbar=curbar;
      return(true);
     }
   return(false);
  }
//+------------------------------------------------------------------+
void Modify(string symbol,double sl,double tp)
  {
   if(sl<0 || tp<0)return;
   double price=0.0;
   double bid=SymbolInfoDouble(symbol,SYMBOL_BID);
   double ask=SymbolInfoDouble(symbol,SYMBOL_ASK);
   double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
   int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
   double ts=SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE);

   if(bid<=0.0 || ask<=0.0)return;

   if(PositionSelect(symbol))
     {
      if(PositionGetDouble(POSITION_SL)==0 && PositionGetDouble(POSITION_TP)==0)
        {
         price=PositionGetDouble(POSITION_PRICE_OPEN);
         if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
           {
            //tp=NormalizeDouble(normalize(symbol,bid+tp*point),digits);
            //sl=NormalizeDouble(normalize(symbol,bid-sl*point),digits);
            tp=NormalizeDouble(normalize(symbol,price+tp*point),digits);
            sl=NormalizeDouble(normalize(symbol,price-sl*point),digits);
           }
         if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
           {
            //tp=NormalizeDouble(normalize(symbol,ask-tp*point),digits);
            //sl=NormalizeDouble(normalize(symbol,ask+sl*point),digits);
            tp=NormalizeDouble(normalize(symbol,price-tp*point),digits);
            sl=NormalizeDouble(normalize(symbol,price+sl*point),digits);
           }
         if(sl<0 || tp<0)return;
         trade.PositionModify(symbol,sl,tp);
        }
     }
  }
//+------------------------------------------------------------------+
void Trailing_Stop(string symbol,double sl)
  {
   double tp=0.0;
   if(sl<=0)return;

   double bid=SymbolInfoDouble(symbol,SYMBOL_BID);
   double ask=SymbolInfoDouble(symbol,SYMBOL_ASK);
   double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
   int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);

   if(bid<=0.0 || ask<=0.0)return;

   if(PositionSelect(symbol))
     {
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
        {
         tp=PositionGetDouble(POSITION_TP);
         sl=NormalizeDouble(normalize(symbol,bid-sl*point),digits);
         if(sl<=PositionGetDouble(POSITION_SL))return;
        }
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
        {
         tp=PositionGetDouble(POSITION_TP);
         sl=NormalizeDouble(normalize(symbol,ask+sl*point),digits);
         if(sl>=PositionGetDouble(POSITION_SL))return;
        }
      if(sl<0 || tp<0)return;
      trade.PositionModify(symbol,sl,tp);
     }
  }
//+------------------------------------------------------------------+
double Dynamic_Stop(string symbol,double k)
  {
   double atr[1];
   double ts=SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE);
   double point=SymbolInfoDouble(symbol,SYMBOL_POINT);

   if(Bars(symbol,TF_ATR)<Period_ATR+1)return(WRONG_VALUE);

   if(m_atr==INVALID_HANDLE || m_atr==0)
     {
      m_atr=iATR(symbol,TF_ATR,Period_ATR);
      return(WRONG_VALUE);
     }

   if(CopyBuffer(m_atr,0,1,1,atr)<1)return(WRONG_VALUE);

   double vol=atr[0]/point*k;
   if(vol<=SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))vol*=2.0;

//vol=NormalizeDouble(vol/ts,0)*ts;
   return(vol);
  }
//+------------------------------------------------------------------+
double normalize(string symbol,double value)
  {
   double ts=SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE);
   return(NormalizeDouble(value/ts,0)*ts);
  }
//+------------------------------------------------------------------+
 
Sergey Gritsay:

А для какой цели, я и так знаю какие ошибки вылетают 10015 и 10016. Дело в том что в спецификации инструмента XAUUSD и XAGUSD указан шаг цены 0,01 а тики в тестере генерируются с шагом 0,001. Ошибку 10016 Неправильные стопы в запросе я вроде победил, а вот ошибку 10015 Неправильная цена в запросе победить не могу.

Это не для того что бы узнать какая ошибка, а для того что бы вывести значения переменных при которых возникает эта ошибка для последующего анализа причины ошибки. Может вы передаете в функцию модификации ордера отрицательные значения или эти значения получаются внутри спреда. 
Причина обращения: