| //+------------------------------------------------------------------+
|
| //| Ea.mq5 |
|
| //| 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 version "1.00"
|
| #property strict
|
| #property description "Bot que implementa la estrateiga del trader nocturno"
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| // SIEMPRE INCLUIMOS A DEF GLOBAL PRIMERO COMO EL PRIMER MQH PARA EVITAR ERRORES
|
| #include "..\\DefGlobal.mqh"
|
| #include <TSN\\MQLArticles\\RM\\Modificators.mqh>
|
| #include "Main.mqh"
|
|
|
| //+------------------------------------------------------------------+
|
| //| Inputs |
|
| //+------------------------------------------------------------------+
|
| sinput group "----------| General |----------"
|
| input ulong InpMagic = 35465; // Número mágico
|
| input bool InpModifiedChart = true; // ¿Modificar el gráfico?
|
|
|
| sinput group ""
|
| sinput group "-------| Estrategia |-------"
|
| input ENUM_VERBOSE_LOG_LEVEL InpStrategyLogLevel = VERBOSE_LOG_LEVEL_CAUTION; // Nivel de log de la estrategia
|
|
|
| sinput group "-----| TP/SL |-----"
|
| input ENUM_TYPE_TP_SL InpStrategyTypeTpSl = TP_SL_BY_STRATEGY_RR; // Tipo de TP/SL
|
|
|
| sinput group "-- TP SL por puntos"
|
| input long InpStrategySlPoint = 200; // Stop Loss en puntos
|
| input long InpStrategyTpPoint = 400; // Take Profit en puntos
|
|
|
| sinput group "-- TP SL por 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 "-- TP/SL by Strategie "
|
| input double RR_TP = 3.1; //RR TakeProfit
|
|
|
| sinput group "-----| Órdenes |-----"
|
| input long InpStrategyMaxDeviationOrders = 100; // Máxima desviación/deslizamiento de las órdenes en puntos
|
|
|
| sinput group ""
|
| sinput group "-------| Estado de la cuenta |-------"
|
| input ENUM_VERBOSE_LOG_LEVEL InpAccountStatusLogLevel = VERBOSE_LOG_LEVEL_ERROR_ONLY; // Nivel de log de Estado de cuenta/Gestión de tickets
|
|
|
| sinput group ""
|
| sinput group "-------| Gestión de riesgo |-------"
|
| input TSN::ENUM_LOTE_TYPE InpRmLoteType = TSN::Dinamico; // Tipo de lote
|
| input double InpRmLote = 0.1; // Tamaño del lote (solo para lote fijo)
|
| input TSN::ENUM_MODE_RISK_MANAGEMENT InpRmRiskMode = TSN::risk_mode_personal_account; // Tipo de modo de gestión de riesgo
|
| input TSN::ENUM_GET_LOT InpRmGetMode = TSN::GET_LOT_BY_STOPLOSS_AND_RISK_PER_OPERATION; // Cómo calcular el tamaño del lote
|
| input double InpRmPropFirmBalance = 0; // Balance de cuenta Prop Firm FTMO (si aplica)
|
| input ENUM_VERBOSE_LOG_LEVEL InpRmLogLevel = VERBOSE_LOG_LEVEL_ERROR_ONLY; // Nivel de log de Gestión de riesgo
|
|
|
| sinput group "- ML/Pérdida máxima -"
|
| input double InpRmPercentageOrMoneyMl = 0; // Porcentaje o dinero (0 => ML no usado)
|
| input TSN::ENUM_RISK_CALCULATION_MODE InpRmModeCalculationMl = TSN::percentage; // Modo de cálculo de Pérdida Máxima
|
| input TSN::ENUM_APPLIED_PERCENTAGES InpRmAppliedPercentagesMl = TSN::Balance; // Porcentaje ML se aplica a
|
|
|
| sinput group "- MWL/Pérdida máxima semanal -"
|
| input double InpRmPercentageOrMoneyMwl = 0; // Porcentaje o dinero (0 => MWL no usado)
|
| input TSN::ENUM_RISK_CALCULATION_MODE InpRmModeCalculationMwl = TSN::percentage; // Modo de cálculo de Pérdida Máxima Semanal
|
| input TSN::ENUM_APPLIED_PERCENTAGES InpRmAppliedPercentagesMwl = TSN::Balance; // Porcentaje MWL se aplica a
|
|
|
| sinput group "- MDL/Pérdida máxima diaria -"
|
| input double InpRmPercentageOrMoneyMdl = 3.0; // Porcentaje o dinero (0 => MDL no usado)
|
| input TSN::ENUM_RISK_CALCULATION_MODE InpRmModeCalculationMdl = TSN::percentage; // Modo de cálculo de Pérdida Máxima Diaria
|
| input TSN::ENUM_APPLIED_PERCENTAGES InpRmAppliedPercentagesMdl = TSN::Balance; // Porcentaje MDL se aplica a
|
|
|
| sinput group "- GMLPO/Pérdida máxima bruta por operación -"
|
| input TSN::ENUM_OF_DYNAMIC_MODES_OF_GMLPO InpRmModeGmlpo = TSN::NO_DYNAMIC_GMLPO; // Modo GMLPO
|
| input double InpRmPercentageOrMoneyGmlpo = 2.0; // Porcentaje o dinero (0 => GMLPO no usado)
|
| input TSN::ENUM_RISK_CALCULATION_MODE InpRmModeCalculationGmlpo = TSN::percentage; // Modo de cálculo de Pérdida Máxima por Operación
|
| input TSN::ENUM_APPLIED_PERCENTAGES InpRmAppliedPercentagesGmlpo = TSN::Balance; // Porcentaje GMLPO se aplica a
|
|
|
| sinput group "-- Configuración opcional de GMLPO, GMLPO dinámico"
|
| sinput group "--- GMLPO dinámico totalmente personalizable"
|
| input string InpRmNote1 = "Este parámetro determina un porcentaje específico que se restará de su balance total para establecer un umbral."; // Nota 1
|
| input string InpRmStrPercentagesToBeReviewed = "15,30,50"; // Porcentajes a revisar (separados por comas)
|
| input string InpRmNote2 = "Cuando el balance actual (equity) cae por debajo de este umbral, se activará un nuevo nivel de riesgo en sus operaciones futuras: "; // Nota 2
|
| input string InpRmStrPercentagesToApply = "10,20,25"; // Porcentajes a aplicar (separados por comas)
|
| input string InpRmNote3 = "Nota: 0 en ambos parámetros => no usar riesgo dinámico en GMLPO"; // Nota 3
|
|
|
| sinput group "--- GMLPO dinámico fijo con parámetros"
|
| sinput group "- Nivel 1 -"
|
| input string InpRmNote11 = "Este parámetro determina un porcentaje específico que se restará de su balance total para establecer un umbral."; // Nota 1.1
|
| input double InpRmBalancePercentageToActivateTheRisk1 = 2.0; // Umbral de porcentaje de balance 1 para modificar el riesgo
|
| input string InpRmNote21 = "Cuando el balance actual (equity) cae por debajo de este umbral, se activará un nuevo nivel de riesgo en sus operaciones futuras: "; // Nota 2.1
|
| input double InpRmPercentageToBeModified1 = 1.0; // Nuevo porcentaje GMLPO 1
|
| sinput group "- Nivel 2 -"
|
| input double InpRmBalancePercentageToActivateTheRisk2 = 5.0; // Umbral de porcentaje de balance 2 para modificar el riesgo
|
| input double InpRmPercentageToBeModified2 = 0.7; // Nuevo porcentaje GMLPO 2
|
| sinput group "- Nivel 3 -"
|
| input double InpRmBalancePercentageToActivateTheRisk3 = 7.0; // Umbral de porcentaje de balance 3 para modificar el riesgo
|
| input double InpRmPercentageToBeModified3 = 0.5; // Nuevo porcentaje GMLPO 3
|
| sinput group "- Nivel 4 -"
|
| input double InpRmBalancePercentageToActivateTheRisk4 = 9.0; // Umbral de porcentaje de balance 4 para modificar el riesgo
|
| input double InpRmPercentageToBeModified4 = 0.33; // Nuevo porcentaje GMLPO 4
|
|
|
| sinput group "-- MDP/Ganancia máxima diaria --"
|
| input bool InpRmMdpIsStrict = true; // ¿MDP es estricto?
|
| input double InpRmPercentageOrMoneyMdp = 11.0; // Porcentaje o dinero (0 => MDP no usado)
|
| input TSN::ENUM_RISK_CALCULATION_MODE InpRmModeCalculationMdp = TSN::percentage; // Modo de cálculo de Ganancia Máxima Diaria
|
| input TSN::ENUM_APPLIED_PERCENTAGES InpRmAppliedPercentagesMdp = TSN::Balance; // Porcentaje MDP se aplica a
|
|
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| sinput group "-------| Modificador de riesgo (Oscar) |-------"
|
| input bool enable_mod_oscar = true; //Habilitar modificador?
|
| input double initial_risk_percenrt_to_mod = 1.0; //% positivo inicial
|
| input double max_risk_to_mod_oscar = 30.0; //Maximo riesgo en %
|
| input double multo_mod_oscar = 2.0; //Multiplicador
|
|
|
|
|
| sinput group ""
|
| sinput group "-------| Session |-------"
|
| input string InpSessionBaseName = "Sesion Nocturna"; //Nombre de la sesion
|
|
|
| sinput group "--| Rectangulo "
|
| input color clr_rect_session = clrMintCream; //Color del rectangulo de sesion
|
| input int width_sessoin = 1; //Rectangle Lines width
|
| input ENUM_LINE_STYLE style_line_rect = STYLE_SOLID; //Rectangle Line Style
|
| input bool fill_session = true; //Fill Rectangle session?
|
|
|
| sinput group "--| Lineas "
|
| input color inp_clr_lines = clrMintCream; //Color de las lineas
|
| input int width_sessoin_lines = 1; //Ancho de las lineas
|
| input ENUM_LINE_STYLE style_line_extra = STYLE_SOLID; //Estilo de las lineas
|
| input ENUM_TYPE_DRAW_RANGE_SESSION type_draw_session = draw_session_range_only_rect; //Tipo de dibujado de la sesion
|
|
|
| sinput group "--| De la sesion en si"
|
| input char inp_hora_inicio = 8;//Hora de inicio para poner ordenes (0-23)
|
| input char inp_min_inicio = 30;//Minuto de inicio para poner ordenes(0-59)
|
| input char inp_hora_fin = 9;//Hora de finalización para poner ordenes (1-23)
|
| input char inp_min_fin = 15; //Minuto de finalización poner ordenes (0-59)
|
|
|
| sinput group ""
|
| sinput group "-------| Session Asia |-------"
|
| input bool fill_rect_asia = true; // Rellenar el rectángulo de la sesión Asia
|
| input ENUM_LINE_STYLE style_rect_actia = STYLE_SOLID; // Estilo de línea para el rectángulo de Asia
|
| input int width_rect_asia = 1; // Ancho de la línea del rectángulo de Asia
|
| input color color_text_line_rect_asia = clrBisque; // Color del texto y línea del rectángulo de Asia
|
| input char hora_inicio_asia = 0; // Hora de inicio de la sesión asiática
|
| input char min_inicio_asia = 0; // Minuto de inicio de la sesión asiática
|
| input char hora_fin_asia = 8; // Hora de finalización de la sesión asiática
|
| input char min_fin_asia = 30; // Minuto de finalización de la sesión asiática
|
|
|
| sinput group ""
|
| sinput group "----------| Session Ny |----------"
|
| input char hora_inicio_ny = 16;
|
| input char min_inicio_ny = 0;
|
|
|
| sinput group ""
|
| sinput group "-------| Operation Days Configuration |-------"
|
| input bool enable_Monday = true; // Operar en lunes
|
| input bool enable_Tuesday = true; // Operar en martes
|
| input bool enable_Wednesday = true; // Operar en miércoles
|
| input bool enable_Thursday = true; // Operar en jueves
|
| input bool enable_Friday = true; // Operar en viernes
|
| input bool enable_Saturday = false; // Operar en sábado
|
| input bool enable_Sunday = false; // Operar en domingo
|
| input bool IsCryptoMarket = false; // ¿Es un mercado de criptomonedas?
|
| sinput group ""
|
| sinput group "-------| Operation Months Configuration |-------"
|
| input bool enable_Enero = true; // Operar en enero
|
| input bool enable_Febrero = true; // Operar en febrero
|
| input bool enable_Marzo = true; // Operar en marzo
|
| input bool enable_Abril = true; // Operar en abril
|
| input bool enable_Mayo = true; // Operar en mayo
|
| input bool enable_Junio = true; // Operar en junio
|
| input bool enable_Julio = true; // Operar en julio
|
| input bool enable_Agosto = true; // Operar en agosto
|
| input bool enable_Septiembre = true; // Operar en septiembre
|
| input bool enable_Octubre = true; // Operar en octubre
|
| input bool enable_Noviembre = true; // Operar en noviembre
|
| input bool enable_Diciembre = true; // Operar en diciembre
|
|
|
| sinput group ""
|
| sinput group "-------| Breakeven |-------"
|
| input bool use_be = true; // Enable Breakeven logic
|
| input TSN::ENUM_BREAKEVEN_TYPE type_break_even = TSN::BREAKEVEN_TYPE_RR; // Calculation method (RR, ATR, or fixed points)
|
| input ENUM_VERBOSE_LOG_LEVEL log_level_be = VERBOSE_LOG_LEVEL_ALL; // Break Even log level
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| sinput group "--- Breakeven based on Risk/Reward (RR) ---"
|
| input string be_rr_adv = "Requires a configured Stop Loss."; // Warning: Stop Loss is required to calculate RR
|
| input double be_rr_dbl = 1.0; // Risk/Reward ratio to activate Breakeven (e.g. 1.0)
|
| input TSN::ENUM_TYPE_EXTRA_BE_BY_RRR be_type_extra_rr = TSN::EXTRA_BE_RRR_BY_ATR; // Method to adjust Breakeven price (ATR or points)
|
| input double be_extra_points_rr_or_atr_multiplier = 1.0; // Adjustment value: ATR multiplier (atr 14 period) if method = ATR, or fixed points if method = Points
|
|
|
|
|
| sinput group "--- Breakeven based solely on ATR ---"
|
| input double be_atr_multiplier = 2.0; // ATR multiplier to trigger Breakeven (atr 14 period)
|
| input double be_atr_multiplier_extra = 1.0; // Additional multiplier for precise Breakeven adjustment (atr 14 period)
|
|
|
|
|
| sinput group "--- Breakeven based on fixed points ---"
|
| input int be_fixed_points_to_put_be = 200; // Minimum distance (in points) to trigger Breakeven
|
| input int be_fixed_points_extra = 100; // Extra points added when Breakeven is triggered
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| //---
|
| CEstrategia strategy(InpMagic, _Symbol, _Period, 0, 0, InpStrategyMaxDeviationOrders);
|
|
|
| //---
|
| int8_t idx_controler_w1 = INVALID_INDEX;
|
| int8_t idx_controler_curr = INVALID_INDEX;
|
| int8_t idx_bar_controlerd1 = INVALID_INDEX;
|
| int8_t idx_bar_mn1 = INVALID_INDEX;
|
|
|
| //---
|
| TSN::CModificatorOscar mod_oscar(max_risk_to_mod_oscar, initial_risk_percenrt_to_mod, multo_mod_oscar, hora_inicio_ny, min_inicio_ny);
|
|
|
| //---
|
| TSN::CYearFilter year_fil;
|
| TSN::CWeeklyFilter wekk_fil;
|
|
|
| //---
|
| TSN::CLossProfitManager g_loss_profit_manager; // LossProfitManager
|
| TSN::CBreakEvenBase* g_breakeven;
|
| TSN::CAtrOptimizedZero g_atr_opt_zero(PERIOD_CURRENT, _Symbol, 14);
|
|
|
| //---
|
| bool NewDay = false;
|
| uint g_trade_flags = 0;
|
|
|
| //+------------------------------------------------------------------+
|
| //| Expert initialization function |
|
| //+------------------------------------------------------------------+
|
| int OnInit()
|
| {
|
| //--- Registramos timeframes
|
| g_new_bar_manager.GetPosExecute(PERIOD_D1, idx_bar_controlerd1);
|
| g_new_bar_manager.GetPosExecute(_Period, idx_controler_curr);
|
| g_new_bar_manager.GetPosExecute(PERIOD_W1, idx_controler_w1);
|
| g_new_bar_manager.GetPosExecute(PERIOD_MN1, idx_bar_mn1);
|
|
|
| //---
|
| 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);
|
| }
|
|
|
| //--- Breakeven
|
| string _what = NULL;
|
| if(use_be)
|
| {
|
| TSNSTD_TRY_INI
|
| {
|
| TSN::CBreakEvenCreator be;
|
| be.SetBeByAtr(be_atr_multiplier, be_atr_multiplier_extra, &g_atr_opt_zero);
|
| be.SetBeByFixedPoints(be_fixed_points_to_put_be, be_fixed_points_extra);
|
| be.SetBeByRR(be_rr_dbl, be_type_extra_rr, be_extra_points_rr_or_atr_multiplier, &g_atr_opt_zero);
|
| TSN::BreakEvenCreatorRes be_res = be.Create(type_break_even, _Symbol, InpMagic);
|
| TSNSTD_TRY_EF(be_res.ok, true,
|
| TSN::CErrorTrace::FormatTrace(_what))
|
| g_breakeven = be_res.ptr;
|
| g_breakeven.AddLogFlags(log_level_be);
|
| CAutoCleaner::AddPtr(g_breakeven);
|
| }
|
| TSNSTD_TRY_END;
|
|
|
| //---
|
| if(_what != NULL)
|
| {
|
| FastLog(FUNCION_ACTUAL, FATAL_ERROR_TEXT, _what);
|
| return INIT_FAILED;
|
| }
|
| }
|
|
|
|
|
| //--- Sesiones
|
| sesion_asia.Create(_Symbol, _Period, 0, 0, true, true, hora_inicio_asia, min_inicio_asia, hora_fin_asia, min_fin_asia, "Session asia");
|
| sesion_asia.SetGrapichStyles(style_rect_actia, color_text_line_rect_asia, width_rect_asia, fill_rect_asia);
|
| sesion_asia.Set(width_rect_asia, STYLE_SOLID, color_text_line_rect_asia, color_text_line_rect_asia, color_text_line_rect_asia, draw_session_text_arriba, draw_session_range_only_rect);
|
|
|
| trading_session.Create(_Symbol, _Period, 0, 0, true, true, inp_hora_inicio, inp_min_inicio, inp_hora_fin, inp_min_fin, InpSessionBaseName);
|
| trading_session.SetGrapichStyles(style_line_rect, clr_rect_session, width_sessoin, fill_session);
|
| trading_session.SetExtra(inp_clr_lines, inp_clr_lines, style_line_extra, width_sessoin_lines, type_draw_session);
|
|
|
|
|
| //--- Filtro
|
| year_fil.Set(enable_Enero, enable_Febrero, enable_Marzo, enable_Abril, enable_Mayo, enable_Junio, enable_Julio, enable_Agosto, enable_Septiembre, enable_Octubre, enable_Noviembre, enable_Diciembre);
|
| wekk_fil.Set(enable_Monday, enable_Tuesday, enable_Wednesday, enable_Thursday, enable_Friday, enable_Saturday, enable_Sunday);
|
| wekk_fil.OperarCrypto(IsCryptoMarket);
|
|
|
|
|
| //--- Estrategia
|
| strategy.AddLogFlags(InpStrategyLogLevel);
|
| strategy.SetAtrTP_SL(&g_atr_opt_zero, InpStrategyAtrMultiplierTp, InpStrategyAtrMultiplierSl);
|
| strategy.SetOperateMode(TR_BUY_SELL, (ENUM_TYPE_TP_SL_FIXED)InpStrategyTypeTpSl);
|
| strategy.SetTP_SL((InpStrategySlPoint), (InpStrategyTpPoint));
|
| strategy.SetGen(RR_TP, InpStrategyTypeTpSl);
|
| strategy.SetNy(hora_inicio_ny, min_inicio_ny);
|
| if(InpRmLoteType == TSN::Fijo)
|
| strategy.FixedLotSize(InpRmLote);
|
|
|
|
|
| //--- Risk management
|
| TSNSTD_TRY_INI
|
| {
|
| TSN::CRiskManagementCreator manager;
|
| manager.SetPropirm(InpRmPropFirmBalance);
|
|
|
| //---
|
| TSN::MQLArtRMCreatorRes result = manager.GetRiskPointer(InpRmRiskMode, InpMagic, InpRmGetMode);
|
| TSNSTD_TRY_EF(result.ok, true,
|
| TSN::CErrorTrace::FormatTrace(_what))
|
|
|
| //---
|
| risk = result.ptr;
|
| risk.AddLogFlags(InpRmLogLevel);
|
| risk.SetLossProfitManager(g_loss_profit_manager);
|
| CAutoCleaner::AddPtr(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(risk.AddLP(InpRmPercentageOrMoneyMdl, InpRmAppliedPercentagesMdl, InpRmModeCalculationMdl, TSN::LP_MDL, true), true);
|
| TSNSTD_TRY_SE(risk.AddLP(InpRmPercentageOrMoneyGmlpo, InpRmAppliedPercentagesGmlpo, InpRmModeCalculationGmlpo, TSN::LP_GMLPO, true,
|
| (InpRmModeGmlpo != TSN::NO_DYNAMIC_GMLPO), to_modfied, to_apply), true);
|
| TSNSTD_TRY_SE(risk.AddLP(InpRmPercentageOrMoneyMl, InpRmAppliedPercentagesMl, InpRmModeCalculationMl, TSN::LP_ML, true), true);
|
| TSNSTD_TRY_SE(risk.AddLP(InpRmPercentageOrMoneyMwl, InpRmAppliedPercentagesMwl, InpRmModeCalculationMwl, TSN::LP_MWL, true), true);
|
| TSNSTD_TRY_SE(risk.AddLP(InpRmPercentageOrMoneyMdp, InpRmAppliedPercentagesMdp, InpRmModeCalculationMdp, TSN::LP_MDP, InpRmMdpIsStrict), true);
|
| risk.EndAddProfitLoss(); // Execute this every time we finish setting the maximum losses and profits
|
|
|
| // We add modifiers
|
| if(enable_mod_oscar)
|
| TSNSTD_TRY_SE(risk.AddModificator(mod_oscar), true);
|
| }
|
| TSNSTD_TRY_END;
|
|
|
| //---
|
| TSNSTD_TRY_N_EF(_err, true, TSN::CErrorTrace::FormatTrace(_what))
|
| }
|
| TSNSTD_TRY_END;
|
|
|
| //---
|
| if(_what != NULL) // error final
|
| {
|
| FastLog(FUNCION_ACTUAL, FATAL_ERROR_TEXT, _what);
|
| return INIT_FAILED;
|
| }
|
|
|
| //--- We initialize the account
|
| TSN::account_status.AddLogFlags(InpAccountStatusLogLevel);
|
| TSN::account_status.OnInitEvent();
|
|
|
| //---
|
| CAutoCleaner::AddFunction(TSN::CAccountStatus_Deinit);
|
| CAutoCleaner::AddFunction(CBasicEvents::Deinit);
|
|
|
|
|
| //---
|
| return(INIT_SUCCEEDED);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Expert deinitialization function |
|
| //+------------------------------------------------------------------+
|
| void OnDeinit(const int reason)
|
| {
|
| //---
|
| CAutoCleaner::Deinit(reason);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Expert tick function |
|
| //+------------------------------------------------------------------+
|
| void OnTick()
|
| {
|
| //---
|
| const datetime time_curr = TimeCurrent();
|
| NewDay = false;
|
| g_new_bar_manager.Execute(time_curr);
|
|
|
| //--- Bloque 1 | Control diario
|
| if(CNewBarManager_IsNewBarM1(g_new_bar_manager))
|
| {
|
| //--- Nuevo dia
|
| if(CNewBarManager_IsNewBar(g_new_bar_manager, idx_bar_controlerd1))
|
| {
|
| CBasicEvents::OnNewDay(time_curr);
|
| NewDay = true;
|
|
|
| //--- limpiamos siempre este o no
|
| TSNMQLART_U_BEVENTS_MAN_REM_F(g_trade_flags, BASICEVENT_REG_FLAG_ON_NEW_DAY);
|
|
|
| //--- Opt: la flag de onnewday=1 entonces si almenos hay un filtro ahora mismo..
|
| // aplicamos un and .. entonces g_tradeflags tenida su bit0 enceidiado si logra pasar eso
|
| g_trade_flags &= (year_fil.IsMonthTrade() | wekk_fil.IsDayTrade());
|
|
|
|
|
| //--- Nueva semana
|
| if(CNewBarManager_IsNewBar(g_new_bar_manager, idx_controler_w1))
|
| {
|
| CBasicEvents::OnNewWeek(time_curr);
|
| TSNMQLART_U_BEVENTS_MAN_REM_F(g_trade_flags, BASICEVENT_REG_FLAG_ON_NEW_WEEK);
|
| }
|
|
|
| //--- Nuevo mes
|
| if(CNewBarManager_IsNewBar(g_new_bar_manager, idx_bar_mn1))
|
| CBasicEvents::OnNewMonth(time_curr);
|
| }
|
| }
|
|
|
| //---
|
| if(TSN::account_status_positions_open)
|
| {
|
| #ifdef MQLARTICLES_RM_MULTI_EA_MODE
|
| risk.CalcProfit();
|
| #else // MQLARTICLES_RM_MULTI_EA_MODE
|
| ACCOUNTSTATUS_ONEVERYTICK
|
| #endif // MQLARTICLES_RM_MULTI_EA_MODE
|
| if(TSNMQLART_U_BEVENTS_MAN_TRADE_NOW(g_trade_flags))
|
| {
|
| if(g_loss_profit_manager.MaxLossIsSuperated())
|
| {
|
| const int type = g_loss_profit_manager.GetLastLossSuperatedType();
|
| if(type < TSN::LP_ML)
|
| {
|
| 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)
|
| {
|
| if(InpRmRiskMode == TSN::risk_mode_propfirm_dynamic_daiy_loss)
|
| Print("The expert advisor lost the funding test");
|
| else
|
| Print("Maximum loss exceeded now");
|
|
|
| //---
|
| risk.CloseAllPositions();
|
| Remover();
|
| }
|
| }
|
| else
|
| if(g_loss_profit_manager.MaxProfitIsSuperated())
|
| {
|
| // 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.
|
| risk.CloseAllPositions();
|
| TSNMQLART_U_BEVENTS_MAN_ADD_F(g_trade_flags, BASICEVENT_REG_FLAG_ON_NEW_DAY);
|
| Print("Excellent Maximum daily profit achieved");
|
| }
|
| }
|
| }
|
|
|
| //---
|
| if(use_be)
|
| g_breakeven.BreakEven();
|
|
|
| //---
|
| if(TSNMQLART_U_BEVENTS_MAN_NO_TRADE_NOW(g_trade_flags))
|
| return;
|
|
|
| //---
|
| if(CNewBarManager_IsNewBarM1(g_new_bar_manager))
|
| {
|
| ICTGen_FuncionOnBarM1(NewDay, time_curr);
|
| sesion_asia.OnNewBarM1();
|
| trading_session.OnNewBarM1();
|
|
|
| //---
|
| if(CNewBarManager_IsNewBar(g_new_bar_manager, idx_controler_curr))
|
| {
|
| strategy.OnNewBar(time_curr);
|
| }
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| TradeTransaction function |
|
| //+------------------------------------------------------------------+
|
| void OnTradeTransaction(const MqlTradeTransaction& trans,
|
| const MqlTradeRequest& request,
|
| const MqlTradeResult& result)
|
| {
|
| //---
|
| TSN::account_status.OnTradeTransactionEvent(trans);
|
| }
|
| //+------------------------------------------------------------------+
|