diff --git a/Scripts/MyScripts/AccountInfoDisplay.mq5 b/Scripts/MyScripts/AccountInfoDisplay.mq5 index df4ed05..acbfa17 100644 --- a/Scripts/MyScripts/AccountInfoDisplay.mq5 +++ b/Scripts/MyScripts/AccountInfoDisplay.mq5 @@ -1,20 +1,27 @@ //+------------------------------------------------------------------+ //| AccountInfoDisplay.mq5 | -//| Copyright 2000-2025, MetaQuotes Ltd. | -//| https://www.mql5.com | +//| Copyright 2025, xxxxxxxx | +//| | //+------------------------------------------------------------------+ -#property copyright "Copyright 2000-2025, MetaQuotes Ltd." -#property link "https://www.mql5.com" +#property copyright "Copyright 2025, xxxxxxxx" +#property link "" #property description "Displays account information directly on the chart." -#property version "1.10" // Version updated to reflect changes +#property version "2.02" // Final fix for boolean conversion //--- Standard library includes #include #include //--- Custom include file for initialization data -// Make sure this file is in your MQL5/Include folder -#include "AccountInfoDisplayInit.mqh" +#include + +//+------------------------------------------------------------------+ +//| A simple structure to hold the formatted account data | +//+------------------------------------------------------------------+ +struct SAccountData + { + string data[ROW_TOTAL_COUNT]; + }; //+------------------------------------------------------------------+ //| Account Info Display script class | @@ -23,177 +30,167 @@ class CAccountInfoDisplay { protected: CAccountInfo m_account; - //--- Chart objects - // The size of the array is now determined by our enum - CChartObjectLabel m_label[ROW_TOTAL_COUNT]; - CChartObjectLabel m_label_info[ROW_TOTAL_COUNT]; + CChartObjectLabel m_labels[ROW_TOTAL_COUNT]; + CChartObjectLabel m_values[ROW_TOTAL_COUNT]; public: CAccountInfoDisplay(void); ~CAccountInfoDisplay(void); - //--- + bool Init(void); - void Deinit(void); void Processing(void); -private: - void AccountInfoToChart(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 | +//| 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 sy=10; - int dy=16; + int y_start = 10; + int y_step = 16; color color_label; - color color_info; + color color_value; color color_heading = clrDarkGray; int font_size_data = 8; int font_size_heading = 9; -//--- Dynamic color tuning - color_info = (color)(ChartGetInteger(0, CHART_COLOR_BACKGROUND) ^ 0xFFFFFF); - color_label = (color)(color_info ^ 0x202020); + color_value = (color)(ChartGetInteger(0, CHART_COLOR_BACKGROUND) ^ 0xFFFFFF); + color_label = (color)(color_value ^ 0x202020); -//--- Adjust starting position if OHLC is shown if(ChartGetInteger(0, CHART_SHOW_OHLC)) - sy += 16; + y_start += 16; - int current_y = sy; + int current_y = y_start; -//--- Create chart labels for(int i = 0; i < ROW_TOTAL_COUNT; i++) { - // Check if the current label is a heading - bool is_heading = ( - StringFind(init_str[i], "I. ") == 0 || - StringFind(init_str[i], "II. ") == 0 || - StringFind(init_str[i], "III. ") == 0 || - StringFind(init_str[i], "IV. ") == 0 || - StringFind(init_str[i], "V. ") == 0 - ); + 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); - // Create the property label (e.g., "Balance") - m_label[i].Create(0, "AccInfoLabel" + IntegerToString(i), 0, 20, current_y); - m_label[i].Description(init_str[i]); - m_label[i].Color(is_heading ? color_heading : color_label); - m_label[i].FontSize(is_heading ? font_size_heading : font_size_data); - m_label[i].Selectable(false); + 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); - // Create the value label (e.g., "99588.30") - m_label_info[i].Create(0, "AccInfoValue" + IntegerToString(i), 0, 140, current_y); - m_label_info[i].Description(" "); - m_label_info[i].Color(color_info); - m_label_info[i].FontSize(font_size_data); - m_label_info[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 += dy; + current_y += y_step; } -// Initial data population - AccountInfoToChart(); + SAccountData data; + GetAccountData(data); + UpdateChartLabels(data); ChartRedraw(); return(true); } -//+------------------------------------------------------------------+ -//| Deinitialization Method | -//+------------------------------------------------------------------+ -void CAccountInfoDisplay::Deinit(void) - { -//--- MODIFICATION: Implemented Deinit to clean up chart objects -// This ensures that when the script is removed, it leaves no trace. - for(int i = 0; i < ROW_TOTAL_COUNT; i++) - { - m_label[i].Delete(); - m_label_info[i].Delete(); - } - ChartRedraw(); - } + //+------------------------------------------------------------------+ //| Processing Method (called in a loop) | //+------------------------------------------------------------------+ void CAccountInfoDisplay::Processing(void) { -// Update the data on the chart - AccountInfoToChart(); + SAccountData data; + GetAccountData(data); + UpdateChartLabels(data); ChartRedraw(); - -//--- MODIFICATION: Increased sleep time for better performance -// Updating every 50ms is excessive. 1 second is plenty for this info. - Sleep(1000); // 1000 milliseconds = 1 second + Sleep(1000); } + //+------------------------------------------------------------------+ -//| Method to write account info to chart labels | +//| Fills the data structure with current account info | //+------------------------------------------------------------------+ -void CAccountInfoDisplay::AccountInfoToChart(void) +void CAccountInfoDisplay::GetAccountData(SAccountData &account_data) { -//--- MODIFICATION: Using the enum for indexing instead of "magic numbers" -// This makes the code readable and robust against reordering. +// 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. -// --- I. Basic Account Information --- - m_label_info[ROW_LOGIN].Description((string)m_account.Login()); - m_label_info[ROW_NAME].Description(m_account.Name()); - m_label_info[ROW_SERVER].Description(m_account.Server()); - m_label_info[ROW_COMPANY].Description(m_account.Company()); - m_label_info[ROW_CURRENCY].Description(m_account.Currency()); - m_label_info[ROW_CURRENCY_DIGITS].Description((string)m_account.InfoInteger(ACCOUNT_CURRENCY_DIGITS)); +// The CAccountInfo class does not have a Refresh() method. +// Data is refreshed automatically by the terminal. -// --- II. Financial Status and Balances --- - m_label_info[ROW_BALANCE].Description(DoubleToString(m_account.Balance(), 2)); - m_label_info[ROW_CREDIT].Description(DoubleToString(m_account.Credit(), 2)); - m_label_info[ROW_PROFIT].Description(DoubleToString(m_account.Profit(), 2)); - m_label_info[ROW_EQUITY].Description(DoubleToString(m_account.Equity(), 2)); - -// --- III. Margin and Risk Management --- - m_label_info[ROW_MARGIN].Description(DoubleToString(m_account.Margin(), 2)); - m_label_info[ROW_MARGIN_FREE].Description(DoubleToString(m_account.FreeMargin(), 2)); - m_label_info[ROW_MARGIN_LEVEL].Description(DoubleToString(m_account.MarginLevel(), 2)); - m_label_info[ROW_MARGIN_CALL].Description(DoubleToString(m_account.MarginCall(), 2)); - m_label_info[ROW_MARGIN_STOPOUT].Description(DoubleToString(m_account.MarginStopOut(), 2)); - -// --- IV. Trading Modes and Rules --- - m_label_info[ROW_TRADE_MODE].Description(m_account.TradeModeDescription()); - m_label_info[ROW_LEVERAGE].Description((string)m_account.Leverage()); - m_label_info[ROW_MARGIN_MODE].Description(m_account.MarginModeDescription()); - m_label_info[ROW_STOPOUT_MODE].Description(m_account.StopoutModeDescription()); - m_label_info[ROW_FIFO_CLOSE].Description((string)m_account.InfoInteger(ACCOUNT_FIFO_CLOSE)); - m_label_info[ROW_HEDGE_ALLOWED].Description((string)m_account.InfoInteger(ACCOUNT_HEDGE_ALLOWED)); - -// --- V. Trading Permissions --- - m_label_info[ROW_TRADE_ALLOWED].Description((string)m_account.TradeAllowed()); - m_label_info[ROW_TRADE_EXPERT].Description((string)m_account.TradeExpert()); + 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) { -//--- Initialize our display object if(g_accountDisplay.Init()) { - //--- Loop until the script is stopped by the user while(!IsStopped()) { g_accountDisplay.Processing(); } } -//--- Deinitialize to clean up the chart - g_accountDisplay.Deinit(); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+