forked from nique_372/MQLArticles
217 lines
8.7 KiB
MQL5
217 lines
8.7 KiB
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 |
|
|
//+------------------------------------------------------------------+
|
|
#include "AccountStatus.mqh"
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Defines\Enums |
|
|
//+------------------------------------------------------------------+
|
|
//--- 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
|
|
|
|
//---
|
|
#ifndef RISK_MANAGEMENT_BASES_MAX_POS_OPEN
|
|
#define RISK_MANAGEMENT_BASES_MAX_POS_OPEN (64)
|
|
#endif // RISK_MANAGEMENT_BASES_MAX_POS_OPEN
|
|
|
|
//---
|
|
// m_positions aamcena posiciones directamente en el array de m_positioncs de las posiciones de la cuenta
|
|
// No amcena hashes ni nada
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Base Class CRiskManagement |
|
|
//+------------------------------------------------------------------+
|
|
class CRiskManagemetBase : public CAccountGestor
|
|
{
|
|
protected:
|
|
//---
|
|
CTrade trade; //Instancia de ctrade
|
|
int m_positions[RISK_MANAGEMENT_BASES_MAX_POS_OPEN];
|
|
|
|
|
|
//---
|
|
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
|
|
int m_positions_size;
|
|
bool positions_open;
|
|
|
|
//---
|
|
bool TryRemoveFromArrayOfPos(const int global_pos_index);
|
|
|
|
|
|
//---
|
|
void GetPositionsProfit(); // Function to get total profit from open positions
|
|
|
|
public:
|
|
CRiskManagemetBase(const ulong magic_);
|
|
~CRiskManagemetBase();
|
|
|
|
//---
|
|
double m_pos_current_profit;
|
|
|
|
//---
|
|
virtual double GetValorWithApplied(double percentage_, int 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[]);
|
|
|
|
//--- Getters
|
|
//- Magic number
|
|
inline ulong MagicNumber() const { return this.magic_number; }
|
|
|
|
//--- 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
|
|
__forceinline int GetPositions(uint flags) const; // Get total open positions filtered by flags
|
|
__forceinline int GetPositionsTotal() const { return m_positions_size; }
|
|
__forceinline void CloseAllPositions(uint flags = FLAG_CLOSE_ALL_LOSS | FLAG_CLOSE_ALL_PROFIT | FLAG_POSITION_TYPE_BUY | FLAG_POSITION_TYPE_SELL);
|
|
void CloseAllOrders(uint flags);
|
|
|
|
|
|
//---
|
|
__forceinline void CalcProfit() { m_pos_current_profit = g_account_open_positions.GetProfitMask(m_positions, m_positions_size); }
|
|
|
|
//---
|
|
static __forceinline bool WraperIsSupertedLoss(const double value, const double saved_value, void *ptr) { return ((CRiskManagemetBase*)ptr).m_pos_current_profit > value; }
|
|
static __forceinline bool WraperIsSupertedProfit(const double value, const double saved_value, void *ptr) { return -(((CRiskManagemetBase*)ptr).m_pos_current_profit) > value; }
|
|
};
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Constructor |
|
|
//+------------------------------------------------------------------+
|
|
CRiskManagemetBase::CRiskManagemetBase(const 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)
|
|
{
|
|
//---
|
|
m_positions_size = 0;
|
|
//---
|
|
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()
|
|
{
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool CRiskManagemetBase::TryRemoveFromArrayOfPos(const int global_pos_index)
|
|
{
|
|
//--- Find
|
|
int index = -1;
|
|
for(int i = 0; i < m_positions_size; i++)
|
|
{
|
|
if(m_positions[i] == global_pos_index)
|
|
{
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//--- Check is invalid
|
|
if(index == -1)
|
|
return false;
|
|
|
|
//--- Reduce size
|
|
m_positions_size--;
|
|
|
|
//--- Move
|
|
for(int i = index; i < m_positions_size; i++)
|
|
{
|
|
m_positions[i] = m_positions[i + 1]; // Move the elements
|
|
}
|
|
|
|
//---
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Function to obtain the number of open positions |
|
|
//+------------------------------------------------------------------+
|
|
__forceinline int CRiskManagemetBase::GetPositions(uint flags) const
|
|
{
|
|
return g_account_open_positions.GetPositionsMask(m_positions, m_positions_size, flags);
|
|
}
|
|
//+---------------------------------------------------------------------------+
|
|
//| Function to close all positions opened by the magic number or by the user |
|
|
//+---------------------------------------------------------------------------+
|
|
__forceinline void CRiskManagemetBase::CloseAllPositions(uint flags = FLAG_CLOSE_ALL_LOSS | FLAG_CLOSE_ALL_PROFIT | FLAG_POSITION_TYPE_BUY | FLAG_POSITION_TYPE_SELL)
|
|
{
|
|
g_account_open_positions.CloseAllPositionMask(m_positions, m_positions_size, trade, flags);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
#endif // MQLARTICLES_RM_RISKMGMTBASES_MQH
|
|
//+------------------------------------------------------------------+
|