MT5 / MQL5 Implementation
MQL5 handles dynamic coloring cleanly via DRAW_COLOR_HISTOGRAM. The script uses real-time Ask/Bid pricing for the live bar and relies on the broker's historical spread[] array to paint past execution drag.
Code: Select all
//+------------------------------------------------------------------+
//| LiveExecutionDragMonitor.mq5 |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 1
#property indicator_type1 DRAW_COLOR_HISTOGRAM
#property indicator_color1 clrTeal, clrMaroon
#property indicator_width1 2
input double InpCommissionRoundTurn = 6.0; // Round-Turn Commission (Account Currency)
input double InpMaxAllowableDrag = 15.0; // Max Drag (in Ticks/Points)
double CostBuffer[];
double ColorBuffer[];
int OnInit()
{
SetIndexBuffer(0, CostBuffer, INDICATOR_DATA);
SetIndexBuffer(1, ColorBuffer, INDICATOR_COLOR_INDEX);
IndicatorSetString(INDICATOR_SHORTNAME, "Effective Drag Monitor");
IndicatorSetDouble(INDICATOR_LEVELVALUE, 0, InpMaxAllowableDrag);
IndicatorSetInteger(INDICATOR_LEVELCOLOR, 0, clrGray);
IndicatorSetInteger(INDICATOR_LEVELSTYLE, 0, STYLE_DASH);
PlotIndexSetInteger(0, PLOT_COLOR_INDEXES, 2);
PlotIndexSetInteger(0, PLOT_LINE_COLOR, 0, clrTeal);
PlotIndexSetInteger(0, PLOT_LINE_COLOR, 1, clrMaroon);
return(INIT_SUCCEEDED);
}
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[])
{
double tick_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
double tick_value = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
double point_size = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
if(tick_size == 0 || tick_value == 0) return 0;
// Convert fiat commission to tick equivalent dynamically based on asset
double comm_ticks = InpCommissionRoundTurn / tick_value;
int start = (prev_calculated > 0) ? prev_calculated - 1 : 0;
for(int i = start; i < rates_total; i++)
{
double current_spread_ticks = 0;
if(i == rates_total - 1)
{
// Live microsecond tick precision for the current active bar
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
current_spread_ticks = (ask - bid) / tick_size;
}
else
{
// Historical approximation using broker's stored spread array
current_spread_ticks = (spread[i] * point_size) / tick_size;
}
double effective_cost = current_spread_ticks + comm_ticks;
CostBuffer[i] = effective_cost;
// 0 = Teal (Safe), 1 = Maroon (Drag exceeds tolerance)
ColorBuffer[i] = (effective_cost > InpMaxAllowableDrag) ? 1 : 0;
}
// Chart UI Overlay
double live_cost = CostBuffer[rates_total - 1];
string status = (live_cost > InpMaxAllowableDrag) ? "[!] DRAG EXCEEDS TOLERANCE" : "[+] EXECUTABLE CONDITIONS";
Comment(status,
"\nEffective Drag: ", DoubleToString(live_cost, 1), " ticks",
"\nLive Spread: ", DoubleToString(live_cost - comm_ticks, 1), " ticks",
"\nCommission Eq: ", DoubleToString(comm_ticks, 1), " ticks");
return(rates_total);
}
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.