Изменение отложенного ордера

 

// parameters
string SymbolName = "EURUSD";
int SymbolPeriod = PERIOD_M1;
int MagicNumber = 1;
double dLot = 0.1;

int EnterLongStop = 10;
int StopLoss = 10;

int SymbolSpread;
double SymbolPoint;
double CurrentLot;

int lastBars = 0;

int init()
{
   SymbolSpread = MarketInfo( SymbolName, MODE_SPREAD);
   SymbolPoint = MarketInfo( SymbolName, MODE_POINT);
   CurrentLot = NormalizeDouble( dLot, 1);
   return(0);
}
  
int deinit()
{
   Print("deinit()");
   return(0);
}

int start()
{
   // проверим тип счета, и если это не демо счет выдадим предупрежение
   // и закончим работу 
   if (!IsDemo()) {Alert("На реальном счете работа запрещена"); return;}
   
   if ( isNewBar())
      OnNewBar();

   OnTick();
          
   return(0);
}

bool isNewBar()
{
   if ( lastBars != Bars)
   {
      lastBars = Bars;
      return ( true);
   }
   return ( false);
}

void OnNewBar()
{
//   Print("Новый бар");
   int iHighBar = iHighest( SymbolName, SymbolPeriod, MODE_HIGH, 5, 1);
   double hhv = iHigh( SymbolName, SymbolPeriod, iHighBar);
   double EnterLongStopLevel = NormalizeDouble(  hhv + ( EnterLongStop + SymbolSpread) * SymbolPoint , 4);
   double StopLevel =  NormalizeDouble( EnterLongStopLevel - StopLoss * SymbolPoint, 4);
   
   Print("HHV(4)=", hhv);
   
   int new_ticket;
   
   // Ищем наш ордер
   bool found = false;
   for( int i = OrdersTotal() - 1; i>=0; i--)
   {
      if ( ! OrderSelect( i, SELECT_BY_POS, MODE_TRADES))   continue;
      if ( OrderMagicNumber() != MagicNumber)               continue;
      if ( found)
         Print( "Double Order");

      switch ( OrderType())
      {
         case OP_BUYSTOP:
            if ( OrderOpenPrice() != EnterLongStopLevel)
               OrderModify( OrderTicket(), EnterLongStopLevel, StopLevel, 0, 0, CLR_NONE);
            Print("Modify Order", EnterLongStopLevel, " Error = ", GetLastError(), " OrderTime = ", TimeToStr( OrderOpenTime()));
            break;
         default:
            Print("Wrong Order Type", OrderType());
      }
      found = true;
   }

   if ( !found)
   {
      new_ticket = OrderSend( SymbolName, OP_BUYSTOP, CurrentLot, EnterLongStopLevel, 0, StopLevel, 0, "Cool", MagicNumber, 0, CLR_NONE);
      if( new_ticket < 0)
         Print("OrderSend failed with error #",GetLastError());
      else
         Print("Set OP_BUYSTOP ", EnterLongStopLevel);
   }

   return;
}

void OnTick()
{
//   Print("Новый тик");
   return;
}


на минутном графике иногда возникает Ошибка 1 (при изменении ордера). Хотя, у мну стоит проверка
if ( OrderOpenPrice() != EnterLongStopLevel)
Как сделать, чтобы эта ошибка никогда не вылазила? То есть я не хочу выполнять Modify, если она вернет ошибку 1.

Я пробовал Normalaze, но не получилось. иправил вот так

   if(   qEqual( OrderOpenPrice(), qGetPrice(i), qGetPoint(i))
      && qEqual( OrderStopLoss(), qGetStopLoss(i), qGetPoint(i))
      && qEqual( OrderTakeProfit(), qGetTakeProfit(i), qGetPoint(i)))
   {
      return (COMMAND_DONE);
   }

   OrderModify( qGetTicket( i), qGetPrice( i), qGetStopLoss( i), qGetTakeProfit( i), 0, CLR_NONE);
  ................


bool qEqual( double value1, double value2, double point_value)
{
   return ( MathAbs( value1 - value2) < 0.5 * point_value);
}



Хотелось бы увидеть "человеческий вариант"


 
Очень хочется услышать начальника транспортного цеха! Up
 
Уже много раз говорили, что нельзя сравнивать два вещественных числа на равенство значений.

Заходите на www.mql4.com
 
А нормализованные можно?
у мну
double EnterLongStopLevel = NormalizeDouble( hhv + ( EnterLongStop + SymbolSpread) * SymbolPoint , 4);
double StopLevel = NormalizeDouble( EnterLongStopLevel - StopLoss * SymbolPoint, 4);

получается, что OrderOpenPrice() возвращает ненормализованное значение? или, и нормализованные double отличаются.

И второй вопрос, кто генерирует ошибку 1 сервер или терминал? То есть отправляются ли на сервер ошибочные комманды?
И третий вопрос, можно увидеть код нормализации на c? Думаю, это не know how. :) Мне в dll охота вставить его.

Кстати, первый вопрос изначально звучал так.
Как сделать, чтобы эта ошибка никогда не вылазила? То есть я не хочу выполнять Modify, если она вернет ошибку 1.

А может, мой вариант с qEqual и есть самый правильный и пацанский?
 
Нормализованные значения тоже нельзя сравнивать на равенство. Нормализуйте разницу значений и сравните её с 0. С 0 можно сравнивать любые значения.

Ошибку 1 генерирует клиентский терминал.

Код нормализации очень прост. Умножить число на 10 в степени digits (можно сразу заготовить таблицу степеней, чтобы каждый раз не возводить), округлить с учётом знака (+0.5 или -0.5) и присвоить длинному целому типа __int64. После этого разделить полученное целое на 10 в степени digits с присвоением к вещественному типу.

Нет, всё-таки лучше сделайте return(NormalizeDouble(val1-val2,8)==0.0);
а ещё лучше сразу if(NormalizeDouble(val1-val2,8)==0.0)
 
Спасибо
 
и присвоить длинному целому типа __int64.
Что за тип? Какие еще есть типы, не упомянутые в документации?
 
Это тип на с и с++. целое 64 бита.
 
Это не тип на с и с++. Такого типа там нет. typedef может быть в конкретных реализациях соответствующих библиотек.
В любом случае, здесь обсуждается не с и с++, а платформа Метатрейдер.
 
Код нормализации очень прост. Умножить число на 10 в степени digits (можно сразу заготовить таблицу степеней, чтобы каждый раз не возводить), округлить с учётом знака (+0.5 или -0.5) и присвоить длинному целому типа __int64. После этого разделить полученное целое на 10 в степени digits с присвоением к вещественному типу.

Трудно представить, что после нормализации по этому алгоритму двух "близких" чисел не будет выполнено равенсто double. Возможно, в указанном мною случае используется 2 разных алгоритма или 2 компилятора разных или на сервере происходит изменение цены ордера, стопа или профита. Или Ваш алгоритм сравнения double на равенство не правильный.
У меня обычно нет большого желания double сравнивать, но если уж значения нормализуются, они должны быть равными, иначе, в чем смысл нормализации?
 
Это не тип на с и с++. Такого типа там нет. typedef может быть в конкретных реализациях соответствующих библиотек.
В любом случае, здесь обсуждается не с и с++, а платформа Метатрейдер.

Человек задал вопрос, как ему самостоятельно делать нормализацию в его собственной dll, написанной на c++. Каждый производитель компиляторов реализует что-то сверх стандарта.

__int64 - это Microsoft specific. Ещё есть такие нотации: __int8, __int16 и __int32
для 64-разрядного целого есть даже форматный символ преобразования, используемый в функциях типа printf - %I64
Причина обращения: