Скачать MetaTrader 5

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

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Где найти программиста? В сервисе Фриланс!
Mike Kharkov
846
Mike Kharkov 2014.08.17 06:03 
Всем привет.
Есть такой кусок кода:

      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. Буду благодарен за любые советы..
Eugeniy Lugovoy
1979
Eugeniy Lugovoy 2014.08.17 17:19  
Mike_Kharkov:
Всем привет.
Есть такой кусок кода:

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

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

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

Mike Kharkov
846
Mike Kharkov 2014.08.18 06:18  
elugovoy:

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

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

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

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


bool ModifyOrder(double price, double prc_bid)
Eugeniy Lugovoy
1979
Eugeniy Lugovoy 2014.08.18 11:27  

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

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

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

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

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

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

Mike Kharkov
846
Mike Kharkov 2014.08.18 12:19  
bizon:
разные переменные
   Я не силен в программировании - но насколько знаю это допускается в данном случае?
   То есть как я понимаю в одном месте при создании функции я прописываю параметры в виде переменных.
   А в другом месте(во время вызова), как мне обьясняли можно уже передавать в это место значение в виде других переменных..
Mike Kharkov
846
Mike Kharkov 2014.08.18 12:30  
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);
   
   };// функция модификации торгового запроса-------------------------------------------------------------------------------------------------+
Тестируя на истории в журнале - получил вот такой результат:

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

Eugeniy Lugovoy
1979
Eugeniy Lugovoy 2014.08.18 15:06  
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...



Mike Kharkov
846
Mike Kharkov 2014.08.18 15:56  
elugovoy:
Попробуйте так



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

  
Eugeniy Lugovoy
1979
Eugeniy Lugovoy 2014.08.18 16:49  
Mike_Kharkov:
   Попробовал - но вроде получается тоже самое.

  
А после изменений, код перекомпилировали? выглядит так, будто ваш предыдущий код работает только.
Mike Kharkov
846
Mike Kharkov 2014.08.18 19:35  
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);
  
  };//---------------------------------------------------------------------------+
123
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий