Автоматическая проверка продуктов в Маркете (вопросы и предложения) - страница 8

 
Stanislav Korotky #:

У кого-нибудь есть пропатченная версия стандартной библиотеки (CTrade и всё такое), которая проходит автоматические проверки Маркета?

Вот парочка патчей ("as is", работоспособность во всех случаях не гарантируется). В файле ExpertTrade.mqh дополняем методы Buy и Sell:

//+------------------------------------------------------------------+
//| Easy LONG trade operation                                        |
//+------------------------------------------------------------------+
bool CExpertTrade::Buy(double volume,double price,double sl,double tp,const string comment="")
  {
   double ask,bid,stops_level;
//--- checking
   if(m_symbol==NULL)
      return(false);
   string symbol=m_symbol.Name();
   if(symbol=="")
      return(false);
//---
   ask=m_symbol.Ask();
   bid=m_symbol.Bid();
   stops_level=m_symbol.StopsLevel()*m_symbol.Point();
   if(price!=0.0)
     {
      if(price>m_symbol.NormalizePrice(ask+stops_level))
        {
         //--- send "BUY_STOP" order
         return(OrderOpen(symbol,ORDER_TYPE_BUY_STOP,volume,0.0,price,sl,tp,
                m_order_type_time,m_order_expiration,comment));
        }
      if(price<m_symbol.NormalizePrice(ask-stops_level))
        {
         //--- send "BUY_LIMIT" order
         return(OrderOpen(symbol,ORDER_TYPE_BUY_LIMIT,volume,0.0,price,sl,tp,
                m_order_type_time,m_order_expiration,comment));
        }
     }
     
   if(sl != 0 && bid - sl < stops_level)
   {
      if(m_log_level>LOG_LEVEL_NO)
         PrintFormat(__FUNCTION__+": SL %f is closer/above to BID %f than level %f", sl, bid, stops_level);
      return false;
   }
   if(tp != 0 && tp - bid < stops_level)
   {
      if(m_log_level>LOG_LEVEL_NO)
         PrintFormat(__FUNCTION__+": TP %f is closer/below to BID %f than level %f", tp, bid, stops_level);
      return false;
   }
//---
   return(PositionOpen(symbol,ORDER_TYPE_BUY,volume,ask,sl,tp,comment));
  }
//+------------------------------------------------------------------+
//| Easy SHORT trade operation                                       |
//+------------------------------------------------------------------+
bool CExpertTrade::Sell(double volume,double price,double sl,double tp,const string comment="")
  {
   double bid,ask,stops_level;
//--- checking
   if(m_symbol==NULL)
      return(false);
   string symbol=m_symbol.Name();
   if(symbol=="")
      return(false);
//---
   bid=m_symbol.Bid();
   ask=m_symbol.Ask();
   stops_level=m_symbol.StopsLevel()*m_symbol.Point();
   if(price!=0.0)
     {
      if(price>m_symbol.NormalizePrice(bid+stops_level))
        {
         //--- send "SELL_LIMIT" order
         return(OrderOpen(symbol,ORDER_TYPE_SELL_LIMIT,volume,0.0,price,sl,tp,
                m_order_type_time,m_order_expiration,comment));
        }
      if(price<m_symbol.NormalizePrice(bid-stops_level))
        {
         //--- send "SELL_STOP" order
         return(OrderOpen(symbol,ORDER_TYPE_SELL_STOP,volume,0.0,price,sl,tp,
                m_order_type_time,m_order_expiration,comment));
        }
     }
     
   if(sl != 0 && sl - ask < stops_level)
   {
      if(m_log_level>LOG_LEVEL_NO)
         PrintFormat(__FUNCTION__+": SL %f is closer/below to ASK %f than level %f", sl, ask, stops_level);
      return false;
   }
   if(tp != 0 && ask - tp < stops_level)
   {
      if(m_log_level>LOG_LEVEL_NO)
         PrintFormat(__FUNCTION__+": TP %f is closer/above to ASK %f than level %f", tp, ask, stops_level);
      return false;
   }
     
//---
   return(PositionOpen(symbol,ORDER_TYPE_SELL,volume,bid,sl,tp,comment));
  }
//+------------------------------------------------------------------+

Это лечит ошибку invalid stops.

По поводу ошибки модификации позиций рядом с рынком - не стал вникать, блокирую любые операции, когда рынок вблизи любой позиции:

bool CheckOrdersAndPositions(const ulong magic = 0) // TODO: pending orders
{
   const double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   const double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   int freeze = (int)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_FREEZE_LEVEL);
   if(!freeze) // dynamic, try double spread as a replacement
   {
      freeze = 2 * (ask - bid) / _Point;
   }
   const int n = PositionsTotal();
   for(int i = 0; i < n; i++)
   {
      if(PositionGetTicket(i) && PositionGetString(POSITION_SYMBOL) == _Symbol) // TODO: magic
      {
         const ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
         if(type == POSITION_TYPE_BUY)
         {
            if(fabs(PositionGetDouble(POSITION_TP) - bid) / _Point < freeze
            || fabs(PositionGetDouble(POSITION_SL) - bid) / _Point < freeze)
               return false;
         }
         else if(type == POSITION_TYPE_SELL)
         {
            if(fabs(PositionGetDouble(POSITION_TP) - ask) / _Point < freeze
            || fabs(PositionGetDouble(POSITION_SL) - ask) / _Point < freeze)
               return false;
         }
      }
   }
   return true;
}

//+------------------------------------------------------------------+
//| "Tick" event handler function                                    |
//+------------------------------------------------------------------+
void OnTick()
{
  if(!CheckOrdersAndPositions())
  {
    return;
  }
  ...
}

Валидацию маркета эксперт прошел.

ЗЫ. Есть еще один вариант - путем добавление OrderCheck - для невалидных стопов и других ошибок той же серии:

bool CTrade::OrderSend(const MqlTradeRequest &request,MqlTradeResult &result)
  {
   bool   res;
   string action="";
   string fmt   ="";
//--- action
   static MqlTradeCheckResult check;
   if(!::OrderCheck(request, check))
   {
      const int d = SymbolInfoInteger(request.symbol, SYMBOL_DIGITS);
      if(m_log_level>LOG_LEVEL_NO)
         PrintFormat("Check failed: %d, (%.*f / %.*f)", check.retcode, d, SymbolInfoDouble(request.symbol, SYMBOL_BID), d, SymbolInfoDouble(request.symbol, SYMBOL_ASK));
      return false;
   }
   if(m_async_mode)
      res=::OrderSendAsync(request,result);
   else
      res=::OrderSend(request,result);
//--- check
   if(res)
     {
      if(m_log_level>LOG_LEVEL_ERRORS)
         PrintFormat(__FUNCTION__+": %s [%s]",FormatRequest(action,request),FormatRequestResult(fmt,request,result));
     }
   else
     {
      if(m_log_level>LOG_LEVEL_NO)
         PrintFormat(__FUNCTION__+": %s [%s]",FormatRequest(action,request),FormatRequestResult(fmt,request,result));
     }
//--- return the result
   return(res);
  }
 
Stanislav Korotky #:

Валидацию маркета эксперт прошел.

А проверка отложек на каждом тике, что хватает маржи на их срабатывание?
 
fxsaber #:
А проверка отложек на каждом тике, что хватает маржи на их срабатывание?

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

У меня в него изначально была добавлена одна строка по проверке уровня маржи в самом начале OnTick, поэтому патчи ориентированы на "новые" ошибки, не связанные с маржой.

 
Stanislav Korotky #:

Мне не видится ошибкой нехватка маржи для отложки. Но Маркет со мной не согласен.