Complete MQL5 guide & code

MQL5 CopyTicks & CopyTicksRange: Real-Time & Historical Tick Data

Master the MQL5 CopyTicks function. Learn how to fetch real-time and historical tick data into MqlTick structures, use COPY_TICKS flags, and handle async caching.

What this MQL5 guide covers

CopyTicks retrieves tick data from terminal memory or broker trade servers into dynamic arrays of MqlTick structures.

Three query flags control data filtering: COPY_TICKS_ALL for complete streams, COPY_TICKS_INFO for bid/ask price shifts, and COPY_TICKS_TRADE for last-price or volume changes.

MqlTick includes a millisecond timestamp and change flags. Buy/sell flags describe feed-provided trade information when available; quote ticks alone do not establish buying or selling pressure.

If historical ticks are not yet cached locally, CopyTicks initiates a background download; verify that returned tick count matches expectations before processing.

CopyTicks Function Signatures and Query Flags

The CopyTicks function extracts ticks for a designated symbol into an array of MqlTick structures. Its signature is int CopyTicks(string symbol_name, MqlTick &ticks_array[], uint flags = COPY_TICKS_ALL, ulong from = 0, uint count = 0).

Filtering selects returned tick types. MetaQuotes notes that selecting INFO or TRADE requires additional filtering and provides no significant speed advantage over ALL; measure your own workload.

Query Flag ConstantSelectionData Stream Included
COPY_TICKS_ALLFull tick historyAll price quote changes, execution deals, and volume updates
COPY_TICKS_INFOInfo ticks onlyOnly bid and ask price alterations (quote updates)
COPY_TICKS_TRADETrade ticks onlyTicks with last-price or volume changes

The MqlTick Structure and Millisecond Precision

Each element filled by CopyTicks is an MqlTick struct. Unlike standard datetime variables that resolve to whole seconds, MqlTick includes time_msc, a 64-bit integer tracking the exact millisecond elapsed since 1970.01.01.

MqlTick FieldData TypeDescription and Significance
timedatetimeStandard timestamp rounded to seconds
biddoubleCurrent bid price recorded on tick
askdoubleCurrent ask price recorded on tick
lastdoubleLast trade execution price
volumeulongVolume associated with the current last price; not a bar tick count
time_msclongMillisecond precision timestamp
flagsuintBitmask identifying tick cause (TICK_FLAG_BUY, TICK_FLAG_BID, etc.)
volume_realdoubleFloating-point trade volume for exchange instruments

Interpreting Tick Direction: TICK_FLAG Constants

Use bitwise AND to inspect which fields changed and any reported buy/sell trade flags. Availability depends on the instrument and data feed; do not infer aggressor-side volume from bid/ask quote updates or assume every record has a trade direction.

  • (tick.flags & TICK_FLAG_BUY): Reports a buy-deal flag supplied in this tick.
  • (tick.flags & TICK_FLAG_SELL): Reports a sell-deal flag supplied in this tick.
  • (tick.flags & TICK_FLAG_BID): Indicates the bid price changed.
  • (tick.flags & TICK_FLAG_ASK): Indicates the ask price changed.

CopyTicks vs CopyTicksRange and Server Synchronization

A nonzero CopyTicks from value starts the request at that millisecond timestamp; from=0 requests the latest count ticks. Results are oldest-first. CopyTicksRange uses an inclusive [from_msc, to_msc] interval.

Indicators return available ticks immediately while synchronization starts. EAs and scripts can wait up to 45 seconds for synchronization, then return available data and continue downloading. Inspect both returned count and errors; a short result is not proof of a particular cause.

Implementation details & mechanics

Core implementation pattern

OnTick requests the latest InpTickCount records, default 20, then logs their buy/sell flags and average quoted spread. It does not place orders. Counts describe the supplied tick flags, not traded volume or verified market-wide order flow. Consecutive rolling windows overlap; this is not an exactly-once tick consumer.

Error handling & safety rules

This example has no positions, trailing stops or CTrade exits. It frees the array in OnDeinit and rejects zero or excessively large input counts. Missing, partial or errored data requires inspection of the return count and GetLastError. OnTick notifications can coalesce multiple market updates.

MQL5 Code Implementation

//+------------------------------------------------------------------+
//|                                              CopyTicksGuideEA.mq5|
//|                             Copyright 2026, Pineify Guides Series |
//|                                              https://pineify.app |
//+------------------------------------------------------------------+
#property copyright "Pineify Guides Series"
#property link      "https://pineify.app/mql5/copyticks-guide"
#property version   "1.00"
#property strict

//--- Input parameters
input uint InpTickCount = 20;  // Number of recent ticks to monitor

//--- Dynamic buffer for tick data
MqlTick g_ticks[];

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   if(InpTickCount==0 || InpTickCount>100000) return INIT_PARAMETERS_INCORRECT;
   PrintFormat("CopyTicks EA initialized for %s. Requesting %u ticks per tick.",
               _Symbol, InpTickCount);
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ArrayFree(g_ticks);
   PrintFormat("Tick buffer released. Deinit reason: %d", reason);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   // from=0 selects the latest N ticks; returned array is oldest-first.
   ResetLastError();
   int copied = CopyTicks(_Symbol, g_ticks, COPY_TICKS_ALL, 0, InpTickCount);

   // Check if data is synchronized
   if(copied <= 0 || copied < (int)InpTickCount)
     {
      PrintFormat("Tick data incomplete: %d of %u requested; error %d.",
                  copied, InpTickCount, GetLastError());
      return;
     }

   int buyCount  = 0;
   int sellCount = 0;
   double totalSpread = 0.0;

   // Process copied ticks
   for(int i = 0; i < copied; i++)
     {
      // Inspect tick flags
      if((g_ticks[i].flags & TICK_FLAG_BUY) != 0)
         buyCount++;
      if((g_ticks[i].flags & TICK_FLAG_SELL) != 0)
         sellCount++;

      double tickSpread = (g_ticks[i].ask - g_ticks[i].bid) / _Point;
      totalSpread += tickSpread;
     }

   double avgSpread = totalSpread / copied;
   MqlTick latestTick = g_ticks[copied - 1]; // Newest tick in array

   PrintFormat("Latest Tick -> Bid: %.5f | Ask: %.5f | Spread: %.1f pts | Time: %I64d ms",
               latestTick.bid, latestTick.ask, avgSpread, latestTick.time_msc);
   PrintFormat("Reported tick flags -> Buys: %d | Sells: %d", buyCount, sellCount);

   // Illustrative count filter, not a validated trading signal.
   if((double)buyCount / copied >= 0.70 && avgSpread <= 25.0)
     {
      Print("Illustrative flag-count threshold reached; no order sent.");
     }
  }

Copy this code into MetaEditor, save it in your MQL5 folder (Experts, Scripts, or Include), and compile with F7.

Generate custom MQL5 code with Pineify AI

Describe the trade execution, indicator calculations, risk management, or data processing logic you need. Pineify generates editable MQL5 source code. Review its logic, request a syntax check, and compile and test the final file in MetaEditor.

Frequently Asked Questions

Related MQL5 pages

Technical references

Risk and testing note

These educational examples require independent compilation and testing. A compile pass or an illustrative setting does not establish execution correctness or profitability. Any reported performance must be supported by reproducible data and test settings; past results do not predict future returns. Trading involves significant risk of loss. This content is not financial advice.