Organize project in different folders

This commit is contained in:
Nkondog A. Venceslas
2022-11-28 16:07:29 +01:00
parent 2f87fb5e3f
commit cbb412a720
244 changed files with 9 additions and 4 deletions
@@ -0,0 +1,27 @@
//+------------------------------------------------------------------+
//| CheckHistory.mqh |
//| Copyright 2021, Nkondog Anselme Venceslas |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Nkondog Anselme Venceslas"
#property link "https://www.mql5.com"
//+------------------------------------------------------------------+
//| defines |
//+------------------------------------------------------------------+
// #define MacrosHello "Hello, world!"
// #define MacrosYear 2010
//+------------------------------------------------------------------+
//| DLL imports |
//+------------------------------------------------------------------+
// #import "user32.dll"
// int SendMessageA(int hWnd,int Msg,int wParam,int lParam);
// #import "my_expert.dll"
// int ExpertRecalculate(int wParam,int lParam);
// #import
//+------------------------------------------------------------------+
//| EX5 imports |
//+------------------------------------------------------------------+
// #import "stdlib.ex5"
// string ErrorDescription(int error_code);
// #import
//+------------------------------------------------------------------+
@@ -0,0 +1,133 @@
//+------------------------------------------------------------------+
//| DCAManager.mqh |
//| Copyright 2022, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link "https://www.mql5.com"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void DcaManager()
{
//Compute pending orders levels
ENUM_DCA_STATUS dcaStatus = DcaWatcher();
switch(dcaStatus)
{
case NO_DEALS :
signal = NO_SIGNAL;
break;
case NO_BUY_POSITIONS :
signal = BUY_SIGNAL;
break;
case BUY_PENDING_ORDERS :
signal = PENDING_ORDERS;
break;
case NO_UPPER_BUY_ORDER :
signal = BUY_STOP_SIGNAL;
break;
case NO_LOWER_BUY_ORDER :
signal = BUY_LIMIT_SIGNAL;
break;
case BUY_POSITION_EXISTS :
signal = NO_SIGNAL;
break;
default:
signal = NO_SIGNAL;
break;
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
ENUM_DCA_STATUS DcaWatcher()
{
if(gTotalBuyPositions > 0)
{
bool hasOrderAbove = false, hasOrderBelow = false;
if(PositionGetTicket(lastTicketId) == 0)
{
int Error=GetLastError();
Print("ERROR - Unable to select the position - ",Error," - ",Error);
return NO_DEALS;
}
if(PositionSelect(gSymbol))
{
if(PositionGetSymbol(lastTicketId)==gSymbol && PositionGetInteger(POSITION_MAGIC)==InpMagicNumber)
{
//Compute above and below orders price
Print("Last ticket id ", lastTicketId, " last ticket price ", PositionGetDouble(POSITION_PRICE_OPEN));
gUpOpenPrice = PositionGetDouble(POSITION_PRICE_OPEN) + (InpBuyCallBack * point);
gDownOpenPrice = PositionGetDouble(POSITION_PRICE_OPEN) - (InpBuyCallBack * point);
Print("gUpOpenPrice ", gUpOpenPrice, " gDownOpenPrice ", gDownOpenPrice);
//Check orders around the last opened position
for(int i=0; i<gTotalOrders; i++)
{
//If there is a problem reading the order print the error, exit the function and return false
if(OrderGetTicket(i) == 0)
{
int Error=GetLastError();
Print("ERROR - Unable to select the order - ",Error," - ",Error);
return NO_DEALS;
}
//Check existence of above and below orders to last opened position
if(OrderGetString(ORDER_SYMBOL)==gSymbol && OrderGetInteger(ORDER_MAGIC)==InpMagicNumber)
{
if(gUpOpenPrice == OrderGetDouble(ORDER_PRICE_OPEN))
{
hasOrderAbove = true;
}
if(gDownOpenPrice == OrderGetDouble(ORDER_PRICE_OPEN))
{
hasOrderBelow = true;
}
}
}
//Do nothing if both orders exist
if(hasOrderAbove && hasOrderBelow)
{
Print("hasOrderAbove && hasOrderBelow");
return NO_DEALS;
}
//Report non existence of one or both orders
if(!hasOrderAbove && hasOrderBelow)
{
Print("hasOrderAbove && hasOrderBelow");
return NO_UPPER_BUY_ORDER;
}
if(hasOrderAbove && !hasOrderBelow)
{
Print("hasOrderAbove && !hasOrderBelow");
return NO_LOWER_BUY_ORDER;
}
if(!hasOrderAbove && !hasOrderBelow)
{
Print("!hasOrderAbove && !hasOrderBelow");
return BUY_PENDING_ORDERS;
}
return BUY_POSITION_EXISTS;
}
}
}
else
{
return NO_BUY_POSITIONS;
}
return NO_DEALS;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
Binary file not shown.
@@ -0,0 +1,63 @@
//+------------------------------------------------------------------+
//| LotSizeCal.mqh |
//| Copyright 2021, Nkondog Anselme Venceslas |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Nkondog Anselme Venceslas"
#property link "https://www.mql5.com"
//Lot Size Calculator
void LotSizeCalculate(double SL=0)
{
//If the position size is dynamic
if(InpRiskDefaultSize==RISK_DEFAULT_AUTO)
{
//If the stop loss is not zero then calculate the lot size
if(SL!=0)
{
double RiskBaseAmount=0;
Print("Compute lot size");
//TickValue is the value of the individual price increment for 1 lot of the instrument, expressed in the account currenty
double TickValue=SymbolInfoDouble(gSymbol,SYMBOL_TRADE_TICK_VALUE);
//Define the base for the risk calculation depending on the parameter chosen
if(InpRiskBase==RISK_BASE_BALANCE)
RiskBaseAmount=AccountInfoDouble(ACCOUNT_BALANCE);
if(InpRiskBase==RISK_BASE_EQUITY)
RiskBaseAmount=AccountInfoDouble(ACCOUNT_EQUITY);
if(InpRiskBase==RISK_BASE_FREEMARGIN)
RiskBaseAmount=AccountInfoDouble(ACCOUNT_FREEMARGIN);
//Calculate the Position Size
gLotSize=((RiskBaseAmount*InpMaxRiskPerTrade/100)/(SL*TickValue));
Print("(RiskBaseAmount ", RiskBaseAmount, " InpMaxRiskPerTrade ", InpMaxRiskPerTrade, " SL ", SL, " TickValue ", TickValue);
}
//If the stop loss is zero then the lot size is the default one
if(SL==0)
{
gLotSize=InpDefaultLotSize;
}
}
//Normalize the Lot Size to satisfy the allowed lot increment and minimum and maximum position size
Print("gLotSize " , gLotSize, " SymbolInfoDouble(gSymbol,SYMBOL_VOLUME_STEP)) ", SymbolInfoDouble(gSymbol,SYMBOL_VOLUME_STEP), " gSymbol ", gSymbol, " SymbolInfoDouble(gSymbol,SYMBOL_VOLUME_STEP)", SymbolInfoDouble(gSymbol,SYMBOL_VOLUME_STEP));
gLotSize=MathFloor(gLotSize/SymbolInfoDouble(gSymbol,SYMBOL_VOLUME_STEP))*SymbolInfoDouble(gSymbol,SYMBOL_VOLUME_STEP);
Print("LotSize ", gLotSize);
//Limit the lot size in case it is greater than the maximum allowed by the broker
if(gLotSize>SymbolInfoDouble(gSymbol,SYMBOL_VOLUME_MAX))
gLotSize=SymbolInfoDouble(gSymbol,SYMBOL_VOLUME_MAX);
Print("Lot ", gLotSize, " Max lot ", SymbolInfoDouble(gSymbol,SYMBOL_VOLUME_MAX));
Print("LotSize2 ", gLotSize);
//If the lot size is too small then set it to 0 and don't trade
if(gLotSize<InpMinLotSize || gLotSize < SymbolInfoDouble(gSymbol,SYMBOL_VOLUME_MIN))
{
gLotSize=0;
Print("Lot size too small : ", gLotSize);
}
Print("LotSize3 ", gLotSize);
}
//+------------------------------------------------------------------+
@@ -0,0 +1,147 @@
//+------------------------------------------------------------------+
//| Parameters.mqh |
//| Copyright 2021, Nkondog Anselme Venceslas |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Nkondog Anselme Venceslas"
#property link "https://www.mql5.com"
//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 trading time
enum ENUM_MODE_TRADING_TIME
{
DAY_TRADING=0, //Day trade
NIGHT_TRADING=1, //Night trade
DAY_NIGHT_TRADING=2, //Both day & night trade
ALL_DAY_TRADING=3, //Round the clock
};
//Enumerative for trading time
enum ENUM_MODE_TRADE_SIGNAL
{
BUY_SIGNAL=0, //Buy trade
BUY_STOP_SIGNAL=1, //Sell trade
BUY_LIMIT_SIGNAL=2,
NO_SIGNAL=3, //No trade
PENDING_ORDERS=4
};
//Enumerative for the DCA mode
enum ENUM_DCA_STATUS
{
NO_DEALS=0,
NO_BUY_POSITIONS=1,
NO_UPPER_BUY_ORDER=2,
NO_LOWER_BUY_ORDER=3,
BUY_POSITION_EXISTS=4,
UPPER_BUY_ORDERS=5,
LOWER_BUY_ORDERS=6,
BUY_PENDING_ORDERS=7
};
//
// Input Section
//
input string Comment_0="=========="; //Risk Management Settings
input ENUM_RISK_DEFAULT_SIZE InpRiskDefaultSize=RISK_DEFAULT_AUTO; //Position Size Mode
input double InpDefaultLotSize=0.01; //Position Size (if fixed or if no stop loss defined)
input ENUM_RISK_BASE InpRiskBase=RISK_BASE_BALANCE; //Risk Base
input double InpMaxRiskPerTrade=0.5; //Percentage To Risk Each Trade
input double InpMinLotSize=0.01; //Minimum Position Size Allowed
input double InpMaxLotSize=100; //Maximum Position Size Allowed
input int InpMaxSpread=10; //Maximum Spread Allowed
input int InpSlippage=1; //Maximum Slippage Allowed in points
input string Comment_01="----------------------"; //Stop loss settings
input int InpDefaultStopLoss=200; //Default Stop Loss In Points (0=No Stop Loss)
input int InpMinStopLoss=0; //Minimum Allowed Stop Loss In Points
input int InpMaxStopLoss=5000; //Maximum Allowed Stop Loss In Points
input string Comment_02="----------------------"; //Take profit settings
input int InpDefaultTakeProfit=100; //Default Take Profit In Points (0=No Take Profit)
input int InpMinTakeProfit=0; //Minimum Allowed Take Profit In Points
input int InpMaxTakeProfit=5000; //Maximum Allowed Take Profit In Points
input double InpTakeProfitPercent=1.0; //Take Profit percent on risk base
input string Comment_03="----------------------"; //Trading Hours Settings
input bool InpUseTradingHours=false; //Limit Trading Hours
input ENUM_MODE_TRADING_TIME InpTradingPeriods=ALL_DAY_TRADING; //Select trading periods
input int InpDayTradingHourStart=7; //Day Trading Start Hour (Broker Server Hour)
input int InpDayTradingHourEnd=21; //Day Trading End Hour (Broker Server Hour)
input int InpNightTradingHourStart=1; //Night Trading Start Hour (Broker Server Hour)
input int InpNightTradingHourEnd=5; //Night Trading End Hour (Broker Server Hour)
input string Comment_04="----------------------"; //DCA settings
input bool InpActivateDCAHedging=true; //Active DCA Hedging
input string InpInstrument1="EURUSD"; //Instrument 1
input string InpInstrument2="USDCHF"; //Instrument 2
input int InpBuyCallBack=100; //Buy call back pips
input int InpMaxCallBack=10; //Call back limit
input int InpWholePositionTP=0; //Whole position TP percent. 0 to disable
input string Comment_05="----------------------"; //Stop loss settings
input string InpComment = __FILE__; //Default trade comment
input int InpMagicNumber = 198901; //Magic Number
input ENUM_TIMEFRAMES InpTimeFrame = PERIOD_CURRENT;
input int InpSameCandleCount= 2; //Same Candle in a row
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
string gSymbol;
int gTotalBuyOrders, gTotalBuyPositions, gTotalOrders, gTotalPositions;
bool gIsOperatingHours=false;
bool gIsPreChecksOk=false; //Indicates if the pre checks are satisfied
bool gIsSpreadOK=false; //Indicates if the spread is low enough to trade
bool IsSpreadOK=false;
bool gEmergencyClose=false; //Urgently close losing trade
double gUpOpenPrice, gDownOpenPrice;
double gLotSize=InpDefaultLotSize, point;
int gTickValue=0, lastTicketId;
long Spread;// = SymbolInfoInteger(gSymbol,SYMBOL_SPREAD) / 100; //Check the impact. It's originally a double
int gOrderOpRetry = 1;
MqlTick last_tick, blast_tick;
MqlDateTime dt;
ENUM_MODE_TRADE_SIGNAL signal = NO_SIGNAL;
//+------------------------------------------------------------------+
@@ -0,0 +1,79 @@
//+------------------------------------------------------------------+
//| 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()
{
gIsPreChecksOk=true;
//Check if Live Trading is enabled
if(!MQLInfoInteger(MQL_TRADE_ALLOWED))
{
gIsPreChecksOk=false;
Print("Live Trading is not enabled, please enable it in Metatrader and chart settings");
return;
}
//Trading period verification
if(!gIsOperatingHours)
{
gIsPreChecksOk=false;
Print("Out of trading hours");
return;
}
//Check if the default stop loss you are setting in above the minimum and below the maximum
if(InpDefaultStopLoss<InpMinStopLoss || InpDefaultStopLoss>InpMaxStopLoss)
{
gIsPreChecksOk=false;
Print("Default Stop Loss must be between Minimum and Maximum Stop Loss Allowed");
return;
}
//Check if the default take profit you are setting in above the minimum and below the maximum
if(InpDefaultTakeProfit<InpMinTakeProfit || InpDefaultTakeProfit>InpMaxTakeProfit)
{
gIsPreChecksOk=false;
Print("Default Take Profit must be between Minimum and Maximum Take Profit Allowed");
return;
}
//Check if the Lot Size is between the minimum and maximum
if(InpDefaultLotSize<InpMinLotSize || InpDefaultLotSize>InpMaxLotSize)
{
gIsPreChecksOk=false;
Print("Default Lot Size must be between Minimum and Maximum Lot Size Allowed");
return;
}
//Slippage must be >= 0
if(InpSlippage<0)
{
gIsPreChecksOk=false;
Print("Slippage must be a positive value");
return;
}
//MaxSpread must be >= 0
if(InpMaxSpread<0)
{
gIsPreChecksOk=false;
Print("Maximum Spread must be a positive value");
return;
}
//MaxRiskPerTrade is a % between 0 and 100
if(InpMaxRiskPerTrade<0 || InpMaxRiskPerTrade>100)
{
gIsPreChecksOk=false;
Print("Maximum Risk Per Trade must be a percentage between 0 and 100");
return;
}
//Spread is acceptable
long SpreadCurr=(int)Spread;
Print("Spread ", Spread);
if(SpreadCurr>InpMaxSpread)
{
gIsPreChecksOk=false;
Print("Spread is higher than Max acceptable spread");
return;
}
}
//+------------------------------------------------------------------+
@@ -0,0 +1,74 @@
//+------------------------------------------------------------------+
//| ScanPositions.mqh |
//| Copyright 2021, Nkondog Anselme Venceslas |
//| https://www.linkedin.com/in/nkondog |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Nkondog Anselme Venceslas"
#property link "https://www.linkedin.com/in/nkondog"
//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
void ScanPositions()
{
//Scan all the orders, retrieving some of the details
gTotalPositions = PositionsTotal();
gTotalOrders = OrdersTotal();
gTotalBuyPositions = 0;
gTotalBuyOrders = 0;
for(int i=0; i<gTotalPositions; 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);
Print("ERROR - Unable to select the order - ",Error," - ",Error);
return;
}
if(PositionSelect(gSymbol))
{
//If the order is not for the instrument on chart we can ignore it
if(PositionGetSymbol(i)!=gSymbol)
continue;
//If the order has Magic Number different from the Magic Number of the EA then we can ignore it
if(PositionGetInteger(POSITION_MAGIC)!=InpMagicNumber)
continue;
//If it is a buy order then increment the total count of buy orders
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
gTotalBuyPositions++;
lastTicketId = i;
}
Print("Total ", gSymbol, " buy position ", gTotalBuyPositions, " lastTicketId ", PositionGetTicket(i), " lastTicket price ", PositionGetDouble(POSITION_PRICE_OPEN));
}
for(int i=0; i<gTotalOrders; i++)
{
//If there is a problem reading the order print the error, exit the function and return false
if(OrderGetTicket(i) == 0)
{
int Error=GetLastError();
//string ErrorText=GetLastErrorText(Error);
//Print("ERROR - Unable to select the order - ",Error," - ",ErrorText);
Print("ERROR - Unable to select the order - ",Error," - ",Error);
return;
}
//If the order is not for the instrument on chart we can ignore it
if(OrderGetString(ORDER_SYMBOL)!=gSymbol)
continue;
//If the order has Magic Number different from the Magic Number of the EA then we can ignore it
if(OrderGetInteger(ORDER_MAGIC)!=InpMagicNumber)
continue;
//If it is a buy order then increment the total count of buy orders
if(OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_LIMIT || OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_STOP)
gTotalBuyOrders++;
}
Print("Total ", gSymbol, " Orders ", gTotalOrders, " - Total ", gSymbol, " buy orders ", gTotalBuyOrders);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
@@ -0,0 +1,62 @@
//+------------------------------------------------------------------+
//| TradingHour.mqh |
//| Copyright 2021, Nkondog Anselme Venceslas |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Nkondog Anselme Venceslas"
#property link "https://www.mql5.com"
//Check and return if it is operation hours or not
void CheckOperationHours()
{
bool day_trading = false, night_trading = false;
gIsOperatingHours=false;
//If we are not using operating hours then IsOperatingHours is true and I skip the other checks
if(!InpUseTradingHours || InpTradingPeriods == ALL_DAY_TRADING)
{
gIsOperatingHours=true;
Print("Round clock trading");
return;
}
if(InpTradingPeriods == DAY_TRADING)
{
Print("dt.hour ", dt.hour," >= InpDayTradingHourStart ", InpDayTradingHourStart ," ", dt.hour >= InpDayTradingHourStart);
Print("dt.hour ", dt.hour," <= InpDayTradingHourEnd ", InpDayTradingHourEnd ," ", dt.hour <= InpDayTradingHourEnd);
//Check day trading hours
if(dt.hour >= InpDayTradingHourStart && dt.hour <= InpDayTradingHourEnd)
{
day_trading = true;
gIsOperatingHours=true;
Print("Day period trading");
return;
}
}
Print("InpTradingPeriods == NIGHT_TRADING ", InpTradingPeriods == NIGHT_TRADING);
if(InpTradingPeriods == NIGHT_TRADING)
{
//Check night trading hours
if(dt.hour >= InpNightTradingHourStart && dt.hour <= InpNightTradingHourEnd)
{
night_trading = true;
gIsOperatingHours=true;
Print("Night period trading");
return;
}
}
if(InpTradingPeriods == DAY_NIGHT_TRADING)
{
//Check night trading hours
if(day_trading || night_trading)
{
gIsOperatingHours=true;
Print("Day and night periods trading");
return;
}
}
}
//+------------------------------------------------------------------+