StopLevel и FreezeLevel. Проверять стоит?

 

 Я сколько терминалов открывал, везде эти параметры равны нулям. В стандартной библиотеке тоже их не учитывают. Сколько смотрел чего в кодобазе, там тоже не попадалось ничего. В мт4 ещё у меня было написано несколько методов для работы со стопами и учёта всех этих моментов. Но там совсем другая структура. Сразу одним махом не скопировать ((

 Возник вопрос. А кто-нить вообще их обрабатывает?

 
hoz:

 Я сколько терминалов открывал, везде эти параметры равны нулям. В стандартной библиотеке тоже их не учитывают. Сколько смотрел чего в кодобазе, там тоже не попадалось ничего. В мт4 ещё у меня было написано несколько методов для работы со стопами и учёта всех этих моментов. Но там совсем другая структура. Сразу одним махом не скопировать ((

 Возник вопрос. А кто-нить вообще их обрабатывает?

      //+------------------------------------------------------------------+
      st_lv=0;
      fr_lv=0;
      st_fr_lv=0;
      if(!SymbolInfoInteger(symb,SYMBOL_TRADE_STOPS_LEVEL,st_lv))
        {Print("st_lv=",st_lv,"   error=",GetLastError());return;}
      if(!SymbolInfoInteger(symb,SYMBOL_TRADE_FREEZE_LEVEL,fr_lv))
        {Print("fr_lv=",fr_lv,"   error=",GetLastError());return;}
      st_fr_lv=MathMax(st_lv,fr_lv);
      //+------------------------------------------------------------------+

Как-то так обрабатываю и учитываю. Надо бы индюка написать по учёту StopLevel и FreezeLevel. На сутки поставить на все пары и отловить. Где FreezeLevel появляется? Даже интересно. Бывает или нет. Сделаю.

 
Vladimir M.:

Как-то так обрабатываю и учитываю. Надо бы индюка написать по учёту StopLevel и FreezeLevel. На сутки поставить на все пары и отловить. Где FreezeLevel появляется? Даже интересно. Бывает или нет. Сделаю.

У меня по сложнее всё. Но там сразу не осилить, если выложу)) Отлов в любых ситуациях. Но нужно оно или нет, вопрос..

 
hoz:

... Но нужно оно или нет, вопрос..

Если есть в документации значит бывает, а значит нужно учитывать, что б не было неожиданностей. Завтра на запись в лог поставлю, во все советники.

Покажите, как это хоть кто-нибудь делает!?

 
Vladimir M.:

Если есть в документации значит бывает, а значит нужно учитывать, что б не было неожиданностей. Завтра на запись в лог поставлю, во все советники.

Покажите, как это хоть кто-нибудь делает!?

Раньше было так:

//=========================================================================================================================================
// 2.3 Проверка ограничений по STOPLEVEL и FREEZELEVEL позций. ============================================================================
bool PositionHandling :: checkLevelsBLOCK(SymbolProperties& Sym,                // Структура данных рыночного окружения выбранного инструмента
                                          PositionProperties& Pos,              // Структура свойств позиции
                                          int     operationType,                // Тип проводимой операции: 1 - Close/Del; 2 - Send; 3 - Modify;
                                          double& newOpenPrice,                 // Новая цена открытия
                                          bool&   isIvalidPriceCorrection) {    // Флаг первоначальной коррекции отложки
  //----
  Sym.stopLevel = (int)(MarketInfo(Pos.instrument, MODE_STOPLEVEL) * Sym.pt);
  Sym.freezeLevel = (int)(MarketInfo(Pos.instrument, MODE_FREEZELEVEL) * Sym.pt);
  bool existStopLevel = Sym.stopLevel > 0 ? checkStopLevelDemand(Sym, Pos, operationType, newOpenPrice, isIvalidPriceCorrection) :  false;
  bool existFreezeLevel = Sym.freezeLevel > 0 ? checkFreezeLevelDemand(Sym, Pos, operationType, newOpenPrice) : false;
  if ((existStopLevel == true) && (existFreezeLevel == true))
    return (true);
  return (false);
}
//=========================================================================================================================================
// 2.4 Проверка требования по параметру STOPLEVEL позиций. ================================================================================
bool PositionHandling :: checkStopLevelDemand(SymbolProperties& Sym,                 // Структура данных рыночного окружения выбранного инструмента
                                              PositionProperties& Pos,               // Структура свойств позиции
                                              int     operationType,                 // Тип проводимой операции: 1 - Close/Del; 2 - Send; 3 - Modify;
                                              double& newOpenPrice,                  // Новая цена открытия
                                              bool&   isIvalidPriceCorrection) {     // Флаг первоначальной коррекции отложки
  bool   existStopLevel = false,
         isNewOrder = false;
  double marketPrice = 0.0;
  int    cmd, li_cmd;

//---- Получение первоначальных данных
  if (Pos.type % 2 == 0) {
    cmd = 1;
    if (Pos.type == 0) li_cmd = 0;
    else               li_cmd = 1;
  }
  else {
    cmd = -1;
    if (Pos.type == 1) li_cmd = 1;
    else               li_cmd = 0;
  }
  marketPrice = Sym.price[li_cmd];
  
  ResetLastError();    // Обнуляем переменную наличия ошибки.

  //---- Блок проверки на StopLevel
  switch (operationType) {
    case 1:    //---- Close\Delete orders
      return (true);
    case 2:    //---- Send orders
      switch (Pos.type) {
        case 0:    //---- Send BUY
          existStopLevel = ((Sym.stopLevel <= marketPrice - Pos.newSL || Pos.newSL == 0) && (Sym.stopLevel <= Pos.newTP - marketPrice || Pos.newTP == 0));
          break;
        case 1:    //---- Send SELL
          existStopLevel = ((Sym.stopLevel <= Pos.newSL - marketPrice || Pos.newSL == 0) && (Sym.stopLevel <= marketPrice - Pos.newTP || Pos.newTP == 0));
          break;
        case 2:    //---- Send BUYLIMIT
          if ((Sym.stopLevel <= marketPrice - newOpenPrice) && (Sym.stopLevel <= newOpenPrice - Pos.newSL || Pos.newSL == 0) && (Sym.stopLevel <= Pos.newTP - newOpenPrice || Pos.newTP == 0))
            existStopLevel = true;
          break;
        case 3:    //---- Send SELLLIMIT
          if ((Sym.stopLevel <= newOpenPrice - marketPrice) && (Sym.stopLevel <= Pos.newSL - newOpenPrice || Pos.newSL == 0) && (Sym.stopLevel <= newOpenPrice - Pos.newTP || Pos.newTP == 0))
            existStopLevel = true;
          break;
        case 4:    //---- Send BUYSTOP
          if ((Sym.stopLevel <= newOpenPrice - marketPrice) && (Sym.stopLevel <= newOpenPrice - Pos.newSL || Pos.newSL == 0) && (Sym.stopLevel <= Pos.newTP - newOpenPrice || Pos.newTP == 0))
            existStopLevel = true;
          break;
        case 5:    //---- Send SELLSTOP
          if ((Sym.stopLevel <= marketPrice - newOpenPrice) && (Sym.stopLevel <= Pos.newSL - newOpenPrice || Pos.newSL == 0) && (Sym.stopLevel <= newOpenPrice - Pos.newTP || Pos.newTP == 0))
            existStopLevel = true;
          break;
      }
      break;
    case 3:    //---- Modify orders
      switch (Pos.type) {
        case 0:    //---- Modify BUY
          existStopLevel = ((Sym.stopLevel <= marketPrice - Pos.newSL || Pos.newSL == 0) && (Sym.stopLevel <= Pos.newTP - marketPrice || Pos.newTP == 0));
          if (Pos.newSL >= marketPrice)
            return (false);
          break; 
        case 1:    //---- Modify SELL
          existStopLevel = ((Sym.stopLevel <= Pos.newSL - marketPrice || Pos.newSL == 0) && (Sym.stopLevel <= marketPrice - Pos.newTP || Pos.newTP == 0));
          if (Pos.newSL <= marketPrice)
            return (false);
          break;
        case 2:    //---- Modify BUYLIMIT
          if ((Sym.stopLevel <= Pos.openPrice - Pos.curSL || Pos.curSL == 0) && (Sym.stopLevel <= Pos.curTP - Pos.openPrice || Pos.curTP == 0)) {
            if ((Sym.stopLevel <= marketPrice - newOpenPrice) && (Sym.stopLevel <= newOpenPrice - Pos.newSL || Pos.newSL == 0) && (Sym.stopLevel <= Pos.newTP - newOpenPrice || Pos.newTP == 0))
            existStopLevel = true;
          }
          break;                 
        case 3:    //---- Modify SELLLIMIT
          if ((Sym.stopLevel <= Pos.curSL - Pos.openPrice || Pos.curSL == 0) && (Sym.stopLevel <= Pos.openPrice - Pos.curTP || Pos.curTP == 0)) {
            if ((Sym.stopLevel <= newOpenPrice - marketPrice) && (Sym.stopLevel <= Pos.newSL - newOpenPrice || Pos.newSL == 0) && (Sym.stopLevel <= newOpenPrice - Pos.newTP || Pos.newTP == 0))
            existStopLevel = true;
          }
          break;
        case 4:    //---- Modify BUYSTOP
          if ((Sym.stopLevel <= Pos.openPrice - Pos.curSL || Pos.curSL == 0) && (Sym.stopLevel <= Pos.curTP - Pos.openPrice || Pos.curTP == 0)) {
            if ((Sym.stopLevel <= newOpenPrice - marketPrice) && (Sym.stopLevel <= newOpenPrice - Pos.newSL || Pos.newSL == 0) && (Sym.stopLevel <= Pos.newTP - newOpenPrice || Pos.newTP == 0))
            existStopLevel = true;
          }
          break; 
        case 5:    //---- Modify SELLSTOP
          if ((Sym.stopLevel <= Pos.curSL - Pos.openPrice ||  Pos.curSL == 0) && (Sym.stopLevel <= Pos.openPrice - Pos.curTP || Pos.curTP == 0)) {
            if ((Sym.stopLevel <= marketPrice - newOpenPrice) && (Sym.stopLevel <= Pos.newSL - newOpenPrice || Pos.newSL == 0) && (Sym.stopLevel <= newOpenPrice - Pos.newTP || Pos.newTP == 0))
            existStopLevel = true;
          }
          break;
      }
  }

  //---- Если не выполняются условия STOPLEVEL
  if (!existStopLevel) {
    if (Pos.type < 2) {
      if (isNewOrder) {    // На Send меняем цены местами
        if (Pos.type % 2 == 0) {
          if (Pos.type == 0) li_cmd = 1;
          else               li_cmd = 0;
        }
        else {
          if (Pos.type == 1) li_cmd = 0;
          else               li_cmd = 1;
        }
      }
         
      if (Pos.newSL != 0.0) {
        if (cmd * (marketPrice - Pos.newSL) < Sym.stopLevel)
          if (cmd * (marketPrice - Pos.newSL) > 0.0)
            err.m_errorInfo = StringConcatenate("STOPLEVEL[", Sym.stopLevel, "] > for NewSL[", cmd * marketPrice - Pos.newSL, "]");
       }
      
      if (Pos.newTP != 0.0) {
        if (cmd * (Pos.newTP - marketPrice) < Sym.stopLevel)
          if (cmd * (Pos.newTP - marketPrice) > 0.0)
            err.m_errorInfo = StringConcatenate("STOPLEVEL[", Sym.stopLevel, "] > for NewTP[", cmd * (Pos.newTP - marketPrice), "]");
      }

      logging.writeLog(StringConcatenate(getNameOP(Pos.type), ": ", err.m_errorInfo));
            
      //---- Корректируем СТОПы у рыночных ордеров
      if (!checkValidStops(Sym, Pos, Sym.price[li_cmd], isNewOrder)) {
        logging.writeLog("fCheck_ValidStops(): Изменить СТОПы не получилось !!!");
        return (false);
      }
      else
        return (true);
    }
    else {
      //---- Корректируем цену открытия (или модификации) и СТОПы у отложенных ордеров
      checkValidOOP(Sym, Pos, marketPrice, isIvalidPriceCorrection, isNewOrder);
      return (true);
    }
  }
  //---- Контролируем возможные ошибки
  if (_LastError > 0)
    logging.writeLog(StringConcatenate(__FUNCTION__, err.errorToString(_LastError)));
  //----
  return existStopLevel;
}
//=========================================================================================================================================
// 2.5 Проверка требования по параметру FREEZELEVEL позиций. ==============================================================================
bool PositionHandling :: checkFreezeLevelDemand (SymbolProperties& Sym,    // Структура данных рыночного окружения выбранного инструмента
                                               PositionProperties& Pos,    // Структура свойств позиции
                                               int     operationType,      // Тип проводимой операции: 1 - Close/Del; 2 - Send; 3 - Modify;
                                               double& newOpenPrice) {     // Новая цена открытия
  bool   existFreezeLevel = false;
  double marketPrice = 0.0;
  int    cmd, li_cmd;
   
  //---- Получение первоначальных данных
  if (Pos.type % 2 == 0) {
    cmd = 1;
    if (Pos.type == 0) li_cmd = 0;
    else               li_cmd = 1;
  }
  else {
    cmd = -1;
    if (Pos.type == 1) li_cmd = 1;
    else               li_cmd = 0;
  }
  marketPrice = Sym.price[li_cmd];
  
  ResetLastError();   // Обнуляем переменную наличия ошибки.
   
  //---- Блок проверки на FreezeLevel
  if (operationType == 1 || operationType == 3) {    // 1 - Close/Del; 3 - Modify;
    if (operationType == 1) {    // 1 - Close/Del;
      if (Pos.curSL == 0 && Pos.curTP == 0)
      return (true);
    }
    
    if (Pos.type < 2) {
      existFreezeLevel = ((cmd * (marketPrice - Pos.curSL) > Sym.freezeLevel || Pos.curSL == 0) && (cmd * (Pos.curTP - marketPrice) > Sym.stopLevel ||  Pos.curTP == 0));
    }
    else {
      existFreezeLevel = ((cmd * (newOpenPrice - Pos.curSL) > Sym.stopLevel || Pos.curSL == 0) && (cmd * (Pos.curTP - newOpenPrice) > Sym.freezeLevel || Pos.curTP == 0));
    }
      
    if (!existFreezeLevel) {
      err.m_errorInfo = StringConcatenate(getNameOP (Pos.type), "[", OrderTicket(), "]: Не выполнены условия сервера на FreezeLevel !!!");
      return (false);
    }
  }
  else {    // 2 - Send;
    if (Pos.newSL == 0 && Pos.newTP == 0)
    return (true);
  }
  return existFreezeLevel;
}

Сейчас я вижу, что структура торгового инструмент, здесь Sym, которую я передавал по ссылке уже не актуальна. Я её заменил клаасом. Так же и с структурой позиции. Но вот меня озадачивает следующий вопрос: класс позиции, если в нём не нужно ничего хранить передавать можно по ссылке или нужно обязательно создавать экземпляр и передавать указатель? Я как-то в этом ещё не совсем чётко имею опыт. По ссылке обычно передаю, но, в данном случает там много чего завяазано. Поэтому ещё придётся подумать 10 раз, прежде пойму, где указатель создать, а где его удалить... Меня это уже 2 дня грузит..((