From 821e97d1d7c78c8a9e6ced7ed667b64bb3f91a9e Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Sun, 30 Jun 2024 11:20:12 +0330 Subject: [PATCH] add some resources for studying later ... --- .../Break_of_Structure_jBoSc_EA.mq5 | Bin 0 -> 15470 bytes Documents/MustSee/FVG_SMC_EA/FVG_SMC_EA.mq5 | 517 ++++++++++++++++++ .../RESISTANCE_AND_SUPPORT.mq5 | 332 +++++++++++ 3 files changed, 849 insertions(+) create mode 100644 Documents/MustSee/Break_of_Structure_tBoSt_EA/Break_of_Structure_jBoSc_EA.mq5 create mode 100644 Documents/MustSee/FVG_SMC_EA/FVG_SMC_EA.mq5 create mode 100644 Documents/MustSee/RESISTANCE_AND_SUPPORT/RESISTANCE_AND_SUPPORT.mq5 diff --git a/Documents/MustSee/Break_of_Structure_tBoSt_EA/Break_of_Structure_jBoSc_EA.mq5 b/Documents/MustSee/Break_of_Structure_tBoSt_EA/Break_of_Structure_jBoSc_EA.mq5 new file mode 100644 index 0000000000000000000000000000000000000000..296023219007f1df4a781ca36adeaae4a51fb9d2 GIT binary patch literal 15470 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 literal 0 HcmV?d00001 diff --git a/Documents/MustSee/FVG_SMC_EA/FVG_SMC_EA.mq5 b/Documents/MustSee/FVG_SMC_EA/FVG_SMC_EA.mq5 new file mode 100644 index 00000000..c3e0e55c --- /dev/null +++ b/Documents/MustSee/FVG_SMC_EA/FVG_SMC_EA.mq5 @@ -0,0 +1,517 @@ +//+------------------------------------------------------------------+ +//| FVG SMC 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 version "3.00" + +#include +CTrade obj_Trade; + +#define FVG_Prefix "FVG REC " +#define CLR_UP clrLime +#define CLR_DOWN clrRed + +int minPts = 100; +int FVG_Rec_Ext_Bars = 10; + +string totalFVGs[]; +int barINDICES[]; +datetime barTIMEs[]; +bool signalFVGs[]; + +//+------------------------------------------------------------------+ +//| Expert initialization function | +//+------------------------------------------------------------------+ +int OnInit(){ + + int visibleBars = (int)ChartGetInteger(0,CHART_VISIBLE_BARS); + Print("Total visible bars on chart = ",visibleBars); + + if (ObjectsTotal(0,0,OBJ_RECTANGLE)==0){ + Print("No FVGs Found, Resizing storage arrays to 0 now!!!"); + ArrayResize(totalFVGs,0); + ArrayResize(barINDICES,0); + ArrayResize(signalFVGs,0); + } + + ObjectsDeleteAll(0,FVG_Prefix); + + for (int i=0; i<=visibleBars; i++){ + //Print("Bar Index = ",i); + double low0 = iLow(_Symbol,_Period,i); + double high2 = iHigh(_Symbol,_Period,i+2); + double gap_L0_H2 = NormalizeDouble((low0 - high2)/_Point,_Digits); + + double high0 = iHigh(_Symbol,_Period,i); + double low2 = iLow(_Symbol,_Period,i+2); + double gap_H0_L2 = NormalizeDouble((low2 - high0)/_Point,_Digits); + + bool FVG_UP = low0 > high2 && gap_L0_H2 > minPts; + bool FVG_DOWN = low2 > high0 && gap_H0_L2 > minPts; + + if (FVG_UP || FVG_DOWN){ + Print("Bar Index with FVG = ",i+1); + datetime time1 = iTime(_Symbol,_Period,i+1); + double price1 = FVG_UP ? high2 : high0; + datetime time2 = time1 + PeriodSeconds(_Period)*FVG_Rec_Ext_Bars; + double price2 = FVG_UP ? low0 : low2; + string fvgNAME = FVG_Prefix+"("+TimeToString(time1)+")"; + color fvgClr = FVG_UP ? CLR_UP : CLR_DOWN; + CreateRec(fvgNAME,time1,price1,time2,price2,fvgClr); + Print("Old ArraySize = ",ArraySize(totalFVGs)); + ArrayResize(totalFVGs,ArraySize(totalFVGs)+1); + ArrayResize(barINDICES,ArraySize(barINDICES)+1); + Print("New ArraySize = ",ArraySize(totalFVGs)); + totalFVGs[ArraySize(totalFVGs)-1] = fvgNAME; + barINDICES[ArraySize(barINDICES)-1] = i+1; + ArrayPrint(totalFVGs); + ArrayPrint(barINDICES); + } + } + + for (int i=ArraySize(totalFVGs)-1; i>=0; i--){ + string objName = totalFVGs[i]; + string fvgNAME = ObjectGetString(0,objName,OBJPROP_NAME); + int barIndex = barINDICES[i]; + datetime timeSTART = (datetime)ObjectGetInteger(0,fvgNAME,OBJPROP_TIME,0); + datetime timeEND = (datetime)ObjectGetInteger(0,fvgNAME,OBJPROP_TIME,1); + double fvgLOW = ObjectGetDouble(0,fvgNAME,OBJPROP_PRICE,0); + double fvgHIGH = ObjectGetDouble(0,fvgNAME,OBJPROP_PRICE,1); + color fvgColor = (color)ObjectGetInteger(0,fvgNAME,OBJPROP_COLOR); + + Print("FVG NAME = ",fvgNAME," >No: ",barIndex," TS: ",timeSTART," TE: ", + timeEND," LOW: ",fvgLOW," HIGH: ",fvgHIGH," CLR = ",fvgColor); + for (int k=barIndex-1; k>=(barIndex-FVG_Rec_Ext_Bars); k--){ + datetime barTime = iTime(_Symbol,_Period,k); + double barLow = iLow(_Symbol,_Period,k); + double barHigh = iHigh(_Symbol,_Period,k); + //Print("Bar No: ",k," >Time: ",barTime," >H: ",barHigh," >L: ",barLow); + + if (k==0){ + Print("OverFlow Detected @ fvg ",fvgNAME); + UpdateRec(fvgNAME,timeSTART,fvgLOW,barTime,fvgHIGH); + break; + } + + if ((fvgColor == CLR_DOWN && barHigh > fvgHIGH) || + (fvgColor == CLR_UP && barLow < fvgLOW) + ){ + Print("Cut Off @ bar no: ",k," of Time: ",barTime); + UpdateRec(fvgNAME,timeSTART,fvgLOW,barTime,fvgHIGH); + break; + } + } + + } + + ArrayResize(totalFVGs,0); + ArrayResize(barINDICES,0); + + return(INIT_SUCCEEDED); +} +//+------------------------------------------------------------------+ +//| Expert deinitialization function | +//+------------------------------------------------------------------+ +void OnDeinit(const int reason) + { +//--- + + } +//+------------------------------------------------------------------+ +//| Expert tick function | +//+------------------------------------------------------------------+ +void OnTick(){ + + for (int i=0; i<=FVG_Rec_Ext_Bars; i++){ + double low0 = iLow(_Symbol,_Period,i+1); + double high2 = iHigh(_Symbol,_Period,i+2+1); + double gap_L0_H2 = NormalizeDouble((low0 - high2)/_Point,_Digits); + + double high0 = iHigh(_Symbol,_Period,i+1); + double low2 = iLow(_Symbol,_Period,i+2+1); + double gap_H0_L2 = NormalizeDouble((low2 - high0)/_Point,_Digits); + + bool FVG_UP = low0 > high2 && gap_L0_H2 > minPts; + bool FVG_DOWN = low2 > high0 && gap_H0_L2 > minPts; + + if (FVG_UP || FVG_DOWN){ + datetime time1 = iTime(_Symbol,_Period,i+1+1); + double price1 = FVG_UP ? high2 : high0; + datetime time2 = time1 + PeriodSeconds(_Period)*FVG_Rec_Ext_Bars; + double price2 = FVG_UP ? low0 : low2; + string fvgNAME = FVG_Prefix+"("+TimeToString(time1)+")"; + color fvgClr = FVG_UP ? CLR_UP : CLR_DOWN; + + if (ObjectFind(0,fvgNAME) < 0){ + CreateRec(fvgNAME,time1,price1,time2,price2,fvgClr); + Print("Old ArraySize = ",ArraySize(totalFVGs)); + ArrayResize(totalFVGs,ArraySize(totalFVGs)+1); + ArrayResize(barTIMEs,ArraySize(barTIMEs)+1); + ArrayResize(signalFVGs,ArraySize(signalFVGs)+1); + Print("New ArraySize = ",ArraySize(totalFVGs)); + totalFVGs[ArraySize(totalFVGs)-1] = fvgNAME; + barTIMEs[ArraySize(barTIMEs)-1] = time1; + signalFVGs[ArraySize(signalFVGs)-1] = false; + ArrayPrint(totalFVGs); + ArrayPrint(barTIMEs); + ArrayPrint(signalFVGs); + } + } + } + + for (int j=ArraySize(totalFVGs)-1; j>=0; j--){ + bool fvgExist = false; + string objName = totalFVGs[j]; + string fvgNAME = ObjectGetString(0,objName,OBJPROP_NAME); + double fvgLow = ObjectGetDouble(0,fvgNAME,OBJPROP_PRICE,0); + double fvgHigh = ObjectGetDouble(0,fvgNAME,OBJPROP_PRICE,1); + color fvgColor = (color)ObjectGetInteger(0,fvgNAME,OBJPROP_COLOR); + + for (int k=1; k<=FVG_Rec_Ext_Bars; k++){ + double barLow = iLow(_Symbol,_Period,k); + double barHigh = iHigh(_Symbol,_Period,k); + + if (barHigh == fvgLow || barLow == fvgLow){ + //Print("Found: ",fvgNAME," @ bar ",k); + fvgExist = true; + break; + } + } + + //Print("Existence of ",fvgNAME," = ",fvgExist); + + double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); + double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); + + if (fvgColor == CLR_DOWN && Bid > fvgHigh && !signalFVGs[j]){ + Print("SELL SIGNAL For (",fvgNAME,") Now @ ",Bid); + double SL_sell = Ask + NormalizeDouble((((fvgHigh-fvgLow)/_Point)*10)*_Point,_Digits); + double trade_lots = Check1_ValidateVolume_Lots(0.01); + + if (Check2_Margin(ORDER_TYPE_SELL,trade_lots) && + Check3_VolumeLimit(trade_lots) && + Check4_TradeLevels(POSITION_TYPE_SELL,SL_sell,fvgLow)){ + obj_Trade.Sell(trade_lots,_Symbol,Bid,SL_sell,fvgLow); + signalFVGs[j] = true; + } + ArrayPrint(totalFVGs,_Digits," [< >] "); + ArrayPrint(signalFVGs,_Digits," [< >] "); + } + else if (fvgColor == CLR_UP && Ask < fvgLow && !signalFVGs[j]){ + Print("BUY SIGNAL For (",fvgNAME,") Now @ ",Ask); + double SL_buy = Bid - NormalizeDouble((((fvgHigh-fvgLow)/_Point)*10)*_Point,_Digits); + double trade_lots = Check1_ValidateVolume_Lots(0.01); + + if (Check2_Margin(ORDER_TYPE_BUY,trade_lots) && + Check3_VolumeLimit(trade_lots) && + Check4_TradeLevels(POSITION_TYPE_BUY,SL_buy,fvgHigh)){ + obj_Trade.Buy(trade_lots,_Symbol,Ask,SL_buy,fvgHigh); + signalFVGs[j] = true; + } + ArrayPrint(totalFVGs,_Digits," [< >] "); + ArrayPrint(signalFVGs,_Digits," [< >] "); + } + + if (fvgExist == false){ + bool removeName = ArrayRemove(totalFVGs,0,1); + bool removeTime = ArrayRemove(barTIMEs,0,1); + bool removeSignal = ArrayRemove(signalFVGs,0,1); + if (removeName && removeTime && removeSignal){ + Print("Success removing the FVG DATA from the arrays. New Data as Below:"); + Print("FVGs: ",ArraySize(totalFVGs)," TIMEs: ",ArraySize(barTIMEs), + " SIGNALs: ",ArraySize(signalFVGs)); + ArrayPrint(totalFVGs); + ArrayPrint(barTIMEs); + ArrayPrint(signalFVGs); + } + } + } + +} +//+------------------------------------------------------------------+ + +void CreateRec(string objName,datetime time1,double price1, + datetime time2, double price2,color clr){ + if (ObjectFind(0,objName) < 0){ + ObjectCreate(0,objName,OBJ_RECTANGLE,0,time1,price1,time2,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_COLOR,clr); + ObjectSetInteger(0,objName,OBJPROP_FILL,true); + ObjectSetInteger(0,objName,OBJPROP_BACK,false); + + ChartRedraw(0); + } +} + +void UpdateRec(string objName,datetime time1,double price1, + datetime time2, double price2){ + if (ObjectFind(0,objName) >= 0){ + 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); + + 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){ + Print("ERROR: Something Unexpected Happened While Calculating Margin"); + 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); +} diff --git a/Documents/MustSee/RESISTANCE_AND_SUPPORT/RESISTANCE_AND_SUPPORT.mq5 b/Documents/MustSee/RESISTANCE_AND_SUPPORT/RESISTANCE_AND_SUPPORT.mq5 new file mode 100644 index 00000000..0f959293 --- /dev/null +++ b/Documents/MustSee/RESISTANCE_AND_SUPPORT/RESISTANCE_AND_SUPPORT.mq5 @@ -0,0 +1,332 @@ +//+------------------------------------------------------------------+ +//| RESISTANCE AND SUPPORT.mq5 | +//| Copyright 2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2024, MetaQuotes Ltd." +#property link "https://www.mql5.com" +#property version "1.00" + +#include +CTrade obj_Trade; + +//bool stop_processing = false; + +double pricesHighest[], pricesLowest[]; + +double resistanceLevels[2], supportLevels[2]; + + +#define resLine "RESISTANCE LEVEL" +#define colorRes clrRed +#define resline_prefix "R" + +#define supLine "SUPPORT LEVEL" +#define colorSup clrBlue +#define supline_prefix "S" + +//+------------------------------------------------------------------+ +//| Expert initialization function | +//+------------------------------------------------------------------+ +int OnInit(){ +//--- + + ArraySetAsSeries(pricesHighest,true); + ArraySetAsSeries(pricesLowest,true); + // define the size of the arrays + ArrayResize(pricesHighest,50); + ArrayResize(pricesLowest,50); +//--- + return(INIT_SUCCEEDED); +} +//+------------------------------------------------------------------+ +//| Expert deinitialization function | +//+------------------------------------------------------------------+ +void OnDeinit(const int reason){ +//--- + ArrayFree(pricesHighest); + ArrayFree(pricesLowest); + + //ArrayFree(resistanceLevels); // cannot be used for static allocated array + //ArrayFree(supportLevels); // cannot be used for static allocated array + + ArrayRemove(resistanceLevels,0,WHOLE_ARRAY); + ArrayRemove(supportLevels,0,WHOLE_ARRAY); +} +//+------------------------------------------------------------------+ +//| Expert tick function | +//+------------------------------------------------------------------+ +void OnTick(){ +//--- + + int currBars = iBars(_Symbol,_Period); + static int prevBars = currBars; + if (prevBars == currBars) return; + prevBars = currBars; + + int visible_bars = (int)ChartGetInteger(0,CHART_VISIBLE_BARS); + bool stop_processing = false; // Flag to control outer loop + bool matchFound_high1 = false, matchFound_low1 = false; + bool matchFound_high2 = false, matchFound_low2 = false; + + ArrayFree(pricesHighest); + ArrayFree(pricesLowest); + + int copiedBarsHighs = CopyHigh(_Symbol,_Period,1,visible_bars,pricesHighest); + int copiedBarsLows = CopyLow(_Symbol,_Period,1,visible_bars,pricesLowest); + + //ArrayPrint(pricesHighest); + //ArrayPrint(pricesLowest); + // sort the array in ascending order + ArraySort(pricesHighest); + ArraySort(pricesLowest); + //ArrayPrint(pricesHighest); + //ArrayPrint(pricesLowest); + ArrayRemove(pricesHighest,10,WHOLE_ARRAY); + ArrayRemove(pricesLowest,0,visible_bars-10); + //Print("FIRST 10 HIGHEST PRICES:"); + //ArrayPrint(pricesHighest); + //Print("LAST 10 LOWEST PRICES:"); + //ArrayPrint(pricesLowest); + + for (int i=1; i<=visible_bars-1 && !stop_processing; i++){ + //Print(":: BAR NO: ",i); + double open = iOpen(_Symbol,_Period,i); + double high = iHigh(_Symbol,_Period,i); + double low = iLow(_Symbol,_Period,i); + double close = iClose(_Symbol,_Period,i); + datetime time = iTime(_Symbol,_Period,i); + + int diff_i_j = 10; + + for (int j=i+diff_i_j; j<=visible_bars-1; j++){ + //Print("BAR CHECK NO: ",j); + double open_j = iOpen(_Symbol,_Period,j); + double high_j = iHigh(_Symbol,_Period,j); + double low_j = iLow(_Symbol,_Period,j); + double close_j = iClose(_Symbol,_Period,j); + datetime time_j = iTime(_Symbol,_Period,j); + + // CHECK FOR RESISTANCE + double high_diff = NormalizeDouble((MathAbs(high-high_j)/_Point),0); + bool is_resistance = high_diff <= 10; + + // CHECK FOR SUPPORT + double low_diff = NormalizeDouble((MathAbs(low-low_j)/_Point),0); + bool is_support = low_diff <= 10; + + if (is_resistance){ + //Print("RESISTANCE AT BAR ",i," (",high,") & ",j," (",high_j,"), Pts = ",high_diff); + + for (int k=0; k RES H1(",high,") FOUND @ ",k," (",pricesHighest[k],")"); + } + if (pricesHighest[k]==high_j){ + matchFound_high2 = true; + //Print("> RES H2(",high_j,") FOUND @ ",k," (",pricesHighest[k],")"); + } + if (matchFound_high1 && matchFound_high2){ + if (resistanceLevels[0]==high || resistanceLevels[1]==high_j){ + Print("CONFIRMED BUT This is the same resistance level, skip updating!"); + stop_processing = true; // Set the flag to stop processing + break; // stop the inner loop prematurily + } + else { + Print(" ++++++++++ RESISTANCE LEVELS CONFIRMED @ BARS ",i, + "(",high,") & ",j,"(",high_j,")"); + resistanceLevels[0] = high; + resistanceLevels[1] = high_j; + ArrayPrint(resistanceLevels); + + draw_S_R_Level(resLine,high,colorRes,5); + draw_S_R_Level_Point(resline_prefix,high,time,218,-1,colorRes,90); + draw_S_R_Level_Point(resline_prefix,high,time_j,218,-1,colorRes,90); + + stop_processing = true; // Set the flag to stop processing + break; + } + } + } + } + + else if (is_support){ + //Print("SUPPORT AT BAR ",i," (",low,") & ",j," (",low_j,"), Pts = ",low_diff); + + for (int k=0; k SUP L1(",low,") FOUND @ ",k," (",pricesLowest[k],")"); + } + if (pricesLowest[k]==low_j){ + matchFound_low2 = true; + //Print("> SUP L2(",low_j,") FOUND @ ",k," (",pricesLowest[k],")"); + } + if (matchFound_low1 && matchFound_low2){ + if (supportLevels[0]==low || supportLevels[1]==low_j){ + Print("CONFIRMED BUT This is the same support level, skip updating!"); + stop_processing = true; // Set the flag to stop processing + break; // stop the inner loop prematurely + } + else { + Print(" ++++++++++ SUPPORT LEVELS CONFIRMED @ BARS ",i, + "(",low,") & ",j,"(",low_j,")"); + supportLevels[0] = low; + supportLevels[1] = low_j; + ArrayPrint(supportLevels); + + draw_S_R_Level(supLine,low,colorSup,5); + draw_S_R_Level_Point(supline_prefix,low,time,217,1,colorSup,-90); + draw_S_R_Level_Point(supline_prefix,low,time_j,217,1,colorSup,-90); + + stop_processing = true; // Set the flag to stop processing + break; + } + } + } + } + + + + if (stop_processing){break;} + } + if (stop_processing){break;} + } + + if (ObjectFind(0,resLine) >= 0){ + double objPrice = ObjectGetDouble(0,resLine,OBJPROP_PRICE); + double visibleHighs[]; + ArraySetAsSeries(visibleHighs,true); + CopyHigh(_Symbol,_Period,1,visible_bars,visibleHighs); + //Print("Object Found & visible bars is: ",ArraySize(visibleHighs)); + //ArrayPrint(visibleHighs); + bool matchHighFound = false; + + for (int i=0; i Match price for resistance found at bar # ",i+1," (",objPrice,")"); + matchHighFound = true; + break; + } + } + if (!matchHighFound){ + Print("(",objPrice,") > Match price for the resistance line not found. Delete!"); + deleteLevel(resLine); + } + } + + if (ObjectFind(0,supLine) >= 0){ + double objPrice = ObjectGetDouble(0,supLine,OBJPROP_PRICE); + double visibleLows[]; + ArraySetAsSeries(visibleLows,true); + CopyLow(_Symbol,_Period,1,visible_bars,visibleLows); + //Print("Object Found & visible bars is: ",ArraySize(visibleLows)); + //ArrayPrint(visibleLows); + bool matchLowFound = false; + + for (int i=0; i Match price for support found at bar # ",i+1," (",objPrice,")"); + matchLowFound = true; + break; + } + } + if (!matchLowFound){ + Print("(",objPrice,") > Match price for the support line not found. Delete!"); + deleteLevel(supLine); + } + } + + static double ResistancePriceTrade = 0; + if (ObjectFind(0,resLine) >= 0){ + double ResistancePriceLevel = ObjectGetDouble(0,resLine,OBJPROP_PRICE); + if (ResistancePriceTrade != ResistancePriceLevel){ + double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); + double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); + double open1 = iOpen(_Symbol,_Period,1); + double high1 = iHigh(_Symbol,_Period,1); + double low1 = iLow(_Symbol,_Period,1); + double close1 = iClose(_Symbol,_Period,1); + + if (open1 > close1 && open1 < ResistancePriceLevel + && high1 > ResistancePriceLevel && Bid < ResistancePriceLevel){ + Print("$$$$$$$$$$$$ SELL NOW SIGNAL!"); + obj_Trade.Sell(0.01,_Symbol,Bid,Bid+350*5*_Point,Bid-350*_Point); + ResistancePriceTrade = ResistancePriceLevel; + } + + } + } + + static double SupportPriceTrade = 0; + if (ObjectFind(0,supLine) >= 0){ + double SupportPriceLevel = ObjectGetDouble(0,supLine,OBJPROP_PRICE); + if (SupportPriceTrade != SupportPriceLevel){ + double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); + double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); + double open1 = iOpen(_Symbol,_Period,1); + double high1 = iHigh(_Symbol,_Period,1); + double low1 = iLow(_Symbol,_Period,1); + double close1 = iClose(_Symbol,_Period,1); + + if (open1 < close1 && open1 > SupportPriceLevel + && low1 < SupportPriceLevel && Ask > SupportPriceLevel){ + Print("$$$$$$$$$$$$ BUY NOW SIGNAL!"); + obj_Trade.Buy(0.01,_Symbol,Ask,Ask-350*5*_Point,Ask+350*_Point); + SupportPriceTrade = SupportPriceLevel; + } + + } + } + +} +//+------------------------------------------------------------------+ + +void draw_S_R_Level(string levelName,double price,color clr,int width){ + if (ObjectFind(0,levelName) < 0){ + ObjectCreate(0,levelName,OBJ_HLINE,0,TimeCurrent(),price); + ObjectSetInteger(0,levelName,OBJPROP_COLOR,clr); + ObjectSetInteger(0,levelName,OBJPROP_WIDTH,width); + } + else { + ObjectSetDouble(0,levelName,OBJPROP_PRICE,price); + } + ChartRedraw(0); +} + +void deleteLevel(string levelName){ + ObjectDelete(0,levelName); + ChartRedraw(0); +} + +void draw_S_R_Level_Point(string objName,double price,datetime time, + int arrowcode,int direction,color clr,double angle){ + //objName = " "; + StringConcatenate(objName,objName," @ \nTime: ",time,"\nPrice: ",DoubleToString(price,_Digits)); + if (ObjectCreate(0,objName,OBJ_ARROW,0,time,price)) { + ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrowcode); + ObjectSetInteger(0,objName,OBJPROP_COLOR,clr); + ObjectSetInteger(0,objName,OBJPROP_FONTSIZE,10); + if (direction > 0) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP); + if (direction < 0) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM); + } + string prefix = resline_prefix; + string txt = "\n"+prefix+"("+DoubleToString(price,_Digits)+")"; + string objNameDescription = objName + txt; + if (ObjectCreate(0,objNameDescription,OBJ_TEXT,0,time,price)) { + // ObjectSetString(0,objNameDescription,OBJPROP_TEXT, "" + txt); + ObjectSetInteger(0,objNameDescription,OBJPROP_COLOR,clr); + ObjectSetDouble(0,objNameDescription,OBJPROP_ANGLE, angle); + ObjectSetInteger(0,objNameDescription,OBJPROP_FONTSIZE,10); + if (direction > 0) { + ObjectSetInteger(0,objNameDescription,OBJPROP_ANCHOR,ANCHOR_LEFT); + ObjectSetString(0,objNameDescription,OBJPROP_TEXT, " " + txt); + } + if (direction < 0) { + ObjectSetInteger(0,objNameDescription,OBJPROP_ANCHOR,ANCHOR_BOTTOM); + ObjectSetString(0,objNameDescription,OBJPROP_TEXT, " " + txt); + } + } + ChartRedraw(0); +}