Как правильно модифицировать ордер?

 
Всем привет.
Есть такой кусок кода:

      else if(pos_prof_gl >= 0.10)
      {
      Print("НАДО МОДИФИЦИРОВАТЬ ОРДЕР. Профит равен: ", pos_prof_gl, "-ти" );
      
        // модификация существующей позиции.  
      
      // -------+ вызов функции формирования торгового запроса +--------- 
      if(ModifyOrder(prc, price_bid))
        {
         Print("ПОЗИЦИИ МОДИФИКАЦИРОВАНА. Тейк профит равен:", price_bid);
         Print("Час: "        +(string)stm.hour);
         Print("Минута: "     +(string)stm.min);
         Print("Секунда: "    +(string)stm.sec);
        }
       
      else
      {
        Print("Ошибка Модификации!!!");
      }
       
       
       
      }
      
};

//функция формирующая торговый запрос на открытие позиции и проверку результата открытия  -------------------+

bool SendOrder(double price, double volume, double pos_prof, double prc_bid)
{  
   
   if(volume >= 99){
   Print("ОШИБКА! Обьем Ордера привысил размер 99 лотов и сейчас ровняется", volume,"-м");
   return(false);
   };

   MqlTradeRequest request = {0};
   MqlTradeResult  result  = {0};
   //---заполняем поля торгового запроса
   request.action       = TRADE_ACTION_DEAL;       // Тип выполняемого действия
   request.symbol       = _Symbol;                 // Имя торгового инструмента
   request.magic        = magic_number;
   request.volume       = volume;                  // Запрашиваемый объем сделки в лотах
   request.price        = price;                   // Цена  
   request.type         = ORDER_TYPE_BUY;          // Тип ордера
   request.tp           = price + 40*_Point;       // Цена, по которой сработает Take Profit ордер при движении цены в благоприятном направлении
   request.sl           = price - 270*_Point;      // Цена, по которой сработает Stop Loss ордер при движении цены в неблагоприятном направлении
   request.deviation    = 0;                       // Максимально приемлемое отклонение от запрашиваемой цены, задаваемое в пунктах
   request.type_filling = ORDER_FILLING_FOK;       // Тип ордера по исполнению
   request.type_time    = ORDER_TIME_GTC;
                  
                  
   //---проверим хватает ли средств для открытия позиции
        double margin = 0.0;
                     
   if (!OrderCalcMargin(request.type, request.symbol, request.volume, request.price, margin))
                        return(false);
                     
   if (margin > AccountInfoDouble(ACCOUNT_FREEMARGIN))
                        return(false);
                  
                     
   //---отправка запроса на сервер и проверка результата отправки
   if (OrderSend(request,result))
       {
         if ( result.retcode == TRADE_RETCODE_DONE)
              {
                 return (true);
              };
            };

                                                  
                     return(false);
   };// функция торгового запроса-------------------------------------------------------------------------------------------------+
      
   
   
   
   
   
 //функция формирующая модификацию торгового запроса и проверки результата -------------------+

bool ModifyOrder(double price, double prc_bid)
{  

   MqlTradeRequest request = {0};
   MqlTradeResult  result  = {0};
   //---заполняем поля торгового запроса
   request.action       = TRADE_ACTION_MODIFY;     // Тип выполняемого действия
   request.symbol       = _Symbol;                 // Имя торгового инструмента
   request.tp           = prc_bid;                 // Цена, по которой сработает Take Profit ордер при движении цены в благоприятном направлении
   request.sl           = price - 270*_Point;      // Цена, по которой сработает Stop Loss ордер при движении цены в неблагоприятном направлении
                  
                  
   //---проверим хватает ли средств для открытия позиции
        double margin = 0.0;
                     
   if (!OrderCalcMargin(request.type, request.symbol, request.volume, request.price, margin))
                        return(false);
                     
   if (margin > AccountInfoDouble(ACCOUNT_FREEMARGIN))
                        return(false);
                  
                     
   //---отправка запроса на сервер и проверка результата отправки
   if (OrderSend(request,result))
       {
         if ( result.retcode == TRADE_RETCODE_DONE)
              {
                 return (true);
              };
            };

                                                  
   
   return(false);
   
   };// функция модификации торгового запроса-------------------------------------------------------------------------------------------------+
Вопрос:
Почему не срабатывает модификация тейк профита?
(2 принта помеченные оранжевым цветом срабатывают при этом.)

P.S. Буду благодарен за любые советы..
 
Mike_Kharkov:
Всем привет.
Есть такой кусок кода:

Вопрос:
Почему не срабатывает модификация тейк профита?
(2 принта помеченные оранжевым цветом срабатывают при этом.)

P.S. Буду благодарен за любые советы..

Модифицируете короткую или длинную позицию?

 
elugovoy:

Модифицируете короткую или длинную позицию?

   Длинную.
 
Mike_Kharkov:
Всем привет.
Есть такой кусок кода:

Вопрос:
Почему не срабатывает модификация тейк профита?
(2 принта помеченные оранжевым цветом срабатывают при этом.)

P.S. Буду благодарен за любые советы..
разные переменные
if(ModifyOrder(prc, price_bid))


bool ModifyOrder(double price, double prc_bid)
 

Ну нужно по порядку разбираться.

Во-первых, доходит ли исполнение до 

//---отправка запроса на сервер и проверка результата отправки
   if (OrderSend(request,result))
       {
         if ( result.retcode == TRADE_RETCODE_DONE)
              {
                 return (true);
              };
            };

Поставьте Print перед этим участком, чтобы видеть проходят ли условия по марже.

Во-вторых, Print после OrderSend (перед if (result.retcode)) с выводом result.retcode, и в дополнение else с выводом ошибки GetLastError().

Тогда получим больше деталей об отказе функции.

 
bizon:
разные переменные
   Я не силен в программировании - но насколько знаю это допускается в данном случае?
   То есть как я понимаю в одном месте при создании функции я прописываю параметры в виде переменных.
   А в другом месте(во время вызова), как мне обьясняли можно уже передавать в это место значение в виде других переменных..
 
elugovoy:

Ну нужно по порядку разбираться.

Во-первых, доходит ли исполнение до 

Поставьте Print перед этим участком, чтобы видеть проходят ли условия по марже.

Во-вторых, Print после OrderSend (перед if (result.retcode)) с выводом result.retcode, и в дополнение else с выводом ошибки GetLastError().

Тогда получим больше деталей об отказе функции.

   Изменил код следующим образом:
   //---проверим хватает ли средств для открытия позиции
        double margin = 0.0;
                     
   if (!OrderCalcMargin(request.type, request.symbol, request.volume, request.price, margin))
       {
                        Print("Условия по марже");
                        return(false);
        }             
   if (margin > AccountInfoDouble(ACCOUNT_FREEMARGIN))
               {
                        Print("Условия по марже_2");
                        return(false);
                }  
                     
   //---отправка запроса на сервер и проверка результата отправки
   if (OrderSend(request,result))
       {
         if ( result.retcode == TRADE_RETCODE_DONE)
              {
                 Print("TRADE_RETCODE_DONE");
                 return (true);
              };
            };

                                                  
   
   return(false);
   
   };// функция модификации торгового запроса-------------------------------------------------------------------------------------------------+
Тестируя на истории в журнале - получил вот такой результат:

Но какой вывод из этого я должен сделать мне пока не понятно? )
Не ужели маржи не хватает для модификации ордера? )
(Она же там вообще ни при чем по идее..)

 
Mike_Kharkov:
   Изменил код следующим образом:
Тестируя на истории в журнале - получил вот такой результат:

Но какой вывод из этого я должен сделать мне пока не понятно? )
Не ужели маржи не хватает для модификации ордера? )
(Она же там вообще ни при чем по идее..)

Не совсем то о чем я говорил.

   //---проверим хватает ли средств для открытия позиции
        double margin = 0.0;
                     
   if (!OrderCalcMargin(request.type, request.symbol, request.volume, request.price, margin))
       {
                        Print("Условия по марже");
                        return(false);
       }
   Print ("Первое условие по марже - ОК");
   if (margin > AccountInfoDouble(ACCOUNT_FREEMARGIN))
               {
                        Print("Условия по марже_2");
                        return(false);
                }  
   Print ("Второе условие по марже - ОК");
                     
   //---отправка запроса на сервер и проверка результата отправки
   if (OrderSend(request,result))
       {
        Print ("Запрос отправлен, результат:",result.retcode);

         if ( result.retcode == TRADE_RETCODE_DONE)
              {
                 Print("TRADE_RETCODE_DONE");
                 return (true);
              };
       }
    else
       {
        Print("Ошибка при отправке запроса #", GetLastError());
       };

                                                  
   
   return(false);
   
   };// функция модификации торгового запроса-------------------------------------------------------------------------------------------------+

Попробуйте так, увидите что по марже оба условия выполняются, далее, возможно OrderSend даст ошибку и увидите "Ошибка при отправке запроса #" с номером ошибки. Далее ищем справку и смотрим по коду ошибки.

Если же получите "Запрос отправлен, результат:" с кодом результата, посмотрите что за код. Могут быть TRADE_RETCODE_PLACED вместо TRADE_RETCODE_DONE...



 
elugovoy:
Попробуйте так



   Попробовал - но вроде получается тоже самое.

  
 
Mike_Kharkov:
   Попробовал - но вроде получается тоже самое.

  
А после изменений, код перекомпилировали? выглядит так, будто ваш предыдущий код работает только.
 
elugovoy:
А после изменений, код перекомпилировали? выглядит так, будто ваш предыдущий код работает только.
   да. компилировал.
  
   Можите сами проверить.
   (если есть желание.)
  
  
//+------------------------------------------------------------------+
//|                                                  My_Practics.mq5 |
//+------------------------------------------------------------------+
#property copyright "Mike_Kharkov"
#property link      "https://www.fl.ru/users/Yamaradg/"
#property version   "1.00"
double COEF  = 1.0;                                              // коэффициент кратности увеличения лота
int    DELTA = 222;                                               // количество пунктов прохода цены для уведичения позиции
ulong  magic_number = 87654321;                                  // магический ордер
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Expert Get history price function                                |
//+------------------------------------------------------------------+
double GetHistoryPrice( const string aSymbol )
{
  double price_in = 0;
  double volume_in = 0;
  
  if ( PositionSelect( aSymbol ) )
  {
    long pos_id = long( PositionGetInteger( POSITION_IDENTIFIER ) );
    
    if ( pos_id > 0 )
    {
      if ( HistorySelectByPosition( ulong( pos_id ) ) )
      {
        int deals = HistoryDealsTotal();
      
        for( int i = 0; i < deals; i++ )
        {
          ulong deal_ticket = HistoryDealGetTicket( i );
          ulong order_ticket = ulong( HistoryDealGetInteger( deal_ticket, DEAL_ORDER ) );
        
          if ( order_ticket > 0 )
          {
            long deal_entry = long( HistoryDealGetInteger( deal_ticket, DEAL_ENTRY ) );
              
            if ( deal_entry == DEAL_ENTRY_IN )
            {
              double price = HistoryDealGetDouble( deal_ticket, DEAL_PRICE );
              double volume = HistoryDealGetDouble( deal_ticket, DEAL_VOLUME );
                                
              price_in = price_in + price * volume;
              volume_in = volume_in + volume;  
            }
          }
        }
        if ( volume_in > 0 ) return( NormalizeDouble( price_in / volume_in, _Digits ) );
      }
      else
      {
        Print( "Не возможно получить историю позиции по символу ", aSymbol );
      }
    }
    else
    {
      Print( "Не возможно определить идентификатор позиции по символу ", aSymbol );
    }
  }
  return( 0 );
}
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+


int OnInit()
{  
//---
   
//---
   return(INIT_SUCCEEDED);
}//---------------------------------------------------------------------------+



//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+


void OnDeinit(const int reason)
{
//---
}//---------------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+


void OnTick()
{ 
      datetime    tm=TimeCurrent();
      MqlDateTime stm;
      TimeToStruct(tm,stm); 
  
      // вызываем функцию вычисления последнего ордера и преобразовываем результат в 5-ти значное число.
      double hist_price = GetHistoryPrice(_Symbol);
      
      double prc = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      
      double price_bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
      
      double posVolume = PositionGetDouble(POSITION_VOLUME);
    
      // Подсчитываем профит текущей позиции
      double pos_prof_gl = NormalizeDouble(PositionGetDouble(POSITION_PROFIT), 2);
      
      if(!PositionSelect(_Symbol))
      {
        pos_prof_gl = 0;
      };
      
      Print("ТЕКУЩИЙ ПРОФИТ: ", pos_prof_gl);
      Print("ТЕКУЩИЙ BID: ", price_bid);
      
    
    
    
    if(!PositionSelect(_Symbol) && stm.hour >= 1 && stm.hour <= 5)
    {

      // вызываем функцию, подсчитывающую кол-во лотов для стартовой сделки
      double trade_lot = function_trade_lot(AccountInfoDouble(ACCOUNT_BALANCE));
      
      
      if(SendOrder(prc, trade_lot, pos_prof_gl, price_bid))
       {
         // первоначальная позиция открыта..
         Print("Первоначальное открытие");
         Print("Час: "        +(string)stm.hour);
         Print("Минута: "     +(string)stm.min);
         Print("Секунда: "    +(string)stm.sec);
       }
     
      }
      
      
      
      else if(pos_prof_gl < 0.10)
      {
        // доливка существующей позиции.  
      
      //увеличим размер позиции на коэффициент
      double lot = posVolume * COEF;
      
      double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      
      if(ask <= hist_price - DELTA * _Point)
      {
      
      // -------+ вызов функции формирования торгового запроса +--------- 
      if(SendOrder(prc, lot, pos_prof_gl, price_bid))
        {
         Print("Позиция добавлена");
         Print("Час: "        +(string)stm.hour);
         Print("Минута: "     +(string)stm.min);
         Print("Секунда: "    +(string)stm.sec);
        }
       
       }
      }
      
      
      
      
      else if(pos_prof_gl >= 0.10)
      {
      Print("НАДО МОДИФИЦИРОВАТЬ ОРДЕР. Профит равен: ", pos_prof_gl, "-ти" );
      
        // модификация существующей позиции.  
      
      // -------+ вызов функции формирования торгового запроса +--------- 
      if(ModifyOrder(prc, price_bid))
        {
         Print("ПОЗИЦИИ МОДИФИКАЦИРОВАНА. Тейк профит равен:", price_bid);
         Print("Час: "        +(string)stm.hour);
         Print("Минута: "     +(string)stm.min);
         Print("Секунда: "    +(string)stm.sec);
        }
       
      else
      {
        Print("Ошибка Модификации!!!");
      }
       
       
       
      }
      
};

//функция формирующая торговый запрос на открытие позиции и проверку результата открытия  -------------------+

bool SendOrder(double price, double volume, double pos_prof, double prc_bid)
{  
   
   if(volume >= 99){
   Print("ОШИБКА! Обьем Ордера привысил размер 99 лотов и сейчас ровняется", volume,"-м");
   return(false);
   };

   MqlTradeRequest request = {0};
   MqlTradeResult  result  = {0};
   //---заполняем поля торгового запроса
   request.action       = TRADE_ACTION_DEAL;       // Тип выполняемого действия
   request.symbol       = _Symbol;                 // Имя торгового инструмента
   request.magic        = magic_number;
   request.volume       = volume;                  // Запрашиваемый объем сделки в лотах
   request.price        = price;                   // Цена  
   request.type         = ORDER_TYPE_BUY;          // Тип ордера
   request.tp           = price + 400*_Point;       // Цена, по которой сработает Take Profit ордер при движении цены в благоприятном направлении
   request.sl           = price - 2700*_Point;      // Цена, по которой сработает Stop Loss ордер при движении цены в неблагоприятном направлении
   request.deviation    = 0;                       // Максимально приемлемое отклонение от запрашиваемой цены, задаваемое в пунктах
   request.type_filling = ORDER_FILLING_FOK;       // Тип ордера по исполнению
   request.type_time    = ORDER_TIME_GTC;
                  
                  
   //---проверим хватает ли средств для открытия позиции
        double margin = 0.0;
                     
   if (!OrderCalcMargin(request.type, request.symbol, request.volume, request.price, margin))
                        return(false);
                     
   if (margin > AccountInfoDouble(ACCOUNT_FREEMARGIN))
                        return(false);
                  
                     
   //---отправка запроса на сервер и проверка результата отправки
   if (OrderSend(request,result))
       {
         if ( result.retcode == TRADE_RETCODE_DONE)
              {
                 return (true);
              };
            };

                                                  
                     return(false);
   };// функция торгового запроса-------------------------------------------------------------------------------------------------+
      
   
   
   
   
   
 //функция формирующая модификацию торгового запроса и проверки результата -------------------+

bool ModifyOrder(double price, double prc_bid)
{  

   MqlTradeRequest request = {0};
   MqlTradeResult  result  = {0};
   //---заполняем поля торгового запроса
   request.action       = TRADE_ACTION_MODIFY;     // Тип выполняемого действия
   request.symbol       = _Symbol;                 // Имя торгового инструмента
   request.tp           = prc_bid;                 // Цена, по которой сработает Take Profit ордер при движении цены в благоприятном направлении
   request.sl           = price - 270*_Point;      // Цена, по которой сработает Stop Loss ордер при движении цены в неблагоприятном направлении
                  
                  
   //---проверим хватает ли средств для открытия позиции
        double margin = 0.0;
                     
   if (!OrderCalcMargin(request.type, request.symbol, request.volume, request.price, margin))
       {
                        Print("Условия по марже");
                        return(false);
       }
   Print ("Первое условие по марже - ОК");
   if (margin > AccountInfoDouble(ACCOUNT_FREEMARGIN))
               {
                        Print("Условия по марже_2");
                        return(false);
                }  
   Print ("Второе условие по марже - ОК");
                     
   //---отправка запроса на сервер и проверка результата отправки
   if (OrderSend(request,result))
       {
        Print ("Запрос отправлен, результат:",result.retcode);

         if ( result.retcode == TRADE_RETCODE_DONE)
              {
                 Print("TRADE_RETCODE_DONE");
                 return (true);
              };
       }
    else
       {
        Print("Ошибка при отправке запроса #", GetLastError());
       };

                                                  
   
   return(false);
   
   };// функция модификации торгового запроса-------------------------------------------------------------------------------------------------+
   
   
   
   
   
   
   

// возвращает цену открытия последнего ордера, где nMode - ORDER_TYPE_BUY/ORDER_TYPE_SELL ----------+
// для позиции с идентификатором PositionID
double FindLastPrice(int nMode)
  {
    int  CntPos;               // количество ордеров в истории
    ulong nTicket;             // тикет выбранного ордера из истории
    ulong OldTicket = 0;       // тикет ордера найденного ранее
    long PosID, PosiID;        // идентификатор позиции, к которой относится выбранный ордер
    //long Magic;              // магический номер
    long Type;                 // тип найденного ордера (Buy или Sell)
    double OrderPrice = 0;     // найденная цена
    // идентификатор позиции
    if((PosiID = PositionGetInteger(POSITION_IDENTIFIER))==0) return(0.0);
    
    // создадим список ордеров и сделок, находящихся в истории
    HistorySelect(0, TimeCurrent());
    
    CntPos = HistoryOrdersTotal(); // количество ордеров в истории
    
    // переберем все ордеры истории и отберем те, что относятся к нашей открытой позиции
    for (int i = 0; i < CntPos; i++)
      {
        nTicket = HistoryOrderGetTicket(i);  // получим тикет очередного ордера
        PosID  = HistoryOrderGetInteger(nTicket, ORDER_POSITION_ID);  // позиция ордера
        Type   = HistoryOrderGetInteger(nTicket, ORDER_TYPE);         // тип ордера
        
        if ((PosID == PosiID) && (Type == nMode)) 
          {
            if (nTicket > OldTicket)  // этот ордер был открыт позже найденного ранее
              {
                OrderPrice = HistoryOrderGetDouble(nTicket, ORDER_PRICE_OPEN); // цена открытия ордера
                OldTicket = nTicket; // запомним тикет
              };
          };
      };
      
    return(OrderPrice);
  };//---------------------------------------------------------------------------+

  
// ---- функция подсчета значения стартового лота. ------------------------------+

       double function_trade_lot(double account_balance ){
       
          double lot = 0.01;
          
          //lot = NormalizeDouble(0.01+MathMax(MathFloor((account_balance-100000)/50000),0)*0.01,2);
          
          //lot = MathMin(lot, SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX));
          
          
    return(lot);
  
  };//---------------------------------------------------------------------------+