//+------------------------------------------------------------------+ //| BOS.mq5 | //| // MDMDMD88 // 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; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(){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;} const int length = 20; const int limit = 20; int right_index, left_index; bool isSwingHigh = true, isSwingLow = true; static double swing_H = -1.0, swing_L = -1.0; int curr_bar = limit; if (isNewBar){ for (int j=1; j<=length; j++){ right_index = curr_bar - j; left_index = curr_bar + j; //Print("Current Bar Index = ",curr_bar," ::: Right index: ",right_index,", Left index: ",left_index); //Print("curr_bar(",curr_bar,") right_index = ",right_index,", left_index = ",left_index); // If high of the current bar curr_bar is <= high of the bar at right_index (to the left), //or if it’s < high of the bar at left_index (to the right), then isSwingHigh is set to false //This means that the current bar curr_bar does not have a higher high compared //to its neighbors, and therefore, it’s not a swing high if ( (high(curr_bar) <= high(right_index)) || (high(curr_bar) < high(left_index)) ){ isSwingHigh = false; } if ( (low(curr_bar) >= low(right_index)) || (low(curr_bar) > low(left_index)) ){ isSwingLow = false; } } //By the end of the loop, if isSwingHigh is still true, it suggests that //current bar curr_bar has a higher high than the surrounding bars within //length range, marking a potential swing high. if (isSwingHigh){ swing_H = high(curr_bar); Print("UP @ BAR INDEX ",curr_bar," of High: ",high(curr_bar)); drawSwingPoint(TimeToString(time(curr_bar)),time(curr_bar),high(curr_bar),77,clrBlue,-1); } if (isSwingLow){ swing_L = low(curr_bar); Print("DOWN @ BAR INDEX ",curr_bar," of Low: ",low(curr_bar)); drawSwingPoint(TimeToString(time(curr_bar)),time(curr_bar),low(curr_bar),77,clrRed,1); } } double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); if (swing_H > 0 && Bid > swing_H && close(1) > swing_H){ Print("BREAK UP NOW"); int swing_H_index = 0; for (int i=0; i<=length*2+1000; i++){ double high_sel = high(i); if (high_sel == swing_H){ swing_H_index = i; Print("BREAK HIGH @ BAR ",swing_H_index); break; } } drawBreakLevel(TimeToString(time(0)),time(swing_H_index),high(swing_H_index), time(0+1),high(swing_H_index),clrBlue,-1); swing_H = -1.0; //--- Open Buy obj_Trade.Buy(0.01,_Symbol,Ask,Bid-500*7*_Point,Bid+500*_Point,"BoS Break Up BUY"); return; } else if (swing_L > 0 && Ask < swing_L && close(1) < swing_L){ Print("BREAK DOWN NOW"); int swing_L_index = 0; for (int i=0; i<=length*2+1000; i++){ double low_sel = low(i); if (low_sel == swing_L){ swing_L_index = i; Print("BREAK LOW @ BAR ",swing_L_index); break; } } drawBreakLevel(TimeToString(time(0)),time(swing_L_index),low(swing_L_index), time(0+1),low(swing_L_index),clrRed,1); swing_L = -1.0; //--- Open Sell obj_Trade.Sell(0.01,_Symbol,Bid,Ask+500*7*_Point,Ask-500*_Point,"BoS Break Down SELL"); return; } } //+------------------------------------------------------------------+ // Riville kommentia // double high(int index){return (iHigh(_Symbol,_Period,index));} double low(int index){return (iLow(_Symbol,_Period,index));} double close(int index){return (iClose(_Symbol,_Period,index));} datetime time(int index){return (iTime(_Symbol,_Period,index));} void drawSwingPoint(string objName,datetime time,double price,int arrCode, color clr,int direction){ if (ObjectFind(0,objName) < 0){ ObjectCreate(0,objName,OBJ_ARROW,0,time,price); ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrCode); 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 txt = " BoS"; string objNameDescr = objName + txt; ObjectCreate(0,objNameDescr,OBJ_TEXT,0,time,price); ObjectSetInteger(0,objNameDescr,OBJPROP_COLOR,clr); ObjectSetInteger(0,objNameDescr,OBJPROP_FONTSIZE,10); if (direction > 0) { ObjectSetInteger(0,objNameDescr,OBJPROP_ANCHOR,ANCHOR_LEFT_UPPER); ObjectSetString(0,objNameDescr,OBJPROP_TEXT, " " + txt); } if (direction < 0) { ObjectSetInteger(0,objNameDescr,OBJPROP_ANCHOR,ANCHOR_LEFT_LOWER); ObjectSetString(0,objNameDescr,OBJPROP_TEXT, " " + txt); } } ChartRedraw(0); } void drawBreakLevel(string objName,datetime time1,double price1, datetime time2,double price2,color clr,int direction){ if (ObjectFind(0,objName) < 0){ ObjectCreate(0,objName,OBJ_ARROWED_LINE,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_WIDTH,2); string txt = " Break "; string objNameDescr = objName + txt; ObjectCreate(0,objNameDescr,OBJ_TEXT,0,time2,price2); ObjectSetInteger(0,objNameDescr,OBJPROP_COLOR,clr); ObjectSetInteger(0,objNameDescr,OBJPROP_FONTSIZE,10); if (direction > 0) { ObjectSetInteger(0,objNameDescr,OBJPROP_ANCHOR,ANCHOR_RIGHT_UPPER); ObjectSetString(0,objNameDescr,OBJPROP_TEXT, " " + txt); } if (direction < 0) { ObjectSetInteger(0,objNameDescr,OBJPROP_ANCHOR,ANCHOR_RIGHT_LOWER); ObjectSetString(0,objNameDescr,OBJPROP_TEXT, " " + txt); } } ChartRedraw(0); } int sub_magicnumber() { string local_a; string local_b; int local_c; int local_d; int local_i; string local_par = "EURUSDJPYCHFCADAUDNZDGBPBTCETHXAUUS3"; // The set of symbols for calculation string local_sym = Symbol(); // Current symbol, e.g., "EURUSD" // Extract the first 3 and the last 3 characters of the symbol name local_a = StringSubstr(local_sym, 0, 3); // Base currency local_b = StringSubstr(local_sym, 3, 3); // Quote currency // Find positions of each substring in local_par local_c = StringFind(local_par, local_a, 0); local_d = StringFind(local_par, local_b, 0); // Calculate the magic number based on the found positions local_i = 146411 * (local_c + 1) + local_d; // Print the result for debugging purposes Print("MagicNumber for ", local_a, local_b, " (", local_c, ", ", local_d, ") is: ", local_i); return local_i; }