diff --git a/Experts/Equilibrium.ex5 b/Experts/Equilibrium.ex5 index 3df5634..f8b1208 100644 Binary files a/Experts/Equilibrium.ex5 and b/Experts/Equilibrium.ex5 differ diff --git a/Experts/Equilibrium.mq5 b/Experts/Equilibrium.mq5 index fc382cb..6a2c0f2 100644 --- a/Experts/Equilibrium.mq5 +++ b/Experts/Equilibrium.mq5 @@ -120,7 +120,7 @@ void InitializeVariables() void CheckSpread() { //Get the current spread in points, the (int) transforms the double coming from MarketInfo into an integer to avoid a warning when compiling - double SpreadCurr=Spread; + long SpreadCurr=Spread; Print("Spread ", SpreadCurr); if(SpreadCurr<=MaxSpread) { diff --git a/Experts/MAGrid.ex5 b/Experts/MAGrid.ex5 new file mode 100644 index 0000000..1b4cef6 Binary files /dev/null and b/Experts/MAGrid.ex5 differ diff --git a/Experts/MAGrid.mq5 b/Experts/MAGrid.mq5 new file mode 100644 index 0000000..377b27a --- /dev/null +++ b/Experts/MAGrid.mq5 @@ -0,0 +1,99 @@ +//+------------------------------------------------------------------+ +//| MAGrid.mq5 | +//| Copyright 2021, Nkondog Anselme Venceslas | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2021, Nkondog Anselme Venceslas" +#property link "https://www.mql5.com" +#property version "1.00" + +// Moving Average grid strategy +/* +Set pending orders x poinst above and below price. +If price above SMA, buy and set buy orders x time the ATR above and below price. +If price below SMA, sell and set sell orders x time the ATR above and below price. +Close all position at the close of the first candle crossing the moving average. + +Open positions and set orders if there's nothing. At take profit, close all pending orders and reopen others +*/ +#include +#include +CiMA* ma; +CiATR* atr; + +#include // Description of variables +//#include // Error library +//#include // Prechecks +//#include // +//#include +#include // Scan for opened positions +//#include //Check transaction history +//#include //Manage trade dynamic open and close conditions +#include // Check buy and sell entries signals and execute them +#include // Lot size calculate +//#include // Close opened positions + + +//+------------------------------------------------------------------+ +//| Expert initialization function | +//+------------------------------------------------------------------+ +int OnInit() + { +//--- + ma = new CiMA(); + ma.Create(gSymbol, PERIOD_CURRENT, InpFastPeriods, InpFastAppliedPrice, InpFastMethod, PRICE_CLOSE); + + atr = new CiATR(); + atr.Create(gSymbol, PERIOD_CURRENT, InpAtrPeriod); +//--- + return(INIT_SUCCEEDED); + } +//+------------------------------------------------------------------+ +//| Expert deinitialization function | +//+------------------------------------------------------------------+ +void OnDeinit(const int reason) + { +//--- + + } +//+------------------------------------------------------------------+ +//| Expert tick function | +//+------------------------------------------------------------------+ +void OnTick() + { +//--- + SymbolInfoTick(_Symbol,last_tick); + ma.Refresh(-1); + gMa = ma.Main(1); + + atr.Refresh(-1); + gAtr = atr.Main(1); + ScanPositions(); + + Print("Total transaction ", gTotalTransactions); + if(gTotalTransactions>0) + return; + + CheckSpread(); + EvaluateEntry(); + ExecuteEntry(); + } +//+------------------------------------------------------------------+ + +//Check and return if the spread is not too high +void CheckSpread() + { +//Get the current spread in points, the (int) transforms the double coming from MarketInfo into an integer to avoid a warning when compiling + long SpreadCurr=SymbolInfoInteger(gSymbol, SYMBOL_SPREAD); + Print("Spread ", SpreadCurr); + if(SpreadCurr<=InpMaxSpread) + { + gIsSpreadOK=true; + } + else + { + gIsSpreadOK=false; + } + } +//+------------------------------------------------------------------+ +//+------------------------------------------------------------------+ diff --git a/Experts/Nkanven/GDeaLite.ex5 b/Experts/Nkanven/GDeaLite.ex5 index c9fd358..95ee4cc 100644 Binary files a/Experts/Nkanven/GDeaLite.ex5 and b/Experts/Nkanven/GDeaLite.ex5 differ diff --git a/Experts/Nkanven/GDeaLite.mq5 b/Experts/Nkanven/GDeaLite.mq5 index 1346f33..dbb3948 100644 --- a/Experts/Nkanven/GDeaLite.mq5 +++ b/Experts/Nkanven/GDeaLite.mq5 @@ -57,6 +57,23 @@ void OnDeinit(const int reason) void OnTick() { //--- + fsma.Refresh(-1); + ssma.Refresh(-1); + + gSsma = ssma.Main(1); +//isQualifiedCandle(0); + OrderClose(); + if(!ScanPositions()) + return; + if(OrdersTotal()>0) + return; + CheckSpread(); + entryConditions(); + EvaluateEntry(); + ExecuteEntry(); + + Comment( + "Expert Advisor by Anselme Nkondog (c) 2021\n"); } //+------------------------------------------------------------------+ diff --git a/Experts/TrendlinesEA.ex5 b/Experts/TrendlinesEA.ex5 index 8767fc0..05fe54b 100644 Binary files a/Experts/TrendlinesEA.ex5 and b/Experts/TrendlinesEA.ex5 differ diff --git a/Include/E_EntriesManagement.mqh b/Include/E_EntriesManagement.mqh index d69973d..e202f27 100644 Binary files a/Include/E_EntriesManagement.mqh and b/Include/E_EntriesManagement.mqh differ diff --git a/Include/E_Parameters.mqh b/Include/E_Parameters.mqh index 4eb0be0..d7ff205 100644 Binary files a/Include/E_Parameters.mqh and b/Include/E_Parameters.mqh differ diff --git a/Include/Nkanven/GDea/ClosePositions.mqh b/Include/Nkanven/GDea/ClosePositions.mqh index e2357b9..219a413 100644 --- a/Include/Nkanven/GDea/ClosePositions.mqh +++ b/Include/Nkanven/GDea/ClosePositions.mqh @@ -5,23 +5,34 @@ //+------------------------------------------------------------------+ #property copyright "Copyright 2021, Nkondog Anselme Venceslas" #property link "https://www.mql5.com" + +CTrade trade; + //+------------------------------------------------------------------+ -//| 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 +bool OrderClose() + { + bool result = true; + int cnt = OrdersTotal(); + if(cnt == 1) + { + + + for(int i = cnt-1; i>=0; i--) + { + ulong ticket = OrderGetTicket(i); + if(OrderSelect(ticket)) + { + + result &= trade.OrderDelete(ticket); + } + else + { + result = false; + } + } + } + return(result); + } //+------------------------------------------------------------------+ diff --git a/Include/Nkanven/GDea/EntriesManager.mqh b/Include/Nkanven/GDea/EntriesManager.mqh index 2b66cbe..23c319f 100644 Binary files a/Include/Nkanven/GDea/EntriesManager.mqh and b/Include/Nkanven/GDea/EntriesManager.mqh differ diff --git a/Include/Nkanven/GDea/LotSizeCal.mqh b/Include/Nkanven/GDea/LotSizeCal.mqh index f3042e7..4d4ba0f 100644 --- a/Include/Nkanven/GDea/LotSizeCal.mqh +++ b/Include/Nkanven/GDea/LotSizeCal.mqh @@ -5,23 +5,53 @@ //+------------------------------------------------------------------+ #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 -//+------------------------------------------------------------------+ + + +//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; + double RiskBase=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(RiskBase==RISK_BASE_BALANCE) + RiskBaseAmount=AccountInfoDouble(ACCOUNT_BALANCE); + if(RiskBase==RISK_BASE_EQUITY) + RiskBaseAmount=AccountInfoDouble(ACCOUNT_EQUITY); + if(RiskBase==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(LotSize=0; i--) + { + ulong ticket = OrderGetTicket(i); + if(OrderSelect(ticket)) + { + + result &= trade.OrderDelete(ticket); + } + else + { + result = false; + } + } + } + return(result); + } +//+------------------------------------------------------------------+ diff --git a/Include/Nkanven/MAGrid/EntriesManager.mqh b/Include/Nkanven/MAGrid/EntriesManager.mqh new file mode 100644 index 0000000..52f6a1c Binary files /dev/null and b/Include/Nkanven/MAGrid/EntriesManager.mqh differ diff --git a/Include/Nkanven/MAGrid/LotSizeCal.mqh b/Include/Nkanven/MAGrid/LotSizeCal.mqh new file mode 100644 index 0000000..4d4ba0f --- /dev/null +++ b/Include/Nkanven/MAGrid/LotSizeCal.mqh @@ -0,0 +1,57 @@ +//+------------------------------------------------------------------+ +//| 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; + double RiskBase=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(RiskBase==RISK_BASE_BALANCE) + RiskBaseAmount=AccountInfoDouble(ACCOUNT_BALANCE); + if(RiskBase==RISK_BASE_EQUITY) + RiskBaseAmount=AccountInfoDouble(ACCOUNT_EQUITY); + if(RiskBase==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/MAGrid/ScanPositions.mqh b/Include/Nkanven/MAGrid/ScanPositions.mqh new file mode 100644 index 0000000..20ce060 --- /dev/null +++ b/Include/Nkanven/MAGrid/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/MAGrid/TradeManager.mqh b/Include/Nkanven/MAGrid/TradeManager.mqh new file mode 100644 index 0000000..3bf43bd --- /dev/null +++ b/Include/Nkanven/MAGrid/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/MAGrid/TradingHour.mqh b/Include/Nkanven/MAGrid/TradingHour.mqh new file mode 100644 index 0000000..7933ad8 --- /dev/null +++ b/Include/Nkanven/MAGrid/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; + } + } +//+------------------------------------------------------------------+