diff --git a/Experts/Nkanven/Dam Launch.ex5 b/Experts/Nkanven/Dam Launch.ex5 deleted file mode 100644 index 36324dc..0000000 Binary files a/Experts/Nkanven/Dam Launch.ex5 and /dev/null differ diff --git a/Experts/Nkanven/MidNightAngel.ex5 b/Experts/Nkanven/MidNightAngel.ex5 new file mode 100644 index 0000000..b060385 Binary files /dev/null and b/Experts/Nkanven/MidNightAngel.ex5 differ diff --git a/Experts/Nkanven/MidNightAngel.mq5 b/Experts/Nkanven/MidNightAngel.mq5 index 7fafa58..7d6fb37 100644 Binary files a/Experts/Nkanven/MidNightAngel.mq5 and b/Experts/Nkanven/MidNightAngel.mq5 differ diff --git a/Include/Nkanven/MidNightAngel/CheckHistory.mqh b/Include/Nkanven/MidNightAngel/CheckHistory.mqh new file mode 100644 index 0000000..8c5f1b0 --- /dev/null +++ b/Include/Nkanven/MidNightAngel/CheckHistory.mqh @@ -0,0 +1,27 @@ +//+------------------------------------------------------------------+ +//| CheckHistory.mqh | +//| Copyright 2021, Nkondog Anselme Venceslas | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2021, Nkondog Anselme Venceslas" +#property link "https://www.mql5.com" +//+------------------------------------------------------------------+ +//| defines | +//+------------------------------------------------------------------+ +// #define MacrosHello "Hello, world!" +// #define MacrosYear 2010 +//+------------------------------------------------------------------+ +//| DLL imports | +//+------------------------------------------------------------------+ +// #import "user32.dll" +// int SendMessageA(int hWnd,int Msg,int wParam,int lParam); +// #import "my_expert.dll" +// int ExpertRecalculate(int wParam,int lParam); +// #import +//+------------------------------------------------------------------+ +//| EX5 imports | +//+------------------------------------------------------------------+ +// #import "stdlib.ex5" +// string ErrorDescription(int error_code); +// #import +//+------------------------------------------------------------------+ diff --git a/Include/Nkanven/MidNightAngel/CloseTransactions.mqh b/Include/Nkanven/MidNightAngel/CloseTransactions.mqh new file mode 100644 index 0000000..ed3bd1b --- /dev/null +++ b/Include/Nkanven/MidNightAngel/CloseTransactions.mqh @@ -0,0 +1,94 @@ +//+------------------------------------------------------------------+ +//| CloseTransactions.mqh | +//| Copyright 2021, Nkondog Anselme Venceslas | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2021, Nkondog Anselme Venceslas" +#property link "https://www.mql5.com" + +CTrade trade; + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CloseTransactions(ENUM_SIGNAL_EXIT tType) + { + bool result = true; + int cnt = OrdersTotal(); + int cts = PositionsTotal(); + if(cnt > 0) + { + + + for(int i = cnt-1; i>=0; i--) + { + ulong ticket = OrderGetTicket(i); + if(OrderSelect(ticket)) + { + if(tType==SIGNAL_EXIT_BUY && (OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_LIMIT || OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP) && OrderGetInteger(ORDER_MAGIC)==InpMagicNumber) + { + if(!trade.OrderDelete(ticket)) + Print("Error (", GetLastError(), ") while deleting all buy orders"); + } + else + { + if(tType==SIGNAL_EXIT_SELL && (OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_LIMIT || OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP) && OrderGetInteger(ORDER_MAGIC)==InpMagicNumber) + { + if(!trade.OrderDelete(ticket)) + Print("Error (", GetLastError(), ") while deleting all sell orders"); + } + else + { + if(tType==SIGNAL_EXIT_ALL) + { + if(!trade.OrderDelete(ticket)) + Print("Error (", GetLastError(), ") while deleting all orders"); + } + } + } + } + else + { + Print("Error (", GetLastError(), ") while selecting order's ticket"); + } + } + } + + if(cts > 0) + { + for(int i = cts-1; i>=0; i--) + { + ulong ticket = PositionGetTicket(i); + if(PositionSelectByTicket(ticket)) + { + if(tType==SIGNAL_EXIT_BUY && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PositionGetInteger(POSITION_MAGIC)==InpMagicNumber) + { + if(!trade.PositionClose(ticket)) + Print("Error (", GetLastError(), ") while deleting all buy positions"); + } + else + { + if(tType==SIGNAL_EXIT_SELL && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && PositionGetInteger(POSITION_MAGIC)==InpMagicNumber) + { + if(!trade.PositionClose(ticket)) + Print("Error (", GetLastError(), ") while deleting all sell positions"); + } + else + { + if(tType==SIGNAL_EXIT_ALL) + { + if(!trade.PositionClose(ticket)) + Print("Error (", GetLastError(), ") while deleting all positions"); + } + } + } + + } + else + { + Print("Error (", GetLastError(), ") while selecting position by ticket"); + } + } + } + } +//+------------------------------------------------------------------+ diff --git a/Include/Nkanven/MidNightAngel/EntriesManager.mqh b/Include/Nkanven/MidNightAngel/EntriesManager.mqh new file mode 100644 index 0000000..2288fa9 Binary files /dev/null and b/Include/Nkanven/MidNightAngel/EntriesManager.mqh differ diff --git a/Include/Nkanven/MidNightAngel/LotSizeCal.mqh b/Include/Nkanven/MidNightAngel/LotSizeCal.mqh new file mode 100644 index 0000000..5ff8fc3 --- /dev/null +++ b/Include/Nkanven/MidNightAngel/LotSizeCal.mqh @@ -0,0 +1,56 @@ +//+------------------------------------------------------------------+ +//| LotSizeCal.mqh | +//| Copyright 2021, Nkondog Anselme Venceslas | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2021, Nkondog Anselme Venceslas" +#property link "https://www.mql5.com" + + +//Lot Size Calculator +void LotSizeCalculate(double SL=0) + { +//If the position size is dynamic + if(InpRiskDefaultSize==RISK_DEFAULT_AUTO) + { + //If the stop loss is not zero then calculate the lot size + if(SL!=0) + { + double RiskBaseAmount=0; + + //TickValue is the value of the individual price increment for 1 lot of the instrument, expressed in the account currenty + double TickValue=SymbolInfoDouble(gSymbol,SYMBOL_TRADE_TICK_VALUE); + //Define the base for the risk calculation depending on the parameter chosen + if(InpRiskBase==RISK_BASE_BALANCE) + RiskBaseAmount=AccountInfoDouble(ACCOUNT_BALANCE); + if(InpRiskBase==RISK_BASE_EQUITY) + RiskBaseAmount=AccountInfoDouble(ACCOUNT_EQUITY); + if(InpRiskBase==RISK_BASE_FREEMARGIN) + RiskBaseAmount=AccountInfoDouble(ACCOUNT_FREEMARGIN); + + //Calculate the Position Size + LotSize=((RiskBaseAmount*InpMaxRiskPerTrade/100)/(SL*TickValue)); + } + //If the stop loss is zero then the lot size is the default one + if(SL==0) + { + LotSize=InpDefaultLotSize; + } + } +//Normalize the Lot Size to satisfy the allowed lot increment and minimum and maximum position size + LotSize=MathFloor(LotSize/SymbolInfoDouble(gSymbol,SYMBOL_VOLUME_STEP))*SymbolInfoDouble(gSymbol,SYMBOL_VOLUME_STEP); + +//Limit the lot size in case it is greater than the maximum allowed by the user + if(LotSize>InpMaxLotSize) + LotSize=InpMaxLotSize; +//Limit the lot size in case it is greater than the maximum allowed by the broker + if(LotSize>SymbolInfoDouble(gSymbol,SYMBOL_VOLUME_MAX)) + LotSize=SymbolInfoDouble(gSymbol,SYMBOL_VOLUME_MAX); + Print("Lot ", LotSize, " Max lot ", SymbolInfoDouble(gSymbol,SYMBOL_VOLUME_MAX)); +//If the lot size is too small then set it to 0 and don't trade + if(LotSizeInpMaxStopLoss) + { + gIsPreChecksOk=false; + Print("Default Stop Loss must be between Minimum and Maximum Stop Loss Allowed"); + return; + } +//Check if the default take profit you are setting in above the minimum and below the maximum + if(InpDefaultTakeProfitInpMaxTakeProfit) + { + gIsPreChecksOk=false; + Print("Default Take Profit must be between Minimum and Maximum Take Profit Allowed"); + return; + } +//Check if the Lot Size is between the minimum and maximum + if(InpDefaultLotSizeInpMaxLotSize) + { + gIsPreChecksOk=false; + Print("Default Lot Size must be between Minimum and Maximum Lot Size Allowed"); + return; + } +//Slippage must be >= 0 + if(InpSlippage<0) + { + gIsPreChecksOk=false; + Print("Slippage must be a positive value"); + return; + } +//MaxSpread must be >= 0 + if(InpMaxSpread<0) + { + gIsPreChecksOk=false; + Print("Maximum Spread must be a positive value"); + return; + } +//MaxRiskPerTrade is a % between 0 and 100 + if(InpMaxRiskPerTrade<0 || InpMaxRiskPerTrade>100) + { + gIsPreChecksOk=false; + Print("Maximum Risk Per Trade must be a percentage between 0 and 100"); + return; + } + } diff --git a/Include/Nkanven/MidNightAngel/ScanPositions.mqh b/Include/Nkanven/MidNightAngel/ScanPositions.mqh new file mode 100644 index 0000000..dd7052e --- /dev/null +++ b/Include/Nkanven/MidNightAngel/ScanPositions.mqh @@ -0,0 +1,52 @@ +//+------------------------------------------------------------------+ +//| ScanPositions.mqh | +//| Copyright 2021, Nkondog Anselme Venceslas | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2021, Nkondog Anselme Venceslas" +#property link "https://www.mql5.com" + +//Scan all positions to find the ones submitted by the EA +//NOTE This function is defined as bool because we want to return true if it is successful and false if it fails +bool ScanPositions() + { + +//Scan all the orders, retrieving some of the details + gTotalOpenOrders = OrdersTotal(); + gTotalPositions = PositionsTotal(); + gTotalBuyPositions = 0; + gTotalSellPositions = 0; + gTotalTransactions = gTotalOpenOrders+gTotalPositions; + + for(int i=0; igLastBarTraded || gLastBarTraded==NULL) + gLastBarTraded=(datetime)PositionGetInteger(POSITION_TIME); + } + Print("Total positions ", gTotalPositions, " - Total buys ", gTotalBuyPositions, " - Total sells ", gTotalSellPositions); + return true; + } \ No newline at end of file diff --git a/Include/Nkanven/MidNightAngel/TradeManager.mqh b/Include/Nkanven/MidNightAngel/TradeManager.mqh new file mode 100644 index 0000000..3bf43bd --- /dev/null +++ b/Include/Nkanven/MidNightAngel/TradeManager.mqh @@ -0,0 +1,27 @@ +//+------------------------------------------------------------------+ +//| TradeManager.mqh | +//| Copyright 2021, Nkondog Anselme Venceslas | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2021, Nkondog Anselme Venceslas" +#property link "https://www.mql5.com" +//+------------------------------------------------------------------+ +//| defines | +//+------------------------------------------------------------------+ +// #define MacrosHello "Hello, world!" +// #define MacrosYear 2010 +//+------------------------------------------------------------------+ +//| DLL imports | +//+------------------------------------------------------------------+ +// #import "user32.dll" +// int SendMessageA(int hWnd,int Msg,int wParam,int lParam); +// #import "my_expert.dll" +// int ExpertRecalculate(int wParam,int lParam); +// #import +//+------------------------------------------------------------------+ +//| EX5 imports | +//+------------------------------------------------------------------+ +// #import "stdlib.ex5" +// string ErrorDescription(int error_code); +// #import +//+------------------------------------------------------------------+ diff --git a/Include/Nkanven/MidNightAngel/TradingHour.mqh b/Include/Nkanven/MidNightAngel/TradingHour.mqh new file mode 100644 index 0000000..7933ad8 --- /dev/null +++ b/Include/Nkanven/MidNightAngel/TradingHour.mqh @@ -0,0 +1,45 @@ +//+------------------------------------------------------------------+ +//| TradingHour.mqh | +//| Copyright 2021, Nkondog Anselme Venceslas | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2021, Nkondog Anselme Venceslas" +#property link "https://www.mql5.com" + +//Check and return if it is operation hours or not +void CheckOperationHours() + { +//If we are not using operating hours then IsOperatingHours is true and I skip the other checks + if(!InpUseTradingHours) + { + gIsOperatingHours=true; + return; + } +//Check if the current hour is between the allowed hours of operations, if so IsOperatingHours is set true + Print("1 this is ", (InpTradingHourStart==InpTradingHourEnd && dt.hour==InpTradingHourStart)); + + if(InpTradingHourStart==InpTradingHourEnd && dt.hour==InpTradingHourStart) + { + gIsOperatingHours=true; + return; + } + + if(InpTradingHourStart= InpTradingStartMin) + { + gIsOperatingHours=true; + return; + } + if(dt.hour > InpTradingHourStart) + { + gIsOperatingHours=true; + } + } + + if(InpTradingHourStart>InpTradingHourEnd && ((dt.hour>=InpTradingHourStart && dt.hour<=23) || (dt.hour<=InpTradingHourEnd && dt.hour>=0))) + { + gIsOperatingHours=true; + } + } +//+------------------------------------------------------------------+