MQLArticles/RM/LossProfit/Manager.mqh

326 Zeilen
22 KiB
MQL5

2026-01-28 12:07:14 -05:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| Manager.mqh |
//| Copyright 2025, Niquel Mendoza. |
//| https://www.mql5.com/es/users/nique_372 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Niquel Mendoza."
#property link "https://www.mql5.com/es/users/nique_372"
#property strict
#ifndef MQLARTICLES_RM_LOSSPROFIT_MANAGERS_MQH
#define MQLARTICLES_RM_LOSSPROFIT_MANAGERS_MQH
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
#include "Basic\\MaxLosses.mqh"
#include "Basic\\MaxProfits.mqh"
//+------------------------------------------------------------------+
//| Manager class to work with different poses |
//+------------------------------------------------------------------+
2026-01-29 08:19:03 -05:00
// NOTA:
2026-02-01 16:17:01 -05:00
// Esta clase no recibe EVENTOS de ningun tipo.. solo se heredo de CAllClassEventsBasic, para propagar logs..
2026-01-29 08:19:03 -05:00
// Y el estado global
//---
class CLossProfitManager : public CAllClassEventsBasic
2026-01-28 12:07:14 -05:00
{
private:
//---
CLossProfit* empty_obj;
//---
CLossProfit* m_losses_profits[LOSS_PROFIT_COUNT];
bool m_is_add[LOSS_PROFIT_COUNT]; // Si esta a<EFBFBD>adido
//--- Indices validos
int m_valid_indexes[];
int m_valid_indexes_size;
//---
CLossProfit* m_profits[];
int m_profits_size;
int m_last_idx_profit_sup;
//---
CLossProfit* m_losses[];
int m_losses_size;
int m_last_idx_loss_sup;
public:
~CLossProfitManager();
2026-01-31 19:44:40 -05:00
CLossProfitManager();
2026-01-28 12:07:14 -05:00
//---
__forceinline int SizeValids() const { return m_valid_indexes_size; }
__forceinline int GetIndexValid(const int index) { return m_valid_indexes[index]; }
//---
inline bool IsAdd(const ENUM_TYPE_LOSS_PROFIT type) const { return m_is_add[type]; }
//--- Clear
void Clear();
//--- Add
bool Add(CLossProfit * new_loss_profit); // Add CLossProfit
//--- Is Superated
// Index
__forceinline int GetLastIndexSuperatedProfit() const { return m_last_idx_profit_sup; }
__forceinline int GetLastIndexSuperatedLoss() const { return m_last_idx_loss_sup; }
// Ptr
const CLossProfit* const GetLastLossSuperated() const { return m_losses[m_last_idx_loss_sup]; }
const CLossProfit* const GetLastProfitSuperated() const { return m_profits[m_last_idx_profit_sup]; }
// Type
__forceinline int GetLastLossSuperatedType() const { return m_losses[m_last_idx_loss_sup].Type(); }
__forceinline int GetLastProfitSuperatedType() const { return m_profits[m_last_idx_profit_sup].Type(); }
// Main
bool MaxProfitIsSuperated() const;
bool MaxLossIsSuperated() const;
//--- On
void SetNewChossenBalanceForDynamicsAndSet(double _chosen_balance, bool update);
void SetValues(); // Setear valores
void SetValuesAndDynamic(); // Valores y dinamicos
void CheckDynamic();
//---
void Summary() const;
//---
2026-03-05 12:10:29 -05:00
CLossProfit* operator[](const ENUM_TYPE_LOSS_PROFIT type) const;
CLossProfit* operator[](const int index) const { return m_losses_profits[index]; }
2026-01-28 12:07:14 -05:00
};
//+------------------------------------------------------------------+
//| Contructor y Destructor |
//+------------------------------------------------------------------+
2026-01-31 19:44:40 -05:00
CLossProfitManager::CLossProfitManager()
2026-01-28 12:07:14 -05:00
{
//---
m_valid_indexes_size = ArrayResize(m_valid_indexes, 0);
m_profits_size = ArrayResize(m_profits, 0);
m_losses_size = ArrayResize(m_losses, 0);
m_last_idx_profit_sup = -1;
m_last_idx_loss_sup = -1;
//---
2026-01-31 19:44:40 -05:00
empty_obj = new CLossLossGmlpo<CLossProfitMoney<CLossProfit>>(true, NULL);
2026-01-28 12:07:14 -05:00
for(int i = 0; i < LOSS_PROFIT_COUNT; i++)
{
m_losses_profits[i] = NULL;
m_is_add[i] = false;
}
}
//+------------------------------------------------------------------+
CLossProfitManager::~CLossProfitManager(void)
{
2026-02-01 16:17:01 -05:00
#ifdef MORE_INFO_LOSS_PROFIT_DEFINE
FastLog(FUNCION_ACTUAL, INFO_TEXT, "Eliminado en CLossProfitManager");
#endif
2026-01-28 12:07:14 -05:00
delete empty_obj;
Clear(); // Eliminamos todos los punteros
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CLossProfitManager::Summary(void) const
{
Print("------------");
Print("Number of losses to revise: ", m_losses_size);
Print("Number of profits to revise: ", m_profits_size);
Print("Total losses and profits: ", SizeValids());
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CLossProfitManager::MaxProfitIsSuperated(void) const
{
for(int i = 0; i < m_profits_size; i++)
{
if(m_profits[i].IsSuperated())
{
((CLossProfitManager*)&this).m_last_idx_profit_sup = i;
return true;
}
}
return false;
}
//+------------------------------------------------------------------+
bool CLossProfitManager::MaxLossIsSuperated(void) const
{
for(int i = 0; i < m_losses_size; i++)
{
if(m_losses[i].IsSuperated())
{
((CLossProfitManager*)&this).m_last_idx_loss_sup = i;
return true;
}
}
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CLossProfitManager::SetValues()
{
for(int i = 0; i < m_valid_indexes_size; i++)
{
const int k = m_valid_indexes[i];
m_losses_profits[k].Set(); // Setea el valor
m_losses_profits[k].SetSavedValue();
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CLossProfitManager::SetValuesAndDynamic()
{
for(int i = 0; i < m_valid_indexes_size; i++)
{
const int key = m_valid_indexes[i];
m_losses_profits[key].Set(); // Setea el valor
if(m_losses_profits[key].IsDynamicMode()) // Check si es dinamico
m_losses_profits[key].CheckAndModifyThePercentage(); // Modificamos
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CLossProfitManager::SetNewChossenBalanceForDynamicsAndSet(double _chosen_balance, bool update)
{
for(int i = 0; i < m_valid_indexes_size; i++)
{
const int key = m_valid_indexes[i];
m_losses_profits[key].Set();
if(m_losses_profits[key].IsDynamicMode()) // Check si es dinamico
{
m_losses_profits[key].SetDynamic(_chosen_balance); // Modificamos
if(update)
m_losses_profits[key].CheckAndModifyThePercentage();
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CLossProfitManager::CheckDynamic(void)
{
for(int i = 0; i < m_valid_indexes_size; i++)
{
const int key = m_valid_indexes[i];
if(m_losses_profits[key].IsDynamicMode()) // Check si es dinamico
m_losses_profits[key].CheckAndModifyThePercentage(); // Modificamos
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CLossProfitManager::Clear(void)
{
//---
ArrayInitialize(m_is_add, false);
//---
m_valid_indexes_size = ArrayResize(m_valid_indexes, 0);
m_profits_size = ArrayResize(m_profits, 0);
m_losses_size = ArrayResize(m_losses, 0);
//---
2026-02-01 16:17:01 -05:00
CleanItems("CLossProfitManager"); // Delete pointers (m_losses_profits (m_loggers)
2026-01-28 12:07:14 -05:00
}
//+------------------------------------------------------------------+
//| operator[] |
//+------------------------------------------------------------------+
2026-03-05 12:10:29 -05:00
CLossProfit* CLossProfitManager::operator[](const ENUM_TYPE_LOSS_PROFIT type) const
2026-01-28 12:07:14 -05:00
{
return m_is_add[type] ? m_losses_profits[type] : empty_obj;
}
//+------------------------------------------------------------------+
//| Function that is executed every time a new item is added |
//+------------------------------------------------------------------+
// check_duplicate: No tiene efecto
bool CLossProfitManager::Add(CLossProfit * new_loss_profit)
{
//---
2026-01-28 13:02:22 -05:00
if(!CheckPointer(new_loss_profit))
2026-01-28 12:07:14 -05:00
{
LogFatalError("The pointer to CLossProfit* is invalid", FUNCION_ACTUAL);
Remover();
return false;
}
//---
const int idx = new_loss_profit.Type();
if(m_is_add[idx])
{
LogWarning(StringFormat("The loss or gain %s has already been added, it will not be added.", new_loss_profit.Name()), FUNCION_ACTUAL);
return false;
}
//---
ArrayResize(m_valid_indexes, m_valid_indexes_size + 1);
m_valid_indexes[m_valid_indexes_size] = idx;
m_valid_indexes_size++;
//---
if(new_loss_profit.TypeLossProfit() == T_LOSS)
{
ArrayResize(m_losses, m_losses_size + 1);
m_losses[m_losses_size] = new_loss_profit;
m_losses_size++;
}
else
if(new_loss_profit.TypeLossProfit() == T_PROFIT)
{
ArrayResize(m_profits, m_profits_size + 1);
m_profits[m_profits_size] = new_loss_profit;
m_profits_size++;
}
//---
m_is_add[idx] = true;
m_losses_profits[idx] = new_loss_profit;
//---
2026-01-31 19:44:40 -05:00
AddLogger(new_loss_profit); // Si son descendientes de CAllBasicClass
2026-01-28 12:07:14 -05:00
return true;
}
//---
/*
ADVERTENCIA:
- Al momento de a<EFBFBD>adir items a esta clase, esta si son dinamicos las eliminara cuidado.
- El unico que maneja esta clase es CRiskManagement, por lo que no se puede remover elementos
WARNINGS:
- When adding items to this class, if they are dynamic, be careful.
- The only one that handles this class is CRiskManagement, so elements cannot be removed.
*/
#endif
//+------------------------------------------------------------------+