Author: Copyright � 2009, Vladimir Hlystov
SL_BW

This script is designed as a technical tool for MetaTrader 4 to help traders visualize and identify appropriate "Stop Loss" levels based on historical price action. Rather than simply suggesting a fixed number of pips, the logic scans through past price data to find specific structural points where a protective stop would logically reside.

Core Logic and Workflow

1. Structural Analysis of Price Peaks and Valleys The primary goal of the script is to identify "swing" points. For a Buy position, the script looks for historical bars where the highest and lowest prices are significantly lower than the current price. For a Sell position, it seeks out areas where the highs and lows were significantly higher than the current price. It essentially looks for the most recent "ceiling" or "floor" that the market has established.

2. Multi-Timeframe Contextualization A key feature of this logic is that it doesn't just look at the chart you are currently viewing. The script automatically calculates a higher timeframe based on your current settings (e.g., if you are on a 5-minute chart, it might look at a 30-minute timeframe). This allows the tool to identify major structural levels that aren't visible on smaller, noisier charts, providing a more "macro" view of where price resistance or support lies.

3. Historical Search Window The script looks back through a user-defined number of historical bars (defaulting to 200). It systematically checks these bars until it finds a point that satisfies the structural criteria (a peak for sells or a valley for buys). Once it finds this point, it calculates a price level slightly beyond that boundary to ensure the stop loss is placed outside of "market noise."

4. Visual Feedback and Mapping To make this information actionable for the user, the script provides three types of visual feedback:

  • Zone Highlighting: It can draw rectangular boxes on the chart to visually "box in" the historical bar that determined the Stop Loss level.
  • Target Markers: It places specific arrows on the current chart to indicate exactly where the calculated Stop Loss price should be placed for both Buy and Sell directions.
  • Alert Information: If the script detects any open trades that currently do not have a Stop Loss assigned, it will display a text notification directly on the chart screen.

Summary of User Experience

For a user, this means the tool acts as an automated "support and resistance" scanner. Instead of guessing where to put a stop, the script analyzes the historical "architecture" of the market across multiple timeframes and draws a clear visual indicator on your screen showing the safest structural point to protect your trades.

Price Data Components
Series array that contains the highest prices of each barSeries array that contains the lowest prices of each bar
Orders Execution
Checks for the total of open orders
Miscellaneous
Implements a curve of type %1
12 Views
0 Downloads
0 Favorites
SL_BW
//+------------------------------------------------------------------+
//|                                                    SL_to_Bar.mq4 |
//|                               Copyright © 2009, Vladimir Hlystov |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Vladimir Hlystov"
#property link      "cmillion@narod.ru"
 
#property indicator_chart_window
#property  indicator_buffers 2
#property  indicator_color1  Blue
#property  indicator_color2  Red
 
//+------------------------------------------------------------------+
extern int   BAR            = 200;//searching for in last BAR bar
extern int   minSL          = 25;//it is exposed when 2 bars are not found
extern bool  show_bar       = true;//show bars on which search for SL
extern bool  show_info      = true;//show warrant on which is not installed by SL
extern color color_BAR      = DarkSlateGray;//colour bar on which search for SL
extern color color_Òåê_BAR  = Gray;//colour of the current bar
extern color color_SL       = Gray;//colour of the marks
//+------------------------------------------------------------------+
int per,Ask_Bid,TstartSell,TstartBay;
color colmet;
double SLSell_old,SLBay_old,SLSell[],SLBay[];
//+------------------------------------------------------------------+
int init()
  {
//---- drawing settings
   SetIndexStyle(0,DRAW_LINE);
   SetIndexStyle(1,DRAW_LINE);
//---- indicator buffers mapping
   SetIndexBuffer(0,SLSell);
   SetIndexBuffer(1,SLBay);
//---- name for DataWindow and indicator subwindow label
   SetIndexLabel(0,"SL Sell");
   SetIndexLabel(1,"SL Bay");
//---- initialization done
      per=Period();
      Ask_Bid = MarketInfo(Symbol(),MODE_STOPLEVEL);
   return(0);
  }
//+------------------------------------------------------------------+
int deinit()
  {
   del("SL");
/*   ObjectDelete("SL-UP-bar ");
   ObjectDelete("SL-LO-bar ");
   ObjectDelete("SL-0-bar");
   ObjectDelete("SL for Sell ");
   ObjectDelete("SL for Bay ");*/
   return(0);
  }
//+------------------------------------------------------------------+
int start()
  {
   double SL_Bay =Stop_Loss( 1,Time[0]);
   double SL_Sell=Stop_Loss(-1,Time[0]);
   string info;
   //-----------------------------------------------------------------
   int counted_bars = IndicatorCounted();      
   if(counted_bars > 0) counted_bars--;
   int limit = Bars-counted_bars;
   double SL;
   for(int i=0; i<limit; i++) 
   {
      SL = Stop_Loss( 1,Time[i]);
      if (SL!=0) SLSell[i] = SL;
      SL = Stop_Loss(-1,Time[i]);
      if (SL!=0) SLBay[i] = SL;
   }
   //-----------------------------------------------------------------
   Drawfoots(SL_Sell,SL_Bay);
   if (show_info)
   {
      for (i=0; i<OrdersTotal(); i++)
      {
         if((OrderSelect(i, SELECT_BY_POS)==true) && (OrderSymbol()==Symbol()))
         { 
            if (OrderType()<2)  //Bay or Sell
            {
               if (OrderStopLoss()==0)
               {
                  info=info+"Îðäåð "+OrderTicket()+" áåç SL\n";
               }
            }
         }
      }
      Comment(info);
   }
   return(0);
  }
//+------------------------------------------------------------------+
//æææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ
//////////////////////////////////////////////////////////////////////
//    Stop_Loss                                                     // 
//    Returns importance SL for operation of the buying or sale     //
//                         "Copyright © 2009, Vladimir Hlystov"     //
//                                          "cmillion@narod.ru"     //
//    direction = 1 Bay           -1 Sell                           //
//                                                                  //
//////////////////////////////////////////////////////////////////////
double Stop_Loss(int direction, int TimeBar) //TimeBar - âðåìÿ íà÷àëà òåê áàðà
{
   if (direction == 0) return (0);
   int i;
   int timeframe,toBar,tf; 
   double SL_toBar,
          max_toBar,
          min_toBar;
   timeframe=next_period(per+1);
   int tekBar = iBarShift(NULL,timeframe,TimeBar,false); //Ïîèñê áàðà ïî âðåìåíè. Ôóíêöèÿ âîçâðàùàåò ñìåùåíèå áàðà, êîòîðîìó ïðèíàäëåæèò óêàçàííîå âðåìÿ.   
   Comment(tekBar);
   double max_0Bar = iHigh( NULL, timeframe, tekBar);
   double min_0Bar = iLow ( NULL, timeframe, tekBar);
   if ( direction ==1 ) //Bay
   {
      SL_toBar=0;
      for (toBar=1+tekBar; toBar<BAR+tekBar; toBar++)
      {
         max_toBar = iHigh( NULL, timeframe, toBar);
         min_toBar = iLow ( NULL, timeframe, toBar);
         if ( max_0Bar > max_toBar && min_0Bar > min_toBar)
         {
            SL_toBar = min_toBar-Point*Ask_Bid;
            if (show_bar==true){
               ObjectDelete("SL-UP-bar ");
               ObjectCreate("SL-UP-bar ", OBJ_RECTANGLE, 0, 0,0, 0,0);
               ObjectSet   ("SL-UP-bar ", OBJPROP_STYLE, STYLE_SOLID);
               ObjectSet   ("SL-UP-bar ", OBJPROP_COLOR, color_BAR);
               ObjectSet   ("SL-UP-bar ", OBJPROP_BACK, true);
               ObjectSet   ("SL-UP-bar ", OBJPROP_TIME1 , iTime( NULL, timeframe, toBar-1));
               ObjectSet   ("SL-UP-bar ", OBJPROP_PRICE1, SL_toBar);
               ObjectSet   ("SL-UP-bar ", OBJPROP_TIME2 , iTime( NULL, timeframe, toBar));
               ObjectSet   ("SL-UP-bar ", OBJPROP_PRICE2, max_toBar);}
            break;
         }
      }
/*      if (SL_toBar==0)//No SL
      {  tf=timeframe;
         for (i=1; i<5; i++)
         {
            tf=next_period(tf+1);
            if ((iLow(NULL,tf,0)-Point*Ask_Bid) < (Bid-Point*minSL))
            {
               SL_toBar=iLow(NULL,tf,0)-Point*Ask_Bid;
               if (show_bar==true){
                  ObjectDelete("SL-UP-bar ");
                  ObjectCreate("SL-UP-bar ", OBJ_RECTANGLE, 0, 0,0, 0,0);
                  ObjectSet   ("SL-UP-bar ", OBJPROP_STYLE, STYLE_SOLID);
                  ObjectSet   ("SL-UP-bar ", OBJPROP_COLOR, Red);
                  ObjectSet   ("SL-UP-bar ", OBJPROP_BACK, false);
                  ObjectSet   ("SL-UP-bar ", OBJPROP_TIME1 , iTime( NULL, tf, 0));
                  ObjectSet   ("SL-UP-bar ", OBJPROP_PRICE1, SL_toBar);
                  ObjectSet   ("SL-UP-bar ", OBJPROP_TIME2 , CurTime());
                  ObjectSet   ("SL-UP-bar ", OBJPROP_PRICE2, iHigh( NULL, tf, 0));}
               break;
            }
         }
      }*/
   }
   if ( direction ==-1 ) //Sell
   {
      SL_toBar=0;
      for (toBar=1+tekBar; toBar<BAR+tekBar; toBar++) 
      {
         max_toBar = iHigh( NULL, timeframe, toBar);
         min_toBar = iLow ( NULL, timeframe, toBar);
         if ( max_0Bar < max_toBar && min_0Bar < min_toBar)
         {
            SL_toBar = max_toBar+Point*Ask_Bid;
            if (show_bar==true){
               ObjectDelete("SL-LO-bar ");
               ObjectCreate("SL-LO-bar ", OBJ_RECTANGLE, 0, 0,0, 0,0);
               ObjectSet   ("SL-LO-bar ", OBJPROP_STYLE, STYLE_SOLID);
               ObjectSet   ("SL-LO-bar ", OBJPROP_COLOR, color_BAR);
               ObjectSet   ("SL-LO-bar ", OBJPROP_BACK, true);
               ObjectSet   ("SL-LO-bar ", OBJPROP_TIME1 , iTime( NULL, timeframe, toBar-1));
               ObjectSet   ("SL-LO-bar ", OBJPROP_PRICE1, min_toBar);
               ObjectSet   ("SL-LO-bar ", OBJPROP_TIME2 , iTime( NULL, timeframe, toBar));
               ObjectSet   ("SL-LO-bar ", OBJPROP_PRICE2, SL_toBar);}
            break;
         }
      }
/*      if (SL_toBar==0)//No SL
      {  tf=timeframe;
         for (i=1; i<5; i++)
         {
            tf=next_period(tf+1);
            if ((iHigh(NULL,tf,0)+Point*Ask_Bid) > (Ask+Point*minSL))
            {
               SL_toBar=iHigh(NULL,tf,0)+Point*Ask_Bid;
               if (show_bar==true){
                  ObjectDelete("SL-LO-bar ");
                  ObjectCreate("SL-LO-bar ", OBJ_RECTANGLE, 0, 0,0, 0,0);
                  ObjectSet   ("SL-LO-bar ", OBJPROP_STYLE, STYLE_SOLID);
                  ObjectSet   ("SL-LO-bar ", OBJPROP_COLOR, Red);
                  ObjectSet   ("SL-LO-bar ", OBJPROP_BACK, false);
                  ObjectSet   ("SL-LO-bar ", OBJPROP_TIME1 , iTime( NULL, tf, 0));
                  ObjectSet   ("SL-LO-bar ", OBJPROP_PRICE1, iLow ( NULL, tf, 0));
                  ObjectSet   ("SL-LO-bar ", OBJPROP_TIME2 , CurTime());
                  ObjectSet   ("SL-LO-bar ", OBJPROP_PRICE2, SL_toBar);}
               break;
            }
         }
      }*/
   }
   if (show_bar==true){
      ObjectDelete("SL-0-bar");
      ObjectCreate("SL-0-bar", OBJ_RECTANGLE, 0, 0,0, 0,0);
      ObjectSet   ("SL-0-bar", OBJPROP_STYLE, STYLE_SOLID);
      ObjectSet   ("SL-0-bar", OBJPROP_COLOR, color_Òåê_BAR);
      ObjectSet   ("SL-0-bar", OBJPROP_BACK, true);
      ObjectSet   ("SL-0-bar", OBJPROP_TIME1 , iTime( NULL, timeframe, 0));
      ObjectSet   ("SL-0-bar", OBJPROP_PRICE1, min_0Bar);
      ObjectSet   ("SL-0-bar", OBJPROP_TIME2 , iTime( NULL, timeframe, 0)+timeframe*60);
      ObjectSet   ("SL-0-bar", OBJPROP_PRICE2, max_0Bar);}
   return (NormalizeDouble(SL_toBar,Digits));   
}
//+------------------------------------------------------------------+
int next_period(int per)
{
   if (per > 10080)  return(43200); 
   if (per > 1440)   return(10080); 
   if (per > 240)    return(1440); 
   if (per > 60)     return(240); 
   if (per > 30)     return(240);
   if (per > 15)     return(60); 
   if (per > 5)      return(30); 
   if (per > 1)      return(5);   
}
//+------------------------------------------------------------------+
double Drawfoots(double top, double bottom)
{  
   int indention=Time[0]+per*3*60;
   if (show_bar==true)
   {
      colmet=color_SL;
      if (top==0) {top=Ask;colmet=Red;}
      ObjectDelete("SL for Sell ");
      ObjectCreate("SL for Sell ", OBJ_ARROW,0,indention,top,0,0,0,0);
      ObjectSet   ("SL for Sell ", OBJPROP_ARROWCODE,6);
      ObjectSet   ("SL for Sell ", OBJPROP_COLOR,colmet );
      ObjectSet   ("SL for Sell ", OBJPROP_BACK, true);
      colmet=color_SL;
      if (bottom ==0) {bottom =Bid;colmet=Red;}
      ObjectDelete("SL for Bay ");
      ObjectCreate("SL for Bay ", OBJ_ARROW,0,indention,bottom,0,0,0,0);
      ObjectSet   ("SL for Bay ", OBJPROP_ARROWCODE,6);
      ObjectSet   ("SL for Bay ", OBJPROP_COLOR,colmet );
      ObjectSet   ("SL for Bay ", OBJPROP_BACK, true);
   }
}
//+------------------------------------------------------------------+
int del(string Ob)
{
   for(int n=ObjectsTotal()-1; n>=0; n--) 
   {
      string Obj_Name=ObjectName(n);
      if (StringFind(Obj_Name,Ob,0) != -1) ObjectDelete(Obj_Name);
   }
   return;
}
//+------------------------------------------------------------------+

Comments