Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 2471

 
Tretyakov Rostyslav #:
Удали это
Для бай ордеров удалаение и нормализация значения помогла- большое спасибо за подсказку и помощь 😋🤓😎😁😁😁😉
 
Konstantin Seredkin #:

Ребята требуется помощь.

Я с хедж счетами работал только в далеком 2015 году на мт4, в МТ5 тут понадобилось сделать универсальность и возникла проблема с тейк профитами.

Смотрите логика:

Открываем Бай Селл

Робот подхватывает позиции, сомотрит что на них нет ТП и выставляет им ТП.

Если открыть еще один бай, по логике робот смотрит что появилось 2 позиции одного направления, он заходит во вторую функцию, сравнивает цены текущего ТП и нового, если они отличаются, он меняет Цену на второй ТП.

Но вот тут ошибка сыпаться начинает, если открыть вторую позицию на сел, то метод почему то берет цену тейка от направления бай и пытается ее модифицировать для направления сел на новый уровень, но так как этот уровень находится ниже цены открытия позиций - вылетает ошибка.


Почему он берет тейк не своего направления понять не могу

Может уже установленные тейки нужно каким то другим образом выявлять и т.д.  ?GetAveragePrice


Во всём виновата GetAveragePrice.

После её вызова и возврата в  функцию TakeMetod  у вас в памяти остаётся выбранная позиция, но какая? Совсем не та которую выбрали в  TakeMetod, а последняя выбранная в GetAveragePrice. Далее вы получаете тейк позиции выбранной в GetAveragePrice

CompareDoubles(m_position.TakeProfit()

И чей тейк вы получаете? Та хз чей.

 
Konstantin Seredkin #:

Ребята требуется помощь.

Я с хедж счетами работал только в далеком 2015 году на мт4, в МТ5 тут понадобилось сделать универсальность и возникла проблема с тейк профитами.

//+------------------------------------------------------------------+
void OnStart()
  {
   AveragePricePositions();
  }
//+------------------------------------------------------------------+
void AveragePricePositions()
  {
   long PosType;
   int buy = 0, sell = 0;
   double PosPriceBuy = 0, PosPriceSell = 0, PricelBuy = 0, PricelSell = 0, PosVol = 0, VolSell = 0, VolBuy = 0, PosPriceOpen = 0;
   for(int i = 0; i < PositionsTotal(); i++)
     {
      if(_Symbol == PositionGetSymbol(i))
        {
         PosVol  = PositionGetDouble(POSITION_VOLUME);
         PosPriceOpen = PositionGetDouble(POSITION_PRICE_OPEN);
         PosType  = PositionGetInteger(POSITION_TYPE);
         if(PosType == POSITION_TYPE_BUY)
           {
            PricelBuy += PosPriceOpen * PosVol;
            VolBuy += PosVol;
            buy++;
           }
         if(PosType == POSITION_TYPE_SELL)
           {
            PricelSell += PosPriceOpen * PosVol;
            VolSell += PosVol;
            sell++;
           }
        }
     }
   if(VolBuy != 0)
     {
      PosPriceBuy = PricelBuy / VolBuy;
      HLine("PosPriceBuy", PosPriceBuy, clrBlue);
     }
   if(VolSell != 0)
     {
      PosPriceSell = PricelSell / VolSell;
      HLine("PosPriceBuy", PosPriceBuy, clrRed);
     }
  }
//+------------------------------------------------------------------+
void HLine(string name, double price, color clr)
  {
   if(ObjectFind(0, name) < 0)
     {
      ObjectCreate(0, name, OBJ_HLINE, 0, 0, 0);
      ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
     }
   ObjectSetDouble(0, name, OBJPROP_PRICE, price);
  }
//+------------------------------------------------------------------+

Нашли среднюю цену. Потом можно и модификацией позиций заняться.

 
Aleksandr Slavskii #:

Нашли среднюю цену. Потом можно и модификацией позиций заняться.

А свопы и комиссии не учтены, это очень важно?

 
Vitaly Muzichenko #:

А свопы и комиссии не учтены, это очень важно?

Та я хз важно это или нет. Кому важно учитывать свопы и комиссии, тот пусть допишет :)

Со свопами проблем не будет, а вот, чтоб добавить комиссии придётся обращаться к истории сделок и то в том случае если комиссия берётся за вход, если комиссия берётся за выход её никак не учесть.

 
Aleksandr Slavskii #:

Нашли среднюю цену. Потом можно и модификацией позиций заняться.

У меня же же тоже самое что вы показали, только при вызове я просто задаю нужный тип бай или селл 

Эти функции выполняют одну и тоже задачу, расчет средней цены серии ордеров, цена может быть не привязана вообще к какому то ордеру или позиции в рынке.

По сути мне кажется, в моем случае нужно искать ордер серии на котором висит тейк профит, я посмотрел в вроде как при первоначальной установке он вешается на первый открытый ордер и далее при его изменении тп на другие ордера не переносится.

В итоге я так думаю нужно постоянно искать самый первый открытый ордер серии и сним работать, попробую цикл поменять

//+----------------------------------------------------------------------------+
//| Расчет среденй цены (0)-buy (1)-sell                                       |
//+----------------------------------------------------------------------------+
double GetAveragePrice(int ot=-1)
  {
   double order_lots = 0, order_price = 0, avg_price = 0;
     {
      for(int i = PositionsTotal()-1; i>=0; i--)
        {
         if(m_position.SelectByIndex(i))
           {
            if(m_position.Symbol()==Symbol())
              {
               if(m_position.PositionType()==ot || ot < 0)
                 {
                  order_lots += m_position.Volume();
                  order_price += m_position.PriceOpen() *m_position.Volume();
                 }
              }
           }
        }
     }
   avg_price = m_symbol.NormalizePrice(order_price / order_lots);
   return(avg_price);
  }
 
Konstantin Seredkin #:

У меня же же тоже самое что вы показали, только при вызове я просто задаю нужный тип бай или селл 

Эти функции выполняют одну и тоже задачу, расчет средней цены серии ордеров, цена может быть не привязана вообще к какому то ордеру или позиции в рынке.

По сути мне кажется, в моем случае нужно искать ордер серии на котором висит тейк профит, я посмотрел в вроде как при первоначальной установке он вешается на первый открытый ордер и далее при его изменении тп на другие ордера не переносится.

В итоге я так думаю нужно постоянно искать самый первый открытый ордер серии и сним работать, попробую цикл поменять

Я вам указал на ошибку, но вы видимо это сообщение пропустили.

 
Konstantin Seredkin #:

У меня же же тоже самое что вы показали, только при вызове я просто задаю нужный тип бай или селл 

Эти функции выполняют одну и тоже задачу, расчет средней цены серии ордеров, цена может быть не привязана вообще к какому то ордеру или позиции в рынке.

Дополню.

Да функция аналогичная, с единственной разницей у меня за один проход обрабатываются оба типа позиций, у вас же для этого все позиции нужно перебрать дважды. В общем разница не большая и на проблему не влияет.

Я не посмотрел, что делает эта функция, так как увидел ошибку и не стал разбираться дальше.

 
Aleksandr Slavskii #:

Дополню.

Да функция аналогичная, с единственной разницей у меня за один проход обрабатываются оба типа позиций, у вас же для этого все позиции нужно перебрать дважды. В общем разница не большая и на проблему не влияет.

Я не посмотрел, что делает эта функция, так как увидел ошибку и не стал разбираться дальше.

Я немного просчитался.

Привык к нетингу.

В итоге то что происходит, открыли бай, выставился ТП, открыли второй, он перенесся на другой уровень, но на второй то ордер ТП не выставился...

Если сработает ТП закроется только первый вход.


Тут надо такую функцию, которая бы отслеживала валютную пару, при появлении первой позиции, ставился тейк профит, при появлении второй позиции,

делался расчет средней цены,

от этой средней цены делался расчет нового расстояния ТП

первая позиция которая имеет уже ТП модифицировала свой ТП на новый уровень, а вторая позиция у которой еще нет ТП, соответственно модифицировалась и выставляла свой ТП на уровень средняя цена + новое расстояние ТП

при появлении третьей и последующих позиций, все повторяется те что имеют ТП, делают новую модификацию средняя цена + уровень ТП

а новый ордер ставит свой тп так же ср цена + уровень тп.


Блин столько гемороя на хедж счетах

 

Все я разобрался в чем причина.

Нужен перебор всех тикетов ордеров серии и по этому  нужно выбирать каждый отдельный тикет и перепроверять далее и по необходимости уже модифицировать


//--- Пройдемся в цикле по всем ордерам
   for(int i=total_position-1; i>=0; i--)
     {      
      //--- Если ордер выбран
      if(m_position.SelectByIndex(i) && m_position.Symbol()==m_symbol.Name() && (position_ticket=PositionGetTicket(i))>0)
        {
         if(m_position.PositionType()==POSITION_TYPE_BUY )
           {

//--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---                
           double new_tp=m_position.TakeProfit();
           if(TakeProfit!=0)
                 {
                  if(m_position.TakeProfit()==0.0 && ((m_account.MarginMode()==ACCOUNT_MARGIN_MODE_RETAIL_NETTING && volume_buys==Lot_) 
                                                      || 
                                                     (m_account.MarginMode()==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING && count_buys==1)))
                                                     {
                      new_tp=m_symbol.NormalizePrice(m_position.PriceOpen()+m_take_profit);
                      if(PositionModifyCheck(position_ticket,m_symbol.NormalizePrice(0),m_symbol.NormalizePrice(new_tp)))    
                         {
                          if(!m_trade.PositionModify(position_ticket,m_symbol.NormalizePrice(0),m_symbol.NormalizePrice(new_tp)))
                             Print("First Modify BUY ",position_ticket,
                                   " Position -> false. Result Retcode: ",m_trade.ResultRetcode(),
                                   ", description of result: ",m_trade.ResultRetcodeDescription());
                           RefreshRates();
                           m_position.SelectByIndex(i);
                           continue;
                          }
                      }
                  }
                  //-----------------
            if(TakeProfit!=0)
                  {
                  if((m_account.MarginMode()==ACCOUNT_MARGIN_MODE_RETAIL_NETTING && volume_buys>Lot_) 
                                        || 
                     (m_account.MarginMode()==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING && count_buys>1))
                                                     {
                    double m_price = GetAveragePrice(POSITION_TYPE_BUY);
                    new_tp  = m_symbol.NormalizePrice(m_price+m_ntake_profit);   
                    if(PositionModifyCheck(position_ticket,m_symbol.NormalizePrice(0),m_symbol.NormalizePrice(new_tp)))   
                       {
                          if(!m_trade.PositionModify(position_ticket,m_symbol.NormalizePrice(0),m_symbol.NormalizePrice(new_tp)))
                             Print("First Modify BUY ",position_ticket,
                                   " Position -> false. Result Retcode: ",m_trade.ResultRetcode(),
                                   ", description of result: ",m_trade.ResultRetcodeDescription());
                           RefreshRates();
                           m_position.SelectByIndex(i);
                           continue;
                        }
                    }
                }               
            }