MQLArticles/PosMgmt/ConditionalPartial/Conds/Ind/SimpleRsi.mqh
2025-12-13 12:04:25 -05:00

145 行
6.3 KiB
MQL5

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