How to implement MT4 synced crosshair

What is it? Why?

Today synced crosshair is a must if you look at multiple charts. Looking at multiple charts is a must if you perform a multi-timeframe analysis. Unfortunately, MT4 and MT5 do not implement it natively.

MT4 and MT5 implement just a crosshair on single charts. While a synced crosshair allows you to synchronize a point in all charts, that means if you set a point in the bar you want in a chart and all other charts will be aligned, setting the point to the corresponding bar on the other charts.

Synced crosshair example

On google, you can find different synced crosshair examples. However, here, our goal is to show you how to implement it step by step. The example provided here also works in MT5.

How to implement

The idea

We can build an MT4 indicator that is triggered every time a chart event occurs. In fact, MQL4 allows creating a function that is called for some specific chart events.

So every time the mouse is moved, we can trigger this function. In this function, we move vertical and horizontal lines in all charts that have the indicator. So in this way, just add this indicator to all charts where you want to use synced crosshair.

Note: the code is tested on MQL4, but it should also run without any change in MQL5.

Setup

We have to create a new indicator on MQL4, and we have to select OnChartEvent.

Then on the OnInit we have to perform the following things:

  • Indicator Name
  • Enable mouse events
int OnInit()
  {
//--- indicator buffers mapping
   IndicatorSetString(INDICATOR_SHORTNAME,"MT4ProfessionalSimpleSyncedCrosshair");
   ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true); 
//---
   return(INIT_SUCCEEDED);
  }
OnInit

Setup Lines

We create a function that creates initial lines (vertical and horizontal lines). We have set blue as color but feel free to change it. We have to call it once in the OnInit.

void SetupLines(){
    ObjectDelete(0, "MT4ProfessionalSimpleVLine");
    ObjectCreate(0, "MT4ProfessionalSimpleVLine", OBJ_VLINE, 0, TimeGMT(), 0);
    ObjectSetInteger(0, "MT4ProfessionalSimpleVLine", OBJPROP_COLOR, clrBlue);
    ObjectSetInteger(0, "MT4ProfessionalSimpleVLine", OBJPROP_STYLE, STYLE_DASH);
    ObjectSetInteger(0, "MT4ProfessionalSimpleVLine", OBJPROP_WIDTH, 1);
    ObjectSetInteger(0, "MT4ProfessionalSimpleVLine", OBJPROP_SELECTABLE, false);
    ObjectSetString(0, "MT4ProfessionalSimpleVLine", OBJPROP_TOOLTIP, "\n");
    ObjectDelete(0, "MT4ProfessionalSimpleHLine");
    ObjectCreate(0, "MT4ProfessionalSimpleHLine", OBJ_HLINE, 0, TimeGMT(), SymbolInfoDouble(Symbol(),SYMBOL_BID));
    ObjectSetInteger(0, "MT4ProfessionalSimpleHLine", OBJPROP_COLOR, clrBlue);
    ObjectSetInteger(0, "MT4ProfessionalSimpleHLine", OBJPROP_STYLE, STYLE_DASH);
    ObjectSetInteger(0, "MT4ProfessionalSimpleHLine", OBJPROP_WIDTH, 1);
    ObjectSetInteger(0, "MT4ProfessionalSimpleHLine", OBJPROP_SELECTABLE	, false);
    ObjectSetString(0, "MT4ProfessionalSimpleHLine", OBJPROP_TOOLTIP, "\n");
}
SetupLines

Perform Movements: preparation

We create a function called MoveCrossHair, and this function has the same parameters that OnChartEvent has. In fact, on OnChartEvent we call MoveCrossHair passing all its parameters.

The first parameter (id) identifies event type, so if it's not CHARTEVENT_MOUSE_MOVE we have to return from the function without doing anything.

While other parameters have a different meaning according to the event type, for our event type, the meaning is the following:

  • lparam is the x position of the mouse
  • dparam is the y position of the mouse
  • sparam is the mouse status, but we do not need it

So we can assign these values to some variables and create other support variables.

void MoveCrossHair(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam){
    if(id != CHARTEVENT_MOUSE_MOVE) return;
   
    int x = (int)lparam; 
    int y = (int)dparam;   
    datetime dt    =0; 
    double   price =0; 
    int      window=0; 
}
MoveCrossHair: Setup

Perform Movements: let's move

We continue working on MoveCrossHair. Firstly we have to convert x and y to chart coordinates: dateTime and price. To do this, we can use the standard ChartXYToTimePrice function.

Then we have to scan all opened charts looking if they have an active line object. If so, we move both lines, and this method is also used to move lines of the current chart (chart where the mouse event occurred).

However, since the bars could not be visible in the other charts, we have to scroll the charts. In this case, we set the vertical line to the visible area's center (that means we scroll until the line is centered aligned).

void MoveCrossHair(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam){
    if(id != CHARTEVENT_MOUSE_MOVE) return;
    
    int x = (int)lparam; 
    int y = (int)dparam;   
    datetime dt    =0; 
    double   price =0; 
    int      window=0; 
      
    if(ChartXYToTimePrice(0,x,y,window,dt,price)) 
    { 
    
        long currentChart = ChartFirst();
        while(currentChart >= 0){
            if(currentChart >= 0 && ObjectFind(0, "MT4ProfessionalSimpleVLine") >= 0){
                ObjectMove(currentChart,"MT4ProfessionalSimpleVLine",0,dt,0); 
                ObjectMove(currentChart,"MT4ProfessionalSimpleHLine",0,0,price);
                if(currentChart != ChartID()){
                    int BarBack = (int)(-iBarShift( ChartSymbol(currentChart), ChartPeriod(currentChart), dt, false) + ChartGetInteger(currentChart,CHART_VISIBLE_BARS)/2);
                    ChartNavigate(currentChart,CHART_END,BarBack);   
                }
                ChartRedraw(currentChart);
            }
            currentChart = ChartNext(currentChart);
         }    
	}
}
MoveCrossHair: Movement

Conclusion

This is just a simple example of the synced crosshair. You can find the entire source code on our github repository for synced crosshair example.
Of course, you can add many features, such as easy color change via settings, start/stop features, and so on.

Did you know MT4Professional is not only the #1 Market scanner on MT4 but has a built-in synced crosshair system?
If you need a complete synced crosshair system that is very efficient, you can evaluate to use MT4Professional. You can try MT4Professional for FREE.