//+------------------------------------------------------------------+ //| valFvgMt5.mq5 | //| Copyright 2025, MQL Development | //| https://www.mqldevelopment.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MQL Development" #property link "https://www.mqldevelopment.com/" #property version "1.00" #include CTrade trade; #resource "\\Indicators\\SequentialVolumeProfileWithFVG.ex5" //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ enum lotcalculator { fix, //Fixed Lot Size rsk, //Risk Percentage }; enum tp_options { zone_based, risk_reward_based, }; sinput string string_0 = "<><><><><><> General SETTINGS <><><><><><>"; //__ input int magic_no = 333; // Magic no input tp_options select_tp = zone_based; // Select Tp input double stoploss = 10; // Fixed Stop Loss in Pips input double takeprofit = 10; // Fixed Take Profit in Pips input string string_0_3 = "<><><><><><> Lot Management<><><><><><>"; //__ input double lot_size = 0.1; // Lot Size input lotcalculator lot_calculator = fix; // Lot Size Calculator input double risk = 0.1; // Risk in Percentage % input string time_setting = "<><><><><> Time Filter Settings <><><><><>"; //_ input bool EnableTimeFilter = false; // Enable Time Filter input string startTime = "03:00"; // Start Time Session input string endTime = "09:00"; // End Time Session sinput string string_1 = "<><><><><><> Sequential Volume Indicator SETTINGS <><><><><><>"; //__ input int BinsCount = 100; // Number of price bins input double ValueAreaPercent = 70; // Value Area percentage (70% default) input color VALColor = clrDarkBlue; // Value Area Low color input color VAHColor = clrDarkBlue; // Value Area High color input color AbsLowColor = clrBlack; // Absolute Low color input color AbsHighColor = clrBlack; // Absolute High color input color TimeLineColor = clrRed; // Time marker line color input int LineWidth = 2; // Line width for all value lines input int TimeLineWidth = 2; // Line width for time marker lines input int MaxDaysBack = 30; // Maximum number of trading days to look back input ENUM_LINE_STYLE VALStyle = STYLE_SOLID; // Value Area Low line style input ENUM_LINE_STYLE VAHStyle = STYLE_SOLID; // Value Area High line style input ENUM_LINE_STYLE AbsLowStyle = STYLE_SOLID; // Absolute Low line style input ENUM_LINE_STYLE AbsHighStyle = STYLE_SOLID; // Absolute High line style input bool ShowLabels = true; // Show price labels input bool ShowComment = true; // Show comment with most recent levels input bool ShowFVG = true; // Enable Fair Value Gap detection input color BullishFVGColor = clrLime; // Bullish FVG color input color BearishFVGColor = clrDeepPink; // Bearish FVG color input double MinFVGSize = 0.0; // Minimum FVG size in points (0 = any size) input int MaxBarsBack = 300; // How many bars to look back for FVG // Global Variables int sequential_handler; datetime startTradingTime = 0, endTradingTime = 0; string sep = ":"; // A separator as a character ushort u_sep; // The code of the separator character string result1[]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { //--- trade.SetExpertMagicNumber(magic_no); trade.SetDeviationInPoints(10); trade.SetTypeFilling(ORDER_FILLING_IOC); trade.LogLevel(LOG_LEVEL_ALL); trade.SetAsyncMode(false); sequential_handler = iCustom(Symbol(), PERIOD_CURRENT, "::Indicators\\SequentialVolumeProfileWithFVG.ex5", BinsCount, ValueAreaPercent, VALColor, VAHColor, AbsLowColor, AbsHighColor, TimeLineColor, LineWidth, TimeLineWidth, MaxDaysBack, VALStyle, VAHStyle, AbsLowStyle, AbsHighStyle, ShowLabels, ShowComment, ShowFVG, BullishFVGColor, BearishFVGColor, MinFVGSize, MaxBarsBack); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- double values[]; CopyBuffer(sequential_handler,0,0,3,values); double val = lines("VAL"); double vah = lines("VAH"); double absHigh = lines("AbsHigh"); double absLow = lines("AbsLow"); // Print("Val: ", val, " Vah: ", vah, " AbsHigh: ", absHigh, " AbsLow: ", absLow); double Ask = SymbolInfoDouble(Symbol(),SYMBOL_ASK); double Bid = SymbolInfoDouble(Symbol(),SYMBOL_BID); timeConversion(); // Comment(" Start Time: ", startTradingTime, " Close time: ", endTradingTime); if((EnableTimeFilter && TimeCurrent() >= startTradingTime && TimeCurrent() < endTradingTime) || !EnableTimeFilter) { if(todayTradesCount(DEAL_TYPE_BUY) == 0) { if(Ask < val && Ask > absLow) { //if(fvgOverLap("VProfFVG_up_", val)) { placeBuyTrade(); } } } if(todayTradesCount(DEAL_TYPE_SELL) == 0) { if(Bid > vah && Bid < absHigh) { //if(fvgOverLap("VProfFVG_dn_", vah)) { placeSellTrade(); } } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void timeConversion() { MqlDateTime date, date1; TimeToStruct(iTime(Symbol(),PERIOD_CURRENT,0),date); u_sep=StringGetCharacter(sep,0); StringSplit(startTime,u_sep,result1); date.hour = (int)StringToInteger(result1[0]); date.min = (int)StringToInteger(result1[1]); startTradingTime = StructToTime(date); TimeToStruct(iTime(Symbol(),PERIOD_CURRENT,0),date1); StringSplit(endTime,u_sep,result1); date.hour = (int)StringToInteger(result1[0]); date.min = (int)StringToInteger(result1[1]); endTradingTime = StructToTime(date); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double lines(string name) { datetime todayStart = iTime(Symbol(), PERIOD_D1, 0); datetime nextDayStart = todayStart + 86400; datetime latestObjectTime = 0; for(int i = 0; i < ObjectsTotal(0, 0, OBJ_TREND); i++) { string object_name = ObjectName(0, i, 0, OBJ_TREND); datetime object_time = (datetime)ObjectGetInteger(0, object_name, OBJPROP_TIME, 1); if(object_time > todayStart && object_time < nextDayStart) { // Print(" Object Name: ", object_name, " Day Start Time: ", todayStart, " Next Day Time: ", nextDayStart); if((StringFind(object_name, name) != -1)) { double objectPrice = ObjectGetDouble(0, object_name, OBJPROP_PRICE, 0); return objectPrice; } } } return 0; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool fvgOverLap(string name, double price_overlap) { datetime todayStart = iTime(Symbol(), PERIOD_D1, 0); datetime nextDayStart = todayStart + 86400; for(int i = 0; i < ObjectsTotal(0, 0, OBJ_RECTANGLE); i++) { string object_name = ObjectName(0, i, 0, OBJ_RECTANGLE); datetime object_time1 = (datetime)ObjectGetInteger(0, object_name, OBJPROP_TIME, 1); datetime object_time0 = (datetime)ObjectGetInteger(0, object_name, OBJPROP_TIME, 0); double object_price0 = ObjectGetDouble(0, object_name, OBJPROP_PRICE, 0); double object_price1 = ObjectGetDouble(0, object_name, OBJPROP_PRICE, 1); if(object_time1 > todayStart && object_time1 < nextDayStart) { if((StringFind(object_name, name) != -1)) { double fvg_top = MathMax(object_price0, object_price1); double fvg_bottom = MathMin(object_price0, object_price1); if(fvg_top > price_overlap && fvg_bottom < price_overlap) { Print(" Called By: (", name, ") Object Name: ", object_name, " | Time 0: ", TimeToString(object_time0), " | Price 0: ", object_price0, " | Time 1: ", TimeToString(object_time1), " | Price 0: ", object_price0, " | Price 1: ", object_price1, " | \n FVG Top: ", fvg_top, " | FVG Bottom: ", fvg_bottom); return true; } } } } return false; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int todayTradesCount(ENUM_DEAL_TYPE dealType) { int count = 0; ulong ticket_deal_Out=0, ticket_deal_In = 0; if(HistorySelect(iTime(Symbol(),PERIOD_D1,0), TimeCurrent())) { int total = HistoryDealsTotal(); for(int i = total-1; i >= 0 ; i--) { ticket_deal_In = HistoryDealGetTicket(i); if((HistoryDealGetInteger(ticket_deal_In,DEAL_MAGIC) == magic_no) && HistoryDealGetInteger(ticket_deal_In,DEAL_ENTRY) == DEAL_ENTRY_IN && HistoryDealGetString(ticket_deal_In,DEAL_SYMBOL) == Symbol()) // here is the problem solved after break { if(HistoryDealGetInteger(ticket_deal_In, DEAL_TYPE) == dealType) { count++; } } } } return count; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void placeBuyTrade() { double buySL = 0, buyTp=0; //openPrice = SymbolInfoDouble(Symbol(),SYMBOL_ASK); double Ask = SymbolInfoDouble(Symbol(),SYMBOL_ASK); double Bid = SymbolInfoDouble(Symbol(),SYMBOL_BID); if(stoploss != 0) { buySL = Ask - (stoploss * 10 * Point()); } if(select_tp == zone_based) { buyTp = lines("VAH"); } //if(select_tp == risk_reward_based) // { //distance = ((price - buySl) / Point()); //distance = (distance * tpMultiplier); // } //if(takeprofit != 0) // { // buyTp = Ask + (takeprofit * 10 * Point()); // } if(trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,getlot(stoploss * 10),Ask,buySL,buyTp,"Buy Trade Placed")) { Print("Buy Trade Placed: ",trade.ResultOrder()); } else { Print("Error in placing Buy: "+Symbol()+" ",GetLastError()); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void placeSellTrade() { double sellSL = 0, sellTp = 0; //openPrice = SymbolInfoDouble(Symbol(),SYMBOL_BID); double Ask = SymbolInfoDouble(Symbol(),SYMBOL_ASK); double Bid = SymbolInfoDouble(Symbol(),SYMBOL_BID); if(stoploss != 0) { sellSL = Bid + (stoploss * 10 * Point()); } if(takeprofit != 0) { sellTp = Bid - (takeprofit * 10 * Point()); } if(trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,getlot(stoploss * 10),Bid,sellSL,sellTp,"Sell Trade Placed")) { Print("Sell Trade PLaced: ",trade.ResultOrder()); } else { Print("Error in placing Sell: "+Symbol()+" ",GetLastError()); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double getlot(double stop_loss) { Print("Tick Value: ",SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)); Print("Tick Size: ",SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE)); double modeTickV=SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE) ,modeTickS=SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE); // Print("Pip value: ", NormalizeDouble(((SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)/(SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE)/Point))*10),2)); double pipvalue = NormalizeDouble(((SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)/(SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE)/Point()))*10),2); // pipvalue=NormalizeDouble((modeTickV/modeTickS/Point()),) // pipvalue= pipvalue = pipvalue / 10; double lotSize = lot_size; if(lot_calculator==rsk) //calculating risk { double riskamount=(risk/100)*AccountInfoDouble(ACCOUNT_BALANCE); double pipvalue_required=riskamount/stop_loss; lotSize = pipvalue_required/pipvalue; //sl=riskamount/pipValuelot int roundDigit=0; double step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP); while(step<1) { roundDigit++; step=step*10; } Print("Round Digits:",roundDigit); lotSize = NormalizeDouble(lotSize,roundDigit); // } Print("Lot Size: ",lotSize); if(lotSize > SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX)) { lotSize=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX); } else if(lotSize