Clearing in the tester - page 6

 
Roman Shiredchenko #:

There is also an organisational issue, if anyone knows how to solve it in the best way - please write it in words, I will put it in code:

in general, how to understand that the order cycle, a new position - PROFIT has started - to take into account the average opening price of the position (clearing changes its value):

to be clear, I can both from the terminal via the keys myself and by a robot with magik....

In general, I need a report point - to calculate the average entry price of the position.

Can I use data from here + for example read time when previous position closed in profit and take a difference with the real server time from there, like if I start a cycle from the terminal - without a robot:

I mean something like this:

like the past position is on the plus side - then the current cycle accounting has already started. and orders - you must already count both entry price and volume to calculate the average entry price of the aggregate position...

https://www.mql5.com/ru/articles/211


--------------------------------------------------------------

Of course, ideally it should be closed regardless of the outcome of the previous cycle - profit or loss.

The start - the new one was marked for calculation in the code - the average price of the new current cycle of averages, for example, or fills - it doesn't matter...

Is there anyone ready to calculate the average price of the final position? I'm getting tired of counting and correcting code - the stone flower does not work....:-)

I tried different methods in OnTrade Transaction () - many extra things get into calculation, lots are doubled in result - that's not right:

Events

"For example, when sending a market buy order, it is processed, an appropriate buy order is created for the account, the order is executed, removed from the list of the open ones, added to the orders history, then an appropriate deal is added to the history and a new position is created. All these actions are trade transactions

"

This is via On Trade Transaction ()

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
  {


 if ((Hour() <= 13 && Minute() < 44) || (Hour() >=14 && Minute() > 5) || 
          (Hour() <= 18 && Minute() < 44) || (Hour() >=19 && Minute() > 5)) 
   if(trans.type == TRADE_TRANSACTION_DEAL_ADD)   //TRADE_TRANSACTION_DEAL_ADD)
   
     {
      long deal_type = -1;
      long deal_entry = -1;
      long deal_magic = 0;

      double deal_volume = 0;
      double deal_price  = 0;
      string deal_symbol = "";

      if(HistoryDealSelect(trans.deal))
        {
         // Print(" deal_entry == DEAL_ENTRY_IN, last_price = ",last_price, " last_lots = ",last_lots);

         deal_type    = HistoryDealGetInteger(trans.deal, DEAL_TYPE);
         deal_entry   = HistoryDealGetInteger(trans.deal, DEAL_ENTRY);
         deal_magic   = HistoryDealGetInteger(trans.deal, DEAL_MAGIC);

         deal_volume  = HistoryDealGetDouble(trans.deal, DEAL_VOLUME);
         deal_price   = HistoryDealGetDouble(trans.deal, DEAL_PRICE);
         deal_symbol  = HistoryDealGetString(trans.deal, DEAL_SYMBOL);
         Print(" deal_entry == DEAL_ENTRY_IN, deal_price = ", deal_price, " deal_volume = ", deal_volume);
        }
      else
         return;

      if(deal_symbol == _Symbol) // && deal_magic == MagicNumber)

         if(deal_entry == DEAL_ENTRY_IN && (deal_type == DEAL_TYPE_BUY || deal_type == DEAL_TYPE_SELL))
           {
            // last_price    = deal_price;
            last_pos_type = (deal_type == DEAL_TYPE_BUY) ? POSITION_TYPE_BUY : POSITION_TYPE_SELL;
            // last_lots     = deal_volume;


          
            if (deal_type == DEAL_TYPE_BUY)
             {
              if(deal_volume > 0)  
              if (!PositionSelect(_Symbol) ||
                 (PositionSelect(_Symbol) && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY   && 
                 NormalizeDouble(PositionGetDouble(POSITION_SL),_Digits) < last_price))
                        
             
              {
               // расчет средней цены СОВОКУПНОЙ ПОЗИЦИИ для общего случая - входа, как руками, так и роботом 
               last_price = (last_price * last_lots + NormalizeDouble(deal_price,_Digits) *
                             NormalizeDouble(deal_volume,0)) / (last_lots +  NormalizeDouble(deal_volume,0));
               last_price = NormalizeDouble(last_price,_Digits);
               
               last_lots = last_lots + NormalizeDouble(deal_volume,0); // накапливаем совокупный объем
              }
            Print(" OnTradeTransaction_BUY: last_price_BUY = ",last_price, " last_lots_BUY = ",last_lots, " N_max_B = ", N_max_B);
           }
           
         if (deal_type == DEAL_TYPE_SELL)
             {
              if(deal_volume > 0)  
              if (!PositionSelect(_Symbol) ||                
                 (PositionSelect(_Symbol) && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL &&
                   (NormalizeDouble(PositionGetDouble(POSITION_SL),_Digits) == 0 ||
                    NormalizeDouble(PositionGetDouble(POSITION_SL),_Digits) > last_price ))) 
                        
             
              {
               // расчет средней цены СОВОКУПНОЙ ПОЗИЦИИ для общего случая - входа, как руками, так и роботом 
               last_price = (last_price * last_lots + NormalizeDouble(deal_price,_Digits) *
                             NormalizeDouble(deal_volume,0)) / (last_lots +  NormalizeDouble(deal_volume,0));
               last_price = NormalizeDouble(last_price,_Digits);
               
               last_lots = last_lots + NormalizeDouble(deal_volume,0); // накапливаем совокупный объем
              }
            Print(" OnTradeTransaction_SELL: last_price_SELL = ",last_price, " last_lots_SELL = ",last_lots, " N_max_S = ", N_max_S);
           }   
           
         } // к if(deal_entry == DEAL_ENTRY_IN && (deal_type == DEAL_TYPE_BUY || deal_type == DEAL_TYPE_SELL))
     }
  }

With this kind of f-i - lots in the average position entry price calculation (netting) is not counted correctly.


It may be easier to do it via On Trade.

I'm looking at it through On Trade () right now: everything is explained here, we just have to insert calculation into the code and that's all... Basically.

https://www.mql5.com/ru/articles/40


Basically, here's the design - if there is an increased position, then the average price will be calculated. When the position is closed, all of the intermediate variables must be zeroed out. Basically, everything is elementary there.

The task is to exclude changes of the position opening price during clearing (when it becomes equal to the symbol price at the time of clearing).

I.e. to read it in the code.

Обработка торговых событий в эксперте при помощи функции OnTrade()
Обработка торговых событий в эксперте при помощи функции OnTrade()
  • www.mql5.com
В 5-ой версии языка MQL появилась масса нововведений, в том числе работа с событиями различных типов (события таймера, торговые события, пользовательские и т.д.). Возможность обработки событий позволяет создавать совершенно новый тип программ для автоматического и полуавтоматического трейдинга. В этой статье мы рассмотрим торговые события и напишем для функции OnTrade() код, который будет обрабатывать событие Trade.
 
Roman Shiredchenko #:

No one has a ready design for calculating the average price of a final position? I'm getting tired of counting and correcting code - it doesn't work....:-)

Here's a piece of my old, but still "fighting" code:

               Pr=HistoryDealGetDouble(DealTicket,DEAL_PRICE);
               Vol=HistoryDealGetDouble(DealTicket,DEAL_VOLUME);
               if(st.Pos==0.0)
                  st.Price=Pr;
               if((ENUM_DEAL_TYPE)HistoryDealGetInteger(DealTicket,DEAL_TYPE)==DEAL_TYPE_BUY)
                 {
                  if(st.Pos>=0.0) // Увеличиваем лонг
                     st.PriceAvr=(st.PriceAvr*st.Pos+Pr*Vol)/(st.Pos+Vol);
                  else  // st.Pos<0
                    {
                     if(Vol<=-st.Pos) // Кроемся или сокращаем позу
                        Res=(-Vol)*(Pr-st.PriceAvr);
                     else if(Vol>-st.Pos) // Переворот в лонг
                       {
                        Res=st.Pos*(Pr-st.PriceAvr);
                        ClearClosedPos();
                        st.Price=Pr; st.PriceAvr=Pr;
                       }
                    }
                  st.Pos+=Vol; st.PlanPos-=Vol;
                 }
               else if((ENUM_DEAL_TYPE)HistoryDealGetInteger(DealTicket,DEAL_TYPE)==DEAL_TYPE_SELL)
                 {
                  if(st.Pos<=0.0) // Увеличиваем шорт
                     st.PriceAvr=(st.PriceAvr*(-st.Pos)+Pr*Vol)/(-st.Pos+Vol);
                  else  // st.Pos>0
                    {
                     if(Vol<=st.Pos) // Кроемся или сокращаем позу
                        Res=(Vol)*(Pr-st.PriceAvr);
                     else if(Vol>st.Pos) // Переворот в шорт
                       {
                        Res=st.Pos*(Pr-st.PriceAvr);
                        ClearClosedPos();
                        st.Price=Pr; st.PriceAvr=Pr;
                       }
                    }
                  st.Pos-=Vol; st.PlanPos+=Vol;
                 }
 
JRandomTrader #:

Here's a piece of my old but still 'actionable' code:

О!!! Thanks so much for such a quick response - I'll take it for review and editing.
 
Roman Shiredchenko #:
О!!! Thanks so much for such a quick response - I'll take it up for review and editing.

Note - "st" (there is quite a big structure, including trails and statistics) is exactly the "state" of the robot - what is dumped to disk after change (and when deinit) and loaded when yinit.

And yes, most likely st.Price and st.PriceAvr aren't really needed here, one is enough, but the code is old, more than 5 years, and all my "combat" robots are tied to it, so "first rule of aviation mechanics - don't mess with the working mechanism".

 

the result of clearing is the transfer of all positions to the current price, i.e. to the average price inside the spread

who cares about this exchange? ...

 
JRandomTrader #:

Note - "st" (there is quite a big structure, including trails and statistics) is exactly the "state" of the robot - what is dumped to disk after change (and when deinit) and loaded when yinit.

And yes, most likely st.Price and st.PriceAvr aren't really needed here, one is enough, but the code is old, more than 5 years, and all my "combat" robots are tied to it, so "first rule of aviation mechanics - don't mess with the working mechanism".

Thanks for the clarification, I'll take it as basic.
 
Renat Akhtyamov #:

the result of clearing is the transfer of all positions to the current price, i.e. to the average price inside the spread

who cares about this exchange? ...

I'll post the file here as soon as I've done it.
 
Renat Akhtyamov #:

the result of clearing is the transfer of all positions to the current price, i.e. to the average price inside the spread

Who cares about the exchange? ...

I only trade on the exchange.

 
JRandomTrader #:

I only trade on the stock exchange.

and I only trade forex.

I don't know how to trade the stock market.

i've been there, i've been there.

not my thing - re-learn

by the way, why is the average price in the market not the one after clearing?

// or else i would trade there ;)

// but as it turns out they don't give everything in the glass, they hide a bit, i.e. the glass sucks?

 
Roman Shiredchenko #:
I'll post it here as soon as I make the fic.

Everything has been posted in the Exchange Trading section for a long time

https://www.mql5.com/ru/forum/67298/page3#comment_2109451

ФОРТС: В помощь начинающим
ФОРТС: В помощь начинающим
  • 2015.12.08
  • www.mql5.com
Установка отложенного ордера командой OrderSend().