OnTimer, OnTrade, OnChartEvent, and pushing a notification to your phone.
Advanced10 min readBeginner → AdvancedLesson 16 / 17
Try it in MetaEditor
Timer, trade events, chart keys, and push alerts
Save as MQL5/Experts/Lesson16Events.mq5. It puts a live dashboard on the chart with a timer, logs trade events, and sends a push notification when you press B.
//+------------------------------------------------------------------+
//| Lesson 16 - Timers, trade events, chart events, notifications |
//+------------------------------------------------------------------+
#property copyright "Strategist Academy"
#property version "1.00"
#property strict
input int TimerSeconds = 60;
int OnInit()
{
EventSetTimer(TimerSeconds);
Print("Timer set to ", TimerSeconds, "s. Press 'B' on the chart to send a test alert.");
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
EventKillTimer(); // always - a stray timer is a nasty bug
Comment(""); // clear the on-chart dashboard
}
//+------------------------------------------------------------------+
//| Time-based work: runs whether or not the market is moving |
//+------------------------------------------------------------------+
void OnTimer()
{
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double equity = AccountInfoDouble(ACCOUNT_EQUITY);
double free = AccountInfoDouble(ACCOUNT_MARGIN_FREE);
Comment("Lesson 16 dashboard",
"\nSymbol: ", _Symbol,
"\nBid: ", DoubleToString(bid, _Digits),
"\nEquity: ", DoubleToString(equity, 2),
"\nFree: ", DoubleToString(free, 2),
"\nPositions: ", PositionsTotal(),
"\nUpdated: ", TimeToString(TimeCurrent(), TIME_SECONDS));
}
//+------------------------------------------------------------------+
//| Fires when anything trade-related happens on the account |
//+------------------------------------------------------------------+
void OnTrade()
{
Print("Trade event. Positions total: ", PositionsTotal(),
" orders: ", OrdersTotal());
// React, but do not place new orders from in here - set a flag instead.
if(PositionSelect(_Symbol))
{
double sl = PositionGetDouble(POSITION_SL);
double tp = PositionGetDouble(POSITION_TP);
Print("Position on ", _Symbol,
" type=", (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY ? "BUY" : "SELL"),
" volume=", DoubleToString(PositionGetDouble(POSITION_VOLUME), 2),
" sl=", DoubleToString(sl, _Digits),
" tp=", DoubleToString(tp, _Digits));
}
}
//+------------------------------------------------------------------+
//| Keyboard and object interaction |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
if(id == CHARTEVENT_KEYDOWN)
{
if(lparam == 66) // 'B'
{
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
string msg = _Symbol + " manual check at " + DoubleToString(bid, _Digits);
Alert(msg);
Print("Alert raised: ", msg);
// Requires push notifications enabled in terminal settings.
if(!SendNotification(msg))
Print("SendNotification failed - enable push notifications in terminal options.");
}
}
}
To run it
1. Open MetaEditor from MT5 (press F4), and pick the folder this program belongs in — Experts, Indicators, or Scripts.
2. Create a new file, paste this over it, then press F7 to compile. Fix anything the Errors tab reports.
3. Back in MT5, drag it onto a chart — or open the Strategy Tester if it is an Expert Advisor.
Beyond OnTick
Ticks only arrive when the market moves. Plenty of what an EA needs is time-based or event-based, not price-based. MQL5 gives you handlers for each.
OnTimer
Call EventSetTimer(seconds) in OnInit and OnTimer() fires on that interval regardless of market activity. Use it for session checks, daily risk resets, periodic health reports, and any housekeeping that must happen even on a dead market. Always EventKillTimer() in OnDeinit — a timer that outlives its EA is a bug that is very hard to find later.
OnTrade and OnTradeTransaction
These fire when something happens on the account: an order placed, a deal executed, a position closed. Use OnTrade to react — update your state, log, or send a notification. Do not place new orders directly from inside it; set a flag and act on the next tick instead, or you risk re-entrant loops.
OnChartEvent
Fires on mouse, keyboard, and object events. It is how you build interactive EAs: press a key to close everything, click a button to toggle trading. The id parameter tells you what happened; lparam carries the key code for CHARTEVENT_KEYDOWN.
Getting the alert to you
Alert() — a pop-up in the terminal. Loud, local, and easy to miss.
SendNotification() — push to the MT5 mobile app. Requires notifications enabled in terminal settings and your MetaQuotes ID. This is the one that actually reaches you.
SendMail() — email, if SMTP is configured.
PlaySound() — for when you are at the desk.
Comment for a live dashboard
Comment() writes text onto the chart. It is the cheapest possible status display — equity, open positions, current signal — and it costs nothing in the tester. Clear it with Comment("") on exit so you do not leave stale text behind.
What you just did
Lesson 16 of 17 in MetaTrader 5 MQL5 for CFD Traders. When you have run the examples or read the section, tick it off and move to the next lesson.