refactor: final fix for boolean conversion

This commit is contained in:
Toh4iem9
2025-08-23 10:19:19 +02:00
parent 0f2445effd
commit e3be397a2d
+105 -108
View File
@@ -1,20 +1,27 @@
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| AccountInfoDisplay.mq5 | //| AccountInfoDisplay.mq5 |
//| Copyright 2000-2025, MetaQuotes Ltd. | //| Copyright 2025, xxxxxxxx |
//| https://www.mql5.com | //| |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
#property copyright "Copyright 2000-2025, MetaQuotes Ltd." #property copyright "Copyright 2025, xxxxxxxx"
#property link "https://www.mql5.com" #property link ""
#property description "Displays account information directly on the chart." #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 //--- Standard library includes
#include <Trade\AccountInfo.mqh> #include <Trade\AccountInfo.mqh>
#include <ChartObjects\ChartObjectsTxtControls.mqh> #include <ChartObjects\ChartObjectsTxtControls.mqh>
//--- Custom include file for initialization data //--- Custom include file for initialization data
// Make sure this file is in your MQL5/Include folder #include <MyIncludes\AccountInfoDisplayInit.mqh>
#include "AccountInfoDisplayInit.mqh"
//+------------------------------------------------------------------+
//| A simple structure to hold the formatted account data |
//+------------------------------------------------------------------+
struct SAccountData
{
string data[ROW_TOTAL_COUNT];
};
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Account Info Display script class | //| Account Info Display script class |
@@ -23,177 +30,167 @@ class CAccountInfoDisplay
{ {
protected: protected:
CAccountInfo m_account; CAccountInfo m_account;
//--- Chart objects CChartObjectLabel m_labels[ROW_TOTAL_COUNT];
// The size of the array is now determined by our enum CChartObjectLabel m_values[ROW_TOTAL_COUNT];
CChartObjectLabel m_label[ROW_TOTAL_COUNT];
CChartObjectLabel m_label_info[ROW_TOTAL_COUNT];
public: public:
CAccountInfoDisplay(void); CAccountInfoDisplay(void);
~CAccountInfoDisplay(void); ~CAccountInfoDisplay(void);
//---
bool Init(void); bool Init(void);
void Deinit(void);
void Processing(void); void Processing(void);
private: protected:
void AccountInfoToChart(void); void GetAccountData(SAccountData &account_data);
void UpdateChartLabels(const SAccountData &account_data);
}; };
//--- Global instance of our class //--- Global instance of our class
CAccountInfoDisplay g_accountDisplay; CAccountInfoDisplay g_accountDisplay;
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Constructor | //| Constructor |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
CAccountInfoDisplay::CAccountInfoDisplay(void) CAccountInfoDisplay::CAccountInfoDisplay(void)
{ {
} }
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Destructor | //| Destructor (handles deinitialization) |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
CAccountInfoDisplay::~CAccountInfoDisplay(void) CAccountInfoDisplay::~CAccountInfoDisplay(void)
{ {
for(int i = 0; i < ROW_TOTAL_COUNT; i++)
{
m_labels[i].Delete();
m_values[i].Delete();
}
ChartRedraw();
} }
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Initialization Method | //| Initialization Method |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
bool CAccountInfoDisplay::Init(void) bool CAccountInfoDisplay::Init(void)
{ {
int sy=10; int y_start = 10;
int dy=16; int y_step = 16;
color color_label; color color_label;
color color_info; color color_value;
color color_heading = clrDarkGray; color color_heading = clrDarkGray;
int font_size_data = 8; int font_size_data = 8;
int font_size_heading = 9; int font_size_heading = 9;
//--- Dynamic color tuning color_value = (color)(ChartGetInteger(0, CHART_COLOR_BACKGROUND) ^ 0xFFFFFF);
color_info = (color)(ChartGetInteger(0, CHART_COLOR_BACKGROUND) ^ 0xFFFFFF); color_label = (color)(color_value ^ 0x202020);
color_label = (color)(color_info ^ 0x202020);
//--- Adjust starting position if OHLC is shown
if(ChartGetInteger(0, CHART_SHOW_OHLC)) 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++) for(int i = 0; i < ROW_TOTAL_COUNT; i++)
{ {
// Check if the current label is a heading bool is_heading = (StringFind(g_init_labels[i], "I. ") == 0 || StringFind(g_init_labels[i], "II. ") == 0 ||
bool is_heading = ( StringFind(g_init_labels[i], "III. ") == 0 || StringFind(g_init_labels[i], "IV. ") == 0 ||
StringFind(init_str[i], "I. ") == 0 || StringFind(g_init_labels[i], "V. ") == 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
);
// Create the property label (e.g., "Balance") m_labels[i].Create(0, "AccInfoLabel" + (string)i, 0, 20, current_y);
m_label[i].Create(0, "AccInfoLabel" + IntegerToString(i), 0, 20, current_y); m_labels[i].Description(g_init_labels[i]);
m_label[i].Description(init_str[i]); m_labels[i].Color(is_heading ? color_heading : color_label);
m_label[i].Color(is_heading ? color_heading : color_label); m_labels[i].FontSize(is_heading ? font_size_heading : font_size_data);
m_label[i].FontSize(is_heading ? font_size_heading : font_size_data); m_labels[i].Selectable(false);
m_label[i].Selectable(false);
// Create the value label (e.g., "99588.30") m_values[i].Create(0, "AccInfoValue" + (string)i, 0, 140, current_y);
m_label_info[i].Create(0, "AccInfoValue" + IntegerToString(i), 0, 140, current_y); m_values[i].Description("...");
m_label_info[i].Description(" "); m_values[i].Color(color_value);
m_label_info[i].Color(color_info); m_values[i].FontSize(font_size_data);
m_label_info[i].FontSize(font_size_data); m_values[i].Selectable(false);
m_label_info[i].Selectable(false);
current_y += dy; current_y += y_step;
} }
// Initial data population SAccountData data;
AccountInfoToChart(); GetAccountData(data);
UpdateChartLabels(data);
ChartRedraw(); ChartRedraw();
return(true); 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) | //| Processing Method (called in a loop) |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
void CAccountInfoDisplay::Processing(void) void CAccountInfoDisplay::Processing(void)
{ {
// Update the data on the chart SAccountData data;
AccountInfoToChart(); GetAccountData(data);
UpdateChartLabels(data);
ChartRedraw(); ChartRedraw();
Sleep(1000);
//--- 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
} }
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| 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 method is part of the CAccountInfoDisplay class, so it can see the m_account member.
// This makes the code readable and robust against reordering. // The enum values are global because of the #include.
// --- I. Basic Account Information --- // The CAccountInfo class does not have a Refresh() method.
m_label_info[ROW_LOGIN].Description((string)m_account.Login()); // Data is refreshed automatically by the terminal.
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));
// --- II. Financial Status and Balances --- account_data.data[ROW_LOGIN] = (string)m_account.Login();
m_label_info[ROW_BALANCE].Description(DoubleToString(m_account.Balance(), 2)); account_data.data[ROW_NAME] = m_account.Name();
m_label_info[ROW_CREDIT].Description(DoubleToString(m_account.Credit(), 2)); account_data.data[ROW_SERVER] = m_account.Server();
m_label_info[ROW_PROFIT].Description(DoubleToString(m_account.Profit(), 2)); account_data.data[ROW_COMPANY] = m_account.Company();
m_label_info[ROW_EQUITY].Description(DoubleToString(m_account.Equity(), 2)); account_data.data[ROW_CURRENCY] = m_account.Currency();
account_data.data[ROW_CURRENCY_DIGITS] = (string)m_account.InfoInteger(ACCOUNT_CURRENCY_DIGITS);
// --- III. Margin and Risk Management --- account_data.data[ROW_BALANCE] = DoubleToString(m_account.Balance(), 2);
m_label_info[ROW_MARGIN].Description(DoubleToString(m_account.Margin(), 2)); account_data.data[ROW_CREDIT] = DoubleToString(m_account.Credit(), 2);
m_label_info[ROW_MARGIN_FREE].Description(DoubleToString(m_account.FreeMargin(), 2)); account_data.data[ROW_PROFIT] = DoubleToString(m_account.Profit(), 2);
m_label_info[ROW_MARGIN_LEVEL].Description(DoubleToString(m_account.MarginLevel(), 2)); account_data.data[ROW_EQUITY] = DoubleToString(m_account.Equity(), 2);
m_label_info[ROW_MARGIN_CALL].Description(DoubleToString(m_account.MarginCall(), 2)); account_data.data[ROW_MARGIN] = DoubleToString(m_account.Margin(), 2);
m_label_info[ROW_MARGIN_STOPOUT].Description(DoubleToString(m_account.MarginStopOut(), 2)); account_data.data[ROW_MARGIN_FREE] = DoubleToString(m_account.FreeMargin(), 2);
account_data.data[ROW_MARGIN_LEVEL] = DoubleToString(m_account.MarginLevel(), 2);
// --- IV. Trading Modes and Rules --- account_data.data[ROW_MARGIN_CALL] = DoubleToString(m_account.MarginCall(), 2);
m_label_info[ROW_TRADE_MODE].Description(m_account.TradeModeDescription()); account_data.data[ROW_MARGIN_STOPOUT] = DoubleToString(m_account.MarginStopOut(), 2);
m_label_info[ROW_LEVERAGE].Description((string)m_account.Leverage()); account_data.data[ROW_TRADE_MODE] = m_account.TradeModeDescription();
m_label_info[ROW_MARGIN_MODE].Description(m_account.MarginModeDescription()); account_data.data[ROW_LEVERAGE] = (string)m_account.Leverage();
m_label_info[ROW_STOPOUT_MODE].Description(m_account.StopoutModeDescription()); account_data.data[ROW_MARGIN_MODE] = m_account.MarginModeDescription();
m_label_info[ROW_FIFO_CLOSE].Description((string)m_account.InfoInteger(ACCOUNT_FIFO_CLOSE)); account_data.data[ROW_STOPOUT_MODE] = m_account.StopoutModeDescription();
m_label_info[ROW_HEDGE_ALLOWED].Description((string)m_account.InfoInteger(ACCOUNT_HEDGE_ALLOWED)); 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);
// --- V. Trading Permissions --- account_data.data[ROW_TRADE_ALLOWED] = m_account.TradeAllowed() ? "true" : "false";
m_label_info[ROW_TRADE_ALLOWED].Description((string)m_account.TradeAllowed()); account_data.data[ROW_TRADE_EXPERT] = m_account.TradeExpert() ? "true" : "false";
m_label_info[ROW_TRADE_EXPERT].Description((string)m_account.TradeExpert());
} }
//+------------------------------------------------------------------+
//| 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 | //| Script program start function |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
void OnStart(void) void OnStart(void)
{ {
//--- Initialize our display object
if(g_accountDisplay.Init()) if(g_accountDisplay.Init())
{ {
//--- Loop until the script is stopped by the user
while(!IsStopped()) while(!IsStopped())
{ {
g_accountDisplay.Processing(); g_accountDisplay.Processing();
} }
} }
//--- Deinitialize to clean up the chart
g_accountDisplay.Deinit();
} }
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+