Requests & Ideas (MQL5 only!) - page 39

 

Hi,

My request/idea:  include the identification of the buyer and seller member firms in the structure MqlTick 

Although this information is not available for Forex, it is available at many stock markets and would help a lot in detecting big players buying or selling huge volumes in these markets.

In medium-sized markets dominated by a few very big players, like Brazilian BMF, this information is one of the most effective predictors for short-term price movement.

Any plans for that? Is it feasible to implement in MT5 ? 

Thank you.

 
HeraldoAlmeida :

Hi,

My request/idea:  include the identification of the buyer and seller member firms in the structure MqlTick  

Although this information is not available for Forex, it is available at many stock markets and would help a lot in detecting big players buying or selling huge volumes in these markets.

In medium-sized markets dominated by a few very big players, like Brazilian BMF, this information is one of the most effective predictors for short-term price movement.

Any plans for that? Is it feasible to implement in MT5 ? 

Thank you.


In the structure MqlTick does not have a field for identification of the buyer and seller

 
Vladimir Karputov:

In the structure MqlTick does not have a field for identification of the buyer and seller


Yes, I know it, but that' s the very idea: to add 2 new fields to store this information.

Is adding new fields to data strutures beyond the scope of this thread ?

 
HeraldoAlmeida :

Yes, I know it, but that' s the very idea: to add 2 new fields to store this information.

Is adding new fields to data strutures beyond the scope of this thread ?


To do this, you need to do your STORAGE: file. But I do not know how and where to get information on the sellers.

 
Vladimir Karputov:

To do this, you need to do your STORAGE: file. But I do not know how and where to get information on the sellers.


Storing outside the MqlTick structure would not be a problem.

The real issue is that one you pointed out: "where to get the information".

I'm sure it is available at the market's diffusion signal.

Moreover, I can see it in another trading platform I have in my notebook, together with MT5, both connected to the same brokerage account, but it seems not to be available in MT5.

It seems that MT5 ignores this extra information contained in the diffusion signal (maybe because it was originally developed for Forex and later adapted to stock markets, I presume).

 
HeraldoAlmeida:

Yes, I know it, but that' s the very idea: to add 2 new fields to store this information.

Is adding new fields to data strutures beyond the scope of this thread ?


heraldo, não tem esta informação no tick... vc não tem como identificar quem é o comprador que está na fila

 
HeraldoAlmeida:

Storing outside the MqlTick structure would not be a problem.

The real issue is that one you pointed out: "where to get the information".

I'm sure it is available at the market's diffusion signal.

Moreover, I can see it in another trading platform I have in my notebook, together with MT5, both connected to the same brokerage account, but it seems not to be available in MT5.

It seems that MT5 ignores this extra information contained in the diffusion signal (maybe because it was originally developed for Forex and later adapted to stock markets, I presume).


Your idea sound interesting, but if you say and confirm by this sentence " Moreover, I can see it in another trading platform I have in my notebook, together with MT5, both connected to the same brokerage account, ", then try to prove us by attaching some images so we can all see what you are talking about !

 

Step Five

Add the function "FillArrayFromBuffer" - this function is taken from the iMA help. The "FillArrayFromBuffer" function fills the indicator buffer with values ​​obtained from handle handle_iMA.

It was:

 //+------------------------------------------------------------------+ 
 //| Find lowest price from start to current position                 | 
 //+------------------------------------------------------------------+ 
 double GetLow( int nPosition, int nStartPeriod, const double &LoData[])
  {
 //--- calculate 
   double result=LoData[nStartPeriod];
   for ( int i=nStartPeriod;i<=nPosition;i++)
       if (result>LoData[i])
         result=LoData[i];
   return (result);
  }
 //+------------------------------------------------------------------+  

Became:

 //+------------------------------------------------------------------+ 
 //| Find lowest price from start to current position                 | 
 //+------------------------------------------------------------------+ 
 double GetLow( int nPosition, int nStartPeriod, const double &LoData[])
  {
 //--- calculate 
   double result=LoData[nStartPeriod];
   for ( int i=nStartPeriod;i<=nPosition;i++)
       if (result>LoData[i])
         result=LoData[i];
   return (result);
  }
 //+------------------------------------------------------------------+  
 //| Filling indicator buffers from the MA indicator                  |  
 //+------------------------------------------------------------------+  
 bool FillArrayFromBuffer( double &values[],   // indicator buffer of Moving Average values  
                         int shift,           // shift  
                         int ind_handle,     // handle of the iMA indicator  
                         int amount           // number of copied values  
                         )
  {
 //--- reset error code  
   ResetLastError ();
 //--- fill a part of the iMABuffer array with values from the indicator buffer that has 0 index  
   if ( CopyBuffer (ind_handle, 0 ,-shift,amount,values)< 0 )
     {
       //--- if the copying fails, tell the error code  
       PrintFormat ( "Failed to copy data from the iMA indicator, error code %d" , GetLastError ());
       //--- quit with zero result - it means that the indicator is considered as not calculated  
       return ( false );
     }
 //--- everything is fine  
   return ( true );
  }

We save version 1.004 and send changes to Storage.

Files:
 

Step Six

We fill the function OnCalculate ().

It was:

 //+------------------------------------------------------------------+ 
 //| Custom indicator iteration function                              | 
 //+------------------------------------------------------------------+ 
 int OnCalculate ( const int rates_total,
                 const int prev_calculated,
                 const datetime &time[],
                 const double &open[],
                 const double &high[],
                 const double &low[],
                 const double &close[],
                 const long &tick_volume[],
                 const long &volume[],
                 const int &spread[])
  {
 //--- check for minimum rates count 
   if (rates_total< 3 )
       return ( 0 );
 //--- detect current position  
   int pos=prev_calculated- 1 ;
 //--- correct position 
   if (pos< 1 )
     {
       //--- first pass, set as SHORT 
      pos= 1 ;
      ExtAFBuffer[ 0 ]=ExtSarStep;
      ExtAFBuffer[ 1 ]=ExtSarStep;
      ExtSARBuffer[ 0 ]=high[ 0 ];
      ExtLastRevPos= 0 ;
      ExtDirectionLong= false ;
      ExtSARBuffer[ 1 ]=GetHigh(pos,ExtLastRevPos,high);
      ExtEPBuffer[ 0 ]=low[pos];
      ExtEPBuffer[ 1 ]=low[pos];
     }

Now insert the preparatory block from the iMA help:

 //+------------------------------------------------------------------+ 
 //| Custom indicator iteration function                              | 
 //+------------------------------------------------------------------+ 
 int OnCalculate ( const int rates_total,
                 const int prev_calculated,
                 const datetime &time[],
                 const double &open[],
                 const double &high[],
                 const double &low[],
                 const double &close[],
                 const long &tick_volume[],
                 const long &volume[],
                 const int &spread[])
  {
 //--- check for minimum rates count 
   if (rates_total< 3 )
       return ( 0 );
 //--- number of values copied from the iMA indicator  
   int values_to_copy;
 //--- determine the number of values calculated in the indicator  
   int calculated= BarsCalculated (handle_iMA);
   if (calculated<= 0 )
     {
       PrintFormat ( "BarsCalculated() returned %d, error code %d" ,calculated, GetLastError ());
       return ( 0 );
     }
 //--- if it is the first start of calculation of the indicator or if the number of values in the iMA indicator changed  
 //---or if it is necessary to calculated the indicator for two or more bars (it means something has changed in the price history)  
   if (prev_calculated== 0 || calculated!=bars_calculated || rates_total>prev_calculated+ 1 )
     {
       //--- if the iMABuffer array is greater than the number of values in the iMA indicator for symbol/period, then we don't copy everything   
       //--- otherwise, we copy less than the size of indicator buffers  
       if (calculated>rates_total)
         values_to_copy=rates_total;
       else 
         values_to_copy=calculated;
     }
   else 
     {
       //--- it means that it's not the first time of the indicator calculation, and since the last call of OnCalculate()  
       //--- for calculation not more than one bar is added  
      values_to_copy=(rates_total-prev_calculated)+ 1 ;
     }
 //--- fill the iMABuffer array with values of the Moving Average indicator  
 //--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operation  
   if (!FillArrayFromBuffer(ExtMABuffer, 0 /*ma_shift*/ ,handle_iMA,values_to_copy)) return ( 0 );
 //--- form the message  
   string comm= StringFormat ( "%s ==>  Updated value in the indicator %s: %d" ,
                             TimeToString ( TimeCurrent (), TIME_DATE | TIME_SECONDS ),
                             "ma" /*short_name*/ ,
                            values_to_copy);
 //--- display the service message on the chart  
   Comment (comm);
 //--- memorize the number of values in the Moving Average indicator  
   bars_calculated=calculated;

 //--- detect current position  
   int pos=rates_total-values_to_copy /*prev_calculated-1*/ ;
 ////--- correct position 
 //   if(pos<1) 
 //     { 
 //      //--- first pass, set as SHORT 
 //      pos=1; 
 //      ExtAFBuffer[0]=ExtSarStep; 
 //      ExtAFBuffer[1]=ExtSarStep; 
 //      ExtSARBuffer[0]=high[0]; 
 //      ExtLastRevPos=0; 
 //      ExtDirectionLong=false; 
 //      ExtSARBuffer[1]=GetHigh(pos,ExtLastRevPos,high); 
 //      ExtEPBuffer[0]=low[pos]; 
 //      ExtEPBuffer[1]=low[pos]; 
 //     } 

now we change the main cycle.

It was:

 //---main cycle 
   for ( int i=pos;i<rates_total- 1 && ! IsStopped ();i++)
     {
       //--- check for reverse 
       if (ExtDirectionLong)
        {
         if (ExtSARBuffer[i]>low[i])
           {
             //--- switch to SHORT 
            ExtDirectionLong= false ;
            ExtSARBuffer[i]=GetHigh(i,ExtLastRevPos,high);
            ExtEPBuffer[i]=low[i];
            ExtLastRevPos=i;
            ExtAFBuffer[i]=ExtSarStep;
           }
        }
       else 
        {
         if (ExtSARBuffer[i]<high[i])
           {
             //--- switch to LONG 
            ExtDirectionLong= true ;
            ExtSARBuffer[i]=GetLow(i,ExtLastRevPos,low);
            ExtEPBuffer[i]=high[i];
            ExtLastRevPos=i;
            ExtAFBuffer[i]=ExtSarStep;
           }
        }
       //--- continue calculations 
       if (ExtDirectionLong)
        {
         //--- check for new High 
         if (high[i]>ExtEPBuffer[i- 1 ] && i!=ExtLastRevPos)
           {
            ExtEPBuffer[i]=high[i];
            ExtAFBuffer[i]=ExtAFBuffer[i- 1 ]+ExtSarStep;
             if (ExtAFBuffer[i]>ExtSarMaximum)
               ExtAFBuffer[i]=ExtSarMaximum;
           }
         else 
           {
             //--- when we haven't reversed 
             if (i!=ExtLastRevPos)
              {
               ExtAFBuffer[i]=ExtAFBuffer[i- 1 ];
               ExtEPBuffer[i]=ExtEPBuffer[i- 1 ];
              }
           }
         //--- calculate SAR for tomorrow 
         ExtSARBuffer[i+ 1 ]=ExtSARBuffer[i]+ExtAFBuffer[i]*(ExtEPBuffer[i]-ExtSARBuffer[i]);
         //--- check for SAR 
         if (ExtSARBuffer[i+ 1 ]>low[i] || ExtSARBuffer[i+ 1 ]>low[i- 1 ])
            ExtSARBuffer[i+ 1 ]= MathMin (low[i],low[i- 1 ]);
        }
       else 
        {
         //--- check for new Low 
         if (low[i]<ExtEPBuffer[i- 1 ] && i!=ExtLastRevPos)
           {
            ExtEPBuffer[i]=low[i];
            ExtAFBuffer[i]=ExtAFBuffer[i- 1 ]+ExtSarStep;
             if (ExtAFBuffer[i]>ExtSarMaximum)
               ExtAFBuffer[i]=ExtSarMaximum;
           }
         else 
           {
             //--- when we haven't reversed 
             if (i!=ExtLastRevPos)
              {
               ExtAFBuffer[i]=ExtAFBuffer[i- 1 ];
               ExtEPBuffer[i]=ExtEPBuffer[i- 1 ];
              }
           }
         //--- calculate SAR for tomorrow 
         ExtSARBuffer[i+ 1 ]=ExtSARBuffer[i]+ExtAFBuffer[i]*(ExtEPBuffer[i]-ExtSARBuffer[i]);
         //--- check for SAR 
         if (ExtSARBuffer[i+ 1 ]<high[i] || ExtSARBuffer[i+ 1 ]<high[i- 1 ])
            ExtSARBuffer[i+ 1 ]= MathMax (high[i],high[i- 1 ]);
        }
     }
 //---- OnCalculate done. Return new prev_calculated. 
   return (rates_total);
  }

became:

 //---main cycle 
   for ( int i=pos;i<rates_total- 1 && ! IsStopped ();i++)
     {
       if (i< 14 )
        {
         //--- first pass, set as SHORT 
         //pos=1; 
         ExtAFBuffer[i]=ExtSarStep;
         ExtSARBuffer[i]=ExtMABuffer[ 14 ];
         ExtLastRevPos= 0 ;
         ExtDirectionLong= false ;
         ExtEPBuffer[i]=ExtMABuffer[ 14 ];
         continue ;
        }
       //--- check for reverse 
       double high_curr=ExtMABuffer[i]+ Point ();
       double low_curr=ExtMABuffer[i]- Point ();
      
       double high_prev=ExtMABuffer[i- 1 ]+ Point ();
       double low_prev=ExtMABuffer[i- 1 ]- Point ();
      
       if (ExtDirectionLong)
        {
         if (ExtSARBuffer[i]>low_curr)
           {
             //--- switch to SHORT 
            ExtDirectionLong= false ;
            ExtSARBuffer[i]=GetHigh(i,ExtLastRevPos,ExtMABuffer);
            ExtEPBuffer[i]=low_curr;
            ExtLastRevPos=i;
            ExtAFBuffer[i]=ExtSarStep;
           }
        }
       else 
        {
         if (ExtSARBuffer[i]<high_curr)
           {
             //--- switch to LONG 
            ExtDirectionLong= true ;
            ExtSARBuffer[i]=GetLow(i,ExtLastRevPos,low);
            ExtEPBuffer[i]=high_curr;
            ExtLastRevPos=i;
            ExtAFBuffer[i]=ExtSarStep;
           }
        }
       //--- continue calculations 
       if (ExtDirectionLong)
        {
         //--- check for new High 
         if (high_curr>ExtEPBuffer[i- 1 ] && i!=ExtLastRevPos)
           {
            ExtEPBuffer[i]=high_curr;
            ExtAFBuffer[i]=ExtAFBuffer[i- 1 ]+ExtSarStep;
             if (ExtAFBuffer[i]>ExtSarMaximum)
               ExtAFBuffer[i]=ExtSarMaximum;
           }
         else 
           {
             //--- when we haven't reversed 
             if (i!=ExtLastRevPos)
              {
               ExtAFBuffer[i]=ExtAFBuffer[i- 1 ];
               ExtEPBuffer[i]=ExtEPBuffer[i- 1 ];
              }
           }
         //--- calculate SAR for tomorrow 
         ExtSARBuffer[i+ 1 ]=ExtSARBuffer[i]+ExtAFBuffer[i]*(ExtEPBuffer[i]-ExtSARBuffer[i]);
         //--- check for SAR 
         if (ExtSARBuffer[i+ 1 ]>low_curr || ExtSARBuffer[i+ 1 ]>low_prev)
            ExtSARBuffer[i+ 1 ]= MathMin (low_curr,low_prev);
        }
       else 
        {
         //--- check for new Low 
         if (low_curr<ExtEPBuffer[i- 1 ] && i!=ExtLastRevPos)
           {
            ExtEPBuffer[i]=low_curr;
            ExtAFBuffer[i]=ExtAFBuffer[i- 1 ]+ExtSarStep;
             if (ExtAFBuffer[i]>ExtSarMaximum)
               ExtAFBuffer[i]=ExtSarMaximum;
           }
         else 
           {
             //--- when we haven't reversed 
             if (i!=ExtLastRevPos)
              {
               ExtAFBuffer[i]=ExtAFBuffer[i- 1 ];
               ExtEPBuffer[i]=ExtEPBuffer[i- 1 ];
              }
           }
         //--- calculate SAR for tomorrow 
         ExtSARBuffer[i+ 1 ]=ExtSARBuffer[i]+ExtAFBuffer[i]*(ExtEPBuffer[i]-ExtSARBuffer[i]);
         //--- check for SAR 
         if (ExtSARBuffer[i+ 1 ]<high_curr || ExtSARBuffer[i+ 1 ]<high_prev)
            ExtSARBuffer[i+ 1 ]= MathMax (high_curr,high_prev);
        }
     }
 //---- OnCalculate done. Return new prev_calculated. 
   return (rates_total);
  }


Let's save version 1.005 to Storage. It's all. The indicator is ready.

Files:
 
Vladimir Karputov:

Step Six

We fill the function OnCalculate ().

It was:

Now insert the preparatory block from the iMA help:

now we change the main cycle.

It was:

became:


Let's save version 1.005 to Storage. It's all. The indicator is ready.


Thank you very much Mr Vladimir

Reason: