30s Timeframe MA Cross EA - how do you pull tick data when you cant choose seconds in the enum_timeframes?

 

Im trying to make an EA as im learning to be able to place a trade on a 30s MA cross.

I can make an EA that can trade based on MA crosses but the second time frame is super confusing.

im a scalper so the 30s timeframe is great and i use tradingview, but i was wondering if there was a way to make an EA using those micro timeframes.


How do you define that you want the MAs to be on the 30s Timeframe and for all trading to occur based on these 30s MA Crosses?


int fastMaHandle = iMA(_Symbol,PERIOD_CURRENT,21,0,MODE_EMA);
int slowMaHandle = iMA(_Symbol,PERIOD_CURRENT,240,0,MODE_EMA);


I thought maybe the periodseconds but that just tells you the amount of seconds within the current chart timeframe

i dont visually need to see a 30s chart, but perhaps the easiest way would be to show a 30s chart and then to run the MAs on the Period_Current?


if so, how do you create a 30s chart?

 
pebs85:

Im trying to make an EA as im learning to be able to place a trade on a 30s MA cross.

I can make an EA that can trade based on MA crosses but the second time frame is super confusing.

im a scalper so the 30s timeframe is great and i use tradingview, but i was wondering if there was a way to make an EA using those micro timeframes.


How do you define that you want the MAs to be on the 30s Timeframe and for all trading to occur based on these 30s MA Crosses?



I thought maybe the periodseconds but that just tells you the amount of seconds within the current chart timeframe

i dont visually need to see a 30s chart, but perhaps the easiest way would be to show a 30s chart and then to run the MAs on the Period_Current?


if so, how do you create a 30s chart?

you can write a function PERIOD_S30 for that and then modify 

iMA

function as well then it will work

Currenly by default MT5 does not support seconds timeframe

 
Arpit T #:

you can write a function PERIOD_S30 for that and then modify 

function as well then it will work

Currenly by default MT5 does not support seconds timeframe

Sorry how do you do that?

If this is my code and works on other timeframes.. how do i get it to work on the seconds?


(i realise its not going to be a profitable EA being just an MA cross but i'm trying to understand how to incorporate the seconds in so im not stuck with 1min and above...)


#include <Trade/Trade.mqh>

CTrade trade;

int OnInit(){

   return(INIT_SUCCEEDED);
   }

void OnDeinit(const int reason) {
   
  }

void OnTick() {

   static datetime timestamp;
   datetime time = iTime(_Symbol,PERIOD_CURRENT,0);
   if(timestamp != time) {
      timestamp = time;
   
      static int handleSlowMA = iMA(_Symbol,PERIOD_CURRENT,
    240 ,0,MODE_EMA,PRICE_CLOSE);
      double slowMaArray[];
      CopyBuffer(handleSlowMA,0,1,2,slowMaArray);
      ArraySetAsSeries(slowMaArray,true);
   
      static int handleFastMA = iMA(_Symbol,PERIOD_CURRENT,
    21 ,0,MODE_EMA,PRICE_CLOSE);
      double fastMaArray[];
      CopyBuffer(handleFastMA,0,1,2,fastMaArray);
      ArraySetAsSeries(fastMaArray,true);
   
      if(fastMaArray [0] > slowMaArray[0] && fastMaArray[1] < slowMaArray[1]) {
      Print("Fast MA is now > than slow ma");
      double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
      double sl = ask - 100 * SymbolInfoDouble(_Symbol,SYMBOL_POINT);
      double tp = ask + 500 * SymbolInfoDouble(_Symbol,SYMBOL_POINT);
      trade.Buy(0.01,_Symbol,ask,sl,tp,"Buy");
      }
      
       if(fastMaArray [0] < slowMaArray[0] && fastMaArray[1] > slowMaArray[1]) {
      Print("Fast MA is now < than slow ma");
      double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
      double sl = bid + 100 * SymbolInfoDouble(_Symbol,SYMBOL_POINT);
      double tp = bid - 500 * SymbolInfoDouble(_Symbol,SYMBOL_POINT);
      trade.Sell(0.01,_Symbol,bid,sl,tp,"Sell");
      }
      
      Comment("\nslowMaArray[0]: ",slowMaArray[0],
              "\nslowMaArray[0]: ",slowMaArray[1],
              "\nfastMaArray[0]: ",fastMaArray[0],
              "\nfastMaArray[0]: ",fastMaArray[1]);
   }
 }

 
Arpit T #: you can write a function PERIOD_S30 for that and then modify function as well then it will work Currenly by default MT5 does not support seconds timeframe

There is no "PERIOD_S30". What are you on about?

pebs85: Im trying to make an EA as im learning to be able to place a trade on a 30s MA cross. I can make an EA that can trade based on MA crosses but the second time frame is super confusing. im a scalper so the 30s timeframe is great and i use tradingview, but i was wondering if there was a way to make an EA using those micro timeframes. How do you define that you want the MAs to be on the 30s Timeframe and for all trading to occur based on these 30s MA Crosses? I thought maybe the periodseconds but that just tells you the amount of seconds within the current chart timeframe i dont visually need to see a 30s chart, but perhaps the easiest way would be to show a 30s chart and then to run the MAs on the Period_Current? if so, how do you create a 30s chart?

MetaTrader does not have standard support for time-frames with seconds, only with minutes.

To be able to work with seconds or any other non-standard time-frame you have to build yourself from the historical tick data.

There usually two options:

  • Either you build a Custom Symbol for the non-standard time-frame, or ...
  • you process the tick-data in real-time and use incremental calculations for indicators.
In both cases, this requires higher levels of coding skill and knowledge in MQL5 and is usually rather difficult for a newbie coder just starting out in MQL5.
Documentation on MQL5: Custom Symbols
Documentation on MQL5: Custom Symbols
  • www.mql5.com
Custom Symbols - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Fernando Carreiro #:

There is no "PERIOD_S30". What are you on about?

MetaTrader does not have standard support for time-frames with seconds, only with minutes.

To be able to work with seconds or any other non-standard time-frame you have to build yourself from the historical tick data.

There usually two options:

  • Either you build a Custom Symbol for the non-standard time-frame, or ...
  • you process the tick-data in real-time and use incremental calculations for indicators.
In both cases, this requires higher levels of coding skill and knowledge in MQL5 and is usually rather difficult for a newbie coder just starting out in MQL5.
Thankyou! I searched for a few hours on how to use function PERIOD_S30 and I couldn’t find anything at all! 

I will look into the custom symbol. I know it won’t be easy and I’m not in a rush.. just would really like to be able to figure this out 

Appreciate your time
 
pebs85 #: Thankyou! I searched for a few hours on how to use function PERIOD_S30 and I couldn’t find anything at all! I will look into the custom symbol. I know it won’t be easy and I’m not in a rush.. just would really like to be able to figure this out. Appreciate your time

You are welcome!

 
Fernando Carreiro #:

There usually two options:

  • Either you build a Custom Symbol for the non-standard time-frame, or ...
  • you process the tick-data in real-time and use incremental calculations for indicators.
In both cases, this requires higher levels of coding skill and knowledge in MQL5 and is usually rather difficult for a newbie coder just starting out in MQL5.
Hi Fernando.

I'm trying to build an EA based on a TF 15s.
I have the impression that the Custom Symbol solution cannot be executed in real time, am I wrong?

So, I'm interested in the second solution, do you have an example? This would help me avoid getting off on the wrong foot.
Documentation on MQL5: Custom Symbols
Documentation on MQL5: Custom Symbols
  • www.mql5.com
Custom Symbols - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
@joelpouliquen #: I'm trying to build an EA based on a TF 15s. I have the impression that the Custom Symbol solution cannot be executed in real time, am I wrong?

So, I'm interested in the second solution, do you have an example? This would help me avoid getting off on the wrong foot.

It is somewhat complex and can easily be a couple hundred lines of code.

Here is a skeleton code example for the tick processing and timing of a seconds based time-frame. It does however, not build the OHLC bar data. In simply uses the open mid price "(Ask + Bid)/2".

You will have to extend the functionality if you want to build the OHLC data as well.

//---------------------------------------------------------------------------------------------------------------------
#property   copyright      "Copyright \x00A9 2022, Fernando M. I. Carreiro, All rights reserved"
#property   link           "https://www.mql5.com/en/users/FMIC"
//---------------------------------------------------------------------------------------------------------------------

//--- Parameter settings

   input group "Parameters: Tick data processing"
      input uint  i_nTimeframeSeconds  = 15,    // Time-frame in seconds
                  i_nTickHistoryDays   = 5;     // Days to backtrack tick history
                                                // enough to cover long weekends
//--- Macro definitions

   // Define macro for invalid parameter values
      #define MCheckParameter( _condition, _text ) if( _condition ) \
         { Print( "Error: Invalid parameter - ", _text ); return INIT_PARAMETERS_INCORRECT; }

   // Define macros for time masking
      #define MDayMinutes ( 24 * 60      )
      #define MDaySeconds ( 24 * 60 * 60 )
      #define MTimeOnly( _vardatetime )       ( int(      ( _vardatetime ) % MDaySeconds ) )
      #define MDateOnly( _vardatetime )       ( int(      ( _vardatetime ) / MDaySeconds ) )
      #define MDateTime( _vardate, _vartime ) ( datetime( ( _vardate )     * MDaySeconds + ( _vartime ) ) )

//--- Structures and classes

   // Tick data processor structure
      struct STickProcessor {
         // Declare member variables
            long     m_nTicksTimeMsc;     // Next search time (milliseconds)
            int      m_nTicksTimeCount,   // Next search duplicate time counter
                     m_iTicksIndex,       // Index of current tick data
                     m_iTicksLast,        // Index of last valid tick data
                     m_nTicksCount;       // Count of available ticks in the cached data
            MqlTick  m_oTicks[];          // Tick data cache
            string   m_sSymbol;           // Symbol name for tick data
            bool     m_bRealtime;         // Real-time processing flag

         // Default deconstructor
            ~STickProcessor( void ) {
               ArrayFree( m_oTicks );
            };

         // Default constructor
            STickProcessor( void ) :
               m_nTicksTimeMsc(   WRONG_VALUE ),
               m_nTicksTimeCount( WRONG_VALUE ),
               m_iTicksIndex(     WRONG_VALUE ),
               m_iTicksLast(      WRONG_VALUE ),
               m_nTicksCount(     WRONG_VALUE ),
               m_bRealtime(       false       ),
               m_sSymbol(         ""          ) {};

         // Initialiser
            bool Init( string sSymbol, long nTicksTimeMsc ) {
               if( ( nTicksTimeMsc > 0 ) && ( sSymbol.Length() > 0 ) ) {
                  m_nTicksTimeMsc   = nTicksTimeMsc;
                  m_nTicksTimeCount = 0;
                  m_iTicksIndex     =
                  m_iTicksLast      =
                  m_nTicksCount     = WRONG_VALUE;
                  m_bRealtime       = false;
                  m_sSymbol         = sSymbol;
                  return true;
               };
               return false; // Failed to initialise
            };

         // Verify validaty of current tick data state
            bool IsValid( void ) {
               return ( m_nTicksCount >  0            ) &&
                      ( m_iTicksIndex >= 0            ) &&
                      ( m_iTicksIndex <= m_iTicksLast );
            };

         // Update Real-time status
            void RealTimeUpdate( void ) {
               if( m_iTicksIndex == m_iTicksLast )
                  m_bRealtime = m_oTicks[ m_iTicksIndex ].time >= TimeCurrent();
            };

         // Advance to next tick
            bool Next( void ) {
               if( ( m_nTicksCount > 0 ) && ( m_iTicksIndex < m_iTicksLast ) ) {
                  m_iTicksIndex++;                       // Next tick
                  if( !m_bRealtime ) RealTimeUpdate(); // Update Real-time status
                  return true;
               };
               if( m_nTicksTimeMsc > 0 ) {
                  // Acquire new data for the cache
                     ResetLastError();
                     m_nTicksCount = _StopFlag ? 0
                                   : CopyTicks( m_sSymbol, m_oTicks, COPY_TICKS_ALL, m_nTicksTimeMsc );
                     if( m_nTicksCount > m_nTicksTimeCount ) {
                        // Count final ticks as there may be more in the future with the same timestamp
                           int iTicksFinal = m_nTicksCount - 1;
                           m_iTicksLast    = iTicksFinal;
                           m_nTicksTimeMsc = m_oTicks[ m_iTicksLast ].time_msc;
                           while( ( iTicksFinal >= 0 ) && ( m_oTicks[ iTicksFinal ].time_msc >= m_nTicksTimeMsc ) )
                              iTicksFinal--;
                           m_iTicksIndex     = m_nTicksTimeCount; // Dismiss initial duplicate ticks
                           m_nTicksTimeCount = m_iTicksLast - iTicksFinal;
                           if( !m_bRealtime ) RealTimeUpdate(); // Update Real-time status
                           return m_iTicksIndex <= m_iTicksLast;  // Succeeded in acquiring tick data
                     };
                  // Report any errors while acquiring the tick data
                     if( ( m_nTicksCount == WRONG_VALUE ) || ( _LastError != ERR_SUCCESS ) )
                        PrintFormat( "Error %d: Unable to acquire tick data for symbol %s",
                           _LastError, m_sSymbol );
                  // Reset everything
                     m_iTicksIndex =
                     m_iTicksLast  =
                     m_nTicksCount = WRONG_VALUE;
               };
               return false; // Failed to acquire tick data
            };

         // Get current tick time - Attention! For the sake of efficiency, validity is not verified
            datetime Time( void ) { return m_oTicks[ m_iTicksIndex ].time; };

         // Get current mid price - Attention! For the sake of efficiency, validity is not verified
            double MidPrice( void ) {
               return 0.5 * ( m_oTicks[ m_iTicksIndex ].ask + m_oTicks[ m_iTicksIndex ].bid );
            };
      };

//--- Global variable declarations

      STickProcessor g_oTickProcessor;                // Tick data processor structure object

//--- Event handling functions

   // Initialisation event handler
      int OnInit( void ) {
         // Validate inputs and calculate parameter variables
            MCheckParameter( i_nTickHistoryDays  < 1, "days to backtrack tick history" );
            MCheckParameter( i_nTimeframeSeconds < 1, "time-frame in seconds"          );

         return INIT_SUCCEEDED;  // Successful initialisation of indicator
      };

   // Tick event handler
      void OnTick( void ) {
         // Detect first tick
            static bool bFirstTick = true;
            if( bFirstTick ) {
               // Initialise tick processing object with symbol and backtracking time
                  g_oTickProcessor.Init( _Symbol, ( TimeCurrent() - i_nTickHistoryDays * MDaySeconds ) * 1000 );
                  bFirstTick = false; // First tick condition complete
            };

         // Process tick data
            while( g_oTickProcessor.Next() ) {
               // Detect a change in timestamp (new bar in specified time-frame)
                  static datetime dtTimeStampCurrent  = WRONG_VALUE;
                         datetime dtTimeStampPrevious = dtTimeStampCurrent;
                                  dtTimeStampCurrent  = g_oTickProcessor.Time() / i_nTimeframeSeconds;
                         bool     bTimeStampNew       = dtTimeStampCurrent != dtTimeStampPrevious;
               // Process opening state for new time (second based time-frame)
                  if( bTimeStampNew ) {
                     // Build data ...
                        // ... do something with data ...

                     // Check if we processing data in real-time
                        if( g_oTickProcessor.m_bRealtime ) {
                           // ... carry out trading operations ...
                        };
                  };
            };
      };

 //---------------------------------------------------------------------------------------------------------------------
Files:
 
I believe that I have understood.

I will take inspiration from your piece of code, as well as from EqualVolumeBars.mq5 found here in the attached files : https://www.mql5.com/en/articles/8226

By making a mix of the two examples, I build my symbol on S15 TF as well as my indicator, and I display all of this in a new window (I like to have a graph to visually validate the behavior)

Secondly, I complete my EA to manage positions when my indicator gives signals.

Does that seem correct?

Thanks for your help.

NB: no problem with the complexity and volume of code, I am a developer.
Custom symbols: Practical basics
Custom symbols: Practical basics
  • www.mql5.com
The article is devoted to the programmatic generation of custom symbols which are used to demonstrate some popular methods for displaying quotes. It describes a suggested variant of minimally invasive adaptation of Expert Advisors for trading a real symbol from a derived custom symbol chart. MQL source codes are attached to this article.
 
@joelpouliquen #:
I believe that I have understood.

I will take inspiration from your piece of code, as well as from EqualVolumeBars.mq5 found here in the attached files : https://www.mql5.com/en/articles/8226

By making a mix of the two examples, I build my symbol on S15 TF as well as my indicator, and I display all of this in a new window (I like to have a graph to visually validate the behavior)

Secondly, I complete my EA to manage positions when my indicator gives signals.

Does that seem correct?

Thanks for your help.

NB: no problem with the complexity and volume of code, I am a developer.

The skeleton code I provided is for processing in real-time in the EA against the real symbol data, not for using a Custom Symbol. It also requires that you calculate all indicator values internally and not via standard indicator functions.

If you are going to build your own Custom Symbol, then you don't need my example code. You can just code a normal EA the reads from the Custom Symbol, but trades against the Real Symbol.

 
Fernando Carreiro #:

The skeleton code I provided is for processing in real-time in the EA against the real symbol data, not for using a Custom Symbol.

If you are going to build your own Custom Symbol, then you don't need my example code. You can just code a normal EA the reads from the Custom Symbol, but trades against the Real Symbol.

As the display is essential for me, I have the impression that the solution with the custom symbol is the most appropriate for my needs.

Unless there are other solutions to display graphics with custom TF?

Reason: