//+------------------------------------------------------------------+ //| Time Range Break and Retest EA v1.0.mq5 | //| Copyright 2024, Bosco A Vega | //| quantumpips85@gmail.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Bosco A Vega" #property link "quantumpips85@gmail.com" #property version "1.00" #include <Trade/Trade.mqh> #include <Trade/PositionInfo.mqh> #include <Trade/SymbolInfo.mqh> sinput group "GENERAL EA INPUTS" input int EA_Magic = 12345; //EA magic number input int Slippage = 10; input bool Buy = true; //Allow Buying input bool Sell = true; //Allow Selling input string InpTradeComment = "Trade has been placed"; sinput group "RANGE START INPUTS" input int InpRangeStartHours = 0; // Range Start Hours (0-23) input int InpRangeStartMinutes = 0; //Range Start Minutes (0-59) sinput group "RANGE END INPUTS" input int InpRangeEndHours = 2; // Range End Hours (0-23) input int InpRangeEndMinutes = 0; //Range End Minutes (0-59) sinput group "RANGE CLOSE INPUTS" input int InpCloseHours = 23; // Close Hours (0-23) input int InpCloseMinutes = 0; //Close Minutes (0-59) sinput group "MONEY MANAGEMENT INPUTS" input bool useMM = false; //Use Money Management input double InpRisk = 1.0; //Risk in % of balance input double InpOrderSize = 0.05; //Lotsize used if useMM = false sinput group "SL AND TP INPUTS" input int Stoploss =25; //Stoploss in pips input int TakeProfit = 25; //Takeprofit in pips sinput group "BREAKEVEN INPUTS" input bool UseBreakEven = true; //Use breakeven input int WhenToBreak = 20; //When to Breakeven in pips input int BreakBy = 5; //Break even in pips sinput group "TRAILING STOP INPUTS" input bool UseTrailing = true; //Use trailing stop input int WhenToTrail = 50; //When to Start Trailing in pips input int TrailBy = 20; //TrailingStop in pips //--- Global Values for the Range bool InsideRange; // Gets set when the time is between start and end time bool InsideClose; // Gets set when time is between end and close time bool BreakoutHigh; bool BreakinHigh; bool BreakoutLow; bool BreakinLow; int RangeStartMinutes; int RangeEndMinutes; int CloseMinutes; double STP,TKP; ulong LastBars = 0; double Ask,Bid,Lots; //---- double m_whentobreak; double m_breakby; double m_whentotrail; double m_trailby; //---Creating some Objects CTrade *Trade; CPositionInfo PositionInfo; CSymbolInfo m_symbol; COrderInfo Order; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //---Initializing the Trade Objects Trade = new CTrade; Trade.SetDeviationInPoints(Slippage); Trade.SetExpertMagicNumber(EA_Magic); m_symbol.Name(Symbol()); //--- Checking user inputs if (!CheckInput()) return (INIT_PARAMETERS_INCORRECT); InsideRange = IsInsideTime (TimeCurrent() , RangeStartMinutes, RangeEndMinutes); InsideClose = IsInsideTime (TimeCurrent() , RangeEndMinutes, CloseMinutes); //---Standardise the currency digits for different pairs STP = Stoploss*_Point; TKP = TakeProfit*_Point; m_whentobreak = WhenToBreak*_Point; m_breakby= BreakBy*_Point; m_trailby = TrailBy*_Point; m_whentotrail = WhenToTrail*_Point; //if(_Digits==5||_Digits==3) { STP=STP*10; TKP=TKP*10; m_whentobreak=m_whentobreak*10; m_trailby=m_trailby*10; m_whentotrail=m_whentotrail*10; } //---Checking the adequecy of the number of bars in history if(Bars(_Symbol,_Period)<500) { Alert("We have less than enough bars, EA will now exit"); return(0); } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //---Checking if we are able to trade if((!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))||(!TerminalInfoInteger(TERMINAL_CONNECTED))||(SymbolInfoInteger(_Symbol,SYMBOL_TRADE_MODE)!=SYMBOL_TRADE_MODE_FULL)) { return; } //---Defining MQL structures to be used for trading MqlTick latest_price; //To be used to get the latest information about prices //---Checking if we have the latest price quote if(!SymbolInfoTick(_Symbol,latest_price)) { Alert("Error getting the latest price quote - Error: ",GetLastError(),"!!"); return; } //--- Checking for the presence of an open position bool Tradeopened = false; if(PositionsTotal()>0) { Tradeopened = true; if(UseBreakEven) { BreakEven(); } if(UseTrailing) { TrailingStopLoss(); } } //--- Static values to track the range static double rangeHigh = 0; static double rangeLow = 0; //--- Conditions for the range bool nowOutsideClose = !IsInsideTime(TimeCurrent(), RangeEndMinutes, CloseMinutes); if (InsideClose && nowOutsideClose ) { CloseAll(); InsideClose = false; rangeHigh = 0; rangeLow = 0; BreakinHigh = false; BreakinLow = false; BreakoutHigh = false; BreakoutLow = false; } InsideClose = !nowOutsideClose; if(InsideClose && IsNewBar(true)) { double close = iClose(Symbol(),Period(),1); long spread = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD) + 50; double point = SymbolInfoDouble(Symbol(), SYMBOL_POINT); double gap = spread * point; //--- Getting the Lotsize if(useMM) { Lots = calclots(InpRisk,STP); } else { Lots = InpOrderSize; } //--- Buy Condition if(!BreakinHigh) { BreakoutHigh = BreakoutHigh || (close > rangeHigh); if (BreakoutHigh && close<rangeHigh) { BreakinHigh = true; OpenTrade(ORDER_TYPE_BUY_STOP, rangeHigh+gap,rangeHigh+gap-STP,rangeHigh+gap+TKP); } } //--- Sell Condition if(!BreakinLow) { BreakoutLow = BreakoutLow || (close < rangeLow); if (BreakoutLow && close>rangeLow) { BreakinLow = true; OpenTrade(ORDER_TYPE_SELL_STOP, rangeLow-gap, rangeLow-gap+STP, rangeLow-gap-TKP); } } } //--- Exited the range and setting our price bool nowOutsideRange = !IsInsideTime(TimeCurrent(), RangeStartMinutes, RangeEndMinutes); if (InsideRange && nowOutsideRange) { ShowRange(rangeHigh,rangeLow); InsideRange = false; InsideClose = true; BreakinHigh = false; BreakinLow = false; BreakoutHigh = false; BreakoutLow = false; } InsideRange = !nowOutsideRange; if (InsideRange) { double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK); double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID); if (rangeHigh==0 || ask > rangeHigh) rangeHigh = ask; if (rangeLow==0 || bid < rangeLow) rangeLow = bid; } //-----End of on tick function } //----------------------> //---Start of global functions //+------------------------------------------------------------------+ //|Checking User Inputs | //+------------------------------------------------------------------+ bool CheckInput() { if( (InpRangeStartHours<0 || InpRangeStartHours>23) ||(InpRangeStartMinutes<0 || InpRangeStartMinutes>59) ||(InpRangeEndHours<0 || InpRangeEndHours>23) ||(InpRangeEndMinutes<0 || InpRangeEndMinutes>59) ||(InpCloseHours<0 || InpCloseHours>23) ||(InpCloseMinutes<0 || InpCloseMinutes>59) ) return false; RangeStartMinutes = InpRangeStartHours*60 + InpRangeStartMinutes; RangeEndMinutes = InpRangeEndHours*60 + InpRangeEndMinutes; CloseMinutes = InpCloseHours*60 + InpCloseMinutes; if(RangeStartMinutes==RangeEndMinutes) return false; if(RangeEndMinutes==CloseMinutes) return false; return true; } //+------------------------------------------------------------------+ //|Is Inside Time Function | //+------------------------------------------------------------------+ bool IsInsideTime(datetime now, int startMinutes, int endMinutes) { MqlDateTime time; TimeToStruct(now, time); int nowMinutes = time.hour*60+time.min; // Currently ignoring seconds after the minute return ( (startMinutes<=nowMinutes && nowMinutes<endMinutes ) || ( ( startMinutes>endMinutes) && (nowMinutes<endMinutes || nowMinutes>=startMinutes) ) ); } //+------------------------------------------------------------------+ //|Calculate lots function | //+------------------------------------------------------------------+ double calclots (double riskPercent, double sl) { double ticksize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE); double tickvalue = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE); double lotstep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP); if(ticksize == 0 || tickvalue == 0 || lotstep == 0) { Print(__FUNCTION__," > Lotsize cannot be calculated..."); return 0; } double riskMoney = AccountInfoDouble(ACCOUNT_BALANCE) * riskPercent / 100; double moneyLotStep = (sl / ticksize) * tickvalue * lotstep; if(moneyLotStep==0) { Print(__FUNCTION__," > Lotsize cannot be calculated..."); return 0; } double lots = MathFloor (riskMoney / moneyLotStep) * lotstep; return lots; } //+------------------------------------------------------------------+ //|Open Order Function | //+------------------------------------------------------------------+ void OpenTrade( ENUM_ORDER_TYPE type, double price, double sl , double tp ) { price = NormalizeDouble(price, Digits() ); sl = NormalizeDouble(sl, Digits() ); tp = NormalizeDouble(tp,Digits() ); if(!Trade.OrderOpen(Symbol(), type, Lots, 0, price, sl, tp, ORDER_TIME_GTC, 0, InpTradeComment) ) { Print("Open failed for %s, %s, price=%f, tp=%f", Symbol(), EnumToString ( type ),price,sl,tp ); } } //+------------------------------------------------------------------+ //|Close All Function | //+------------------------------------------------------------------+ void CloseAll () { for(int i=PositionsTotal()-1; i>=0; i--) { ulong ticket = PositionGetTicket(i); if (!PositionSelectByTicket(ticket)) continue; if (PositionInfo.Symbol() !=Symbol() || PositionInfo.Magic()!=EA_Magic) continue; if (!Trade.PositionClose(ticket)) { PrintFormat("Failed to close position %i", ticket); } } for(int i=OrdersTotal()-1; i>=0; i--) { ulong ticket = OrderGetTicket(i); if (!OrderSelect(ticket)) continue; if (Order.Symbol() !=Symbol() || Order.Magic()!=EA_Magic) continue; if (!Trade.OrderDelete(ticket)) { PrintFormat("Failed to delete order %i", ticket); } } } //+------------------------------------------------------------------+ //|Is New Bar Function | //+------------------------------------------------------------------+ bool IsNewBar( bool first_call = false ) { static bool result = false; if ( !first_call ) return ( result ); static datetime previous_time = 0; datetime current_time = iTime( Symbol(), Period(), 0 ); result = false; if ( previous_time != current_time ) { previous_time = current_time; result = true; } return ( result ); } //+------------------------------------------------------------------+ //|Breaking Even Function | //+------------------------------------------------------------------+ void BreakEven() { //---Loop through all open positions for(int i = PositionsTotal()-1; i>=0; i--) { if(!PositionInfo.SelectByIndex(i)) { continue; } if(PositionInfo.Magic() != EA_Magic) { continue; } if(PositionInfo.Symbol() != m_symbol.Name()) { continue; } //---Checking if SL is in profit double current_sl = PositionInfo.StopLoss(); double openingPrice = PositionInfo.PriceOpen(); if(PositionInfo.PositionType()==POSITION_TYPE_BUY) { if(current_sl>=openingPrice) { continue; } } if(PositionInfo.PositionType()==POSITION_TYPE_SELL) { if(current_sl!=0 && current_sl<=openingPrice) { continue; } } //---Checking if price has arrived at BE point double breakevenprice = PositionInfo.PositionType()==POSITION_TYPE_BUY ? openingPrice+m_whentobreak : openingPrice-m_whentobreak; double current_price = PositionInfo.PriceCurrent(); if(PositionInfo.PositionType()==POSITION_TYPE_BUY) { if(current_price<breakevenprice) { continue; } } else { if(current_price>breakevenprice) { continue; } } //---Breaking even double new_sl=PositionInfo.PositionType() == POSITION_TYPE_BUY ? openingPrice + m_breakby : openingPrice - m_breakby; //---Modify position if(!Trade.PositionModify(PositionInfo.Ticket(),new_sl,PositionInfo.TakeProfit())) { Alert("Error Modifying position [%d]",GetLastError()); } } } //+------------------------------------------------------------------+ //|Trailing Stop Function | //+------------------------------------------------------------------+ void TrailingStopLoss() { //---Loop through all open positions for(int i = PositionsTotal()-1; i>=0; i--) { if(!PositionInfo.SelectByIndex(i)) { continue; } if(PositionInfo.Magic() != EA_Magic) { continue; } if(PositionInfo.Symbol() != m_symbol.Name()) { continue; } //---Getting the Stoploss and OpenPrice double current_sl = PositionInfo.StopLoss(); double opening_price = PositionInfo.PriceOpen(); double current_price = PositionInfo.PriceCurrent(); //---Checking if Price Has reached the trailmark double trailprice = PositionInfo.PositionType()==POSITION_TYPE_BUY ? opening_price + m_whentotrail : opening_price - m_whentotrail; if(PositionInfo.PositionType()==POSITION_TYPE_BUY) { if(current_price < trailprice) { continue; } } else { if(current_price > trailprice) { continue; } } //---Getting the new sl and checking if position sl has moved double new_sl = PositionInfo.PositionType()==POSITION_TYPE_BUY ? current_price - m_trailby : current_price + m_trailby; //---Checking if new SL is valid if(PositionInfo.PositionType()==POSITION_TYPE_BUY && new_sl < current_sl) { continue; } if(PositionInfo.PositionType()==POSITION_TYPE_SELL && new_sl > current_sl) { continue; } ulong m_ticket = PositionInfo.Ticket(); double TP = PositionInfo.TakeProfit(); if(!Trade.PositionModify(m_ticket,new_sl,TP)) { Alert("Error Modifying position [%d]",GetLastError()); } } } //+------------------------------------------------------------------+ //|Function for creating range objects | //+------------------------------------------------------------------+ void ShowRange( double hi, double lo ) { ShowRangeLine( "hi", OBJ_HLINE, hi ); ShowRangeLine( "lo", OBJ_HLINE, lo ); ShowRangeLine( "now", OBJ_VLINE, lo ); } void ShowRangeLine( string name, ENUM_OBJECT type, double value ) { ObjectDelete( 0, name ); ObjectCreate( 0, name, type, 0, iTime( Symbol(), Period(), 1 ), value ); ObjectSetInteger( 0, name, OBJPROP_COLOR, clrCyan ); ObjectSetInteger( 0, name, OBJPROP_STYLE, STYLE_DASHDOTDOT); } //+------------------------------------------------------------------+
To calculate the lot size based on the risk percentage, you need to use a formula that takes into account the balance, the stop loss, the symbol price, and the symbol properties. The formula is:
AccountBalance * InpRisk / 100 = LotSize * (|OrderOpenPrice - OrderStopLoss| * SymbolInfoDouble(Symbol(), SYMBOL_POINT) * SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE) + SymbolInfoDouble(Symbol(), SYMBOL_TRADE_COMMISSION) * SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE))
This formula will give you the lot size that corresponds to the risk percentage that you want to use. You can then use this lot size in your trade request structure. For example, if you want to risk 1% of your balance, you can use:
double LotSize = AccountBalance * 0.01 / ((|OrderOpenPrice - OrderStopLoss| * SymbolInfoDouble(Symbol(), SYMBOL_POINT) * SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE) + SymbolInfoDouble(Symbol(), SYMBOL_TRADE_COMMISSION) * SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE)));
You can also use a function to calculate the lot size based on the risk percentage, and then call it in your code. For example, you can use:
double CalculateLotSize(double risk) { double LotSize = AccountBalance * risk / ((|OrderOpenPrice - OrderStopLoss| * SymbolInfoDouble(Symbol(), SYMBOL_POINT) * SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE) + SymbolInfoDouble(Symbol(), SYMBOL_TRADE_COMMISSION) * SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE))); return LotSize; }
And then call it in your code like this:
double LotSize = CalculateLotSize(0.01); // Risk 1% of balance
i hope this helps
double LotSize = CalculateLotSize(0.01); // Risk 1% of balance
Hello my friend, i appreciate your kind help. I tried to figure it out but i am getting errors. Im not sure how i can exactly use the code you provided in my code. I attempted. Any other suggestion would be appreciated.
To calculate the lot size based on the risk percentage, you need to use a formula that takes into account the balance, the stop loss, the symbol price, and the symbol properties. The formula is:
AccountBalance * InpRisk / 100 = LotSize * (|OrderOpenPrice - OrderStopLoss| * SymbolInfoDouble(Symbol(), SYMBOL_POINT) * SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE) + SymbolInfoDouble(Symbol(), SYMBOL_TRADE_COMMISSION) * SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE))
This formula will give you the lot size that corresponds to the risk percentage that you want to use. You can then use this lot size in your trade request structure. For example, if you want to risk 1% of your balance, you can use:
You can also use a function to calculate the lot size based on the risk percentage, and then call it in your code. For example, you can use:
double CalculateLotSize(double risk) { double LotSize = AccountBalance * risk / ((|OrderOpenPrice - OrderStopLoss| * SymbolInfoDouble(Symbol(), SYMBOL_POINT) * SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE) + SymbolInfoDouble(Symbol(), SYMBOL_TRADE_COMMISSION) * SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE))); return LotSize; }
And then call it in your code like this:
i hope this helps
Stop using AI to sort out other peoples problems.....What you describe here is not the problem he is having. ChatGPT will not find solutions to problems, we told you that already

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
EA is working for fixed lot size but not for risk percentage. I get diffrent loss values for most currency pairs. On USD pairs risk works as close to accurate as possible. EX: Risk 1 % of 3500.00 USD and i lose about 36 dollars. GBPJPY i lose 50 USD, EURNZD i lose 25 USD.
I am fairly new to programming in MQL5 and i have been working on creating this EA with very minimal help for the last few months. I researched and worked tirelessly trying to figure this lot thing out. I would greatly appreciate it if anyone can point me in the right direction.
Cheers!