When in doubt, please refer to the documentation ...
Please learn to research the documentation ...
Gets ticks in the MqlTick format into ticks_array
Gets ticks in the MqlTick format within the specified date range to ticks_array
Gets history data of the Rates structure for a specified symbol and period into an array
Gets the synchronized timeseries from the Rates structure for the specified symbol-period and the specified amount
Gets history data on bar opening time for a specified symbol and period into an array
Gets history data on bar opening price for a specified symbol and period into an array
Gets history data on maximal bar price for a specified symbol and period into an array
Gets history data on minimal bar price for a specified symbol and period into an array
Gets history data on bar closing price for a specified symbol and period into an array
Gets history data on tick volumes for a specified symbol and period into an array
Gets history data on trade volumes for a specified symbol and period into an array
Gets history data on spreads for a specified symbol and period into an array
Please learn to research the documentation ...
Gets ticks in the MqlTick format into ticks_array
Gets ticks in the MqlTick format within the specified date range to ticks_array
Gets history data of the Rates structure for a specified symbol and period into an array
Gets the synchronized timeseries from the Rates structure for the specified symbol-period and the specified amount
Gets history data on bar opening time for a specified symbol and period into an array
Gets history data on bar opening price for a specified symbol and period into an array
Gets history data on maximal bar price for a specified symbol and period into an array
Gets history data on minimal bar price for a specified symbol and period into an array
Gets history data on bar closing price for a specified symbol and period into an array
Gets history data on tick volumes for a specified symbol and period into an array
Gets history data on trade volumes for a specified symbol and period into an array
Gets history data on spreads for a specified symbol and period into an array
Please read the following post ...
Forum on trading, automated trading systems and testing trading strategies
Fernando Carreiro, 2023.09.04 15:57
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 ... }; }; }; }; //---------------------------------------------------------------------------------------------------------------------
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use