Best forex brokers with low spreads for scalping
Re: Best forex brokers with low spreads for scalping
What makes this version "Pro":
Breakeven Analysis: The script now calculates exactly how many ticks/pips the asset has to move in your favor just to pay for your fees and slippage. If you are scalping, knowing you need 3.5 ticks just to break even is a massive edge.
Dual Fee Logic: You can now toggle between "Per Unit" (for trading E-mini Futures, Forex, or standard stocks) and "Percentage" (essential for Crypto traders on Binance/Bybit where fees are a % of the total notional value).
Notional Value Display: Added a row to show the total underlying position value to ensure your math aligns with your account size.
Institutional UI:
Uses a clean dark-mode palette (color.rgb) that looks native to TradingView.
Input settings are cleanly separated into groups (Trade Parameters, Fee Structure, Market Impact).
Hover tooltips have been added to the settings menu to explain complex inputs to the user.
Round-Trip Precision: Separated Slippage into "Per Side" inputs, automatically doubling it for round-trip math, which matches how professional traders calculate expected execution drag.
Breakeven Analysis: The script now calculates exactly how many ticks/pips the asset has to move in your favor just to pay for your fees and slippage. If you are scalping, knowing you need 3.5 ticks just to break even is a massive edge.
Dual Fee Logic: You can now toggle between "Per Unit" (for trading E-mini Futures, Forex, or standard stocks) and "Percentage" (essential for Crypto traders on Binance/Bybit where fees are a % of the total notional value).
Notional Value Display: Added a row to show the total underlying position value to ensure your math aligns with your account size.
Institutional UI:
Uses a clean dark-mode palette (color.rgb) that looks native to TradingView.
Input settings are cleanly separated into groups (Trade Parameters, Fee Structure, Market Impact).
Hover tooltips have been added to the settings menu to explain complex inputs to the user.
Round-Trip Precision: Separated Slippage into "Per Side" inputs, automatically doubling it for round-trip math, which matches how professional traders calculate expected execution drag.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Best forex brokers with low spreads for scalping
To elevate this tool to an institutional standard, we must move beyond static math and introduce dynamic market conditions and portfolio impact.
True professional execution models account for expanding volatility, visualize the cost on the chart, and measure the "drag" on the overall account portfolio.
Here is the "Institutional" tier of the script, adding Volatility-Adjusted Slippage (ATR), Visual Breakeven Envelopes, and Account Drag calculations.
True professional execution models account for expanding volatility, visualize the cost on the chart, and measure the "drag" on the overall account portfolio.
Here is the "Institutional" tier of the script, adding Volatility-Adjusted Slippage (ATR), Visual Breakeven Envelopes, and Account Drag calculations.
Code: Select all
//@version=5
indicator("Institutional Execution Cost & Breakeven", overlay=true, max_lines_count=50)
// =========================================================================
// INPUT GROUPS & SETTINGS
// =========================================================================
grp_acct = "1. Account & Sizing"
acctBal = input.float(10000, title="Account Balance ($)", group=grp_acct, tooltip="Used to calculate the % drag this trade has on your total portfolio.")
qty = input.float(100, title="Position Size (Qty)", group=grp_acct, tooltip="Total shares, contracts, or coins.")
grp_fees = "2. Fee Structure"
feeType = input.string("Per Unit", title="Commission Type", options=["Per Unit", "Percentage (%)"], group=grp_fees)
feeVal = input.float(0.005, title="Fee Rate (Round Trip)", group=grp_fees)
fixedFee = input.float(0.0, title="Fixed Ticket Fee", group=grp_fees)
grp_mkt = "3. Market Impact & Volatility"
spread = input.float(1.0, title="Base Spread (Ticks)", group=grp_mkt, step=0.5)
baseSlip = input.float(1.0, title="Base Slippage Per Side (Ticks)", group=grp_mkt, step=0.5)
useDyn = input.bool(true, title="Use Volatility-Adjusted Slippage?", group=grp_mkt, tooltip="Adds dynamic slippage based on ATR. During high volatility (e.g., news), expected slippage increases automatically.")
slipFact = input.float(0.05, title="ATR Slippage Factor", group=grp_mkt, step=0.01, tooltip="What % of the 14-period ATR to add as extra slippage.")
grp_ui = "4. Visuals & UI"
showTable = input.bool(true, title="Show Cost Dashboard", group=grp_ui)
tablePos = input.string("Bottom Right", title="Table Position", options=["Top Right", "Bottom Right", "Bottom Left", "Top Left"], group=grp_ui)
showEnv = input.bool(true, title="Show Breakeven Envelope on Chart", group=grp_ui, tooltip="Plots the exact price level you must cross to become profitable after all fees.")
// =========================================================================
// CORE DYNAMIC CALCULATIONS
// =========================================================================
// Asset base metrics
pointVal = syminfo.pointvalue > 0 ? syminfo.pointvalue : 1
tickVal = syminfo.mintick * pointVal
posValue = close * pointVal * qty
// Volatility (ATR) Adjusted Slippage
atr14 = ta.atr(14)
atrTicks = atr14 / syminfo.mintick
dynSlip = useDyn ? baseSlip + (atrTicks * slipFact) : baseSlip
// 1. Commission Cost (Round Trip)
commCost = feeType == "Per Unit" ? (feeVal * qty) + fixedFee : (posValue * (feeVal / 100)) + fixedFee
// 2. Spread Cost (Round Trip)
spreadCost = spread * tickVal * qty
// 3. Slippage Cost (Round Trip = Per side * 2)
slipCost = (dynSlip * 2) * tickVal * qty
// Total Overhead & Account Drag
totalCost = commCost + spreadCost + slipCost
acctDrag = (totalCost / acctBal) * 100
// Breakeven Analysis
ticksToBE = totalCost / (tickVal * qty)
priceToBE = ticksToBE * syminfo.mintick
// =========================================================================
// VISUAL BREAKEVEN ENVELOPE (CHART PLOTS)
// =========================================================================
// Calculates the dynamic spread/fee envelope. Price must escape this channel to be green.
longBE = close + priceToBE
shortBE = close - priceToBE
plot(showEnv ? longBE : na, title="Long Breakeven", color=color.new(color.teal, 30), linewidth=1, style=plot.style_linebr)
plot(showEnv ? shortBE : na, title="Short Breakeven", color=color.new(color.maroon, 30), linewidth=1, style=plot.style_linebr)
fill(plot(close, display=display.none), plot(showEnv ? longBE : na, display=display.none), color=color.new(color.teal, 90), title="Long Drag Zone")
fill(plot(close, display=display.none), plot(showEnv ? shortBE : na, display=display.none), color=color.new(color.maroon, 90), title="Short Drag Zone")
// =========================================================================
// INSTITUTIONAL DASHBOARD RENDERING
// =========================================================================
get_position(pos) =>
pos == "Top Right" ? position.top_right :
pos == "Bottom Right" ? position.bottom_right :
pos == "Bottom Left" ? position.bottom_left : position.top_left
var table t = table.new(get_position(tablePos), 2, 8, border_width = 1, border_color = color.rgb(30, 30, 30))
cStr = " " + syminfo.currency
// Custom Pro Colors
bg_head = color.rgb(15, 15, 15)
bg_row = color.rgb(28, 28, 28)
bg_tot = color.rgb(25, 118, 210) // Darker institutional blue
bg_warn = color.rgb(255, 82, 82, 20) // Soft alert red
if barstate.islast and showTable
// Headers
table.cell(t, 0, 0, "Execution Drag Model", text_color=color.white, bgcolor=bg_head, text_halign=text.align_left, text_weight="bold")
table.cell(t, 1, 0, syminfo.ticker, text_color=color.white, bgcolor=bg_head, text_halign=text.align_right, text_weight="bold")
// Position Data
table.cell(t, 0, 1, "Notional Exposure", text_color=color.gray, bgcolor=bg_row, text_halign=text.align_left, text_size=size.small)
table.cell(t, 1, 1, str.tostring(posValue, "#,###.##") + cStr, text_color=color.gray, bgcolor=bg_row, text_halign=text.align_right, text_size=size.small)
// Component Breakdown
table.cell(t, 0, 2, "Broker Commissions", text_color=color.silver, bgcolor=bg_row, text_halign=text.align_left)
table.cell(t, 1, 2, str.tostring(commCost, "#.##") + cStr, text_color=color.red, bgcolor=bg_row, text_halign=text.align_right)
table.cell(t, 0, 3, "Bid-Ask Spread Drag", text_color=color.silver, bgcolor=bg_row, text_halign=text.align_left)
table.cell(t, 1, 3, str.tostring(spreadCost, "#.##") + cStr, text_color=color.red, bgcolor=bg_row, text_halign=text.align_right)
table.cell(t, 0, 4, useDyn ? "Vol-Adjusted Slippage (ATR)" : "Static Slippage Est.", text_color=useDyn ? color.orange : color.silver, bgcolor=bg_row, text_halign=text.align_left)
table.cell(t, 1, 4, str.tostring(slipCost, "#.##") + cStr, text_color=color.red, bgcolor=bg_row, text_halign=text.align_right)
// Totals
table.cell(t, 0, 5, "Total Cost (Round Trip)", text_color=color.white, bgcolor=bg_tot, text_halign=text.align_left, text_weight="bold")
table.cell(t, 1, 5, str.tostring(totalCost, "#.##") + cStr, text_color=color.white, bgcolor=bg_tot, text_halign=text.align_right, text_weight="bold")
// Account Impact (The Hidden Tax)
table.cell(t, 0, 6, "Portfolio Drag (Cost %)", text_color=color.silver, bgcolor=bg_warn, text_halign=text.align_left, text_size=size.small)
table.cell(t, 1, 6, str.tostring(acctDrag, "#.####") + "%", text_color=color.red, bgcolor=bg_warn, text_halign=text.align_right, text_size=size.small, text_weight="bold")
// Target Metrics
table.cell(t, 0, 7, "Ticks to Breakeven", text_color=color.orange, bgcolor=bg_warn, text_halign=text.align_left, text_weight="bold")
table.cell(t, 1, 7, str.tostring(ticksToBE, "#.##") + " Ticks", text_color=color.orange, bgcolor=bg_warn, text_halign=text.align_right, text_weight="bold")Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Best forex brokers with low spreads for scalping
The Institutional Upgrades:
1. Volatility-Adjusted Slippage (Dynamic Market Impact)
Standard calculators use a fixed slippage assumption (e.g., 1 tick). This fails during news events or market opens. The script now reads the 14-period Average True Range (ATR). If the asset is experiencing high volatility, the script automatically dynamically increases your estimated slippage cost.
2. Visual Breakeven Envelopes
Instead of just giving you a number, the script actively plots your "Drag Zones" directly on the chart.
Teal Cloud above price: Shows exactly where price must travel if you enter a Long position right now just to clear your overhead costs.
Maroon Cloud below price: Shows the breakeven barrier for Short positions.
Application: If your profit target is sitting inside this cloud, the trade has a negative expected value before it even triggers.
3. Portfolio Drag % (The Hidden Tax)
You now input your total Account Balance. The script calculates what percentage of your entire portfolio is evaporating into thin air purely from execution costs on this one trade. If a scalper sees their Portfolio Drag is 0.5% per trade, they immediately know they will grind their account to zero on fees alone without a massive win rate.
1. Volatility-Adjusted Slippage (Dynamic Market Impact)
Standard calculators use a fixed slippage assumption (e.g., 1 tick). This fails during news events or market opens. The script now reads the 14-period Average True Range (ATR). If the asset is experiencing high volatility, the script automatically dynamically increases your estimated slippage cost.
2. Visual Breakeven Envelopes
Instead of just giving you a number, the script actively plots your "Drag Zones" directly on the chart.
Teal Cloud above price: Shows exactly where price must travel if you enter a Long position right now just to clear your overhead costs.
Maroon Cloud below price: Shows the breakeven barrier for Short positions.
Application: If your profit target is sitting inside this cloud, the trade has a negative expected value before it even triggers.
3. Portfolio Drag % (The Hidden Tax)
You now input your total Account Balance. The script calculates what percentage of your entire portfolio is evaporating into thin air purely from execution costs on this one trade. If a scalper sees their Portfolio Drag is 0.5% per trade, they immediately know they will grind their account to zero on fees alone without a massive win rate.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Best forex brokers with low spreads for scalping
Translating this institutional logic from TradingView (Pine Script) to MetaTrader (MQL4/MQL5) requires adapting to MetaTrader's environment. Instead of abstract "Ticks," MetaTrader uses Points (the smallest price unit, e.g., pipettes in Forex). Furthermore, MetaTrader allows us to dynamically fetch your real account balance rather than relying on manual input.
Because MetaTrader does not have a native "Table" object like TradingView, the dashboard is constructed using a vertical stack of Graphical Object Labels, and the Breakeven Envelopes are drawn using Indicator Buffers.
Because MetaTrader does not have a native "Table" object like TradingView, the dashboard is constructed using a vertical stack of Graphical Object Labels, and the Breakeven Envelopes are drawn using Indicator Buffers.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Best forex brokers with low spreads for scalping
1. MetaTrader 5 (MQL5) Version
Save this as ExecutionDragModel.mq5 in your MQL5/Indicators folder.
Save this as ExecutionDragModel.mq5 in your MQL5/Indicators folder.
Code: Select all
//+------------------------------------------------------------------+
//| ExecutionDragModel.mq5 |
//| Institutional Cost Model |
//+------------------------------------------------------------------+
#property copyright "Pro Execution Model"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
// Plot Long Breakeven
#property indicator_label1 "Long Breakeven"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrTeal
#property indicator_style1 STYLE_DASH
#property indicator_width1 1
// Plot Short Breakeven
#property indicator_label2 "Short Breakeven"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrMaroon
#property indicator_style2 STYLE_DASH
#property indicator_width2 1
// --- Inputs ---
input string grp1 = "--- Position & Fees ---";
input double InpLots = 1.0; // Position Size (Lots)
input int InpFeeType = 0; // Fee Type: 0=Per Lot, 1=Percentage
input double InpFeeRate = 3.5; // Fee Rate (Round Trip per Lot or %)
input double InpFixedFee = 0.0; // Fixed Ticket Fee ($)
input string grp2 = "--- Market Impact ---";
input int InpBaseSpread = 10; // Base Spread (in Points)
input int InpBaseSlippage = 10; // Base Slippage Per Side (in Points)
input bool InpUseDynSlip = true; // Use Volatility-Adjusted Slippage (ATR)
input double InpSlipFactor = 0.05; // ATR Slippage Factor
// --- Buffers ---
double LongBEBuffer[];
double ShortBEBuffer[];
// --- Global Variables ---
int atr_handle;
string prefix = "EDM_";
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, LongBEBuffer, INDICATOR_DATA);
SetIndexBuffer(1, ShortBEBuffer, INDICATOR_DATA);
atr_handle = iATR(_Symbol, PERIOD_CURRENT, 14);
if(atr_handle == INVALID_HANDLE) {
Print("Error creating ATR handle");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectsDeleteAll(0, prefix);
IndicatorRelease(atr_handle);
}
//+------------------------------------------------------------------+
//| 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[])
{
if(rates_total < 14) return(0);
double atr_array[];
if(CopyBuffer(atr_handle, 0, 0, rates_total, atr_array) <= 0) return(0);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double tick_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
double tick_val = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
// Value of 1 point for 1 lot
double point_val = tick_val * (point / tick_size);
if(point_val == 0) point_val = 1; // Failsafe
double contract_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_CONTRACT_SIZE);
int start = prev_calculated == 0 ? 0 : prev_calculated - 1;
for(int i = start; i < rates_total; i++)
{
double current_close = close[i];
double notional = InpLots * contract_size * current_close;
// Volatility Adjusted Slippage
double atr_val = atr_array[i];
double atr_points = atr_val / point;
double dyn_slip = InpUseDynSlip ? InpBaseSlippage + (atr_points * InpSlipFactor) : InpBaseSlippage;
// Costs
double commCost = (InpFeeType == 0) ? (InpFeeRate * InpLots) + InpFixedFee : (notional * (InpFeeRate / 100)) + InpFixedFee;
double spreadCost = InpBaseSpread * point_val * InpLots;
double slipCost = (dyn_slip * 2) * point_val * InpLots; // Round trip
double totalCost = commCost + spreadCost + slipCost;
// Breakeven
double pointsToBE = totalCost / (point_val * InpLots);
LongBEBuffer[i] = current_close + (pointsToBE * point);
ShortBEBuffer[i] = current_close - (pointsToBE * point);
// Update Dashboard on the very last tick
if(i == rates_total - 1)
{
double acct_bal = AccountInfoDouble(ACCOUNT_BALANCE);
double acct_drag = (acct_bal > 0) ? (totalCost / acct_bal) * 100 : 0;
DrawDashboard(notional, commCost, spreadCost, slipCost, totalCost, acct_drag, pointsToBE);
}
}
return(rates_total);
}
//+------------------------------------------------------------------+
//| Draw On-Chart Dashboard |
//+------------------------------------------------------------------+
void DrawDashboard(double notional, double comm, double spread, double slip, double total, double drag, double be_points)
{
int x = 20, y = 30, space = 22;
string ccy = AccountInfoString(ACCOUNT_CURRENCY);
CreateLabel(prefix+"H1", "Institutional Execution Drag Model | " + _Symbol, x, y, clrWhite, 11, true);
CreateLabel(prefix+"R1", "Notional Exposure: " + DoubleToString(notional, 2) + " " + ccy, x, y+(space*1), clrSilver);
CreateLabel(prefix+"R2", "Broker Commissions: " + DoubleToString(comm, 2) + " " + ccy, x, y+(space*2), clrRed);
CreateLabel(prefix+"R3", "Bid-Ask Spread Drag: " + DoubleToString(spread, 2) + " " + ccy, x, y+(space*3), clrRed);
CreateLabel(prefix+"R4", "Slippage Estimate: " + DoubleToString(slip, 2) + " " + ccy, x, y+(space*4), InpUseDynSlip ? clrOrange : clrRed);
CreateLabel(prefix+"R5", "Total Overhead: " + DoubleToString(total, 2) + " " + ccy, x, y+(space*5)+5, clrDodgerBlue, 10, true);
CreateLabel(prefix+"R6", "Portfolio Drag: " + DoubleToString(drag, 4) + "%", x, y+(space*6)+5, clrSalmon, 10, true);
CreateLabel(prefix+"R7", "Points to Breakeven: " + DoubleToString(be_points, 1), x, y+(space*7)+5, clrGold, 10, true);
}
void CreateLabel(string name, string text, int x, int y, color clr, int size=10, bool bold=false)
{
if(ObjectFind(0, name) < 0) ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_RIGHT_LOWER); // Bottom Right
ObjectSetString(0, name, OBJPROP_TEXT, text);
ObjectSetString(0, name, OBJPROP_FONT, "Trebuchet MS");
ObjectSetInteger(0, name, OBJPROP_FONTSIZE, size);
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
ObjectSetInteger(0, name, OBJPROP_BACK, false);
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
}Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Best forex brokers with low spreads for scalping
2. MetaTrader 4 (MQL4) Version
Save this as ExecutionDragModel.mq4 in your MQL4/Indicators folder.
Save this as ExecutionDragModel.mq4 in your MQL4/Indicators folder.
Code: Select all
//+------------------------------------------------------------------+
//| ExecutionDragModel.mq4 |
//| Institutional Cost Model |
//+------------------------------------------------------------------+
#property copyright "Pro Execution Model"
#property link ""
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
// Plot Long Breakeven
#property indicator_color1 clrTeal
#property indicator_style1 STYLE_DASH
#property indicator_width1 1
// Plot Short Breakeven
#property indicator_color2 clrMaroon
#property indicator_style2 STYLE_DASH
#property indicator_width2 1
// --- Inputs ---
extern double InpLots = 1.0; // Position Size (Lots)
extern int InpFeeType = 0; // Fee Type: 0=Per Lot, 1=Percentage
extern double InpFeeRate = 3.5; // Fee Rate (Round Trip per Lot or %)
extern double InpFixedFee = 0.0; // Fixed Ticket Fee ($)
extern int InpBaseSpread = 10; // Base Spread (in Points)
extern int InpBaseSlippage = 10; // Base Slippage Per Side (in Points)
extern bool InpUseDynSlip = true; // Use Volatility-Adjusted Slippage (ATR)
extern double InpSlipFactor = 0.05; // ATR Slippage Factor
// --- Buffers ---
double LongBEBuffer[];
double ShortBEBuffer[];
string prefix = "EDM_";
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, LongBEBuffer);
SetIndexStyle(0, DRAW_LINE);
SetIndexLabel(0, "Long Breakeven");
SetIndexBuffer(1, ShortBEBuffer);
SetIndexStyle(1, DRAW_LINE);
SetIndexLabel(1, "Short Breakeven");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectsDeleteAll(0, prefix);
}
//+------------------------------------------------------------------+
//| 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[])
{
if(rates_total < 14) return(0);
double point = Point;
double tick_size = MarketInfo(Symbol(), MODE_TICKSIZE);
double tick_val = MarketInfo(Symbol(), MODE_TICKVALUE);
double point_val = tick_val * (point / tick_size);
if(point_val == 0) point_val = 1;
double contract_size = MarketInfo(Symbol(), MODE_LOTSIZE);
int start = prev_calculated == 0 ? 0 : prev_calculated - 1;
for(int i = start; i < rates_total; i++)
{
double current_close = close[i];
double notional = InpLots * contract_size * current_close;
// Calculate ATR using built-in MQL4 function
double atr_val = iATR(Symbol(), 0, 14, i);
double atr_points = atr_val / point;
double dyn_slip = InpUseDynSlip ? InpBaseSlippage + (atr_points * InpSlipFactor) : InpBaseSlippage;
// Costs
double commCost = (InpFeeType == 0) ? (InpFeeRate * InpLots) + InpFixedFee : (notional * (InpFeeRate / 100)) + InpFixedFee;
double spreadCost = InpBaseSpread * point_val * InpLots;
double slipCost = (dyn_slip * 2) * point_val * InpLots;
double totalCost = commCost + spreadCost + slipCost;
// Breakeven
double pointsToBE = totalCost / (point_val * InpLots);
LongBEBuffer[i] = current_close + (pointsToBE * point);
ShortBEBuffer[i] = current_close - (pointsToBE * point);
if(i == rates_total - 1)
{
double acct_bal = AccountInfoDouble(ACCOUNT_BALANCE);
double acct_drag = (acct_bal > 0) ? (totalCost / acct_bal) * 100 : 0;
DrawDashboard(notional, commCost, spreadCost, slipCost, totalCost, acct_drag, pointsToBE);
}
}
return(rates_total);
}
void DrawDashboard(double notional, double comm, double spread, double slip, double total, double drag, double be_points)
{
int x = 20, y = 180, space = 20;
string ccy = AccountInfoString(ACCOUNT_CURRENCY);
CreateLabel(prefix+"H1", "Institutional Execution Drag Model | " + Symbol(), x, y, clrWhite, 11);
CreateLabel(prefix+"R1", "Notional Exposure: " + DoubleToString(notional, 2) + " " + ccy, x, y-(space*1), clrSilver);
CreateLabel(prefix+"R2", "Broker Commissions: " + DoubleToString(comm, 2) + " " + ccy, x, y-(space*2), clrRed);
CreateLabel(prefix+"R3", "Bid-Ask Spread Drag: " + DoubleToString(spread, 2) + " " + ccy, x, y-(space*3), clrRed);
CreateLabel(prefix+"R4", "Slippage Estimate: " + DoubleToString(slip, 2) + " " + ccy, x, y-(space*4), InpUseDynSlip ? clrOrange : clrRed);
CreateLabel(prefix+"R5", "Total Overhead: " + DoubleToString(total, 2) + " " + ccy, x, y-(space*5)-5, clrDodgerBlue, 10);
CreateLabel(prefix+"R6", "Portfolio Drag: " + DoubleToString(drag, 4) + "%", x, y-(space*6)-5, clrSalmon, 10);
CreateLabel(prefix+"R7", "Points to Breakeven: " + DoubleToString(be_points, 1), x, y-(space*7)-5, clrGold, 10);
}
void CreateLabel(string name, string text, int x, int y, color clr, int size=9)
{
if(ObjectFind(name) < 0) ObjectCreate(name, OBJ_LABEL, 0, 0, 0);
ObjectSet(name, OBJPROP_XDISTANCE, x);
ObjectSet(name, OBJPROP_YDISTANCE, y);
ObjectSet(name, OBJPROP_CORNER, CORNER_RIGHT_LOWER);
ObjectSetText(name, text, size, "Trebuchet MS", clr);
}Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Best forex brokers with low spreads for scalping
Setup Instructions
1.) Open your MetaTrader platform.
2.) Press F4 to open the MetaQuotes Language Editor.
3.) In the Navigator panel on the left, right-click the Indicators folder -> New File.
4.) Choose Custom Indicator, name it ExecutionDragModel, and paste the code above (matching your MT4 or MT5 version).
5.) Click Compile (or press F7).
6.) Drag the indicator from your Navigator panel onto any live chart.
Key differences handled in this version:
True Point Value: Uses SYMBOL_TRADE_TICK_VALUE and SYMBOL_TRADE_TICK_SIZE to calculate the exact monetary value of a single point movement based on your broker's specific lot sizing.
Auto Portfolio Drag: Instead of manually typing your account size, the script calls AccountInfoDouble(ACCOUNT_BALANCE) dynamically on every tick to show you exactly how much damage the fees do to your current capital.
Non-Intrusive HUD: Anchors neatly to the bottom right of the chart via CORNER_RIGHT_LOWER, automatically cleaning itself up when you remove the indicator.
1.) Open your MetaTrader platform.
2.) Press F4 to open the MetaQuotes Language Editor.
3.) In the Navigator panel on the left, right-click the Indicators folder -> New File.
4.) Choose Custom Indicator, name it ExecutionDragModel, and paste the code above (matching your MT4 or MT5 version).
5.) Click Compile (or press F7).
6.) Drag the indicator from your Navigator panel onto any live chart.
Key differences handled in this version:
True Point Value: Uses SYMBOL_TRADE_TICK_VALUE and SYMBOL_TRADE_TICK_SIZE to calculate the exact monetary value of a single point movement based on your broker's specific lot sizing.
Auto Portfolio Drag: Instead of manually typing your account size, the script calls AccountInfoDouble(ACCOUNT_BALANCE) dynamically on every tick to show you exactly how much damage the fees do to your current capital.
Non-Intrusive HUD: Anchors neatly to the bottom right of the chart via CORNER_RIGHT_LOWER, automatically cleaning itself up when you remove the indicator.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Best forex brokers with low spreads for scalping
To make the MetaTrader versions truly as "Pro" and visually polished as the final TradingView table, we need to upgrade the code in two major ways that take advantage of MetaTrader's native environment:
Live Broker Spread: Unlike Pine Script, MetaTrader can pull the exact real-time spread your broker is currently charging directly from the order book on every single tick, replacing the static manual input.
True Graphical UI Panels: We will upgrade the floating text labels into a solid, dark-mode background panel (OBJ_RECTANGLE_LABEL) to perfectly mimic the TradingView data table.
Here are the ultimate, visually polished institutional versions for both MT4 and MT5.
Live Broker Spread: Unlike Pine Script, MetaTrader can pull the exact real-time spread your broker is currently charging directly from the order book on every single tick, replacing the static manual input.
True Graphical UI Panels: We will upgrade the floating text labels into a solid, dark-mode background panel (OBJ_RECTANGLE_LABEL) to perfectly mimic the TradingView data table.
Here are the ultimate, visually polished institutional versions for both MT4 and MT5.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Best forex brokers with low spreads for scalping
1. MetaTrader 5 (MQL5) Pro UI Version
Save as ProExecutionModel.mq5 in MQL5/Indicators.
Save as ProExecutionModel.mq5 in MQL5/Indicators.
Code: Select all
//+------------------------------------------------------------------+
//| ProExecutionModel.mq5 |
//| Institutional Cost Model w/ GUI |
//+------------------------------------------------------------------+
#property copyright "Pro Execution Model"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
// Plot Long Breakeven
#property indicator_label1 "Long Breakeven"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrTeal
#property indicator_style1 STYLE_DASH
#property indicator_width1 1
// Plot Short Breakeven
#property indicator_label2 "Short Breakeven"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrMaroon
#property indicator_style2 STYLE_DASH
#property indicator_width2 1
// --- Inputs ---
input string grp1 = "--- Position & Fees ---";
input double InpLots = 1.0; // Position Size (Lots)
input int InpFeeType = 0; // Fee Type: 0=Per Lot, 1=Percentage
input double InpFeeRate = 3.5; // Fee Rate (Round Trip per Lot or %)
input double InpFixedFee = 0.0; // Fixed Ticket Fee ($)
input string grp2 = "--- Market Impact ---";
input bool InpUseLiveSpread = true; // Use Live Broker Spread? (Overrides Base)
input int InpBaseSpread = 10; // Base Spread (if Live is false)
input int InpBaseSlippage = 10; // Base Slippage Per Side (in Points)
input bool InpUseDynSlip = true; // Use Volatility-Adjusted Slippage (ATR)
input double InpSlipFactor = 0.05; // ATR Slippage Factor
// --- Buffers ---
double LongBEBuffer[];
double ShortBEBuffer[];
// --- Global Variables ---
int atr_handle;
string prefix = "PRO_EDM_";
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, LongBEBuffer, INDICATOR_DATA);
SetIndexBuffer(1, ShortBEBuffer, INDICATOR_DATA);
atr_handle = iATR(_Symbol, PERIOD_CURRENT, 14);
if(atr_handle == INVALID_HANDLE) return(INIT_FAILED);
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason) { ObjectsDeleteAll(0, prefix); IndicatorRelease(atr_handle); }
//+------------------------------------------------------------------+
//| 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[])
{
if(rates_total < 14) return(0);
double atr_array[];
if(CopyBuffer(atr_handle, 0, 0, rates_total, atr_array) <= 0) return(0);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double tick_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
double tick_val = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
double point_val = tick_val * (point / tick_size);
if(point_val == 0) point_val = 1;
double contract_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_CONTRACT_SIZE);
int start = prev_calculated == 0 ? 0 : prev_calculated - 1;
for(int i = start; i < rates_total; i++)
{
double current_close = close[i];
double notional = InpLots * contract_size * current_close;
// Dynamic ATR Slippage
double dyn_slip = InpBaseSlippage;
if(InpUseDynSlip) dyn_slip += ((atr_array[i] / point) * InpSlipFactor);
// Live vs Manual Spread
int current_spread = InpBaseSpread;
if(InpUseLiveSpread) current_spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
// Core Costs
double commCost = (InpFeeType == 0) ? (InpFeeRate * InpLots) + InpFixedFee : (notional * (InpFeeRate / 100)) + InpFixedFee;
double spreadCost = current_spread * point_val * InpLots;
double slipCost = (dyn_slip * 2) * point_val * InpLots;
double totalCost = commCost + spreadCost + slipCost;
// Breakeven Math
double pointsToBE = totalCost / (point_val * InpLots);
LongBEBuffer[i] = current_close + (pointsToBE * point);
ShortBEBuffer[i] = current_close - (pointsToBE * point);
// UI Update on live tick
if(i == rates_total - 1)
{
double acct_bal = AccountInfoDouble(ACCOUNT_BALANCE);
double acct_drag = (acct_bal > 0) ? (totalCost / acct_bal) * 100 : 0;
DrawPanel(notional, commCost, spreadCost, slipCost, totalCost, acct_drag, pointsToBE, InpUseLiveSpread);
}
}
return(rates_total);
}
//+------------------------------------------------------------------+
//| Graphical UI Panel Construction |
//+------------------------------------------------------------------+
void DrawPanel(double notional, double comm, double spread, double slip, double total, double drag, double be_points, bool liveSpread)
{
int baseX = 20, baseY = 20, w = 310, h = 210, pad = 15, rowH = 22;
string ccy = AccountInfoString(ACCOUNT_CURRENCY);
// Background Panel
if(ObjectFind(0, prefix+"_BG") < 0) ObjectCreate(0, prefix+"_BG", OBJ_RECTANGLE_LABEL, 0, 0, 0);
ObjectSetInteger(0, prefix+"_BG", OBJPROP_XDISTANCE, baseX);
ObjectSetInteger(0, prefix+"_BG", OBJPROP_YDISTANCE, baseY);
ObjectSetInteger(0, prefix+"_BG", OBJPROP_XSIZE, w);
ObjectSetInteger(0, prefix+"_BG", OBJPROP_YSIZE, h);
ObjectSetInteger(0, prefix+"_BG", OBJPROP_BGCOLOR, C'20,20,20');
ObjectSetInteger(0, prefix+"_BG", OBJPROP_COLOR, C'60,60,60'); // Border
ObjectSetInteger(0, prefix+"_BG", OBJPROP_CORNER, CORNER_RIGHT_UPPER);
ObjectSetInteger(0, prefix+"_BG", OBJPROP_BACK, true);
// Draw Rows
DrawTextItem(prefix+"H1", "Execution Drag Model | " + _Symbol, baseX+pad, baseY+pad, clrWhite, 10, true);
DrawTextItem(prefix+"R1", "Notional Exposure:", baseX+pad, baseY+pad+(rowH*1), clrSilver);
DrawValItem(prefix+"V1", DoubleToString(notional, 2) + " " + ccy, baseX+w-pad, baseY+pad+(rowH*1), clrSilver);
DrawTextItem(prefix+"R2", "Broker Commissions:", baseX+pad, baseY+pad+(rowH*2), clrSilver);
DrawValItem(prefix+"V2", DoubleToString(comm, 2) + " " + ccy, baseX+w-pad, baseY+pad+(rowH*2), C'255,100,100');
DrawTextItem(prefix+"R3", liveSpread ? "Spread Drag (LIVE):" : "Spread Drag (STATIC):", baseX+pad, baseY+pad+(rowH*3), clrSilver);
DrawValItem(prefix+"V3", DoubleToString(spread, 2) + " " + ccy, baseX+w-pad, baseY+pad+(rowH*3), C'255,100,100');
DrawTextItem(prefix+"R4", "Est. Slippage (ATR):", baseX+pad, baseY+pad+(rowH*4), clrSilver);
DrawValItem(prefix+"V4", DoubleToString(slip, 2) + " " + ccy, baseX+w-pad, baseY+pad+(rowH*4), C'255,150,50');
DrawTextItem(prefix+"R5", "Total Overhead:", baseX+pad, baseY+pad+(rowH*5)+5, clrDodgerBlue, 9, true);
DrawValItem(prefix+"V5", DoubleToString(total, 2) + " " + ccy, baseX+w-pad, baseY+pad+(rowH*5)+5, clrDodgerBlue, 9, true);
DrawTextItem(prefix+"R6", "Portfolio Drag:", baseX+pad, baseY+pad+(rowH*6)+5, clrSilver);
DrawValItem(prefix+"V6", DoubleToString(drag, 3) + "%", baseX+w-pad, baseY+pad+(rowH*6)+5, clrSalmon, 9, true);
DrawTextItem(prefix+"R7", "Points to Breakeven:", baseX+pad, baseY+pad+(rowH*7)+5, clrGold, 9, true);
DrawValItem(prefix+"V7", DoubleToString(be_points, 1), baseX+w-pad, baseY+pad+(rowH*7)+5, clrGold, 9, true);
}
void DrawTextItem(string name, string text, int x, int y, color clr, int size=9, bool bold=false)
{
if(ObjectFind(0, name) < 0) ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_RIGHT_UPPER);
ObjectSetString(0, name, OBJPROP_TEXT, text);
ObjectSetString(0, name, OBJPROP_FONT, "Trebuchet MS");
ObjectSetInteger(0, name, OBJPROP_FONTSIZE, size);
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
}
void DrawValItem(string name, string text, int x, int y, color clr, int size=9, bool bold=false)
{
DrawTextItem(name, text, x, y, clr, size, bold);
ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_RIGHT_UPPER); // Right align the numbers
}Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Best forex brokers with low spreads for scalping
2. MetaTrader 4 (MQL4) Pro UI Version
Save as ProExecutionModel.mq4 in MQL4/Indicators.
Save as ProExecutionModel.mq4 in MQL4/Indicators.
Code: Select all
//+------------------------------------------------------------------+
//| ProExecutionModel.mq4 |
//| Institutional Cost Model w/ GUI |
//+------------------------------------------------------------------+
#property copyright "Pro Execution Model"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 clrTeal
#property indicator_style1 STYLE_DASH
#property indicator_width1 1
#property indicator_color2 clrMaroon
#property indicator_style2 STYLE_DASH
#property indicator_width2 1
// --- Inputs ---
extern double InpLots = 1.0; // Position Size (Lots)
extern int InpFeeType = 0; // Fee Type: 0=Per Lot, 1=Percentage
extern double InpFeeRate = 3.5; // Fee Rate (Round Trip per Lot or %)
extern double InpFixedFee = 0.0; // Fixed Ticket Fee ($)
extern bool InpUseLiveSpread = true; // Use Live Broker Spread?
extern int InpBaseSpread = 10; // Base Spread (if Live is false)
extern int InpBaseSlippage = 10; // Base Slippage Per Side (in Points)
extern bool InpUseDynSlip = true; // Use Volatility-Adjusted Slippage (ATR)
extern double InpSlipFactor = 0.05; // ATR Slippage Factor
// --- Buffers ---
double LongBEBuffer[];
double ShortBEBuffer[];
string prefix = "PRO_EDM_";
int OnInit()
{
SetIndexBuffer(0, LongBEBuffer);
SetIndexStyle(0, DRAW_LINE);
SetIndexLabel(0, "Long Breakeven");
SetIndexBuffer(1, ShortBEBuffer);
SetIndexStyle(1, DRAW_LINE);
SetIndexLabel(1, "Short Breakeven");
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason) { ObjectsDeleteAll(0, prefix); }
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 < 14) return(0);
double point = Point;
double tick_size = MarketInfo(Symbol(), MODE_TICKSIZE);
double tick_val = MarketInfo(Symbol(), MODE_TICKVALUE);
double point_val = tick_val * (point / tick_size);
if(point_val == 0) point_val = 1;
double contract_size = MarketInfo(Symbol(), MODE_LOTSIZE);
int start = prev_calculated == 0 ? 0 : prev_calculated - 1;
for(int i = start; i < rates_total; i++)
{
double current_close = close[i];
double notional = InpLots * contract_size * current_close;
// Dynamic ATR Slippage
double atr_val = iATR(Symbol(), 0, 14, i);
double dyn_slip = InpBaseSlippage;
if(InpUseDynSlip) dyn_slip += ((atr_val / point) * InpSlipFactor);
// Live Spread Pull
int current_spread = InpBaseSpread;
if(InpUseLiveSpread) current_spread = (int)MarketInfo(Symbol(), MODE_SPREAD);
// Core Costs
double commCost = (InpFeeType == 0) ? (InpFeeRate * InpLots) + InpFixedFee : (notional * (InpFeeRate / 100)) + InpFixedFee;
double spreadCost = current_spread * point_val * InpLots;
double slipCost = (dyn_slip * 2) * point_val * InpLots;
double totalCost = commCost + spreadCost + slipCost;
// Breakeven Math
double pointsToBE = totalCost / (point_val * InpLots);
LongBEBuffer[i] = current_close + (pointsToBE * point);
ShortBEBuffer[i] = current_close - (pointsToBE * point);
// UI Update
if(i == rates_total - 1)
{
double acct_bal = AccountInfoDouble(ACCOUNT_BALANCE);
double acct_drag = (acct_bal > 0) ? (totalCost / acct_bal) * 100 : 0;
DrawPanel(notional, commCost, spreadCost, slipCost, totalCost, acct_drag, pointsToBE, InpUseLiveSpread);
}
}
return(rates_total);
}
void DrawPanel(double notional, double comm, double spread, double slip, double total, double drag, double be_points, bool liveSpread)
{
int baseX = 20, baseY = 20, w = 310, h = 210, pad = 15, rowH = 22;
string ccy = AccountInfoString(ACCOUNT_CURRENCY);
if(ObjectFind(prefix+"_BG") < 0) ObjectCreate(prefix+"_BG", OBJ_RECTANGLE_LABEL, 0, 0, 0);
ObjectSet(prefix+"_BG", OBJPROP_XDISTANCE, baseX);
ObjectSet(prefix+"_BG", OBJPROP_YDISTANCE, baseY);
ObjectSet(prefix+"_BG", OBJPROP_XSIZE, w);
ObjectSet(prefix+"_BG", OBJPROP_YSIZE, h);
ObjectSet(prefix+"_BG", OBJPROP_BGCOLOR, C'20,20,20');
ObjectSet(prefix+"_BG", OBJPROP_COLOR, C'60,60,60');
ObjectSet(prefix+"_BG", OBJPROP_CORNER, CORNER_RIGHT_UPPER);
ObjectSet(prefix+"_BG", OBJPROP_BACK, true);
DrawTextItem(prefix+"H1", "Execution Drag Model | " + Symbol(), baseX+pad, baseY+pad, clrWhite, 10);
DrawTextItem(prefix+"R1", "Notional Exposure:", baseX+pad, baseY+pad+(rowH*1), clrSilver);
DrawValItem(prefix+"V1", DoubleToString(notional, 2) + " " + ccy, baseX+w-pad, baseY+pad+(rowH*1), clrSilver);
DrawTextItem(prefix+"R2", "Broker Commissions:", baseX+pad, baseY+pad+(rowH*2), clrSilver);
DrawValItem(prefix+"V2", DoubleToString(comm, 2) + " " + ccy, baseX+w-pad, baseY+pad+(rowH*2), C'255,100,100');
DrawTextItem(prefix+"R3", liveSpread ? "Spread Drag (LIVE):" : "Spread Drag (STATIC):", baseX+pad, baseY+pad+(rowH*3), clrSilver);
DrawValItem(prefix+"V3", DoubleToString(spread, 2) + " " + ccy, baseX+w-pad, baseY+pad+(rowH*3), C'255,100,100');
DrawTextItem(prefix+"R4", "Est. Slippage (ATR):", baseX+pad, baseY+pad+(rowH*4), clrSilver);
DrawValItem(prefix+"V4", DoubleToString(slip, 2) + " " + ccy, baseX+w-pad, baseY+pad+(rowH*4), C'255,150,50');
DrawTextItem(prefix+"R5", "Total Overhead:", baseX+pad, baseY+pad+(rowH*5)+5, clrDodgerBlue, 9);
DrawValItem(prefix+"V5", DoubleToString(total, 2) + " " + ccy, baseX+w-pad, baseY+pad+(rowH*5)+5, clrDodgerBlue, 9);
DrawTextItem(prefix+"R6", "Portfolio Drag:", baseX+pad, baseY+pad+(rowH*6)+5, clrSilver);
DrawValItem(prefix+"V6", DoubleToString(drag, 3) + "%", baseX+w-pad, baseY+pad+(rowH*6)+5, clrSalmon, 9);
DrawTextItem(prefix+"R7", "Points to Breakeven:", baseX+pad, baseY+pad+(rowH*7)+5, clrGold, 9);
DrawValItem(prefix+"V7", DoubleToString(be_points, 1), baseX+w-pad, baseY+pad+(rowH*7)+5, clrGold, 9);
}
void DrawTextItem(string name, string text, int x, int y, color clr, int size=9)
{
if(ObjectFind(name) < 0) ObjectCreate(name, OBJ_LABEL, 0, 0, 0);
ObjectSet(name, OBJPROP_XDISTANCE, x);
ObjectSet(name, OBJPROP_YDISTANCE, y);
ObjectSet(name, OBJPROP_CORNER, CORNER_RIGHT_UPPER);
ObjectSetText(name, text, size, "Trebuchet MS", clr);
}
void DrawValItem(string name, string text, int x, int y, color clr, int size=9)
{
DrawTextItem(name, text, x, y, clr, size);
ObjectSet(name, OBJPROP_ANCHOR, ANCHOR_RIGHT_UPPER);
}Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.