//+------------------------------------------------------------------+ //| 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 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 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 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 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 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 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 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 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