Code: Select all
//@version=5
indicator("Interactive Spread & Risk Monitor v2.0", overlay=true, max_boxes_count=50)
// --- Inputs ---
grp1 = "Interactive Trade Setup"
// The 'confirm=true' argument allows you to click the chart to set these levels visually
entryPrice = input.price(title="1. Click Entry Price", defval=0, confirm=true, group=grp1)
slPrice = input.price(title="2. Click Stop Loss", defval=0, confirm=true, group=grp1)
tpPrice = input.price(title="3. Click Take Profit", defval=0, confirm=true, group=grp1)
grp2 = "Execution & Risk"
spreadPips = input.float(1.5, title="Broker Spread (Pips)", step=0.1, group=grp2)
grp3 = "Dashboard Settings"
maxRatio = input.float(15.0, title="Max Spread/Stop Ratio (%)", step=1.0, group=grp3)
tablePos = input.string("Bottom Right", options=["Top Right", "Top Left", "Bottom Right", "Bottom Left"], title="Position", group=grp3)
// --- Pip Calculation Logic ---
// Automatically adjust for standard Forex (5-digit) vs JPY pairs
isJPY = str.contains(syminfo.ticker, "JPY")
pipMultiplier = syminfo.type == "forex" ? (isJPY ? 100 : 10000) : 1
// --- Trade Math ---
isLong = tpPrice > entryPrice
// Nominal distances (in Pips) based on your chart clicks
slDistPips = math.abs(entryPrice - slPrice) * pipMultiplier
tpDistPips = math.abs(tpPrice - entryPrice) * pipMultiplier
// Effective distances (Spread adjusted)
// If Long: Buy at Ask (Entry + Spread), Sell at Bid (SL/TP as is).
effSlPips = slDistPips + spreadPips
effTpPips = tpDistPips - spreadPips
nominalRR = slDistPips > 0 ? (tpDistPips / slDistPips) : 0
effRR = effSlPips > 0 ? (effTpPips / effSlPips) : 0
spreadRatio = slDistPips > 0 ? ((spreadPips / slDistPips) * 100) : 0
// Required Breakeven Win Rates
reqWinRateNominal = nominalRR > 0 ? (1 / (1 + nominalRR)) * 100 : 0
reqWinRateEff = effRR > 0 ? (1 / (1 + effRR)) * 100 : 0
// --- Visuals (Draw Risk/Reward Zones) ---
var box riskBox = na
var box rewardBox = na
if barstate.islast and entryPrice != 0
box.delete(riskBox[1])
box.delete(rewardBox[1])
riskBg = color.new(color.red, 85)
rewardBg = color.new(color.green, 85)
// Draw the structural zones extending slightly forward
riskBox := box.new(left=bar_index - 2, top=isLong ? entryPrice : slPrice, right=bar_index + 10, bottom=isLong ? slPrice : entryPrice, border_color=color.red, bgcolor=riskBg)
rewardBox := box.new(left=bar_index - 2, top=isLong ? tpPrice : entryPrice, right=bar_index + 10, bottom=isLong ? entryPrice : tpPrice, border_color=color.green, bgcolor=rewardBg)
// --- Dashboard ---
isAcceptable = spreadRatio <= maxRatio
statusBg = isAcceptable ? color.new(color.teal, 85) : color.new(color.maroon, 85)
statusText = isAcceptable ? color.teal : color.red
headerBg = color.new(color.gray, 85)
var pos = tablePos == "Top Right" ? position.top_right : tablePos == "Top Left" ? position.top_left : tablePos == "Bottom Right" ? position.bottom_right : position.bottom_left
var table dash = table.new(pos, 2, 6, border_width=1, border_color=color.new(color.gray, 80))
if barstate.islast and entryPrice != 0
table.cell(dash, 0, 0, "Metric", text_color=color.gray, bgcolor=headerBg, text_halign=text.align_left)
table.cell(dash, 1, 0, "Value", text_color=color.gray, bgcolor=headerBg, text_halign=text.align_right)
table.cell(dash, 0, 1, "Nominal R:R", text_color=color.gray, bgcolor=color.new(color.black, 90), text_halign=text.align_left)
table.cell(dash, 1, 1, "1 : " + str.tostring(nominalRR, "#.##"), text_color=color.gray, bgcolor=color.new(color.black, 90), text_halign=text.align_right)
table.cell(dash, 0, 2, "Effective R:R", text_color=color.white, bgcolor=statusBg, text_halign=text.align_left)
table.cell(dash, 1, 2, "1 : " + str.tostring(effRR, "#.##"), text_color=color.white, bgcolor=statusBg, text_halign=text.align_right)
table.cell(dash, 0, 3, "Spread Cost", text_color=color.white, bgcolor=statusBg, text_halign=text.align_left)
table.cell(dash, 1, 3, str.tostring(spreadRatio, "#.#") + "%", text_color=statusText, bgcolor=statusBg, text_halign=text.align_right)
table.cell(dash, 0, 4, "Req. Win Rate (Nominal)", text_color=color.gray, bgcolor=color.new(color.black, 90), text_halign=text.align_left)
table.cell(dash, 1, 4, str.tostring(reqWinRateNominal, "#.#") + "%", text_color=color.gray, bgcolor=color.new(color.black, 90), text_halign=text.align_right)
table.cell(dash, 0, 5, "Req. Win Rate (Actual)", text_color=color.white, bgcolor=statusBg, text_halign=text.align_left)
table.cell(dash, 1, 5, str.tostring(reqWinRateEff, "#.#") + "%", text_color=color.white, bgcolor=statusBg, text_halign=text.align_right)