MetaTrader 4 Build 186 - страница 4

 
Еще вопрос по функции RefreshRates - в документации в примере написано так:
RefreshRates
sleep(10000)

:-/ я так понимаю через 10 секунд запрошенные цены будут совершенно не актуальны
надо бы
RefreshRates
SendOrder

или я где-то не прав?
 
На счет торговли из двух экспертов работает IsTradeAllowed() проверка, я так понимаю она и таймауты учитывает?
Ничего она не учитывает.... Только флаг в настройках эксперта.
Если 2 подряд - он !по идее! сначала закончит с первым, потом возьмётся за второй. Но не факт. И паузы никакой не будет.
Если одновременно несколько экспертов, надо городить семафоры, паузы, и т.д. - обсуждалось в теме "Ошибка №6".
В принципе, у меня есть готовое решение - могу поделиться. А скоро я выложу его (решение, библиотеку, т.е.) на mql4.com
 
странно, а почему у меня работает? :) несколько экспертов срабатывают одновременно по новому бару и спокойно разруливаются этой функцией
 
//---------------------------------------------------------------------
// wait for trade context
//---------------------------------------------------------------------
bool WaitForTradeContext()
  {
    int i;
  
    // wait for trade to be allowed if trade context is busy for 30 seconds
    i = 0;
    while ((i < 300) && !(IsTradeAllowed())) 
      {
        Sleep(100);
        i++;
      }
     
    if (i == 300) 
      {
        OrderError = "Trade is not allowed";
        return(false);
      }
     
    // refresh rates  
    if (i > 10) 
      if (!RefreshRates()) 
        {
          OrderError = ErrorDescription(GetLastError());
          return(false);
        }
        
    return(true);  
  }


//---------------------------------------------------------------------
// send sell order
//---------------------------------------------------------------------
int _Sell(double LotSize, int StopLoss, int TakeProfit)
  {
    double sl, tp;
  
    if (StopLoss == 0) sl = 0; else sl = NormalizeDouble(Bid + StopLoss*Point, Digits);
    if (TakeProfit == 0) tp = 0; else tp = NormalizeDouble(Bid - TakeProfit*Point, Digits); 
    return(OrderSend(Symbol(), OP_SELL, LotSize, Bid, 3, sl, tp, "", 0, 0, Red));
  }


//---------------------------------------------------------------------
// send buy order
//---------------------------------------------------------------------
int _Buy(double LotSize, int StopLoss, int TakeProfit)
  {
    double sl, tp;
    
    if (StopLoss == 0) sl = 0; else sl = NormalizeDouble(Ask - StopLoss*Point, Digits);
    if (TakeProfit == 0) tp = 0; else tp = NormalizeDouble(Ask + TakeProfit*Point, Digits);
    return(OrderSend(Symbol(), OP_BUY, LotSize, Ask, 3, sl, tp, "", 0, 0, Yellow));
  }


//---------------------------------------------------------------------
// send sell order with checking
//---------------------------------------------------------------------
int Sell(double LotSize, int StopLoss, int TakeProfit)
  {
    int err, OrderHandle;
 
    // wait for trade context
    if (!WaitForTradeContext()) return(-1);
 
    // trying to sell
    OrderHandle = _Sell(LotSize, StopLoss, TakeProfit);
    if (OrderHandle < 0)
      {
        // have error
        err = GetLastError();
        if ((err == ERR_REQUOTE) || (err == ERR_PRICE_CHANGED) || (err == ERR_INVALID_PRICE))
          {
            // trying to refresh rates
            Sleep(5000);
            if (!RefreshRates())
              {
                OrderError = ErrorDescription(GetLastError());
                return(-1);
              }       
            else  
              {
                // trying to sell again
                OrderHandle = _Sell(LotSize, StopLoss, TakeProfit);
                if (OrderHandle < 0) OrderError = ErrorDescription(GetLastError());
              }          
          }
      }
           
    return(OrderHandle);
  }
  
//---------------------------------------------------------------------
// send buy order with checking
//---------------------------------------------------------------------
int Buy(double LotSize, int StopLoss, int TakeProfit)
  {
    int err, OrderHandle;
 
    // wait for trade context
    if (!WaitForTradeContext()) return(-1);
 
    // trying to buy
    OrderHandle = _Buy(LotSize, StopLoss, TakeProfit);
    if (OrderHandle < 0)
      {
        // have error
        err = GetLastError();
        if ((err == ERR_REQUOTE) || (err == ERR_PRICE_CHANGED) || (err == ERR_INVALID_PRICE))
          {
            // trying to refresh rates
            Sleep(5000);  
            if (!RefreshRates())
              {
                OrderError = ErrorDescription(GetLastError());
                return(-1);
              }       
            else  
              {
                // trying to buy again
                OrderHandle = _Buy(LotSize, StopLoss, TakeProfit);
                if (OrderHandle < 0) OrderError = ErrorDescription(GetLastError());
              }          
          }
      }
           
    return(OrderHandle);
  }
 
эксперт отработал больше месяца, только иногда выскакивают совершенно левые ошибки вроде Trade timeout
 
Без этой проверки постоянно выдавало ошибку Trade context is busy
 
эксперт отработал больше месяца, только иногда выскакивают совершенно левые ошибки вроде Trade timeout
повезло? не знаю... у меня есть эта проверка и ошибки были.
Сейчас нету, уже достаточно давно.
 
везло весь месяц? :-) хммм, я ж говорю ситуация весьма частая когда все 3 эксперта на разных графиках пытались открыться в одно и тоже время по новому бару, таймфрейм у них один и тот же. Причем с голосовым сопровождением - и я просто слышал как 2 или 3 голосовых сообщения накладывались одно на другое. :) Без этой проверки была обычная ситуация когда срабатывал только один эксперт а остальные пролетали.
 
Я в скрипте даже делаю вот так:

BuyWithMsg(0.1, 0, 0);
BuyWithMsg(0.2, 0, 0);
SellWithMsg(0.1, 0, 0);
BuyWithMsg(0.1, 0, 0);

все 4 ордера подряд отрабатывают без вопросов.
 
На счет торговли из двух экспертов работает IsTradeAllowed() проверка, я так понимаю она и таймауты учитывает?
Ничего она не учитывает.... Только флаг в настройках эксперта.

Не только.

Если 2 подряд - он !по идее! сначала закончит с первым, потом возьмётся за второй. Но не факт. И паузы никакой не будет.

Сначала положит первый запрос на ордер в трейдовый поток, потом второй. Если повезет, конечно. Что поток с ними будет делать - тайна. Паузы не будет, это точно.
Если одновременно несколько экспертов, надо городить семафоры, паузы, и т.д. - обсуждалось в теме "Ошибка №6".
В принципе, у меня есть готовое решение - могу поделиться. А скоро я выложу его (решение, библиотеку, т.е.) на mql4.com

При всем уважении, это не решение. Это огород.
Причина обращения: