Generate code in 3 minutes
Enter your idea and AI generates runnable code.
To manage charts programmatically in MQL4, you utilize the ChartOpen, ChartClose, and the chart navigation functions (ChartFirst, ChartNext) to iterate through existing windows.
Below is a complete script that demonstrates three core functionalities:
FindChartID: Iterates through all open charts to find a specific Symbol and Timeframe.OpenNewChart: Opens a new chart window.CloseChartWindow: Closes a specific chart window.//+------------------------------------------------------------------+
//| ChartManagerScript.mq4 |
//| Copyright 2023, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#property script_show_inputs
//--- Input parameters
input string InpSymbol = "EURUSD"; // Symbol to manage
input ENUM_TIMEFRAMES InpPeriod = PERIOD_H1; // Timeframe to manage
input bool InpCloseIfFound = false; // Close chart if found?
input bool InpOpenIfMissing = true; // Open chart if not found?
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
// 1. Try to find an existing chart for the specified Symbol and Period
long chartID = FindChartID(InpSymbol, InpPeriod);
if(chartID > 0)
{
PrintFormat("Found existing chart for %s %s. ID: %I64d",
InpSymbol, GetPeriodName(InpPeriod), chartID);
// Bring the found chart to the foreground (optional)
// ChartSetInteger(chartID, CHART_BRING_TO_TOP, true);
if(InpCloseIfFound)
{
// Prevent closing the chart the script is currently running on
if(chartID == ChartID())
{
Print("Cannot close the chart where the script is running.");
}
else
{
Print("Closing chart ID: ", chartID);
if(ChartClose(chartID))
Print("Chart closed successfully.");
else
Print("Failed to close chart. Error: ", GetLastError());
}
}
}
else
{
PrintFormat("Chart for %s %s not found.", InpSymbol, GetPeriodName(InpPeriod));
if(InpOpenIfMissing)
{
Print("Attempting to open new chart...");
long newChartID = ChartOpen(InpSymbol, InpPeriod);
if(newChartID > 0)
PrintFormat("Successfully opened new chart. ID: %I64d", newChartID);
else
Print("Failed to open chart. Error: ", GetLastError());
}
}
}
//+------------------------------------------------------------------+
//| Function to find a chart ID by Symbol and Period |
//+------------------------------------------------------------------+
long FindChartID(string symbol, ENUM_TIMEFRAMES period)
{
long currChartId = ChartFirst(); // Get the first chart ID
// Loop through all open charts
while(currChartId >= 0)
{
// Check if Symbol and Period match
if(ChartSymbol(currChartId) == symbol && ChartPeriod(currChartId) == period)
{
return(currChartId); // Return the ID if found
}
// Move to the next chart
currChartId = ChartNext(currChartId);
}
return(0); // Return 0 if not found
}
//+------------------------------------------------------------------+
//| Helper function to convert period enum to string |
//+------------------------------------------------------------------+
string GetPeriodName(ENUM_TIMEFRAMES period)
{
switch(period)
{
case PERIOD_M1: return("M1");
case PERIOD_M5: return("M5");
case PERIOD_M15: return("M15");
case PERIOD_M30: return("M30");
case PERIOD_H1: return("H1");
case PERIOD_H4: return("H4");
case PERIOD_D1: return("D1");
case PERIOD_W1: return("W1");
case PERIOD_MN1: return("MN1");
default: return("Unknown");
}
}
//+------------------------------------------------------------------+
ChartOpen(symbol, period):
long value representing the Chart ID.GetLastError() to debug.ChartClose(chart_id):
true if successful.ChartFirst() and ChartNext(chart_id):
ChartFirst() gets the ID of the very first chart in the terminal list.ChartNext(current_id) gets the ID of the chart following the current one.ChartNext returns -1 (end of list).ChartSymbol(chart_id) and ChartPeriod(chart_id):
ChartManager.mq4).true if you want to close that specific chart if it already exists.true if you want to open it if it doesn't exist.Q: Can I open a chart for a symbol that is not in the Market Watch?
A: No. If the symbol is not selected in the Market Watch window, ChartOpen may fail or return error 4106 (ERR_UNKNOWN_SYMBOL). You should ensure the symbol is selected using SymbolSelect("SymbolName", true) before attempting to open the chart.
Q: Does ChartClose work on the chart running the script?
A: Yes, a script can close its own chart. However, this immediately terminates the script execution. In the provided code, I added a safety check if(chartID == ChartID()) to prevent accidental self-closing, but you can remove this if that is the desired behavior.
Q: How do I apply a template to the newly opened chart?
A: Immediately after getting the newChartID from ChartOpen, you can call ChartApplyTemplate(newChartID, "MyTemplate.tpl");. Note that this is an asynchronous command and is added to the chart's queue.