Watch how to download trading robots for free
Find us on Facebook!
Join our fan page
Interesting script?
So post a link to it -
let others appraise it
You liked the script? Try it in the MetaTrader 5 terminal
Indicators

Spread Monitor and Filter - indicator for MetaTrader 5

Views:
187
Rating:
(1)
Published:
MQL5 Freelance Need a robot or indicator based on this code? Order it on Freelance Go to Freelance
//+------------------------------------------------------------------+
//|                                            SpreadMonitorDemo.mq5 |
//|                                        Copyright 2026, Algosphere |
//|                                      https://algosphere-quant.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Algosphere"
#property link      "https://algosphere-quant.com"
#property version   "1.00"
#property description "Demo indicator for SpreadMonitor Library"
#property description "Displays real-time spread statistics and alerts"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   0

//+------------------------------------------------------------------+
//| Includes                                                         |
//+------------------------------------------------------------------+
#include "SpreadMonitor.mqh"

//+------------------------------------------------------------------+
//| Input parameters                                                 |
//+------------------------------------------------------------------+
input group              "=== Display Settings ==="
input int                InpPanelX=10;              // Panel X Position
input int                InpPanelY=30;              // Panel Y Position
input color              InpBackgroundColor=C'32,32,32';  // Background Color
input color              InpTextColor=clrWhite;    // Text Color

input group              "=== Spread Thresholds (Pips) ==="
input double             InpLowThreshold=1.0;      // Low Spread Threshold
input double             InpNormalThreshold=2.0;   // Normal Spread Threshold  
input double             InpHighThreshold=5.0;     // High Spread Threshold

input group              "=== Filter Settings ==="
input double             InpMaxSpread=3.0;         // Maximum Acceptable Spread
input int                InpHistorySize=500;       // History Size (samples)

input group              "=== Alert Settings ==="
input bool               InpAlertOnHigh=true;      // Alert on High Spread
input bool               InpAlertOnExtreme=true;   // Alert on Extreme Spread

//+------------------------------------------------------------------+
//| Defines                                                          |
//+------------------------------------------------------------------+
#define PREFIX           "SPM_"
#define PANEL_WIDTH      200
#define PANEL_HEIGHT     230
#define ROW_SPACING      18

//+------------------------------------------------------------------+
//| Global variables                                                 |
//+------------------------------------------------------------------+
CSpreadMonitor           g_spread_monitor;
double                   g_spread_buffer[];
ENUM_SPREAD_CONDITION    g_last_condition=SPREAD_LOW;
datetime                 g_last_alert_time=0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Initialize spread monitor
   if(!g_spread_monitor.Init(_Symbol,InpHistorySize,
                              InpLowThreshold,InpNormalThreshold,InpHighThreshold))
     {
      Print("Error: Failed to initialize SpreadMonitor");
      return(INIT_FAILED);
     }

//--- Set indicator buffer (not plotted, just for data storage)
   SetIndexBuffer(0,g_spread_buffer,INDICATOR_CALCULATIONS);

//--- Create panel
   CreatePanel();
   
//--- Initial update
   g_spread_monitor.Update();
   UpdatePanel();

//--- Set timer for frequent updates
   EventSetMillisecondTimer(250);

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   EventKillTimer();
   ObjectsDeleteAll(0,PREFIX);
  }

//+------------------------------------------------------------------+
//| Timer function - updates spread display                          |
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- Record spread sample
   g_spread_monitor.Update();
   
//--- Update display
   UpdatePanel();
   
//--- Check for alerts
   CheckAlerts();
  }

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//--- Store current spread
   if(rates_total>0)
      g_spread_buffer[rates_total-1]=g_spread_monitor.GetCurrentSpread();
      
   return(rates_total);
  }

//+------------------------------------------------------------------+
//| Check and trigger alerts                                         |
//+------------------------------------------------------------------+
void CheckAlerts()
  {
   ENUM_SPREAD_CONDITION current_condition=g_spread_monitor.GetSpreadCondition();
   
//--- Only alert on condition change to avoid spam
   if(current_condition==g_last_condition)
      return;
      
//--- Check if enough time passed since last alert (30 seconds)
   if(TimeCurrent()-g_last_alert_time<30)
      return;

//--- Alert on high spread
   if(InpAlertOnHigh && current_condition==SPREAD_HIGH && g_last_condition<SPREAD_HIGH)
     {
      Alert(_Symbol," - HIGH SPREAD: ",DoubleToString(g_spread_monitor.GetCurrentSpread(),1)," pips");
      g_last_alert_time=TimeCurrent();
     }

//--- Alert on extreme spread
   if(InpAlertOnExtreme && current_condition==SPREAD_EXTREME && g_last_condition<SPREAD_EXTREME)
     {
      Alert(_Symbol," - EXTREME SPREAD: ",DoubleToString(g_spread_monitor.GetCurrentSpread(),1)," pips!");
      g_last_alert_time=TimeCurrent();
     }

   g_last_condition=current_condition;
  }

//+------------------------------------------------------------------+
//| Create information panel                                         |
//+------------------------------------------------------------------+
void CreatePanel()
  {
   int x=InpPanelX;
   int y=InpPanelY;

//--- Background
   CreateRectangleLabel(PREFIX+"Background",x,y,PANEL_WIDTH,PANEL_HEIGHT,
                        InpBackgroundColor,C'60,60,60');

//--- Title
   CreateTextLabel(PREFIX+"Title",x+10,y+8,"SPREAD MONITOR",
                   InpTextColor,11,"Arial Bold");

//--- Symbol
   CreateTextLabel(PREFIX+"Symbol",x+PANEL_WIDTH-60,y+10,_Symbol,
                   clrDodgerBlue,9,"Arial");

//--- Separator
   CreateRectangleLabel(PREFIX+"Sep1",x+10,y+30,PANEL_WIDTH-20,1,
                        clrDimGray,clrDimGray);

   int row_y=y+40;

//--- Current spread (large display)
   CreateTextLabel(PREFIX+"LblCurrent",x+15,row_y,"Current:",clrGray,9,"Arial");
   CreateTextLabel(PREFIX+"ValCurrent",x+80,row_y,"0.0",clrLime,14,"Arial Bold");
   CreateTextLabel(PREFIX+"UnitCurrent",x+130,row_y,"pips",clrGray,9,"Arial");
   row_y+=24;

//--- Condition
   CreateTextLabel(PREFIX+"LblCondition",x+15,row_y,"Status:",clrGray,9,"Arial");
   CreateTextLabel(PREFIX+"ValCondition",x+80,row_y,"LOW",clrLime,10,"Arial Bold");
   row_y+=ROW_SPACING+5;

//--- Separator
   CreateRectangleLabel(PREFIX+"Sep2",x+10,row_y,PANEL_WIDTH-20,1,
                        clrDimGray,clrDimGray);
   row_y+=10;

//--- Statistics section
   CreateTextLabel(PREFIX+"LblStats",x+15,row_y,"Statistics",clrWhite,9,"Arial Bold");
   row_y+=ROW_SPACING;

   CreateTextLabel(PREFIX+"LblAvg",x+15,row_y,"Average:",clrGray,9,"Arial");
   CreateTextLabel(PREFIX+"ValAvg",x+100,row_y,"0.0 pips",InpTextColor,9,"Arial");
   row_y+=ROW_SPACING;

   CreateTextLabel(PREFIX+"LblMin",x+15,row_y,"Minimum:",clrGray,9,"Arial");
   CreateTextLabel(PREFIX+"ValMin",x+100,row_y,"0.0 pips",clrLime,9,"Arial");
   row_y+=ROW_SPACING;

   CreateTextLabel(PREFIX+"LblMax",x+15,row_y,"Maximum:",clrGray,9,"Arial");
   CreateTextLabel(PREFIX+"ValMax",x+100,row_y,"0.0 pips",clrOrange,9,"Arial");
   row_y+=ROW_SPACING;

//--- Separator
   CreateRectangleLabel(PREFIX+"Sep3",x+10,row_y+5,PANEL_WIDTH-20,1,
                        clrDimGray,clrDimGray);
   row_y+=15;

//--- Filter status
   CreateTextLabel(PREFIX+"LblFilter",x+15,row_y,"Trade Filter:",clrGray,9,"Arial");
   CreateTextLabel(PREFIX+"ValFilter",x+100,row_y,"ALLOW",clrLime,9,"Arial Bold");
   row_y+=ROW_SPACING;

//--- Samples
   CreateTextLabel(PREFIX+"LblSamples",x+15,row_y,"Samples:",clrGray,9,"Arial");
   CreateTextLabel(PREFIX+"ValSamples",x+100,row_y,"0",clrGray,9,"Arial");

   ChartRedraw();
  }

//+------------------------------------------------------------------+
//| Update panel values                                              |
//+------------------------------------------------------------------+
void UpdatePanel()
  {
//--- Get statistics
   SSpreadStats stats=g_spread_monitor.GetStatistics();

//--- Update current spread
   ObjectSetString(0,PREFIX+"ValCurrent",OBJPROP_TEXT,
                   DoubleToString(stats.current,1));
   ObjectSetInteger(0,PREFIX+"ValCurrent",OBJPROP_COLOR,
                    g_spread_monitor.GetConditionColor(stats.condition));

//--- Update condition
   ObjectSetString(0,PREFIX+"ValCondition",OBJPROP_TEXT,
                   g_spread_monitor.GetConditionName(stats.condition));
   ObjectSetInteger(0,PREFIX+"ValCondition",OBJPROP_COLOR,
                    g_spread_monitor.GetConditionColor(stats.condition));

//--- Update statistics
   ObjectSetString(0,PREFIX+"ValAvg",OBJPROP_TEXT,
                   DoubleToString(stats.average,1)+" pips");
   ObjectSetString(0,PREFIX+"ValMin",OBJPROP_TEXT,
                   DoubleToString(stats.minimum,1)+" pips");
   ObjectSetString(0,PREFIX+"ValMax",OBJPROP_TEXT,
                   DoubleToString(stats.maximum,1)+" pips");

//--- Update filter status
   bool acceptable=g_spread_monitor.IsSpreadAcceptable(InpMaxSpread);
   ObjectSetString(0,PREFIX+"ValFilter",OBJPROP_TEXT,
                   acceptable ? "ALLOW" : "BLOCK");
   ObjectSetInteger(0,PREFIX+"ValFilter",OBJPROP_COLOR,
                    acceptable ? clrLime : clrRed);

//--- Update samples count
   ObjectSetString(0,PREFIX+"ValSamples",OBJPROP_TEXT,
                   IntegerToString(stats.sample_count));

   ChartRedraw();
  }

//+------------------------------------------------------------------+
//| Create text label                                                |
//+------------------------------------------------------------------+
void CreateTextLabel(const string name,
                     const int x,
                     const int y,
                     const string text,
                     const color clr,
                     const int font_size,
                     const string font_name)
  {
   if(ObjectFind(0,name)>=0)
      ObjectDelete(0,name);

   if(!ObjectCreate(0,name,OBJ_LABEL,0,0,0))
      return;

   ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x);
   ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y);
   ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_LEFT_UPPER);
   ObjectSetString(0,name,OBJPROP_TEXT,text);
   ObjectSetInteger(0,name,OBJPROP_COLOR,clr);
   ObjectSetInteger(0,name,OBJPROP_FONTSIZE,font_size);
   ObjectSetString(0,name,OBJPROP_FONT,font_name);
   ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
   ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
  }

//+------------------------------------------------------------------+
//| Create rectangle label                                           |
//+------------------------------------------------------------------+
void CreateRectangleLabel(const string name,
                          const int x,
                          const int y,
                          const int width,
                          const int height,
                          const color bg_color,
                          const color border_color)
  {
   if(ObjectFind(0,name)>=0)
      ObjectDelete(0,name);

   if(!ObjectCreate(0,name,OBJ_RECTANGLE_LABEL,0,0,0))
      return;

   ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x);
   ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y);
   ObjectSetInteger(0,name,OBJPROP_XSIZE,width);
   ObjectSetInteger(0,name,OBJPROP_YSIZE,height);
   ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_LEFT_UPPER);
   ObjectSetInteger(0,name,OBJPROP_BGCOLOR,bg_color);
   ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR,border_color);
   ObjectSetInteger(0,name,OBJPROP_BORDER_TYPE,BORDER_FLAT);
   ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
   ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
  }
//+------------------------------------------------------------------+

nModify Orders nModify Orders

Function for modifying open positions and pending orders

nProfit and Loss Positions nProfit and Loss Positions

Profit/loss calculator of positions (open orders)

Session Time Filter Library Session Time Filter Library

Filter trades by trading sessions (London, NY, Tokyo, Sydney)

MACD Signals MACD Signals

Indicator edition for new platform.