To make this script truly "Pro," we need to elevate it from a basic calculator to an institutional-grade trading tool.
A professional version needs Dual Fee Structures (to handle both Crypto/Stock percentage fees and Futures/Forex per-unit fees), Breakeven Analysis (calculating exactly how many ticks/points the asset needs to move just to pay for itself), and a Modern UI with grouped settings and tooltips.
Code: Select all
//@version=5
indicator("Pro Trade Execution Cost & Breakeven", overlay=true)
// =========================================================================
// INPUT GROUPS & SETTINGS
// =========================================================================
grp_trade = "1. Trade Parameters"
qty = input.float(100, title="Position Size (Qty)", group=grp_trade, 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, tooltip="If 'Per Unit', enter $ amount per contract/share. If 'Percentage', enter % (e.g., 0.1 for 0.1%).")
fixedFee = input.float(0.0, title="Fixed Ticket Fee", group=grp_fees, tooltip="Flat fee charged per order regardless of size.")
grp_mkt = "3. Market Impact"
spread = input.float(1.0, title="Average Spread (Ticks)", group=grp_mkt, step=0.5, tooltip="The distance between Bid and Ask in ticks/pips.")
slippage = input.float(1.0, title="Est. Slippage Per Side (Ticks)", group=grp_mkt, step=0.5, tooltip="Expected slippage on entry AND exit. Will be multiplied by 2 for round-trip.")
grp_ui = "4. UI Settings"
showTable = input.bool(true, title="Show Cost Table", group=grp_ui)
tablePos = input.string("Bottom Right", title="Table Position", options=["Top Right", "Bottom Right", "Bottom Left", "Top Left"], group=grp_ui)
// =========================================================================
// CORE CALCULATIONS
// =========================================================================
// Safety check for exotic tickers where pointvalue might be missing
pointVal = syminfo.pointvalue > 0 ? syminfo.pointvalue : 1
tickVal = syminfo.mintick * pointVal
posValue = close * pointVal * qty
// 1. Commission Calculation (Round Trip)
commCost = feeType == "Per Unit" ? (feeVal * qty) + fixedFee : (posValue * (feeVal / 100)) + fixedFee
// 2. Spread Cost
// Crossing the spread once accounts for a full round trip (e.g., buy at Ask, sell at Bid)
spreadCost = spread * tickVal * qty
// 3. Slippage Cost
// Multiplied by 2 to account for slippage on both entry and exit
slipCost = (slippage * 2) * tickVal * qty
// Total Dollar Cost
totalCost = commCost + spreadCost + slipCost
// 4. Breakeven Analysis
// How many ticks the market must move in your favor just to pay for the trade
ticksToBE = totalCost / (tickVal * qty)
priceToBE = ticksToBE * syminfo.mintick
// =========================================================================
// PROFESSIONAL UI TABLE 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 costTable = table.new(get_position(tablePos), 2, 7, border_width = 1, border_color = color.rgb(40, 40, 40))
currencyStr = " " + syminfo.currency
// Styling variables
bg_header = color.rgb(20, 20, 20)
bg_row = color.rgb(35, 35, 35)
bg_total = color.rgb(41, 98, 255) // Institutional Blue
bg_warn = color.rgb(255, 152, 0, 20) // Subtle orange for breakeven
txt_color = color.white
if barstate.islast and showTable
// Headers
table.cell(costTable, 0, 0, "Trade Cost Analysis", text_color=txt_color, bgcolor=bg_header, text_halign=text.align_left, text_weight="bold")
table.cell(costTable, 1, 0, syminfo.ticker, text_color=txt_color, bgcolor=bg_header, text_halign=text.align_right, text_weight="bold")
// Position Value
table.cell(costTable, 0, 1, "Notional Value", text_color=color.gray, bgcolor=bg_row, text_halign=text.align_left, text_size=size.small)
table.cell(costTable, 1, 1, str.tostring(posValue, "#,###.##") + currencyStr, text_color=color.gray, bgcolor=bg_row, text_halign=text.align_right, text_size=size.small)
// Commission
table.cell(costTable, 0, 2, "Commission & Fees", text_color=txt_color, bgcolor=bg_row, text_halign=text.align_left)
table.cell(costTable, 1, 2, str.tostring(commCost, "#.##") + currencyStr, text_color=color.red, bgcolor=bg_row, text_halign=text.align_right)
// Spread
table.cell(costTable, 0, 3, "Spread Cost", text_color=txt_color, bgcolor=bg_row, text_halign=text.align_left)
table.cell(costTable, 1, 3, str.tostring(spreadCost, "#.##") + currencyStr, text_color=color.red, bgcolor=bg_row, text_halign=text.align_right)
// Slippage
table.cell(costTable, 0, 4, "Slippage (Entry + Exit)", text_color=txt_color, bgcolor=bg_row, text_halign=text.align_left)
table.cell(costTable, 1, 4, str.tostring(slipCost, "#.##") + currencyStr, text_color=color.red, bgcolor=bg_row, text_halign=text.align_right)
// Total Cost
table.cell(costTable, 0, 5, "Total Overhead Cost", text_color=txt_color, bgcolor=bg_total, text_halign=text.align_left, text_weight="bold")
table.cell(costTable, 1, 5, str.tostring(totalCost, "#.##") + currencyStr, text_color=txt_color, bgcolor=bg_total, text_halign=text.align_right, text_weight="bold")
// Breakeven Analysis (The "Pro" Feature)
table.cell(costTable, 0, 6, "Ticks to Breakeven", text_color=color.orange, bgcolor=bg_warn, text_halign=text.align_left, text_weight="bold")
table.cell(costTable, 1, 6, str.tostring(ticksToBE, "#.##") + " Ticks", text_color=color.orange, bgcolor=bg_warn, text_halign=text.align_right, text_weight="bold")