//+------------------------------------------------------------------+ //| ORDER BLOCKS EA.mq5 | //| Copyright 2024, ALLAN MUNENE MUTIIRIA. #@Forex Algo-Trader. | //| https://youtube.com/@ForexAlgo-Trader? | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, ALLAN MUNENE MUTIIRIA. #@Forex Algo-Trader" #property link "https://youtube.com/@ForexAlgo-Trader?" #property description "======= IMPORTANT =======\n" #property description "1. This is a FREE EA." #property description "2. To get the source code of the EA, follow the Copyright link." #property description "3. Incase of anything, contact developer via the link provided." "Hope you will enjoy the EA Logic.\n" #property description "*** HAPPY TRADING! ***" #property version "2.00" sinput group "✔🔰 EA GENERAL SETTINGS 💱💲" input double inpLot = 0.01; // Lotsize input ulong magic_no = 1234567; // Magic Number input int sl_tp_pts = 300; // Stop Loss/Take Profit Points input double r2r_ratio = 7; // Risk : Reward Ratio sinput string ob_up_name = "Bullish Order Block"; // OB Up Name sinput string ob_down_name = "Bearish Order Block"; // OB Down Name sinput short ob_up_unicode = 0x2BED; // OB Up Unicode sinput short ob_down_unicode = 0x2BEF; // OB Down Unicode sinput string range_name = "Range"; // Range name sinput string src_code1 = "https://t.me/forexalgo_trading"; // Source Code HERE 👉 sinput string src_code2 = "https://youtube.com/@ForexAlgo-Trader?"; // Join Community HERE 👉 input int range_candles = 7; // Range Candles input double max_deviation = 50; // Maximum Deviation Points input int starting_index = 1; // Starting Index input int wait_bars = 3; // Validation Wait Bars sinput color def_clr_up = clrLime; // Bullish OB Color sinput color def_clr_down = clrRed; // Bearish OB Color sinput color def_invalid = clrBlue; // Invalid OB Color sinput color def_text = clrBlack; // Text Color sinput bool prt = false; // Print Statements sinput int fontSize = 15; // Font Size #include CTrade obj_Trade; struct PriceIndex{ double price; int index; }; PriceIndex highestHigh = {0,0}; PriceIndex lowestLow = {0,0}; bool breakoutDetected = false; double impulseLow = 0.0; double impulseHigh = 0.0; int breakoutBarIndex = -1; datetime breakoutTime = 0; string totalOBs_names[]; datetime totalOBs_dates[]; bool totalOBs_is_signals[]; bool is_OB_UP = false; bool is_OB_DOWN = false; #define OB_Prefix "OB REC " #define CLR_UP def_clr_up #define CLR_DOWN def_clr_down //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(){ //--- obj_Trade.SetExpertMagicNumber(magic_no); if (prt){ Print("Success. "+__FILE__+" Initialized..."); } //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason){ //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick(){ //--- static bool isNewBar = false; int currBars = iBars(_Symbol,_Period); static int prevBars = currBars; if (prevBars == currBars){isNewBar = false;} else if (prevBars != currBars){ isNewBar = true; prevBars = currBars; } if (!isNewBar) return; int rangeCandles = range_candles; double maxDeviation = max_deviation; int startingIndex = starting_index; int waitBars = wait_bars; if (!breakoutDetected){ if (highestHigh.price == 0 && lowestLow.price == 0){ if (IsConsolidationEqualHighsAndLows(rangeCandles,maxDeviation,startingIndex)){ GetHighestHigh(rangeCandles,startingIndex,highestHigh); GetLowestLow(rangeCandles,startingIndex,lowestLow); if (prt){ Print("Consolidation range established: Highest High = ",highestHigh.price, " at index ,",highestHigh.index, " and Lowest Low = ",lowestLow.price, " at index ",lowestLow.index ); } } } else{ ExtendRangeIfWithinLimits(); } } if (highestHigh.price > 0 && lowestLow.price > 0){ breakoutDetected = CheckRangeBreak(highestHigh,lowestLow); } if (breakoutDetected){ if (prt){ Print("Breakout detected. Resetting for the next range."); } breakoutBarIndex = 1; breakoutTime = TimeCurrent(); impulseHigh = highestHigh.price; impulseLow = lowestLow.price; breakoutDetected = false; highestHigh.price = 0; highestHigh.index = 0; lowestLow.price = 0; lowestLow.index = 0; } if (breakoutBarIndex >= 0 && TimeCurrent() > breakoutTime+waitBars*PeriodSeconds()){ DetectImpulsiveMovement(impulseHigh,impulseLow,waitBars,1); bool is_OB_Valid = is_OB_UP || is_OB_DOWN; datetime time1 = iTime(_Symbol,_Period,rangeCandles+waitBars+1); double price1 = impulseHigh; int visisbleBars = (int)ChartGetInteger(0,CHART_VISIBLE_BARS); datetime time2 = is_OB_Valid ? time1+(visisbleBars/1)*PeriodSeconds() : time(waitBars+1); double price2 = impulseLow; string obName = OB_Prefix+"("+TimeToString(time1)+")"; color obClr = clrBlack; if (is_OB_Valid){obClr = is_OB_UP ? CLR_UP : CLR_DOWN;} else if (!is_OB_Valid){obClr = def_invalid;} string obText = ""; if (is_OB_Valid){obText = is_OB_UP ? ob_up_name+ShortToString(ob_up_unicode) : ob_down_name+ShortToString(ob_down_unicode);} else if (!is_OB_Valid){obText = range_name;} if (!is_OB_Valid){ if (ObjectFind(0,obName) < 0){ CreateRec(obName,time1,price1,time2,price2,obClr,obText); } } else if (is_OB_Valid){ if (ObjectFind(0,obName) < 0){ CreateRec(obName,time1,price1,time2,price2,obClr,obText); if (prt){Print("Old Arraysize = ",ArraySize(totalOBs_names));} ArrayResize(totalOBs_names,ArraySize(totalOBs_names)+1); if (prt){Print("New Arraysize = ",ArraySize(totalOBs_names));} totalOBs_names[ArraySize(totalOBs_names)-1] = obName; if (prt){ArrayPrint(totalOBs_names);} if (prt){Print("Old Arraysize = ",ArraySize(totalOBs_dates));} ArrayResize(totalOBs_dates,ArraySize(totalOBs_dates)+1); if (prt){Print("New Arraysize = ",ArraySize(totalOBs_dates));} totalOBs_dates[ArraySize(totalOBs_dates)-1] = time2; if (prt){ArrayPrint(totalOBs_dates);} if (prt){Print("Old Arraysize = ",ArraySize(totalOBs_is_signals));} ArrayResize(totalOBs_is_signals,ArraySize(totalOBs_is_signals)+1); if (prt){Print("New Arraysize = ",ArraySize(totalOBs_is_signals));} totalOBs_is_signals[ArraySize(totalOBs_is_signals)-1] = false; if (prt){ArrayPrint(totalOBs_is_signals);} } } breakoutBarIndex = -1; breakoutTime = 0; impulseHigh = 0; impulseLow = 0; is_OB_UP = false; is_OB_DOWN = false; } for (int j=ArraySize(totalOBs_names)-1; j>=0; j--){ string obNAME = totalOBs_names[j]; bool obExist = false; double obHigh = ObjectGetDouble(0,obNAME,OBJPROP_PRICE,0); double obLow = ObjectGetDouble(0,obNAME,OBJPROP_PRICE,1); datetime objTime1 = (datetime)ObjectGetInteger(0,obNAME,OBJPROP_TIME,0); datetime objTime2 = (datetime)ObjectGetInteger(0,obNAME,OBJPROP_TIME,1); color obColor = (color)ObjectGetInteger(0,obNAME,OBJPROP_COLOR); if (time(1) < objTime2){ obExist = true; } double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); if (obColor == CLR_UP && Ask > obHigh && close(1) > obHigh && open(1) < obHigh && !totalOBs_is_signals[j]){ if (prt){Print("BUY SIGNAL for (",obNAME,") Now @ ",Ask);} double sl = Bid-(sl_tp_pts*r2r_ratio)*_Point; double tp = Bid+sl_tp_pts*_Point; double trade_lots = Check1_ValidateVolume_Lots(inpLot); if (Check2_Margin(ORDER_TYPE_BUY,trade_lots) && Check3_VolumeLimit(trade_lots) && Check4_TradeLevels(POSITION_TYPE_BUY,sl,tp) ){ obj_Trade.Buy(trade_lots,_Symbol,Ask,sl,tp); totalOBs_is_signals[j] = true; if (prt){ArrayPrint(totalOBs_names,_Digits," [< >] ");} if (prt){ArrayPrint(totalOBs_is_signals,_Digits," [< >] ");} } } else if (obColor == CLR_DOWN && Bid < obLow && close(1) < obLow && open(1) > obLow && !totalOBs_is_signals[j]){ if (prt){Print("SELL SIGNAL for (",obNAME,") Now @ ",Bid);} double sl = Ask+(sl_tp_pts*r2r_ratio)*_Point; double tp = Ask-sl_tp_pts*_Point; double trade_lots = Check1_ValidateVolume_Lots(inpLot); if (Check2_Margin(ORDER_TYPE_SELL,trade_lots) && Check3_VolumeLimit(trade_lots) && Check4_TradeLevels(POSITION_TYPE_SELL,sl,tp) ){ obj_Trade.Sell(trade_lots,_Symbol,Bid,sl,tp); totalOBs_is_signals[j] = true; if (prt){ArrayPrint(totalOBs_names,_Digits," [< >] ");} if (prt){ArrayPrint(totalOBs_is_signals,_Digits," [< >] ");} } } if (obExist == false){ bool removeName = ArrayRemove(totalOBs_names,0,1); bool removeTime = ArrayRemove(totalOBs_dates,0,1); bool remove_isSignal = ArrayRemove(totalOBs_is_signals,0,1); if (removeName && removeTime && remove_isSignal){ if (prt){ Print("Success removing the OB DATA from the arrays. New data is as below:"); Print("Total sizes => OBs: ",ArraySize(totalOBs_names),", TIMEs: ",ArraySize(totalOBs_dates),", SIGNALs: ",ArraySize(totalOBs_is_signals)); ArrayPrint(totalOBs_names); ArrayPrint(totalOBs_dates); ArrayPrint(totalOBs_is_signals); } } } } } //+------------------------------------------------------------------+ bool IsConsolidationEqualHighsAndLows(int rangeCandles, double maxDeviation, int startingIndex){ for (int i=startingIndex; i maxDeviation*Point()){ return false; } if (MathAbs(low(i) - low(i+1)) > maxDeviation*Point()){ return false; } } return true; } void GetHighestHigh(int rangeCandles, int startingIndex, PriceIndex &highestHighRef){ highestHighRef.price = high(startingIndex); highestHighRef.index = startingIndex; for (int i=startingIndex+1; i highestHighRef.price){ highestHighRef.price = high(i); highestHighRef.index = i; } } } void GetLowestLow(int rangeCandles, int startingIndex, PriceIndex &lowestLowRef){ lowestLowRef.price = low(startingIndex); lowestLowRef.index = startingIndex; for (int i=startingIndex+1; i= lowestLow.price){ if (prt){ Print("Range extended: Including candle with high = ",currentHigh," and low = ",currentLow); } } else { if (prt){ Print("No extension posiible. The current bar is outside the range."); } } } bool CheckRangeBreak(PriceIndex &highestHighRef, PriceIndex &lowestLowRef){ double closingPrice = close(1); if (closingPrice > highestHighRef.price){ if (prt){ Print("Range break upwards detected. Closing price ",closingPrice," is above the highest high: ",highestHighRef.price); } return true; } else if (closingPrice < lowestLowRef.price){ if (prt){ Print("Range break downwards detected. Closing price ",closingPrice," is below the lowest low: ",lowestLowRef.price); } return true; } return false; } void DetectImpulsiveMovement(double breakoutHigh,double breakoutLow,int impulseBars,double impulseThreshold){ double range = breakoutHigh - breakoutLow; double impulseThresholdPrice = range *impulseThreshold; for (int i=1; i<=impulseBars; i++){ double closePrice = close(i); if (closePrice >= breakoutHigh+impulseThresholdPrice){ is_OB_UP = true; if (prt){ Print("Impulsive upward movement detected: Close Price = ",closePrice, ", Threshold = ",breakoutHigh+impulseThresholdPrice ); } return; } else if (closePrice <= breakoutLow-impulseThresholdPrice){ is_OB_DOWN = true; if (prt){ Print("Impulsive downward movement detected: Close Price = ",closePrice, ", Threshold = ",breakoutHigh-impulseThresholdPrice ); } return; } } is_OB_UP = false; is_OB_DOWN = false; if (prt){Print("No impulsive movement detected after breakout.");} } double high(int index){return iHigh(_Symbol,_Period,index);} double low(int index){return iLow(_Symbol,_Period,index);} double open(int index){return iOpen(_Symbol,_Period,index);} double close(int index){return iClose(_Symbol,_Period,index);} datetime time(int index){return iTime(_Symbol,_Period,index);} void CreateRec(string objName,datetime time1,double price1, datetime time2,double price2,color clr,string txt ){ if (ObjectFind(0,objName) < 0){ ObjectCreate(0,objName,OBJ_RECTANGLE,0,time1,price1,time2,price2); if (prt){ Print("SUCCESS CREATING OBJECT >",objName,"< WITH"," T1: ",time1,", P1: ",price1, ", T2: ",time2,", P2: ",price2); } ObjectSetInteger(0,objName,OBJPROP_TIME,0,time1); ObjectSetDouble(0,objName,OBJPROP_PRICE,0,price1); ObjectSetInteger(0,objName,OBJPROP_TIME,1,time2); ObjectSetDouble(0,objName,OBJPROP_PRICE,1,price2); ObjectSetInteger(0,objName,OBJPROP_FILL,true); ObjectSetInteger(0,objName,OBJPROP_COLOR,clr); ObjectSetInteger(0,objName,OBJPROP_BACK,false); string description_txt = txt; string textObjName = objName+description_txt; datetime midTime = time1 +(time2-time1)/2; double midPrice = (price1+price2)/2; if (ObjectFind(0,textObjName) < 0){ ObjectCreate(0,textObjName,OBJ_TEXT,0,midTime,midPrice); ObjectSetString(0,textObjName,OBJPROP_TEXT,description_txt); ObjectSetInteger(0,textObjName,OBJPROP_COLOR,def_text); ObjectSetInteger(0,textObjName,OBJPROP_FONTSIZE,fontSize); ObjectSetInteger(0,textObjName,OBJPROP_ANCHOR,ANCHOR_CENTER); if (prt){ Print("SUCCESS CREATING LABEL >",textObjName,"< WITH TEXT: ",description_txt); } } ChartRedraw(0); } } //+------------------------------------------------------------------+ //| 1. CHECK TRADING VOLUME | //+------------------------------------------------------------------+ double Check1_ValidateVolume_Lots(double lots){ double symbolVol_Min = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN); double symbolVol_Max = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX); double symbolVol_STEP = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP); double accepted_Lots; double CurrentLots = lots; accepted_Lots = MathMax(MathMin(CurrentLots,symbolVol_Max),symbolVol_Min); int lotDigits = 0; if (symbolVol_Min == 1) lotDigits = 0; if (symbolVol_Min == 0.1) lotDigits = 1; if (symbolVol_Min == 0.01) lotDigits = 2; if (symbolVol_Min == 0.001) lotDigits = 3; double normalized_lots = NormalizeDouble(accepted_Lots,lotDigits); //Print("MIN LOTS = ",symbolVol_Min,", NORMALIZED LOTS = ",normalized_lots); return (normalized_lots); } //+------------------------------------------------------------------+ //| 2. CHECK MONEY/MARGIN TO OPEN POSITION | //+------------------------------------------------------------------+ bool Check2_Margin(ENUM_ORDER_TYPE Order_Type,double lot_Vol){ double margin; double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); double openPrice = (Order_Type == ORDER_TYPE_BUY) ? Ask : Bid; bool result = OrderCalcMargin(Order_Type,_Symbol,lot_Vol,openPrice,margin); if (result == false){ ResetLastError(); Print("ERROR: Something Unexpected Happened While Calculating Margin\n", "RESULT = ",result,", ERROR = ",_LastError); return (false); } if (margin > AccountInfoDouble(ACCOUNT_MARGIN_FREE)){ Print("WARNING! NOT ENOUGH MARGIN TO OPEN THE POSITION. NEEDED = ",margin); return (false); } return (true); } //+------------------------------------------------------------------+ //| 3. CHECK VOLUME LIMIT | //+------------------------------------------------------------------+ bool Check3_VolumeLimit(double lots_Vol_Limit){ double volumeLimit = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_LIMIT); double symb_Vol_Max40 = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX); double allowed_Vol_Lim = (volumeLimit == 0) ? symb_Vol_Max40 : volumeLimit; if (getAllVolume()+lots_Vol_Limit > allowed_Vol_Lim){ Print("WARNING! VOLUME LIMIT REACHED: LIMIT = ",allowed_Vol_Lim); return (false); } return (true); } double getAllVolume(){ ulong ticket=0; double Volume=0; for (int i=PositionsTotal()-1 ;i>=0 ;i--){ ticket = PositionGetTicket(i); if (PositionSelectByTicket(ticket)){ if (PositionGetString(POSITION_SYMBOL)==_Symbol){ Volume += PositionGetDouble(POSITION_VOLUME); } } } for (int i=OrdersTotal()-1 ;i>=0 ;i--){ ticket = OrderGetTicket(i); if (OrderSelect(ticket)){ if (OrderGetString(ORDER_SYMBOL)==_Symbol){ Volume += OrderGetDouble(ORDER_VOLUME_CURRENT); } } } return (Volume); } //+------------------------------------------------------------------+ //| 4. CHECK TRADE LEVELS | //+------------------------------------------------------------------+ bool Check4_TradeLevels(ENUM_POSITION_TYPE pos_Type,double sl=0,double tp=0,ulong tkt=0){ double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); int stopLevel = (int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL); int freezeLevel = (int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_FREEZE_LEVEL); int spread = (int)SymbolInfoInteger(_Symbol,SYMBOL_SPREAD); double stopLevel_Pts = stopLevel*_Point; double freezeLevel_Pts = freezeLevel*_Point; if (pos_Type == POSITION_TYPE_BUY){ // STOP LEVELS CHECK if (tp > 0 && tp - Bid < stopLevel_Pts){ Print("WARNING! BUY TP ",tp,", Bid ",Bid," (TP-Bid = ",NormalizeDouble((tp-Bid)/_Point,_Digits),") WITHIN STOP LEVEL OF ",stopLevel); return (false); } if (sl > 0 && Bid - sl < stopLevel_Pts){ Print("WARNING! BUY SL ",sl,", Bid ",Bid," (Bid-SL = ",NormalizeDouble((Bid-sl)/_Point,_Digits),") WITHIN STOP LEVEL OF ",stopLevel); return (false); } // FREEZE LEVELS CHECK if (tp > 0 && tp - Bid < freezeLevel_Pts){ Print("WARNING! BUY TP ",tp,", Bid ",Bid," (TP-Bid = ",NormalizeDouble((tp-Bid)/_Point,_Digits),") WITHIN FREEZE LEVEL OF ",freezeLevel); return (false); } if (sl > 0 && Bid - sl < freezeLevel_Pts){ Print("WARNING! BUY SL ",sl,", Bid ",Bid," (Bid-SL = ",NormalizeDouble((Bid-sl)/_Point,_Digits),") WITHIN FREEZE LEVEL OF ",freezeLevel); return (false); } } if (pos_Type == POSITION_TYPE_SELL){ // STOP LEVELS CHECK if (tp > 0 && Ask - tp < stopLevel_Pts){ Print("WARNING! SELL TP ",tp,", Ask ",Ask," (Ask-TP = ",NormalizeDouble((Ask-tp)/_Point,_Digits),") WITHIN STOP LEVEL OF ",stopLevel); return (false); } if (sl > 0 && sl - Ask < stopLevel_Pts){ Print("WARNING! SELL SL ",sl,", Ask ",Ask," (SL-Ask = ",NormalizeDouble((sl-Ask)/_Point,_Digits),") WITHIN STOP LEVEL OF ",stopLevel); return (false); } // FREEZE LEVELS CHECK if (tp > 0 && Ask - tp < freezeLevel_Pts){ Print("WARNING! SELL TP ",tp,", Ask ",Ask," (Ask-TP = ",NormalizeDouble((Ask-tp)/_Point,_Digits),") WITHIN FREEZE LEVEL OF ",freezeLevel); return (false); } if (sl > 0 && sl - Ask < freezeLevel_Pts){ Print("WARNING! SELL SL ",sl,", Ask ",Ask," (SL-Ask = ",NormalizeDouble((sl-Ask)/_Point,_Digits),") WITHIN FREEZE LEVEL OF ",freezeLevel); return (false); } } if (tkt > 0){ bool result = PositionSelectByTicket(tkt); if (result == false){ Print("ERROR Selecting The Position (CHECK) With Ticket # ",tkt); return (false); } double point = SymbolInfoDouble(_Symbol,SYMBOL_POINT); double pos_SL = PositionGetDouble(POSITION_SL); double pos_TP = PositionGetDouble(POSITION_TP); bool slChanged = MathAbs(pos_SL - sl) > point; bool tpChanged = MathAbs(pos_TP - tp) > point; //bool slChanged = pos_SL != sl; //bool tpChanged = pos_TP != tp; if (!slChanged && !tpChanged){ Print("ERROR. Pos # ",tkt," Already has Levels of SL: ",pos_SL, ", TP: ",pos_TP," NEW[SL = ",sl," | TP = ",tp,"]. NO POINT IN MODIFYING!!!"); return (false); } } return (true); } //+------------------------------------------------------------------+ //| 5. CHECK & CORRECT TRADE LEVELS | //+------------------------------------------------------------------+ double Check5_TradeLevels_Rectify(ENUM_POSITION_TYPE pos_Type,double sl=0,double tp=0){ double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); int stopLevel = (int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL); int freezeLevel = (int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_FREEZE_LEVEL); int spread = (int)SymbolInfoInteger(_Symbol,SYMBOL_SPREAD); double stopLevel_Pts = stopLevel*_Point; double freezeLevel_Pts = freezeLevel*_Point; double accepted_price = 0.0; if (pos_Type == POSITION_TYPE_BUY){ // STOP LEVELS CHECK if (tp > 0 && tp - Bid < stopLevel_Pts){ accepted_price = Bid+stopLevel_Pts; Print("WARNING! BUY TP ",tp,", Bid ",Bid," (TP-Bid = ",NormalizeDouble((tp-Bid)/_Point,_Digits),") WITHIN STOP LEVEL OF ",stopLevel); Print("PRICE MODIFIED TO: ",accepted_price); return (accepted_price); } if (sl > 0 && Bid - sl < stopLevel_Pts){ accepted_price = Bid-stopLevel_Pts; Print("WARNING! BUY SL ",sl,", Bid ",Bid," (Bid-SL = ",NormalizeDouble((Bid-sl)/_Point,_Digits),") WITHIN STOP LEVEL OF ",stopLevel); Print("PRICE MODIFIED TO: ",accepted_price); return (accepted_price); } // FREEZE LEVELS CHECK if (tp > 0 && tp - Bid < freezeLevel_Pts){ accepted_price = Bid+freezeLevel_Pts; Print("WARNING! BUY TP ",tp,", Bid ",Bid," (TP-Bid = ",NormalizeDouble((tp-Bid)/_Point,_Digits),") WITHIN FREEZE LEVEL OF ",freezeLevel); Print("PRICE MODIFIED TO: ",accepted_price); return (accepted_price); } if (sl > 0 && Bid - sl < freezeLevel_Pts){ accepted_price = Bid-freezeLevel_Pts; Print("WARNING! BUY SL ",sl,", Bid ",Bid," (Bid-SL = ",NormalizeDouble((Bid-sl)/_Point,_Digits),") WITHIN FREEZE LEVEL OF ",freezeLevel); Print("PRICE MODIFIED TO: ",accepted_price); return (accepted_price); } } if (pos_Type == POSITION_TYPE_SELL){ // STOP LEVELS CHECK if (tp > 0 && Ask - tp < stopLevel_Pts){ accepted_price = Ask-stopLevel_Pts; Print("WARNING! SELL TP ",tp,", Ask ",Ask," (Ask-TP = ",NormalizeDouble((Ask-tp)/_Point,_Digits),") WITHIN STOP LEVEL OF ",stopLevel); Print("PRICE MODIFIED TO: ",accepted_price); return (accepted_price); } if (sl > 0 && sl - Ask < stopLevel_Pts){ accepted_price = Ask+stopLevel_Pts; Print("WARNING! SELL SL ",sl,", Ask ",Ask," (SL-Ask = ",NormalizeDouble((sl-Ask)/_Point,_Digits),") WITHIN STOP LEVEL OF ",stopLevel); Print("PRICE MODIFIED TO: ",accepted_price); return (accepted_price); } // FREEZE LEVELS CHECK if (tp > 0 && Ask - tp < freezeLevel_Pts){ accepted_price = Ask-freezeLevel_Pts; Print("WARNING! SELL TP ",tp,", Ask ",Ask," (Ask-TP = ",NormalizeDouble((Ask-tp)/_Point,_Digits),") WITHIN FREEZE LEVEL OF ",freezeLevel); Print("PRICE MODIFIED TO: ",accepted_price); return (accepted_price); } if (sl > 0 && sl - Ask < freezeLevel_Pts){ accepted_price = Ask+freezeLevel_Pts; Print("WARNING! SELL SL ",sl,", Ask ",Ask," (SL-Ask = ",NormalizeDouble((sl-Ask)/_Point,_Digits),") WITHIN FREEZE LEVEL OF ",freezeLevel); Print("PRICE MODIFIED TO: ",accepted_price); return (accepted_price); } } return (accepted_price); }