Проблемы с выходом из сделки
Страница 1 из 2 1 2 ПоследняяПоследняя
Показано с 1 по 10 из 14

Тема: Проблемы с выходом из сделки

  1. #1
    Новичок Аватар для Mike_Kharkov
    Регистрация
    08.07.2014
    Сообщений
    103
    Promo (¢)
    1,685
    Благодарности
    Получено: 8
    Отправлено: 126

    Проблемы с выходом из сделки

    Всем привет.
    Есть такой код:
    Код:
    //+------------------------------------------------------------------+
    //|                                                  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 = 200;                                               // количество пунктов прохода цены для уведичения позиции
    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 posProfClose = 500;
        
          // Подсчитываем профит текущей позиции
          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 >= 0 && stm.hour <= 23)
        {
    
          // вызываем функцию, подсчитывающую кол-во лотов для стартовой сделки
          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(PositionSelect(_Symbol))
          {
            // доливка существующей позиции.  
          
          //увеличим размер позиции на коэффициент
          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 > posProfClose)
          {
          Print("НАДО МОДИФИЦИРОВАТЬ ОРДЕР. Профит равен: ", pos_prof_gl, "-ти" );
          
            // модификация существующей позиции.  
          
          // -------+ вызов функции формирования торгового запроса +--------- 
          if(ModifyOrder(prc, price_bid, posVolume))
            {
             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 >= 50){
       Print("ОШИБКА! Обьем Ордера привысил размер 50 лотов и сейчас ровняется", 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           = 0;                        // Цена, по которой сработает Take Profit ордер при движении цены в благоприятном направлении
       request.sl           = 0;                       // Цена, по которой сработает Stop Loss ордер при движении цены в неблагоприятном направлении
       request.deviation    = 0;                       // Максимально приемлемое отклонение от запрашиваемой цены, задаваемое в пунктах
       request.type_filling = ORDER_FILLING_IOC;       // Тип ордера по исполнению
       request.type_time    = ORDER_TIME_DAY;          // Тип  длительности действия ордера               
                      
                      
       //---проверим хватает ли средств для открытия позиции
            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, double posVolume)
    {  
    
       MqlTradeRequest request = {0};
       MqlTradeResult  result  = {0};
       //---заполняем поля торгового запроса
       request.action       = TRADE_ACTION_DEAL;       // Тип выполняемого действия
       request.symbol       = _Symbol;                 // Имя торгового инструмента
       request.magic        = magic_number;            // Магический Ордер
       request.volume       = posVolume;               // Запрашиваемый объем сделки в лотах
       request.price        = prc_bid;                 // Цена  
       request.type         = ORDER_TYPE_SELL;         // Тип ордера
       request.tp           = 0;                       // Цена, по которой сработает Take Profit ордер при движении цены в благоприятном направлении
       request.sl           = 0;                       // Цена, по которой сработает Stop Loss ордер при движении цены в неблагоприятном направлении
       request.deviation    = 0;                       // Максимально приемлемое отклонение от запрашиваемой цены, задаваемое в пунктах
       request.type_filling = ORDER_FILLING_IOC;       // Тип ордера по исполнению
       request.type_time    = ORDER_TIME_DAY;          // Тип  длительности действия ордера 
                      
                      
                         
       //---отправка запроса на сервер и проверка результата отправки
       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);
      
      };//---------------------------------------------------------------------------+
    В данной версии кода не работает выход из позиции.
    (это должно происходить в случае, когда профит равен больше 500-ста.
    Оранжевым цветом отметил части кода, которые за это отвечают.)
    Вопрос:
    Почему это проиcходит(условие не срабатывает) и как это пофиксить?

    Вы не можете благодарить!

  2. #2
    Теоретик
    Регистрация
    03.04.2013
    Сообщений
    475
    Promo (¢)
    690
    Благодарности
    Получено: 148
    Отправлено: 79
    PositionGetDouble надо располагать после PositionSelect(_Symbol)

    Вы не можете благодарить!

  3. #3
    Новичок Аватар для Mike_Kharkov
    Регистрация
    08.07.2014
    Сообщений
    103
    Promo (¢)
    1,685
    Благодарности
    Получено: 8
    Отправлено: 126
    Цитата Сообщение от KLoAF Посмотреть сообщение
    PositionGetDouble надо располагать после PositionSelect(_Symbol)
    Вы не могли бы конкретизировать какую именно строку за какой следом необходимо прописать?

    Вы не можете благодарить!

  4. #4
    Теоретик
    Регистрация
    03.04.2013
    Сообщений
    475
    Promo (¢)
    690
    Благодарности
    Получено: 148
    Отправлено: 79
    Mike_Kharkov, пересмотрел ещё раз код: видимо не в этом проблема, ибо выбор позиции происходит в функции GetHistoryPrice(_Symbol);

    - - - Добавлено - - -

    Не знаю в чём проблема...Надо бы через функцию Print проследить ошибку

    Вы не можете благодарить!

  5. #5
    Новичок Аватар для Mike_Kharkov
    Регистрация
    08.07.2014
    Сообщений
    103
    Promo (¢)
    1,685
    Благодарности
    Получено: 8
    Отправлено: 126
    Цитата Сообщение от KLoAF Посмотреть сообщение
    Mike_Kharkov, пересмотрел ещё раз код: видимо не в этом проблема, ибо выбор позиции происходит в функции GetHistoryPrice(_Symbol);

    - - - Добавлено - - -

    Не знаю в чём проблема...Надо бы через функцию Print проследить ошибку
    А как это делается на примере можите показать?
    Например я прописал такие принты:
    Print("ТЕКУЩИЙ ПРОФИТ: ", pos_prof_gl);
    Print("ТЕКУЩИЙ BID: ", price_bid);
    Дальше тестирую в тестере с визуализацией и вижу, что условие уже должно сработать(прибыль больше 500-ста)
    но оно не срабатывает.
    https://yadi.sk/i/qLhK-DdnbknWf
    Какой я должен делать из этого вывод?
    Или какой ещё принт можно прописать, что бы что то проверить для себя в данном контексте?

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

    Вы не можете благодарить!
    Последний раз редактировалось Mike_Kharkov; 01.10.2014 в 12:58.

  6. #6
    Теоретик
    Регистрация
    03.04.2013
    Сообщений
    475
    Promo (¢)
    690
    Благодарности
    Получено: 148
    Отправлено: 79
    Например, есть Print("НАДО МОДИФИЦИРОВАТЬ ОРДЕР. Профит равен: ", pos_prof_gl, "-ти" ); Выполняется ли оно? Если нет, то идём дальше и проверяем pos_prof_gl и posProfClose (сразу после else помещаем Print("pos_prof_gl=",pos_prof_gl); вместо else if(pos_prof_gl > posProfClose)). и т.д. Т.е. явно там, где вы ожидаете один результат получается другой
    Просто условий много и сложно тут сказать где ошибка, во-всяком случае навскидку не видно...

    Вы не можете благодарить!

  7. #7
    Новичок Аватар для Mike_Kharkov
    Регистрация
    08.07.2014
    Сообщений
    103
    Promo (¢)
    1,685
    Благодарности
    Получено: 8
    Отправлено: 126
    Цитата Сообщение от KLoAF Посмотреть сообщение
    Например, есть Print("НАДО МОДИФИЦИРОВАТЬ ОРДЕР. Профит равен: ", pos_prof_gl, "-ти" ); Выполняется ли оно? Если нет, то идём дальше и проверяем pos_prof_gl и posProfClose (сразу после else помещаем Print("pos_prof_gl=",pos_prof_gl); вместо else if(pos_prof_gl > posProfClose)). и т.д. Т.е. явно там, где вы ожидаете один результат получается другой
    Просто условий много и сложно тут сказать где ошибка, во-всяком случае навскидку не видно...
    поставил принты как вы сказали вместо условия else if(pos_prof_gl > posProfClose)) и принты работаю нормально. )
    Print("НАДО МОДИФИЦИРОВАТЬ ОРДЕР - не работает, если условие не удалять.
    Что в этом случае ещё можно придумать?

    Вы не можете благодарить!

  8. #8
    Теоретик
    Регистрация
    03.04.2013
    Сообщений
    475
    Promo (¢)
    690
    Благодарности
    Получено: 148
    Отправлено: 79
    Mike_Kharkov, а значения-то какие у pos_prof_gl? И попробуйте posProfClose уменьшить

    Вы не можете благодарить!

  9. #9
    Новичок Аватар для Mike_Kharkov
    Регистрация
    08.07.2014
    Сообщений
    103
    Promo (¢)
    1,685
    Благодарности
    Получено: 8
    Отправлено: 126
    Цитата Сообщение от KLoAF Посмотреть сообщение
    Mike_Kharkov, а значения-то какие у pos_prof_gl? И попробуйте posProfClose уменьшить
    значения больше, чем у posProfClose.

    Вы не можете благодарить!
    Последний раз редактировалось Mike_Kharkov; 01.10.2014 в 21:08.

  10. #10
    Теоретик
    Регистрация
    03.04.2013
    Сообщений
    475
    Promo (¢)
    690
    Благодарности
    Получено: 148
    Отправлено: 79
    Mike_Kharkov, скопировал код в редактор...тут сразу же и понял в чём ошибка:
    PHP код:
       else if(PositionSelect(_Symbol))
          {
            
    // доливка существующей позиции.  
          
          //увеличим размер позиции на коэффициент
          
    double lot posVolume COEF;
          
          
    double ask SymbolInfoDouble(_SymbolSYMBOL_ASK);
          
          if(
    ask <= hist_price DELTA _Point)
          {
          
          
    // -------+ вызов функции формирования торгового запроса +--------- 
          
    if(SendOrder(prclotpos_prof_glprice_bid))
            {
             Print(
    "Позиция добавлена");
             Print(
    "Час: "        +(string)stm.hour);
             Print(
    "Минута: "     +(string)stm.min);
             Print(
    "Секунда: "    +(string)stm.sec);
            }
           
           }
          }
    else if(
    pos_prof_gl >= posProfClose)
          {
          Print(
    "НАДО МОДИФИЦИРОВАТЬ ОРДЕР. Профит равен: "pos_prof_gl"-ти" );
          
            
    // модификация существующей позиции.  
          
          // -------+ вызов функции формирования торгового запроса +--------- 
          
    if(ModifyOrder(prcprice_bidposVolume))
            {
             Print(
    "ПОЗИЦИИ МОДИФИКАЦИРОВАНА. Тейк профит равен:"price_bid);
             Print(
    "Час: "        +(string)stm.hour);
             Print(
    "Минута: "     +(string)stm.min);
             Print(
    "Секунда: "    +(string)stm.sec);
            } 
    По факту получается условие
    PHP код:
    if(PositionSelect(_Symbol))
    {
    }
    else if(
    pos_prof_gl >= posProfClose)
    {

    Но такое не выполнится никогда! Ибо если позиция не выбирается (PositionSelect(_Symbol)), то позиции нету, т.е. она закрыта. О какой прибыли может идти тогда речь?
    P.S. при написании кода желательно пиши в php тегах, ибо они подсвечиваются и лучше читается код

    Вы не можете благодарить!

Страница 1 из 2 1 2 ПоследняяПоследняя

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •