Files
2026-06-08 10:36:15 +02:00

695 lines
53 KiB
Plaintext

//+------------------------------------------------------------------+
//| 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 <Trade/Trade.mqh>
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<startingIndex+rangeCandles-1; i++){
if (MathAbs(high(i) - high(i+1)) > 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<startingIndex+rangeCandles; i++){
if (high(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<startingIndex+rangeCandles; i++){
if (low(i) < lowestLowRef.price){
lowestLowRef.price = low(i);
lowestLowRef.index = i;
}
}
}
void ExtendRangeIfWithinLimits(){
double currentHigh = high(1);
double currentLow = low(1);
if (currentHigh <= highestHigh.price && currentLow >= 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);
}