140 lines
11 KiB
MQL4
140 lines
11 KiB
MQL4
|
|
//+-----------------------------------------------------------------+
|
|
//+------------------------------------------------------------------+
|
|
//| AverageTrueSpreadLabel.mq4 |
|
|
//| Enhanced version with zero errors/warnings|
|
|
//+------------------------------------------------------------------+
|
|
#property strict
|
|
#property indicator_chart_window
|
|
|
|
//--- input parameters
|
|
input ENUM_TIMEFRAMES SpreadTimeframe = PERIOD_H1; // Timeframe for simulated spread
|
|
input int CandlesCount = 20; // Bars for average
|
|
input int UpdateIntervalSeconds = 5; // Refresh rate
|
|
input color LabelColor = clrWhite; // Text color
|
|
input int FontSize = 12; // Font size
|
|
input string FontName = "Arial"; // Font type
|
|
input bool ShowLiveSpread = true; // Toggle for live spread display
|
|
input int LabelCorner = CORNER_LEFT_UPPER; // Chart corner
|
|
input int LabelXOffset = 10;
|
|
input int LabelYOffset = 20;
|
|
input int LabelLineSpacing = 20; // Space between lines
|
|
|
|
//--- label identifiers
|
|
string avgLabel = "AVG_SPREAD_LABEL";
|
|
string liveLabel = "LIVE_SPREAD_LABEL";
|
|
string warnLabel = "SPREAD_WARN_LABEL";
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Initialization |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
EventSetTimer(UpdateIntervalSeconds);
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Deinitialization |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
EventKillTimer();
|
|
ObjectDelete(0, avgLabel);
|
|
ObjectDelete(0, liveLabel);
|
|
ObjectDelete(0, warnLabel);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Timer-driven label update |
|
|
//+------------------------------------------------------------------+
|
|
void OnTimer()
|
|
{
|
|
int m1Bars = iBars(Symbol(), PERIOD_M1);
|
|
if (m1Bars < CandlesCount + 5)
|
|
{
|
|
DrawLabel(warnLabel, "M1 data missing – load M1 chart!", LabelCorner, LabelXOffset, LabelYOffset, clrRed);
|
|
ObjectDelete(0, avgLabel);
|
|
ObjectDelete(0, liveLabel);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
ObjectDelete(0, warnLabel);
|
|
}
|
|
|
|
double avgSpread = CalculateAverageSpread();
|
|
double liveSpread = MarketInfo(Symbol(), MODE_SPREAD) / 10.0;
|
|
|
|
string avgText = StringFormat("Avg Spread (%s, %d bars): %.1f pips", EnumToString(SpreadTimeframe), CandlesCount, avgSpread);
|
|
string liveText = StringFormat("Live Spread: %.1f pips", liveSpread);
|
|
|
|
DrawLabel(avgLabel, avgText, LabelCorner, LabelXOffset, LabelYOffset, LabelColor);
|
|
if (ShowLiveSpread)
|
|
DrawLabel(liveLabel, liveText, LabelCorner, LabelXOffset, LabelYOffset + LabelLineSpacing, LabelColor);
|
|
else
|
|
ObjectDelete(0, liveLabel);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Calculate average simulated spread via M1 bars |
|
|
//+------------------------------------------------------------------+
|
|
double CalculateAverageSpread()
|
|
{
|
|
double totalSpread = 0;
|
|
int counted = 0;
|
|
|
|
datetime startTime = iTime(Symbol(), SpreadTimeframe, 0) - CandlesCount * PeriodSeconds(SpreadTimeframe);
|
|
int totalBars = iBars(Symbol(), PERIOD_M1);
|
|
|
|
for (int i = 0; i < totalBars && counted < CandlesCount; i++)
|
|
{
|
|
datetime barTime = iTime(Symbol(), PERIOD_M1, i);
|
|
if (barTime < startTime || barTime == 0) break;
|
|
|
|
double high = iHigh(Symbol(), PERIOD_M1, i);
|
|
double low = iLow(Symbol(), PERIOD_M1, i);
|
|
if (high == 0 || low == 0) continue;
|
|
|
|
double spread = (high - low) / Point / 10.0;
|
|
totalSpread += spread;
|
|
counted++;
|
|
}
|
|
|
|
if (counted == 0) return 0;
|
|
return totalSpread / counted;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Draw or update text label |
|
|
//+------------------------------------------------------------------+
|
|
void DrawLabel(string name, string text, int corner, int x_offset, int y_offset, color clr)
|
|
{
|
|
if (!ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0))
|
|
ObjectSetInteger(0, name, OBJPROP_CORNER, corner);
|
|
|
|
ObjectSetInteger(0, name, OBJPROP_CORNER, corner);
|
|
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x_offset);
|
|
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y_offset);
|
|
ObjectSetInteger(0, name, OBJPROP_FONTSIZE, FontSize);
|
|
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
|
|
ObjectSetString(0, name, OBJPROP_FONT, FontName);
|
|
ObjectSetString(0, name, OBJPROP_TEXT, text);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Dummy OnCalculate to fulfill compiler requirement |
|
|
//+------------------------------------------------------------------+
|
|
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[])
|
|
{
|
|
return(rates_total); // no action needed
|
|
}
|