forké depuis nique_372/MQLArticles
187 lignes
15 Kio
MQL5
187 lignes
15 Kio
MQL5
//+------------------------------------------------------------------+
| |
//| RiskManagementBases.mqh |
| |
//| Copyright 2025, Niquel Mendoza. |
| |
//| https://www.mql5.com |
| |
//+------------------------------------------------------------------+
| |
#property copyright "Copyright 2025, Leo."
| |
#property link "https://www.mql5.com"
| |
#property strict
| |
| |
#ifndef MQLARTICLES_RM_RISKMGMTBASES_MQH
| |
#define MQLARTICLES_RM_RISKMGMTBASES_MQH
| |
| |
#include "AccountStatus.mqh"
| |
| |
//--- Risk management classes
| |
class CRiskManagemetBase; // Base class
| |
class CRiskManagemet; // Parent class
| |
class CRiskManagemetPersonal; // Class for personal risk management
| |
class CRiskManagemetPropFirm; // Class for prop firm risk management
| |
class CRiskPointer; // Class to obtain a pointer based on the selected risk management
| |
| |
//---
| |
class CLossProfit; // Class to handle maximum losses or gains
| |
class CLossProfitManager; // Container class to manage CLossProfit objects
| |
| |
//---
| |
#define RISK_MANAGEMENT_RESERVE_POS 10
| |
| |
//+------------------------------------------------------------------+
| |
//| Base Class CRiskManagement |
| |
//+------------------------------------------------------------------+
| |
class CRiskManagemetBase : public CAccountGestor
| |
{
| |
protected:
| |
CTrade* trade; //Instancia de ctrade
| |
Position open_positions[]; //Tickets abiertos por el maic
| |
ulong magic_number; //Numero magico
| |
double daily_profit, weekly_profit, monthly_profit, gross_profit; //Profits de la cuenta
| |
datetime last_day_time;
| |
datetime last_weekly_time;
| |
datetime last_monthly_time;
| |
datetime init_trade_time;
| |
double account_profit; //Ganancia de la cuenta NETA, no confundir con ganancia BRUTA desde que inicio la cuenta
| |
bool positions_open;
| |
void GetPositionsProfit(); // Function to get total profit from open positions
| |
| |
public:
| |
CRiskManagemetBase(ulong magic_);
| |
~CRiskManagemetBase();
| |
//---
| |
virtual double GetValorWithApplied(double percentage_, ENUM_TYPE_LOSS_PROFIT type, ENUM_APPLIED_PERCENTAGES applied) const = 0; // Function to get value based on max loss or gain type
| |
| |
//--- Function to set general class parameters
| |
virtual void SetGeneralParameters(MqlParam ¶ms[]);
| |
| |
//--- General profit retrieval
| |
inline double GrossProfit() const { return this.gross_profit; }
| |
inline double WeeklyProfit() const { return this.weekly_profit; }
| |
inline double DailyProfit() const { return this.daily_profit; }
| |
inline double MontlyProfit() const { return monthly_profit; }
| |
| |
//--- Functions to work with open positions
| |
int GetPositions(uint flags) const; // Get total open positions filtered by flags
| |
inline int16_t GetPositionsTotal() const { return (int16_t)open_positions.Size(); }
| |
void CloseAllPositions(uint flags = FLAG_CLOSE_ALL_LOSS | FLAG_CLOSE_ALL_PROFIT | FLAG_POSITION_TYPE_BUY | FLAG_POSITION_TYPE_SELL);
| |
void CloseAllOrders(uint flags);
| |
};
| |
| |
//+------------------------------------------------------------------+
| |
//| Constructor |
| |
//+------------------------------------------------------------------+
| |
CRiskManagemetBase::CRiskManagemetBase(ulong magic_)
| |
: daily_profit(0.00), weekly_profit(0.00), monthly_profit(0.00), gross_profit(0.00), last_day_time(0), last_weekly_time(0), last_monthly_time(0)
| |
, init_trade_time(0), account_profit(0.00), positions_open(false)
| |
{
| |
//---
| |
ArrayResize(open_positions, 0, RISK_MANAGEMENT_RESERVE_POS);
| |
| |
//---
| |
trade = new CTrade();
| |
| |
//---
| |
trade.SetExpertMagicNumber(magic_);
| |
if(magic_ == NOT_MAGIC_NUMBER)
| |
LogWarning("No magic number has been chosen, taking into account all the magic numbers and the user's trades", FUNCION_ACTUAL);
| |
| |
this.magic_number = magic_;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Destructor |
| |
//+------------------------------------------------------------------+
| |
CRiskManagemetBase::~CRiskManagemetBase()
| |
{
| |
if(CheckPointer(trade) == POINTER_DYNAMIC)
| |
delete trade;
| |
}
| |
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
void CRiskManagemetBase::CloseAllOrders(uint flags)
| |
{
| |
for(int i = OrdersTotal() - 1; i >= 0; i--)
| |
{
| |
const ulong ticket = OrderGetTicket(i);
| |
| |
//---
| |
ResetLastError();
| |
if(OrderSelect(ticket))
| |
{
| |
ENUM_ORDER_TYPE type_order = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
| |
const ulong magic = OrderGetInteger(ORDER_MAGIC);
| |
const int bandera = OrderTypeToFlag(type_order);
| |
| |
if((bandera & flags) != 0 && (magic == this.magic_number || this.magic_number == NOT_MAGIC_NUMBER))
| |
{
| |
if(type_order == ORDER_TYPE_BUY || type_order == ORDER_TYPE_SELL)
| |
trade.PositionClose(ticket);
| |
else
| |
trade.OrderDelete(ticket);
| |
}
| |
}
| |
else
| |
{
| |
LogError(StringFormat("Error al selecionar la order %I64u, ultimo error = %d", ticket, GetLastError()), FUNCION_ACTUAL);
| |
}
| |
}
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Function to obtain the number of open positions |
| |
//+------------------------------------------------------------------+
| |
int CRiskManagemetBase::GetPositions(uint flags) const
| |
{
| |
int count = 0;
| |
| |
for(int16_t i = 0; i < (int16_t)open_positions.Size() ; i++)
| |
{
| |
ENUM_POSITION_TYPE type = this.open_positions[i].type;
| |
| |
if((flags & FLAG_POSITION_TYPE_BUY) != 0)
| |
if(type == POSITION_TYPE_BUY)
| |
count++;
| |
| |
if((flags & FLAG_POSITION_TYPE_SELL) != 0)
| |
if(type == POSITION_TYPE_SELL)
| |
count++;
| |
}
| |
| |
return count;
| |
}
| |
//+---------------------------------------------------------------------------+
| |
//| Function to close all positions opened by the magic number or by the user |
| |
//+---------------------------------------------------------------------------+
| |
void CRiskManagemetBase::CloseAllPositions(uint flags = FLAG_CLOSE_ALL_LOSS | FLAG_CLOSE_ALL_PROFIT | FLAG_POSITION_TYPE_BUY | FLAG_POSITION_TYPE_SELL)
| |
{
| |
for(int i = (int)this.open_positions.Size() - 1; i >= 0; i--)
| |
{
| |
bool close = false;
| |
| |
if(!PositionSelectByTicket(this.open_positions[i].ticket))
| |
continue; // Si no se puede seleccionar la posición, continuar
| |
| |
double profit = PositionGetDouble(POSITION_PROFIT);
| |
ENUM_POSITION_TYPE type = this.open_positions[i].type;
| |
| |
// Verificar si el tipo de posición está en los flags
| |
if((type == POSITION_TYPE_BUY && (flags & FLAG_POSITION_TYPE_BUY) == 0)
| |
|| (type == POSITION_TYPE_SELL && (flags & FLAG_POSITION_TYPE_SELL) == 0))
| |
continue;
| |
| |
if((flags & FLAG_CLOSE_ALL_PROFIT) != 0 && profit > 0)
| |
{
| |
close = trade.PositionClose(this.open_positions[i].ticket);
| |
}
| |
else
| |
if((flags & FLAG_CLOSE_ALL_LOSS) != 0 && profit < 0)
| |
{
| |
close = trade.PositionClose(this.open_positions[i].ticket);
| |
}
| |
}
| |
}
| |
//+------------------------------------------------------------------+
| |
#endif // MQLARTICLES_RM_RISKMGMTBASES_MQH
| |
//+------------------------------------------------------------------+
|