Reorganize files, symbolic link to MT5 folder

This commit is contained in:
Nkondog Anselme
2022-01-03 05:26:31 +01:00
parent 2bb0816712
commit b9bdccdd2a
41 changed files with 0 additions and 0 deletions
Binary file not shown.
Binary file not shown.
+62
View File
@@ -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");
}
}
+213
View File
@@ -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;
//+------------------------------------------------------------------+
+123
View File
@@ -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; i<PositionsTotal(); i++)
{
//If there is a problem reading the order print the error, exit the function and return false
if(PositionGetTicket(i) == 0)
{
int Error=GetLastError();
string ErrorText=GetLastErrorText(Error);
Print("ERROR - Unable to select the order - ",Error," - ",ErrorText);
return false;
}
//If the order is not for the instrument on chart we can ignore it
if(PositionGetSymbol(i)!=Symb)
continue;
//If the order has Magic Number different from the Magic Number of the EA then we can ignore it
if(PositionGetInteger(POSITION_MAGIC)!=MagicNumber)
continue;
//If it is a buy order then increment the total count of buy orders
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
TotalOpenBuy++;
//If it is a sell order then increment the total count of sell orders
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
TotalOpenSell++;
//Increment the total orders count
TotalOpenOrders++;
//Find what is the open time of the most recent trade and assign it to LastBarTraded
//this is necessary to check if we already traded in the current candle
if((datetime)PositionGetInteger(POSITION_TIME)>LastBarTraded || 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);
}
}
//+------------------------------------------------------------------+
+23
View File
@@ -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);
}
+27
View File
@@ -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
//+------------------------------------------------------------------+
Binary file not shown.
@@ -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<TradingHourEnd && In_Trade)
{
if(TradingHourStart == dt.hour && dt.min >= 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;
}
}
//+------------------------------------------------------------------+
+67
View File
@@ -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);
}
}
}
//+------------------------------------------------------------------+
Binary file not shown.
+97
View File
@@ -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;
}
+65
View File
@@ -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
+54
View File
@@ -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(LotSize<MinLotSize || LotSize < SymbolInfoDouble(Symb,SYMBOL_VOLUME_MIN))
{
LotSize=0;
Print("Lot size too small : ", LotSize);
}
}
+175
View File
@@ -0,0 +1,175 @@
//+------------------------------------------------------------------+
//| DL_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 |
//+------------------------------------------------------------------+
#property strict
//+------------------------------------------------------------------+
//| defines |
//+------------------------------------------------------------------+
//--- input parameters
input bool rangedetection=true;
input double upperboundary;
input double lowerboundary;
input int stoploss;
input string taketype="fix";
input int takeprofitpercent=3;
input string timeframe="5min";
input double rangemargin=0.0;
//-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
};
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; //Activate 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 TradingBoundaryHour="01"; //Trading Boundary Hour
input string TradingBoundaryMin="25"; //Trading Boundary 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 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 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 int MaxSpread=100; //Maximum Allowed Spread To Trade In Points
input int MaxCandleIteration=100; //Max candles to check for trading range boundaries
//-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 = false; //Indicates if trade range has been formed
double TickValue=0; //Value of a tick in account currency at 1 lot
double LotSize=0; //Lot size for the position
double upper_boundary, lower_boundary; //Trading range boundaries
double rangeScope;
double Tick_Size = SymbolInfoDouble(Symb,SYMBOL_TRADE_TICK_SIZE); //Tick size
double High[];
double Low[];
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
int Mas_Tip[6]; // Order type array
int lotMultiplier =1; //Adust lot size according to loosing trades
datetime LastBarTraded;
MqlDateTime dt;
MqlTick last_tick;
ENUM_SIGNAL_ENTRY SignalEntry=SIGNAL_ENTRY_NEUTRAL; //Entry signal variable
ENUM_SIGNAL_EXIT SignalExit=SIGNAL_EXIT_NEUTRAL; //Exit signal variable
+62
View File
@@ -0,0 +1,62 @@
//+------------------------------------------------------------------+
//| DL_PreChecks.mqh |
//| Copyright 2021, Nkondog Anselme Venceslas |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Nkondog Anselme Venceslas"
#property link "https://www.mql5.com"
//Perform integrity checks when the EA is loaded
void CheckPreChecks()
{
IsPreChecksOk=true;
//Check if Live Trading is enabled in MT4
if(!MQLInfoInteger(MQL_TRADE_ALLOWED))
{
IsPreChecksOk=false;
Print("Live Trading is not enabled, please enable it in MT4 and chart settings");
return;
}
//Check if the default stop loss you are setting in above the minimum and below the maximum
if(DefaultStopLoss<MinStopLoss || DefaultStopLoss>MaxStopLoss)
{
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(DefaultTakeProfit<MinTakeProfit || DefaultTakeProfit>MaxTakeProfit)
{
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(DefaultLotSize<MinLotSize || DefaultLotSize>MaxLotSize)
{
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;
}
}
+49
View File
@@ -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; i<PositionsTotal(); i++)
{
//If there is a problem reading the order print the error, exit the function and return false
if(PositionGetTicket(i) == 0)
{
int Error=GetLastError();
string ErrorText=GetLastErrorText(Error);
Print("ERROR - Unable to select the order - ",Error," - ",ErrorText);
return false;
}
//If the order is not for the instrument on chart we can ignore it
if(PositionGetSymbol(i)!=Symb)
continue;
//If the order has Magic Number different from the Magic Number of the EA then we can ignore it
if(PositionGetInteger(POSITION_MAGIC)!=MagicNumber)
continue;
//If it is a buy order then increment the total count of buy orders
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
TotalOpenBuy++;
//If it is a sell order then increment the total count of sell orders
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
TotalOpenSell++;
//Increment the total orders count
TotalOpenOrders++;
//Find what is the open time of the most recent trade and assign it to LastBarTraded
//this is necessary to check if we already traded in the current candle
if((datetime)PositionGetInteger(POSITION_TIME)>LastBarTraded || LastBarTraded==0)
LastBarTraded=(datetime)PositionGetInteger(POSITION_TIME);
}
Print("Total positions ", TotalOpenOrders, " - Total buys ", TotalOpenBuy, " - Total sells ", TotalOpenSell);
return true;
}
+20
View File
@@ -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;
}
//+------------------------------------------------------------------+
+112
View File
@@ -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;
}
}
//+------------------------------------------------------------------+
Binary file not shown.
+81
View File
@@ -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);
}
}
//+------------------------------------------------------------------+
Binary file not shown.
Binary file not shown.
+49
View File
@@ -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; i<PositionsTotal(); i++)
{
//If there is a problem reading the order print the error, exit the function and return false
if(PositionGetTicket(i) == 0)
{
int Error=GetLastError();
string ErrorText=GetLastErrorText(Error);
Print("ERROR - Unable to select the order - ",Error," - ",ErrorText);
return false;
}
//If the order is not for the instrument on chart we can ignore it
if(PositionGetSymbol(i)!=Symb)
continue;
//If the order has Magic Number different from the Magic Number of the EA then we can ignore it
if(PositionGetInteger(POSITION_MAGIC)!=MagicNumber)
continue;
//If it is a buy order then increment the total count of buy orders
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
TotalOpenBuy++;
//If it is a sell order then increment the total count of sell orders
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
TotalOpenSell++;
//Increment the total orders count
TotalOpenOrders++;
//Find what is the open time of the most recent trade and assign it to LastBarTraded
//this is necessary to check if we already traded in the current candle
if((datetime)PositionGetInteger(POSITION_TIME)>LastBarTraded || LastBarTraded==0)
LastBarTraded=(datetime)PositionGetInteger(POSITION_TIME);
}
Print("Total positions ", TotalOpenOrders, " - Total buys ", TotalOpenBuy, " - Total sells ", TotalOpenSell);
return true;
}
+57
View File
@@ -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);
}
//+------------------------------------------------------------------+
+380
View File
@@ -0,0 +1,380 @@
/*
ExpertBase.mqh
Copyright 2013-2020, Orchard Forex
https://www.orchardforex.com
*/
#include "CommonBase.mqh"
#include "SignalBase.mqh"
#include "TPSLBase.mqh"
#include "Trade/Trade.mqh"
class CExpertBase : public CCommonBase {
protected:
int mMagicNumber;
string mTradeComment;
double mVolume;
datetime mLastBarTime;
datetime mBarTime;
////Changed
// Arrays to hold the signal objects
CSignalBase *mEntrySignals[];
CSignalBase *mExitSignals[];
////CSignalBase *mEntrySignal;
////CSignalBase *mExitSignal;
double mTakeProfitValue;
double mStopLossValue;
CTPSLBase *mTakeProfitObj;
CTPSLBase *mStopLossObj;
CTradeCustom Trade;
private:
protected:
virtual bool LoopMain(bool newBar, bool firstTime);
protected:
int Init(int magicNumber, string tradeComment);
public:
//
// Constructors
//
CExpertBase() : CCommonBase()
{ Init(0, ""); }
CExpertBase(string symbol, int timeframe, int magicNumber, string tradeComment)
: CCommonBase(symbol, timeframe)
{ Init(magicNumber, tradeComment); }
CExpertBase(string symbol, ENUM_TIMEFRAMES timeframe, int magicNumber, string tradeComment)
: CCommonBase(symbol, timeframe)
{ Init(magicNumber, tradeComment); }
CExpertBase(int magicNumber, string tradeComment)
: CCommonBase()
{ Init(magicNumber, tradeComment); }
//
// Destructors
//
~CExpertBase();
public: // Default properties
//
// Assign the default values to the expert
//
virtual void SetVolume(double volume) { mVolume = volume; }
virtual void SetTakeProfitValue(int takeProfitPoints)
{ mTakeProfitValue = PointsToDouble(takeProfitPoints); }
virtual void SetTakeProfitObj(CTPSLBase *takeProfitObj)
{ mTakeProfitObj = takeProfitObj; }
virtual void SetStopLossValue(int stopLossPoints)
{ mStopLossValue = PointsToDouble(stopLossPoints); }
virtual void SetStopLossObj(CTPSLBase *stopLossObj)
{ mStopLossObj = stopLossObj; }
virtual void SetTradeComment(string comment) { mTradeComment = comment; }
virtual void SetMagic(int magicNumber) { mMagicNumber = magicNumber;
Trade.SetExpertMagicNumber(magicNumber); }
public: // Setup
////Changed
virtual void AddEntrySignal(CSignalBase *signal) { AddSignal(signal, mEntrySignals); }
virtual void AddExitSignal(CSignalBase *signal) { AddSignal(signal, mExitSignals); }
virtual void AddSignal(CSignalBase *signal, CSignalBase* &signals[]);
////virtual void AddEntrySignal(CSignalBase *signal) { mEntrySignal=signal; }
////virtual void AddExitSignal(CSignalBase *signal) { mExitSignal=signal; }
public: // Event handlers
virtual int OnInit();
virtual void OnTick();
virtual void OnTimer() { return; }
virtual double OnTester() { return(0.0); }
virtual void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) {};
#ifdef __MQL5__
virtual void OnTrade() { return; }
virtual void OnTradeTransaction(const MqlTradeTransaction& trans,
const MqlTradeRequest& request,
const MqlTradeResult& result)
{ return; }
virtual int OnTesterInit() { return(INIT_SUCCEEDED); }
virtual void OnTesterPass() { return; }
virtual void OnTesterDeinit() { return; }
virtual void OnBookEvent() { return; }
#endif
public: // Functions
virtual void GetMarketPrices(ENUM_ORDER_TYPE orderType, MqlTradeRequest &request);
////New
virtual ENUM_OFX_SIGNAL_DIRECTION GetCurrentSignal(CSignalBase* &signals[],
ENUM_OFX_SIGNAL_TYPE signalType);
};
CExpertBase::~CExpertBase() {
}
int CExpertBase::OnInit() {
int i = 0;
for (i=ArraySize(mEntrySignals)-1; i>=0; i--) {
if (mEntrySignals[i].InitResult()!=INIT_SUCCEEDED) return(mEntrySignals[i].InitResult());
}
for (i=ArraySize(mExitSignals)-1; i>=0; i--) {
if (mExitSignals[i].InitResult()!=INIT_SUCCEEDED) return(mExitSignals[i].InitResult());
}
if (mTakeProfitObj!=NULL) {
if (mTakeProfitObj.InitResult()!=INIT_SUCCEEDED) return(mTakeProfitObj.InitResult());
}
if (mStopLossObj!=NULL) {
if (mStopLossObj.InitResult()!=INIT_SUCCEEDED) return(mStopLossObj.InitResult());
}
return(INIT_SUCCEEDED);
}
int CExpertBase::Init(int magicNumber, string tradeComment) {
if (mInitResult!=INIT_SUCCEEDED) return(mInitResult);
mTradeComment = tradeComment;
SetMagic(magicNumber);
mTakeProfitValue = 0.0;
mStopLossValue = 0.0;
mLastBarTime = 0;
////New
ArrayResize(mEntrySignals, 0); // Just make sure these are initialised
ArrayResize(mExitSignals, 0);
return(INIT_SUCCEEDED);
}
void CExpertBase::OnTick(void) {
if (!TradeAllowed()) return;
mBarTime = iTime(mSymbol, mTimeframe, 0);
bool firstTime = (mLastBarTime==0);
bool newBar = (mBarTime!=mLastBarTime);
if (LoopMain(newBar, firstTime)) {
mLastBarTime = mBarTime;
}
return;
}
bool CExpertBase::LoopMain(bool newBar,bool firstTime) {
//
// To start I will only trade on a new bar
// and not on the first bar after start
//
if (!newBar) return(true);
if (firstTime) return(true);
//
// Update the signals
//
////Changed
ENUM_OFX_SIGNAL_DIRECTION entrySignal = GetCurrentSignal(mEntrySignals, OFX_ENTRY_SIGNAL);
ENUM_OFX_SIGNAL_DIRECTION exitSignal = GetCurrentSignal(mExitSignals, OFX_EXIT_SIGNAL);
////if (mEntrySignal!=NULL) mEntrySignal.UpdateSignal();
////if (mEntrySignal!=mExitSignal) {
//// if (mExitSignal!=NULL) mExitSignal.UpdateSignal();
////}
//
// Should any trades be closed
//
////Changed
if (exitSignal==OFX_SIGNAL_BOTH) {
Trade.PositionCloseByType(mSymbol, POSITION_TYPE_BUY);
Trade.PositionCloseByType(mSymbol, POSITION_TYPE_SELL);
} else
if (exitSignal==OFX_SIGNAL_BUY) {
Trade.PositionCloseByType(mSymbol, POSITION_TYPE_BUY);
} else
if (exitSignal==OFX_SIGNAL_SELL) {
Trade.PositionCloseByType(mSymbol, POSITION_TYPE_SELL);
}
////if (mExitSignal!=NULL) {
//// if (mExitSignal.ExitSignal()==OFX_SIGNAL_BOTH) {
//// Trade.PositionCloseByType(mSymbol, POSITION_TYPE_BUY);
//// Trade.PositionCloseByType(mSymbol, POSITION_TYPE_SELL);
//// } else
//// if (mExitSignal.ExitSignal()==OFX_SIGNAL_BUY) {
//// Trade.PositionCloseByType(mSymbol, POSITION_TYPE_BUY);
//// } else
//// if (mExitSignal.ExitSignal()==OFX_SIGNAL_SELL) {
//// Trade.PositionCloseByType(mSymbol, POSITION_TYPE_SELL);
//// }
////}
//
// Should a trade be opened
//
MqlTradeRequest request = {}; // Just initialising
////Changed
if (entrySignal==OFX_SIGNAL_BOTH) {
GetMarketPrices(ORDER_TYPE_BUY, request);
Trade.Buy(mVolume, mSymbol, request.price, request.sl, request.tp);
GetMarketPrices(ORDER_TYPE_SELL, request);
Trade.Sell(mVolume, mSymbol, request.price, request.sl, request.tp);
} else
if (entrySignal==OFX_SIGNAL_BUY) {
GetMarketPrices(ORDER_TYPE_BUY, request);
Trade.Buy(mVolume, mSymbol, request.price, request.sl, request.tp);
} else
if (entrySignal==OFX_SIGNAL_SELL) {
GetMarketPrices(ORDER_TYPE_SELL, request);
Trade.Sell(mVolume, mSymbol, request.price, request.sl, request.tp);
}
//// if (mEntrySignal!=NULL) {
//// if (mEntrySignal.EntrySignal()==OFX_SIGNAL_BOTH) {
////
//// GetMarketPrices(ORDER_TYPE_BUY, request);
//// Trade.Buy(mVolume, mSymbol, request.price, request.sl, request.tp);
////
//// GetMarketPrices(ORDER_TYPE_SELL, request);
//// Trade.Sell(mVolume, mSymbol, request.price, request.sl, request.tp);
////
//// } else
//// if (mEntrySignal.EntrySignal()==OFX_SIGNAL_BUY) {
////
//// GetMarketPrices(ORDER_TYPE_BUY, request);
//// Trade.Buy(mVolume, mSymbol, request.price, request.sl, request.tp);
////
//// } else
//// if (mEntrySignal.EntrySignal()==OFX_SIGNAL_SELL) {
////
//// GetMarketPrices(ORDER_TYPE_SELL, request);
//// Trade.Sell(mVolume, mSymbol, request.price, request.sl, request.tp);
////
//// }
//// }
return(true);
}
void CExpertBase::GetMarketPrices(ENUM_ORDER_TYPE orderType, MqlTradeRequest &request) {
double sl = (mStopLossObj==NULL) ? mStopLossValue : mStopLossObj.GetStopLoss();
double tp = (mTakeProfitObj==NULL) ? mTakeProfitValue : mTakeProfitObj.GetTakeProfit();
if (orderType==ORDER_TYPE_BUY) {
if (request.price==0.0) request.price = SymbolInfoDouble(mSymbol, SYMBOL_ASK);
request.tp = (tp==0.0) ? 0.0 : NormalizeDouble(request.price+tp, mDigits);
request.sl = (sl==0.0) ? 0.0 : NormalizeDouble(request.price-sl, mDigits);
}
if (orderType==ORDER_TYPE_SELL) {
if (request.price==0.0) request.price = SymbolInfoDouble(mSymbol, SYMBOL_BID);
request.tp = (tp==0.0) ? 0.0 : NormalizeDouble(request.price-tp, mDigits);
request.sl = (sl==0.0) ? 0.0 : NormalizeDouble(request.price+sl, mDigits);
}
return;
}
////New
void CExpertBase::AddSignal(CSignalBase *signal, CSignalBase* &signals[]) {
int index = ArraySize(signals);
ArrayResize(signals, index+1);
signals[index] = signal;
}
////New
ENUM_OFX_SIGNAL_DIRECTION CExpertBase::GetCurrentSignal(CSignalBase* &signals[],
ENUM_OFX_SIGNAL_TYPE signalType) {
ENUM_OFX_SIGNAL_DIRECTION result = OFX_SIGNAL_NONE;
ENUM_OFX_SIGNAL_DIRECTION r2 = OFX_SIGNAL_NONE; // Just working value
int index = ArraySize(signals);
if (index<=0) {
return(result);
} else {
signals[0].UpdateSignal();
result = signals[0].GetSignal(signalType);
// I have chosen to update all signals in case there is some
// behavour that needs it. The penalty is some performance
// If performance is an issue just add an exit inside the loop
// as the commented line
for (int i = 1; i<index; i++) {
//if (result==OFX_SIGNAL_NONE) return(result);
signals[i].UpdateSignal();
r2 = signals[i].GetSignal(signalType);
// The logic here
// If the current result is both then just update to the r2
// because this allows for any value
// If r2 is both then this just leave the current result as is
// Last test, meaning result is already none or buy or sell
// If r2 is different then we cannot combine them
// so the result must be none
//
// or like this
//
// result r2 gives
// Both + Any = Any
// Any + Both = Any
// !Both + !Same = None
if (result==OFX_SIGNAL_BOTH) { result = r2; }
else if (r2==OFX_SIGNAL_BOTH) { }
else if (result!=r2) { result = OFX_SIGNAL_NONE; }
}
}
return(result);
}
+21
View File
@@ -0,0 +1,21 @@
/*
Framework.mqh
Copyright 2013-2020, Orchard Forex
https://www.orchardforex.com
*/
//
// The only purpose of this mqh file is to provide a single
// point to change the current framework version
//
// If you place an include to this file in your code you
// will get the version framework defined in this file
// unless your code has already included another
// framework file
#ifndef _FRAMEWORK_VERSION_
#include "Framework_2.04/Framework.mqh"
#endif
Binary file not shown.