diff --git a/Experts/Nkanven/CandleCount.ex5 b/Experts/Nkanven/CandleCount.ex5 deleted file mode 100644 index 22dcaea..0000000 Binary files a/Experts/Nkanven/CandleCount.ex5 and /dev/null differ diff --git a/Experts/Nkanven/GeminiHedge.ex5 b/Experts/Nkanven/GeminiHedge.ex5 new file mode 100644 index 0000000..0dc87d4 Binary files /dev/null and b/Experts/Nkanven/GeminiHedge.ex5 differ diff --git a/Experts/Nkanven/GeminiHedge.mq5 b/Experts/Nkanven/GeminiHedge.mq5 new file mode 100644 index 0000000..f0933cf --- /dev/null +++ b/Experts/Nkanven/GeminiHedge.mq5 @@ -0,0 +1,78 @@ +//+------------------------------------------------------------------+ +//| GeminiHedge.mq5 | +//| Copyright 2022, Nkondog Anselme Venceslas. | +//| https://www.linkedin.com/in/nkondog | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2022, Nkondog Anselme Venceslas." +#property link "https://www.linkedin.com/in/nkondog" +#property version "1.00" +#include +#include //EA paramters +#include //Trading hours checks +#include //Trading conditions checks +#include //Trading conditions checks +#include //Lot size calculator +#include //Lot size calculator +//+------------------------------------------------------------------+ +//| Expert initialization function | +//+------------------------------------------------------------------+ + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int OnInit() + { +//--- +//--- + return(INIT_SUCCEEDED); + } +//+------------------------------------------------------------------+ +//| Expert deinitialization function | +//+------------------------------------------------------------------+ +void OnDeinit(const int reason) + { +//--- + + } +//+------------------------------------------------------------------+ +//| Expert tick function | +//+------------------------------------------------------------------+ +void OnTick() + { +//--- + TimeCurrent(dt); + string instruments[]; + + if(InpActivateDCAHedging) + { + string instruments[] = {InpInstrument1, InpInstrument2}; + } + else + { + string instruments[] = {InpInstrument1}; + } + + for(int i=0; i 0) + { + //return position exists + } + } +//+------------------------------------------------------------------+ diff --git a/Include/Nkanven/GeminiHedge/EntriesManager.mqh b/Include/Nkanven/GeminiHedge/EntriesManager.mqh new file mode 100644 index 0000000..51dff0d Binary files /dev/null and b/Include/Nkanven/GeminiHedge/EntriesManager.mqh differ diff --git a/Include/Nkanven/GeminiHedge/LotSizeCal.mqh b/Include/Nkanven/GeminiHedge/LotSizeCal.mqh new file mode 100644 index 0000000..7bf44fc --- /dev/null +++ b/Include/Nkanven/GeminiHedge/LotSizeCal.mqh @@ -0,0 +1,62 @@ +//+------------------------------------------------------------------+ +//| 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 + 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(gLotSizeInpMaxStopLoss) + { + gIsPreChecksOk=false; + Print("Default Stop Loss must be between Minimum and Maximum Stop Loss Allowed"); + return; + } +//Check if the default take profit you are setting in above the minimum and below the maximum + if(InpDefaultTakeProfitInpMaxTakeProfit) + { + gIsPreChecksOk=false; + Print("Default Take Profit must be between Minimum and Maximum Take Profit Allowed"); + return; + } +//Check if the Lot Size is between the minimum and maximum + if(InpDefaultLotSizeInpMaxLotSize) + { + gIsPreChecksOk=false; + Print("Default Lot Size must be between Minimum and Maximum Lot Size Allowed"); + return; + } +//Slippage must be >= 0 + if(InpSlippage<0) + { + gIsPreChecksOk=false; + Print("Slippage must be a positive value"); + return; + } +//MaxSpread must be >= 0 + if(InpMaxSpread<0) + { + gIsPreChecksOk=false; + Print("Maximum Spread must be a positive value"); + return; + } +//MaxRiskPerTrade is a % between 0 and 100 + if(InpMaxRiskPerTrade<0 || InpMaxRiskPerTrade>100) + { + gIsPreChecksOk=false; + Print("Maximum Risk Per Trade must be a percentage between 0 and 100"); + return; + } +//Spread is acceptable + long SpreadCurr=(int)Spread; + Print("Spread ", Spread); + if(SpreadCurr>InpMaxSpread) + { + gIsPreChecksOk=false; + Print("Spread is higher than Max acceptable spread"); + return; + } + } +//+------------------------------------------------------------------+ diff --git a/Include/Nkanven/GeminiHedge/ScanPositions.mqh b/Include/Nkanven/GeminiHedge/ScanPositions.mqh new file mode 100644 index 0000000..6f636c8 --- /dev/null +++ b/Include/Nkanven/GeminiHedge/ScanPositions.mqh @@ -0,0 +1,76 @@ +//+------------------------------------------------------------------+ +//| 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= 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; + } + } + } +//+------------------------------------------------------------------+ diff --git a/gemini.drawio b/gemini.drawio new file mode 100644 index 0000000..0f476fe --- /dev/null +++ b/gemini.drawio @@ -0,0 +1 @@ +1Vpbb6s4EP41kXYfWgHmlsekTXtW291Wp5V6+uiAQ7wlODKmTc6vX1PM1YSQBEjahwqPx8bMfPMxM2EEblabewrXy3+Ii/yRpribEbgdaZqtjvn/WLBNBLqtJQKPYjcRqbngGf9GQqgIaYRdFJYUGSE+w+uy0CFBgBxWkkFKyWdZbUH88l3X0EOS4NmBvix9xS5bisfSrFz+A2Fvmd5ZNcUDr2CqLJ4kXEKXfBZEYDYCN5QQllytNjfIj22X2iVZd7djNjsYRQFrs8CYPv6GLxq+ZxDTt49JdLX6uFLNZJsP6EfiicVp2TY1AXK5RcSQULYkHgmgP8ulU0qiwEXxfRQ+ynUeCFlzocqF/yHGtsK9MGKEi5Zs5YvZBfb9G+IT+nVH4BrIdnUuDxkl76gwY2tzYJp8JjllfLSd5hCikETUQU020AWuIPUQa1I0MrdxuCOyQoxu+UKKfMjwR/kkUADPy/Ry3/AL4Z5DXKVLrpo4jBum6i8OtHV8Ga38RAFMPxBlmIP6Ac6R/0RCzDAJuMqcMEZWBYWJj714gsWOK3qIRMzHAXdFGmZK5oR4Ldo0u0E2mlgARHQIelAtMf7Mgy1VWRbizFR6srJmXERAdAlvoyW8d3lqIHjXGd70+YGnc45x04uvHmAUOEuuNZtIXvlcYoae1/DLGJ/8ZVS2aD3CjyWekzA/NvZiXtUGBb0q2f6JImeJnPdQsjNdktU84keY7rF4xbYL/ucodbZdLBT+141tNaNCKLZsXLvGtnpvttUk295BP0RHsErBtlCg2EcLVgPujNdR4E7iLCjec42CRCJYx270RZnCuPXp9hcfXCnXijZOJW/x9LVu26ngdlNccLstjp4QxdymiJbeHhLH7SW0BjLcz3FmI3quxD6tKU/s9EQwP0m2ja6UQagpFXQl5xSrcoBxV8FtQW0dK4S776ONy/cRuWcO12TDHLzZE5+AZyDh+YVG/cI54erOsayUYWzsAfFZ8GoPgdcqjjKG7BmvoFyy9ATY8UVkdGctcTTzRLwNkwNqcjW6Ow/h++F1GPumUPDw+oTb0z88ObEd5Dh17pjbhm50VexU8S/nJlZNblKNxs7sDWQuP0dodAl0uyXQgVLvqcOY9FACNJRGAtyrnyYS/RKmLUehaBmEsZ82OGQSTHIQqAcHnwuRvagNPtOx0XzRUfCZ9rVVrryy91Gx8lK1a0OOwd5qr5QDCtbmJOYmHZrvVXsZ+oXVXkCua79z7TVQvpoi8ph8FeiNCOkoXzUrRb7VT7pq2LW36ZV8gdwuuNTyKktUu4HrrgT5LDAepE1QxReoEmFPOB6k7ALWEZg9OZXMwZfj7a0Et8PAN0h1Btr+ALULlsNUZ0D+AerJjxMQ/tScKnDg8StCXURrmsYXnx6aleRFr0sNh2zK68ZZAmiDWRI/liGGb4WpPHziQam9e0TUdRlDbTscYHxiDB1FwZZWrjyA3Vz4WabVpN8TZcvtl5u49xK7JC8A775viIMW5d+gP7zp4IJiXGkX4+rolLSudaOtG1YYt2WFHXXLQG9WuUU9i7ssySvVg+s/wj8b4k250HanpZRJLPtZ7HzxJjdbJl+rQtTU0jrcwMN8SGCY1Zzl7AZu8z1ZXmg6PgxDnAARUiaLCxbeVWVea6WcQ93DR+3Z5eh0vGB9o8b4qezUJoi2w/npFgk7StWjXB6qlY20fsrQ6oH35UDVjHyvvtmYY/WTM+mWBPgfs9v7v/6958KXn5Pb5Gr6+ML/vz7+/Pvu4fH1NKrxKHQxB2tKKgEJ4rTAj7/tm0Ln3fvarXb2K3WrzCxIwNKEQ03HSeqgWRVmE0vKpCaEHfBZ5WNAYMp0llFXMaLUKvRb8Bkf5t/eJmjIP2AGs/8B \ No newline at end of file