2026-10-25 11:24:06 -05:00
//+------------------------------------------------------------------+
//| Ea.mq5 |
//| Copyright 2025, Niquel Mendoza. |
//| https://www.mql5.com/es/users/nique_372 |
//+------------------------------------------------------------------+
# property copyright " Copyright 2025, Niquel Mendoza. "
# property link " https://www.mql5.com/es/users/nique_372 "
# property version " 1.00 "
# property strict
/ / + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
//| |
//+------------------------------------------------------------------+
2026-10-25 12:04:40 -05:00
// Acivare debug.. si es necesario.. por ahora lo activo para ver todo el proceso de eliminacion
2026-10-25 11:24:06 -05:00
// Mas detalladamente
# define MQLARTICLES_AUTOCLENER_DEBUG
# define CSM_DEBUG_ELIMIACIONES
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
2026-11-01 22:12:14 -05:00
# include <TSN\\MQLArticles\\RM\\RiskManagement.mqh>
2026-10-25 11:24:06 -05:00
# include "Main.mqh"
//+------------------------------------------------------------------+
//| Input |
//+------------------------------------------------------------------+
sinput group " ----------| General |---------- "
input ulong InpMagic = 35465 ; // Magic Number
input bool InpModifiedChart = true ; // Modificar el grafico?
sinput group " "
sinput group " -------| Strategy |------- "
input ENUM_VERBOSE_LOG_LEVEL InpStrategyLogLevel = VERBOSE_LOG_LEVEL_CAUTION ; // Strategy log level
sinput group " -----| TP/SL |----- "
input ENUM_TYPE_TP_SL_FIXED InpStrategyTypeTpSl = TP_SL_ATR ; // Tipo de TP/SL
sinput group " -- TP SL by Point "
input long InpStrategySlPoint = 250 ; // Stop Loss en puntos
input long InpStrategyTpPoint = 500 ; // Take Profit en puntos
sinput group " -- TP SL by ATR "
input double InpStrategyAtrMultiplierTp = 2.0 ; // Multiplicador del ATR para el TP
input double InpStrategyAtrMultiplierSl = 2.0 ; // Multiplicador del ATR para el SL
sinput group " -----| Ordenes |----- "
input ulong InpStrategyMaxDeviationOrders = 100 ; //Maxima desviacion/slípagge de las ordenes en puntos
sinput group " "
sinput group " -------| Account Status |------- "
input ENUM_VERBOSE_LOG_LEVEL InpAccountStatusLogLevel = VERBOSE_LOG_LEVEL_ERROR_ONLY ; //(Account Status|Ticket Mangement) log level:
sinput group " "
sinput group " -------| Risk Management |------- "
input TSN : : ENUM_LOTE_TYPE InpRmLoteType = TSN : : Dinamico ; //Lote Type:
input double InpRmLote = 0.1 ; //Lot size (only for fixed lot)
input TSN : : ENUM_MODE_RISK_MANAGEMENT InpRmRiskMode = TSN : : risk_mode_personal_account ; //type of g_risk management mode
input TSN : : ENUM_GET_LOT InpRmGetMode = TSN : : GET_LOT_BY_STOPLOSS_AND_RISK_PER_OPERATION ; //How to get the lot
input double InpRmPropFirmBalance = 0 ; //If g_risk mode is Prop Firm FTMO, then put your ftmo account balance
input ENUM_VERBOSE_LOG_LEVEL InpRmLogLevel = VERBOSE_LOG_LEVEL_ERROR_ONLY ; //Risk Management log level:
sinput group " - ML/Maximum loss/Maximum loss - "
input double InpRmPercentageOrMoneyMl = 0 ; //percentage or money (0 => not used ML)
input TSN : : ENUM_RISK_CALCULATION_MODE InpRmModeCalculationMl = TSN : : percentage ; //Mode calculation Max Loss
input TSN : : ENUM_APPLIED_PERCENTAGES InpRmAppliedPercentagesMl = TSN : : Balance ; //ML percentage applies to:
sinput group " - MWL/Maximum weekly loss/Maximum weekly loss - "
input double InpRmPercentageOrMoneyMwl = 0 ; //percentage or money (0 => not used MWL)
input TSN : : ENUM_RISK_CALCULATION_MODE InpRmModeCalculationMwl = TSN : : percentage ; //Mode calculation Max weekly Loss
input TSN : : ENUM_APPLIED_PERCENTAGES InpRmAppliedPercentagesMwl = TSN : : Balance ; //MWL percentage applies to:
sinput group " - MDL/Maximum daily loss/Maximum daily loss - "
input double InpRmPercentageOrMoneyMdl = 3.0 ; //percentage or money (0 => not used MDL)
input TSN : : ENUM_RISK_CALCULATION_MODE InpRmModeCalculationMdl = TSN : : percentage ; //Mode calculation Max daily loss
input TSN : : ENUM_APPLIED_PERCENTAGES InpRmAppliedPercentagesMdl = TSN : : Balance ; //MDL percentage applies to:
sinput group " - GMLPO/Gross maximum loss per CanTradetion/Percentage to g_risk per CanTradetion - "
input TSN : : ENUM_OF_DYNAMIC_MODES_OF_GMLPO InpRmModeGmlpo = TSN : : NO_DYNAMIC_GMLPO ; //Select GMLPO mode:
input double InpRmPercentageOrMoneyGmlpo = 2.0 ; //percentage or money (0 => not used GMLPO)
input TSN : : ENUM_RISK_CALCULATION_MODE InpRmModeCalculationGmlpo = TSN : : percentage ; //Mode calculation Max Loss per CanTradetion
input TSN : : ENUM_APPLIED_PERCENTAGES InpRmAppliedPercentagesGmlpo = TSN : : Balance ; //GMPLO percentage applies to:
sinput group " -- Optional GMLPO settings, Dynamic GMLPO "
sinput group " --- Full customizable dynamic GMLPO "
input string InpRmNote1 = " subtracted from your total balance to establish a threshold. " ; //This parameter determines a specific percentage that will be
input string InpRmStrPercentagesToBeReviewed = " 15,30,50 " ; //percentages separated by commas.
input string InpRmNote2 = " a new g_risk level will be triggered on your future trades: " ; //When the current balance (equity) falls below this threshold
input string InpRmStrPercentagesToApply = " 10,20,25 " ; //percentages separated by commas.
input string InpRmNote3 = " 0 in both parameters => do not use dynamic g_risk in gmlpo " ; //Note:
sinput group " --- Fixed dynamic GMLPO with parameters "
sinput group " - 1 - "
input string InpRmNote11 = " subtracted from your total balance to establish a threshold. " ; //This parameter determines a specific percentage that will be
input double InpRmBalancePercentageToActivateTheRisk1 = 2.0 ; //percentage 1 that will be exceeded to modify the g_risk separated by commas
input string InpRmNote21 = " a new g_risk level will be triggered on your future trades: " ; //When the current balance (equity) falls below this threshold
input double InpRmPercentageToBeModified1 = 1.0 ; //new percentage 1 to which the gmlpo is modified
sinput group " - 2 - "
input double InpRmBalancePercentageToActivateTheRisk2 = 5.0 ; //percentage 2 that will be exceeded to modify the g_risk separated by commas
input double InpRmPercentageToBeModified2 = 0.7 ; //new percentage 2 to which the gmlpo is modified
sinput group " - 3 - "
input double InpRmBalancePercentageToActivateTheRisk3 = 7.0 ; //percentage 3 that will be exceeded to modify the g_risk separated by commas
input double InpRmPercentageToBeModified3 = 0.5 ; //new percentage 3 to which the gmlpo is modified
sinput group " - 4 - "
input double InpRmBalancePercentageToActivateTheRisk4 = 9.0 ; //percentage 4 that will be exceeded to modify the g_risk separated by commas
input double InpRmPercentageToBeModified4 = 0.33 ; //new percentage 4 1 to which the gmlpo is modified
sinput group " -- MDP/Maximum daily profit/Maximum daily profit -- "
input bool InpRmMdpIsStrict = true ; //MDP is strict?
input double InpRmPercentageOrMoneyMdp = 11.0 ; //percentage or money (0 => not used MDP)
input TSN : : ENUM_RISK_CALCULATION_MODE InpRmModeCalculationMdp = TSN : : percentage ; //Mode calculation Max Daily Profit
input TSN : : ENUM_APPLIED_PERCENTAGES InpRmAppliedPercentagesMdp = TSN : : Balance ; //MDP percentage applies to:
sinput group " ------| Order Blocks |------ "
input int minutos_despues_mitigacion_eliminar_ob = 10 ; //minutes to delete the order block after being invalidated
input bool mostar_la_mitad_ob = true ; //show the middle line of an order block?
input ENUM_ORDERBLOCKS_OBTENCIUON_TYPE mod_obtencion_obs = ORDER_BLOCKS_ALL ; //Order blocks Obtaining mode
sinput group " --| General properties of the order block rectangle "
input bool fill_order_blocks = true ; //Fill Order Blocks?
sinput group " --| Bullish order block "
input color Color_OrderBlock_Alcista = C ' 45 , 154 , 29 ' ; // Choose the Bullish Order Block Color
input color line_mitad_color_oba = clrDarkGreen ; //color of the middle line of the bullish order blocks
input ENUM_OB_STYLE price_1_oba = low ; // choose price1 bullish order block
input ENUM_OB_STYLE price_2_oba = high ; // choose price2 bullish order block
sinput group " --| Bearish order block "
input color Color_OrderBlock_Bajista = C ' 249 , 95 , 57 ' ; // Choose the Bearish Order Block Color
input color line_mitad_color_obb = clrTomato ; //color of the middle line of the bearish order blocks
input ENUM_OB_STYLE price_1_obb = high ; // choose price1 bearish order block
input ENUM_OB_STYLE price_2_obb = low ; // choose price2 bearish order block
sinput group " --| Settings order block by sweeps "
input int16_t lenth_order_block = 4 ; //Num bar of swings to identify swing points
input ENUM_TYPE_ROPTRUA_CONFIRMAR_OB breakout_type_ob = BREAKUP_VELA_ROPTURA_SWING ; // break type for order block by sweep
input int max_espera_roptura_ob_sweep = 20 ; //maximum wait in bars to break a swing or open of a candle
//+------------------------------------------------------------------+
//| Global variables |
//+------------------------------------------------------------------+
CEstrategia g_strategy ( InpMagic , _Symbol , _Period , 0 , 0 , InpStrategyMaxDeviationOrders ) ;
//---
int8_t g_idx_controler_w1 = INVALID_INDEX ;
int8_t g_idx_controler_curr = INVALID_INDEX ;
int8_t g_idx_bar_controlerd1 = INVALID_INDEX ;
int8_t g_idx_bar_mn1 = INVALID_INDEX ;
//---
bool g_new_day = false ;
2026-11-02 11:19:09 -05:00
uint g_trade_flags = 0 ;
2026-10-25 11:24:06 -05:00
//---
2026-11-01 22:12:14 -05:00
TSN : : CLossProfitManager g_loss_profit_manager ; // LossProfitManager
2026-10-25 12:04:40 -05:00
TSN : : CAtrOptimizedZero g_atr_opt_zero ( PERIOD_CURRENT , _Symbol , 14 ) ;
2026-10-25 11:24:06 -05:00
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit ( )
{
//--- Registramos timeframes
g_new_bar_manager . GetPosExecute ( PERIOD_D1 , g_idx_bar_controlerd1 ) ;
g_new_bar_manager . GetPosExecute ( _Period , g_idx_controler_curr ) ;
g_new_bar_manager . GetPosExecute ( PERIOD_W1 , g_idx_controler_w1 ) ;
g_new_bar_manager . GetPosExecute ( PERIOD_MN1 , g_idx_bar_mn1 ) ;
//--- Modifamos el grafico si se permite
if ( InpModifiedChart )
{
long chart_id = ChartID ( ) ; // Obtén el ID del gráfico actual
// Ocultar la cuadrícula
ChartSetInteger ( chart_id , CHART_SHOW_GRID , false ) ;
ChartSetInteger ( chart_id , CHART_COLOR_BACKGROUND , C ' 255 , 255 , 255 ' ) ; // Fondo blanco
ChartSetInteger ( chart_id , CHART_COLOR_FOREGROUND , clrBlack ) ; // Texto y escalas negras
ChartSetInteger ( chart_id , CHART_COLOR_CHART_UP , C ' 38 , 166 , 154 ' ) ; // Velas alcistas color verde azulado
ChartSetInteger ( chart_id , CHART_COLOR_CHART_DOWN , C ' 239 , 83 , 80 ' ) ; // Velas bajistas color rojo
ChartSetInteger ( chart_id , CHART_COLOR_CANDLE_BULL , C ' 38 , 166 , 154 ' ) ; // Cuerpo de las velas alcistas
ChartSetInteger ( chart_id , CHART_COLOR_CANDLE_BEAR , C ' 239 , 83 , 80 ' ) ; // Cuerpo de las velas bajistas
ChartSetInteger ( chart_id , CHART_COLOR_CHART_LINE , clrDarkSeaGreen ) ; // Línea de tendencia
ChartSetInteger ( chart_id , CHART_COLOR_VOLUME , C ' 38 , 166 , 154 ' ) ; // Color de los volúmenes
ChartSetInteger ( chart_id , CHART_COLOR_BID , C ' 38 , 166 , 154 ' ) ; // Línea de oferta
ChartSetInteger ( chart_id , CHART_COLOR_ASK , C ' 239 , 83 , 80 ' ) ; // Línea de demanda
ChartSetInteger ( chart_id , CHART_COLOR_LAST , C ' 156 , 186 , 240 ' ) ; // Último precio
ChartSetInteger ( chart_id , CHART_COLOR_STOP_LEVEL , C ' 239 , 83 , 80 ' ) ; // Líneas de stop
ChartSetInteger ( chart_id , CHART_SHOW_VOLUMES , true ) ;
// Actualizar el gráfico
ChartRedraw ( chart_id ) ;
}
//--- Conceptos
// Order block
g_ob . Create ( _Symbol , _Period , 0 , 0 , true ) ;
g_ob . SetGrapich ( Color_OrderBlock_Alcista , Color_OrderBlock_Bajista , line_mitad_color_oba , line_mitad_color_obb , STYLE_SOLID , fill_order_blocks , 1 , mostar_la_mitad_ob ,
minutos_despues_mitigacion_eliminar_ob , 1 , STYLE_DOT ) ;
g_ob . SetTypeBusqueda ( mod_obtencion_obs ) ;
g_ob . SetStylesPrices ( price_1_oba , price_1_obb , price_2_oba , price_2_obb ) ;
g_ob . SetOrderBlockSweep ( lenth_order_block , max_espera_roptura_ob_sweep , breakout_type_ob ) ;
g_ob .Set ( 500 ) ;
//--- Estrategia
g_strategy . AddLogFlags ( InpStrategyLogLevel ) ;
2026-10-25 12:04:40 -05:00
g_strategy . SetAtrTP_SL ( & g_atr_opt_zero , InpStrategyAtrMultiplierTp , InpStrategyAtrMultiplierSl ) ;
2026-10-25 11:24:06 -05:00
g_strategy . SetOperateMode ( TR_BUY_SELL , InpStrategyTypeTpSl ) ;
g_strategy . SetTP_SL ( InpStrategySlPoint , InpStrategyTpPoint ) ;
if ( InpRmLoteType = = TSN : : Fijo )
g_strategy . FixedLotSize ( InpRmLote ) ;
2026-11-01 22:12:14 -05:00
//--- Risk management
string _what = NULL ;
TSNSTD_TRY_INI
{
TSN : : CRiskManagementCreator manager ;
manager . SetPropirm ( InpRmPropFirmBalance ) ;
//---
TSN : : MQLArtRMCreatorRes result = manager . GetRiskPointer ( InpRmRiskMode , InpMagic , InpRmGetMode ) ;
2026-11-05 18:16:32 -05:00
TSNSTD_TRY_EF ( result . ok , true ,
2026-11-06 10:58:48 -05:00
TSN : : CErrorTrace : : FormatTrace ( _what ) )
2026-11-01 22:12:14 -05:00
//---
g_risk = result . ptr ;
g_risk . AddLogFlags ( InpRmLogLevel ) ;
g_risk . SetLossProfitManager ( g_loss_profit_manager ) ;
CAutoCleaner : : AddPtr ( g_risk ) ;
// We set the parameters
string to_apply = InpRmStrPercentagesToApply , to_modfied = InpRmStrPercentagesToBeReviewed ;
if ( InpRmModeGmlpo = = TSN : : DYNAMIC_GMLPO_FIXED_PARAMETERS )
TSN : : CRmFunctions : : SetDynamicUsingFixedParameters ( InpRmBalancePercentageToActivateTheRisk1 , InpRmBalancePercentageToActivateTheRisk2 , InpRmBalancePercentageToActivateTheRisk3
, InpRmBalancePercentageToActivateTheRisk4 , InpRmPercentageToBeModified1 , InpRmPercentageToBeModified2 , InpRmPercentageToBeModified3 , InpRmPercentageToBeModified4
, to_modfied , to_apply ) ;
//--- Maximum losses and profits
TSNSTD_TRY_INI_S // nota: genera bool _err implicito
{
TSNSTD_TRY_SE ( g_risk . AddLP ( InpRmPercentageOrMoneyMdl , InpRmAppliedPercentagesMdl , InpRmModeCalculationMdl , TSN : : LP_MDL , true ) , true ) ;
TSNSTD_TRY_SE ( g_risk . AddLP ( InpRmPercentageOrMoneyGmlpo , InpRmAppliedPercentagesGmlpo , InpRmModeCalculationGmlpo , TSN : : LP_GMLPO , true ,
( InpRmModeGmlpo ! = TSN : : NO_DYNAMIC_GMLPO ) , to_modfied , to_apply ) , true ) ;
TSNSTD_TRY_SE ( g_risk . AddLP ( InpRmPercentageOrMoneyMl , InpRmAppliedPercentagesMl , InpRmModeCalculationMl , TSN : : LP_ML , true ) , true ) ;
TSNSTD_TRY_SE ( g_risk . AddLP ( InpRmPercentageOrMoneyMwl , InpRmAppliedPercentagesMwl , InpRmModeCalculationMwl , TSN : : LP_MWL , true ) , true ) ;
TSNSTD_TRY_SE ( g_risk . AddLP ( InpRmPercentageOrMoneyMdp , InpRmAppliedPercentagesMdp , InpRmModeCalculationMdp , TSN : : LP_MDP , InpRmMdpIsStrict ) , true ) ;
g_risk . EndAddProfitLoss ( ) ; // Execute this every time we finish setting the maximum losses and profits
}
TSNSTD_TRY_END ;
2026-10-25 11:24:06 -05:00
2026-11-01 22:12:14 -05:00
//---
2026-11-06 10:58:48 -05:00
TSNSTD_TRY_N_EF ( _err , true , TSN : : CErrorTrace : : FormatTrace ( _what ) )
2026-11-01 22:12:14 -05:00
}
TSNSTD_TRY_END ;
2026-10-25 11:24:06 -05:00
2026-11-01 22:12:14 -05:00
//---
if ( _what ! = NULL ) // error final
{
FastLog ( FUNCION_ACTUAL , FATAL_ERROR_TEXT , _what ) ;
return INIT_FAILED ;
}
2026-10-25 11:24:06 -05:00
//--- We initialize the account
TSN : : account_status . AddLogFlags ( InpAccountStatusLogLevel ) ;
TSN : : account_status . OnInitEvent ( ) ;
2026-11-01 22:12:14 -05:00
//---
CAutoCleaner : : AddFunction ( TSN : : CAccountStatus_Deinit ) ;
CAutoCleaner : : AddFunction ( CBasicEvents : : Deinit ) ;
2026-10-25 11:24:06 -05:00
//---
return ( INIT_SUCCEEDED ) ;
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit ( const int reason )
{
//---
// Llamoas a esta funcion para que lipie todo
// Mencionar que esta funcion es como "un muro" por lo que ENCARECIDAMENTE no recomiendo llamar a ninguna funcion
// De la libreria ICT luego de llamar a CAutoCleaner::Deinit(reason);, de lo contrario pueden ocurrir bugs o memory leaks
// Tampoco LLAMAR o hacer uso de los punteros de CAtr..que la libreria es dueña (creados con ICTAtr_*), asi que
// Dare una lista de QUE no usar/llamar..
// - Atr
// - Funciones de la libreria ICT (TODAS, ICTGen etc..)
// - ICTSymbol
// - ICTSymbolManager
//---
CAutoCleaner : : Deinit ( reason ) ;
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick ( )
{
//---
const datetime time_curr = TimeCurrent ( ) ;
g_new_day = false ;
g_new_bar_manager . Execute ( time_curr ) ;
//--- Bloque 1 | Control Diario/Semanal/Mensual
if ( CNewBarManager_IsNewBarM1 ( g_new_bar_manager ) )
{
if ( CNewBarManager_IsNewBar ( g_new_bar_manager , g_idx_bar_controlerd1 ) )
{
CBasicEvents : : OnNewDay ( time_curr ) ;
2026-11-02 11:19:09 -05:00
TSNMQLART_U_BEVENTS_MAN_REM_F ( g_trade_flags , BASICEVENT_REG_FLAG_ON_NEW_DAY ) ;
2026-10-25 11:24:06 -05:00
//---
if ( CNewBarManager_IsNewBar ( g_new_bar_manager , g_idx_controler_w1 ) ) //Limpiar para no acomular mucha memoria
{
CBasicEvents : : OnNewWeek ( time_curr ) ;
2026-11-02 11:19:09 -05:00
TSNMQLART_U_BEVENTS_MAN_REM_F ( g_trade_flags , BASICEVENT_REG_FLAG_ON_NEW_WEEK ) ;
2026-10-25 11:24:06 -05:00
}
//--- Nuevo mes, eliminacion de liquidez
if ( CNewBarManager_IsNewBar ( g_new_bar_manager , g_idx_bar_mn1 ) )
2026-11-02 11:19:09 -05:00
{
2026-10-25 11:24:06 -05:00
CBasicEvents : : OnNewMonth ( time_curr ) ;
2026-11-02 11:19:09 -05:00
// no uso tradeflags dado que no hay parametros para un Monthly.. pero si lo hubiera:
//TSNMQLART_U_BEVENTS_MAN_REM_F(g_trade_flags, BASICEVENT_REG_FLAG_ON_NEW_MON);
}
2026-10-25 11:24:06 -05:00
//---
g_new_day = true ;
}
}
//--- Bloque 2 | Control de MDL\MDP.. etc
if ( TSN : : account_status_positions_open )
{
2026-11-01 22:12:14 -05:00
# ifdef MQLARTICLES_RM_MULTI_EA_MODE
g_risk . CalcProfit ( ) ;
# else // MQLARTICLES_RM_MULTI_EA_MODE
ACCOUNTSTATUS_ONEVERYTICK
# endif // MQLARTICLES_RM_MULTI_EA_MODE
2026-11-02 11:19:09 -05:00
if ( TSNMQLART_U_BEVENTS_MAN_TRADE_NOW ( g_trade_flags ) )
2026-10-25 11:24:06 -05:00
{
if ( g_loss_profit_manager . MaxLossIsSuperated ( ) )
{
const int type = g_loss_profit_manager . GetLastLossSuperatedType ( ) ;
2026-11-02 11:19:09 -05:00
if ( type < TSN : : LP_ML )
{
g_strategy . OnInterupcion ( ) ;
g_risk . CloseAllPositions ( ) ;
// anadimos segun corresponda
TSNMQLART_U_BEVENTS_MAN_ADD_F ( g_trade_flags , TSNMQLART_RM_LP_M_BEVENTS_F_LOSS ( type ) ) ;
Print ( TSN : : g_mqarticles_lp_str_names [ type ] , " is superated now " ) ;
}
else // Manejo de las demas perdidas (aqui tambien entra pico, como no lo tenemos "agregado" no importa, pero si estuviera habria que manejar un caso especial)
2026-10-25 11:24:06 -05:00
{
if ( InpRmRiskMode = = TSN : : risk_mode_propfirm_dynamic_daiy_loss )
Print ( " The expert advisor lost the funding test " ) ;
else
Print ( " Maximum loss exceeded now " ) ;
//---
2026-11-02 11:19:09 -05:00
g_strategy . OnInterupcion ( ) ;
g_risk . CloseAllPositions ( ) ;
2026-10-25 11:24:06 -05:00
Remover ( ) ;
}
}
else
if ( g_loss_profit_manager . MaxProfitIsSuperated ( ) )
{
2026-11-02 11:19:09 -05:00
// NOTA: no se comprueba el tipo dado que ahora mismo solo hay un profit agregado (MDP).
// Si hubieran mas se haria algo similar a la rama de losses.
2026-10-25 11:24:06 -05:00
g_strategy . OnInterupcion ( ) ;
g_risk . CloseAllPositions ( ) ;
2026-11-02 11:19:09 -05:00
TSNMQLART_U_BEVENTS_MAN_ADD_F ( g_trade_flags , BASICEVENT_REG_FLAG_ON_NEW_DAY ) ;
2026-10-25 11:24:06 -05:00
Print ( " Excellent Maximum daily profit achieved " ) ;
}
}
}
//--- Bloque 3 | Ejecucion
2026-11-02 11:19:09 -05:00
// Si hay al menos una bandera activa no se puede operar
if ( TSNMQLART_U_BEVENTS_MAN_NO_TRADE_NOW ( g_trade_flags ) )
2026-10-25 11:24:06 -05:00
return ;
//---
/*
Bien, llegamos a esta parte del código donde debemos ejecutar los conceptos ICT.
Este bloque, como tal, no es “fijo”; existen muchas combinaciones posibles.
Esto se debe a que intervienen varios factores:
1. ¿El timeframe de todos los conceptos y el que utiliza la estrategia es el mismo?
2. ¿Existe algún concepto en M1 (que, en lugar de usar OnNewBar, utilice
OnNewBarM1), por ejemplo sesiones o High/Low Zones?
En base a estos dos criterios podemos optimizar la ejecución.
Por ejemplo, en el caso de utilizar sesiones, y cuando los conceptos no varían
de timeframe (o en caso de hacerlo, el período actual es múltiplo del timeframe
de los conceptos), podríamos hacer lo siguiente:
if(CNewBarManager_IsNewBarM1(g_new_bar_manager))
{
//---
// Esta función siempre se ejecuta en cada nueva barra M1
ICTGen_FuncionOnBarM1(g_new_day, time_curr);
// Aquí irían las sesiones u otros objetos en M1
//---
if(CNewBarManager_IsNewBar(g_new_bar_manager, g_idx_controler_curr))
{
//---
// Aquí se ejecutan los conceptos,
// o bien se delega dentro de la clase, dependiendo de la estrategia
//---
g_strategy.OnNewBar(time_curr);
}
}
Por otro lado, si tenemos conceptos en varios timeframes, o los timeframes no son
fijos ni múltiplos entre sí, entonces deberíamos ejecutar los conceptos en cada
vela M1, y también llamar a OnNewBar de la estrategia en M1. En ese caso, el control
de la apertura de velas deberá gestionarse internamente.
if(CNewBarManager_IsNewBarM1(g_new_bar_manager))
{
//---
// Siempre se ejecuta en cada nueva barra M1
ICTGen_FuncionOnBarM1(g_new_day, time_curr);
// Aquí las sesiones u objetos M1
//---
// Aquí los conceptos, o dentro de la clase de la estrategia
//---
g_strategy.OnNewBar(time_curr);
}
Para nuestro caso es especial, ya que:
- El punto 1 es falso (todo trabaja en el timeframe actual).
- El punto 2 también es falso (no utilizamos sesiones).
Por lo tanto, podemos optimizar ejecutando todo únicamente en cada nueva barra
del timeframe actual, siempre que también exista una nueva barra M1.
if(CNewBarManager_IsNewBarM1(g_new_bar_manager) &&
CNewBarManager_IsNewBar(g_new_bar_manager, g_idx_controler_curr))
{
//---
// Siempre ejecutamos esta función en cada nueva barra M1
ICTGen_FuncionOnBarM1(g_new_day, time_curr);
//---
// Conceptos
//---
g_strategy.OnNewBar(time_curr);
}
Siendo esto lo que haremos a continuación.
*/
//---
if ( CNewBarManager_IsNewBarM1 ( g_new_bar_manager ) & &
CNewBarManager_IsNewBar ( g_new_bar_manager , g_idx_controler_curr ) )
{
//---
// Siempre se ejecuta en cada nueva barra M1
ICTGen_FuncionOnBarM1 ( g_new_day , time_curr ) ;
//---
g_ob . OnNewBar ( ) ;
//---
g_strategy . OnNewBar ( time_curr ) ;
}
//--- Bloque 3.1 | OnTick
g_ob . OnTickEvent ( time_curr ) ;
g_strategy . OnTick ( time_curr ) ; // SIEMPRE se ejecuta después
// También es importante mencionar que, siempre que trabajemos con g_new_bar_manager
// dentro de OnTick, debemos comprobar la nueva vela M1.
// En cambio, dentro de CEstrategia::OnNewBar, si esta función se ejecuta en cada vela M1,
// dicha comprobación ya no es necesaria, ya que sería una forma de “simplificar”
// las primeras verificaciones.
}
//+------------------------------------------------------------------+
//| TradeTransaction function |
//+------------------------------------------------------------------+
void OnTradeTransaction ( const MqlTradeTransaction & trans ,
const MqlTradeRequest & request ,
const MqlTradeResult & result )
{
//---
TSN : : account_status . OnTradeTransactionEvent ( trans ) ;
}
//+------------------------------------------------------------------+