233 lines
8.8 KiB
MQL5
233 lines
8.8 KiB
MQL5
|
//+------------------------------------------------------------------+
|
||
|
//| SmartATR MT5 - Adaptive, Volume & News-Weighted ATR |
|
||
|
//| Project: SmartATR MT5 (Open Source, MIT License) |
|
||
|
//| Author: Steve Rosenstock & Community |
|
||
|
//| Repository: https://forge.mql5.io/steverosenstock/SmartATR |
|
||
|
//| Git: https://forge.mql5.io/steverosenstock/SmartATR.git |
|
||
|
//+------------------------------------------------------------------+
|
||
|
#property copyright "Steve Rosenstock & Community"
|
||
|
#property link "https://forge.mql5.io/steverosenstock/SmartATR"
|
||
|
#property version "1.0"
|
||
|
#property indicator_separate_window
|
||
|
#property indicator_buffers 2
|
||
|
#property indicator_plots 2
|
||
|
|
||
|
#property indicator_label1 "SmartATR"
|
||
|
#property indicator_type1 DRAW_LINE
|
||
|
#property indicator_color1 clrDodgerBlue
|
||
|
#property indicator_width1 2
|
||
|
|
||
|
#property indicator_label2 "News Event Overlay"
|
||
|
#property indicator_type2 DRAW_HISTOGRAM
|
||
|
#property indicator_color2 clrOrangeRed
|
||
|
#property indicator_width2 3
|
||
|
|
||
|
//--- INPUT PARAMETERS
|
||
|
input int ATR_Period = 14; // Initial ATR period (used for first calculation, adaptively changes)
|
||
|
input bool Adaptive_Mode = true; // Enable adaptive period (dynamic lookback)
|
||
|
input int Min_Period = 7; // Minimum ATR period (adaptive mode)
|
||
|
input int Max_Period = 28; // Maximum ATR period (adaptive mode)
|
||
|
input bool Volume_Filter = true; // Weight True Range by volume
|
||
|
input bool News_Filter = true; // Weight True Range by economic news events (MT5 Calendar)
|
||
|
input double Alert_Threshold= 2.0; // Multiplier: alert if ATR exceeds this factor of average
|
||
|
input bool Enable_Alerts = true; // Enable pop-up & sound alerts on high volatility
|
||
|
|
||
|
//--- BUFFERS
|
||
|
double SmartATRBuffer[]; // Main SmartATR output
|
||
|
double NewsBarBuffer[]; // For chart overlays on news events
|
||
|
|
||
|
//--- GLOBALS
|
||
|
int current_period; // Adaptive ATR period in use
|
||
|
double avgVolume = 0; // Rolling average volume for weighting
|
||
|
datetime lastAlertTime = 0; // For alert throttling
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| INIT: Buffers & Setup |
|
||
|
//+------------------------------------------------------------------+
|
||
|
int OnInit()
|
||
|
{
|
||
|
SetIndexBuffer(0, SmartATRBuffer, INDICATOR_DATA);
|
||
|
SetIndexBuffer(1, NewsBarBuffer, INDICATOR_DATA);
|
||
|
|
||
|
PlotIndexSetString(0, PLOT_LABEL, "SmartATR");
|
||
|
PlotIndexSetString(1, PLOT_LABEL, "News Event Overlay");
|
||
|
|
||
|
IndicatorSetInteger(INDICATOR_DIGITS, 2);
|
||
|
ArrayInitialize(SmartATRBuffer, 0.0);
|
||
|
ArrayInitialize(NewsBarBuffer, 0.0);
|
||
|
|
||
|
Print("SmartATR MT5 initialized! Project: https://forge.mql5.io/steverosenstock/SmartATR");
|
||
|
return(INIT_SUCCEEDED);
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| MAIN CALCULATION: SmartATR |
|
||
|
//+------------------------------------------------------------------+
|
||
|
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[])
|
||
|
{
|
||
|
if(rates_total < Max_Period+2)
|
||
|
return(0);
|
||
|
|
||
|
int start = Max_Period; // avoid lookback errors
|
||
|
|
||
|
//--- average volume calculation for weighting
|
||
|
int volWindow = 20;
|
||
|
double volSum = 0;
|
||
|
for(int i=0; i<volWindow && i<rates_total; i++)
|
||
|
volSum += tick_volume[i];
|
||
|
avgVolume = volSum / MathMax(volWindow,1);
|
||
|
|
||
|
//--- rolling ATR mean for alerts
|
||
|
double rollingATRmean = 0.0;
|
||
|
int rollingWindow = 50;
|
||
|
for(int i=0; i<rollingWindow && i<rates_total; i++)
|
||
|
rollingATRmean += SmartATRBuffer[i];
|
||
|
rollingATRmean = rollingATRmean / MathMax(rollingWindow,1);
|
||
|
|
||
|
//--- MAIN LOOP
|
||
|
for(int i=start; i<rates_total; i++)
|
||
|
{
|
||
|
// 1. True Range Calculation
|
||
|
double tr1 = high[i] - low[i];
|
||
|
double tr2 = MathAbs(high[i] - close[i-1]);
|
||
|
double tr3 = MathAbs(low[i] - close[i-1]);
|
||
|
double trueRange = MathMax(tr1, MathMax(tr2, tr3));
|
||
|
|
||
|
// 2. Volume Weighting
|
||
|
double vol_weight = 1.0;
|
||
|
if(Volume_Filter)
|
||
|
{
|
||
|
if(tick_volume[i] > avgVolume)
|
||
|
vol_weight = 1.2;
|
||
|
else if(tick_volume[i] < avgVolume*0.5)
|
||
|
vol_weight = 0.7;
|
||
|
}
|
||
|
|
||
|
// 3. News Weighting (MT5 Calendar)
|
||
|
double news_weight = 1.0;
|
||
|
bool newsDetected = false;
|
||
|
if(News_Filter)
|
||
|
{
|
||
|
newsDetected = IsEconomicNewsEvent(time[i]);
|
||
|
if(newsDetected)
|
||
|
{
|
||
|
news_weight = 1.5;
|
||
|
NewsBarBuffer[i] = trueRange; // draw histogram at bar height
|
||
|
}
|
||
|
else
|
||
|
NewsBarBuffer[i] = 0.0;
|
||
|
}
|
||
|
else
|
||
|
NewsBarBuffer[i] = 0.0;
|
||
|
|
||
|
// 4. Adaptive ATR period
|
||
|
if(Adaptive_Mode)
|
||
|
{
|
||
|
int window = 20;
|
||
|
double localTRsum = 0;
|
||
|
for(int j=1; j<=window && i-j>=0; j++)
|
||
|
{
|
||
|
double ltr1 = high[i-j] - low[i-j];
|
||
|
double ltr2 = MathAbs(high[i-j] - close[i-j-1]);
|
||
|
double ltr3 = MathAbs(low[i-j] - close[i-j-1]);
|
||
|
double ltr = MathMax(ltr1, MathMax(ltr2,ltr3));
|
||
|
localTRsum += ltr;
|
||
|
}
|
||
|
double localTRmean = localTRsum / window;
|
||
|
|
||
|
if(trueRange > localTRmean*1.5)
|
||
|
current_period = MathMax(Min_Period, current_period-1);
|
||
|
else if(trueRange < localTRmean*0.7)
|
||
|
current_period = MathMin(Max_Period, current_period+1);
|
||
|
// else keep as is
|
||
|
}
|
||
|
else
|
||
|
current_period = ATR_Period;
|
||
|
|
||
|
// 5. SmartATR Calculation (EMA-like smoothing)
|
||
|
if(i==start)
|
||
|
SmartATRBuffer[i] = trueRange * vol_weight * news_weight;
|
||
|
else
|
||
|
SmartATRBuffer[i] = (SmartATRBuffer[i-1]*(current_period-1) + trueRange*vol_weight*news_weight) / current_period;
|
||
|
|
||
|
// 6. Alerts for High Volatility
|
||
|
if(Enable_Alerts && SmartATRBuffer[i] > rollingATRmean*Alert_Threshold)
|
||
|
{
|
||
|
// Only alert once per bar!
|
||
|
if(lastAlertTime != time[i])
|
||
|
{
|
||
|
string msg = StringFormat("SmartATR ALERT: Volatility Spike at %s! ATR = %.5f (%.2fx mean)\nProject: https://forge.mql5.io/steverosenstock/SmartATR",
|
||
|
TimeToString(time[i]), SmartATRBuffer[i], SmartATRBuffer[i]/rollingATRmean);
|
||
|
Alert(msg);
|
||
|
lastAlertTime = time[i];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(rates_total);
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| News Event Detection (MT5 Calendar) |
|
||
|
//| Uses MQL5 built-in economic news database. |
|
||
|
//| Returns true if news event detected for the bar's time. |
|
||
|
//+------------------------------------------------------------------+
|
||
|
bool IsEconomicNewsEvent(datetime bartime)
|
||
|
{
|
||
|
MqlCalendarValue news[];
|
||
|
datetime fromTime = bartime - 60; // look 1 min before bar
|
||
|
datetime toTime = bartime + 60; // and 1 min after
|
||
|
int count = CalendarValueHistory(news, fromTime, toTime);
|
||
|
|
||
|
if(count>0)
|
||
|
{
|
||
|
// Check if any high/medium-impact event exists
|
||
|
for(int i=0; i<count; i++)
|
||
|
{
|
||
|
if(news[i].impact>=CALENDAR_IMPORTANCE_MEDIUM)
|
||
|
return(true);
|
||
|
}
|
||
|
}
|
||
|
return(false);
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| --- DEVELOPER NOTES & EXTENSION HOOKS --- |
|
||
|
//| |
|
||
|
//| - SmartATRBuffer[] holds the final ATR output, use in EAs etc. |
|
||
|
//| - NewsBarBuffer[] overlays colored bars on news-event candles |
|
||
|
//| - You can extend IsEconomicNewsEvent() to add more logic |
|
||
|
//| - Adaptive period logic can be improved for other markets |
|
||
|
//| - For more overlays: add custom graphics via OnChartEvent |
|
||
|
//| - For multi-symbol operation: adapt buffer logic as needed |
|
||
|
//+------------------------------------------------------------------+
|
||
|
|
||
|
/*
|
||
|
README FOR DEVELOPERS
|
||
|
|
||
|
SmartATR MT5 is a fully open-source, community-friendly, adaptive ATR indicator for MetaTrader 5.
|
||
|
It combines classic ATR with volume weighting, news sensitivity (using the native MT5 economic calendar), and an adaptive lookback window.
|
||
|
- Ready for plug-and-play use in all markets.
|
||
|
- All main settings are input parameters.
|
||
|
- All calculation logic is fully documented and extensible.
|
||
|
- Alerts and chart overlays are included.
|
||
|
|
||
|
Contributions, improvements and bugfixes are highly encouraged!
|
||
|
- Project home: https://forge.mql5.io/steverosenstock/SmartATR
|
||
|
- Repository: https://forge.mql5.io/steverosenstock/SmartATR.git
|
||
|
|
||
|
License: MIT
|
||
|
Author: Steve Rosenstock & Community
|
||
|
|
||
|
*/
|
||
|
|