refactor: UTF-8

This commit is contained in:
Toh4iem9
2025-08-23 15:01:31 +02:00
parent 4c74075a2f
commit 4dd73def9e
14 changed files with 1602 additions and 1602 deletions
+55 -55
View File
@@ -1,55 +1,55 @@
# Account Info Display Script
## 1. Summary (Introduction)
The Account Info Display is an MQL5 script designed as a utility tool for traders. When executed on a chart, it displays a comprehensive, real-time overview of the current trading account's key statistics.
Unlike an indicator, which continuously recalculates based on price data, this script runs in a persistent loop, periodically refreshing and displaying account information directly on the chart using text label objects. Its primary purpose is to provide traders with at-a-glance access to crucial account metrics without needing to keep the "Terminal" window open.
## 2. Features and Displayed Data
The script organizes and displays account information in several logical categories:
- **I. Basic Info:**
- Login, Name, Server, Company, and account Currency.
- **II. Financials:**
- Real-time Balance, Credit, floating Profit/Loss, and Equity.
- **III. Margin:**
- Current Margin used, Free Margin, Margin Level (%), and the broker-defined Margin Call and Stop Out levels.
- **IV. Rules:**
- The account's trade mode (e.g., Real, Demo), Leverage, Margin Mode (e.g., Hedging), and other rules like FIFO.
- **V. Permissions:**
- Confirms whether trading is allowed and if Expert Advisors (EAs) are permitted to trade on the account.
## 3. MQL5 Implementation Details
The script was refocused to follow a clean, object-oriented, and modular design, adhering to our established coding principles.
- **Object-Oriented Design:** The core logic is encapsulated within a `CAccountInfoDisplay` class. A single global instance of this class (`g_accountDisplay`) manages the script's entire lifecycle.
- **Separation of Concerns:** The logic is clearly divided into two distinct responsibilities:
1. **Data Retrieval (`GetAccountData` method):** This method is solely responsible for querying the terminal for the latest account information using the standard `CAccountInfo` library class and formatting the data into a simple `SAccountData` structure.
2. **Data Presentation (`UpdateChartLabels` method):** This method is responsible only for the visual aspect. It takes the `SAccountData` structure and updates the text of the `CChartObjectLabel` objects on the chart. It includes an optimization to only update a label if its text has actually changed, reducing unnecessary chart redraws.
- **Modular Configuration (`AccountInfoDisplayInit.mqh`):** The labels and their order are not hard-coded into the main script. They are defined in a separate include file, `MyIncludes\AccountInfoDisplayInit.mqh`. This file contains:
- An `enum` (`ENUM_ACCOUNT_INFO_ROWS`) that provides clear, readable indices for each data row.
- A `const string` array (`g_init_labels`) that holds the text for each label.
- This approach makes it extremely easy to add, remove, or reorder the displayed information without touching the main script's logic.
- **Automatic Cleanup (RAII):** The script follows the **Resource Acquisition Is Initialization (RAII)** principle. The chart label objects are created in the `Init()` method, and their cleanup (deletion) is handled automatically by the `CAccountInfoDisplay` class's **destructor** (`~CAccountInfoDisplay`). This ensures that whenever the script is stopped or removed from the chart, all created objects are properly deleted, leaving the chart clean.
- **Persistent Loop:** The script's main logic resides in the `OnStart` function, which initializes the display object and then enters a `while(!IsStopped())` loop. Inside this loop, the `Processing()` method is called, which refreshes the data and sleeps for 1 second. This persistent execution is what allows the script to provide real-time updates, behaving much like an indicator.
## 4. Usage
1. **Installation:**
- Place `AccountInfoDisplay.mq5` into your `MQL5\Scripts` folder.
- Place `AccountInfoDisplayInit.mqh` into your `MQL5\Include\MyIncludes` folder.
2. **Execution:** Drag and drop the `AccountInfoDisplay` script from the Navigator window onto any chart.
3. **Termination:** To stop the script and remove the information from the chart, right-click on the chart and select "Remove Script". The script will automatically clean up all text objects it created.
## 5. Parameters
This script has no adjustable input parameters.
# Account Info Display Script
## 1. Summary (Introduction)
The Account Info Display is an MQL5 script designed as a utility tool for traders. When executed on a chart, it displays a comprehensive, real-time overview of the current trading account's key statistics.
Unlike an indicator, which continuously recalculates based on price data, this script runs in a persistent loop, periodically refreshing and displaying account information directly on the chart using text label objects. Its primary purpose is to provide traders with at-a-glance access to crucial account metrics without needing to keep the "Terminal" window open.
## 2. Features and Displayed Data
The script organizes and displays account information in several logical categories:
- **I. Basic Info:**
- Login, Name, Server, Company, and account Currency.
- **II. Financials:**
- Real-time Balance, Credit, floating Profit/Loss, and Equity.
- **III. Margin:**
- Current Margin used, Free Margin, Margin Level (%), and the broker-defined Margin Call and Stop Out levels.
- **IV. Rules:**
- The account's trade mode (e.g., Real, Demo), Leverage, Margin Mode (e.g., Hedging), and other rules like FIFO.
- **V. Permissions:**
- Confirms whether trading is allowed and if Expert Advisors (EAs) are permitted to trade on the account.
## 3. MQL5 Implementation Details
The script was refocused to follow a clean, object-oriented, and modular design, adhering to our established coding principles.
- **Object-Oriented Design:** The core logic is encapsulated within a `CAccountInfoDisplay` class. A single global instance of this class (`g_accountDisplay`) manages the script's entire lifecycle.
- **Separation of Concerns:** The logic is clearly divided into two distinct responsibilities:
1. **Data Retrieval (`GetAccountData` method):** This method is solely responsible for querying the terminal for the latest account information using the standard `CAccountInfo` library class and formatting the data into a simple `SAccountData` structure.
2. **Data Presentation (`UpdateChartLabels` method):** This method is responsible only for the visual aspect. It takes the `SAccountData` structure and updates the text of the `CChartObjectLabel` objects on the chart. It includes an optimization to only update a label if its text has actually changed, reducing unnecessary chart redraws.
- **Modular Configuration (`AccountInfoDisplayInit.mqh`):** The labels and their order are not hard-coded into the main script. They are defined in a separate include file, `MyIncludes\AccountInfoDisplayInit.mqh`. This file contains:
- An `enum` (`ENUM_ACCOUNT_INFO_ROWS`) that provides clear, readable indices for each data row.
- A `const string` array (`g_init_labels`) that holds the text for each label.
- This approach makes it extremely easy to add, remove, or reorder the displayed information without touching the main script's logic.
- **Automatic Cleanup (RAII):** The script follows the **Resource Acquisition Is Initialization (RAII)** principle. The chart label objects are created in the `Init()` method, and their cleanup (deletion) is handled automatically by the `CAccountInfoDisplay` class's **destructor** (`~CAccountInfoDisplay`). This ensures that whenever the script is stopped or removed from the chart, all created objects are properly deleted, leaving the chart clean.
- **Persistent Loop:** The script's main logic resides in the `OnStart` function, which initializes the display object and then enters a `while(!IsStopped())` loop. Inside this loop, the `Processing()` method is called, which refreshes the data and sleeps for 1 second. This persistent execution is what allows the script to provide real-time updates, behaving much like an indicator.
## 4. Usage
1. **Installation:**
- Place `AccountInfoDisplay.mq5` into your `MQL5\Scripts` folder.
- Place `AccountInfoDisplayInit.mqh` into your `MQL5\Include\MyIncludes` folder.
2. **Execution:** Drag and drop the `AccountInfoDisplay` script from the Navigator window onto any chart.
3. **Termination:** To stop the script and remove the information from the chart, right-click on the chart and select "Remove Script". The script will automatically clean up all text objects it created.
## 5. Parameters
This script has no adjustable input parameters.
+196 -196
View File
@@ -1,196 +1,196 @@
//+------------------------------------------------------------------+
//| AccountInfoDisplay.mq5 |
//| Copyright 2025, xxxxxxxx |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, xxxxxxxx"
#property link ""
#property description "Displays account information directly on the chart."
#property version "2.02" // Final fix for boolean conversion
//--- Standard library includes
#include <Trade\AccountInfo.mqh>
#include <ChartObjects\ChartObjectsTxtControls.mqh>
//--- Custom include file for initialization data
#include <MyIncludes\AccountInfoDisplayInit.mqh>
//+------------------------------------------------------------------+
//| A simple structure to hold the formatted account data |
//+------------------------------------------------------------------+
struct SAccountData
{
string data[ROW_TOTAL_COUNT];
};
//+------------------------------------------------------------------+
//| Account Info Display script class |
//+------------------------------------------------------------------+
class CAccountInfoDisplay
{
protected:
CAccountInfo m_account;
CChartObjectLabel m_labels[ROW_TOTAL_COUNT];
CChartObjectLabel m_values[ROW_TOTAL_COUNT];
public:
CAccountInfoDisplay(void);
~CAccountInfoDisplay(void);
bool Init(void);
void Processing(void);
protected:
void GetAccountData(SAccountData &account_data);
void UpdateChartLabels(const SAccountData &account_data);
};
//--- Global instance of our class
CAccountInfoDisplay g_accountDisplay;
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CAccountInfoDisplay::CAccountInfoDisplay(void)
{
}
//+------------------------------------------------------------------+
//| Destructor (handles deinitialization) |
//+------------------------------------------------------------------+
CAccountInfoDisplay::~CAccountInfoDisplay(void)
{
for(int i = 0; i < ROW_TOTAL_COUNT; i++)
{
m_labels[i].Delete();
m_values[i].Delete();
}
ChartRedraw();
}
//+------------------------------------------------------------------+
//| Initialization Method |
//+------------------------------------------------------------------+
bool CAccountInfoDisplay::Init(void)
{
int y_start = 10;
int y_step = 16;
color color_label;
color color_value;
color color_heading = clrDarkGray;
int font_size_data = 8;
int font_size_heading = 9;
color_value = (color)(ChartGetInteger(0, CHART_COLOR_BACKGROUND) ^ 0xFFFFFF);
color_label = (color)(color_value ^ 0x202020);
if(ChartGetInteger(0, CHART_SHOW_OHLC))
y_start += 16;
int current_y = y_start;
for(int i = 0; i < ROW_TOTAL_COUNT; i++)
{
bool is_heading = (StringFind(g_init_labels[i], "I. ") == 0 || StringFind(g_init_labels[i], "II. ") == 0 ||
StringFind(g_init_labels[i], "III. ") == 0 || StringFind(g_init_labels[i], "IV. ") == 0 ||
StringFind(g_init_labels[i], "V. ") == 0);
m_labels[i].Create(0, "AccInfoLabel" + (string)i, 0, 20, current_y);
m_labels[i].Description(g_init_labels[i]);
m_labels[i].Color(is_heading ? color_heading : color_label);
m_labels[i].FontSize(is_heading ? font_size_heading : font_size_data);
m_labels[i].Selectable(false);
m_values[i].Create(0, "AccInfoValue" + (string)i, 0, 140, current_y);
m_values[i].Description("...");
m_values[i].Color(color_value);
m_values[i].FontSize(font_size_data);
m_values[i].Selectable(false);
current_y += y_step;
}
SAccountData data;
GetAccountData(data);
UpdateChartLabels(data);
ChartRedraw();
return(true);
}
//+------------------------------------------------------------------+
//| Processing Method (called in a loop) |
//+------------------------------------------------------------------+
void CAccountInfoDisplay::Processing(void)
{
SAccountData data;
GetAccountData(data);
UpdateChartLabels(data);
ChartRedraw();
Sleep(1000);
}
//+------------------------------------------------------------------+
//| Fills the data structure with current account info |
//+------------------------------------------------------------------+
void CAccountInfoDisplay::GetAccountData(SAccountData &account_data)
{
// This method is part of the CAccountInfoDisplay class, so it can see the m_account member.
// The enum values are global because of the #include.
// The CAccountInfo class does not have a Refresh() method.
// Data is refreshed automatically by the terminal.
account_data.data[ROW_LOGIN] = (string)m_account.Login();
account_data.data[ROW_NAME] = m_account.Name();
account_data.data[ROW_SERVER] = m_account.Server();
account_data.data[ROW_COMPANY] = m_account.Company();
account_data.data[ROW_CURRENCY] = m_account.Currency();
account_data.data[ROW_CURRENCY_DIGITS] = (string)m_account.InfoInteger(ACCOUNT_CURRENCY_DIGITS);
account_data.data[ROW_BALANCE] = DoubleToString(m_account.Balance(), 2);
account_data.data[ROW_CREDIT] = DoubleToString(m_account.Credit(), 2);
account_data.data[ROW_PROFIT] = DoubleToString(m_account.Profit(), 2);
account_data.data[ROW_EQUITY] = DoubleToString(m_account.Equity(), 2);
account_data.data[ROW_MARGIN] = DoubleToString(m_account.Margin(), 2);
account_data.data[ROW_MARGIN_FREE] = DoubleToString(m_account.FreeMargin(), 2);
account_data.data[ROW_MARGIN_LEVEL] = DoubleToString(m_account.MarginLevel(), 2);
account_data.data[ROW_MARGIN_CALL] = DoubleToString(m_account.MarginCall(), 2);
account_data.data[ROW_MARGIN_STOPOUT] = DoubleToString(m_account.MarginStopOut(), 2);
account_data.data[ROW_TRADE_MODE] = m_account.TradeModeDescription();
account_data.data[ROW_LEVERAGE] = (string)m_account.Leverage();
account_data.data[ROW_MARGIN_MODE] = m_account.MarginModeDescription();
account_data.data[ROW_STOPOUT_MODE] = m_account.StopoutModeDescription();
account_data.data[ROW_FIFO_CLOSE] = (string)m_account.InfoInteger(ACCOUNT_FIFO_CLOSE);
account_data.data[ROW_HEDGE_ALLOWED] = (string)m_account.InfoInteger(ACCOUNT_HEDGE_ALLOWED);
account_data.data[ROW_TRADE_ALLOWED] = m_account.TradeAllowed() ? "true" : "false";
account_data.data[ROW_TRADE_EXPERT] = m_account.TradeExpert() ? "true" : "false";
}
//+------------------------------------------------------------------+
//| Updates the chart labels from the data structure |
//+------------------------------------------------------------------+
void CAccountInfoDisplay::UpdateChartLabels(const SAccountData &account_data)
{
for(int i = 0; i < ROW_TOTAL_COUNT; i++)
{
if(m_values[i].Description() != account_data.data[i])
{
m_values[i].Description(account_data.data[i]);
}
}
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart(void)
{
if(g_accountDisplay.Init())
{
while(!IsStopped())
{
g_accountDisplay.Processing();
}
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| AccountInfoDisplay.mq5 |
//| Copyright 2025, xxxxxxxx |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, xxxxxxxx"
#property link ""
#property description "Displays account information directly on the chart."
#property version "2.02" // Final fix for boolean conversion
//--- Standard library includes
#include <Trade\AccountInfo.mqh>
#include <ChartObjects\ChartObjectsTxtControls.mqh>
//--- Custom include file for initialization data
#include <MyIncludes\AccountInfoDisplayInit.mqh>
//+------------------------------------------------------------------+
//| A simple structure to hold the formatted account data |
//+------------------------------------------------------------------+
struct SAccountData
{
string data[ROW_TOTAL_COUNT];
};
//+------------------------------------------------------------------+
//| Account Info Display script class |
//+------------------------------------------------------------------+
class CAccountInfoDisplay
{
protected:
CAccountInfo m_account;
CChartObjectLabel m_labels[ROW_TOTAL_COUNT];
CChartObjectLabel m_values[ROW_TOTAL_COUNT];
public:
CAccountInfoDisplay(void);
~CAccountInfoDisplay(void);
bool Init(void);
void Processing(void);
protected:
void GetAccountData(SAccountData &account_data);
void UpdateChartLabels(const SAccountData &account_data);
};
//--- Global instance of our class
CAccountInfoDisplay g_accountDisplay;
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CAccountInfoDisplay::CAccountInfoDisplay(void)
{
}
//+------------------------------------------------------------------+
//| Destructor (handles deinitialization) |
//+------------------------------------------------------------------+
CAccountInfoDisplay::~CAccountInfoDisplay(void)
{
for(int i = 0; i < ROW_TOTAL_COUNT; i++)
{
m_labels[i].Delete();
m_values[i].Delete();
}
ChartRedraw();
}
//+------------------------------------------------------------------+
//| Initialization Method |
//+------------------------------------------------------------------+
bool CAccountInfoDisplay::Init(void)
{
int y_start = 10;
int y_step = 16;
color color_label;
color color_value;
color color_heading = clrDarkGray;
int font_size_data = 8;
int font_size_heading = 9;
color_value = (color)(ChartGetInteger(0, CHART_COLOR_BACKGROUND) ^ 0xFFFFFF);
color_label = (color)(color_value ^ 0x202020);
if(ChartGetInteger(0, CHART_SHOW_OHLC))
y_start += 16;
int current_y = y_start;
for(int i = 0; i < ROW_TOTAL_COUNT; i++)
{
bool is_heading = (StringFind(g_init_labels[i], "I. ") == 0 || StringFind(g_init_labels[i], "II. ") == 0 ||
StringFind(g_init_labels[i], "III. ") == 0 || StringFind(g_init_labels[i], "IV. ") == 0 ||
StringFind(g_init_labels[i], "V. ") == 0);
m_labels[i].Create(0, "AccInfoLabel" + (string)i, 0, 20, current_y);
m_labels[i].Description(g_init_labels[i]);
m_labels[i].Color(is_heading ? color_heading : color_label);
m_labels[i].FontSize(is_heading ? font_size_heading : font_size_data);
m_labels[i].Selectable(false);
m_values[i].Create(0, "AccInfoValue" + (string)i, 0, 140, current_y);
m_values[i].Description("...");
m_values[i].Color(color_value);
m_values[i].FontSize(font_size_data);
m_values[i].Selectable(false);
current_y += y_step;
}
SAccountData data;
GetAccountData(data);
UpdateChartLabels(data);
ChartRedraw();
return(true);
}
//+------------------------------------------------------------------+
//| Processing Method (called in a loop) |
//+------------------------------------------------------------------+
void CAccountInfoDisplay::Processing(void)
{
SAccountData data;
GetAccountData(data);
UpdateChartLabels(data);
ChartRedraw();
Sleep(1000);
}
//+------------------------------------------------------------------+
//| Fills the data structure with current account info |
//+------------------------------------------------------------------+
void CAccountInfoDisplay::GetAccountData(SAccountData &account_data)
{
// This method is part of the CAccountInfoDisplay class, so it can see the m_account member.
// The enum values are global because of the #include.
// The CAccountInfo class does not have a Refresh() method.
// Data is refreshed automatically by the terminal.
account_data.data[ROW_LOGIN] = (string)m_account.Login();
account_data.data[ROW_NAME] = m_account.Name();
account_data.data[ROW_SERVER] = m_account.Server();
account_data.data[ROW_COMPANY] = m_account.Company();
account_data.data[ROW_CURRENCY] = m_account.Currency();
account_data.data[ROW_CURRENCY_DIGITS] = (string)m_account.InfoInteger(ACCOUNT_CURRENCY_DIGITS);
account_data.data[ROW_BALANCE] = DoubleToString(m_account.Balance(), 2);
account_data.data[ROW_CREDIT] = DoubleToString(m_account.Credit(), 2);
account_data.data[ROW_PROFIT] = DoubleToString(m_account.Profit(), 2);
account_data.data[ROW_EQUITY] = DoubleToString(m_account.Equity(), 2);
account_data.data[ROW_MARGIN] = DoubleToString(m_account.Margin(), 2);
account_data.data[ROW_MARGIN_FREE] = DoubleToString(m_account.FreeMargin(), 2);
account_data.data[ROW_MARGIN_LEVEL] = DoubleToString(m_account.MarginLevel(), 2);
account_data.data[ROW_MARGIN_CALL] = DoubleToString(m_account.MarginCall(), 2);
account_data.data[ROW_MARGIN_STOPOUT] = DoubleToString(m_account.MarginStopOut(), 2);
account_data.data[ROW_TRADE_MODE] = m_account.TradeModeDescription();
account_data.data[ROW_LEVERAGE] = (string)m_account.Leverage();
account_data.data[ROW_MARGIN_MODE] = m_account.MarginModeDescription();
account_data.data[ROW_STOPOUT_MODE] = m_account.StopoutModeDescription();
account_data.data[ROW_FIFO_CLOSE] = (string)m_account.InfoInteger(ACCOUNT_FIFO_CLOSE);
account_data.data[ROW_HEDGE_ALLOWED] = (string)m_account.InfoInteger(ACCOUNT_HEDGE_ALLOWED);
account_data.data[ROW_TRADE_ALLOWED] = m_account.TradeAllowed() ? "true" : "false";
account_data.data[ROW_TRADE_EXPERT] = m_account.TradeExpert() ? "true" : "false";
}
//+------------------------------------------------------------------+
//| Updates the chart labels from the data structure |
//+------------------------------------------------------------------+
void CAccountInfoDisplay::UpdateChartLabels(const SAccountData &account_data)
{
for(int i = 0; i < ROW_TOTAL_COUNT; i++)
{
if(m_values[i].Description() != account_data.data[i])
{
m_values[i].Description(account_data.data[i]);
}
}
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart(void)
{
if(g_accountDisplay.Init())
{
while(!IsStopped())
{
g_accountDisplay.Processing();
}
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
+97 -97
View File
@@ -1,97 +1,97 @@
//+------------------------------------------------------------------+
//| AccountInfoDisplayInit.mqh |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
//--- MODIFICATION: Using an enumeration for robust indexing
// This enum provides meaningful names for each row, preventing errors
// if the order of items in init_str changes.
enum ENUM_INFO_ROWS
{
// --- I. Basic Account Information ---
ROW_HEADING_BASIC,
ROW_LOGIN,
ROW_NAME,
ROW_SERVER,
ROW_COMPANY,
ROW_CURRENCY,
ROW_CURRENCY_DIGITS,
// --- II. Financial Status and Balances ---
ROW_HEADING_FINANCIAL,
ROW_BALANCE,
ROW_CREDIT,
ROW_PROFIT,
ROW_EQUITY,
// --- III. Margin and Risk Management ---
ROW_HEADING_MARGIN,
ROW_MARGIN,
ROW_MARGIN_FREE,
ROW_MARGIN_LEVEL,
ROW_MARGIN_CALL,
ROW_MARGIN_STOPOUT,
// --- IV. Trading Modes and Rules ---
ROW_HEADING_RULES,
ROW_TRADE_MODE,
ROW_LEVERAGE,
ROW_MARGIN_MODE,
ROW_STOPOUT_MODE,
ROW_FIFO_CLOSE,
ROW_HEDGE_ALLOWED,
// --- V. Trading Permissions ---
ROW_HEADING_PERMISSIONS,
ROW_TRADE_ALLOWED,
ROW_TRADE_EXPERT,
// A special member to get the total count of rows
ROW_TOTAL_COUNT
};
//--- The array of strings for display labels.
// The order MUST match the order in ENUM_INFO_ROWS.
string init_str[ROW_TOTAL_COUNT]=
{
// --- I. Basic Account Information ---
"I. Basic Account Information",
"Login",
"Name",
"Server",
"Company",
"Currency",
"Currency Digits",
// --- II. Financial Status and Balances ---
"II. Financial Status and Balances",
"Balance",
"Credit",
"Profit",
"Equity",
// --- III. Margin and Risk Management ---
"III. Margin and Risk Management",
"Margin",
"Free Margin",
"Margin Level",
"Margin Call",
"Margin StopOut",
// --- IV. Trading Modes and Rules ---
"IV. Trading Modes and Rules",
"Trade Mode",
"Leverage",
"Margin Mode",
"Stopout Mode",
"FIFO Close",
"Hedge Allowed",
// --- V. Trading Permissions ---
"V. Trading Permissions",
"Trade Allowed",
"Trade Expert"
};
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| AccountInfoDisplayInit.mqh |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
//--- MODIFICATION: Using an enumeration for robust indexing
// This enum provides meaningful names for each row, preventing errors
// if the order of items in init_str changes.
enum ENUM_INFO_ROWS
{
// --- I. Basic Account Information ---
ROW_HEADING_BASIC,
ROW_LOGIN,
ROW_NAME,
ROW_SERVER,
ROW_COMPANY,
ROW_CURRENCY,
ROW_CURRENCY_DIGITS,
// --- II. Financial Status and Balances ---
ROW_HEADING_FINANCIAL,
ROW_BALANCE,
ROW_CREDIT,
ROW_PROFIT,
ROW_EQUITY,
// --- III. Margin and Risk Management ---
ROW_HEADING_MARGIN,
ROW_MARGIN,
ROW_MARGIN_FREE,
ROW_MARGIN_LEVEL,
ROW_MARGIN_CALL,
ROW_MARGIN_STOPOUT,
// --- IV. Trading Modes and Rules ---
ROW_HEADING_RULES,
ROW_TRADE_MODE,
ROW_LEVERAGE,
ROW_MARGIN_MODE,
ROW_STOPOUT_MODE,
ROW_FIFO_CLOSE,
ROW_HEDGE_ALLOWED,
// --- V. Trading Permissions ---
ROW_HEADING_PERMISSIONS,
ROW_TRADE_ALLOWED,
ROW_TRADE_EXPERT,
// A special member to get the total count of rows
ROW_TOTAL_COUNT
};
//--- The array of strings for display labels.
// The order MUST match the order in ENUM_INFO_ROWS.
string init_str[ROW_TOTAL_COUNT]=
{
// --- I. Basic Account Information ---
"I. Basic Account Information",
"Login",
"Name",
"Server",
"Company",
"Currency",
"Currency Digits",
// --- II. Financial Status and Balances ---
"II. Financial Status and Balances",
"Balance",
"Credit",
"Profit",
"Equity",
// --- III. Margin and Risk Management ---
"III. Margin and Risk Management",
"Margin",
"Free Margin",
"Margin Level",
"Margin Call",
"Margin StopOut",
// --- IV. Trading Modes and Rules ---
"IV. Trading Modes and Rules",
"Trade Mode",
"Leverage",
"Margin Mode",
"Stopout Mode",
"FIFO Close",
"Hedge Allowed",
// --- V. Trading Permissions ---
"V. Trading Permissions",
"Trade Allowed",
"Trade Expert"
};
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
Binary file not shown.
+53 -53
View File
@@ -1,53 +1,53 @@
# Symbol Info Double Checker Script
## 1. Summary (Introduction)
The Symbol Info Double Checker is an MQL5 script designed as a **diagnostic and development tool**. When executed on a chart, it systematically queries and displays the status and value of every `ENUM_SYMBOL_INFO_DOUBLE` property for the chart's current symbol.
Its primary purpose is to provide developers and advanced traders with a quick and comprehensive way to check which data points are provided by their broker for a specific financial instrument. This is crucial for developing robust Expert Advisors and indicators, as it helps to identify which properties are supported and which are not, preventing potential runtime errors from requests for unavailable data.
## 2. Features and Displayed Data
The script iterates through a comprehensive, hard-coded list of all `ENUM_SYMBOL_INFO_DOUBLE` properties available in the MQL5 language. For each property, it prints a formatted line to the "Experts" tab of the terminal, indicating:
- **Property Name:** The official `enum` name of the property (e.g., `SYMBOL_TRADE_TICK_VALUE`).
- **Status:** Whether the request for the property was `SUPPORTED` or `FAILED`.
- **Value / Error:**
- If **supported**, it displays the retrieved `double` value.
- If **failed**, it displays the error code returned by `GetLastError()`, which can help in diagnosing the reason for the failure.
The output is neatly aligned in columns for easy readability.
## 3. MQL5 Implementation Details
The script was refactored to follow a clean, object-oriented, and modular design, making its logic reusable and easy to understand.
- **Object-Oriented Design:** The core logic is encapsulated within a `CSymbolPropertyChecker` class. This isolates the functionality from the script's entry point (`OnStart`).
- The constructor takes the symbol name as an argument.
- A single public method, `Run()`, executes the entire checking process.
- Private helper methods (`PrintHeader`, `PrintFooter`, `PrintProperty`) break down the logic into smaller, manageable pieces.
- **Self-Contained Logic:** The script is completely self-contained. It uses the standard `<Trade\SymbolInfo.mqh>` library to interact with the terminal's symbol properties but does not rely on any external indicators or custom include files beyond that.
- **Static Property List:** The array of `ENUM_SYMBOL_INFO_DOUBLE` properties is defined as a `static const` member of the `CSymbolPropertyChecker` class. This logically associates the data with the class that uses it, which is a cleaner approach than using a global variable.
- **Simplified `OnStart`:** The script's entry point, `OnStart()`, is now extremely simple. It is only responsible for creating an instance of the `CSymbolPropertyChecker` class and calling its `Run()` method. This clear separation of concerns makes the code's execution flow easy to trace.
- **Formatted Output:** The script uses `StringFormat` with padding (`%-35s`) to ensure that the output in the "Experts" tab is well-aligned, making it easy to scan and compare the results for different properties.
## 4. Usage
1. **Installation:**
- Place `SymbolInfoDoubleChecker.mq5` into your `MQL5\Scripts` folder.
2. **Execution:**
- Open the chart of the symbol you wish to inspect.
- Drag and drop the `SymbolInfoDoubleChecker` script from the Navigator window onto the chart.
3. **Review Output:**
- Open the "Terminal" window (Ctrl+T).
- Navigate to the "Experts" tab.
- The script will print the full list of properties and their status for the selected symbol. The script terminates automatically after printing the list.
## 5. Parameters
This script has no adjustable input parameters. It always runs on the symbol of the chart it is attached to.
# Symbol Info Double Checker Script
## 1. Summary (Introduction)
The Symbol Info Double Checker is an MQL5 script designed as a **diagnostic and development tool**. When executed on a chart, it systematically queries and displays the status and value of every `ENUM_SYMBOL_INFO_DOUBLE` property for the chart's current symbol.
Its primary purpose is to provide developers and advanced traders with a quick and comprehensive way to check which data points are provided by their broker for a specific financial instrument. This is crucial for developing robust Expert Advisors and indicators, as it helps to identify which properties are supported and which are not, preventing potential runtime errors from requests for unavailable data.
## 2. Features and Displayed Data
The script iterates through a comprehensive, hard-coded list of all `ENUM_SYMBOL_INFO_DOUBLE` properties available in the MQL5 language. For each property, it prints a formatted line to the "Experts" tab of the terminal, indicating:
- **Property Name:** The official `enum` name of the property (e.g., `SYMBOL_TRADE_TICK_VALUE`).
- **Status:** Whether the request for the property was `SUPPORTED` or `FAILED`.
- **Value / Error:**
- If **supported**, it displays the retrieved `double` value.
- If **failed**, it displays the error code returned by `GetLastError()`, which can help in diagnosing the reason for the failure.
The output is neatly aligned in columns for easy readability.
## 3. MQL5 Implementation Details
The script was refactored to follow a clean, object-oriented, and modular design, making its logic reusable and easy to understand.
- **Object-Oriented Design:** The core logic is encapsulated within a `CSymbolPropertyChecker` class. This isolates the functionality from the script's entry point (`OnStart`).
- The constructor takes the symbol name as an argument.
- A single public method, `Run()`, executes the entire checking process.
- Private helper methods (`PrintHeader`, `PrintFooter`, `PrintProperty`) break down the logic into smaller, manageable pieces.
- **Self-Contained Logic:** The script is completely self-contained. It uses the standard `<Trade\SymbolInfo.mqh>` library to interact with the terminal's symbol properties but does not rely on any external indicators or custom include files beyond that.
- **Static Property List:** The array of `ENUM_SYMBOL_INFO_DOUBLE` properties is defined as a `static const` member of the `CSymbolPropertyChecker` class. This logically associates the data with the class that uses it, which is a cleaner approach than using a global variable.
- **Simplified `OnStart`:** The script's entry point, `OnStart()`, is now extremely simple. It is only responsible for creating an instance of the `CSymbolPropertyChecker` class and calling its `Run()` method. This clear separation of concerns makes the code's execution flow easy to trace.
- **Formatted Output:** The script uses `StringFormat` with padding (`%-35s`) to ensure that the output in the "Experts" tab is well-aligned, making it easy to scan and compare the results for different properties.
## 4. Usage
1. **Installation:**
- Place `SymbolInfoDoubleChecker.mq5` into your `MQL5\Scripts` folder.
2. **Execution:**
- Open the chart of the symbol you wish to inspect.
- Drag and drop the `SymbolInfoDoubleChecker` script from the Navigator window onto the chart.
3. **Review Output:**
- Open the "Terminal" window (Ctrl+T).
- Navigate to the "Experts" tab.
- The script will print the full list of properties and their status for the selected symbol. The script terminates automatically after printing the list.
## 5. Parameters
This script has no adjustable input parameters. It always runs on the symbol of the chart it is attached to.
+146 -146
View File
@@ -1,146 +1,146 @@
//+------------------------------------------------------------------+
//| SymbolInfoDoubleChecker.mq5 |
//| Copyright 2025, xxxxxxxx |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, xxxxxxxx"
#property link ""
#property version "2.00" // Refactored into a class-based structure
#property description "Checks and displays all DOUBLE properties for the current symbol."
#include <Trade\SymbolInfo.mqh>
//+------------------------------------------------------------------+
//| Class to check and display symbol properties |
//+------------------------------------------------------------------+
class CSymbolPropertyChecker
{
private:
CSymbolInfo m_symbol_info;
string m_symbol_name;
//--- Array of all double properties to check.
static const ENUM_SYMBOL_INFO_DOUBLE S_DOUBLE_PROPERTIES[];
public:
CSymbolPropertyChecker(const string symbol);
bool Run(void);
private:
void PrintHeader(void);
void PrintFooter(void);
void PrintProperty(ENUM_SYMBOL_INFO_DOUBLE property_id);
};
//--- Static member initialization
const ENUM_SYMBOL_INFO_DOUBLE CSymbolPropertyChecker::S_DOUBLE_PROPERTIES[] =
{
SYMBOL_BID, SYMBOL_BIDHIGH, SYMBOL_BIDLOW, SYMBOL_ASK, SYMBOL_ASKHIGH,
SYMBOL_ASKLOW, SYMBOL_LAST, SYMBOL_LASTHIGH, SYMBOL_LASTLOW,
SYMBOL_VOLUME_REAL, SYMBOL_VOLUMEHIGH_REAL, SYMBOL_VOLUMELOW_REAL,
SYMBOL_OPTION_STRIKE, SYMBOL_POINT, SYMBOL_TRADE_TICK_VALUE,
SYMBOL_TRADE_TICK_VALUE_PROFIT, SYMBOL_TRADE_TICK_VALUE_LOSS,
SYMBOL_TRADE_TICK_SIZE, SYMBOL_TRADE_CONTRACT_SIZE,
SYMBOL_TRADE_ACCRUED_INTEREST, SYMBOL_TRADE_FACE_VALUE,
SYMBOL_TRADE_LIQUIDITY_RATE, SYMBOL_VOLUME_MIN, SYMBOL_VOLUME_MAX,
SYMBOL_VOLUME_STEP, SYMBOL_VOLUME_LIMIT, SYMBOL_SWAP_LONG,
SYMBOL_SWAP_SHORT, SYMBOL_SWAP_SUNDAY, SYMBOL_SWAP_MONDAY, SYMBOL_SWAP_TUESDAY,
SYMBOL_SWAP_WEDNESDAY, SYMBOL_SWAP_THURSDAY, SYMBOL_SWAP_FRIDAY,
SYMBOL_SWAP_SATURDAY, SYMBOL_MARGIN_INITIAL, SYMBOL_MARGIN_MAINTENANCE,
SYMBOL_SESSION_VOLUME, SYMBOL_SESSION_TURNOVER, SYMBOL_SESSION_INTEREST,
SYMBOL_SESSION_BUY_ORDERS_VOLUME, SYMBOL_SESSION_SELL_ORDERS_VOLUME,
SYMBOL_SESSION_OPEN, SYMBOL_SESSION_CLOSE, SYMBOL_SESSION_AW,
SYMBOL_SESSION_PRICE_SETTLEMENT, SYMBOL_SESSION_PRICE_LIMIT_MIN,
SYMBOL_SESSION_PRICE_LIMIT_MAX, SYMBOL_MARGIN_HEDGED, SYMBOL_PRICE_CHANGE,
SYMBOL_PRICE_VOLATILITY, SYMBOL_PRICE_THEORETICAL, SYMBOL_PRICE_DELTA,
SYMBOL_PRICE_THETA, SYMBOL_PRICE_GAMMA, SYMBOL_PRICE_VEGA,
SYMBOL_PRICE_RHO, SYMBOL_PRICE_OMEGA, SYMBOL_PRICE_SENSITIVITY
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CSymbolPropertyChecker::CSymbolPropertyChecker(const string symbol) : m_symbol_name(symbol)
{
// Initialization of m_symbol_info is handled in Run()
}
//+------------------------------------------------------------------+
//| Runs the property check process |
//+------------------------------------------------------------------+
bool CSymbolPropertyChecker::Run(void)
{
if(!m_symbol_info.Name(m_symbol_name))
{
PrintFormat("Error: Symbol '%s' not found or not available in Market Watch.", m_symbol_name);
return false;
}
PrintHeader();
for(int i = 0; i < ArraySize(S_DOUBLE_PROPERTIES); i++)
{
PrintProperty(S_DOUBLE_PROPERTIES[i]);
}
PrintFooter();
return true;
}
//+------------------------------------------------------------------+
//| Prints a single property's status and value |
//+------------------------------------------------------------------+
void CSymbolPropertyChecker::PrintProperty(ENUM_SYMBOL_INFO_DOUBLE property_id)
{
double value;
string result_str;
string property_name = EnumToString(property_id);
ResetLastError();
bool success = m_symbol_info.InfoDouble(property_id, value);
int error = GetLastError();
if(success)
{
result_str = StringFormat("%-35s | Status: SUPPORTED | Value: %g",
property_name,
value);
}
else
{
result_str = StringFormat("%-35s | Status: FAILED | Error: %d",
property_name,
error);
}
Print(result_str);
}
//+------------------------------------------------------------------+
//| Prints the header for the output |
//+------------------------------------------------------------------+
void CSymbolPropertyChecker::PrintHeader(void)
{
Print("--- Symbol Property Checker Started ---");
PrintFormat("Checking symbol: %s", m_symbol_name);
Print("------------------------------------------------------------------");
}
//+------------------------------------------------------------------+
//| Prints the footer for the output |
//+------------------------------------------------------------------+
void CSymbolPropertyChecker::PrintFooter(void)
{
Print("------------------------------------------------------------------");
Print("--- Check Completed ---");
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
CSymbolPropertyChecker checker(_Symbol);
checker.Run();
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| SymbolInfoDoubleChecker.mq5 |
//| Copyright 2025, xxxxxxxx |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, xxxxxxxx"
#property link ""
#property version "2.00" // Refactored into a class-based structure
#property description "Checks and displays all DOUBLE properties for the current symbol."
#include <Trade\SymbolInfo.mqh>
//+------------------------------------------------------------------+
//| Class to check and display symbol properties |
//+------------------------------------------------------------------+
class CSymbolPropertyChecker
{
private:
CSymbolInfo m_symbol_info;
string m_symbol_name;
//--- Array of all double properties to check.
static const ENUM_SYMBOL_INFO_DOUBLE S_DOUBLE_PROPERTIES[];
public:
CSymbolPropertyChecker(const string symbol);
bool Run(void);
private:
void PrintHeader(void);
void PrintFooter(void);
void PrintProperty(ENUM_SYMBOL_INFO_DOUBLE property_id);
};
//--- Static member initialization
const ENUM_SYMBOL_INFO_DOUBLE CSymbolPropertyChecker::S_DOUBLE_PROPERTIES[] =
{
SYMBOL_BID, SYMBOL_BIDHIGH, SYMBOL_BIDLOW, SYMBOL_ASK, SYMBOL_ASKHIGH,
SYMBOL_ASKLOW, SYMBOL_LAST, SYMBOL_LASTHIGH, SYMBOL_LASTLOW,
SYMBOL_VOLUME_REAL, SYMBOL_VOLUMEHIGH_REAL, SYMBOL_VOLUMELOW_REAL,
SYMBOL_OPTION_STRIKE, SYMBOL_POINT, SYMBOL_TRADE_TICK_VALUE,
SYMBOL_TRADE_TICK_VALUE_PROFIT, SYMBOL_TRADE_TICK_VALUE_LOSS,
SYMBOL_TRADE_TICK_SIZE, SYMBOL_TRADE_CONTRACT_SIZE,
SYMBOL_TRADE_ACCRUED_INTEREST, SYMBOL_TRADE_FACE_VALUE,
SYMBOL_TRADE_LIQUIDITY_RATE, SYMBOL_VOLUME_MIN, SYMBOL_VOLUME_MAX,
SYMBOL_VOLUME_STEP, SYMBOL_VOLUME_LIMIT, SYMBOL_SWAP_LONG,
SYMBOL_SWAP_SHORT, SYMBOL_SWAP_SUNDAY, SYMBOL_SWAP_MONDAY, SYMBOL_SWAP_TUESDAY,
SYMBOL_SWAP_WEDNESDAY, SYMBOL_SWAP_THURSDAY, SYMBOL_SWAP_FRIDAY,
SYMBOL_SWAP_SATURDAY, SYMBOL_MARGIN_INITIAL, SYMBOL_MARGIN_MAINTENANCE,
SYMBOL_SESSION_VOLUME, SYMBOL_SESSION_TURNOVER, SYMBOL_SESSION_INTEREST,
SYMBOL_SESSION_BUY_ORDERS_VOLUME, SYMBOL_SESSION_SELL_ORDERS_VOLUME,
SYMBOL_SESSION_OPEN, SYMBOL_SESSION_CLOSE, SYMBOL_SESSION_AW,
SYMBOL_SESSION_PRICE_SETTLEMENT, SYMBOL_SESSION_PRICE_LIMIT_MIN,
SYMBOL_SESSION_PRICE_LIMIT_MAX, SYMBOL_MARGIN_HEDGED, SYMBOL_PRICE_CHANGE,
SYMBOL_PRICE_VOLATILITY, SYMBOL_PRICE_THEORETICAL, SYMBOL_PRICE_DELTA,
SYMBOL_PRICE_THETA, SYMBOL_PRICE_GAMMA, SYMBOL_PRICE_VEGA,
SYMBOL_PRICE_RHO, SYMBOL_PRICE_OMEGA, SYMBOL_PRICE_SENSITIVITY
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CSymbolPropertyChecker::CSymbolPropertyChecker(const string symbol) : m_symbol_name(symbol)
{
// Initialization of m_symbol_info is handled in Run()
}
//+------------------------------------------------------------------+
//| Runs the property check process |
//+------------------------------------------------------------------+
bool CSymbolPropertyChecker::Run(void)
{
if(!m_symbol_info.Name(m_symbol_name))
{
PrintFormat("Error: Symbol '%s' not found or not available in Market Watch.", m_symbol_name);
return false;
}
PrintHeader();
for(int i = 0; i < ArraySize(S_DOUBLE_PROPERTIES); i++)
{
PrintProperty(S_DOUBLE_PROPERTIES[i]);
}
PrintFooter();
return true;
}
//+------------------------------------------------------------------+
//| Prints a single property's status and value |
//+------------------------------------------------------------------+
void CSymbolPropertyChecker::PrintProperty(ENUM_SYMBOL_INFO_DOUBLE property_id)
{
double value;
string result_str;
string property_name = EnumToString(property_id);
ResetLastError();
bool success = m_symbol_info.InfoDouble(property_id, value);
int error = GetLastError();
if(success)
{
result_str = StringFormat("%-35s | Status: SUPPORTED | Value: %g",
property_name,
value);
}
else
{
result_str = StringFormat("%-35s | Status: FAILED | Error: %d",
property_name,
error);
}
Print(result_str);
}
//+------------------------------------------------------------------+
//| Prints the header for the output |
//+------------------------------------------------------------------+
void CSymbolPropertyChecker::PrintHeader(void)
{
Print("--- Symbol Property Checker Started ---");
PrintFormat("Checking symbol: %s", m_symbol_name);
Print("------------------------------------------------------------------");
}
//+------------------------------------------------------------------+
//| Prints the footer for the output |
//+------------------------------------------------------------------+
void CSymbolPropertyChecker::PrintFooter(void)
{
Print("------------------------------------------------------------------");
Print("--- Check Completed ---");
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
CSymbolPropertyChecker checker(_Symbol);
checker.Run();
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
+53 -53
View File
@@ -1,53 +1,53 @@
# Symbol Info Integer Checker Script
## 1. Summary (Introduction)
The Symbol Info Integer Checker is an MQL5 script designed as a **diagnostic and development tool**. When executed on a chart, it systematically queries and displays the status and value of every relevant `ENUM_SYMBOL_INFO_INTEGER` property for the chart's current symbol.
Its primary purpose is to provide developers and advanced traders with a quick and comprehensive way to check which integer-based data points are provided by their broker for a specific financial instrument. This is crucial for developing robust Expert Advisors and indicators, as many of a symbol's core trading rules and characteristics (e.g., execution modes, order types allowed) are defined by these integer properties.
## 2. Features and Displayed Data
The script iterates through a comprehensive, hard-coded list of all modern `ENUM_SYMBOL_INFO_INTEGER` properties. For each property, it prints a formatted line to the "Experts" tab of the terminal, indicating:
- **Property Name:** The official `enum` name of the property (e.g., `SYMBOL_TRADE_EXEMODE`).
- **Status:** Whether the request for the property was `SUPPORTED` or `FAILED`.
- **Value / Error:**
- If **supported**, it displays the retrieved `long` value, intelligently formatted into a human-readable string (e.g., converting `SYMBOL_TRADE_EXEMODE`'s integer value to "Instant Execution", `datetime` values to a readable date, and booleans to "true"/"false").
- If **failed**, it displays the error code returned by `GetLastError()`.
The output is neatly aligned in columns for easy readability.
## 3. MQL5 Implementation Details
The script was refactored to follow a clean, object-oriented, and modular design, making its logic reusable and easy to understand.
- **Object-Oriented Design:** The core logic is encapsulated within a `CSymbolIntegerPropertyChecker` class. This isolates the functionality from the script's entry point (`OnStart`).
- The constructor takes the symbol name as an argument.
- A single public method, `Run()`, executes the entire checking process.
- Private helper methods (`PrintHeader`, `PrintFooter`, `PrintProperty`, `FormatValue`) break down the logic into smaller, manageable pieces.
- **Self-Contained Logic:** The script is completely self-contained. It uses the standard `<Trade\SymbolInfo.mqh>` library but does not require any custom include files. The formatting logic, which was previously in a separate file, has been integrated into the class as a private `FormatValue` method for better encapsulation.
- **Intelligent Formatting:** The `FormatValue` method contains a large `switch` block that correctly interprets the meaning of different integer properties. It uses helper methods from the `CSymbolInfo` class (e.g., `TradeModeDescription()`) or standard MQL5 functions (`TimeToString()`) to convert raw integer values into descriptive text, making the output far more useful than a simple list of numbers.
- **Static Property List:** The array of `ENUM_SYMBOL_INFO_INTEGER` properties is defined as a `static const` member of the `CSymbolIntegerPropertyChecker` class. This logically associates the data with the class that uses it, which is a cleaner approach than using a global variable.
- **Simplified `OnStart`:** The script's entry point, `OnStart()`, is now extremely simple. It is only responsible for creating an instance of the `CSymbolIntegerPropertyChecker` class and calling its `Run()` method.
## 4. Usage
1. **Installation:**
- Place `SymbolInfoIntegerChecker.mq5` into your `MQL5\Scripts` folder.
2. **Execution:**
- Open the chart of the symbol you wish to inspect.
- Drag and drop the `SymbolInfoIntegerChecker` script from the Navigator window onto the chart.
3. **Review Output:**
- Open the "Terminal" window (Ctrl+T).
- Navigate to the "Experts" tab.
- The script will print the full list of integer properties and their status for the selected symbol. The script terminates automatically after printing the list.
## 5. Parameters
This script has no adjustable input parameters. It always runs on the symbol of the chart it is attached to.
# Symbol Info Integer Checker Script
## 1. Summary (Introduction)
The Symbol Info Integer Checker is an MQL5 script designed as a **diagnostic and development tool**. When executed on a chart, it systematically queries and displays the status and value of every relevant `ENUM_SYMBOL_INFO_INTEGER` property for the chart's current symbol.
Its primary purpose is to provide developers and advanced traders with a quick and comprehensive way to check which integer-based data points are provided by their broker for a specific financial instrument. This is crucial for developing robust Expert Advisors and indicators, as many of a symbol's core trading rules and characteristics (e.g., execution modes, order types allowed) are defined by these integer properties.
## 2. Features and Displayed Data
The script iterates through a comprehensive, hard-coded list of all modern `ENUM_SYMBOL_INFO_INTEGER` properties. For each property, it prints a formatted line to the "Experts" tab of the terminal, indicating:
- **Property Name:** The official `enum` name of the property (e.g., `SYMBOL_TRADE_EXEMODE`).
- **Status:** Whether the request for the property was `SUPPORTED` or `FAILED`.
- **Value / Error:**
- If **supported**, it displays the retrieved `long` value, intelligently formatted into a human-readable string (e.g., converting `SYMBOL_TRADE_EXEMODE`'s integer value to "Instant Execution", `datetime` values to a readable date, and booleans to "true"/"false").
- If **failed**, it displays the error code returned by `GetLastError()`.
The output is neatly aligned in columns for easy readability.
## 3. MQL5 Implementation Details
The script was refactored to follow a clean, object-oriented, and modular design, making its logic reusable and easy to understand.
- **Object-Oriented Design:** The core logic is encapsulated within a `CSymbolIntegerPropertyChecker` class. This isolates the functionality from the script's entry point (`OnStart`).
- The constructor takes the symbol name as an argument.
- A single public method, `Run()`, executes the entire checking process.
- Private helper methods (`PrintHeader`, `PrintFooter`, `PrintProperty`, `FormatValue`) break down the logic into smaller, manageable pieces.
- **Self-Contained Logic:** The script is completely self-contained. It uses the standard `<Trade\SymbolInfo.mqh>` library but does not require any custom include files. The formatting logic, which was previously in a separate file, has been integrated into the class as a private `FormatValue` method for better encapsulation.
- **Intelligent Formatting:** The `FormatValue` method contains a large `switch` block that correctly interprets the meaning of different integer properties. It uses helper methods from the `CSymbolInfo` class (e.g., `TradeModeDescription()`) or standard MQL5 functions (`TimeToString()`) to convert raw integer values into descriptive text, making the output far more useful than a simple list of numbers.
- **Static Property List:** The array of `ENUM_SYMBOL_INFO_INTEGER` properties is defined as a `static const` member of the `CSymbolIntegerPropertyChecker` class. This logically associates the data with the class that uses it, which is a cleaner approach than using a global variable.
- **Simplified `OnStart`:** The script's entry point, `OnStart()`, is now extremely simple. It is only responsible for creating an instance of the `CSymbolIntegerPropertyChecker` class and calling its `Run()` method.
## 4. Usage
1. **Installation:**
- Place `SymbolInfoIntegerChecker.mq5` into your `MQL5\Scripts` folder.
2. **Execution:**
- Open the chart of the symbol you wish to inspect.
- Drag and drop the `SymbolInfoIntegerChecker` script from the Navigator window onto the chart.
3. **Review Output:**
- Open the "Terminal" window (Ctrl+T).
- Navigate to the "Experts" tab.
- The script will print the full list of integer properties and their status for the selected symbol. The script terminates automatically after printing the list.
## 5. Parameters
This script has no adjustable input parameters. It always runs on the symbol of the chart it is attached to.
+178 -178
View File
@@ -1,178 +1,178 @@
//+------------------------------------------------------------------+
//| SymbolInfoIntegerChecker.mq5 |
//| Copyright 2025, xxxxxxxx |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, xxxxxxxx"
#property link ""
#property version "2.00" // Refactored into a class-based structure
#property description "Checks and displays all INTEGER properties for the current symbol."
#include <Trade\SymbolInfo.mqh>
//+------------------------------------------------------------------+
//| Class to check and display INTEGER symbol properties |
//+------------------------------------------------------------------+
class CSymbolIntegerPropertyChecker
{
private:
CSymbolInfo m_symbol_info;
string m_symbol_name;
//--- Array of all integer properties to check.
static const ENUM_SYMBOL_INFO_INTEGER S_INT_PROPERTIES[];
public:
CSymbolIntegerPropertyChecker(const string symbol);
bool Run(void);
private:
void PrintHeader(void);
void PrintFooter(void);
void PrintProperty(ENUM_SYMBOL_INFO_INTEGER property_id);
string FormatValue(ENUM_SYMBOL_INFO_INTEGER property_id, long value);
};
//--- Static member initialization
const ENUM_SYMBOL_INFO_INTEGER CSymbolIntegerPropertyChecker::S_INT_PROPERTIES[] =
{
SYMBOL_CUSTOM, SYMBOL_CHART_MODE, SYMBOL_EXIST, SYMBOL_SELECT,
SYMBOL_VISIBLE, SYMBOL_SESSION_DEALS, SYMBOL_SESSION_BUY_ORDERS,
SYMBOL_SESSION_SELL_ORDERS, SYMBOL_VOLUME, SYMBOL_VOLUMEHIGH,
SYMBOL_VOLUMELOW, SYMBOL_TIME, SYMBOL_TIME_MSC, SYMBOL_DIGITS,
SYMBOL_SPREAD_FLOAT, SYMBOL_SPREAD, SYMBOL_TICKS_BOOKDEPTH,
SYMBOL_TRADE_CALC_MODE, SYMBOL_TRADE_MODE, SYMBOL_START_TIME,
SYMBOL_EXPIRATION_TIME, SYMBOL_TRADE_STOPS_LEVEL,
SYMBOL_TRADE_FREEZE_LEVEL, SYMBOL_TRADE_EXEMODE, SYMBOL_SWAP_MODE,
SYMBOL_SWAP_ROLLOVER3DAYS, SYMBOL_EXPIRATION_MODE,
SYMBOL_FILLING_MODE, SYMBOL_ORDER_MODE, SYMBOL_ORDER_GTC_MODE,
SYMBOL_OPTION_MODE, SYMBOL_OPTION_RIGHT, SYMBOL_SECTOR, SYMBOL_INDUSTRY
// SYMBOL_SUBSCRIPTION_DELAY, SYMBOL_BACKGROUND_COLOR are obsolete
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CSymbolIntegerPropertyChecker::CSymbolIntegerPropertyChecker(const string symbol) : m_symbol_name(symbol)
{
}
//+------------------------------------------------------------------+
//| Runs the property check process |
//+------------------------------------------------------------------+
bool CSymbolIntegerPropertyChecker::Run(void)
{
if(!m_symbol_info.Name(m_symbol_name))
{
PrintFormat("Error: Symbol '%s' not found or not available in Market Watch.", m_symbol_name);
return false;
}
m_symbol_info.Refresh();
PrintHeader();
for(int i = 0; i < ArraySize(S_INT_PROPERTIES); i++)
{
PrintProperty(S_INT_PROPERTIES[i]);
}
PrintFooter();
return true;
}
//+------------------------------------------------------------------+
//| Prints a single property's status and value |
//+------------------------------------------------------------------+
void CSymbolIntegerPropertyChecker::PrintProperty(ENUM_SYMBOL_INFO_INTEGER property_id)
{
long value;
string result_str;
string property_name = EnumToString(property_id);
ResetLastError();
if(m_symbol_info.InfoInteger(property_id, value))
{
result_str = StringFormat("%-35s | Status: SUPPORTED | Value: %s",
property_name,
FormatValue(property_id, value));
}
else
{
result_str = StringFormat("%-35s | Status: FAILED | Error: %d",
property_name,
GetLastError());
}
Print(result_str);
}
//+------------------------------------------------------------------+
//| Formats an INTEGER property value into a readable string |
//+------------------------------------------------------------------+
string CSymbolIntegerPropertyChecker::FormatValue(ENUM_SYMBOL_INFO_INTEGER property_id, long value)
{
switch(property_id)
{
// Descriptions from CSymbolInfo
case SYMBOL_TRADE_CALC_MODE:
return(m_symbol_info.TradeCalcModeDescription());
case SYMBOL_TRADE_MODE:
return(m_symbol_info.TradeModeDescription());
case SYMBOL_TRADE_EXEMODE:
return(m_symbol_info.TradeExecutionDescription());
case SYMBOL_SWAP_MODE:
return(m_symbol_info.SwapModeDescription());
case SYMBOL_SWAP_ROLLOVER3DAYS:
return(m_symbol_info.SwapRollover3daysDescription());
// Datetimes
case SYMBOL_START_TIME:
case SYMBOL_EXPIRATION_TIME:
case SYMBOL_TIME:
return(TimeToString((datetime)value, TIME_DATE | TIME_SECONDS));
case SYMBOL_TIME_MSC:
{
datetime seconds_part = (datetime)(value / 1000);
long milliseconds_part = value % 1000;
return(StringFormat("%s.%03d", TimeToString(seconds_part, TIME_DATE | TIME_SECONDS), milliseconds_part));
}
// Bools
case SYMBOL_CUSTOM:
case SYMBOL_EXIST:
case SYMBOL_SELECT:
case SYMBOL_VISIBLE:
case SYMBOL_SPREAD_FLOAT:
return((bool)value ? "true" : "false");
// Default long to string conversion
default:
return((string)value);
}
}
//+------------------------------------------------------------------+
//| Prints the header for the output |
//+------------------------------------------------------------------+
void CSymbolIntegerPropertyChecker::PrintHeader(void)
{
Print("--- Symbol Integer Property Checker Started ---");
PrintFormat("Checking symbol: %s", m_symbol_name);
Print("------------------------------------------------------------------");
}
//+------------------------------------------------------------------+
//| Prints the footer for the output |
//+------------------------------------------------------------------+
void CSymbolIntegerPropertyChecker::PrintFooter(void)
{
Print("------------------------------------------------------------------");
Print("--- Check Completed ---");
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
CSymbolIntegerPropertyChecker checker(_Symbol);
checker.Run();
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| SymbolInfoIntegerChecker.mq5 |
//| Copyright 2025, xxxxxxxx |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, xxxxxxxx"
#property link ""
#property version "2.00" // Refactored into a class-based structure
#property description "Checks and displays all INTEGER properties for the current symbol."
#include <Trade\SymbolInfo.mqh>
//+------------------------------------------------------------------+
//| Class to check and display INTEGER symbol properties |
//+------------------------------------------------------------------+
class CSymbolIntegerPropertyChecker
{
private:
CSymbolInfo m_symbol_info;
string m_symbol_name;
//--- Array of all integer properties to check.
static const ENUM_SYMBOL_INFO_INTEGER S_INT_PROPERTIES[];
public:
CSymbolIntegerPropertyChecker(const string symbol);
bool Run(void);
private:
void PrintHeader(void);
void PrintFooter(void);
void PrintProperty(ENUM_SYMBOL_INFO_INTEGER property_id);
string FormatValue(ENUM_SYMBOL_INFO_INTEGER property_id, long value);
};
//--- Static member initialization
const ENUM_SYMBOL_INFO_INTEGER CSymbolIntegerPropertyChecker::S_INT_PROPERTIES[] =
{
SYMBOL_CUSTOM, SYMBOL_CHART_MODE, SYMBOL_EXIST, SYMBOL_SELECT,
SYMBOL_VISIBLE, SYMBOL_SESSION_DEALS, SYMBOL_SESSION_BUY_ORDERS,
SYMBOL_SESSION_SELL_ORDERS, SYMBOL_VOLUME, SYMBOL_VOLUMEHIGH,
SYMBOL_VOLUMELOW, SYMBOL_TIME, SYMBOL_TIME_MSC, SYMBOL_DIGITS,
SYMBOL_SPREAD_FLOAT, SYMBOL_SPREAD, SYMBOL_TICKS_BOOKDEPTH,
SYMBOL_TRADE_CALC_MODE, SYMBOL_TRADE_MODE, SYMBOL_START_TIME,
SYMBOL_EXPIRATION_TIME, SYMBOL_TRADE_STOPS_LEVEL,
SYMBOL_TRADE_FREEZE_LEVEL, SYMBOL_TRADE_EXEMODE, SYMBOL_SWAP_MODE,
SYMBOL_SWAP_ROLLOVER3DAYS, SYMBOL_EXPIRATION_MODE,
SYMBOL_FILLING_MODE, SYMBOL_ORDER_MODE, SYMBOL_ORDER_GTC_MODE,
SYMBOL_OPTION_MODE, SYMBOL_OPTION_RIGHT, SYMBOL_SECTOR, SYMBOL_INDUSTRY
// SYMBOL_SUBSCRIPTION_DELAY, SYMBOL_BACKGROUND_COLOR are obsolete
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CSymbolIntegerPropertyChecker::CSymbolIntegerPropertyChecker(const string symbol) : m_symbol_name(symbol)
{
}
//+------------------------------------------------------------------+
//| Runs the property check process |
//+------------------------------------------------------------------+
bool CSymbolIntegerPropertyChecker::Run(void)
{
if(!m_symbol_info.Name(m_symbol_name))
{
PrintFormat("Error: Symbol '%s' not found or not available in Market Watch.", m_symbol_name);
return false;
}
m_symbol_info.Refresh();
PrintHeader();
for(int i = 0; i < ArraySize(S_INT_PROPERTIES); i++)
{
PrintProperty(S_INT_PROPERTIES[i]);
}
PrintFooter();
return true;
}
//+------------------------------------------------------------------+
//| Prints a single property's status and value |
//+------------------------------------------------------------------+
void CSymbolIntegerPropertyChecker::PrintProperty(ENUM_SYMBOL_INFO_INTEGER property_id)
{
long value;
string result_str;
string property_name = EnumToString(property_id);
ResetLastError();
if(m_symbol_info.InfoInteger(property_id, value))
{
result_str = StringFormat("%-35s | Status: SUPPORTED | Value: %s",
property_name,
FormatValue(property_id, value));
}
else
{
result_str = StringFormat("%-35s | Status: FAILED | Error: %d",
property_name,
GetLastError());
}
Print(result_str);
}
//+------------------------------------------------------------------+
//| Formats an INTEGER property value into a readable string |
//+------------------------------------------------------------------+
string CSymbolIntegerPropertyChecker::FormatValue(ENUM_SYMBOL_INFO_INTEGER property_id, long value)
{
switch(property_id)
{
// Descriptions from CSymbolInfo
case SYMBOL_TRADE_CALC_MODE:
return(m_symbol_info.TradeCalcModeDescription());
case SYMBOL_TRADE_MODE:
return(m_symbol_info.TradeModeDescription());
case SYMBOL_TRADE_EXEMODE:
return(m_symbol_info.TradeExecutionDescription());
case SYMBOL_SWAP_MODE:
return(m_symbol_info.SwapModeDescription());
case SYMBOL_SWAP_ROLLOVER3DAYS:
return(m_symbol_info.SwapRollover3daysDescription());
// Datetimes
case SYMBOL_START_TIME:
case SYMBOL_EXPIRATION_TIME:
case SYMBOL_TIME:
return(TimeToString((datetime)value, TIME_DATE | TIME_SECONDS));
case SYMBOL_TIME_MSC:
{
datetime seconds_part = (datetime)(value / 1000);
long milliseconds_part = value % 1000;
return(StringFormat("%s.%03d", TimeToString(seconds_part, TIME_DATE | TIME_SECONDS), milliseconds_part));
}
// Bools
case SYMBOL_CUSTOM:
case SYMBOL_EXIST:
case SYMBOL_SELECT:
case SYMBOL_VISIBLE:
case SYMBOL_SPREAD_FLOAT:
return((bool)value ? "true" : "false");
// Default long to string conversion
default:
return((string)value);
}
}
//+------------------------------------------------------------------+
//| Prints the header for the output |
//+------------------------------------------------------------------+
void CSymbolIntegerPropertyChecker::PrintHeader(void)
{
Print("--- Symbol Integer Property Checker Started ---");
PrintFormat("Checking symbol: %s", m_symbol_name);
Print("------------------------------------------------------------------");
}
//+------------------------------------------------------------------+
//| Prints the footer for the output |
//+------------------------------------------------------------------+
void CSymbolIntegerPropertyChecker::PrintFooter(void)
{
Print("------------------------------------------------------------------");
Print("--- Check Completed ---");
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
CSymbolIntegerPropertyChecker checker(_Symbol);
checker.Run();
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
+51 -51
View File
@@ -1,51 +1,51 @@
# Symbol Info String Checker Script
## 1. Summary (Introduction)
The Symbol Info String Checker is an MQL5 script designed as a **diagnostic and development tool**. When executed on a chart, it systematically queries and displays the status and value of every `ENUM_SYMBOL_INFO_STRING` property for the chart's current symbol.
Its primary purpose is to provide developers and advanced traders with a quick and comprehensive way to check the text-based metadata provided by their broker for a specific financial instrument. This includes crucial information like the symbol's description, the underlying base and profit currencies, the exchange it trades on, and its path in the Market Watch.
## 2. Features and Displayed Data
The script iterates through a comprehensive, hard-coded list of all `ENUM_SYMBOL_INFO_STRING` properties. For each property, it prints a formatted line to the "Experts" tab of the terminal, indicating:
- **Property Name:** The official `enum` name of the property (e.g., `SYMBOL_CURRENCY_BASE`).
- **Status:** Whether the request for the property was `SUPPORTED` or `FAILED`.
- **Value / Error:**
- If **supported**, it displays the retrieved `string` value. For clarity, empty strings are explicitly marked as `<EMPTY>`, and non-empty strings are enclosed in single quotes (e.g., `'EUR'`).
- If **failed**, it displays the error code returned by `GetLastError()`.
The output is neatly aligned in columns for easy readability.
## 3. MQL5 Implementation Details
The script was refactored to follow a clean, object-oriented, and modular design, ensuring consistency with our other diagnostic tools.
- **Object-Oriented Design:** The core logic is encapsulated within a `CSymbolStringPropertyChecker` class. This isolates the functionality from the script's entry point (`OnStart`).
- The constructor takes the symbol name as an argument.
- A single public method, `Run()`, executes the entire checking process.
- Private helper methods (`PrintHeader`, `PrintFooter`, `PrintProperty`, `FormatValue`) break down the logic into smaller, manageable pieces.
- **Self-Contained Logic:** The script is completely self-contained. It uses the standard `<Trade\SymbolInfo.mqh>` library but does not require any custom include files. The formatting logic is integrated into the class as a private `FormatValue` method.
- **Static Property List:** The array of `ENUM_SYMBOL_INFO_STRING` properties is defined as a `static const` member of the `CSymbolStringPropertyChecker` class. This logically associates the data with the class that uses it, which is a cleaner approach than using a global variable.
- **Simplified `OnStart`:** The script's entry point, `OnStart()`, is now extremely simple. It is only responsible for creating an instance of the `CSymbolStringPropertyChecker` class and calling its `Run()` method.
## 4. Usage
1. **Installation:**
- Place `SymbolInfoStringChecker.mq5` into your `MQL5\Scripts` folder.
2. **Execution:**
- Open the chart of the symbol you wish to inspect.
- Drag and drop the `SymbolInfoStringChecker` script from the Navigator window onto the chart.
3. **Review Output:**
- Open the "Terminal" window (Ctrl+T).
- Navigate to the "Experts" tab.
- The script will print the full list of string properties and their status for the selected symbol. The script terminates automatically after printing the list.
## 5. Parameters
This script has no adjustable input parameters. It always runs on the symbol of the chart it is attached to.
# Symbol Info String Checker Script
## 1. Summary (Introduction)
The Symbol Info String Checker is an MQL5 script designed as a **diagnostic and development tool**. When executed on a chart, it systematically queries and displays the status and value of every `ENUM_SYMBOL_INFO_STRING` property for the chart's current symbol.
Its primary purpose is to provide developers and advanced traders with a quick and comprehensive way to check the text-based metadata provided by their broker for a specific financial instrument. This includes crucial information like the symbol's description, the underlying base and profit currencies, the exchange it trades on, and its path in the Market Watch.
## 2. Features and Displayed Data
The script iterates through a comprehensive, hard-coded list of all `ENUM_SYMBOL_INFO_STRING` properties. For each property, it prints a formatted line to the "Experts" tab of the terminal, indicating:
- **Property Name:** The official `enum` name of the property (e.g., `SYMBOL_CURRENCY_BASE`).
- **Status:** Whether the request for the property was `SUPPORTED` or `FAILED`.
- **Value / Error:**
- If **supported**, it displays the retrieved `string` value. For clarity, empty strings are explicitly marked as `<EMPTY>`, and non-empty strings are enclosed in single quotes (e.g., `'EUR'`).
- If **failed**, it displays the error code returned by `GetLastError()`.
The output is neatly aligned in columns for easy readability.
## 3. MQL5 Implementation Details
The script was refactored to follow a clean, object-oriented, and modular design, ensuring consistency with our other diagnostic tools.
- **Object-Oriented Design:** The core logic is encapsulated within a `CSymbolStringPropertyChecker` class. This isolates the functionality from the script's entry point (`OnStart`).
- The constructor takes the symbol name as an argument.
- A single public method, `Run()`, executes the entire checking process.
- Private helper methods (`PrintHeader`, `PrintFooter`, `PrintProperty`, `FormatValue`) break down the logic into smaller, manageable pieces.
- **Self-Contained Logic:** The script is completely self-contained. It uses the standard `<Trade\SymbolInfo.mqh>` library but does not require any custom include files. The formatting logic is integrated into the class as a private `FormatValue` method.
- **Static Property List:** The array of `ENUM_SYMBOL_INFO_STRING` properties is defined as a `static const` member of the `CSymbolStringPropertyChecker` class. This logically associates the data with the class that uses it, which is a cleaner approach than using a global variable.
- **Simplified `OnStart`:** The script's entry point, `OnStart()`, is now extremely simple. It is only responsible for creating an instance of the `CSymbolStringPropertyChecker` class and calling its `Run()` method.
## 4. Usage
1. **Installation:**
- Place `SymbolInfoStringChecker.mq5` into your `MQL5\Scripts` folder.
2. **Execution:**
- Open the chart of the symbol you wish to inspect.
- Drag and drop the `SymbolInfoStringChecker` script from the Navigator window onto the chart.
3. **Review Output:**
- Open the "Terminal" window (Ctrl+T).
- Navigate to the "Experts" tab.
- The script will print the full list of string properties and their status for the selected symbol. The script terminates automatically after printing the list.
## 5. Parameters
This script has no adjustable input parameters. It always runs on the symbol of the chart it is attached to.
+143 -143
View File
@@ -1,143 +1,143 @@
//+------------------------------------------------------------------+
//| SymbolInfoStringChecker.mq5 |
//| Copyright 2025, xxxxxxxx |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, xxxxxxxx"
#property link ""
#property version "2.00" // Refactored into a class-based structure
#property description "Checks and displays all STRING properties for the current symbol."
#include <Trade\SymbolInfo.mqh>
//+------------------------------------------------------------------+
//| Class to check and display STRING symbol properties |
//+------------------------------------------------------------------+
class CSymbolStringPropertyChecker
{
private:
CSymbolInfo m_symbol_info;
string m_symbol_name;
//--- Array of all string properties to check.
static const ENUM_SYMBOL_INFO_STRING S_STRING_PROPERTIES[];
public:
CSymbolStringPropertyChecker(const string symbol);
bool Run(void);
private:
void PrintHeader(void);
void PrintFooter(void);
void PrintProperty(ENUM_SYMBOL_INFO_STRING property_id);
string FormatValue(string value);
};
//--- Static member initialization
const ENUM_SYMBOL_INFO_STRING CSymbolStringPropertyChecker::S_STRING_PROPERTIES[] =
{
SYMBOL_BASIS, SYMBOL_CATEGORY, SYMBOL_COUNTRY, SYMBOL_SECTOR_NAME,
SYMBOL_INDUSTRY_NAME, SYMBOL_CURRENCY_BASE, SYMBOL_CURRENCY_PROFIT,
SYMBOL_CURRENCY_MARGIN, SYMBOL_BANK, SYMBOL_DESCRIPTION,
SYMBOL_EXCHANGE, SYMBOL_FORMULA, SYMBOL_ISIN, SYMBOL_PAGE, SYMBOL_PATH
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CSymbolStringPropertyChecker::CSymbolStringPropertyChecker(const string symbol) : m_symbol_name(symbol)
{
}
//+------------------------------------------------------------------+
//| Runs the property check process |
//+------------------------------------------------------------------+
bool CSymbolStringPropertyChecker::Run(void)
{
if(!m_symbol_info.Name(m_symbol_name))
{
PrintFormat("Error: Symbol '%s' not found or not available in Market Watch.", m_symbol_name);
return false;
}
m_symbol_info.Refresh();
PrintHeader();
for(int i = 0; i < ArraySize(S_STRING_PROPERTIES); i++)
{
PrintProperty(S_STRING_PROPERTIES[i]);
}
PrintFooter();
return true;
}
//+------------------------------------------------------------------+
//| Prints a single property's status and value |
//+------------------------------------------------------------------+
void CSymbolStringPropertyChecker::PrintProperty(ENUM_SYMBOL_INFO_STRING property_id)
{
string value;
string result_str;
string property_name = EnumToString(property_id);
ResetLastError();
if(m_symbol_info.InfoString(property_id, value))
{
result_str = StringFormat("%-35s | Status: SUPPORTED | Value: %s",
property_name,
FormatValue(value));
}
else
{
result_str = StringFormat("%-35s | Status: FAILED | Error: %d",
property_name,
GetLastError());
}
Print(result_str);
}
//+------------------------------------------------------------------+
//| Formats a STRING property value into a readable string |
//+------------------------------------------------------------------+
string CSymbolStringPropertyChecker::FormatValue(string value)
{
if(value == "")
{
return("<EMPTY>");
}
else
{
return("'" + value + "'");
}
}
//+------------------------------------------------------------------+
//| Prints the header for the output |
//+------------------------------------------------------------------+
void CSymbolStringPropertyChecker::PrintHeader(void)
{
Print("--- Symbol String Property Checker Started ---");
PrintFormat("Checking symbol: %s", m_symbol_name);
Print("------------------------------------------------------------------");
}
//+------------------------------------------------------------------+
//| Prints the footer for the output |
//+------------------------------------------------------------------+
void CSymbolStringPropertyChecker::PrintFooter(void)
{
Print("------------------------------------------------------------------");
Print("--- Check Completed ---");
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
CSymbolStringPropertyChecker checker(_Symbol);
checker.Run();
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| SymbolInfoStringChecker.mq5 |
//| Copyright 2025, xxxxxxxx |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, xxxxxxxx"
#property link ""
#property version "2.00" // Refactored into a class-based structure
#property description "Checks and displays all STRING properties for the current symbol."
#include <Trade\SymbolInfo.mqh>
//+------------------------------------------------------------------+
//| Class to check and display STRING symbol properties |
//+------------------------------------------------------------------+
class CSymbolStringPropertyChecker
{
private:
CSymbolInfo m_symbol_info;
string m_symbol_name;
//--- Array of all string properties to check.
static const ENUM_SYMBOL_INFO_STRING S_STRING_PROPERTIES[];
public:
CSymbolStringPropertyChecker(const string symbol);
bool Run(void);
private:
void PrintHeader(void);
void PrintFooter(void);
void PrintProperty(ENUM_SYMBOL_INFO_STRING property_id);
string FormatValue(string value);
};
//--- Static member initialization
const ENUM_SYMBOL_INFO_STRING CSymbolStringPropertyChecker::S_STRING_PROPERTIES[] =
{
SYMBOL_BASIS, SYMBOL_CATEGORY, SYMBOL_COUNTRY, SYMBOL_SECTOR_NAME,
SYMBOL_INDUSTRY_NAME, SYMBOL_CURRENCY_BASE, SYMBOL_CURRENCY_PROFIT,
SYMBOL_CURRENCY_MARGIN, SYMBOL_BANK, SYMBOL_DESCRIPTION,
SYMBOL_EXCHANGE, SYMBOL_FORMULA, SYMBOL_ISIN, SYMBOL_PAGE, SYMBOL_PATH
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CSymbolStringPropertyChecker::CSymbolStringPropertyChecker(const string symbol) : m_symbol_name(symbol)
{
}
//+------------------------------------------------------------------+
//| Runs the property check process |
//+------------------------------------------------------------------+
bool CSymbolStringPropertyChecker::Run(void)
{
if(!m_symbol_info.Name(m_symbol_name))
{
PrintFormat("Error: Symbol '%s' not found or not available in Market Watch.", m_symbol_name);
return false;
}
m_symbol_info.Refresh();
PrintHeader();
for(int i = 0; i < ArraySize(S_STRING_PROPERTIES); i++)
{
PrintProperty(S_STRING_PROPERTIES[i]);
}
PrintFooter();
return true;
}
//+------------------------------------------------------------------+
//| Prints a single property's status and value |
//+------------------------------------------------------------------+
void CSymbolStringPropertyChecker::PrintProperty(ENUM_SYMBOL_INFO_STRING property_id)
{
string value;
string result_str;
string property_name = EnumToString(property_id);
ResetLastError();
if(m_symbol_info.InfoString(property_id, value))
{
result_str = StringFormat("%-35s | Status: SUPPORTED | Value: %s",
property_name,
FormatValue(value));
}
else
{
result_str = StringFormat("%-35s | Status: FAILED | Error: %d",
property_name,
GetLastError());
}
Print(result_str);
}
//+------------------------------------------------------------------+
//| Formats a STRING property value into a readable string |
//+------------------------------------------------------------------+
string CSymbolStringPropertyChecker::FormatValue(string value)
{
if(value == "")
{
return("<EMPTY>");
}
else
{
return("'" + value + "'");
}
}
//+------------------------------------------------------------------+
//| Prints the header for the output |
//+------------------------------------------------------------------+
void CSymbolStringPropertyChecker::PrintHeader(void)
{
Print("--- Symbol String Property Checker Started ---");
PrintFormat("Checking symbol: %s", m_symbol_name);
Print("------------------------------------------------------------------");
}
//+------------------------------------------------------------------+
//| Prints the footer for the output |
//+------------------------------------------------------------------+
void CSymbolStringPropertyChecker::PrintFooter(void)
{
Print("------------------------------------------------------------------");
Print("--- Check Completed ---");
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
CSymbolStringPropertyChecker checker(_Symbol);
checker.Run();
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
+82 -82
View File
@@ -1,82 +1,82 @@
# Symbol Scanner Panel Script
## 1. Summary (Introduction)
The Symbol Scanner Panel is an MQL5 script designed as a powerful **data mining and analysis tool**. When executed, it scans through a list of symbols (either user-defined or all symbols available on the server) and filters them based on a wide range of criteria.
Its primary purpose is to help traders and developers quickly find instruments that meet specific trading conditions, such as having low spreads, specific contract sizes, or belonging to a particular market sector. The results are printed in a clean, tabular format in the "Experts" tab of the terminal, allowing for easy analysis and export.
## 2. Features and Scanned Data
The script is highly configurable through its input parameters and can filter symbols based on multiple criteria simultaneously. For each symbol that passes the filters, it displays the following key trading parameters:
- **Symbol:** The symbol's ticker name.
- **Spread:** The current spread in points.
- **Point:** The size of a single point.
- **Tick Value & Size:** The value and size of a single tick movement.
- **Volume Min/Step:** The minimum allowed trade volume and the step for increasing it.
- **Swaps:** The long and short swap rates.
- **Path:** The symbol's category path in the Market Watch (e.g., `CFD\Indices`).
## 3. MQL5 Implementation Details
The script was refactored into a clean, fully object-oriented structure to ensure its logic is modular, reusable, and easy to maintain.
- **Object-Oriented Design:** The entire scanning and filtering logic is encapsulated within a `CSymbolScanner` class. The script's entry point (`OnStart`) is minimal and is only responsible for creating an instance of this class with the user's input parameters and executing its `Run()` method.
- **Self-Contained Logic:** The script is completely self-contained and uses the standard `<Trade\SymbolInfo.mqh>` library for data retrieval. All helper functions for getting the symbol list, filtering, and printing are private methods of the `CSymbolScanner` class, avoiding the use of global functions.
- **Clear, Staged Execution:** The `Run()` method orchestrates the process in clear, sequential steps:
1. Print the active filter criteria.
2. Get the list of symbols to be scanned.
3. Print the results table header.
4. Loop through each symbol, gather its data, and check it against the filters.
5. Print the data for any symbol that passes.
6. Print a final summary.
- **Data Encapsulation:** A private `struct` named `SymbolData` is used within the class to neatly store all the relevant information for a single symbol. This makes the code cleaner by allowing a single data object to be passed between methods.
## 4. Usage and Practical Examples
To use the script, set your desired filter criteria in the input window and then drag it onto any chart. The results will be printed in the **Terminal -> Experts** tab.
### Example 1: Finding all Forex pairs with low spreads
You want to find all Forex pairs available on the server that are currently in your Market Watch and have a spread of 10 points or less.
- **`InpSymbolsToScan`**: `""` (leave empty to scan all server symbols)
- **`InpFilterPathContains`**: `"Forex"` (or your broker's specific path for forex, e.g., "Majors")
- **`InpFilterMarketWatch`**: `true`
- **`InpFilterMaxSpread`**: `10` _(Note: This parameter would need to be added to the script, but demonstrates the concept)_
### Example 2: Finding specific US stocks with a minimum trade size of 1 share
You want to check the swap rates and tick values for a specific list of stocks, but only if their minimum trade size is exactly 1 share (volume step of 1).
- **`InpSymbolsToScan`**: `"AAPL,GOOG,MSFT,AMZN"`
- **`InpSymbolSeparator`**: `","`
- **`InpFilterMinVolMin`**: `1.0`
- **`InpFilterMaxVolMin`**: `1.0`
- **`InpFilterMinVolStep`**: `1.0`
- **`InpFilterMaxVolStep`**: `1.0`
- **`InpFilterMarketWatch`**: `false` (to ensure it finds them even if not in Market Watch)
### Example 3: Finding all ETFs
You want a list of all available Exchange Traded Funds (ETFs).
- **`InpSymbolsToScan`**: `""`
- **`InpFilterOnlyETFs`**: `true`
## 5. Input Parameters
- **`InpSymbolsToScan`**: A comma-separated list of symbols to scan. If left empty, the script will scan all symbols available on the broker's server.
- **`InpSymbolSeparator`**: The character used to separate symbols in the list above.
- **`InpFilterPathContains`**: Filters for symbols whose path (in Market Watch) contains this text. E.g., "Forex", "Indices", "Crypto".
- **`InpFilterMarketWatch`**: If `true`, only scans symbols currently visible in your Market Watch window.
- **`InpFilterMin/MaxVolMin`**: Filters symbols based on their minimum allowed trade volume.
- **`InpFilterMin/MaxVolStep`**: Filters symbols based on their volume step (e.g., 0.01, 1).
- **`InpFilterOnlyETFs`**: If `true`, only shows symbols whose industry is "Exchange Traded Fund".
- **`InpFilterExtendedHours`**: If `true`, only shows symbols whose description contains the specified keyword.
- **`InpKeywordExtHours`**: The keyword to look for when `InpFilterExtendedHours` is active.
# Symbol Scanner Panel Script
## 1. Summary (Introduction)
The Symbol Scanner Panel is an MQL5 script designed as a powerful **data mining and analysis tool**. When executed, it scans through a list of symbols (either user-defined or all symbols available on the server) and filters them based on a wide range of criteria.
Its primary purpose is to help traders and developers quickly find instruments that meet specific trading conditions, such as having low spreads, specific contract sizes, or belonging to a particular market sector. The results are printed in a clean, tabular format in the "Experts" tab of the terminal, allowing for easy analysis and export.
## 2. Features and Scanned Data
The script is highly configurable through its input parameters and can filter symbols based on multiple criteria simultaneously. For each symbol that passes the filters, it displays the following key trading parameters:
- **Symbol:** The symbol's ticker name.
- **Spread:** The current spread in points.
- **Point:** The size of a single point.
- **Tick Value & Size:** The value and size of a single tick movement.
- **Volume Min/Step:** The minimum allowed trade volume and the step for increasing it.
- **Swaps:** The long and short swap rates.
- **Path:** The symbol's category path in the Market Watch (e.g., `CFD\Indices`).
## 3. MQL5 Implementation Details
The script was refactored into a clean, fully object-oriented structure to ensure its logic is modular, reusable, and easy to maintain.
- **Object-Oriented Design:** The entire scanning and filtering logic is encapsulated within a `CSymbolScanner` class. The script's entry point (`OnStart`) is minimal and is only responsible for creating an instance of this class with the user's input parameters and executing its `Run()` method.
- **Self-Contained Logic:** The script is completely self-contained and uses the standard `<Trade\SymbolInfo.mqh>` library for data retrieval. All helper functions for getting the symbol list, filtering, and printing are private methods of the `CSymbolScanner` class, avoiding the use of global functions.
- **Clear, Staged Execution:** The `Run()` method orchestrates the process in clear, sequential steps:
1. Print the active filter criteria.
2. Get the list of symbols to be scanned.
3. Print the results table header.
4. Loop through each symbol, gather its data, and check it against the filters.
5. Print the data for any symbol that passes.
6. Print a final summary.
- **Data Encapsulation:** A private `struct` named `SymbolData` is used within the class to neatly store all the relevant information for a single symbol. This makes the code cleaner by allowing a single data object to be passed between methods.
## 4. Usage and Practical Examples
To use the script, set your desired filter criteria in the input window and then drag it onto any chart. The results will be printed in the **Terminal -> Experts** tab.
### Example 1: Finding all Forex pairs with low spreads
You want to find all Forex pairs available on the server that are currently in your Market Watch and have a spread of 10 points or less.
- **`InpSymbolsToScan`**: `""` (leave empty to scan all server symbols)
- **`InpFilterPathContains`**: `"Forex"` (or your broker's specific path for forex, e.g., "Majors")
- **`InpFilterMarketWatch`**: `true`
- **`InpFilterMaxSpread`**: `10` _(Note: This parameter would need to be added to the script, but demonstrates the concept)_
### Example 2: Finding specific US stocks with a minimum trade size of 1 share
You want to check the swap rates and tick values for a specific list of stocks, but only if their minimum trade size is exactly 1 share (volume step of 1).
- **`InpSymbolsToScan`**: `"AAPL,GOOG,MSFT,AMZN"`
- **`InpSymbolSeparator`**: `","`
- **`InpFilterMinVolMin`**: `1.0`
- **`InpFilterMaxVolMin`**: `1.0`
- **`InpFilterMinVolStep`**: `1.0`
- **`InpFilterMaxVolStep`**: `1.0`
- **`InpFilterMarketWatch`**: `false` (to ensure it finds them even if not in Market Watch)
### Example 3: Finding all ETFs
You want a list of all available Exchange Traded Funds (ETFs).
- **`InpSymbolsToScan`**: `""`
- **`InpFilterOnlyETFs`**: `true`
## 5. Input Parameters
- **`InpSymbolsToScan`**: A comma-separated list of symbols to scan. If left empty, the script will scan all symbols available on the broker's server.
- **`InpSymbolSeparator`**: The character used to separate symbols in the list above.
- **`InpFilterPathContains`**: Filters for symbols whose path (in Market Watch) contains this text. E.g., "Forex", "Indices", "Crypto".
- **`InpFilterMarketWatch`**: If `true`, only scans symbols currently visible in your Market Watch window.
- **`InpFilterMin/MaxVolMin`**: Filters symbols based on their minimum allowed trade volume.
- **`InpFilterMin/MaxVolStep`**: Filters symbols based on their volume step (e.g., 0.01, 1).
- **`InpFilterOnlyETFs`**: If `true`, only shows symbols whose industry is "Exchange Traded Fund".
- **`InpFilterExtendedHours`**: If `true`, only shows symbols whose description contains the specified keyword.
- **`InpKeywordExtHours`**: The keyword to look for when `InpFilterExtendedHours` is active.
+291 -291
View File
@@ -1,291 +1,291 @@
//+------------------------------------------------------------------+
//| SymbolScannerPanel.mq5 |
//| Copyright 2025, xxxxxxxx |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, xxxxxxxx"
#property link ""
#property version "2.00" // Refactored into a class-based structure
#property script_show_inputs
#property description "Scans and filters symbols based on various criteria."
#include <Trade\SymbolInfo.mqh>
//--- Input Parameters for Filtering ---
input string InpSymbolsToScan = "";
input string InpSymbolSeparator = ",";
input string InpFilterPathContains = "";
input bool InpFilterMarketWatch = true;
input double InpFilterMinVolMin = 0.0;
input double InpFilterMaxVolMin = 1000000.0;
input double InpFilterMinVolStep = 0.0;
input double InpFilterMaxVolStep = 1000000.0;
input bool InpFilterOnlyETFs = false;
input bool InpFilterExtendedHours= false;
input string InpKeywordExtHours = "(Extended Hours)";
//+------------------------------------------------------------------+
//| CSymbolScanner Class |
//| Encapsulates all logic for scanning and filtering symbols. |
//+------------------------------------------------------------------+
class CSymbolScanner
{
private:
//--- A structure to hold all necessary data for a symbol
struct SymbolData
{
string name;
string path;
string description;
string industry_name;
int spread;
double point;
double tick_value;
double tick_value_profit;
double tick_value_loss;
double tick_size;
double volume_min;
double volume_step;
double swap_long;
double swap_short;
};
//--- Filter criteria
string m_symbols_to_scan;
string m_symbol_separator;
string m_filter_path_contains;
bool m_filter_market_watch;
double m_filter_min_vol_min;
double m_filter_max_vol_min;
double m_filter_min_vol_step;
double m_filter_max_vol_step;
bool m_filter_only_etfs;
bool m_filter_extended_hours;
string m_keyword_ext_hours;
//--- Internal objects
CSymbolInfo m_symbol_info;
public:
//--- Constructor
CSymbolScanner(string symbols, string separator, string path, bool market_watch,
double min_vol_min, double max_vol_min, double min_vol_step, double max_vol_step,
bool only_etfs, bool ext_hours, string keyword);
//--- Main execution method
void Run(void);
private:
//--- Helper methods
bool GetSymbolsToScan(string &symbols_array[]);
bool SymbolPassesFilters(const SymbolData &data);
void GatherSymbolData(const string symbol_name, SymbolData &data);
void PrintSymbolData(const SymbolData &data);
void PrintHeader(void);
void PrintFilterCriteria(void);
};
//+------------------------------------------------------------------+
//| Constructor: Initializes the scanner with filter criteria |
//+------------------------------------------------------------------+
CSymbolScanner::CSymbolScanner(string symbols, string separator, string path, bool market_watch,
double min_vol_min, double max_vol_min, double min_vol_step, double max_vol_step,
bool only_etfs, bool ext_hours, string keyword)
{
m_symbols_to_scan = symbols;
m_symbol_separator = separator;
m_filter_path_contains = path;
m_filter_market_watch = market_watch;
m_filter_min_vol_min = min_vol_min;
m_filter_max_vol_min = max_vol_min;
m_filter_min_vol_step = min_vol_step;
m_filter_max_vol_step = max_vol_step;
m_filter_only_etfs = only_etfs;
m_filter_extended_hours = ext_hours;
m_keyword_ext_hours = keyword;
}
//+------------------------------------------------------------------+
//| Main execution method |
//+------------------------------------------------------------------+
void CSymbolScanner::Run(void)
{
Print("--- Symbol Scanner Panel Started ---");
PrintFilterCriteria();
Print("---------------------------------");
string symbols_to_scan[];
if(!GetSymbolsToScan(symbols_to_scan))
{
Print("No symbols to scan. Exiting.");
return;
}
int found_count = 0;
PrintHeader();
SymbolData current_symbol_data;
for(int i = 0; i < ArraySize(symbols_to_scan); i++)
{
string symbol_name = symbols_to_scan[i];
StringTrimLeft(symbol_name);
StringTrimRight(symbol_name);
if(StringLen(symbol_name) == 0)
continue;
GatherSymbolData(symbol_name, current_symbol_data);
if(SymbolPassesFilters(current_symbol_data))
{
found_count++;
PrintSymbolData(current_symbol_data);
}
}
Print("--------------------------------------------------------------------------------------------------------------------------------------------------------");
PrintFormat("Scanner Completed. Found %d matching symbols.", found_count);
Print("---------------------------------");
}
//+------------------------------------------------------------------+
//| Gathers all required data for a single symbol |
//+------------------------------------------------------------------+
void CSymbolScanner::GatherSymbolData(const string symbol_name, SymbolData &data)
{
if(!m_symbol_info.Name(symbol_name))
return;
if(!m_symbol_info.RefreshRates())
return;
data.name = m_symbol_info.Name();
data.path = m_symbol_info.Path();
data.description = m_symbol_info.Description();
m_symbol_info.InfoString(SYMBOL_INDUSTRY_NAME, data.industry_name);
data.spread = m_symbol_info.Spread();
data.point = m_symbol_info.Point();
data.tick_value = m_symbol_info.TickValue();
data.tick_value_profit = m_symbol_info.TickValueProfit();
data.tick_value_loss = m_symbol_info.TickValueLoss();
data.tick_size = m_symbol_info.TickSize();
data.volume_min = m_symbol_info.LotsMin();
data.volume_step = m_symbol_info.LotsStep();
data.swap_long = m_symbol_info.SwapLong();
data.swap_short = m_symbol_info.SwapShort();
}
//+------------------------------------------------------------------+
//| Checks if a symbol's data meets all the filter criteria |
//+------------------------------------------------------------------+
bool CSymbolScanner::SymbolPassesFilters(const SymbolData &data)
{
if(m_filter_market_watch && !SymbolInfoInteger(data.name, SYMBOL_SELECT))
return false;
if(StringLen(m_filter_path_contains) > 0 && StringFind(data.path, m_filter_path_contains) == -1)
return false;
if(data.volume_min < m_filter_min_vol_min || data.volume_min > m_filter_max_vol_min)
return false;
if(data.volume_step < m_filter_min_vol_step || data.volume_step > m_filter_max_vol_step)
return false;
if(m_filter_only_etfs && data.industry_name != "Exchange Traded Fund")
return false;
if(m_filter_extended_hours && StringFind(data.description, m_keyword_ext_hours) == -1)
return false;
return true;
}
//+------------------------------------------------------------------+
//| Gets the list of symbols to scan from inputs or the whole market |
//+------------------------------------------------------------------+
bool CSymbolScanner::GetSymbolsToScan(string &symbols_array[])
{
string symbols_input_copy = m_symbols_to_scan;
StringTrimLeft(symbols_input_copy);
StringTrimRight(symbols_input_copy);
if(StringLen(symbols_input_copy) > 0)
{
StringSplit(symbols_input_copy, StringGetCharacter(m_symbol_separator, 0), symbols_array);
PrintFormat("%d symbols provided by user.", ArraySize(symbols_array));
}
else
{
int total_server_symbols = SymbolsTotal(false);
if(total_server_symbols == 0)
return false;
ArrayResize(symbols_array, total_server_symbols);
for(int j = 0; j < total_server_symbols; j++)
{
symbols_array[j] = SymbolName(j, false);
}
Print("No specific symbols provided. Scanning all available server symbols.");
}
return(ArraySize(symbols_array) > 0);
}
//+------------------------------------------------------------------+
//| Prints a formatted row of data for a single symbol |
//+------------------------------------------------------------------+
void CSymbolScanner::PrintSymbolData(const SymbolData &data)
{
PrintFormat("%-15s | %-8s | %-8s | %-10s | %-10s | %-10s | %-10s | %-10s | %-10s | %-10s | %-10s | %-20s",
data.name,
(string)data.spread,
DoubleToString(data.point, -1),
DoubleToString(data.tick_value, 2),
DoubleToString(data.tick_value_profit, 2),
DoubleToString(data.tick_value_loss, 2),
DoubleToString(data.tick_size, -1),
DoubleToString(data.volume_min, -1),
DoubleToString(data.volume_step, -1),
DoubleToString(data.swap_long, 2),
DoubleToString(data.swap_short, 2),
data.path);
}
//+------------------------------------------------------------------+
//| Prints the header for the output table |
//+------------------------------------------------------------------+
void CSymbolScanner::PrintHeader()
{
PrintFormat("%-15s | %-8s | %-8s | %-10s | %-10s | %-10s | %-10s | %-10s | %-10s | %-10s | %-10s | %-20s",
"Symbol", "Spread", "Point", "TickValue", "TV_Profit", "TV_Loss", "TickSize", "Vol_Min", "Vol_Step", "Swap_Long", "Swap_Short", "Path");
Print("--------------------------------------------------------------------------------------------------------------------------------------------------------");
}
//+------------------------------------------------------------------+
//| Prints the filter criteria that the scanner is using |
//+------------------------------------------------------------------+
void CSymbolScanner::PrintFilterCriteria()
{
PrintFormat("Filter Criteria:");
PrintFormat(" Symbols to Scan: '%s'", m_symbols_to_scan);
PrintFormat(" Path Contains: '%s'", m_filter_path_contains);
PrintFormat(" Only Market Watch Selected: %s", (string)m_filter_market_watch);
PrintFormat(" Min Volume (Min): %g - %g", m_filter_min_vol_min, m_filter_max_vol_min);
PrintFormat(" Volume Step: %g - %g", m_filter_min_vol_step, m_filter_max_vol_step);
PrintFormat(" Only ETFs: %s", (string)m_filter_only_etfs);
PrintFormat(" Only Extended Hours: %s (Keyword: '%s')", (string)m_filter_extended_hours, m_keyword_ext_hours);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- Create an instance of the scanner with the input parameters
CSymbolScanner scanner(InpSymbolsToScan, InpSymbolSeparator, InpFilterPathContains, InpFilterMarketWatch,
InpFilterMinVolMin, InpFilterMaxVolMin, InpFilterMinVolStep, InpFilterMaxVolStep,
InpFilterOnlyETFs, InpFilterExtendedHours, InpKeywordExtHours);
//--- Run the scanner
scanner.Run();
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| SymbolScannerPanel.mq5 |
//| Copyright 2025, xxxxxxxx |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, xxxxxxxx"
#property link ""
#property version "2.00" // Refactored into a class-based structure
#property script_show_inputs
#property description "Scans and filters symbols based on various criteria."
#include <Trade\SymbolInfo.mqh>
//--- Input Parameters for Filtering ---
input string InpSymbolsToScan = "";
input string InpSymbolSeparator = ",";
input string InpFilterPathContains = "";
input bool InpFilterMarketWatch = true;
input double InpFilterMinVolMin = 0.0;
input double InpFilterMaxVolMin = 1000000.0;
input double InpFilterMinVolStep = 0.0;
input double InpFilterMaxVolStep = 1000000.0;
input bool InpFilterOnlyETFs = false;
input bool InpFilterExtendedHours= false;
input string InpKeywordExtHours = "(Extended Hours)";
//+------------------------------------------------------------------+
//| CSymbolScanner Class |
//| Encapsulates all logic for scanning and filtering symbols. |
//+------------------------------------------------------------------+
class CSymbolScanner
{
private:
//--- A structure to hold all necessary data for a symbol
struct SymbolData
{
string name;
string path;
string description;
string industry_name;
int spread;
double point;
double tick_value;
double tick_value_profit;
double tick_value_loss;
double tick_size;
double volume_min;
double volume_step;
double swap_long;
double swap_short;
};
//--- Filter criteria
string m_symbols_to_scan;
string m_symbol_separator;
string m_filter_path_contains;
bool m_filter_market_watch;
double m_filter_min_vol_min;
double m_filter_max_vol_min;
double m_filter_min_vol_step;
double m_filter_max_vol_step;
bool m_filter_only_etfs;
bool m_filter_extended_hours;
string m_keyword_ext_hours;
//--- Internal objects
CSymbolInfo m_symbol_info;
public:
//--- Constructor
CSymbolScanner(string symbols, string separator, string path, bool market_watch,
double min_vol_min, double max_vol_min, double min_vol_step, double max_vol_step,
bool only_etfs, bool ext_hours, string keyword);
//--- Main execution method
void Run(void);
private:
//--- Helper methods
bool GetSymbolsToScan(string &symbols_array[]);
bool SymbolPassesFilters(const SymbolData &data);
void GatherSymbolData(const string symbol_name, SymbolData &data);
void PrintSymbolData(const SymbolData &data);
void PrintHeader(void);
void PrintFilterCriteria(void);
};
//+------------------------------------------------------------------+
//| Constructor: Initializes the scanner with filter criteria |
//+------------------------------------------------------------------+
CSymbolScanner::CSymbolScanner(string symbols, string separator, string path, bool market_watch,
double min_vol_min, double max_vol_min, double min_vol_step, double max_vol_step,
bool only_etfs, bool ext_hours, string keyword)
{
m_symbols_to_scan = symbols;
m_symbol_separator = separator;
m_filter_path_contains = path;
m_filter_market_watch = market_watch;
m_filter_min_vol_min = min_vol_min;
m_filter_max_vol_min = max_vol_min;
m_filter_min_vol_step = min_vol_step;
m_filter_max_vol_step = max_vol_step;
m_filter_only_etfs = only_etfs;
m_filter_extended_hours = ext_hours;
m_keyword_ext_hours = keyword;
}
//+------------------------------------------------------------------+
//| Main execution method |
//+------------------------------------------------------------------+
void CSymbolScanner::Run(void)
{
Print("--- Symbol Scanner Panel Started ---");
PrintFilterCriteria();
Print("---------------------------------");
string symbols_to_scan[];
if(!GetSymbolsToScan(symbols_to_scan))
{
Print("No symbols to scan. Exiting.");
return;
}
int found_count = 0;
PrintHeader();
SymbolData current_symbol_data;
for(int i = 0; i < ArraySize(symbols_to_scan); i++)
{
string symbol_name = symbols_to_scan[i];
StringTrimLeft(symbol_name);
StringTrimRight(symbol_name);
if(StringLen(symbol_name) == 0)
continue;
GatherSymbolData(symbol_name, current_symbol_data);
if(SymbolPassesFilters(current_symbol_data))
{
found_count++;
PrintSymbolData(current_symbol_data);
}
}
Print("--------------------------------------------------------------------------------------------------------------------------------------------------------");
PrintFormat("Scanner Completed. Found %d matching symbols.", found_count);
Print("---------------------------------");
}
//+------------------------------------------------------------------+
//| Gathers all required data for a single symbol |
//+------------------------------------------------------------------+
void CSymbolScanner::GatherSymbolData(const string symbol_name, SymbolData &data)
{
if(!m_symbol_info.Name(symbol_name))
return;
if(!m_symbol_info.RefreshRates())
return;
data.name = m_symbol_info.Name();
data.path = m_symbol_info.Path();
data.description = m_symbol_info.Description();
m_symbol_info.InfoString(SYMBOL_INDUSTRY_NAME, data.industry_name);
data.spread = m_symbol_info.Spread();
data.point = m_symbol_info.Point();
data.tick_value = m_symbol_info.TickValue();
data.tick_value_profit = m_symbol_info.TickValueProfit();
data.tick_value_loss = m_symbol_info.TickValueLoss();
data.tick_size = m_symbol_info.TickSize();
data.volume_min = m_symbol_info.LotsMin();
data.volume_step = m_symbol_info.LotsStep();
data.swap_long = m_symbol_info.SwapLong();
data.swap_short = m_symbol_info.SwapShort();
}
//+------------------------------------------------------------------+
//| Checks if a symbol's data meets all the filter criteria |
//+------------------------------------------------------------------+
bool CSymbolScanner::SymbolPassesFilters(const SymbolData &data)
{
if(m_filter_market_watch && !SymbolInfoInteger(data.name, SYMBOL_SELECT))
return false;
if(StringLen(m_filter_path_contains) > 0 && StringFind(data.path, m_filter_path_contains) == -1)
return false;
if(data.volume_min < m_filter_min_vol_min || data.volume_min > m_filter_max_vol_min)
return false;
if(data.volume_step < m_filter_min_vol_step || data.volume_step > m_filter_max_vol_step)
return false;
if(m_filter_only_etfs && data.industry_name != "Exchange Traded Fund")
return false;
if(m_filter_extended_hours && StringFind(data.description, m_keyword_ext_hours) == -1)
return false;
return true;
}
//+------------------------------------------------------------------+
//| Gets the list of symbols to scan from inputs or the whole market |
//+------------------------------------------------------------------+
bool CSymbolScanner::GetSymbolsToScan(string &symbols_array[])
{
string symbols_input_copy = m_symbols_to_scan;
StringTrimLeft(symbols_input_copy);
StringTrimRight(symbols_input_copy);
if(StringLen(symbols_input_copy) > 0)
{
StringSplit(symbols_input_copy, StringGetCharacter(m_symbol_separator, 0), symbols_array);
PrintFormat("%d symbols provided by user.", ArraySize(symbols_array));
}
else
{
int total_server_symbols = SymbolsTotal(false);
if(total_server_symbols == 0)
return false;
ArrayResize(symbols_array, total_server_symbols);
for(int j = 0; j < total_server_symbols; j++)
{
symbols_array[j] = SymbolName(j, false);
}
Print("No specific symbols provided. Scanning all available server symbols.");
}
return(ArraySize(symbols_array) > 0);
}
//+------------------------------------------------------------------+
//| Prints a formatted row of data for a single symbol |
//+------------------------------------------------------------------+
void CSymbolScanner::PrintSymbolData(const SymbolData &data)
{
PrintFormat("%-15s | %-8s | %-8s | %-10s | %-10s | %-10s | %-10s | %-10s | %-10s | %-10s | %-10s | %-20s",
data.name,
(string)data.spread,
DoubleToString(data.point, -1),
DoubleToString(data.tick_value, 2),
DoubleToString(data.tick_value_profit, 2),
DoubleToString(data.tick_value_loss, 2),
DoubleToString(data.tick_size, -1),
DoubleToString(data.volume_min, -1),
DoubleToString(data.volume_step, -1),
DoubleToString(data.swap_long, 2),
DoubleToString(data.swap_short, 2),
data.path);
}
//+------------------------------------------------------------------+
//| Prints the header for the output table |
//+------------------------------------------------------------------+
void CSymbolScanner::PrintHeader()
{
PrintFormat("%-15s | %-8s | %-8s | %-10s | %-10s | %-10s | %-10s | %-10s | %-10s | %-10s | %-10s | %-20s",
"Symbol", "Spread", "Point", "TickValue", "TV_Profit", "TV_Loss", "TickSize", "Vol_Min", "Vol_Step", "Swap_Long", "Swap_Short", "Path");
Print("--------------------------------------------------------------------------------------------------------------------------------------------------------");
}
//+------------------------------------------------------------------+
//| Prints the filter criteria that the scanner is using |
//+------------------------------------------------------------------+
void CSymbolScanner::PrintFilterCriteria()
{
PrintFormat("Filter Criteria:");
PrintFormat(" Symbols to Scan: '%s'", m_symbols_to_scan);
PrintFormat(" Path Contains: '%s'", m_filter_path_contains);
PrintFormat(" Only Market Watch Selected: %s", (string)m_filter_market_watch);
PrintFormat(" Min Volume (Min): %g - %g", m_filter_min_vol_min, m_filter_max_vol_min);
PrintFormat(" Volume Step: %g - %g", m_filter_min_vol_step, m_filter_max_vol_step);
PrintFormat(" Only ETFs: %s", (string)m_filter_only_etfs);
PrintFormat(" Only Extended Hours: %s (Keyword: '%s')", (string)m_filter_extended_hours, m_keyword_ext_hours);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- Create an instance of the scanner with the input parameters
CSymbolScanner scanner(InpSymbolsToScan, InpSymbolSeparator, InpFilterPathContains, InpFilterMarketWatch,
InpFilterMinVolMin, InpFilterMaxVolMin, InpFilterMinVolStep, InpFilterMaxVolStep,
InpFilterOnlyETFs, InpFilterExtendedHours, InpKeywordExtHours);
//--- Run the scanner
scanner.Run();
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
+59 -59
View File
@@ -1,59 +1,59 @@
# Candle Data Exporter Script
## 1. Summary (Introduction)
The Candle Data Exporter is an MQL5 script designed as a simple yet powerful **data utility tool**. When executed on a chart, it extracts a specified number of historical price bars (candlesticks) and saves them into a CSV (Comma-Separated Values) file.
Its primary purpose is to allow traders, analysts, and developers to easily export historical data from the MetaTrader 5 terminal for use in external applications such as Microsoft Excel, Python scripts, or other data analysis software. The generated file is saved in a standard, easy-to-parse format.
## 2. Features and Exported Data
The script is configurable through its input parameters and exports a comprehensive set of data for each candlestick. The resulting CSV file is saved in the terminal's `MQL5/Files/` directory.
For each candle, the following data points are exported into a separate column:
- **time:** The opening time of the candle, formatted as a human-readable string (e.g., `YYYY.MM.DD HH:MI:SS`).
- **open:** The opening price.
- **high:** The highest price.
- **low:** The lowest price.
- **close:** The closing price.
- **tick_volume:** The volume of ticks within the bar.
- **real_volume:** The real trade volume (if provided by the broker).
- **spread:** The spread in points at the time the bar was formed.
## 3. MQL5 Implementation Details
The script was refactored into a clean, fully object-oriented structure to ensure its logic is modular, reusable, and robust.
- **Object-Oriented Design:** The entire export logic is encapsulated within a `CCandleExporter` class. The script's entry point (`OnStart`) is minimal and is only responsible for creating an instance of this class with the user's input parameters and executing its `Run()` method.
- **Clear, Staged Execution:** The main `Run()` method orchestrates the export process in a series of clear, sequential steps, each handled by a dedicated private method:
1. `PrepareFileName()`: Generates a descriptive file name if one is not provided by the user.
2. `OpenFile()`: Opens the CSV file for writing.
3. `CopyData()`: Retrieves the historical `MqlRates` data from the terminal.
4. `WriteData()`: Writes the header row and then iterates through the retrieved data to write each candle to the file.
5. `CloseFile()`: Closes the file handle.
- **Robust File Handling (RAII):** The script follows the **Resource Acquisition Is Initialization (RAII)** principle. The file handle is managed as a class member. The `CloseFile()` method is called automatically by the class's **destructor** (`~CCandleExporter`). This is a robust safety feature that guarantees the file handle is always properly closed, even if an error occurs during the export process, preventing file corruption or resource leaks.
- **Self-Contained Logic:** The script is completely self-contained and uses standard MQL5 functions (`CopyRates`, `FileOpen`, etc.) for its operations. It has no external dependencies on other indicators or libraries.
## 4. Usage
1. **Installation:**
- Place `util_ExportCandlesToCSV.mq5` into your `MQL5\Scripts` folder.
2. **Execution:**
- Open the chart of the symbol and timeframe you wish to export.
- Drag and drop the `util_ExportCandlesToCSV` script from the Navigator window onto the chart.
- The script input window will appear, allowing you to configure the export parameters.
3. **Retrieve File:**
- After the script finishes, it will print a success message to the "Experts" tab.
- To find the exported file, go to **File -> Open Data Folder** in the MetaTrader 5 terminal.
- Navigate to the `MQL5\Files\` directory. Your CSV file will be located there.
## 5. Input Parameters
- **`InpCandlesToExport`**: The number of most recent candles you want to export from the current bar backwards. Default is `1000`.
- **`InpFileName`**: The name of the output CSV file. If left empty, a descriptive name will be automatically generated based on the symbol and timeframe (e.g., `EURUSD_PERIOD_M15_Candles.csv`).
- **`InpDelimiter`**: The character used to separate values in the CSV file. The default is a comma (`,`), but a semicolon (`;`) can be used for compatibility with some regional settings in Excel.
# Candle Data Exporter Script
## 1. Summary (Introduction)
The Candle Data Exporter is an MQL5 script designed as a simple yet powerful **data utility tool**. When executed on a chart, it extracts a specified number of historical price bars (candlesticks) and saves them into a CSV (Comma-Separated Values) file.
Its primary purpose is to allow traders, analysts, and developers to easily export historical data from the MetaTrader 5 terminal for use in external applications such as Microsoft Excel, Python scripts, or other data analysis software. The generated file is saved in a standard, easy-to-parse format.
## 2. Features and Exported Data
The script is configurable through its input parameters and exports a comprehensive set of data for each candlestick. The resulting CSV file is saved in the terminal's `MQL5/Files/` directory.
For each candle, the following data points are exported into a separate column:
- **time:** The opening time of the candle, formatted as a human-readable string (e.g., `YYYY.MM.DD HH:MI:SS`).
- **open:** The opening price.
- **high:** The highest price.
- **low:** The lowest price.
- **close:** The closing price.
- **tick_volume:** The volume of ticks within the bar.
- **real_volume:** The real trade volume (if provided by the broker).
- **spread:** The spread in points at the time the bar was formed.
## 3. MQL5 Implementation Details
The script was refactored into a clean, fully object-oriented structure to ensure its logic is modular, reusable, and robust.
- **Object-Oriented Design:** The entire export logic is encapsulated within a `CCandleExporter` class. The script's entry point (`OnStart`) is minimal and is only responsible for creating an instance of this class with the user's input parameters and executing its `Run()` method.
- **Clear, Staged Execution:** The main `Run()` method orchestrates the export process in a series of clear, sequential steps, each handled by a dedicated private method:
1. `PrepareFileName()`: Generates a descriptive file name if one is not provided by the user.
2. `OpenFile()`: Opens the CSV file for writing.
3. `CopyData()`: Retrieves the historical `MqlRates` data from the terminal.
4. `WriteData()`: Writes the header row and then iterates through the retrieved data to write each candle to the file.
5. `CloseFile()`: Closes the file handle.
- **Robust File Handling (RAII):** The script follows the **Resource Acquisition Is Initialization (RAII)** principle. The file handle is managed as a class member. The `CloseFile()` method is called automatically by the class's **destructor** (`~CCandleExporter`). This is a robust safety feature that guarantees the file handle is always properly closed, even if an error occurs during the export process, preventing file corruption or resource leaks.
- **Self-Contained Logic:** The script is completely self-contained and uses standard MQL5 functions (`CopyRates`, `FileOpen`, etc.) for its operations. It has no external dependencies on other indicators or libraries.
## 4. Usage
1. **Installation:**
- Place `util_ExportCandlesToCSV.mq5` into your `MQL5\Scripts` folder.
2. **Execution:**
- Open the chart of the symbol and timeframe you wish to export.
- Drag and drop the `util_ExportCandlesToCSV` script from the Navigator window onto the chart.
- The script input window will appear, allowing you to configure the export parameters.
3. **Retrieve File:**
- After the script finishes, it will print a success message to the "Experts" tab.
- To find the exported file, go to **File -> Open Data Folder** in the MetaTrader 5 terminal.
- Navigate to the `MQL5\Files\` directory. Your CSV file will be located there.
## 5. Input Parameters
- **`InpCandlesToExport`**: The number of most recent candles you want to export from the current bar backwards. Default is `1000`.
- **`InpFileName`**: The name of the output CSV file. If left empty, a descriptive name will be automatically generated based on the symbol and timeframe (e.g., `EURUSD_PERIOD_M15_Candles.csv`).
- **`InpDelimiter`**: The character used to separate values in the CSV file. The default is a comma (`,`), but a semicolon (`;`) can be used for compatibility with some regional settings in Excel.
+198 -198
View File
@@ -1,198 +1,198 @@
//+------------------------------------------------------------------+
//| util_ExportCandlesToCSV.mq5 |
//| Copyright 2025, xxxxxxxx |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, xxxxxxxx"
#property link ""
#property version "2.00" // Refactored into a class-based structure
#property script_show_inputs
#property description "Exports historical candle data for the current chart to a CSV file."
#property description "The file is saved in the terminal's MQL5/Files/ folder."
//--- Input Parameters ---
input int InpCandlesToExport = 1000; // Number of most recent candles to export
input string InpFileName = ""; // CSV file name. If empty, it will be auto-generated.
input string InpDelimiter = ","; // Delimiter for the CSV file (e.g., comma or semicolon)
//+------------------------------------------------------------------+
//| CCandleExporter Class |
//| Encapsulates all logic for exporting candle data to a CSV file. |
//+------------------------------------------------------------------+
class CCandleExporter
{
private:
//--- Export settings
int m_candles_to_export;
string m_file_name;
char m_delimiter;
string m_symbol;
ENUM_TIMEFRAMES m_period;
//--- Internal state
int m_file_handle;
public:
//--- Constructor
CCandleExporter(int candles, string file_name, string delimiter);
//--- Destructor
~CCandleExporter(void);
//--- Main execution method
bool Run(void);
private:
//--- Helper methods
bool PrepareFileName(void);
bool OpenFile(void);
int CopyData(MqlRates &rates[]);
bool WriteData(const MqlRates &rates[], int count);
void CloseFile(void);
};
//+------------------------------------------------------------------+
//| Constructor: Initializes the exporter with settings |
//+------------------------------------------------------------------+
CCandleExporter::CCandleExporter(int candles, string file_name, string delimiter)
{
m_candles_to_export = (candles > 0) ? candles : 1;
m_file_name = file_name;
m_delimiter = (char)StringGetCharacter(delimiter, 0);
m_symbol = _Symbol;
m_period = _Period;
m_file_handle = INVALID_HANDLE;
}
//+------------------------------------------------------------------+
//| Destructor: Ensures the file is always closed |
//+------------------------------------------------------------------+
CCandleExporter::~CCandleExporter(void)
{
CloseFile();
}
//+------------------------------------------------------------------+
//| Main execution method |
//+------------------------------------------------------------------+
bool CCandleExporter::Run(void)
{
if(!PrepareFileName())
return false;
if(!OpenFile())
return false;
MqlRates rates[];
int copied_count = CopyData(rates);
if(copied_count <= 0)
{
CloseFile();
return false;
}
if(!WriteData(rates, copied_count))
{
CloseFile();
return false;
}
CloseFile();
PrintFormat("Successfully exported %d candles to '%s'.", copied_count, m_file_name);
Print("You can find the file in the terminal's Data Folder under MQL5/Files/.");
return true;
}
//+------------------------------------------------------------------+
//| Prepares and validates the file name |
//+------------------------------------------------------------------+
bool CCandleExporter::PrepareFileName(void)
{
if(m_file_name == "")
{
m_file_name = StringFormat("%s_%s_Candles.csv", m_symbol, EnumToString(m_period));
}
if(StringFind(m_file_name, ".csv", StringLen(m_file_name) - 4) == -1)
{
m_file_name += ".csv";
}
PrintFormat("Starting export of %d candles for %s on %s...", m_candles_to_export, m_symbol, EnumToString(m_period));
PrintFormat("Target file: MQL5\\Files\\%s", m_file_name);
return true;
}
//+------------------------------------------------------------------+
//| Opens the target file for writing |
//+------------------------------------------------------------------+
bool CCandleExporter::OpenFile(void)
{
ResetLastError();
m_file_handle = FileOpen(m_file_name, FILE_WRITE | FILE_CSV | FILE_ANSI, m_delimiter);
if(m_file_handle == INVALID_HANDLE)
{
PrintFormat("Error opening file '%s'. Error code: %d", m_file_name, GetLastError());
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Copies historical rate data from the terminal |
//+------------------------------------------------------------------+
int CCandleExporter::CopyData(MqlRates &rates[])
{
ArraySetAsSeries(rates, false);
int copied_count = CopyRates(m_symbol, m_period, 0, m_candles_to_export, rates);
if(copied_count <= 0)
{
PrintFormat("Error: Could not copy any candle data. Error code: %d", GetLastError());
return 0;
}
if(copied_count < m_candles_to_export)
{
PrintFormat("Warning: Could only copy %d candles, less than the requested %d.", copied_count, m_candles_to_export);
}
return copied_count;
}
//+------------------------------------------------------------------+
//| Writes the header and candle data to the opened CSV file |
//+------------------------------------------------------------------+
bool CCandleExporter::WriteData(const MqlRates &rates[], int count)
{
FileWrite(m_file_handle, "time", "open", "high", "low", "close", "tick_volume", "real_volume", "spread");
for(int i = 0; i < count; i++)
{
string time_str = TimeToString(rates[i].time, TIME_DATE | TIME_MINUTES | TIME_SECONDS);
FileWrite(m_file_handle, time_str, rates[i].open, rates[i].high, rates[i].low,
rates[i].close, rates[i].tick_volume, rates[i].real_volume, rates[i].spread);
}
return true;
}
//+------------------------------------------------------------------+
//| Closes the file handle if it's open |
//+------------------------------------------------------------------+
void CCandleExporter::CloseFile(void)
{
if(m_file_handle != INVALID_HANDLE)
{
FileClose(m_file_handle);
m_file_handle = INVALID_HANDLE;
}
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
CCandleExporter exporter(InpCandlesToExport, InpFileName, InpDelimiter);
exporter.Run();
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| util_ExportCandlesToCSV.mq5 |
//| Copyright 2025, xxxxxxxx |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, xxxxxxxx"
#property link ""
#property version "2.00" // Refactored into a class-based structure
#property script_show_inputs
#property description "Exports historical candle data for the current chart to a CSV file."
#property description "The file is saved in the terminal's MQL5/Files/ folder."
//--- Input Parameters ---
input int InpCandlesToExport = 1000; // Number of most recent candles to export
input string InpFileName = ""; // CSV file name. If empty, it will be auto-generated.
input string InpDelimiter = ","; // Delimiter for the CSV file (e.g., comma or semicolon)
//+------------------------------------------------------------------+
//| CCandleExporter Class |
//| Encapsulates all logic for exporting candle data to a CSV file. |
//+------------------------------------------------------------------+
class CCandleExporter
{
private:
//--- Export settings
int m_candles_to_export;
string m_file_name;
char m_delimiter;
string m_symbol;
ENUM_TIMEFRAMES m_period;
//--- Internal state
int m_file_handle;
public:
//--- Constructor
CCandleExporter(int candles, string file_name, string delimiter);
//--- Destructor
~CCandleExporter(void);
//--- Main execution method
bool Run(void);
private:
//--- Helper methods
bool PrepareFileName(void);
bool OpenFile(void);
int CopyData(MqlRates &rates[]);
bool WriteData(const MqlRates &rates[], int count);
void CloseFile(void);
};
//+------------------------------------------------------------------+
//| Constructor: Initializes the exporter with settings |
//+------------------------------------------------------------------+
CCandleExporter::CCandleExporter(int candles, string file_name, string delimiter)
{
m_candles_to_export = (candles > 0) ? candles : 1;
m_file_name = file_name;
m_delimiter = (char)StringGetCharacter(delimiter, 0);
m_symbol = _Symbol;
m_period = _Period;
m_file_handle = INVALID_HANDLE;
}
//+------------------------------------------------------------------+
//| Destructor: Ensures the file is always closed |
//+------------------------------------------------------------------+
CCandleExporter::~CCandleExporter(void)
{
CloseFile();
}
//+------------------------------------------------------------------+
//| Main execution method |
//+------------------------------------------------------------------+
bool CCandleExporter::Run(void)
{
if(!PrepareFileName())
return false;
if(!OpenFile())
return false;
MqlRates rates[];
int copied_count = CopyData(rates);
if(copied_count <= 0)
{
CloseFile();
return false;
}
if(!WriteData(rates, copied_count))
{
CloseFile();
return false;
}
CloseFile();
PrintFormat("Successfully exported %d candles to '%s'.", copied_count, m_file_name);
Print("You can find the file in the terminal's Data Folder under MQL5/Files/.");
return true;
}
//+------------------------------------------------------------------+
//| Prepares and validates the file name |
//+------------------------------------------------------------------+
bool CCandleExporter::PrepareFileName(void)
{
if(m_file_name == "")
{
m_file_name = StringFormat("%s_%s_Candles.csv", m_symbol, EnumToString(m_period));
}
if(StringFind(m_file_name, ".csv", StringLen(m_file_name) - 4) == -1)
{
m_file_name += ".csv";
}
PrintFormat("Starting export of %d candles for %s on %s...", m_candles_to_export, m_symbol, EnumToString(m_period));
PrintFormat("Target file: MQL5\\Files\\%s", m_file_name);
return true;
}
//+------------------------------------------------------------------+
//| Opens the target file for writing |
//+------------------------------------------------------------------+
bool CCandleExporter::OpenFile(void)
{
ResetLastError();
m_file_handle = FileOpen(m_file_name, FILE_WRITE | FILE_CSV | FILE_ANSI, m_delimiter);
if(m_file_handle == INVALID_HANDLE)
{
PrintFormat("Error opening file '%s'. Error code: %d", m_file_name, GetLastError());
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Copies historical rate data from the terminal |
//+------------------------------------------------------------------+
int CCandleExporter::CopyData(MqlRates &rates[])
{
ArraySetAsSeries(rates, false);
int copied_count = CopyRates(m_symbol, m_period, 0, m_candles_to_export, rates);
if(copied_count <= 0)
{
PrintFormat("Error: Could not copy any candle data. Error code: %d", GetLastError());
return 0;
}
if(copied_count < m_candles_to_export)
{
PrintFormat("Warning: Could only copy %d candles, less than the requested %d.", copied_count, m_candles_to_export);
}
return copied_count;
}
//+------------------------------------------------------------------+
//| Writes the header and candle data to the opened CSV file |
//+------------------------------------------------------------------+
bool CCandleExporter::WriteData(const MqlRates &rates[], int count)
{
FileWrite(m_file_handle, "time", "open", "high", "low", "close", "tick_volume", "real_volume", "spread");
for(int i = 0; i < count; i++)
{
string time_str = TimeToString(rates[i].time, TIME_DATE | TIME_MINUTES | TIME_SECONDS);
FileWrite(m_file_handle, time_str, rates[i].open, rates[i].high, rates[i].low,
rates[i].close, rates[i].tick_volume, rates[i].real_volume, rates[i].spread);
}
return true;
}
//+------------------------------------------------------------------+
//| Closes the file handle if it's open |
//+------------------------------------------------------------------+
void CCandleExporter::CloseFile(void)
{
if(m_file_handle != INVALID_HANDLE)
{
FileClose(m_file_handle);
m_file_handle = INVALID_HANDLE;
}
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
CCandleExporter exporter(InpCandlesToExport, InpFileName, InpDelimiter);
exporter.Run();
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+