2026-09-12 19:41:52 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| MaxProfits.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_MAXPROFITS_MQH
|
| | | #define MQLARTICLES_RM_LOSSPROFIT_BASIC_MAXPROFITS_MQH
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Include |
|
| | | //+------------------------------------------------------------------+
|
| | | #include "Classes.mqh"
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | namespace TSN
|
| | | {
|
| | | //+------------------------------------------------------------------+
|
| | | //| MDP |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TPadre>
|
| | | class CLossProfitMaxDaily : public CLossProfitBaseProfit<TPadre>
|
| | | {
|
| | | public:
|
| | | CLossProfitMaxDaily(bool empty, CRiskManagemetBase* risk_pointer);
|
| | | ~CLossProfitMaxDaily(void) { if(!m_empty_flag && CBasicEvents::IsActive()) CBasicEvents::UnregisterEvent(&this, BASICEVENT_REG_FLAG_ON_NEW_DAY); }
|
| | |
|
| | | //---
|
| | | void OnNewDay(const datetime curr_time) override final;
|
| | | };
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TPadre> CLossProfitMaxDaily::CLossProfitMaxDaily(bool empty, CRiskManagemetBase *risk_pointer)
|
| | | : CLossProfitBaseProfit<TPadre>(LOSSPROFIT_TYPE_MDP, empty, false, risk_pointer)
|
| | | {
|
| | | if(empty)
|
| | | return;
|
| | | CBasicEvents::RegisterEvent(&this, BASICEVENT_REG_FLAG_ON_NEW_DAY); // Registramos para recibir OnNewDay
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TPadre>
|
| | | void CLossProfitMaxDaily::OnNewDay(const datetime curr_time)
|
| | | {
|
| | | if(Set())
|
| | | m_saved_value = m_lp.value;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| MWP |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TPadre>
|
| | | class CLossProfitMaxWeekly : public CLossProfitBaseProfit<TPadre>
|
| | | {
|
| | | public:
|
| | | CLossProfitMaxWeekly(bool empty, CRiskManagemetBase* risk_pointer);
|
| | | ~CLossProfitMaxWeekly(void) { if(!m_empty_flag && CBasicEvents::IsActive()) CBasicEvents::UnregisterEvent(&this, BASICEVENT_REG_FLAG_ON_NEW_WEEK); }
|
| | |
|
| | | //---
|
| | | void OnNewWeek(const datetime curr_time) override final;
|
| | | };
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TPadre> CLossProfitMaxWeekly::CLossProfitMaxWeekly(bool empty, CRiskManagemetBase *risk_pointer)
|
| | | : CLossProfitBaseProfit<TPadre>(LOSSPROFIT_TYPE_MWL, empty, false, risk_pointer)
|
| | | {
|
| | | if(empty)
|
| | | return;
|
| | | CBasicEvents::RegisterEvent(&this, BASICEVENT_REG_FLAG_ON_NEW_WEEK); // Registramos para recibir OnNewWeek
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TPadre>
|
| | | void CLossProfitMaxWeekly::OnNewWeek(const datetime curr_time)
|
| | | {
|
| | | if(Set())
|
| | | m_saved_value = m_lp.value;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | |
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| MMP |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TPadre>
|
| | | class CLossProfitMaxMon : public CLossProfitBaseProfit<TPadre>
|
| | | {
|
| | | public:
|
| | | CLossProfitMaxMon(bool empty, CRiskManagemetBase* risk_pointer);
|
| | | ~CLossProfitMaxMon(void) { if(!m_empty_flag && CBasicEvents::IsActive()) CBasicEvents::UnregisterEvent(&this, BASICEVENT_REG_FLAG_ON_NEW_MON); }
|
| | |
|
| | | //---
|
| | | void OnNewMonth(const datetime curr_time) override final;
|
| | | };
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TPadre> CLossProfitMaxMon::CLossProfitMaxMon(bool empty, CRiskManagemetBase *risk_pointer)
|
| | | : CLossProfitBaseProfit<TPadre>(LOSSPROFIT_TYPE_MMP, empty, false, risk_pointer)
|
| | | {
|
| | | if(empty)
|
| | | return;
|
| | | CBasicEvents::RegisterEvent(&this, BASICEVENT_REG_FLAG_ON_NEW_MON); // Registramos para recibir OnNewMonth
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TPadre>
|
| | | void CLossProfitMaxMon::OnNewMonth(const datetime curr_time)
|
| | | {
|
| | | if(Set())
|
| | | m_saved_value = m_lp.value;
|
| | | }
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| MP - Maximum Profit (sin reseteo temporal) |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TPadre>
|
| | | class CLossProfitMax : public CLossProfitBaseProfit<TPadre>
|
| | | {
|
| | | public:
|
| | | CLossProfitMax(bool empty, CRiskManagemetBase* risk_pointer);
|
| | | ~CLossProfitMax(void) {}
|
| | | };
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TPadre> CLossProfitMax::CLossProfitMax(bool empty, CRiskManagemetBase *risk_pointer)
|
| | | : CLossProfitBaseProfit<TPadre>(LOSSPROFIT_TYPE_MP, empty, false, risk_pointer)
|
| | | {
|
| | | // No registra eventos temporales - tracking continuo sin reseteos
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | |
|
| | |
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| M desde el bajo |
|
| | | //+------------------------------------------------------------------+
|
| | | #define LOSSPROFIT_MAXMON_FLAG_BAJO_LISTO (1)
|
| | | template <typename TPadre>
|
| | | class CLossProfitMaxDesdeBaajo : public CLossProfitBaseProfit<TPadre>
|
| | | {
|
| | | private:
|
| | | uint8_t m_flags;
|
| | | double m_negative_profit;
|
| | | double m_min_negative_profit;
|
| | | FuncionLossProfitSuperate m_func_base;
|
| | |
|
| | | //---
|
| | | void OnSuperated() override final;
|
| | |
|
| | | public:
|
| | | CLossProfitMaxDesdeBaajo(bool empty, CRiskManagemetBase* risk_pointer);
|
| | | ~CLossProfitMaxDesdeBaajo(void) {}
|
| | |
|
| | | //---
|
| | | void OnLossProfit(const double p) override final;
|
| | |
|
| | | //---
|
| | | void Init(double _percentage, ENUM_APPLIED_PERCENTAGES _applied, bool _is_strict, FuncionLossProfitSuperate fsup);
|
| | | };
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TPadre> CLossProfitMaxDesdeBaajo::CLossProfitMaxDesdeBaajo(bool empty, CRiskManagemetBase *risk_pointer)
|
| | | : CLossProfitBaseProfit<TPadre>(LOSSPROFIT_TYPE_MDDBAJO, empty, true, risk_pointer), m_func_base(NULL)
|
| | | , m_negative_profit(0.00), m_min_negative_profit(0.00),
|
| | | m_flags(0)
|
| | | {
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TPadre>
|
| | | void CLossProfitMaxDesdeBaajo::Init(double _percentage, ENUM_APPLIED_PERCENTAGES _applied, bool _is_strict, FuncionLossProfitSuperate fsup)
|
| | | {
|
| | | //---
|
| | | if(m_empty_flag)
|
| | | return;
|
| | |
|
| | | //---
|
| | | if(fsup == NULL)
|
| | | {
|
| | | LogError("Function superation cannot be NULL", FUNCION_ACTUAL);
|
| | | return;
|
| | | }
|
| | |
|
| | | //---
|
| | | m_func_base = fsup;
|
| | | CLossProfitBaseProfit<TPadre>::Init(_percentage, _applied, _is_strict, fsup); // Llamaos a la del padre
|
| | | m_funcion_check_sup = LossProfitEmptyFuncionSup;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TPadre>
|
| | | void CLossProfitMaxDesdeBaajo::OnSuperated()
|
| | | {
|
| | | m_flags = 0;
|
| | | m_negative_profit = 0.00;
|
| | | m_min_negative_profit = 0.00;
|
| | | m_funcion_check_sup = LossProfitEmptyFuncionSup;
|
| | |
|
| | | #ifdef MORE_INFO_LOSS_PROFIT_DEFINE
|
| | | LogInfo("Run-up target reached, resetting to search new minimum", FUNCION_ACTUAL);
|
| | | #endif
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TPadre>
|
| | | void CLossProfitMaxDesdeBaajo::OnLossProfit(const double p)
|
| | | {
|
| | | //---
|
| | | if(m_magic_number != NOT_MAGIC_NUMBER && m_magic_number != account_status.LastDealMagic())
|
| | | return;
|
| | |
|
| | | //---
|
| | | const bool is_profit = (p > 0.00);
|
| | | m_negative_profit += p;
|
| | |
|
| | | //---
|
| | | if(m_negative_profit < m_min_negative_profit)
|
| | | {
|
| | | //--- Calculamos el nuevo valor
|
| | | if(Set())
|
| | | m_saved_value = m_lp.value;
|
| | |
|
| | | //---
|
| | | m_flags = 0;
|
| | |
|
| | | //---
|
| | | m_min_negative_profit = m_negative_profit;
|
| | |
|
| | | //---
|
| | | m_funcion_check_sup = LossProfitEmptyFuncionSup;
|
| | |
|
| | | #ifdef MORE_INFO_LOSS_PROFIT_DEFINE
|
| | | LogInfo(StringFormat("New minimum detected: %.2f, target: %.2f", m_min_negative_profit, m_saved_value), FUNCION_ACTUAL);
|
| | | #endif
|
| | | }
|
| | |
|
| | | //---
|
| | | if(is_profit && m_min_negative_profit != 0.00 && m_flags == 0) // Caimos y se recupero
|
| | | {
|
| | | m_flags |= LOSSPROFIT_MAXMON_FLAG_BAJO_LISTO;
|
| | | m_funcion_check_sup = m_func_base;
|
| | |
|
| | | #ifdef MORE_INFO_LOSS_PROFIT_DEFINE
|
| | | LogInfo("Recovery tracking activated", FUNCION_ACTUAL);
|
| | | #endif
|
| | | }
|
| | |
|
| | | //--- Perdida
|
| | | if((m_flags & LOSSPROFIT_MAXMON_FLAG_BAJO_LISTO) != 0)
|
| | | {
|
| | | 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(is_profit)
|
| | | {
|
| | | m_lp.value -= p; // Si es negativo es por que ya se supero y se gano demas y por mucho
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //+------------------------------------------------------------------+
|
| | | #endif // MQLARTICLES_RM_LOSSPROFIT_BASIC_MAXPROFITS_MQH
|