diff --git a/Include/A_EntriesManagement.mqh b/Include/A_EntriesManagement.mqh new file mode 100644 index 0000000..893777e Binary files /dev/null and b/Include/A_EntriesManagement.mqh differ diff --git a/Include/A_HistoryChecker.mqh b/Include/A_HistoryChecker.mqh new file mode 100644 index 0000000..cce9256 Binary files /dev/null and b/Include/A_HistoryChecker.mqh differ diff --git a/Include/A_LotSizeCal.mqh b/Include/A_LotSizeCal.mqh new file mode 100644 index 0000000..79f5c11 --- /dev/null +++ b/Include/A_LotSizeCal.mqh @@ -0,0 +1,62 @@ +//+------------------------------------------------------------------+ +//| A_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(RiskDefaultSize==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 + TickValue=SymbolInfoDouble(Symb,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 + Print("Multiplier ", lotMultiplier, "Before lot multiplier ", (RiskBaseAmount*MaxRiskPerTrade/100)/(SL*TickValue)); + Print("RiskBaseAmount ", RiskBaseAmount, " MaxRiskPerTrade ", MaxRiskPerTrade, "Stop loss ", SL, " TickValue ", TickValue); + + LotSize=((RiskBaseAmount*MaxRiskPerTrade/100)/(SL*TickValue)); + + Print("After lot multiplier ", LotSize, " Lot multiplier ", lotMultiplier); + if(ActiveMartingale) + { + LotSize = LotSize * lotMultiplier; + } + } + //If the stop loss is zero then the lot size is the default one + if(SL==0) + { + LotSize=DefaultLotSize; + } + } +//Normalize the Lot Size to satisfy the allowed lot increment and minimum and maximum position size + LotSize=MathFloor(LotSize/SymbolInfoDouble(Symb,SYMBOL_VOLUME_STEP))*SymbolInfoDouble(Symb,SYMBOL_VOLUME_STEP); + +//Limit the lot size in case it is greater than the maximum allowed by the user + if(LotSize>MaxLotSize) + LotSize=MaxLotSize; +//Limit the lot size in case it is greater than the maximum allowed by the broker + if(LotSize>SymbolInfoDouble(Symb,SYMBOL_VOLUME_MAX)) + LotSize=SymbolInfoDouble(Symb,SYMBOL_VOLUME_MAX); + Print("Lot ", LotSize, " Max lot ", SymbolInfoDouble(Symb,SYMBOL_VOLUME_MAX)); +//If the lot size is too small then set it to 0 and don't trade + if(LotSize < SymbolInfoDouble(Symb,SYMBOL_VOLUME_MIN)) + { + LotSize=0; + Print("Lot size too small"); + } + } diff --git a/Include/A_Parameters.mqh b/Include/A_Parameters.mqh new file mode 100644 index 0000000..42702da --- /dev/null +++ b/Include/A_Parameters.mqh @@ -0,0 +1,213 @@ +//+------------------------------------------------------------------+ +//| A_Parameters.mqh | +//| Copyright 2021, Nkondog Anselme Venceslas | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2021, Nkondog Anselme Venceslas" +#property link "https://www.mql5.com" +//+------------------------------------------------------------------+ +//| defines | +//+------------------------------------------------------------------+ + +//-ENUMERATIVE VARIABLES-// +//Enumerative variables are useful to associate numerical values to easy to remember strings +//It is similar to constants but also helps if the variable is set from the input page of the EA +//The text after the // is what you see in the input paramenters when the EA loads +//It is good practice to place all the enumberative at the start + +//Enumerative for the entry signal value +enum ENUM_SIGNAL_ENTRY + { + SIGNAL_ENTRY_NEUTRAL=0, //SIGNAL ENTRY NEUTRAL + SIGNAL_ENTRY_BUY=1, //SIGNAL ENTRY BUY + SIGNAL_ENTRY_SELL=-1, //SIGNAL ENTRY SELL + }; + +//Enumerative for the exit signal value +enum ENUM_SIGNAL_EXIT + { + SIGNAL_EXIT_NEUTRAL=0, //SIGNAL EXIT NEUTRAL + SIGNAL_EXIT_BUY=1, //SIGNAL EXIT BUY + SIGNAL_EXIT_SELL=-1, //SIGNAL EXIT SELL + SIGNAL_EXIT_ALL=2, //SIGNAL EXIT ALL + }; + +//Enumerative for the allowed trading direction +enum ENUM_TRADING_ALLOW_DIRECTION + { + TRADING_ALLOW_BOTH=0, //ALLOW BOTH BUY AND SELL + TRADING_ALLOW_BUY=1, //ALLOW BUY ONLY + TRADING_ALLOW_SELL=-1, //ALLOW SELL ONLY + }; + +//Enumerative for the base used for risk calculation +enum ENUM_RISK_BASE + { + RISK_BASE_EQUITY=1, //EQUITY + RISK_BASE_BALANCE=2, //BALANCE + RISK_BASE_FREEMARGIN=3, //FREE MARGIN + }; + +//Enumerative for the default risk size +enum ENUM_RISK_DEFAULT_SIZE + { + RISK_DEFAULT_FIXED=1, //FIXED SIZE + RISK_DEFAULT_AUTO=2, //AUTOMATIC SIZE BASED ON RISK + }; + +//Enumerative for the Stop Loss mode +enum ENUM_MODE_SL + { + SL_FIXED=0, //FIXED STOP LOSS + SL_AUTO=1, //AUTOMATIC STOP LOSS + }; + +//Enumerative for the Take Profit Mode +enum ENUM_MODE_TP + { + TP_FIXED=0, //FIXED TAKE PROFIT + TP_AUTO=1, //AUTOMATIC TAKE PROFIT + }; + +//Enumerative for the stop loss calculation +enum ENUM_MODE_SL_BY + { + SL_BY_POINTS=0, //STOP LOSS PASSED IN POINTS + SL_BY_PRICE=1, //STOP LOSS PASSED BY PRICE + }; + +//Enumerative for candle type +enum ENUM_CANDLE_TYPE + { + NEUTRAL_CANDLE=0, + BEARISH_CANDLE=1, + BULLISH_CANDLE=2, + }; + +//Enumerative for price momentum +enum ENUM_PRICE_MOMENTUM + { + UP=2, + DOWN=1, + NEUTRAL=0, + }; + +struct LastTransaction + { + string time; + int type; + double profit; + } lt; + +//-INPUT PARAMETERS-// +//The input parameters are the ones that can be set by the user when launching the EA +//If you place a comment following the input variable this will be shown as description of the field + +//This is where you should include the input parameters for your entry and exit signals +input string Comment_strategy="=========="; //Entry And Exit Settings +//Add in this section the parameters for the indicators used in your entry and exit + +//General input parameters +input string Comment_0="=========="; //Risk Management Settings +input ENUM_RISK_DEFAULT_SIZE RiskDefaultSize=RISK_DEFAULT_AUTO; //Position Size Mode +input double DefaultLotSize=1; //Position Size (if fixed or if no stop loss defined) +input ENUM_RISK_BASE RiskBase=RISK_BASE_BALANCE; //Risk Base +input double MaxRiskPerTrade=0.5; //Percentage To Risk Each Trade +input double MinLotSize=0.01; //Minimum Position Size Allowed +input double MaxLotSize=100; //Maximum Position Size Allowed + +input string Comment_1="=========="; //Trading Hours Settings +input bool UseTradingHours=false; //Limit Trading Hours +input string TradingHourStart="01"; //Trading Start Hour (Broker Server Hour) +input string TradingHourEnd="23"; //Trading End Hour (Broker Server Hour) +input string TradingStartMin="30"; //Trading Start minute (Broker Server Hour) +input string TradingEndMin="00"; //Trading End minute + +input string Comment_2="=========="; //Stop Loss And Take Profit Settings +input ENUM_MODE_SL StopLossMode=SL_AUTO; //Stop Loss Mode +input int DefaultStopLoss=0; //Default Stop Loss In Points (0=No Stop Loss) +input int MinStopLoss=0; //Minimum Allowed Stop Loss In Points +input int MaxStopLoss=5000; //Maximum Allowed Stop Loss In Points +input bool AtrStopLoss=false; //Set Stop loss based on ATR +input int atr_sl_factor=3; //Multiplicator for ATR stop loss +input ENUM_MODE_TP TakeProfitMode=TP_AUTO; //Take Profit Mode +input int DefaultTakeProfit=0; //Default Take Profit In Points (0=No Take Profit) +input int MinTakeProfit=0; //Minimum Allowed Take Profit In Points +input int MaxTakeProfit=5000; //Maximum Allowed Take Profit In Points +input double TakeProfitPercent=1.0; //Take Profit percent on risk base +input double Breakevent=1.0; //Minimum Profit to breakeven +input bool ProfitRun=true; +input bool ActiveMartingale=false; + +input string Comment_3="=========="; //Trailing Stop Settings +input bool UseTrailingStop=false; //Use Trailing Stop + +input string Comment_4="=========="; //Additional Settings +input int MagicNumber=0; //Magic Number For The Orders Opened By This EA +input string OrderNote=""; //Comment For The Orders Opened By This EA +input int Slippage=5; //Slippage in points +input double MaxSpread=10.0; //Maximum Allowed Spread To Trade In Points + +input string Comment_5="==========="; //Zigzag indicator setting +input int Depth=5; +input int Deviation=5; +input int Backstep=3; +input int GapPoint=100; //Minimum gap between peaks +input int Sensitivity=2; //Minimum peak at same level +input int LookBack=50; //Maximum peak to consider + +input int NumberOfCandles=3; + +//-GLOBAL VARIABLES-// +//The variables included in this section are global, hence they can be used in any part of the code +string Symb=Symbol(), server_time; + +long current_chart_id = ChartID(); + +bool IsPreChecksOk=false; //Indicates if the pre checks are satisfied +bool IsNewCandle=false; //Indicates if this is a new candle formed +bool IsSpreadOK=false; //Indicates if the spread is low enough to trade +bool IsOperatingHours=false; //Indicates if it is possible to trade at the current time (server time) +bool IsTradedThisBar=false; //Indicates if an order was already executed in the current candle +bool In_Trade = true; //Indicates if trade range has been formed +bool CanBuy = true; +bool CanSell = true; +bool ClosePosition = false; +bool FollowProfit = false; +bool UpTrendingMarket = false; +bool DownTrendingMarket = false; + +double TickValue=0; //Value of a tick in account currency at 1 lot +double LotSize=0; //Lot size for the position +double Tick_Size = SymbolInfoDouble(Symb,SYMBOL_TRADE_TICK_SIZE); //Tick size +double High[]; +double Low[]; +double PositionProfit; + +//Indicators + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +long Spread = SymbolInfoInteger(Symb,SYMBOL_SPREAD) / 100; //Check the impact. It's originally a double +int OrderOpRetry=10; //Number of attempts to retry the order submission +int TotalOpenOrders=0; //Number of total open orders +int TotalOpenBuy=0; //Number of total open buy orders +int TotalOpenSell=0; //Number of total open sell orders +int StopLossBy=SL_BY_POINTS; //How the stop loss is passed for the lot size calculation +double lotMultiplier =1; //Adust lot size according to loosing trades +int candleCounter =0; +double firstCandleOpen =0; +double lastCandleClose=0; +double ProfitRunTargetPercent=10.0; + +datetime LastBarTraded; + +MqlDateTime dt; +MqlTick last_tick; + +ENUM_SIGNAL_ENTRY SignalEntry=SIGNAL_ENTRY_NEUTRAL; //Entry signal variable +ENUM_SIGNAL_EXIT SignalExit=SIGNAL_EXIT_NEUTRAL; +ENUM_CANDLE_TYPE candleType=NEUTRAL_CANDLE; +ENUM_PRICE_MOMENTUM priceMomentum=NEUTRAL; +//+------------------------------------------------------------------+ diff --git a/Include/A_PositionsManager.mqh b/Include/A_PositionsManager.mqh new file mode 100644 index 0000000..ac8a2b1 --- /dev/null +++ b/Include/A_PositionsManager.mqh @@ -0,0 +1,123 @@ +//+------------------------------------------------------------------+ +//| A_PositionsManager.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; + +//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 + TotalOpenOrders = 0; + TotalOpenBuy = 0; + TotalOpenSell = 0; + for(int i=0; iLastBarTraded || LastBarTraded==0) + LastBarTraded=(datetime)PositionGetInteger(POSITION_TIME); + } + Print("Total positions ", TotalOpenOrders, " - Total buys ", TotalOpenBuy, " - Total sells ", TotalOpenSell); + return true; + } + +// We declare a function CloseOpenPositions of type int and we want to return +// the number of positions that are closed. +void CloseOpenPositions() + { + + int TotalClose=0; // We want to count how many orders have been closed. + int c_slippage = Slippage; + Print("Close position status ", ClosePosition); +// Normalization of the slippage. + if(_Digits==3 || _Digits==5) + { + c_slippage=c_slippage*10; + } + +// We scan all the orders backwards. +// This is required as if we start from the first order, we will have problems with the counters and the loop. + for(int i=PositionsTotal()-1; i>=0; i--) + { + + ulong ticket = PositionGetTicket(i); + + Print("Position profit is ", PositionGetDouble(POSITION_PROFIT)); + PositionProfit = PositionGetDouble(POSITION_PROFIT); + /*if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && iClose(Symb, PERIOD_CURRENT, 1) < Senkouspanb && iClose(Symb, PERIOD_CURRENT, 1) < Senkouspana) + { + // We select the order of index i, selecting by position and from the pool of market/pending trades. + //If the selection is successful we try to close the order. + if(trade.PositionClose(ticket, c_slippage)) + { + TotalClose++; + } + else + { + // If the order fails to be closed, we print the error. + Print("Order failed to close with error - ",GetLastError()); + } + } + + if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && iClose(Symb, PERIOD_CURRENT, 1) > Senkouspanb && iClose(Symb, PERIOD_CURRENT, 1) > Senkouspana) + { + // We select the order of index i, selecting by position and from the pool of market/pending trades. + //If the selection is successful we try to close the order. + if(trade.PositionClose(ticket, c_slippage)) + { + TotalClose++; + } + else + { + // If the order fails to be closed, we print the error. + Print("Order failed to close with error - ",GetLastError()); + } + }*/ + + if(ClosePosition) + { + if(trade.PositionClose(ticket, c_slippage)) + { + TotalClose++; + ClosePosition = false; + } + else + { + // If the order fails to be closed, we print the error. + Print("Order failed to close with error - ",GetLastError()); + } + } + // We can use a delay if the execution is too fast. + // Sleep() will wait X milliseconds before proceeding with the code. + // Sleep(300); + } + } +//+------------------------------------------------------------------+ diff --git a/Include/A_TradeManager.mqh b/Include/A_TradeManager.mqh new file mode 100644 index 0000000..fa829a9 --- /dev/null +++ b/Include/A_TradeManager.mqh @@ -0,0 +1,23 @@ +//+------------------------------------------------------------------+ +//| A_TradeManager.mqh | +//| Copyright 2021, Nkondog Anselme Venceslas | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2021, Nkondog Anselme Venceslas" +#property link "https://www.mql5.com" + +void ProfitRunner() + { + if(ProfitRun) + { + if(iClose(Symb, _Period, 1) < iClose(Symb, _Period, 2) && TotalOpenBuy > 0) + { + ClosePosition = true; + } + if(iClose(Symb, _Period, 1) > iClose(Symb, _Period, 2) && TotalOpenSell > 0) + { + ClosePosition = true; + } + } + Print("Looking to close this position ", ClosePosition); + } \ No newline at end of file diff --git a/Include/A_TradingHour.mqh b/Include/A_TradingHour.mqh new file mode 100644 index 0000000..72d352a --- /dev/null +++ b/Include/A_TradingHour.mqh @@ -0,0 +1,27 @@ +//+------------------------------------------------------------------+ +//| A_TradingHour.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/DL_CheckHistory.mqh b/Include/DL_CheckHistory.mqh new file mode 100644 index 0000000..992b7ab Binary files /dev/null and b/Include/DL_CheckHistory.mqh differ diff --git a/Include/DL_CheckOperationHours.mqh b/Include/DL_CheckOperationHours.mqh new file mode 100644 index 0000000..e4f7362 --- /dev/null +++ b/Include/DL_CheckOperationHours.mqh @@ -0,0 +1,46 @@ +//+------------------------------------------------------------------+ +//| DL_CheckOperationHours.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(!UseTradingHours) + { + IsOperatingHours=true; + return; + } +//Check if the current hour is between the allowed hours of operations, if so IsOperatingHours is set true + Print("1 this is ", (TradingHourStart==TradingHourEnd && dt.hour==TradingHourStart && In_Trade)); + + if(TradingHourStart==TradingHourEnd && dt.hour==TradingHourStart && In_Trade) + IsOperatingHours=true; + + if(TradingHourStart= TradingStartMin) + { + IsOperatingHours=true; + } + if(dt.hour > TradingHourStart) + { + IsOperatingHours=true; + } + } + + if(TradingHourStart>TradingHourEnd && ((dt.hour>=TradingHourStart && dt.hour<=23) || (dt.hour<=TradingHourEnd && dt.hour>=0)) && In_Trade) + { + IsOperatingHours=true; + } + + if(IsOperatingHours == false) + { + rangeUpdated = false; + } + } +//+------------------------------------------------------------------+ diff --git a/Include/DL_ClosePositions.mqh b/Include/DL_ClosePositions.mqh new file mode 100644 index 0000000..b262b0f --- /dev/null +++ b/Include/DL_ClosePositions.mqh @@ -0,0 +1,67 @@ +//+------------------------------------------------------------------+ +//| DL_ClosePositions.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; + +// We declare a function CloseOpenPositions of type int and we want to return +// the number of positions that are closed. +void CloseOpenPositions() + { + + int TotalClose=0; // We want to count how many orders have been closed. + int c_slippage = Slippage; + +// Normalization of the slippage. + if(_Digits==3 || _Digits==5) + { + c_slippage=c_slippage*10; + } + + if(TimeToString(LastBarTraded, TIME_DATE) == TimeToString(TimeCurrent(), TIME_DATE)) + return; + +// We scan all the orders backwards. +// This is required as if we start from the first order, we will have problems with the counters and the loop. +// We select the order of index i, selecting by position and from the pool of market/pending trades. + + double accountProfit = AccountInfoDouble(ACCOUNT_EQUITY) - AccountInfoDouble(ACCOUNT_BALANCE); + double accountProfitPercent = (fabs(accountProfit)*100)/AccountInfoDouble(ACCOUNT_BALANCE); + if(accountProfit < 0 && accountProfitPercent >= 10) + { + + + + for(int i=PositionsTotal()-1; i>=0; i--) + { + + ulong ticket = PositionGetTicket(i); + + //If the selection is successful we try to close the order. + if(trade.PositionClose(ticket, c_slippage)) + { + TotalClose++; + } + else + { + // If the order fails to be closed, we print the error. + Print("Order failed to close with error - ",GetLastError()); + } + + /*Print("Position profit is ", PositionGetDouble(POSITION_PROFIT)); + if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PositionGetDouble(POSITION_PRICE_CURRENT) < upper_boundary || PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && PositionGetDouble(POSITION_PRICE_CURRENT) < upper_boundary) + { + + }*/ + + // We can use a delay if the execution is too fast. + // Sleep() will wait X milliseconds before proceeding with the code. + // Sleep(300); + } + } + } +//+------------------------------------------------------------------+ diff --git a/Include/DL_EntriesManagement.mqh b/Include/DL_EntriesManagement.mqh new file mode 100644 index 0000000..8cc157c Binary files /dev/null and b/Include/DL_EntriesManagement.mqh differ diff --git a/Include/DL_ErrorHandling.mqh b/Include/DL_ErrorHandling.mqh new file mode 100644 index 0000000..3684451 --- /dev/null +++ b/Include/DL_ErrorHandling.mqh @@ -0,0 +1,97 @@ +//+------------------------------------------------------------------+ +//| DL_ErrorHandling.mqh | +//| Copyright 2021, Nkondog Anselme Venceslas | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2021, Nkondog Anselme Venceslas" +#property link "https://www.mql5.com" + + +//+------------------------------------------------------------------+ +//This functions returns a string corresponding to the description of an error +//Complete list of error available https://book.mql4.com/appendix/errors +string GetLastErrorText(int Error){ + string Text="Error Not Defined"; + if(Error==ERR_SUCCESS) Text="The operation completed successfully."; + if(Error==ERR_INTERNAL_ERROR) Text="Unexpected internal error."; + /*if(Error==ERR_COMMON_ERROR) Text="Common error."; + if(Error==ERR_INVALID_TRADE_PARAMETERS) Text="Invalid trade parameters."; + if(Error==ERR_SERVER_BUSY) Text="Trade server is busy."; + if(Error==ERR_OLD_VERSION) Text="Old version of the client terminal."; + if(Error==ERR_NO_CONNECTION) Text="No connection with trade server."; + if(Error==ERR_NOT_ENOUGH_RIGHTS) Text="Not enough rights."; + if(Error==ERR_TOO_FREQUENT_REQUESTS) Text="Too frequent requests."; + if(Error==ERR_MALFUNCTIONAL_TRADE) Text="Malfunctional trade operation."; + if(Error==ERR_ACCOUNT_DISABLED) Text="Account disabled."; + if(Error==ERR_INVALID_ACCOUNT) Text="Invalid account."; + if(Error==ERR_TRADE_TIMEOUT) Text="Trade timeout."; + if(Error==ERR_INVALID_PRICE) Text="Invalid price."; + if(Error==ERR_INVALID_STOPS) Text="Invalid stops."; + if(Error==ERR_INVALID_TRADE_VOLUME) Text="Invalid trade volume."; + if(Error==ERR_MARKET_CLOSED) Text="Market is closed."; + if(Error==ERR_TRADE_DISABLED) Text="Trade is disabled."; + if(Error==ERR_NOT_ENOUGH_MONEY) Text="Not enough money."; + if(Error==ERR_PRICE_CHANGED) Text="Price changed."; + if(Error==ERR_OFF_QUOTES) Text="Off quotes."; + if(Error==ERR_BROKER_BUSY) Text="Broker is busy."; + if(Error==ERR_REQUOTE) Text="Requote."; + if(Error==ERR_ORDER_LOCKED) Text="Order is locked."; + if(Error==ERR_LONG_POSITIONS_ONLY_ALLOWED) Text="Long positions only allowed."; + if(Error==ERR_TOO_MANY_REQUESTS) Text="Too many requests."; + if(Error==ERR_TRADE_MODIFY_DENIED) Text="Modification denied because an order is too close to market."; + if(Error==ERR_TRADE_CONTEXT_BUSY) Text="Trade context is busy."; + if(Error==ERR_TRADE_EXPIRATION_DENIED) Text="Expirations are denied by broker."; + if(Error==ERR_TRADE_TOO_MANY_ORDERS) Text="The amount of opened and pending orders has reached the limit set by a broker."; + if(Error==ERR_NO_MQLERROR) Text="No error."; + if(Error==ERR_WRONG_FUNCTION_POINTER) Text="Wrong function pointer."; + if(Error==ERR_ARRAY_INDEX_OUT_OF_RANGE) Text="Array index is out of range."; + if(Error==ERR_RECURSIVE_STACK_OVERFLOW) Text="Recursive stack overflow."; + if(Error==ERR_NO_MEMORY_FOR_TEMP_STRING) Text="No memory for temp string."; + if(Error==ERR_NOT_INITIALIZED_STRING) Text="Not initialized string."; + if(Error==ERR_NOT_INITIALIZED_ARRAYSTRING) Text="Not initialized string in an array."; + if(Error==ERR_NO_MEMORY_FOR_ARRAYSTRING) Text="No memory for an array string."; + if(Error==ERR_TOO_LONG_STRING) Text="Too long string."; + if(Error==ERR_REMAINDER_FROM_ZERO_DIVIDE) Text="Remainder from zero divide."; + if(Error==ERR_ZERO_DIVIDE) Text="Zero divide."; + if(Error==ERR_UNKNOWN_COMMAND) Text="Unknown command."; + if(Error==ERR_WRONG_JUMP) Text="Wrong jump."; + if(Error==ERR_NOT_INITIALIZED_ARRAY) Text="Not initialized array."; + if(Error==ERR_DLL_CALLS_NOT_ALLOWED) Text="DLL calls are not allowed."; + if(Error==ERR_CANNOT_LOAD_LIBRARY) Text="Cannot load library."; + if(Error==ERR_CANNOT_CALL_FUNCTION) Text="Cannot call function."; + if(Error==ERR_SYSTEM_BUSY) Text="System is busy."; + if(Error==ERR_SOME_ARRAY_ERROR) Text="Some array error."; + if(Error==ERR_CUSTOM_INDICATOR_ERROR) Text="Custom indicator error."; + if(Error==ERR_INCOMPATIBLE_ARRAYS) Text="Arrays are incompatible."; + if(Error==ERR_GLOBAL_VARIABLE_NOT_FOUND) Text="Global variable not found."; + if(Error==ERR_FUNCTION_NOT_CONFIRMED) Text="Function is not confirmed."; + if(Error==ERR_SEND_MAIL_ERROR) Text="Mail sending error."; + if(Error==ERR_STRING_PARAMETER_EXPECTED) Text="String parameter expected."; + if(Error==ERR_INTEGER_PARAMETER_EXPECTED) Text="Integer parameter expected."; + if(Error==ERR_DOUBLE_PARAMETER_EXPECTED) Text="Double parameter expected."; + if(Error==ERR_ARRAY_AS_PARAMETER_EXPECTED) Text="Array as parameter expected."; + if(Error==ERR_HISTORY_WILL_UPDATED) Text="Requested history data in updating state."; + if(Error==ERR_TRADE_ERROR) Text="Some error in trade operation execution."; + if(Error==ERR_END_OF_FILE) Text="End of a file."; + if(Error==ERR_SOME_FILE_ERROR) Text="Some file error."; + if(Error==ERR_WRONG_FILE_NAME) Text="Wrong file name."; + if(Error==ERR_TOO_MANY_OPENED_FILES) Text="Too many opened files."; + if(Error==ERR_CANNOT_OPEN_FILE) Text="Cannot open file."; + if(Error==ERR_NO_ORDER_SELECTED) Text="No order selected."; + if(Error==ERR_UNKNOWN_SYMBOL) Text="Unknown symbol."; + if(Error==ERR_INVALID_PRICE_PARAM) Text="Invalid price."; + if(Error==ERR_INVALID_TICKET) Text="Invalid ticket."; + if(Error==ERR_TRADE_NOT_ALLOWED) Text="Trade is not allowed."; + if(Error==ERR_LONGS_NOT_ALLOWED) Text="Longs are not allowed."; + if(Error==ERR_SHORTS_NOT_ALLOWED) Text="Shorts are not allowed."; + if(Error==ERR_OBJECT_ALREADY_EXISTS) Text="Object already exists."; + if(Error==ERR_UNKNOWN_OBJECT_PROPERTY) Text="Unknown object property."; + if(Error==ERR_OBJECT_DOES_NOT_EXIST) Text="Object does not exist."; + if(Error==ERR_UNKNOWN_OBJECT_TYPE) Text="Unknown object type."; + if(Error==ERR_NO_OBJECT_NAME) Text="No object name."; + if(Error==ERR_OBJECT_COORDINATES_ERROR) Text="Object coordinates error."; + if(Error==ERR_NO_SPECIFIED_SUBWINDOW) Text="No specified subwindow."; + if(Error==ERR_SOME_OBJECT_ERROR) Text="Some error in object operation.";*/ + + return Text; +} \ No newline at end of file diff --git a/Include/DL_InitMQL4.mqh b/Include/DL_InitMQL4.mqh new file mode 100644 index 0000000..b65eeca --- /dev/null +++ b/Include/DL_InitMQL4.mqh @@ -0,0 +1,65 @@ +//+------------------------------------------------------------------+ +//| InitMQL4.mqh | +//| Copyright DC2008 | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "keiji" +#property copyright "DC2008" +#property link "https://www.mql5.com" +//--- Declaration of constants +#define OP_BUY 0 //Buy +#define OP_SELL 1 //Sell +#define OP_BUYLIMIT 2 //Pending order of BUY LIMIT type +#define OP_SELLLIMIT 3 //Pending order of SELL LIMIT type +#define OP_BUYSTOP 4 //Pending order of BUY STOP type +#define OP_SELLSTOP 5 //Pending order of SELL STOP type +//--- +#define MODE_OPEN 0 +#define MODE_CLOSE 3 +#define MODE_VOLUME 4 +#define MODE_REAL_VOLUME 5 +#define MODE_TRADES 0 +#define MODE_HISTORY 1 +#define SELECT_BY_POS 0 +#define SELECT_BY_TICKET 1 +//--- +#define DOUBLE_VALUE 0 +#define FLOAT_VALUE 1 +#define LONG_VALUE INT_VALUE +//--- +#define CHART_BAR 0 +#define CHART_CANDLE 1 +//--- +#define MODE_ASCEND 0 +#define MODE_DESCEND 1 +//--- +#define MODE_LOW 1 +#define MODE_HIGH 2 +#define MODE_TIME 5 +#define MODE_BID 9 +#define MODE_ASK 10 +#define MODE_POINT 11 +#define MODE_DIGITS 12 +#define MODE_SPREAD 13 +#define MODE_STOPLEVEL 14 +#define MODE_LOTSIZE 15 +#define MODE_TICKVALUE 16 +#define MODE_TICKSIZE 17 +#define MODE_SWAPLONG 18 +#define MODE_SWAPSHORT 19 +#define MODE_STARTING 20 +#define MODE_EXPIRATION 21 +#define MODE_TRADEALLOWED 22 +#define MODE_MINLOT 23 +#define MODE_LOTSTEP 24 +#define MODE_MAXLOT 25 +#define MODE_SWAPTYPE 26 +#define MODE_PROFITCALCMODE 27 +#define MODE_MARGINCALCMODE 28 +#define MODE_MARGININIT 29 +#define MODE_MARGINMAINTENANCE 30 +#define MODE_MARGINHEDGED 31 +#define MODE_MARGINREQUIRED 32 +#define MODE_FREEZELEVEL 33 +//--- +#define EMPTY -1 \ No newline at end of file diff --git a/Include/DL_LotSizeCal.mqh b/Include/DL_LotSizeCal.mqh new file mode 100644 index 0000000..02a99d1 --- /dev/null +++ b/Include/DL_LotSizeCal.mqh @@ -0,0 +1,54 @@ +//+------------------------------------------------------------------+ +//| DL_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(RiskDefaultSize==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 + TickValue=SymbolInfoDouble(Symb,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*MaxRiskPerTrade/100)/(SL*TickValue)); + } + //If the stop loss is zero then the lot size is the default one + if(SL==0) + { + LotSize=DefaultLotSize; + } + } +//Normalize the Lot Size to satisfy the allowed lot increment and minimum and maximum position size + LotSize=MathFloor(LotSize/SymbolInfoDouble(Symb,SYMBOL_VOLUME_STEP))*SymbolInfoDouble(Symb,SYMBOL_VOLUME_STEP); + +//Limit the lot size in case it is greater than the maximum allowed by the user + if(LotSize>MaxLotSize) + LotSize=MaxLotSize; +//Limit the lot size in case it is greater than the maximum allowed by the broker + if(LotSize>SymbolInfoDouble(Symb,SYMBOL_VOLUME_MAX)) + LotSize=SymbolInfoDouble(Symb,SYMBOL_VOLUME_MAX); + Print("Lot ", LotSize, " Max lot ", SymbolInfoDouble(Symb,SYMBOL_VOLUME_MAX)); +//If the lot size is too small then set it to 0 and don't trade + if(LotSizeMaxStopLoss) + { + IsPreChecksOk=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(DefaultTakeProfitMaxTakeProfit) + { + IsPreChecksOk=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(DefaultLotSizeMaxLotSize) + { + IsPreChecksOk=false; + Print("Default Lot Size must be between Minimum and Maximum Lot Size Allowed"); + return; + } +//Slippage must be >= 0 + if(Slippage<0) + { + IsPreChecksOk=false; + Print("Slippage must be a positive value"); + return; + } +//MaxSpread must be >= 0 + if(MaxSpread<0) + { + IsPreChecksOk=false; + Print("Maximum Spread must be a positive value"); + return; + } +//MaxRiskPerTrade is a % between 0 and 100 + if(MaxRiskPerTrade<0 || MaxRiskPerTrade>100) + { + IsPreChecksOk=false; + Print("Maximum Risk Per Trade must be a percentage between 0 and 100"); + return; + } + } diff --git a/Include/DL_ScanPositions.mqh b/Include/DL_ScanPositions.mqh new file mode 100644 index 0000000..4cb5d70 --- /dev/null +++ b/Include/DL_ScanPositions.mqh @@ -0,0 +1,49 @@ +//+------------------------------------------------------------------+ +//| DL_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 + TotalOpenOrders = 0; + TotalOpenBuy = 0; + TotalOpenSell = 0; + for(int i=0; iLastBarTraded || LastBarTraded==0) + LastBarTraded=(datetime)PositionGetInteger(POSITION_TIME); + } + Print("Total positions ", TotalOpenOrders, " - Total buys ", TotalOpenBuy, " - Total sells ", TotalOpenSell); + return true; + } \ No newline at end of file diff --git a/Include/DL_TradeManagement.mqh b/Include/DL_TradeManagement.mqh new file mode 100644 index 0000000..99524ff --- /dev/null +++ b/Include/DL_TradeManagement.mqh @@ -0,0 +1,20 @@ +//+------------------------------------------------------------------+ +//| DL_TradeManagement.mqh | +//| Copyright 2021, Nkondog Anselme Venceslas | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2021, Nkondog Anselme Venceslas" +#property link "https://www.mql5.com" + +bool ShouldTrade() + { + //double minProfitAllow = ((AccountInfoDouble(ACCOUNT_BALANCE)*MaxRiskPerTrade)/100)*(TakeProfitPercent*MinStopTradeProfit); +Print("1 Profit ", lt.profit, " Hist time ", lt.time, " current time ", TimeToString(TimeCurrent(), TIME_DATE)); + if(lt.time == TimeToString(TimeCurrent(), TIME_DATE) && lt.profit > 0) + { + Print("2 Profit ", lt.profit); + return false; + } + return true; + } +//+------------------------------------------------------------------+ diff --git a/Include/DL_TradingBoundaries.mqh b/Include/DL_TradingBoundaries.mqh new file mode 100644 index 0000000..d3b231b --- /dev/null +++ b/Include/DL_TradingBoundaries.mqh @@ -0,0 +1,112 @@ +//+------------------------------------------------------------------+ +//| DL_TradingBoundaries.mqh | +//| Copyright 2021, Nkondog Anselme Venceslas | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2021, Nkondog Anselme Venceslas" +#property link "https://www.mql5.com" + +double newHigh, newLow; +bool rangeUpdated = false; +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void drawRange() + { + string candles_times; + int time_to_string; + ushort a; + string d_time = TimeToString(iTime(Symb,PERIOD_M5,0), TIME_MINUTES); + string open_hour[]; + string obj_name = "Upper boundary", obj_name_l = "Lower boundary"; + + ArraySetAsSeries(High,true); + CopyHigh(_Symbol,_Period,0,MaxCandleIteration,High); + + ArraySetAsSeries(Low,true); + CopyLow(_Symbol,_Period,0,MaxCandleIteration,Low); + +//--- Get the separator code + a = StringGetCharacter(":",0); + + int k = StringSplit(d_time, a, open_hour); + + if(k>0) + { + server_time = "Server time on last 5 Min candle => Hour = " +open_hour[0]+ ", Minute = " +open_hour[1]; + } + +// Get trading range + for(int j = 0; j <= MaxCandleIteration; j++) + { + string result[]; + candles_times = TimeToString(iTime(Symb,_Period,j), TIME_MINUTES); + time_to_string = StringSplit(candles_times, a, result); + //Print("Is trading boundary "+(result[0] == TradingBoundaryHour && result[1] == TradingBoundaryMin)); + if(result[0] == TradingBoundaryHour && result[1] == TradingBoundaryMin) + { + if(!rangeUpdated) + { + upper_boundary = iHigh(Symb, _Period, j) + rangemargin; + lower_boundary = iLow(Symb, _Period, j)- rangemargin; + } + + UpdateRange(); + //Print("Iteration no "+iTime(Symb,PERIOD_M5,j)); + ObjectCreate(current_chart_id, obj_name, OBJ_HLINE, 0, iTime(Symb,_Period,j), upper_boundary); + + //--- set color to Red + ObjectSetInteger(current_chart_id, obj_name, OBJPROP_COLOR, clrRed); + //--- set object width + ObjectSetInteger(current_chart_id, obj_name, OBJPROP_WIDTH, 2); + //--- Move the line + ObjectMove(current_chart_id, obj_name, 0, iTime(Symb,_Period,j), upper_boundary); + + ObjectCreate(current_chart_id, obj_name_l, OBJ_HLINE, 0, iTime(Symb,_Period,j), lower_boundary); + + //--- set color to Red + ObjectSetInteger(current_chart_id, obj_name_l, OBJPROP_COLOR, clrRed); + //--- set object width + ObjectSetInteger(current_chart_id, obj_name_l, OBJPROP_WIDTH, 2); + //--- Move the line + ObjectMove(current_chart_id, obj_name_l, 0, iTime(Symb,_Period,j), lower_boundary); + + if(!rangedetection) + { + upper_boundary = upperboundary; + lower_boundary = lowerboundary; + } + + //Print("upper_boundary ", upper_boundary, " lower_boundary ", lower_boundary); + //Print("Real high ", iHigh(Symb, PERIOD_M5, j), " Real low ", iLow(Symb, PERIOD_M5, j), " as of ", TimeToString(iTime(Symb,PERIOD_M5, j))); + In_Trade = true; + rangeScope = fabs(upper_boundary-lower_boundary); + break; + } + ObjectDelete(current_chart_id, obj_name_l); + ObjectDelete(current_chart_id, obj_name); + In_Trade = false; + } + } +//+------------------------------------------------------------------+ + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void UpdateRange() + { + newHigh = iHigh(Symb, PERIOD_CURRENT, 0); + newLow = iLow(Symb, PERIOD_CURRENT, 0); + Print("Updating range high from ", upper_boundary, "to ", newHigh, " and low from ", lower_boundary, " to ", newLow); + if(newHigh > upper_boundary && TotalOpenBuy > 0) + { + upper_boundary = newHigh; + rangeUpdated = true; + } + if(lower_boundary > newLow && TotalOpenSell > 0) + { + lower_boundary = newLow; + rangeUpdated = true; + } + } +//+------------------------------------------------------------------+ diff --git a/Include/E_CheckHistory.mqh b/Include/E_CheckHistory.mqh new file mode 100644 index 0000000..aa967ff Binary files /dev/null and b/Include/E_CheckHistory.mqh differ diff --git a/Include/E_ClosePositions.mqh b/Include/E_ClosePositions.mqh new file mode 100644 index 0000000..7b061e4 --- /dev/null +++ b/Include/E_ClosePositions.mqh @@ -0,0 +1,81 @@ +//+------------------------------------------------------------------+ +//| E_ClosePositions.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; + +// We declare a function CloseOpenPositions of type int and we want to return +// the number of positions that are closed. +void CloseOpenPositions() + { + + int TotalClose=0; // We want to count how many orders have been closed. + int c_slippage = Slippage; +Print("Close position status ", ClosePosition); +// Normalization of the slippage. + if(_Digits==3 || _Digits==5) + { + c_slippage=c_slippage*10; + } + +// We scan all the orders backwards. +// This is required as if we start from the first order, we will have problems with the counters and the loop. + for(int i=PositionsTotal()-1; i>=0; i--) + { + + ulong ticket = PositionGetTicket(i); + + Print("Position profit is ", PositionGetDouble(POSITION_PROFIT)); + PositionProfit = PositionGetDouble(POSITION_PROFIT); + if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && iClose(Symb, PERIOD_CURRENT, 1) < Senkouspanb && iClose(Symb, PERIOD_CURRENT, 1) < Senkouspana) + { + // We select the order of index i, selecting by position and from the pool of market/pending trades. + //If the selection is successful we try to close the order. + if(trade.PositionClose(ticket, c_slippage)) + { + TotalClose++; + } + else + { + // If the order fails to be closed, we print the error. + Print("Order failed to close with error - ",GetLastError()); + } + } + + if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && iClose(Symb, PERIOD_CURRENT, 1) > Senkouspanb && iClose(Symb, PERIOD_CURRENT, 1) > Senkouspana) + { + // We select the order of index i, selecting by position and from the pool of market/pending trades. + //If the selection is successful we try to close the order. + if(trade.PositionClose(ticket, c_slippage)) + { + TotalClose++; + } + else + { + // If the order fails to be closed, we print the error. + Print("Order failed to close with error - ",GetLastError()); + } + } + + if(ClosePosition) + { + if(trade.PositionClose(ticket, c_slippage)) + { + TotalClose++; + ClosePosition = false; + } + else + { + // If the order fails to be closed, we print the error. + Print("Order failed to close with error - ",GetLastError()); + } + } + // We can use a delay if the execution is too fast. + // Sleep() will wait X milliseconds before proceeding with the code. + // Sleep(300); + } + } +//+------------------------------------------------------------------+ diff --git a/Include/E_EntriesManagement.mqh b/Include/E_EntriesManagement.mqh new file mode 100644 index 0000000..d69973d Binary files /dev/null and b/Include/E_EntriesManagement.mqh differ diff --git a/Include/E_Parameters.mqh b/Include/E_Parameters.mqh new file mode 100644 index 0000000..4eb0be0 Binary files /dev/null and b/Include/E_Parameters.mqh differ diff --git a/Include/E_ScanPositions.mqh b/Include/E_ScanPositions.mqh new file mode 100644 index 0000000..53f5789 --- /dev/null +++ b/Include/E_ScanPositions.mqh @@ -0,0 +1,49 @@ +//+------------------------------------------------------------------+ +//| E_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 + TotalOpenOrders = 0; + TotalOpenBuy = 0; + TotalOpenSell = 0; + for(int i=0; iLastBarTraded || LastBarTraded==0) + LastBarTraded=(datetime)PositionGetInteger(POSITION_TIME); + } + Print("Total positions ", TotalOpenOrders, " - Total buys ", TotalOpenBuy, " - Total sells ", TotalOpenSell); + return true; + } \ No newline at end of file diff --git a/Include/E_TradeManagement.mqh b/Include/E_TradeManagement.mqh new file mode 100644 index 0000000..9b95978 --- /dev/null +++ b/Include/E_TradeManagement.mqh @@ -0,0 +1,57 @@ +//+------------------------------------------------------------------+ +//| E_TradeManagement.mqh | +//| Copyright 2021, Nkondog Anselme Venceslas | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2021, Nkondog Anselme Venceslas" +#property link "https://www.mql5.com" + +//Done for the day after a profitable trade +//If closed trade was opened the day before, look for trade opportunities +double minProfitAllow = AccountInfoDouble(ACCOUNT_BALANCE)*(Breakevent/100); +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void TradeManager() + { + CanSell = true; + CanBuy = true; + + if(lt.time == TimeToString(TimeCurrent(), TIME_DATE)) + { + if(lt.type == DEAL_TYPE_BUY && lt.profit < 0) + { + CanBuy = false; + } + if(lt.type = DEAL_TYPE_SELL && lt.profit < 0) + { + CanSell = false; + } + } + } +//+------------------------------------------------------------------+ + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void ProfitRunner() + { + Print("Min acceptablbe profit ", minProfitAllow); + ClosePosition = false; + if(PositionProfit > minProfitAllow) + FollowProfit=true; + + if(FollowProfit) + { + if(Kijunsen > iClose(Symb, _Period, 1) && TotalOpenBuy > 0) + { + ClosePosition = true; + } + if(Kijunsen < iClose(Symb, _Period, 1) && TotalOpenSell > 0) + { + ClosePosition = true; + } + } + Print("Looking to close this position ", ClosePosition, " Follow profit ", FollowProfit); + } +//+------------------------------------------------------------------+