MQLArticles/RM/AccountStatus.mqh

1096 lines
83 KiB
MQL5

2025-09-22 09:09:20 -05:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| AccountStatus.mqh |
//| Copyright 2025, Niquel Mendoza. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
2025-11-10 09:33:30 -05:00
#property copyright "Copyright 2025, Niquel Mendoza."
2025-09-22 09:09:20 -05:00
2025-11-23 19:15:34 -05:00
#property link "https://www.mql5.com"
#property strict
2025-09-22 09:09:20 -05:00
#ifndef MQLARTICLES_RM_ACCOUNTSTATUS_MQH
2026-01-28 12:07:20 -05:00
#define MQLARTICLES_RM_ACCOUNTSTATUS_MQH
2026-01-31 19:44:40 -05:00
//+------------------------------------------------------------------+
//| |
2026-01-29 16:08:44 -05:00
//+------------------------------------------------------------------+
2026-01-31 19:44:40 -05:00
#include "RM_Functions.mqh"
2026-01-28 12:07:20 -05:00
#include <Math/Stat/Stat.mqh>
//+------------------------------------------------------------------+
//| Defines |
//+------------------------------------------------------------------+
//--- Events
2025-11-23 19:15:34 -05:00
#define ACCOUNT_STATUS_REG_FLAG_ON_OPEN_CLOSE_POSITION (8)
#define ACCOUNT_STATUS_REG_FLAG_ON_POSITION_MODIFY (16)
2026-01-31 19:44:40 -05:00
#define ACCOUNT_STATUS_REG_FLAG_ON_ORDER_ADD (32)
#define ACCOUNT_STATUS_REG_FLAG_ON_ORDER_UPDATE (64)
2025-11-23 19:15:34 -05:00
#define ACCOUNT_STATUS_REG_FLAG_ON_ORDER_DELETE (128)
2025-09-24 14:00:58 -05:00
2025-09-22 09:09:20 -05:00
#define ACCOUNT_STATUS_REG_FLAG_ON_NEW_PROFIT (256)
2025-09-24 14:00:58 -05:00
#define ACCOUNT_STATUS_REG_FLAG_ON_WITHDRAWAL_DEPOSIT (512)
2025-09-22 09:09:20 -05:00
#define ACCOUNT_STATUS_REG_FLAG_ON_INIT_NEW_POS (1024)
2025-09-24 14:00:58 -05:00
2025-09-22 09:09:20 -05:00
#define ACCOUNT_STATUS_REG_FLAG_ON_LOSS_PROFIT (2048)
2026-01-28 12:07:20 -05:00
2025-09-22 09:09:20 -05:00
2026-01-31 19:44:40 -05:00
//--- All events
2026-01-28 12:07:20 -05:00
#define ACCOUNT_STATUS_REG_FLAG_ALL (ACCOUNT_STATUS_REG_FLAG_ON_OPEN_CLOSE_POSITION | \
ACCOUNT_STATUS_REG_FLAG_ON_POSITION_MODIFY | \
ACCOUNT_STATUS_REG_FLAG_ON_ORDER_ADD | \
ACCOUNT_STATUS_REG_FLAG_ON_ORDER_UPDATE | \
ACCOUNT_STATUS_REG_FLAG_ON_ORDER_DELETE | \
ACCOUNT_STATUS_REG_FLAG_ON_NEW_PROFIT | \
ACCOUNT_STATUS_REG_FLAG_ON_WITHDRAWAL_DEPOSIT | \
ACCOUNT_STATUS_REG_FLAG_ON_INIT_NEW_POS | \
ACCOUNT_STATUS_REG_FLAG_ON_LOSS_PROFIT)
//---
#define ACCOUNTSTATUS_ON_POS_MODIFY_FLAG_CHANGE_TP 1
#define ACCOUNTSTATUS_ON_POS_MODIFY_FLAG_CHANGE_SL 2
#define ACCOUNTSTATUS_ON_POS_MODIFY_FLAG_CHANGE_TP_SL (ACCOUNTSTATUS_ON_POS_MODIFY_FLAG_CHANGE_TP|ACCOUNTSTATUS_ON_POS_MODIFY_FLAG_CHANGE_SL)
2025-09-22 09:09:20 -05:00
2025-11-23 08:04:37 -05:00
//---
2025-09-22 09:09:20 -05:00
#define ACCOUNT_STATUS_FLAG_FREE (1)
2025-09-24 14:00:58 -05:00
#define ACCOUNT_STATUS_FLAG_INIT (2)
2025-09-22 09:09:20 -05:00
//+------------------------------------------------------------------+
2025-11-23 08:04:37 -05:00
//| Global Variables |
2025-09-24 14:00:58 -05:00
2025-09-22 09:09:20 -05:00
//+------------------------------------------------------------------+
double account_status_curr_profit; // Profit en flotante - profit in float
bool account_status_positions_open; // Flag indicating if there are open positions in the account
//+------------------------------------------------------------------+
2025-09-24 14:00:58 -05:00
//| Class for account management |
2025-11-26 07:03:20 -05:00
//+------------------------------------------------------------------+
2025-09-22 09:09:20 -05:00
2026-01-28 13:39:14 -05:00
class CAccountStatus : public CAllClassEventsBasic
{
2025-09-22 09:09:20 -05:00
private:
2025-11-23 08:04:37 -05:00
2025-09-22 09:09:20 -05:00
//---
2026-01-29 10:49:55 -05:00
uint8_t m_flags;
2026-01-28 12:07:20 -05:00
//--- Event Subscribers Arrays
2026-01-28 13:39:14 -05:00
CAccountGestor* m_on_open_close_position[];
2026-01-28 17:12:28 -05:00
int m_on_open_close_position_size;
2026-01-28 12:07:20 -05:00
2025-09-22 09:09:20 -05:00
2026-01-28 12:07:20 -05:00
2026-02-14 17:00:45 -05:00
CAccountGestor* m_on_position_modify[];
int m_on_position_modify_size;
2026-01-28 12:07:20 -05:00
2026-01-28 17:12:28 -05:00
CAccountGestor* m_on_order_add[];
2025-09-22 09:09:20 -05:00
int m_on_order_add_size;
2026-01-28 12:07:20 -05:00
2026-01-31 19:44:40 -05:00
CAccountGestor* m_on_order_update[];
int m_on_order_update_size;
2026-01-28 12:07:20 -05:00
2026-01-28 17:12:28 -05:00
CAccountGestor* m_on_order_delete[];
2025-09-22 09:09:20 -05:00
int m_on_order_delete_size;
CAccountGestor* m_on_new_profit[];
2025-09-24 14:00:58 -05:00
int m_on_new_profit_size;
2026-02-14 17:00:45 -05:00
CAccountGestor* m_on_withdrawal_deposit[];
2025-11-23 08:04:37 -05:00
int m_on_withdrawal_deposit_size;
2026-01-31 19:44:40 -05:00
CAccountGestor* m_on_init_new_pos[];
2026-02-14 17:00:45 -05:00
2025-09-22 09:09:20 -05:00
int m_on_init_new_pos_size;
2025-09-24 14:00:58 -05:00
2025-09-22 09:09:20 -05:00
CAccountGestor* m_on_loss_profit[];
2026-01-31 19:44:40 -05:00
int m_on_loss_profit_size;
//---
2025-09-22 09:09:20 -05:00
2026-01-28 13:39:14 -05:00
CTicketsInfo* open_positions; // CTicketsInfo type object for efficient ticket management
2025-09-22 09:09:20 -05:00
2026-01-28 13:39:14 -05:00
//---
2025-11-23 08:04:37 -05:00
2026-01-31 19:44:40 -05:00
double account_daily_profit; // Account profit (adding EAs and user etc, total) daily
2025-11-23 08:04:37 -05:00
double account_weekly_profit; // Account profit (adding EAs and user etc, total) weekly
double account_monthly_profit; // Account profit (adding EAs and user etc, total) monthly
double account_gross_profit; // Account profit (adding EAs and user etc, total) total
2026-02-01 16:17:01 -05:00
2026-01-28 17:12:28 -05:00
//---
2025-09-22 09:09:20 -05:00
ROrder last_order_struct;
2026-01-31 19:44:40 -05:00
//--- Most recent structure of the opened or closed position
2026-02-14 17:00:45 -05:00
2026-01-31 19:44:40 -05:00
ROnOpenClosePosition last_struct;
// Variables that store a property of the last deal (when adding a deal, TRADE_TRANSACTION_DEAL_ADD)
ulong last_deal_ticket; // Ticket
2026-02-14 17:00:45 -05:00
2026-01-31 19:44:40 -05:00
ENUM_DEAL_TYPE last_deal_type; // Deal type
ulong last_deal_magic; // Magic
// Variable that stores the last symbol for specific events (TRADE_TRANSACTION_DEAL_ADD, TRADE_TRANSACTION_ORDER_DELETE)
string last_trans_symbol; // Symbol
//--- Function to update profits
void UpdateProfitInit();
void UpdateProfit(const double new_profit);
//---
void RemoveFromArrayFast(CAccountGestor* &array[], int &size, CAccountGestor* &ptr);
2026-01-28 13:39:14 -05:00
2026-01-28 12:07:20 -05:00
public:
CAccountStatus();
~CAccountStatus();
//--- Tipos (publcios para facil acceso.. recuerda NO modificar)
datetime last_day_time; // Opening time of the current daily candle
datetime last_weekly_time; // Opening time of the current weekly candle
datetime last_monthly_time; // Opening time of the current monthly candle
//--- Event Registration Method
void RegisterEvents(CAccountGestor* ptr, const int flags);
void UnregisterEvents(CAccountGestor* ptr, const int flags);
void UnregisterEvent(CAccountGestor* ptr, const int event);
void RegisterEvent(CAccountGestor* ptr, const int event);
//--- Getter
//- Tickets
__forceinline Position GetPosition(ulong ticket) { return open_positions.GetByTicket(ticket); } // Get Position by ticket
__forceinline int16_t GetPositionsTotal() const { return open_positions.Total(); } // Get total number of open positions
__forceinline bool TheTicketExists(const ulong ticket) const { return open_positions.Exists(ticket); } // Check if ticket exists in positions array
//- Profits
inline double AccountGrossProfit() const { return account_gross_profit; }
2026-01-28 13:39:14 -05:00
inline double AccountDailyProfit() const { return account_daily_profit; }
2026-01-28 17:12:28 -05:00
inline double AccountWeeklyProfit() const { return account_weekly_profit; }
inline double AccountMonthlyProfit() const { return account_monthly_profit; }
//- Esta iniciado ?
__forceinline bool IsInitialized() const { return (m_flags & ACCOUNT_STATUS_FLAG_INIT) != 0; }
//- Aun esta activo?? (util para deinciacion en destrucotr de herederos de CAccountGestor)
__forceinline bool IsActive() const { return (m_flags & ACCOUNT_STATUS_FLAG_FREE) == 0; }
//- Ultima transaccion
inline string LastTransctionSymbol() const { return last_trans_symbol; }
__forceinline ROnOpenClosePosition LastStructPosition() const { return last_struct; }
__forceinline Position LastPosition() const { return last_struct.position; }
//- Deals (solo en DEAL_TRANSACTION_ADD)
__forceinline ulong LastDealMagic() const { return last_deal_magic; }
__forceinline ulong LastDealTicket() const { return last_deal_ticket; }
//--- Events
void OnTradeTransactionEvent(const MqlTradeTransaction& trans); // Should be executed in OnTradeTransaction
void OnInitEvent(); // Should be executed in OnInit, at the end
void OnNewDay(const datetime curr_time) override final; // The function should be called every new day
void OnNewWeek(const datetime curr_time) override final; // The function should be called every new week
void OnNewMonth(const datetime curr_time) override final; // The function should be called every new month
//--- Info functions
void PrintLastOrder();
void PrintLastPosition();
//---
2026-01-28 13:39:14 -05:00
void Deinit(const int reason);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CAccountStatus::CAccountStatus(void)
:
account_daily_profit(0.00), account_weekly_profit(0.00), account_gross_profit(0.00), account_monthly_profit(0.00),
m_on_open_close_position_size(0), m_on_position_modify_size(0), m_on_order_add_size(0), m_on_order_update_size(0),
m_on_order_delete_size(0), m_on_new_profit_size(0), m_on_withdrawal_deposit_size(0), m_on_init_new_pos_size(0), m_on_loss_profit_size(0),
m_flags(0)
{
//---
account_status_curr_profit = 0.00;
account_status_positions_open = false;
//---
open_positions = new CTicketsInfo();
AddLogger(open_positions);
}
//+------------------------------------------------------------------+
2026-01-28 17:12:28 -05:00
//| Destructor |
//+------------------------------------------------------------------+
CAccountStatus::~CAccountStatus()
{
//Print("Entrando");
CleanItems("AccountStatus");
// CBasicEvents::Unregister(CAllClassEventsBasic *ptr,const uchar flags) no tiene sentido. dado que es global...
// Entonces es eliminar cuando se elimina... asi que dejemos que mql5 haga loq eu tenga que hacer
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CAccountStatus_Deinit(const int reason)
{
// WRapper para poder pasarlo
account_status.Deinit(reason);
}
//+------------------------------------------------------------------+
void CAccountStatus::Deinit(const int reason)
{
//--- Limpiamos todos los arrays
// SOlo ejecutamos en caso la clase solo tenga la benadera de incilzaicon
// En caso tenga otra bandera como free entonces no se ejeucta
2026-01-28 13:39:14 -05:00
if((m_flags & ACCOUNT_STATUS_FLAG_INIT) == ACCOUNT_STATUS_FLAG_INIT)
{
//---
m_on_open_close_position_size = ArrayResize(m_on_open_close_position, 0);
m_on_position_modify_size = ArrayResize(m_on_position_modify, 0);
m_on_order_add_size = ArrayResize(m_on_order_add, 0);
m_on_order_update_size = ArrayResize(m_on_order_update, 0);
m_on_order_delete_size = ArrayResize(m_on_order_delete, 0);
m_on_new_profit_size = ArrayResize(m_on_new_profit, 0);
m_on_withdrawal_deposit_size = ArrayResize(m_on_withdrawal_deposit, 0);
2026-01-28 12:07:20 -05:00
m_on_init_new_pos_size = ArrayResize(m_on_init_new_pos, 0);
2025-09-24 14:00:58 -05:00
2025-09-22 09:09:20 -05:00
m_on_loss_profit_size = ArrayResize(m_on_loss_profit, 0);
2026-02-14 17:00:45 -05:00
2025-09-22 09:09:20 -05:00
2026-01-29 10:49:55 -05:00
2025-09-22 09:09:20 -05:00
//---
m_flags |= ACCOUNT_STATUS_FLAG_FREE;
2025-09-24 14:00:58 -05:00
}
2025-09-22 09:09:20 -05:00
2026-02-14 17:00:45 -05:00
}
2025-09-22 09:09:20 -05:00
2026-01-31 19:44:40 -05:00
//+------------------------------------------------------------------+
//| Registro y De-Registro |
//+------------------------------------------------------------------+
2026-01-29 10:49:55 -05:00
2025-09-22 09:09:20 -05:00
void CAccountStatus::RegisterEvents(CAccountGestor* ptr, const int flags)
{
2025-09-24 14:00:58 -05:00
//---
2025-09-22 09:09:20 -05:00
2026-02-14 17:00:45 -05:00
if(!CheckPointer(ptr))
2025-09-22 09:09:20 -05:00
2026-01-29 10:49:55 -05:00
{
2025-09-22 09:09:20 -05:00
LogFatalError("Puntero invalido registrado", FUNCION_ACTUAL);
Remover();
2025-09-24 14:00:58 -05:00
2025-09-22 09:09:20 -05:00
return;
2026-01-29 10:49:55 -05:00
2025-09-22 09:09:20 -05:00
}
2026-01-28 12:07:20 -05:00
2026-01-31 19:44:40 -05:00
2026-01-28 12:07:20 -05:00
//---
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_OPEN_CLOSE_POSITION) != 0)
2026-01-29 10:49:55 -05:00
m_on_open_close_position[ArrayResize(m_on_open_close_position, (++m_on_open_close_position_size)) - 1] = ptr;
2025-09-24 14:00:58 -05:00
2026-01-29 10:49:55 -05:00
//---
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_POSITION_MODIFY) != 0)
2026-01-31 19:44:40 -05:00
2025-09-22 09:09:20 -05:00
m_on_position_modify[ArrayResize(m_on_position_modify, (++m_on_position_modify_size)) - 1] = ptr;
2026-01-28 12:07:20 -05:00
2025-09-24 14:00:58 -05:00
//---
2025-11-26 07:03:20 -05:00
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_ORDER_ADD) != 0)
2025-09-22 09:09:20 -05:00
m_on_order_add[ArrayResize(m_on_order_add, (++m_on_order_add_size)) - 1] = ptr;
//---
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_ORDER_UPDATE) != 0)
2026-01-28 12:07:20 -05:00
m_on_order_update[ArrayResize(m_on_order_update, (++m_on_order_update_size)) - 1] = ptr;
2026-01-29 10:49:55 -05:00
2025-09-22 09:09:20 -05:00
2025-09-24 14:00:58 -05:00
2025-09-22 09:09:20 -05:00
//---
2025-09-24 14:00:58 -05:00
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_ORDER_DELETE) != 0)
2025-09-22 09:09:20 -05:00
m_on_order_delete[ArrayResize(m_on_order_delete, (++m_on_order_delete_size)) - 1] = ptr;
2025-09-22 09:09:20 -05:00
//---
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_NEW_PROFIT) != 0)
2025-11-28 20:21:30 -05:00
m_on_new_profit[ArrayResize(m_on_new_profit, (++m_on_new_profit_size)) - 1] = ptr;
2026-02-14 17:00:45 -05:00
2025-09-22 09:09:20 -05:00
//---
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_WITHDRAWAL_DEPOSIT) != 0)
2025-11-23 08:04:37 -05:00
m_on_withdrawal_deposit[ArrayResize(m_on_withdrawal_deposit, (++m_on_withdrawal_deposit_size)) - 1] = ptr;
2025-09-22 09:09:20 -05:00
2025-11-28 20:21:30 -05:00
//---
2025-09-22 09:09:20 -05:00
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_INIT_NEW_POS) != 0)
m_on_init_new_pos[ArrayResize(m_on_init_new_pos, (++m_on_init_new_pos_size)) - 1] = ptr;
2026-01-28 12:07:20 -05:00
//---
2025-09-22 09:09:20 -05:00
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_LOSS_PROFIT) != 0)
m_on_loss_profit[ArrayResize(m_on_loss_profit, (++m_on_loss_profit_size)) - 1] = ptr;
}
2025-09-22 09:09:20 -05:00
2025-11-26 07:03:20 -05:00
//+------------------------------------------------------------------+
void CAccountStatus::RegisterEvent(CAccountGestor* ptr, const int event)
2025-09-22 09:09:20 -05:00
{
2025-11-26 07:03:20 -05:00
//---
if(!CheckPointer(ptr))
2025-09-22 09:09:20 -05:00
{
2026-01-28 12:07:20 -05:00
LogFatalError("Puntero invalido registrado", FUNCION_ACTUAL);
Remover();
2025-11-26 07:03:20 -05:00
return;
}
//---
if(event == ACCOUNT_STATUS_REG_FLAG_ON_OPEN_CLOSE_POSITION)
m_on_open_close_position[ArrayResize(m_on_open_close_position, (++m_on_open_close_position_size)) - 1] = ptr;
2025-09-22 09:09:20 -05:00
//---
else
if(event == ACCOUNT_STATUS_REG_FLAG_ON_POSITION_MODIFY)
m_on_position_modify[ArrayResize(m_on_position_modify, (++m_on_position_modify_size)) - 1] = ptr;
2025-11-28 20:21:30 -05:00
//---
2025-11-26 07:03:20 -05:00
2025-09-22 09:09:20 -05:00
else
if(event == ACCOUNT_STATUS_REG_FLAG_ON_ORDER_ADD)
2025-11-23 08:04:37 -05:00
m_on_order_add[ArrayResize(m_on_order_add, (++m_on_order_add_size)) - 1] = ptr;
//---
else
if(event == ACCOUNT_STATUS_REG_FLAG_ON_ORDER_UPDATE)
m_on_order_update[ArrayResize(m_on_order_update, (++m_on_order_update_size)) - 1] = ptr;
2025-09-22 09:09:20 -05:00
//---
else
2025-11-23 08:04:37 -05:00
if(event == ACCOUNT_STATUS_REG_FLAG_ON_ORDER_DELETE)
2025-09-22 09:09:20 -05:00
m_on_order_delete[ArrayResize(m_on_order_delete, (++m_on_order_delete_size)) - 1] = ptr;
2025-11-23 08:04:37 -05:00
2025-09-22 09:09:20 -05:00
2025-11-23 08:04:37 -05:00
//---
else
if(event == ACCOUNT_STATUS_REG_FLAG_ON_NEW_PROFIT)
2025-09-22 09:09:20 -05:00
m_on_new_profit[ArrayResize(m_on_new_profit, (++m_on_new_profit_size)) - 1] = ptr;
2025-11-23 19:15:34 -05:00
//---
2025-09-22 09:09:20 -05:00
else
2025-11-23 19:15:34 -05:00
if(event == ACCOUNT_STATUS_REG_FLAG_ON_WITHDRAWAL_DEPOSIT)
m_on_withdrawal_deposit[ArrayResize(m_on_withdrawal_deposit, (++m_on_withdrawal_deposit_size)) - 1] = ptr;
//---
else
2025-09-22 09:09:20 -05:00
if(event == ACCOUNT_STATUS_REG_FLAG_ON_INIT_NEW_POS)
2026-01-28 12:07:20 -05:00
m_on_init_new_pos[ArrayResize(m_on_init_new_pos, (++m_on_init_new_pos_size)) - 1] = ptr;
2025-11-23 19:15:34 -05:00
//---
else
2025-09-22 09:09:20 -05:00
2025-11-23 08:04:37 -05:00
if(event == ACCOUNT_STATUS_REG_FLAG_ON_LOSS_PROFIT)
2025-09-22 09:09:20 -05:00
2025-11-23 08:04:37 -05:00
m_on_loss_profit[ArrayResize(m_on_loss_profit, (++m_on_loss_profit_size)) - 1] = ptr;
}
2025-09-22 09:09:20 -05:00
2025-11-23 08:04:37 -05:00
2025-09-22 09:09:20 -05:00
//+------------------------------------------------------------------+
2025-11-23 08:04:37 -05:00
//| De-Suscribirse |
//+------------------------------------------------------------------+
2025-09-22 09:09:20 -05:00
2025-11-23 08:04:37 -05:00
void CAccountStatus::UnregisterEvents(CAccountGestor* ptr, const int flags)
2025-11-23 19:15:34 -05:00
{
if(!CheckPointer(ptr))
2025-09-22 09:09:20 -05:00
2025-11-23 19:15:34 -05:00
{
LogError("Invalid pointer for unregister", FUNCION_ACTUAL);
return;
}
//--- OnOpenClosePosition
2025-09-22 09:09:20 -05:00
2026-01-28 12:07:20 -05:00
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_OPEN_CLOSE_POSITION) != 0)
RemoveFromArrayFast(m_on_open_close_position, m_on_open_close_position_size, ptr);
2025-11-23 19:15:34 -05:00
//--- OnPositionModify
2025-09-22 09:09:20 -05:00
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_POSITION_MODIFY) != 0)
2025-11-23 08:04:37 -05:00
2025-09-22 09:09:20 -05:00
RemoveFromArrayFast(m_on_position_modify, m_on_position_modify_size, ptr);
2025-11-23 08:04:37 -05:00
2025-09-22 09:09:20 -05:00
//--- OnOrderAdd
2025-11-23 08:04:37 -05:00
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_ORDER_ADD) != 0)
RemoveFromArrayFast(m_on_order_add, m_on_order_add_size, ptr);
2025-09-22 09:09:20 -05:00
2025-11-23 08:04:37 -05:00
//--- OnOrderUpdate
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_ORDER_UPDATE) != 0)
2025-11-23 19:15:34 -05:00
RemoveFromArrayFast(m_on_order_update, m_on_order_update_size, ptr);
//--- OnOrderDelete
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_ORDER_DELETE) != 0)
RemoveFromArrayFast(m_on_order_delete, m_on_order_delete_size, ptr);
//--- OnNewProfit
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_NEW_PROFIT) != 0)
RemoveFromArrayFast(m_on_new_profit, m_on_new_profit_size, ptr);
//--- OnWithdrawalDeposit
2026-01-28 12:07:20 -05:00
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_WITHDRAWAL_DEPOSIT) != 0)
RemoveFromArrayFast(m_on_withdrawal_deposit, m_on_withdrawal_deposit_size, ptr);
2025-11-23 19:15:34 -05:00
//--- OnInitNewPos
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_INIT_NEW_POS) != 0)
2025-11-23 08:04:37 -05:00
RemoveFromArrayFast(m_on_init_new_pos, m_on_init_new_pos_size, ptr);
//--- OnLossProfit
if((flags & ACCOUNT_STATUS_REG_FLAG_ON_LOSS_PROFIT) != 0)
RemoveFromArrayFast(m_on_loss_profit, m_on_loss_profit_size, ptr);
}
//+------------------------------------------------------------------+
void CAccountStatus::UnregisterEvent(CAccountGestor* ptr, const int event)
2025-11-26 07:03:20 -05:00
{
2025-11-23 08:04:37 -05:00
if(!CheckPointer(ptr))
{
2025-11-26 07:03:20 -05:00
2025-11-23 08:04:37 -05:00
LogError("Invalid pointer for unregister", FUNCION_ACTUAL);
2025-09-22 09:09:20 -05:00
2025-11-23 08:04:37 -05:00
return;
}
2025-11-26 07:03:20 -05:00
2025-09-22 09:09:20 -05:00
2025-11-23 08:04:37 -05:00
//--- OnOpenClosePosition
2025-09-22 09:09:20 -05:00
if(event == ACCOUNT_STATUS_REG_FLAG_ON_OPEN_CLOSE_POSITION)
2025-11-23 08:04:37 -05:00
2026-03-02 12:39:28 -05:00
RemoveFromArrayFast(m_on_open_close_position, m_on_open_close_position_size, ptr);
2025-11-23 08:04:37 -05:00
2025-09-22 09:09:20 -05:00
2025-09-22 09:09:20 -05:00
//--- OnPositionModify
2025-11-23 08:04:37 -05:00
else
2025-09-22 09:09:20 -05:00
2025-11-23 08:04:37 -05:00
if(event == ACCOUNT_STATUS_REG_FLAG_ON_POSITION_MODIFY)
RemoveFromArrayFast(m_on_position_modify, m_on_position_modify_size, ptr);
2025-11-23 08:04:37 -05:00
2025-11-26 07:03:20 -05:00
//--- OnOrderAdd
2025-11-23 08:04:37 -05:00
else
2025-11-26 07:03:20 -05:00
if(event == ACCOUNT_STATUS_REG_FLAG_ON_ORDER_ADD)
2025-11-23 11:01:56 -05:00
RemoveFromArrayFast(m_on_order_add, m_on_order_add_size, ptr);
2025-11-26 07:03:20 -05:00
2025-11-23 08:04:37 -05:00
2025-11-26 07:03:20 -05:00
//--- OnOrderUpdate
2025-11-23 08:04:37 -05:00
else
2025-09-22 09:09:20 -05:00
if(event == ACCOUNT_STATUS_REG_FLAG_ON_ORDER_UPDATE)
2025-09-24 14:00:58 -05:00
2025-11-23 08:04:37 -05:00
RemoveFromArrayFast(m_on_order_update, m_on_order_update_size, ptr);
2025-09-22 09:09:20 -05:00
2025-09-24 14:00:58 -05:00
2025-09-22 09:09:20 -05:00
//--- OnOrderDelete
else
if(event == ACCOUNT_STATUS_REG_FLAG_ON_ORDER_DELETE)
2025-11-23 08:04:37 -05:00
RemoveFromArrayFast(m_on_order_delete, m_on_order_delete_size, ptr);
2025-09-22 09:09:20 -05:00
//--- OnNewProfit
2025-11-23 08:04:37 -05:00
else
2025-09-22 09:09:20 -05:00
2026-01-28 12:07:20 -05:00
if(event == ACCOUNT_STATUS_REG_FLAG_ON_NEW_PROFIT)
RemoveFromArrayFast(m_on_new_profit, m_on_new_profit_size, ptr);
2025-11-23 08:04:37 -05:00
//--- OnWithdrawalDeposit
else
if(event == ACCOUNT_STATUS_REG_FLAG_ON_WITHDRAWAL_DEPOSIT)
2025-11-26 07:03:20 -05:00
RemoveFromArrayFast(m_on_withdrawal_deposit, m_on_withdrawal_deposit_size, ptr);
//--- OnInitNewPos
2025-11-28 20:21:30 -05:00
else
2025-11-26 07:03:20 -05:00
if(event == ACCOUNT_STATUS_REG_FLAG_ON_INIT_NEW_POS)
2025-11-23 08:04:37 -05:00
RemoveFromArrayFast(m_on_init_new_pos, m_on_init_new_pos_size, ptr);
2025-11-26 07:03:20 -05:00
//--- OnLossProfit
2025-11-23 08:04:37 -05:00
else
if(event == ACCOUNT_STATUS_REG_FLAG_ON_LOSS_PROFIT)
RemoveFromArrayFast(m_on_loss_profit, m_on_loss_profit_size, ptr);
}
2025-11-26 07:03:20 -05:00
//+------------------------------------------------------------------+
2025-11-23 08:04:37 -05:00
void CAccountStatus::RemoveFromArrayFast(CAccountGestor* &array[], int &size, CAccountGestor* &ptr)
2025-11-26 07:03:20 -05:00
2025-11-23 08:04:37 -05:00
{
2025-11-26 07:03:20 -05:00
for(int i = 0; i < size; i++)
2025-11-23 08:04:37 -05:00
{
if(array[i] == ptr)
{
array[i] = array[size - 1];
ArrayResize(array, (--size));
//LogInfo(StringFormat("Event subscriber removed (size now: %d)", size), FUNCION_ACTUAL);
return;
2025-11-23 08:04:37 -05:00
2026-01-28 12:07:20 -05:00
}
}
2025-11-26 07:03:20 -05:00
//LogWarning("Pointer not found in event array", FUNCION_ACTUAL);
2025-11-23 08:04:37 -05:00
}
2025-11-26 07:03:20 -05:00
2025-11-23 08:04:37 -05:00
2025-11-26 07:03:20 -05:00
//+------------------------------------------------------------------+
//| Function that executes every new day |
//+------------------------------------------------------------------+
void CAccountStatus::OnNewDay(const datetime curr_time)
{
this.last_day_time = curr_time - (curr_time % 86400);
2025-11-23 08:04:37 -05:00
this.account_daily_profit = 0.0;
2025-11-26 07:03:20 -05:00
2025-09-22 09:09:20 -05:00
}
2025-11-23 08:04:37 -05:00
//+------------------------------------------------------------------+
//| Function that executes every new month |
2025-09-22 09:09:20 -05:00
2025-11-23 08:04:37 -05:00
//+------------------------------------------------------------------+
void CAccountStatus::OnNewMonth(const datetime curr_time)
2025-09-22 09:09:20 -05:00
2026-01-28 12:07:20 -05:00
{
if((m_flags & ACCOUNT_STATUS_FLAG_INIT) == 0)
2025-11-26 07:03:20 -05:00
{
2025-11-23 08:04:37 -05:00
LogError("Account status no INICIADO", FUNCION_ACTUAL);
2025-11-26 07:03:20 -05:00
Remover();
2025-11-23 08:04:37 -05:00
return;
}
2025-09-22 09:09:20 -05:00
this.last_monthly_time = CTimeUtils::StartOfMonth(curr_time);
2025-11-23 08:04:37 -05:00
this.account_monthly_profit = 0.0;
}
//+------------------------------------------------------------------+
//| Function that executes weekly |
//+------------------------------------------------------------------+
2025-09-22 09:09:20 -05:00
void CAccountStatus::OnNewWeek(const datetime curr_time)
2025-11-23 08:04:37 -05:00
2025-11-28 20:21:30 -05:00
{
this.last_weekly_time = CTimeUtils::StartOfWeek(curr_time, true);
2025-11-23 19:15:34 -05:00
2025-09-22 09:09:20 -05:00
this.account_weekly_profit = 0.0;
2025-11-23 08:04:37 -05:00
}
//+------------------------------------------------------------------+
2025-11-23 19:15:34 -05:00
2025-11-23 08:04:37 -05:00
//| Function that executes in OnInit |
2025-09-22 09:09:20 -05:00
2025-11-23 08:04:37 -05:00
//+------------------------------------------------------------------+
void CAccountStatus::OnInitEvent()
{
2025-11-23 19:15:34 -05:00
//---
2025-11-23 08:04:37 -05:00
if((m_flags & ACCOUNT_STATUS_FLAG_INIT) != 0)
2026-01-28 12:07:20 -05:00
2025-11-23 19:15:34 -05:00
{
2026-01-28 12:07:20 -05:00
LogWarning("Clase ya iniciada", FUNCION_ACTUAL);
2025-09-22 09:09:20 -05:00
2025-11-23 08:04:37 -05:00
return;
}
2025-09-22 09:09:20 -05:00
2025-11-23 08:04:37 -05:00
2025-09-22 09:09:20 -05:00
//---
2025-11-23 08:04:37 -05:00
const datetime curr_time = TimeCurrent();
2025-09-22 09:09:20 -05:00
2025-11-23 08:04:37 -05:00
//--- Initialize the profit collection variables
this.last_day_time = curr_time - (curr_time % 86400);
this.last_weekly_time = CTimeUtils::StartOfWeek(curr_time, true);
this.last_monthly_time = CTimeUtils::StartOfMonth(curr_time);
this.m_flags |= ACCOUNT_STATUS_FLAG_INIT;
//--- Registramos para que reciba el evento
CBasicEvents::Register(&this, BASICEVENT_REG_ALL_FLAG);
//--- Initialize the managers with the new profit
UpdateProfitInit();
//---
ROnOpenClosePosition profit;
profit.account_balance = AccountInfoDouble(ACCOUNT_BALANCE);
profit.account_profit_diario = this.account_daily_profit;
2025-09-22 09:09:20 -05:00
profit.account_profit_mensual = this.account_monthly_profit;
2025-11-26 07:03:20 -05:00
profit.account_profit_semanal = this.account_weekly_profit;
2026-01-28 17:12:28 -05:00
profit.account_profit_total = this.account_gross_profit;
2025-09-22 09:09:20 -05:00
2025-11-23 08:04:37 -05:00
//--- Notify OnNewProfit subscribers
2025-09-22 09:09:20 -05:00
2025-11-26 07:03:20 -05:00
for(int i = 0; i < m_on_new_profit_size; i++)
2026-01-28 12:07:20 -05:00
m_on_new_profit[i].OnNewProfit(profit, curr_time);
2025-09-22 09:09:20 -05:00