//+------------------------------------------------------------------+ //| SimpleRsi.mqh | //| Copyright 2025, Niquel Mendoza. | //| https://www.mql5.com/es/users/nique_372/news | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, Niquel Mendoza." #property link "https://www.mql5.com/es/users/nique_372/news" #property strict #ifndef MQLARTICLES_POSMGMT_CONDPART_COND_IND_RSI_MQH #define MQLARTICLES_POSMGMT_CONDPART_COND_IND_RSI_MQH //+------------------------------------------------------------------+ //| Include | //+------------------------------------------------------------------+ #include "Base.mqh" //+------------------------------------------------------------------+ //| Class that implements partial close condition by RSI. | //| Partial close of buy positions occurs when RSI is in | //| overbought, and for sell positions when RSI is in oversold. | //+------------------------------------------------------------------+ class CConditionalPartialsIndRsi : public CConditionalPartialsInd { private: double m_overbought_level; // Overbought rsi level double m_oversold_level; // Oversold rsi level double m_next_price_buy; // Next (min) price to closure buy position double m_next_price_sell; // Next (max) price to closure sell position uint8_t m_partial_closure; // Flag indicating the type of "position" to close (0=none, 1=buy, 2=sell) public: CConditionalPartialsIndRsi(); //--- Initialize function bool Init(ENUM_TIMEFRAMES tf, string symbol, int period, double overbought_level = 70.0, double oversold_level = 30.0); //--- General void OnInitPartials(double initial_price) override final; void OnNewDay() override final { } void OnNewWeek() override final { } void Execute(datetime current_time) override final; bool CloseBuy() override final; bool CloseSell() override final; }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CConditionalPartialsIndRsi::CConditionalPartialsIndRsi() : m_overbought_level(70.0), m_oversold_level(30.0) { } //+------------------------------------------------------------------+ //| Defines | //+------------------------------------------------------------------+ #define CONDITIONAL_PARTIAL_IND_RSI_BUY 1 #define CONDITIONAL_PARTIAL_IND_RSI_SELL 2 //+------------------------------------------------------------------+ //| Initializes the class and creates and sets values for the RSI. | //| Inputs: | //| - ENUM_TIMEFRAMES tf: RSI timeframe. | //| - string symbol: Symbol where the RSI will be executed. | //| - int period: RSI period. | //| - double overbought_level: RSI overbought level. | //| - double oversold_level: RSI oversold level | //| Outputs: The function returns true on success, otherwise false. | //+------------------------------------------------------------------+ bool CConditionalPartialsIndRsi::Init(ENUM_TIMEFRAMES tf, string symbol, int period, double overbought_level = 70.0, double oversold_level = 30.0) { //--- m_ind = new CiRsi(); CiRsi* rsi = (CiRsi *)m_ind; // Cast m_name = "PartialCondition By Rsi"; if(!rsi.Create(tf, symbol, period, PRICE_CLOSE, true, true)) return false; //--- m_overbought_level = overbought_level; m_oversold_level = oversold_level; //--- return true; } //+------------------------------------------------------------------+ //| Function that executes each time the process starts | //| to search for partial closes | //+------------------------------------------------------------------+ void CConditionalPartialsIndRsi::OnInitPartials(double initial_price) { //--- m_next_price_buy = initial_price; m_next_price_sell = initial_price; } //+------------------------------------------------------------------+ //| Main function, where it is determined if buy or sell operations | //| should be partially closed | //+------------------------------------------------------------------+ void CConditionalPartialsIndRsi::Execute(datetime current_time) { m_ind.CopyData(1, 2, 0); m_partial_closure = 0; double price; //--- if(m_ind.GetValue(0) > m_overbought_level && m_overbought_level > m_ind.GetValue(1) && (price = SymbolInfoDouble(m_ind.Symbol(), SYMBOL_BID)) > m_next_price_buy) // Overbought { m_partial_closure = CONDITIONAL_PARTIAL_IND_RSI_BUY; m_next_price_buy = price; } else if(m_ind.GetValue(0) < m_oversold_level && m_oversold_level < m_ind.GetValue(1) && (price = SymbolInfoDouble(m_ind.Symbol(), SYMBOL_ASK)) < m_next_price_sell) // Oversold { m_partial_closure = CONDITIONAL_PARTIAL_IND_RSI_SELL; m_next_price_sell = price; } } //+------------------------------------------------------------------+ //| Returns true if buy positions should be partially closed, | //| otherwise false | //+------------------------------------------------------------------+ bool CConditionalPartialsIndRsi::CloseBuy(void) { return m_partial_closure == CONDITIONAL_PARTIAL_IND_RSI_BUY; } //+------------------------------------------------------------------+ //| Returns true if sell positions should be partially closed, | //| otherwise false | //+------------------------------------------------------------------+ bool CConditionalPartialsIndRsi::CloseSell(void) { return m_partial_closure == CONDITIONAL_PARTIAL_IND_RSI_SELL; } //+------------------------------------------------------------------+ #endif //+------------------------------------------------------------------+