Problem Description
Solution
To achieve this functionality, we need to create an Expert Advisor (EA) rather than a simple Script.
Why an EA?
- Scripts run once and terminate immediately. They cannot "wait" for a trade to open.
- Expert Advisors run continuously on every tick, allowing them to monitor the account state and trigger actions (like taking a screenshot) the moment a new order is detected.
MQL4 Expert Advisor: AutoScreenshot_OnTrade
This EA monitors the trade pool. When the number of open trades for the current symbol increases, it identifies the new order and saves a screenshot to your MQL4\Files folder.
//+------------------------------------------------------------------+
//| AutoScreenshot_OnTrade.mq4 |
//| Copyright 2023, Quantitative |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Quantitative"
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//--- Input Parameters
input int ImageWidth = 1366; // Screenshot Width (pixels)
input int ImageHeight = 768; // Screenshot Height (pixels)
input string FilePrefix = "TradeShot"; // Filename Prefix
//--- Global Variables
int lastOrderCount = 0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Initialize the order count so we don't take photos of existing trades on startup
lastOrderCount = CountOrders();
Print("AutoScreenshot EA Started. Monitoring for new trades on ", Symbol());
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Get the current number of orders for this symbol
int currentOrderCount = CountOrders();
// Check if the number of orders has increased
if(currentOrderCount > lastOrderCount)
{
// A new trade has been opened
// We need to find the ticket number of the newest trade to name the file
int lastTicket = GetLastOrderTicket();
if(lastTicket > 0)
{
TakeScreenshot(lastTicket);
}
}
// Update the tracker
lastOrderCount = currentOrderCount;
}
//+------------------------------------------------------------------+
//| Helper: Counts open trades for the current symbol only |
//+------------------------------------------------------------------+
int CountOrders()
{
int count = 0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
// Only count trades for the chart the EA is attached to
if(OrderSymbol() == Symbol())
{
count++;
}
}
}
return(count);
}
//+------------------------------------------------------------------+
//| Helper: Finds the ticket number of the most recently opened trade|
//+------------------------------------------------------------------+
int GetLastOrderTicket()
{
datetime lastTime = 0;
int ticket = -1;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol())
{
// Find the order with the latest open time
if(OrderOpenTime() > lastTime)
{
lastTime = OrderOpenTime();
ticket = OrderTicket();
}
}
}
}
return(ticket);
}
//+------------------------------------------------------------------+
//| Helper: Captures the screen and saves as GIF |
//+------------------------------------------------------------------+
void TakeScreenshot(int ticket)
{
// Construct a unique filename: Prefix_Symbol_Ticket_Time.gif
string timeStr = TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS);
StringReplace(timeStr, ":", "-"); // Replace colons for valid filename
StringReplace(timeStr, " ", "_"); // Replace spaces
string filename = StringFormat("%s_%s_Ticket%d_%s.gif",
FilePrefix,
Symbol(),
ticket,
timeStr);
// Take the screenshot
// start_bar=0 (current), chart_scale=-1 (current), chart_mode=-1 (current)
bool res = WindowScreenShot(filename, ImageWidth, ImageHeight, 0, -1, -1);
if(res)
Print("Screenshot saved: ", filename);
else
Print("Error saving screenshot. Error code: ", GetLastError());
}
//+------------------------------------------------------------------+
How to Install and Use
- Copy the Code: Copy the code block above.
- Open MetaEditor: In MT4, press
F4or click the "MetaEditor" button. - Create New File: Click New -> Expert Advisor (template) -> Next.
- Name it: Name it
AutoScreenshotand click Finish. - Paste: Delete everything in the new file and paste the code provided above.
- Compile: Press
F7or click Compile. Ensure there are no errors in the "Errors" tab at the bottom. - Attach to Chart:
- Go back to the main MT4 terminal.
- Find
AutoScreenshotin the Navigator window under Expert Advisors. - Drag and drop it onto the chart you want to monitor.
- Important: Ensure "Allow live trading" is checked in the Common tab (though this EA doesn't trade, it requires permission to run logic).
- Test: Open a trade manually on that chart. Check the Experts tab in the Terminal window for a confirmation message.
Where are the files saved?
The screenshots are saved in the MT4 Data Folder.
- Go to File -> Open Data Folder.
- Navigate to
MQL4->Files. - You will see your GIF files there.
Key Features of the Code
- Symbol Specific: It filters orders using
OrderSymbol() == Symbol(). It will only take a picture if a trade opens on the specific chart where the EA is running. - Dynamic Naming: The filename includes the Symbol, Ticket Number, and Timestamp to prevent overwriting previous images.
- GIF Format: The
WindowScreenShotfunction automatically detects the format based on the file extension provided (.gif).
Q&A
Q: Can I use this to capture screenshots for pending orders?
A: Yes. The OrdersTotal() function counts both market and pending orders. If you place a pending order, the count increases, and the EA will take a screenshot.
Q: Will this work if an automated EA opens the trade?
A: Yes. This utility monitors the account state. It does not matter if a human or another algorithm opened the trade; as long as the trade appears in the terminal list, the screenshot will trigger.
Q: Why did you use WindowScreenShot instead of ChartScreenShot?
A: WindowScreenShot is the older MQL4 standard function that is highly reliable for capturing the visual state of the current window. ChartScreenShot is the newer MQL5-style function available in updated MQL4, but WindowScreenShot is sufficient and simpler for this specific task.
Q: Does the chart need to be visible?
A: Yes. WindowScreenShot captures what is rendered. If the chart is minimized or covered, it might still capture the data, but it is best practice to keep the terminal open.