2026-09-12 19:41:52 -05:00
//+------------------------------------------------------------------+
//| Modificators.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_RM_HOOKS_MQH
# define MQLARTICLES_RM_HOOKS_MQH
/ / + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
//| |
//+------------------------------------------------------------------+
# include "LossProfit\\Manager.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
# define RISK_MANAGEMENT_EVENT_ON_OPEN_POSITION ( 1 )
# define RISK_MANAGEMENT_EVENT_ON_CLOSE_POSITION ( 2 )
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class IRiskManagementHook : public CAllClassEventsBasic
{
private :
const uint8_t m_events_flags ;
protected :
const string m_hook_name ;
public :
IRiskManagementHook ( uint8_t f , const string & name ) : m_events_flags ( f ) , m_hook_name ( name ) { }
~ IRiskManagementHook ( ) { }
//--- Virtual functions
// Function that will be executed each time a position is closed
virtual void OnClosePosition ( const ModifierOnOpenCloseStruct & on_open_close_struct ) { }
// Function that will be executed each time an operation is opened
virtual void OnOpenPosition ( const ModifierOnOpenCloseStruct & on_open_close_struct ) { }
// Function that will be executed only once (at the moment of creating the m_modifier)
virtual void OnInitModifier ( const ModfierInitInfo & on_init ) { }
// Name
__forceinline string Name ( ) const { return m_hook_name ; }
//---
__forceinline uint8_t EventsFlags ( ) const { return m_events_flags ; }
} ;
//+--------------------------------------------------------------------+
//| Class to integrate external modifications to risk management |
//+--------------------------------------------------------------------+
class CExtraModifications : public IRiskManagementHook
{
protected :
const CLossProfit * m_modifier ;
const int m_property_to_modify ;
public :
// WRONG_VALUE si no se busca modificar nada,
CExtraModifications ( int _property_to_modify , uint8_t flags_events , const string & name )
: IRiskManagementHook ( flags_events , name ) , m_property_to_modify ( _property_to_modify ) { }
//--- Non-modifiable functions
// Function that returns the type of "maximum loss or profit" that this class is modifying
__forceinline int MaximumProfitOrLossAModify ( ) const { return m_property_to_modify ; } ;
// Function that will be used in CRiskManagement to assign the "maximum loss or profit" based on the type of "maximum loss or profit" chosen
// in the constructor.
void SetPointer ( const CLossProfit * const _modifier ) ;
} ;
//+------------------------------------------------------------------+
//| Set pointer |
//+------------------------------------------------------------------+
void CExtraModifications::SetPointer ( const CLossProfit * const _modifier )
{
//---
if ( ! CheckPointer ( _modifier ) )
{
LogFatalError ( StringFormat ( " The pointer to CLossProfit* for m_modifier %s is invalid " , m_hook_name ) , FUNCION_ACTUAL ) ;
Remover ( ) ;
return ;
}
//---
if ( _modifier . Type ( ) ! = MaximumProfitOrLossAModify ( ) )
{
LogFatalError ( StringFormat ( " The type of the maximum loss/gain = %d, is different from the property to be modified = %d " ,
_modifier . Type ( ) , m_property_to_modify ) , FUNCION_ACTUAL ) ;
Remover ( ) ;
return ;
}
//---
m_modifier = _modifier ;
}
//+------------------------------------------------------------------+
//| Clase para aumentar el riesgo |
//+------------------------------------------------------------------+
enum ENUM_MULTIPLIER_METHOD_DR
{
DR_MULTIPLIER = 0 , // Multiplier
DR_EXPONECIAL = 1 , // Exponential
DR_SUMATORIO = 2 // Additive (Summation)
} ;
//--- Clase
class CDynamicRisk : public CExtraModifications
{
private :
double paso ;
double val ;
double percentage_a_empezar_modfiicacioneS ;
ENUM_MULTIPLIER_METHOD_DR metod ;
void Aumentar ( ) ;
bool is_set ;
public :
CDynamicRisk ( double step , double percentage_to_empezar , ENUM_TYPE_LOSS_PROFIT property_to_modify , ENUM_MULTIPLIER_METHOD_DR multiplier_ ) ;
//---
void OnClosePosition ( const ModifierOnOpenCloseStruct & on_open_close_struct ) override final ;
void OnInitModifier ( const ModfierInitInfo & on_init ) override final ;
} ;
//+------------------------------------------------------------------+
CDynamicRisk : : CDynamicRisk ( double step , double percentage_to_empezar , ENUM_TYPE_LOSS_PROFIT property_to_modify , ENUM_MULTIPLIER_METHOD_DR multiplier_ )
: CExtraModifications ( property_to_modify , RISK_MANAGEMENT_EVENT_ON_CLOSE_POSITION , " Risk enhancer by default " )
{
paso = step ;
percentage_a_empezar_modfiicacioneS = percentage_to_empezar ;
metod = multiplier_ ;
is_set = false ;
if ( ( int ) metod > 2 | | metod < 0 )
{
LogFatalError ( StringFormat ( " The method %s is invalid " , EnumToString ( metod ) ) , FUNCION_ACTUAL ) ;
Remover ( ) ;
}
}
//+------------------------------------------------------------------+
void CDynamicRisk : : OnInitModifier ( const ModfierInitInfo & on_init )
{
percentage_a_empezar_modfiicacioneS / = 100.0 ;
percentage_a_empezar_modfiicacioneS * = on_init . balance ;
Print ( " Balance to increase risk: " , percentage_a_empezar_modfiicacioneS ) ;
val = m_modifier . GetCalcValue ( ) ;
//Print("Valor del porcentaje: ", val);
}
//+------------------------------------------------------------------+
void CDynamicRisk : : OnClosePosition ( const ModifierOnOpenCloseStruct & on_open_close_struct )
{
if ( on_open_close_struct . position . profit > 0 & & on_open_close_struct . profit_total > percentage_a_empezar_modfiicacioneS )
{
LogInfo ( StringFormat ( " By increasing the risk, a profit of %.2f has been obtained. The initial balance has been exceeded by %.2f. " ,
on_open_close_struct . position . profit , percentage_a_empezar_modfiicacioneS ) , FUNCION_ACTUAL ) ;
Aumentar ( ) ;
m_modifier . SetCalcValue ( val ) ;
}
else
{
val = m_modifier . SetInitialCalcValue ( ) ;
}
}
//+------------------------------------------------------------------+
void CDynamicRisk : : Aumentar ( void )
{
switch ( metod )
{
case DR_MULTIPLIER :
val * = paso ;
break ;
case DR_EXPONECIAL :
val * = MathExp ( paso ) ;
break ;
case DR_SUMATORIO :
val + = paso ;
break ;
default :
Remover ( ) ;
break ;
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CModificatorOscar : public CExtraModifications
{
private :
double max_risk ;
double riesgo_inciial ;
double fat_mul ;
double prev_risk ;
int hora_ny_init ;
int min_ny_inti ;
datetime hora_pa ;
datetime hora_pd ;
public :
CModificatorOscar ( double max_risk_percent , double risk_init_percent , double multiplicator_ , int init_ny_h , int init_ny_min ) ;
~ CModificatorOscar ( ) ;
//---
void OnNewDay ( const datetime curr_time ) override final ;
void OnInitModifier ( const ModfierInitInfo & on_init ) override final ;
void OnClosePosition ( const ModifierOnOpenCloseStruct & on_open_close_struct ) override final ;
} ;
//+------------------------------------------------------------------+
CModificatorOscar : : CModificatorOscar ( double max_risk_percent , double risk_init_percent , double multiplicator_ , int init_ny_h , int init_ny_min )
: CExtraModifications ( LP_GMLPO , RISK_MANAGEMENT_EVENT_ON_CLOSE_POSITION , " Modifier by oscar " )
{
max_risk = max_risk_percent ;
riesgo_inciial = risk_init_percent ;
fat_mul = multiplicator_ ;
hora_ny_init = init_ny_h ;
min_ny_inti = init_ny_min ;
//--- Registrar evento de nuevo dia
CBasicEvents : : RegisterEvent ( GetPointer ( this ) , BASICEVENT_REG_FLAG_ON_NEW_DAY ) ;
}
//+------------------------------------------------------------------+
CModificatorOscar : : ~ CModificatorOscar ( )
{
if ( CBasicEvents : : IsActive ( ) )
CBasicEvents : : UnregisterEvent ( GetPointer ( this ) , BASICEVENT_REG_FLAG_ON_NEW_DAY ) ;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CModificatorOscar : : OnNewDay ( const datetime curr_time )
{
datetime hora_ny = HoraYMinutoADatetime ( hora_ny_init , min_ny_inti , curr_time ) ;
hora_pa = hora_ny - 60 ;
hora_pd = hora_ny + 60 ;
}
//+------------------------------------------------------------------+
void CModificatorOscar : : OnInitModifier ( const ModfierInitInfo & on_init )
{
riesgo_inciial / = 100.0 ;
riesgo_inciial * = on_init . balance ;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CModificatorOscar : : OnClosePosition ( const ModifierOnOpenCloseStruct & on_open_close_struct )
{
bool es_perdida = on_open_close_struct . position . profit < 0.00 ;
bool cerro_por_sl = on_open_close_struct . deal_reason = = DEAL_REASON_SL ;
bool cerro_por_tp = on_open_close_struct . deal_reason = = DEAL_REASON_TP ;
bool cerrado_en_ny = TimeCurrent ( ) > = hora_pa & & TimeCurrent ( ) < = hora_pd ;
//---
if ( cerrado_en_ny )
{
LogInfo ( " Operation closed during NY hours - current risk remains " , FUNCION_ACTUAL ) ;
return ;
}
//---
if ( es_perdida & & cerro_por_sl )
{
LogInfo ( StringFormat ( " SL reached - increasing risk. Loss: %.2f " , on_open_close_struct . position . profit ) , FUNCION_ACTUAL ) ;
double new_risk = m_modifier . GetCalcValue ( ) * fat_mul ;
if ( new_risk < = max_risk )
m_modifier . SetCalcValue ( new_risk ) ;
else
m_modifier . SetCalcValue ( max_risk ) ;
}
else
if ( ! es_perdida & & cerro_por_tp )
{
LogInfo ( " TP reached - resetting to initial risk " , FUNCION_ACTUAL ) ;
m_modifier . SetInitialCalcValue ( ) ;
}
}
//+--------------------------------------------------------------------------------------+
//| Clase para modificar el riesgo en base a la estrategia de 2.0 |
//+--------------------------------------------------------------------------------------+
class CModifierDynamicRisk : public CExtraModifications
{
private :
double to_applied [ ] ;
int index_gmlpo ;
public :
CModifierDynamicRisk ( string percentages_to_applied ) ;
//---
void OnClosePosition ( const ModifierOnOpenCloseStruct & on_open_close_struct ) override final ;
} ;
//+------------------------------------------------------------------+
CModifierDynamicRisk : : CModifierDynamicRisk ( string percentages_to_applied )
: CExtraModifications ( LP_GMLPO , RISK_MANAGEMENT_EVENT_ON_CLOSE_POSITION , " Dynamic Risk 2.0 " )
{
const int s = TSN : : CStringFunc : : ToArr < double , TSN : : CStringConvert > ( percentages_to_applied , to_applied , ' , ' ) ;
ArrayResize ( to_applied , s ) ;
index_gmlpo = 0 ;
}
//+------------------------------------------------------------------+
void CModifierDynamicRisk : : OnClosePosition ( const ModifierOnOpenCloseStruct & on_open_close_struct )
{
if ( on_open_close_struct . position . profit < 0.00 ) //La posicion salio SL
{
// Print(__FUNCTION__, "Se a obtenido un sl modificando el riesgo...");
m_modifier . SetCalcValue ( to_applied [ index_gmlpo ] ) ;
if ( index_gmlpo < ( int ) to_applied .Size ( ) - 1 )
index_gmlpo + + ;
}
else //La posicion salio TP
{
//Print(__FUNCTION__, "Se a obtenido un tp modificando el riesgo...");
index_gmlpo = 0 ;
m_modifier . SetInitialCalcValue ( ) ; //Modificar al riesgo inicial
}
}
//+------------------------------------------------------------------+
//| Modificador de riesgo 2 |
//+------------------------------------------------------------------+
class CDynamicRiskAlma : public CExtraModifications
{
private :
double multiplier ;
public :
CDynamicRiskAlma ( double mul )
: CExtraModifications ( LP_GMLPO , RISK_MANAGEMENT_EVENT_ON_CLOSE_POSITION , " Dynamic Risk Alma v2 " ) { multiplier = mul ; }
//---
void OnClosePosition ( const ModifierOnOpenCloseStruct & on_open_close_struct ) override final ;
} ;
//+------------------------------------------------------------------+
void CDynamicRiskAlma::OnClosePosition ( const ModifierOnOpenCloseStruct & on_open_close_struct )
{
if ( on_open_close_struct . profit_total < 0 )
{
double r = m_modifier . GetCalcValue ( ) * multiplier ;
m_modifier . SetCalcValue ( r ) ;
}
else
{
m_modifier . SetInitialCalcValue ( ) ;
}
}
//+------------------------------------------------------------------+
//| Clase para modificar riesgo 3 |
//+------------------------------------------------------------------+
inline double FunctionKevin ( double defect_risk , double loss_percentage , double constante )
{
return ( defect_risk * MathExp ( loss_percentage / constante ) ) ;
}
//+------------------------------------------------------------------+
class CMathDynamicRisk : public CExtraModifications
{
private :
double constante ;
double balance_inicial ;
public :
CMathDynamicRisk ( double constante_ )
: CExtraModifications ( LP_GMLPO , RISK_MANAGEMENT_EVENT_ON_CLOSE_POSITION , " Modifier By Kevin " ) { constante = constante_ ; }
//---
void OnClosePosition ( const ModifierOnOpenCloseStruct & on_open_close_struct ) override final ;
void OnInitModifier ( const ModfierInitInfo & on_init ) override final ;
} ;
//+------------------------------------------------------------------+
void CMathDynamicRisk::OnInitModifier ( const ModfierInitInfo & on_init )
{
balance_inicial = on_init . balance ;
}
//+------------------------------------------------------------------+
void CMathDynamicRisk::OnClosePosition ( const ModifierOnOpenCloseStruct & on_open_close_struct )
{
double percentage_ = CalcularPorcentaje ( on_open_close_struct . profit_total , balance_inicial ) ;
if ( percentage_ < 0.00 )
{
double new_percentage = FunctionKevin ( m_modifier . GetInitialCalcValue ( ) , percentage_ , constante ) ;
m_modifier . SetCalcValue ( NormalizeDouble ( new_percentage , 2 ) ) ;
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CDynamicFOptimal : public CExtraModifications
{
private :
int num_pos ; // Número total de posiciones cerradas
double profit [ ] ; // Profits de operaciones ganadoras
double loss [ ] ; // Pérdidas (valor absoluto)
double sum_profit ; // Suma acumulada de profits
double sum_loss ; // Suma acumulada de pérdidas
double avg_profit ; // Promedio de profits
double avg_loss ; // Promedio de pérdidas
double rr ; // Relación ganancia/pérdida (R)
double win_probability ; // Probabilidad de ganar (p)
int min_trades ; // Mínimo de operaciones para Kelly
double kelly_fraction ; // Fracción de Kelly (por ejemplo, 0.5)
int max_data ; // Máximo número de operaciones a almacenar
bool enable_kelly_mod ; // Agregar como variable de clase
public :
CDynamicFOptimal ( int min_trades_ , int max_data_to_update , double kelly_fraction_ ) : CExtraModifications ( LP_GMLPO , RISK_MANAGEMENT_EVENT_ON_CLOSE_POSITION , " Optimal F Modifier " )
{
num_pos = 0 ;
sum_profit = 0.0 ;
sum_loss = 0.0 ;
avg_profit = 0.0 ;
avg_loss = 0.0 ;
rr = 0.0 ;
win_probability = 0.0 ;
min_trades = MathMax ( min_trades_ , 10 ) ;
kelly_fraction = MathMax ( 0.0 , MathMin ( kelly_fraction_ , 1.0 ) ) ; // Corregir
max_data = MathMax ( max_data_to_update , 30 ) ;
enable_kelly_mod = true ;
ArrayResize ( profit , 0 ) ;
ArrayResize ( loss , 0 ) ;
}
void TrimOldData ( )
{
int total_data = ArraySize ( profit ) + ArraySize ( loss ) ;
if ( total_data < = max_data )
return ;
while ( total_data > max_data )
{
if ( ArraySize ( profit ) > 0 & & ( ArraySize ( loss ) = = 0 | | profit [ 0 ] < = loss [ 0 ] ) )
{
sum_profit - = profit [ 0 ] ;
ArrayRemove ( profit , 0 , 1 ) ;
int win_count = ArraySize ( profit ) ;
avg_profit = win_count > 0 ? sum_profit / win_count : 0.0 ;
num_pos - - ; // Decrementar
}
else
if ( ArraySize ( loss ) > 0 )
{
sum_loss - = loss [ 0 ] ;
ArrayRemove ( loss , 0 , 1 ) ;
int loss_count = ArraySize ( loss ) ;
avg_loss = loss_count > 0 ? sum_loss / loss_count : 0.0 ;
num_pos - - ; // Decrementar
}
total_data = ArraySize ( profit ) + ArraySize ( loss ) ;
}
}
void OnClosePosition ( const ModifierOnOpenCloseStruct & on_open_close_struct ) override final
{
double profit_value = on_open_close_struct . position . profit ;
num_pos + + ;
if ( profit_value = = 0 )
{
Print ( " Break-even operation detected " ) ;
return ;
}
if ( profit_value > 0 )
{
AddArrayNoVerification ( profit , profit_value , 0 ) ;
sum_profit + = profit_value ;
int win_count = ArraySize ( profit ) ;
avg_profit = win_count > 0 ? sum_profit / win_count : 0.0 ;
}
else
{
double val = fabs ( profit_value ) ;
AddArrayNoVerification ( loss , val , 0 ) ;
sum_loss + = fabs ( profit_value ) ;
int loss_count = ArraySize ( loss ) ;
avg_loss = loss_count > 0 ? sum_loss / loss_count : 0.0 ;
}
TrimOldData ( ) ;
int win_count = ArraySize ( profit ) ;
int total_data = ArraySize ( profit ) + ArraySize ( loss ) ;
win_probability = total_data > 0 ? ( double ) win_count / total_data : 0.0 ;
rr = avg_loss > 0 ? avg_profit / avg_loss : 0.0 ;
PrintFormat ( " %s: Debug | win_count: %d, loss_count: %d, avg_profit: %.2f, avg_loss: %.2f " , __FUNCTION__ , ArraySize ( profit ) , ArraySize ( loss ) , avg_profit , avg_loss ) ;
if ( enable_kelly_mod & & num_pos > = min_trades & & rr > 0 & & win_probability > 0 )
{
double kelly = ( win_probability * ( rr + 1 ) - 1 ) / rr ;
kelly = MathMax ( 0.0 , MathMin ( kelly , 1.0 ) ) ;
double adjusted_kelly = kelly * kelly_fraction ;
m_modifier . SetCalcValue ( adjusted_kelly * 100.0 ) ;
PrintFormat ( " %s: Info | Kelly ajustado: %+.2f, Probabilidad: %.2f, R: %.2f, Operaciones: %d " , __FUNCTION__ , adjusted_kelly * 100.0 , win_probability , rr , num_pos ) ;
}
}
} ;
//+------------------------------------------------------------------+
//| Clase manager para modidicadores |
//+------------------------------------------------------------------+
class CRiskManagemeHookManager : public CSpecializedManager
{
private :
//---
IRiskManagementHook * m_on_close_position [ ] ;
int m_on_close_position_size ;
//---
IRiskManagementHook * m_on_open_position [ ] ;
int m_on_open_position_size ;
//---
void RemoveFromArray ( IRiskManagementHook * hook , IRiskManagementHook * & arr [ ] , int & size , bool delete_ptr ) ;
public :
CRiskManagemeHookManager ( ) ;
~ CRiskManagemeHookManager ( ) { Clean ( true ) ; }
//---
__forceinline int SizeOnOpenPosition ( ) const { return m_on_open_position_size ; }
__forceinline int SizeOnClosePosition ( ) const { return m_on_close_position_size ; }
//--- Events
__forceinline void OnClosePosition ( const ModifierOnOpenCloseStruct & on_open_close_struct ) ;
__forceinline void OnOpenPosition ( const ModifierOnOpenCloseStruct & on_open_close_struct ) ;
//--- Add \ Remove \ Clean
void Add ( IRiskManagementHook * hook ) ;
void Remove ( IRiskManagementHook * hook , bool delete_ptr ) ;
void Clean ( bool delete_ptr ) ;
} ;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CRiskManagemeHookManager : : CRiskManagemeHookManager ( void )
{
m_on_open_position_size = ArrayResize ( m_on_open_position , 0 ) ;
m_on_close_position_size = ArrayResize ( m_on_close_position , 0 ) ;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CRiskManagemeHookManager : : Add ( IRiskManagementHook * hook )
{
const uint8_t f = hook . EventsFlags ( ) ;
if ( ( f & RISK_MANAGEMENT_EVENT_ON_OPEN_POSITION ) ! = 0 )
{
m_on_open_position [ ArrayResize ( m_on_open_position , ( + + m_on_open_position_size ) ) - 1 ] = hook ;
}
if ( ( f & RISK_MANAGEMENT_EVENT_ON_CLOSE_POSITION ) ! = 0 )
{
m_on_close_position [ ArrayResize ( m_on_close_position , ( + + m_on_close_position_size ) ) - 1 ] = hook ;
}
//---
AddLogger ( hook ) ;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CRiskManagemeHookManager : : Remove ( IRiskManagementHook * hook , bool delete_ptr )
{
//---
RemoveLogger ( hook ) ;
//---
const uint8_t f = hook . EventsFlags ( ) ;
if ( ( f & RISK_MANAGEMENT_EVENT_ON_OPEN_POSITION ) ! = 0 )
{
RemoveFromArray ( hook , m_on_open_position , m_on_open_position_size , delete_ptr ) ;
}
if ( ( f & RISK_MANAGEMENT_EVENT_ON_CLOSE_POSITION ) ! = 0 )
{
RemoveFromArray ( hook , m_on_close_position , m_on_close_position_size , delete_ptr ) ;
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CRiskManagemeHookManager : : RemoveFromArray ( IRiskManagementHook * hook , IRiskManagementHook * & arr [ ] , int & size , bool delete_ptr )
{
//---
int idx = -1 ;
for ( int i = 0 ; i < size ; i + + )
{
if ( arr [ i ] = = hook )
{
idx = i ;
break ;
}
}
//---
if ( idx = = -1 )
{
LogError ( " No se encontro el puntero para eliminar del arr " , FUNCION_ACTUAL ) ;
return ;
}
//---
if ( delete_ptr & & CheckPointer ( hook ) = = POINTER_DYNAMIC )
delete hook ;
//---
const int last = - - size ;
if ( last ! = idx )
{
arr [ idx ] = arr [ last ] ;
}
ArrayResize ( arr , size ) ;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CRiskManagemeHookManager : : Clean ( bool delete_ptr )
{
//---
if ( delete_ptr )
{
for ( int i = 0 ; i < m_on_open_position_size ; i + + )
{
if ( CheckPointer ( m_on_open_position [ i ] ) = = POINTER_DYNAMIC )
delete m_on_open_position [ i ] ;
}
}
if ( delete_ptr )
{
for ( int i = 0 ; i < m_on_close_position_size ; i + + )
{
if ( CheckPointer ( m_on_close_position [ i ] ) = = POINTER_DYNAMIC )
delete m_on_close_position [ i ] ;
}
}
//---
m_on_open_position_size = ArrayResize ( m_on_open_position , 0 ) ;
m_on_close_position_size = ArrayResize ( m_on_close_position , 0 ) ;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
__forceinline void CRiskManagemeHookManager : : OnClosePosition ( const ModifierOnOpenCloseStruct & on_open_close_struct )
{
for ( int i = 0 ; i < m_on_close_position_size ; i + + )
m_on_close_position [ i ] . OnClosePosition ( on_open_close_struct ) ;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
__forceinline void CRiskManagemeHookManager : : OnOpenPosition ( const ModifierOnOpenCloseStruct & on_open_close_struct )
{
for ( int i = 0 ; i < m_on_open_position_size ; i + + )
m_on_open_position [ i ] . OnOpenPosition ( on_open_close_struct ) ;
}
/*
ADVERTENCIA al momeneto de añadir items a esta clase, esta si son dinamicos las eliminara cuidado.
WARNING when adding items to this class, if they are dynamic, be careful.
*/
}
//+------------------------------------------------------------------+
# endif // MQLARTICLES_RM_HOOKS_MQH
//+------------------------------------------------------------------+