2026-09-12 19:41:52 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| 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"
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | namespace TSN
|
| | | {
|
| | | //+------------------------------------------------------------------+
|
| | | //| Manager class to work with different poses |
|
| | | //+------------------------------------------------------------------+
|
| | | // NOTA:
|
| | | // Esta clase no recibe EVENTOS de ningun tipo.. solo se heredo de CAllClassEventsBasic, para propagar logs..
|
| | | // Y el estado global
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | // 1. Solo peude tener 1 tipo de perdida en el manager no mas..
|
| | | // osea solo peudes tener un MDL en el manager no dos limites
|
| | | // 2. tamaños fijos de arrays para evitar el overhead de una rray dinamico
|
| | | // como el 1# punto se cumple (maximo podemos tener X puntos donde x se sabe en compilacion) por lo que podemos
|
| | | // tener ya el array al maximo tamaño que podra tener este..
|
| | | // 3. Una vez que ya se agrega NO se peude quitar
|
| | |
|
| | | //---
|
| | | class CLossProfitManager : public CAllClassEventsBasic
|
| | | {
|
| | | private:
|
| | | //---
|
| | | CLossProfit* empty_obj;
|
| | |
|
| | | //---
|
| | | CLossProfit* m_losses_profits[LOSS_PROFIT_COUNT]; // todos los punteros de losses profits
|
| | | bool m_is_add[LOSS_PROFIT_COUNT]; // Si esta añadido (solo uno de x tipo)
|
| | |
|
| | | //--- Indices validos
|
| | | // en este array se ubican todos los indices (referente a m_lossesesporifts)
|
| | | // que son validos (esto para evitar chekear con NULL)
|
| | | // osea es una lista de indices en la cual estan todos los indices validos
|
| | | int m_valid_indexes[LOSS_PROFIT_COUNT];
|
| | | int m_valid_indexes_size;
|
| | |
|
| | | //--- Optimizaicon extra
|
| | | // Tambien para iterar rapido sobre profit\losses
|
| | | // tenemos arrays fijos
|
| | | //-
|
| | | CLossProfit* m_profits[LOSS_PROFIT_COUNT_MAXTYPE];
|
| | | int m_profits_size;
|
| | | int m_last_idx_profit_sup;
|
| | |
|
| | | //-
|
| | | CLossProfit* m_losses[LOSS_PROFIT_COUNT_MAXTYPE];
|
| | | int m_losses_size;
|
| | | int m_last_idx_loss_sup;
|
| | |
|
| | |
|
| | | public:
|
| | | ~CLossProfitManager();
|
| | | CLossProfitManager();
|
| | |
|
| | | //---
|
| | | __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;
|
| | |
|
| | | //---
|
| | | CLossProfit* operator[](const ENUM_TYPE_LOSS_PROFIT type) const;
|
| | | CLossProfit* operator[](const int index) const { return m_losses_profits[index]; }
|
| | |
|
| | | //--- Objeto vacio
|
| | | static CLossLossGmlpo<CLossProfitMoney<CLossProfit>> EMPTY_OBJ;
|
| | | };
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | CLossLossGmlpo<CLossProfitMoney<CLossProfit>> CLossProfitManager::EMPTY_OBJ(true, NULL);
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Contructor y Destructor |
|
| | | //+------------------------------------------------------------------+
|
| | | CLossProfitManager::CLossProfitManager()
|
| | | : m_valid_indexes_size(0), m_profits_size(0), m_losses_size(0), m_last_idx_profit_sup(-1), m_last_idx_loss_sup(-1)
|
| | | {
|
| | | //---
|
| | | for(int i = 0; i < LOSS_PROFIT_COUNT; i++)
|
| | | m_losses_profits[i] = NULL;
|
| | |
|
| | | //---
|
| | | ArrayInitialize(m_is_add, false);
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | CLossProfitManager::~CLossProfitManager(void)
|
| | | {
|
| | | #ifdef MORE_INFO_LOSS_PROFIT_DEFINE
|
| | | FastLog(FUNCION_ACTUAL, INFO_TEXT, "Eliminado en CLossProfitManager");
|
| | | #endif
|
| | | 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 = 0;
|
| | | m_profits_size = 0;
|
| | | m_losses_size = 0;
|
| | |
|
| | | //---
|
| | | CleanItems("CLossProfitManager"); // Delete pointers (m_losses_profits (m_loggers)
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| operator[] |
|
| | | //+------------------------------------------------------------------+
|
| | | CLossProfit* CLossProfitManager::operator[](const ENUM_TYPE_LOSS_PROFIT type) const
|
| | | {
|
| | | 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)
|
| | | {
|
| | | //---
|
| | | if(!CheckPointer(new_loss_profit))
|
| | | {
|
| | | 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;
|
| | | }
|
| | |
|
| | | //---
|
| | | m_valid_indexes[m_valid_indexes_size++] = idx;
|
| | |
|
| | | //---
|
| | | const ENUM_LOSS_PROFIT typelp = new_loss_profit.TypeLossProfit();
|
| | | if(typelp == T_LOSS)
|
| | | {
|
| | | m_losses[m_losses_size++] = new_loss_profit;
|
| | | }
|
| | | else
|
| | | if(typelp == T_PROFIT)
|
| | | {
|
| | | m_profits[m_profits_size++] = new_loss_profit;
|
| | | }
|
| | |
|
| | | //---
|
| | | m_is_add[idx] = true;
|
| | | m_losses_profits[idx] = new_loss_profit;
|
| | |
|
| | | //---
|
| | | AddLogger(new_loss_profit); // Si son descendientes de CAllBasicClass
|
| | | return true;
|
| | | }
|
| | |
|
| | | //---
|
| | | /*
|
| | | ADVERTENCIA:
|
| | | - Al momento de añ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
|
| | | //+------------------------------------------------------------------+
|