//+------------------------------------------------------------------+ //| line_level_ea.mq5 | //| Copyright 2025, MQL Development | //| https://www.mqldevelopment.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MQL Development" #property link "https://www.mqldevelopment.com/" #property version "1.1" #include CTrade trade; enum tradeType { buyTrades, // Buy sellTrades, // Sell }; enum NewsCloseOrder { CloseAllRunningOrder=0, LetTheOrderRun=1, }; enum selectLine { LineOnNewsBar =0, LineOnNewsStop=1 }; #import "line_level_news_filter.ex5" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void initiateNews(); int returnNewsStatus(bool High_Impact_News=true ,int High_Start_Time=60//Stop Trade before high News (min) ,int High_Stop_Time=15 //Stop Trade after high News (min) ,bool show_high_line=true//Show verticle Line when high news comes ,bool Medium_Impact_News=true ,int Medium_Start_Time=60//Stop Trade before medium News (min) ,int Medium_Stop_Time=15 //Stop Trade after medium News (min) ,bool show_medium_line=true//Show verticle Line when medium news comes ,bool Low_Impact_News=true ,int Low_Start_Time=60//Stop Trade before low News (min) ,int Low_Stop_Time=15 //Stop Trade after low News (min) ,bool show_low_line=true//Show verticle Line when low news comes ,string symbol="" ,string expert="" ,int GMT_Broker_Time=2 ,selectLine sl=0 ,string extraSymbol="" ); #import input string string_0 = "<><><><><><> General SETTINGS <><><><><><>"; //__ input int magic_no = 333; // Magic no input tradeType selectSide = buyTrades; // Select Side input double lot_size = 0.1; // Lot Size input double lot_multiplier = 2; // Lot Multiplier on Loss Trade input double levels_distence = 10; // Levels Distance in Dollars input double stoploss = 10; // Fixed Stop Loss in Pips input double takeprofit = 10; // Fixed Take Profit in Pips input bool countinueCycleAfterProfit = true; // Continue Trading After Profit 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 input string news = "<><><><><><> News Settings <><><><><><>"; // News input NewsCloseOrder newsClose = CloseAllRunningOrder; // On News Action on Running Orders input bool High_Impact_News = true; //High Impact News input int High_Start_Time = 60; //Stop Trade before high News (min) input int High_Stop_Time = 15; //Stop Trade after high News (min) input bool show_high_line = true; //Show verticle Line when high news comes input bool Medium_Impact_News = true; //Medium Impact News input int Medium_Start_Time = 60; //Stop Trade before medium News (min) input int Medium_Stop_Time = 15; //Stop Trade after medium News (min) input bool show_medium_line = true; //Show verticle Line when medium news comes input bool Low_Impact_News = true; //Low Impact News input int Low_Start_Time = 60; //Stop Trade before low News (min) input int Low_Stop_Time = 15; //Stop Trade after low News (min) input bool show_low_line = true; //Show verticle Line when low news comes input selectLine Select_News_Line = 0; //News Line input bool mobileAlert = true; //Mobile Alert int GMT_Broker_Time = +2; //GMT_Broker_Time Time of your Broker // Global Variables double above_level = 0, below_level = 0; static double tickCurrentBid = 0, tickCurrentAsk = 0; double tickPreviousBid = 0, tickPreviousAsk = 0; datetime startTradingTime = 0, endTradingTime = 0; string sep = ":"; // A separator as a character ushort u_sep; // The code of the separator character string result1[]; datetime ea_start_time = 0; bool tradeNow = true; bool printingDisplay = true; string Lname="newsLabel3"; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- // news int timeDifference = (int)TimeCurrent() - (int)TimeGMT(); Print("Time Difference is: ", timeDifference); if(timeDifference > 0) { GMT_Broker_Time = +timeDifference/3600; } else if(timeDifference < 0) { GMT_Broker_Time = timeDifference/3600; } else if(timeDifference == 0) { GMT_Broker_Time = timeDifference; } Print("Gmt Time: ", TimeGMT(), " Broker Gmt Time: ", GMT_Broker_Time); if(!MQLInfoInteger(MQL_TESTER)) { initiateNews(); } // Fill Values above and below levels trade.SetExpertMagicNumber(magic_no); trade.SetDeviationInPoints(10); trade.SetTypeFilling(ORDER_FILLING_IOC); trade.LogLevel(LOG_LEVEL_ALL); trade.SetAsyncMode(false); ea_start_time = TimeCurrent(); double currentPrice = iClose(Symbol(), PERIOD_CURRENT, 0); getNearestLevels(currentPrice, levels_distence, below_level, above_level); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Main Activity function | //+------------------------------------------------------------------+ void mainActivity() { //--- double Ask = SymbolInfoDouble(Symbol(),SYMBOL_ASK); double Bid = SymbolInfoDouble(Symbol(),SYMBOL_BID); tickPreviousBid = tickCurrentBid; tickCurrentBid = Bid; tickPreviousAsk = tickCurrentAsk; tickCurrentAsk = Ask; timeConversion(); // Comment(" Below Value is: ", below_level, " Above Value: ", above_level, " Previous Tick: ", tickPreviousAsk, " Tick Current Ask: ", tickCurrentAsk); double lastLot = 0; if(!countinueCycleAfterProfit) if(selectLatestTicket(lastLot) > 0) { tradeNow = false; } // Comment(" Trades Count: ", orderCount(), " Below Value is: ", below_level, " Above Value: ", above_level); if(orderCount() == 0) { double latestClosePrice = getClosePriceByTicket(); if(latestClosePrice > 0) { getNearestLevels(latestClosePrice, levels_distence, below_level, above_level); if(printingDisplay) { Print(" ---------------------------------- Resetting Level no trade open. Setting new Levels using last ticket close price: ", latestClosePrice, " ------------------------------------------------ "); Print(" Current Price: ", latestClosePrice, " Below Value is: ", below_level, " Above Value: ", above_level); printingDisplay = false; } } } else { printingDisplay = true; } if(tradeNow) if((EnableTimeFilter && TimeCurrent() >= startTradingTime && TimeCurrent() < endTradingTime) || !EnableTimeFilter) { if(above_level == 0 && below_level == 0) { double currentPrice = iClose(Symbol(), PERIOD_CURRENT, 0); getNearestLevels(currentPrice, levels_distence, below_level, above_level); Print(" Price Levels Updated on New Session Start. "); } if(selectSide == buyTrades) // Buy trade case { if(((tickPreviousAsk < above_level) && (tickCurrentAsk >= above_level)) || ((tickPreviousAsk > below_level) && (tickCurrentAsk <= below_level))) { placeBuyTrade(); Print(" ----------------------------- Buy Trade Executed and Levels Updated -----------------------------------------------------"); double currentPrice = 0; if((tickPreviousAsk < above_level) && (tickCurrentAsk >= above_level)) { currentPrice = above_level; } else if(((tickPreviousAsk > below_level) && (tickCurrentAsk <= below_level))) { currentPrice = below_level; } getNearestLevels(currentPrice, levels_distence, below_level, above_level); Print(" Current Price: ", currentPrice, " Below Value is: ", below_level, " Above Value: ", above_level); } } if(selectSide == sellTrades) { if(((tickPreviousBid < above_level) && (tickCurrentBid >= above_level)) || ((tickPreviousBid > below_level) && (tickCurrentBid <= below_level))) { placeSellTrade(); Print(" ----------------------------- Sell Trade Executed and Levels Updated -----------------------------------------------------"); double currentPrice = 0; if((tickPreviousBid < above_level) && (tickCurrentBid >= above_level)) { currentPrice = above_level; } else if(((tickPreviousBid > below_level) && (tickCurrentBid <= below_level))) { currentPrice = below_level; } getNearestLevels(currentPrice, levels_distence, below_level, above_level); Print(" Current Price: ", currentPrice, " Below Value: ", below_level, " Above Value: ", above_level); } } } else { below_level = 0; above_level = 0; } } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { static int status=-1,preStatus=-1; status=returnNewsStatus(High_Impact_News ,High_Start_Time ,High_Stop_Time ,show_high_line ,Medium_Impact_News ,Medium_Start_Time ,Medium_Stop_Time ,show_medium_line ,Low_Impact_News ,Low_Start_Time ,Low_Stop_Time ,show_low_line ,Symbol() ,MQLInfoString(MQL_PROGRAM_NAME) ,GMT_Broker_Time ,Select_News_Line ,"" ); if(status==0) { mainActivity(); } if(status==1 || status==2 || status==3) { if(newsClose==0) { if(orderCount_1(POSITION_TYPE_BUY,magic_no)>0) closeTrades(POSITION_TYPE_BUY,magic_no); if(orderCount_1(POSITION_TYPE_SELL,magic_no)>0) closeTrades(POSITION_TYPE_SELL,magic_no); } else if(newsClose==1) { mainActivity(); } } if(status!=preStatus) { if(status==0 && preStatus!=-1) { { ObjectSetString(0,Lname,OBJPROP_TEXT,""); } Alert("Trading is start"); if(mobileAlert) SendNotification("Trading is start"); preStatus=status; } else if(status==1) { ObjectSetInteger(0,Lname,OBJPROP_COLOR,clrRed); ObjectSetString(0,Lname,OBJPROP_TEXT,"High Impact News"); Alert("Trading Stop due to high impact news"); if(mobileAlert) SendNotification("Trading Stop due to high impact news"); preStatus=status; } else if(status==2) { ObjectSetInteger(0,Lname,OBJPROP_COLOR,clrBlue); ObjectSetString(0,Lname,OBJPROP_TEXT,"Medium Impact News"); Alert("Trading Stop due to medium impact news"); if(mobileAlert) SendNotification("Trading Stop due to medium impact news"); preStatus=status; } else if(status==3) { ObjectSetInteger(0,Lname,OBJPROP_COLOR,clrGreen); ObjectSetString(0,Lname,OBJPROP_TEXT,"Low Impact News"); Alert("Trading Stop due to low impact news"); if(mobileAlert) SendNotification("Trading Stop due to low impact news"); preStatus=status; } } else mainActivity(); } //+------------------------------------------------------------------+ //| Calculate Base Level Function | //+------------------------------------------------------------------+ double calculateBaseLevel(double price, double step) { return step * MathFloor(price / step); } //+------------------------------------------------------------------+ //| Get Nearest Levels Function | //+------------------------------------------------------------------+ void getNearestLevels(double currentPrice, double step, double &LowerLevel, double &UpperLevel) { double epsilon = 0.000001; // Compute the anchor as the nearest multiple of step. double anchor = MathRound(currentPrice / step) * step; double diff = fabs(currentPrice - anchor); // If currentPrice exactly equals the anchor, use symmetric levels. if(diff < epsilon) { LowerLevel = anchor - step; UpperLevel = anchor + step; return; } // Special handling for step == 10: use non–symmetric levels. if(step == 10) { if(currentPrice > anchor) { LowerLevel = anchor; UpperLevel = anchor + step; } else // currentPrice < anchor { LowerLevel = anchor - step; UpperLevel = anchor; } return; } // For all other steps, use the ratio threshold logic. double ratio = diff / step; double threshold = 0.45; // Adjusted threshold if(currentPrice > anchor) { if(ratio > threshold) { LowerLevel = anchor - step; UpperLevel = anchor + step; } else { LowerLevel = anchor; UpperLevel = anchor + step; } } else // currentPrice < anchor { if(ratio > threshold) { LowerLevel = anchor - step; UpperLevel = anchor + step; } else { LowerLevel = anchor - step; UpperLevel = anchor; } } } //+------------------------------------------------------------------+ //| Place Buy Trade Function | //+------------------------------------------------------------------+ 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(takeprofit != 0) { buyTp = Ask + (takeprofit * 10 * Point()); } double lot = 0; double lastLot = 0; if(selectLatestTicket(lastLot) < 0) { lot = lastLot * lot_multiplier; } else { lot = lot_size; } if(trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,NormalizeDouble(lot, 2),Ask,buySL,buyTp,"Buy Trade Placed")) { Print("Buy Trade Placed: ", trade.ResultOrder()); } else { Print("Error in placing Buy: "+Symbol()+" ",GetLastError()); } } //+------------------------------------------------------------------+ //| Place Sell Trade Function | //+------------------------------------------------------------------+ 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()); } double lot = 0; double lastLot = 0; if(selectLatestTicket(lastLot) < 0) { lot = lastLot * lot_multiplier; } else { lot = lot_size; } if(trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,NormalizeDouble(lot, 2),Bid,sellSL,sellTp,"Sell Trade Placed")) { Print("Sell Trade PLaced: ", trade.ResultOrder()); } else { Print("Error in placing Sell: "+Symbol()+" ",GetLastError()); } } //+------------------------------------------------------------------+ //| Time Conversion Function | //+------------------------------------------------------------------+ 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); } //+------------------------------------------------------------------+ //| Select Latest Ticket Function | //+------------------------------------------------------------------+ double selectLatestTicket(double &lastOrderLot) { int count = 0; ulong ticket_deal_Out=0, ticket_deal_In = 0; datetime latestCloseTime = 0; double orderProfit = 0; ulong latestTicket = 0; if(HistorySelect(ea_start_time, TimeCurrent())) { int total = HistoryDealsTotal(); for(int i = total-1; i >= 0 ; i--) { ticket_deal_Out = HistoryDealGetTicket(i); if((HistoryDealGetInteger(ticket_deal_Out,DEAL_MAGIC) == magic_no) && HistoryDealGetInteger(ticket_deal_Out,DEAL_ENTRY) == DEAL_ENTRY_OUT && HistoryDealGetString(ticket_deal_Out,DEAL_SYMBOL) == Symbol()) // here is the problem solved after break { datetime orderCloseTime = (datetime) HistoryDealGetInteger(ticket_deal_Out, DEAL_TIME); if(orderCloseTime > latestCloseTime) { latestCloseTime = (datetime) HistoryDealGetInteger(ticket_deal_Out, DEAL_TIME); orderProfit = HistoryDealGetDouble(ticket_deal_Out, DEAL_PROFIT); latestTicket = ticket_deal_Out; lastOrderLot = HistoryDealGetDouble(ticket_deal_Out, DEAL_VOLUME); // Print(" Last order Lot: ", lastOrderLot); } } } } // Print(" Latest Selected Ticket: ", latestTicket, " Order Close Time: ", latestCloseTime, " Ticket Profit: ", orderProfit); return orderProfit; } //+------------------------------------------------------------------+ //| Get Close Price By Ticket Function | //+------------------------------------------------------------------+ double getClosePriceByTicket() { ulong ticket_deal_Out=0, ticket_deal_In = 0; datetime latestCloseTime = 0; double orderClosePrice = 0; ulong latestTicket = 0; if(HistorySelect(ea_start_time, TimeCurrent())) { int total = HistoryDealsTotal(); for(int i = total-1; i >= 0 ; i--) { ticket_deal_Out = HistoryDealGetTicket(i); if((HistoryDealGetInteger(ticket_deal_Out,DEAL_MAGIC) == magic_no) && HistoryDealGetInteger(ticket_deal_Out,DEAL_ENTRY) == DEAL_ENTRY_OUT && HistoryDealGetString(ticket_deal_Out,DEAL_SYMBOL) == Symbol()) // here is the problem solved after break { datetime orderCloseTime = (datetime) HistoryDealGetInteger(ticket_deal_Out, DEAL_TIME); if(orderCloseTime > latestCloseTime) { orderClosePrice = HistoryDealGetDouble(ticket_deal_Out, DEAL_PRICE); latestCloseTime = orderCloseTime; } } } } return orderClosePrice; } //+------------------------------------------------------------------+ //| Order Count Function | //+------------------------------------------------------------------+ int orderCount() { int count = 0; for(int i= PositionsTotal()-1; i>=0; i--) { ulong ticket = PositionGetTicket(i); if(PositionSelectByTicket(ticket)) { if(PositionGetInteger(POSITION_MAGIC) == magic_no && PositionGetString(POSITION_SYMBOL) == Symbol()) { //if(PositionGetInteger(POSITION_TYPE) == type) { count++; } } } } return count; } //+------------------------------------------------------------------+ //| Order Count 1 with Parameters Function | //+------------------------------------------------------------------+ int orderCount_1(int type,int magic) { int count1=0; for(int i= PositionsTotal()-1; i>=0; i--) { ulong ticket = PositionGetTicket(i); if(PositionSelectByTicket(ticket)) { if(PositionGetInteger(POSITION_MAGIC) == magic && PositionGetString(POSITION_SYMBOL) == Symbol()) { if(PositionGetInteger(POSITION_TYPE) == type) { count1++; } } } } return count1; } //+------------------------------------------------------------------+ //| Close Trades Function | //+------------------------------------------------------------------+ void closeTrades(int type,int magicno) { Print("Total order: ",OrdersTotal()); for(int i= PositionsTotal()-1; i>=0; i--) { ulong ticket = PositionGetTicket(i); if(PositionSelectByTicket(ticket)) { if(PositionGetInteger(POSITION_TYPE) == type) { if(PositionGetInteger(POSITION_MAGIC) == magicno && PositionGetString(POSITION_SYMBOL) == Symbol()) { if(!trade.PositionClose(PositionGetInteger(POSITION_TICKET))) {Print("Problem in closing order order ",PositionGetInteger(POSITION_TICKET)); } else { Print("Order Closed by closeTrades() new filter",PositionGetInteger(POSITION_TICKET)); } } } } } } //+------------------------------------------------------------------+