forked from nique_372/MQLArticles
610 lines
25 KiB
MQL5
610 lines
25 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Ea2.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 tester_indicator "OrderBlockIndPart2.ex5"
|
|
#resource "\\Shared Projects\\MQLArticles\\Ob\\Indicator\\OrderBlockIndPart2.ex5"
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
enum ENUM_TP_SL_STYLE
|
|
{
|
|
ATR = 0, //Atr
|
|
POINT = 1 //Points
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Include |
|
|
//+------------------------------------------------------------------+
|
|
// To avoid unnecessary copying of the RSI data, we will define the define CONDITIONAL_PARTIAL_EXECUTE_WHEN_THE_ARE_POSITIONS
|
|
// This implies that the execution of Execute is only done when there are positions to review.
|
|
#define CONDITIONAL_PARTIAL_EXECUTE_WHEN_THE_ARE_POSITIONS
|
|
#define CONDITIONALPARTIAL_FACTORY_MQH
|
|
#define CONDITIONALPARTIAL_CONDITION_SIMPLE_RSI_MQH
|
|
#include "..\\..\\..\\PosMgmt\\ConditionalPartial\\Main.mqh"
|
|
#include "..\\..\\..\\PosMgmt\\Breakeven.mqh"
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Inputs |
|
|
//+------------------------------------------------------------------+
|
|
sinput group "-------| General |-------"
|
|
input ulong InpMagic = 545244; //Magic number
|
|
|
|
sinput group "-------| Ob Indicator settings |-------"
|
|
input ENUM_TIMEFRAMES InpObTimeframe = PERIOD_M5; //Order block timeframe
|
|
input int InpObRangoUniversalBusqueda = 500; //search range of order blocks
|
|
input int InpObWidth = 1; //Width order block
|
|
input bool InpObBack = true; //Back order block?
|
|
input bool InpObFill = true; //Fill order block?
|
|
input color InpObColorBajista = clrRed; //Bearish order block color
|
|
input color InpObColorAlcista = clrGreen; //Bullish order block color
|
|
input double InpObTransparency = 0.5; // Transparency from 0.0 (invisible) to 1.0 (opaque)
|
|
|
|
sinput group ""
|
|
sinput group "-------| Strategy |-------"
|
|
input ENUM_TP_SL_STYLE InpStrtTpSlStyle = ATR;//Tp and sl style:
|
|
|
|
sinput group "- TP SL by ATR "
|
|
input double InpStrtAtrMultiplier1 = 9.3;//Atr multiplier 1 (SL)
|
|
input double InpStrtAtrMultiplier2 = 24.4;//Atr multiplier 2 (TP)
|
|
|
|
sinput group "- TP SL by POINT "
|
|
input int InpStrtTpPoint = 1000; //TP in Points
|
|
input int InpStrtSlPoint = 1000; //SL in Points
|
|
|
|
sinput group ""
|
|
sinput group "-------| Account Status |-------"
|
|
input ENUM_VERBOSE_LOG_LEVEL InpLogLevelAccountStatus = VERBOSE_LOG_LEVEL_ERROR_ONLY; //(Account Status|Ticket Mangement) log level:
|
|
|
|
sinput group ""
|
|
sinput group "-------| Risk Management |-------"
|
|
input ENUM_LOTE_TYPE InpRmLoteType = Dinamico; //Lote Type:
|
|
input double InpRmLote = 0.1; //Lot size (only for fixed lot)
|
|
input ENUM_MODE_RISK_MANAGEMENT InpRmRiskMode = risk_mode_personal_account; //type of g_risk management mode
|
|
input ENUM_GET_LOT InpRmGetMode = 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 ENUM_RISK_CALCULATION_MODE InpRmModeCalculationMl = percentage; //Mode calculation Max Loss
|
|
input ENUM_APPLIED_PERCENTAGES InpRmAppliedPercentagesMl = 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 ENUM_RISK_CALCULATION_MODE InpRmModeCalculationMwl = percentage; //Mode calculation Max weekly Loss
|
|
input ENUM_APPLIED_PERCENTAGES InpRmAppliedPercentagesMwl = 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 ENUM_RISK_CALCULATION_MODE InpRmModeCalculationMdl = percentage; //Mode calculation Max daily loss
|
|
input ENUM_APPLIED_PERCENTAGES InpRmAppliedPercentagesMdl = Balance;//MDL percentage applies to:
|
|
|
|
sinput group "- GMLPO/Gross maximum loss per operation/Percentage to g_risk per operation -"
|
|
input ENUM_OF_DYNAMIC_MODES_OF_GMLPO InpRmModeGmlpo = NO_DYNAMIC_GMLPO; //Select GMLPO mode:
|
|
input double InpRmPercentageOrMoneyGmlpo = 2.0; //percentage or money (0 => not used GMLPO)
|
|
input ENUM_RISK_CALCULATION_MODE InpRmModeCalculationGmlpo = percentage; //Mode calculation Max Loss per operation
|
|
input ENUM_APPLIED_PERCENTAGES InpRmAppliedPercentagesGmlpo = 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 ENUM_RISK_CALCULATION_MODE InpRmModeCalculationMdp = percentage; //Mode calculation Max Daily Profit
|
|
input ENUM_APPLIED_PERCENTAGES InpRmAppliedPercentagesMdp = Balance;//MDP percentage applies to:
|
|
|
|
sinput group ""
|
|
sinput group "-------| Risk Modifier 1 |-------"
|
|
input bool InpRmod1Enable = false; // Enables dynamic g_risk adjustment (Booster)
|
|
input double InpRmod1Step = 2.0; // Increment applied to g_risk each time the condition is met
|
|
input double InpRmod1Start = 2.0; // Profit percentage from which g_risk adjustment begins
|
|
input ENUM_MULTIPLIER_METHOD_DR InpRmod1Method = DR_EXPONECIAL; // Type of progression used to increase g_risk
|
|
|
|
sinput group ""
|
|
sinput group "-------| Risk modifier 2 |-------"
|
|
input bool InpRmod2Enable = false; //Activate g_risk modifier 2
|
|
input string InpRmod2StrPercentagesToApply = "6, 8, 10, 20, 25"; //Percentages to apply
|
|
|
|
sinput group ""
|
|
sinput group "-------| Risk modifier 3 by Kevin |-------"
|
|
input bool InpRmod3Enable = false; //Activate g_risk modifier 3
|
|
input double InpRmod3Constant = 8.0; //Function constant
|
|
|
|
sinput group ""
|
|
sinput group "-------| Session |-------"
|
|
input char InpSessionStartHour = 1; // Start hour to operate (0-23)
|
|
input char InpSessionStartMinute = 0; // Start minute to operate (0-59)
|
|
input char InpSessionEndHour = 23; // End hour to operate (1-23)
|
|
input char InpSessionEndMinute = 0; // End minute to operate (0-59)
|
|
|
|
sinput group ""
|
|
sinput group "-------| Breakeven |-------"
|
|
input bool InpBeUse = false; // Enable Breakeven logic
|
|
input ENUM_BREAKEVEN_TYPE InpBeType = BREAKEVEN_TYPE_RR; // Calculation method (RR, ATR, or fixed points)
|
|
input ENUM_VERBOSE_LOG_LEVEL InpBeLogLevel = VERBOSE_LOG_LEVEL_ERROR_ONLY; // Break Even log level:
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
sinput group "--- Breakeven based on Risk/Reward (RR) ---"
|
|
input string InpBeRrAdv = "Requires a configured Stop Loss."; // Warning: Stop Loss is required to calculate RR
|
|
input double InpBeRrRatio = 1.0; // Risk/Reward ratio to activate Breakeven (e.g. 1.0)
|
|
input ENUM_TYPE_EXTRA_BE_BY_RRR InpBeRrTypeExtra = EXTRA_BE_RRR_BY_ATR;// Method to adjust Breakeven price (ATR or points)
|
|
input double InpBeRrExtraPointsOrAtrMultiplier = 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 InpBeAtrMultiplier = 2.0; // ATR multiplier to trigger Breakeven (atr 14 period)
|
|
input double InpBeAtrMultiplierExtra = 1.0; // Additional multiplier for precise Breakeven adjustment (atr 14 period)
|
|
|
|
sinput group "--- Breakeven based on fixed points ---"
|
|
input int InpBeFixedPointsToPutBe = 200; // Minimum distance (in points) to trigger Breakeven
|
|
input int InpBeFixedPointsExtra = 100; // Extra points added when Breakeven is triggered
|
|
|
|
sinput group ""
|
|
sinput group "-------| Partial Closures by Rsi condition |-------"
|
|
input ENUM_VERBOSE_LOG_LEVEL InpPartialsLogLevel = VERBOSE_LOG_LEVEL_ERROR_ONLY; // Partial Closures log level
|
|
input bool InpPartialsIsEnable = true; // Enable partials ?
|
|
input ENUM_TYPE_CONDITIONAL_PARTIAL_CLASS InpPartialsClassManagerType = CONDITIONAL_PARTIAL_CLASS_TYPE_BASE; // Partial class manager type:
|
|
input double InpPartialsVolumeToClosePercentage = 20.0; // Volume to close
|
|
input ENUM_TIMEFRAMES InpPartialsRsiTimeframe = PERIOD_CURRENT; // Rsi timeframe
|
|
input int InpPartialsRsiPeriod = 14; // Rsi period
|
|
input double InpPartialsRsiOverBoughtLevel = 70.0; // Rsi overbought level
|
|
input double InpPartialsRsiOverSoldLevel = 30.0; // Rsi oversold level
|
|
input double InpPartialsMinDistanceInAtrMul = 1.0; // Min distance between partials in atr14 mult
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Global variables |
|
|
//+------------------------------------------------------------------+
|
|
CTrade g_trade;
|
|
CRiskManagemet* g_risk;
|
|
CBreakEven g_break_even(InpMagic, _Symbol);
|
|
CConditionalPartials* g_partials;
|
|
CAtr* g_atr;
|
|
|
|
//--- Handles
|
|
int order_block_indicator_handle;
|
|
int ma_handle;
|
|
|
|
//--- Global buffers
|
|
double tp1[];
|
|
double tp2[];
|
|
double sl1[];
|
|
double sl2[];
|
|
|
|
//--- Session
|
|
datetime start_sesion;
|
|
datetime end_sesion;
|
|
|
|
//--- General
|
|
CBarControlerFast bar_d1(PERIOD_D1, _Symbol);
|
|
CBarControlerFast bar_w1(PERIOD_W1, _Symbol);
|
|
CBarControlerFast bar_mn1(PERIOD_MN1, _Symbol);
|
|
CBarControlerFast bar_curr(PERIOD_CURRENT, _Symbol);
|
|
CDynamicRisk riesgo_c(InpRmod1Step, InpRmod1Start, LP_GMLPO, InpRmod1Method);
|
|
CModifierDynamicRisk risk_modificator(InpRmod2StrPercentagesToApply);
|
|
CMathDynamicRisk risk_modificator_kevin(InpRmod3Constant);
|
|
|
|
//---
|
|
bool CanTrade = true;
|
|
CAtrUltraOptimized atr_ultra_optimized;
|
|
const CLossProfitManager* g_loss_profit_manager;
|
|
//+------------------------------------------------------------------+
|
|
//| Expert initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
//--- Atr
|
|
atr_ultra_optimized.SetVariables(_Period, _Symbol, 0, 14);
|
|
atr_ultra_optimized.SetInternalPointer();
|
|
|
|
//--- We set the breakeven values so its use is allowed
|
|
if(InpBeUse)
|
|
{
|
|
g_break_even.SetBeByAtr(InpBeAtrMultiplier, InpBeAtrMultiplierExtra, GetPointer(atr_ultra_optimized));
|
|
g_break_even.SetBeByFixedPoints(InpBeFixedPointsToPutBe, InpBeFixedPointsExtra);
|
|
g_break_even.SetBeByRR(InpBeRrRatio, InpBeRrTypeExtra, InpBeRrExtraPointsOrAtrMultiplier, GetPointer(atr_ultra_optimized));
|
|
g_break_even.SetInternalPointer(InpBeType);
|
|
g_break_even.obj.AddLogFlags(InpBeLogLevel);
|
|
}
|
|
|
|
//--- Partials
|
|
if(InpPartialsIsEnable)
|
|
{
|
|
// Atr creation
|
|
g_atr = new CAtr();
|
|
g_atr.Create(_Period, _Symbol, 14, true, true);
|
|
g_atr.SetAsSeries(true);
|
|
|
|
// We assign to g_partilas the dynamic instance returned by CConditionalPartialsFactory::Create(...)
|
|
g_partials = CConditionalPartialsFactory::Create(InpPartialsClassManagerType);
|
|
|
|
// Initial log flags
|
|
g_partials.AddLogFlags(InpPartialsLogLevel);
|
|
|
|
// Create condition
|
|
CConditionalPartialsIndRsi* rsi_condition = new CConditionalPartialsIndRsi();
|
|
|
|
// Rsi condition config
|
|
if(!rsi_condition.Init(InpPartialsRsiTimeframe, _Symbol, InpPartialsRsiPeriod, InpPartialsRsiOverBoughtLevel, InpPartialsRsiOverSoldLevel))
|
|
return INIT_PARAMETERS_INCORRECT;
|
|
|
|
// Condition config
|
|
ConditionalPartialConfig config;
|
|
config.condition = rsi_condition;
|
|
config.min_distance_to_close_pos = CreateDiffptr(MODE_DIFF_BY_ATR, _Symbol, g_atr, 0, InpPartialsMinDistanceInAtrMul);
|
|
config.str_percentage_volume_to_close = DoubleToString(InpPartialsVolumeToClosePercentage, 4);
|
|
config.magic_number = InpMagic;
|
|
|
|
// Init partials
|
|
if(g_partials.Init(config))
|
|
{
|
|
account_status.AddItemFast(g_partials); // Add to account status
|
|
}
|
|
else // Error in parameters
|
|
return INIT_PARAMETERS_INCORRECT;
|
|
|
|
if(InpPartialsClassManagerType == CONDITIONAL_PARTIAL_CLASS_TYPE_CONSTANT)
|
|
{
|
|
CConditionalPartialsConst* partial = (CConditionalPartialsConst*)g_partials;
|
|
partial.ForzeToClose(true);
|
|
}
|
|
}
|
|
|
|
|
|
//--- Indicators
|
|
// Create ob handle
|
|
order_block_indicator_handle = CreateIndicatorObHandle();
|
|
|
|
// Create ma handle
|
|
ma_handle = iMA(_Symbol, InpObTimeframe, 30, 0, MODE_EMA, PRICE_CLOSE);
|
|
|
|
// Check ma
|
|
if(ma_handle == INVALID_HANDLE)
|
|
{
|
|
Print("The ema indicator is not available latest error: ", _LastError);
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
ChartIndicatorAdd(0, 0, ma_handle);
|
|
|
|
//--- Trade
|
|
g_trade.SetExpertMagicNumber(InpMagic);
|
|
|
|
//--- Risk management
|
|
CRiskPointer* manager = new CRiskPointer(InpMagic, InpRmGetMode);
|
|
manager.SetPropirm(InpRmPropFirmBalance);
|
|
g_risk = manager.GetRiskPointer(InpRmRiskMode);
|
|
g_risk.AddLogFlags(InpRmLogLevel);
|
|
g_risk.SetLote(CreateLotePtr(_Symbol));
|
|
|
|
|
|
// We set the parameters
|
|
string to_apply = InpRmStrPercentagesToApply, to_modfied = InpRmStrPercentagesToBeReviewed;
|
|
|
|
if(InpRmModeGmlpo == DYNAMIC_GMLPO_FIXED_PARAMETERS)
|
|
SetDynamicUsingFixedParameters(InpRmBalancePercentageToActivateTheRisk1, InpRmBalancePercentageToActivateTheRisk2, InpRmBalancePercentageToActivateTheRisk3
|
|
, InpRmBalancePercentageToActivateTheRisk4, InpRmPercentageToBeModified1, InpRmPercentageToBeModified2, InpRmPercentageToBeModified3, InpRmPercentageToBeModified4
|
|
, to_modfied, to_apply);
|
|
|
|
g_risk.AddLoss(InpRmPercentageOrMoneyMdl, InpRmAppliedPercentagesMdl, InpRmModeCalculationMdl, LP_MDL, true);
|
|
g_risk.AddLoss(InpRmPercentageOrMoneyGmlpo, InpRmAppliedPercentagesGmlpo, InpRmModeCalculationGmlpo, LP_GMLPO, true, (InpRmModeGmlpo != NO_DYNAMIC_GMLPO), to_modfied, to_apply);
|
|
g_risk.AddLoss(InpRmPercentageOrMoneyMl, InpRmAppliedPercentagesMl, InpRmModeCalculationMl, LP_ML, true);
|
|
g_risk.AddLoss(InpRmPercentageOrMoneyMwl, InpRmAppliedPercentagesMwl, InpRmModeCalculationMwl, LP_MWL, true);
|
|
g_risk.AddProfit(InpRmPercentageOrMoneyMdp, InpRmAppliedPercentagesMdp, InpRmModeCalculationMdp, LP_MDP, InpRmMdpIsStrict);
|
|
g_risk.EndAddProfitLoss(); // Execute this every time we finish setting the maximum losses and profits
|
|
g_loss_profit_manager = g_risk.GetLossProfitManager();
|
|
|
|
// We add modifiers
|
|
if(InpRmod1Enable)
|
|
g_risk.AddModificator(riesgo_c);
|
|
|
|
if(InpRmod2Enable)
|
|
|
|
g_risk.AddModificator(risk_modificator);
|
|
|
|
if(InpRmod3Enable)
|
|
g_risk.AddModificator(risk_modificator_kevin);
|
|
|
|
// We finish by adding it
|
|
account_status.AddItemFast(g_risk);
|
|
|
|
// We delete the temporary pointer
|
|
delete manager;
|
|
|
|
//--- We initialize the account
|
|
account_status.AddLogFlagTicket(InpLogLevelAccountStatus);
|
|
account_status.AddLogFlags(InpLogLevelAccountStatus);
|
|
account_status.OnInitEvent();
|
|
|
|
//--- We configure the arrays in series
|
|
ArraySetAsSeries(tp1, true);
|
|
ArraySetAsSeries(tp2, true);
|
|
ArraySetAsSeries(sl1, true);
|
|
ArraySetAsSeries(sl2, true);
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
//--- Indicators
|
|
ChartIndicatorDelete(0, 0, ChartIndicatorName(0, 0, GetMovingAverageIndex()));
|
|
ChartIndicatorDelete(0, 0, "Order Block Indicator");
|
|
|
|
if(ma_handle != INVALID_HANDLE)
|
|
IndicatorRelease(ma_handle);
|
|
|
|
if(order_block_indicator_handle != INVALID_HANDLE)
|
|
IndicatorRelease(order_block_indicator_handle);
|
|
|
|
//--- Partials
|
|
if(InpPartialsIsEnable)
|
|
{
|
|
delete g_atr;
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert tick function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTick()
|
|
{
|
|
//--- General
|
|
const datetime time_curr = TimeCurrent();
|
|
|
|
//--- Code that runs every new day
|
|
if(bar_d1.IsNewBar(time_curr))
|
|
{
|
|
account_status.OnNewDay();
|
|
|
|
if(bar_w1.IsNewBar(time_curr))
|
|
account_status.OnNewWeek();
|
|
|
|
if(bar_mn1.IsNewBar(time_curr))
|
|
account_status.OnNewMonth();
|
|
|
|
CanTrade = true;
|
|
}
|
|
|
|
//---
|
|
if(account_status_positions_open)
|
|
{
|
|
CAccountStatus_OnTickEvent
|
|
if(CanTrade)
|
|
{
|
|
if(g_loss_profit_manager.MaxLossIsSuperated())
|
|
{
|
|
const ENUM_TYPE_LOSS_PROFIT type = g_loss_profit_manager.GetLastLossSuperatedType();
|
|
if(type == LP_ML)
|
|
{
|
|
if(InpRmRiskMode == risk_mode_propfirm_dynamic_daiy_loss)
|
|
{
|
|
Print("The expert advisor lost the funding test");
|
|
}
|
|
else
|
|
{
|
|
Print("Maximum loss exceeded now");
|
|
}
|
|
|
|
//---
|
|
Remover();
|
|
}
|
|
else
|
|
if(type == LP_MDL)
|
|
{
|
|
Print("Maximum daily loss exceeded now");
|
|
}
|
|
|
|
//---
|
|
g_risk.CloseAllPositions();
|
|
CanTrade = false;
|
|
}
|
|
else
|
|
if(g_loss_profit_manager.MaxProfitIsSuperated())
|
|
{
|
|
if(g_loss_profit_manager.GetLastProfitSuperatedType() != LP_MDP)
|
|
return;
|
|
g_risk.CloseAllPositions();
|
|
Print("Excellent Maximum daily profit achieved");
|
|
CanTrade = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
//--- Check Session
|
|
if(time_curr > end_sesion)
|
|
{
|
|
start_sesion = HoraYMinutoADatetime(InpSessionStartHour, InpSessionStartMinute, time_curr);
|
|
end_sesion = HoraYMinutoADatetime(InpSessionEndHour, InpSessionEndMinute, time_curr);
|
|
|
|
if(start_sesion > end_sesion)
|
|
end_sesion = end_sesion + 86400;
|
|
}
|
|
|
|
//--- Breakeven
|
|
if(InpBeUse)
|
|
g_break_even.obj.BreakEven();
|
|
|
|
//--- bar controlation
|
|
const bool new_bar = bar_curr.IsNewBar(time_curr);
|
|
|
|
//--- Partials
|
|
if(InpPartialsIsEnable && new_bar)
|
|
{
|
|
g_atr.CopyData(0, 1); // Copy atr data
|
|
g_partials.Execute(time_curr); // Execution in newbar
|
|
}
|
|
|
|
//--- Check to operate
|
|
if(!CanTrade)
|
|
return;
|
|
|
|
//--- Strategy
|
|
if(new_bar)
|
|
{
|
|
if(time_curr > start_sesion && time_curr < end_sesion)
|
|
{
|
|
if(g_risk.GetPositionsTotal() == 0)
|
|
{
|
|
CopyBuffer(order_block_indicator_handle, 2, 0, 5, tp1);
|
|
CopyBuffer(order_block_indicator_handle, 3, 0, 5, tp2);
|
|
CopyBuffer(order_block_indicator_handle, 4, 0, 5, sl1);
|
|
CopyBuffer(order_block_indicator_handle, 5, 0, 5, sl2);
|
|
|
|
if(tp1[0] > 0 && tp2[0] > 0 && sl1[0] > 0 && sl2[0] > 0)
|
|
{
|
|
if(tp2[0] > sl2[0]) // buy orders
|
|
{
|
|
const double ASK = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits);
|
|
g_risk.SetStopLoss(ASK - sl1[0]);
|
|
const double lot = (InpRmLoteType == Dinamico ? g_risk.GetLote(ORDER_TYPE_BUY, ASK, 0, 0) : InpRmLote);
|
|
g_trade.Buy(lot, _Symbol, ASK, sl1[0], tp2[0], "Order Block EA Buy");
|
|
}
|
|
else
|
|
if(sl2[0] > tp2[0]) // sell orders
|
|
{
|
|
const double BID = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits);
|
|
g_risk.SetStopLoss(sl1[0] - BID);
|
|
const double lot = (InpRmLoteType == Dinamico ? g_risk.GetLote(ORDER_TYPE_SELL, BID, 0, 0) : InpRmLote);
|
|
g_trade.Sell(lot, _Symbol, BID, sl1[0], tp2[0], "Order Block EA Sell");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| TradeTransaction function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTradeTransaction(const MqlTradeTransaction & trans,
|
|
const MqlTradeRequest & request,
|
|
const MqlTradeResult & result)
|
|
{
|
|
account_status.OnTradeTransactionEvent(trans);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Extra Functions |
|
|
//+------------------------------------------------------------------+
|
|
int GetMovingAverageIndex(long chart_id = 0)
|
|
{
|
|
int total_indicators = ChartIndicatorsTotal(chart_id, 0);
|
|
for(int i = 0; i < total_indicators; i++)
|
|
{
|
|
string indicator_name = ChartIndicatorName(chart_id, 0, i);
|
|
if(StringFind(indicator_name, "MA") >= 0)
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
int CreateIndicatorObHandle()
|
|
{
|
|
//--- We configure the indicator parameters
|
|
MqlParam param[19];
|
|
|
|
param[0].type = TYPE_STRING;
|
|
param[0].string_value = "::Shared Projects\\MQLArticles\\Ob\\Indicator\\OrderBlockIndPart2.ex5";
|
|
|
|
param[1].type = TYPE_STRING;
|
|
param[1].string_value = "--- Order Block Indicator settings ---";
|
|
|
|
param[2].type = TYPE_BOOL;
|
|
param[2].integer_value = false;
|
|
|
|
param[3].type = TYPE_STRING;
|
|
param[3].string_value = "-- Order Block --";
|
|
|
|
param[4].type = TYPE_INT;
|
|
param[4].integer_value = InpObRangoUniversalBusqueda;
|
|
|
|
param[5].type = TYPE_INT;
|
|
param[5].integer_value = InpObWidth;
|
|
|
|
param[6].type = TYPE_BOOL;
|
|
param[6].integer_value = InpObBack;
|
|
|
|
param[7].type = TYPE_BOOL;
|
|
param[7].integer_value = InpObFill;
|
|
|
|
param[8].type = TYPE_COLOR;
|
|
param[8].integer_value = InpObColorBajista;
|
|
|
|
param[9].type = TYPE_COLOR;
|
|
param[9].integer_value = InpObColorAlcista;
|
|
|
|
param[10].type = TYPE_DOUBLE;
|
|
param[10].double_value = InpObTransparency;
|
|
|
|
param[11].type = TYPE_STRING;
|
|
param[11].string_value = "-- Strategy --";
|
|
|
|
param[12].type = TYPE_INT;
|
|
param[12].integer_value = InpStrtTpSlStyle;
|
|
|
|
param[13].type = TYPE_STRING;
|
|
param[13].string_value = "- ATR";
|
|
|
|
param[14].type = TYPE_DOUBLE;
|
|
param[14].double_value = InpStrtAtrMultiplier1;
|
|
|
|
param[15].type = TYPE_DOUBLE;
|
|
param[15].double_value = InpStrtAtrMultiplier2;
|
|
|
|
param[16].type = TYPE_STRING;
|
|
param[16].string_value = "- POINT";
|
|
|
|
param[17].type = TYPE_INT;
|
|
param[17].integer_value = InpStrtTpPoint;
|
|
|
|
param[18].type = TYPE_INT;
|
|
param[18].integer_value = InpStrtSlPoint;
|
|
|
|
order_block_indicator_handle = IndicatorCreate(_Symbol, InpObTimeframe, IND_CUSTOM, ArraySize(param), param);
|
|
|
|
if(order_block_indicator_handle == INVALID_HANDLE)
|
|
{
|
|
Print("The order blocks indicator is not available last error: ", _LastError);
|
|
ExpertRemove();
|
|
return INVALID_HANDLE;
|
|
}
|
|
|
|
ChartIndicatorAdd(0, 0, order_block_indicator_handle);
|
|
return order_block_indicator_handle;
|
|
}
|
|
//+------------------------------------------------------------------+
|