MQLArticles/RM/LossProfit/Basic/Classes.mqh
Nique_372 7e5ff17b47 Modify - Fixed
- Ahora todas las maximas gancnais y perdidias filtrar por numero magico (asi que ya no es "global")
2026-02-19 11:31:44 -05:00

298 行
9.1 KiB
MQL5

//+------------------------------------------------------------------+
//| Classes.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_BASIC_CLASESS_MQH
#define MQLARTICLES_RM_LOSSPROFIT_BASIC_CLASESS_MQH
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
#include "..\\Base.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
/*
## Notas:
Stricto:
-True: "Se tiene que recuperar todo, incluso lo perdido"
TPadre:
Puede ser money o percentage (dado que implemnta el tipo de calculo)
*/
//+------------------------------------------------------------------+
//| Clase base para los profits |
//+------------------------------------------------------------------+
template <typename TPadre>
class CLossProfitBaseProfit : public TPadre
{
protected:
bool m_strict;
//--- Aqui para impedir instanciacion
CLossProfitBaseProfit(const int type, const bool im_empty, const bool act_hook, CRiskManagemetBase* _risk_pointer);
public:
// Solo eliminamos si no es global..
~CLossProfitBaseProfit(void) { if(!m_empty_flag && account_status.IsActive()) account_status.UnregisterEvent(&this, ACCOUNT_STATUS_REG_FLAG_ON_LOSS_PROFIT); }
//---
void Init(double _percentage, ENUM_APPLIED_PERCENTAGES _applied, bool _is_strict, FuncionLossProfitSuperate fsup);
//---
void OnLossProfit(const double p) override;
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template <typename TPadre> CLossProfitBaseProfit::CLossProfitBaseProfit(const int type, const bool im_empty, const bool act_hook, CRiskManagemetBase* _risk_pointer)
: TPadre(type, im_empty, act_hook, _risk_pointer), m_strict(true)
{
//---
if(im_empty)
return;
//--- Requerimos el denevto OnLossPrfoit para capturar el profit
account_status.RegisterEvent(&this, ACCOUNT_STATUS_REG_FLAG_ON_LOSS_PROFIT);
//---
switch(type - 6)
{
case 0:
m_name = "Maxium daily profit";
break;
case 1:
m_name = "Maxium weekly profit";
break;
case 2:
m_name = "Maxium monthly profit";
break;
case 3:
m_name = "Maxium profit";
break;
case 4:
m_name = "Maxium profit BAJO";
break;
default:
LogFatalError("Tipo de maximum profit invalido", FUNCION_ACTUAL);
Remover();
break;
}
//---
m_type_loss_or_profit = T_PROFIT;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template <typename TPadre>
void CLossProfitBaseProfit::OnLossProfit(const double p)
{
//---
if(m_magic_number != NOT_MAGIC_NUMBER && m_magic_number != account_status.LastDealMagic())
return;
//--- Perdida
if(p < 0.00)
{
const double nv = m_lp.value - p;
m_lp.value = (m_strict && nv > m_saved_value) ? nv : m_saved_value;
}
//--- Profit
else
if(p > 0.00)
{
m_lp.value -= p; // Si es negativo es por que ya se supero y se gano demas y por mucho
}
//---
#ifdef MORE_INFO_LOSS_PROFIT_DEFINE
LogInfo(StringFormat("Risk value '%s' updated: %.2f", m_name, m_lp.value), FUNCION_ACTUAL);
#endif
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template <typename TPadre>
void CLossProfitBaseProfit::Init(double _percentage, ENUM_APPLIED_PERCENTAGES _applied, bool _is_strict, FuncionLossProfitSuperate fsup)
{
//---
if(m_empty_flag)
return;
//---
if(_percentage < 0.0000000001)
{
LogCriticalError(StringFormat("Invalid calc value %.2f ,must be greater than 0.00", _percentage), FUNCION_ACTUAL);
m_empty_flag = true;
return;
}
//---
m_lp.calculation_value = _percentage;
m_lp.percentage_applied_to = _applied;
m_lp.value = 0.00;
m_initial_calc_value = _percentage;
//---
m_strict = _is_strict;
//---
m_funcion_check_sup = fsup;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Clase base para los profits |
//+------------------------------------------------------------------+
template <typename TPadre>
class CLossProfitBaseLoss : public TPadre
{
protected:
bool m_strict;
//--- Aqui para impedir instanciacion
CLossProfitBaseLoss(const int type, const bool im_empty, const bool act_hook, CRiskManagemetBase* _risk_pointer);
public:
~CLossProfitBaseLoss(void) { if(!m_empty_flag && account_status.IsActive()) account_status.UnregisterEvent(&this, ACCOUNT_STATUS_REG_FLAG_ON_LOSS_PROFIT); }
//---
void Init(double _percentage, ENUM_APPLIED_PERCENTAGES _applied, bool _is_strict, FuncionLossProfitSuperate fsup);
//---
void OnLossProfit(const double p) override;
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template <typename TPadre> CLossProfitBaseLoss::CLossProfitBaseLoss(const int type, const bool im_empty, const bool act_hook, CRiskManagemetBase* _risk_pointer)
: TPadre(type, im_empty, act_hook, _risk_pointer), m_strict(true)
{
//---
if(im_empty)
return;
//--- Requerimos el denevto OnLossPrfoit para capturar el profit
if(type != LOSSPROFIT_TYPE_GMLPO) // Solo si no es GMLPO
account_status.RegisterEvent(&this, ACCOUNT_STATUS_REG_FLAG_ON_LOSS_PROFIT);
//--- Tipo
switch(type)
{
case 0:
m_name = "GMLPO";
break;
case 1:
m_name = "Maxium daily loss";
break;
case 2:
m_name = "Maxium weekly loss";
break;
case 3:
m_name = "Maxium monthly loss";
break;
case 4:
m_name = "Maxium loss";
break;
case 5:
m_name = "Maxium loss PICO";
break;
default:
LogFatalError("Tipo de maximum loss invalido", FUNCION_ACTUAL);
Remover();
break;
}
//---
m_type_loss_or_profit = (type == LOSSPROFIT_TYPE_GMLPO) ? T_GMLPO : T_LOSS;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template <typename TPadre>
void CLossProfitBaseLoss::OnLossProfit(const double p)
{
//---
if(m_magic_number != NOT_MAGIC_NUMBER && m_magic_number != account_status.LastDealMagic())
return;
//--- Perdida
if(p < 0.00)
{
m_lp.value += p; // Si es negativo es por que se supero y por mucho
}
//--- Profit
else
if(p > 0.00)
{
const double nv = m_lp.value + p;
m_lp.value = (!m_strict && nv > m_saved_value) ? nv : m_saved_value;
}
//---
#ifdef MORE_INFO_LOSS_PROFIT_DEFINE
LogInfo(StringFormat("Risk value '%s' updated: %.2f", m_name, m_lp.value), FUNCION_ACTUAL);
#endif
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template <typename TPadre>
void CLossProfitBaseLoss::Init(double _percentage, ENUM_APPLIED_PERCENTAGES _applied, bool _is_strict, FuncionLossProfitSuperate fsup)
{
//---
if(m_empty_flag)
return;
//---
if(_percentage < 0.0000000001)
{
LogCriticalError(StringFormat("Invalid calc value %.2f ,must be greater than 0.00", _percentage), FUNCION_ACTUAL);
m_empty_flag = true;
return;
}
//---
m_lp.calculation_value = _percentage;
m_lp.percentage_applied_to = _applied;
m_lp.value = 0.00;
m_initial_calc_value = _percentage;
//---
m_strict = _is_strict;
//---
m_funcion_check_sup = fsup;
}
//+------------------------------------------------------------------+
#endif // MQLARTICLES_RM_LOSSPROFIT_BASIC_CLASESS_MQH