From 6c9b39e743e52c0938967e094e582ede9f2ca2bc Mon Sep 17 00:00:00 2001 From: Moshood Adejare Date: Sat, 15 Nov 2025 21:06:56 -0500 Subject: [PATCH 1/6] start --- .../order-block-smart-money-strategy.pine | 246 ++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 projects/order-block-smart-money-strategy.pine diff --git a/projects/order-block-smart-money-strategy.pine b/projects/order-block-smart-money-strategy.pine new file mode 100644 index 0000000..2d0c104 --- /dev/null +++ b/projects/order-block-smart-money-strategy.pine @@ -0,0 +1,246 @@ +//@version=6 +strategy("Order Block Trading Strategy - Smart Money Concepts", overlay=true, margin_long=100, margin_short=100, default_qty_type=strategy.percent_of_equity, default_qty_value=10) + +// ============================================================================ +// ORDER BLOCK TRADING STRATEGY - SMART MONEY CONCEPTS +// ============================================================================ +// This strategy identifies institutional order blocks and trades reversals +// when price returns to these zones. Based on ICT (Inner Circle Trader) concepts. +// +// Simplified approach: +// - Bullish Order Block: Strong bearish candle followed by reversal upward +// - Bearish Order Block: Strong bullish candle followed by reversal downward +// - Entry: When price retests the order block zone with confirmation +// ============================================================================ + +// === INPUTS === +// Order Block Detection +swingLength = input.int(5, "Swing Detection Length", minval=2, maxval=20, tooltip="Length for detecting swing highs and lows") +minCandleSize = input.float(0.5, "Minimum Candle Body Size (%)", minval=0.1, maxval=3.0, step=0.1, tooltip="Minimum candle body size as % of price") +useVolumeFilter = input.bool(false, "Use Volume Filter", tooltip="Only consider blocks with above-average volume") + +// Entry Settings +riskRewardRatio = input.float(2.0, "Risk:Reward Ratio", minval=1.0, maxval=5.0, step=0.5, tooltip="Target profit as multiple of risk") +stopLossATRMultiplier = input.float(1.5, "Stop Loss (ATR Multiple)", minval=0.5, maxval=5.0, step=0.5, tooltip="Stop loss distance in ATR multiples") + +// Visual Settings +showBullishZones = input.bool(true, "Show Bullish Order Blocks", group="Display") +showBearishZones = input.bool(true, "Show Bearish Order Blocks", group="Display") +showLabels = input.bool(true, "Show Entry Labels", group="Display") +bullishColor = input.color(color.new(color.green, 80), "Bullish Zone Color", group="Display") +bearishColor = input.color(color.new(color.red, 80), "Bearish Zone Color", group="Display") + +// === CALCULATIONS === + +// ATR for stop loss +atr = ta.atr(14) + +// Volume filter +avgVol = ta.sma(volume, 20) +volumeCondition = not useVolumeFilter or volume > avgVol + +// Detect swing points +swingHigh = ta.pivothigh(high, swingLength, swingLength) +swingLow = ta.pivotlow(low, swingLength, swingLength) + +// Calculate candle properties +candleBody = math.abs(close - open) +candleRange = high - low +bodyPercent = candleRange > 0 ? (candleBody / candleRange) * 100 : 0 +isBullish = close > open +isBearish = close < open +strongCandle = (candleBody / close * 100) >= minCandleSize + +// === ORDER BLOCK STORAGE === +var float bullishOB_high = na +var float bullishOB_low = na +var int bullishOB_bar = na +var bool bullishOB_active = false + +var float bearishOB_high = na +var float bearishOB_low = na +var int bearishOB_bar = na +var bool bearishOB_active = false + +// === DETECT BULLISH ORDER BLOCK === +// Look for swing low with strong bearish candle +if not na(swingLow) + // Find strong bearish candle before the swing low + lookbackStart = swingLength + 1 + lookbackEnd = swingLength + 10 + + for i = lookbackStart to lookbackEnd + if isBearish[i] and strongCandle[i] and volumeCondition[i] + // This is our bullish order block (last bearish push before reversal) + bullishOB_high := high[i] + bullishOB_low := low[i] + bullishOB_bar := bar_index - i + bullishOB_active := true + + if showBullishZones + box.new(left=bar_index - i, top=bullishOB_high, right=bar_index + 20, bottom=bullishOB_low, border_color=color.new(color.green, 60), bgcolor=bullishColor, extend=extend.right) + label.new(x=bar_index - i, y=bullishOB_low, text="Bullish OB", style=label.style_label_up, color=color.new(color.green, 50), textcolor=color.white, size=size.small) + break + +// === DETECT BEARISH ORDER BLOCK === +// Look for swing high with strong bullish candle +if not na(swingHigh) + // Find strong bullish candle before the swing high + lookbackStart = swingLength + 1 + lookbackEnd = swingLength + 10 + + for i = lookbackStart to lookbackEnd + if isBullish[i] and strongCandle[i] and volumeCondition[i] + // This is our bearish order block (last bullish push before reversal) + bearishOB_high := high[i] + bearishOB_low := low[i] + bearishOB_bar := bar_index - i + bearishOB_active := true + + if showBearishZones + box.new(left=bar_index - i, top=bearishOB_high, right=bar_index + 20, bottom=bearishOB_low, border_color=color.new(color.red, 60), bgcolor=bearishColor, extend=extend.right) + label.new(x=bar_index - i, y=bearishOB_high, text="Bearish OB", style=label.style_label_down, color=color.new(color.red, 50), textcolor=color.white, size=size.small) + break + +// === CHECK FOR RETEST === + +// Price is retesting bullish order block +inBullishOB = false +if bullishOB_active and not na(bullishOB_high) and not na(bullishOB_low) + // Check if current price is touching the order block + if low <= bullishOB_high and high >= bullishOB_low + inBullishOB := true + // Deactivate if price breaks below (order block failed) + if close < bullishOB_low - atr + bullishOB_active := false + +// Price is retesting bearish order block +inBearishOB = false +if bearishOB_active and not na(bearishOB_high) and not na(bearishOB_low) + // Check if current price is touching the order block + if low <= bearishOB_high and high >= bearishOB_low + inBearishOB := true + // Deactivate if price breaks above (order block failed) + if close > bearishOB_high + atr + bearishOB_active := false + +// === ENTRY CONDITIONS === + +// Bullish entry: Price retests bullish OB and shows bullish momentum +bullishEntry = inBullishOB and isBullish and close > open and volumeCondition + +// Bearish entry: Price retests bearish OB and shows bearish momentum +bearishEntry = inBearishOB and isBearish and close < open and volumeCondition + +// === RISK MANAGEMENT === + +var float stopLoss = na +var float takeProfit = na + +// Long trade setup +if bullishEntry and strategy.position_size == 0 + stopLoss := close - (atr * stopLossATRMultiplier) + riskDistance = close - stopLoss + takeProfit := close + (riskDistance * riskRewardRatio) + + strategy.entry("Long", strategy.long) + strategy.exit("Exit Long", "Long", stop=stopLoss, limit=takeProfit) + + if showLabels + label.new(x=bar_index, y=low, text="LONG\nEntry: " + str.tostring(close, "#.##") + "\nSL: " + str.tostring(stopLoss, "#.##") + "\nTP: " + str.tostring(takeProfit, "#.##"), style=label.style_label_up, color=color.new(color.green, 20), textcolor=color.white, size=size.normal) + + // Deactivate order block after entry + bullishOB_active := false + +// Short trade setup +if bearishEntry and strategy.position_size == 0 + stopLoss := close + (atr * stopLossATRMultiplier) + riskDistance = stopLoss - close + takeProfit := close - (riskDistance * riskRewardRatio) + + strategy.entry("Short", strategy.short) + strategy.exit("Exit Short", "Short", stop=stopLoss, limit=takeProfit) + + if showLabels + label.new(x=bar_index, y=high, text="SHORT\nEntry: " + str.tostring(close, "#.##") + "\nSL: " + str.tostring(stopLoss, "#.##") + "\nTP: " + str.tostring(takeProfit, "#.##"), style=label.style_label_down, color=color.new(color.red, 20), textcolor=color.white, size=size.normal) + + // Deactivate order block after entry + bearishOB_active := false + +// === VISUAL PLOTS === + +// Plot stop loss and take profit +plot(strategy.position_size != 0 ? stopLoss : na, "Stop Loss", color.red, 2, plot.style_linebr) +plot(strategy.position_size != 0 ? takeProfit : na, "Take Profit", color.green, 2, plot.style_linebr) + +// Plot entry signals +plotshape(bullishEntry and strategy.position_size == 0, "Long Signal", shape.triangleup, location.belowbar, color.new(color.green, 0), size=size.small) +plotshape(bearishEntry and strategy.position_size == 0, "Short Signal", shape.triangledown, location.abovebar, color.new(color.red, 0), size=size.small) + +// Highlight active order blocks +bgcolor(inBullishOB and bullishOB_active ? color.new(color.green, 95) : na, title="In Bullish OB") +bgcolor(inBearishOB and bearishOB_active ? color.new(color.red, 95) : na, title="In Bearish OB") + +// === PERFORMANCE METRICS TABLE === + +var table statsTable = table.new(position.top_right, 2, 9, bgcolor=color.new(color.black, 85), frame_color=color.gray, frame_width=1, border_color=color.gray, border_width=1) + +if barstate.islast + // Calculate statistics + totalTrades = strategy.closedtrades + winningTrades = 0 + losingTrades = 0 + totalProfit = 0.0 + totalLoss = 0.0 + + for i = 0 to totalTrades - 1 + tradeProfit = strategy.closedtrades.profit(i) + if tradeProfit > 0 + winningTrades += 1 + totalProfit += tradeProfit + else + losingTrades += 1 + totalLoss += math.abs(tradeProfit) + + winRate = totalTrades > 0 ? winningTrades / totalTrades * 100 : 0 + avgWin = winningTrades > 0 ? totalProfit / winningTrades : 0 + avgLoss = losingTrades > 0 ? totalLoss / losingTrades : 0 + profitFactor = totalLoss > 0 ? totalProfit / totalLoss : 0 + netProfit = strategy.netprofit + + // Table headers + table.cell(statsTable, 0, 0, "šŸ“Š Order Block Stats", text_color=color.white, text_size=size.normal, bgcolor=color.new(color.blue, 70)) + table.merge_cells(statsTable, 0, 0, 1, 0) + + // Metrics + table.cell(statsTable, 0, 1, "Total Trades", text_color=color.gray, text_size=size.small) + table.cell(statsTable, 1, 1, str.tostring(totalTrades), text_color=color.white, text_size=size.small) + + table.cell(statsTable, 0, 2, "Winning", text_color=color.gray, text_size=size.small) + table.cell(statsTable, 1, 2, str.tostring(winningTrades), text_color=color.green, text_size=size.small) + + table.cell(statsTable, 0, 3, "Losing", text_color=color.gray, text_size=size.small) + table.cell(statsTable, 1, 3, str.tostring(losingTrades), text_color=color.red, text_size=size.small) + + table.cell(statsTable, 0, 4, "Win Rate", text_color=color.gray, text_size=size.small) + winColor = winRate >= 50 ? color.green : color.orange + table.cell(statsTable, 1, 4, str.tostring(winRate, "#.#") + "%", text_color=winColor, text_size=size.small) + + table.cell(statsTable, 0, 5, "Profit Factor", text_color=color.gray, text_size=size.small) + pfColor = profitFactor >= 1.5 ? color.green : profitFactor >= 1 ? color.yellow : color.red + table.cell(statsTable, 1, 5, str.tostring(profitFactor, "#.##"), text_color=pfColor, text_size=size.small) + + table.cell(statsTable, 0, 6, "Net Profit", text_color=color.gray, text_size=size.small) + npColor = netProfit > 0 ? color.green : color.red + table.cell(statsTable, 1, 6, str.tostring(netProfit, "#.##"), text_color=npColor, text_size=size.small) + + table.cell(statsTable, 0, 7, "Avg Win", text_color=color.gray, text_size=size.small) + table.cell(statsTable, 1, 7, str.tostring(avgWin, "#.##"), text_color=color.green, text_size=size.small) + + table.cell(statsTable, 0, 8, "Avg Loss", text_color=color.gray, text_size=size.small) + table.cell(statsTable, 1, 8, str.tostring(avgLoss, "#.##"), text_color=color.red, text_size=size.small) + +// === ALERTS === + +alertcondition(bullishEntry, "Long Entry", "Order Block - Long Entry Signal") +alertcondition(bearishEntry, "Short Entry", "Order Block - Short Entry Signal") From f8f7b663976044df5fb0d240dcbe3ba241a6fad7 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 18 Nov 2025 19:39:41 +0000 Subject: [PATCH 2/6] Add Order Block Trading Signals indicator This indicator provides automated trading signals based on smart money order blocks and market structure analysis. Key features include: - Market structure detection (BOS/CHoCH) - Volumetric order block identification - Automated entry signals with TP/SL levels - Risk:Reward ratio calculation - Real-time signal status tracking - Comprehensive alert system - Customizable visual elements Entry signals are generated when price returns to unmitigated order blocks aligned with the current market structure trend. --- projects/orderblock-trading-signals.pine | 574 +++++++++++++++++++++++ 1 file changed, 574 insertions(+) create mode 100644 projects/orderblock-trading-signals.pine diff --git a/projects/orderblock-trading-signals.pine b/projects/orderblock-trading-signals.pine new file mode 100644 index 0000000..2df6cb8 --- /dev/null +++ b/projects/orderblock-trading-signals.pine @@ -0,0 +1,574 @@ +//@version=6 +indicator("Order Block Trading Signals", "OB Signals", overlay=true, max_boxes_count=500, max_lines_count=500, max_labels_count=500) + +// ════════════════════════════════════════════════════════════════════════════════ +// INPUTS +// ════════════════════════════════════════════════════════════════════════════════ + +// Market Structure Settings +swingLength = input.int(5, "Swing Length", minval=2, maxval=50, group="Market Structure", + tooltip="Length for pivot high/low detection. Lower = more sensitive, Higher = major swings only") +showStructure = input.bool(true, "Show BOS/CHoCH Labels", group="Market Structure", + tooltip="Display Break of Structure and Change of Character labels on chart") +structUpColor = input.color(color.new(#089981, 0), "Bullish", inline="struct", group="Market Structure") +structDnColor = input.color(color.new(#f23645, 0), "Bearish", inline="struct", group="Market Structure") + +// Order Block Settings +obShowCount = input.int(3, "Show Last N Order Blocks", minval=0, maxval=10, group="Order Blocks", + tooltip="Number of recent order blocks to display (0 to hide all)") +obConstructionMode = input.string("Length", "Construction Method", options=["Length", "Full"], group="Order Blocks", + tooltip="Length: Use ATR-based sizing | Full: Use entire candle body") +obAtrLength = input.int(5, "ATR Length", minval=1, maxval=50, group="Order Blocks") +obBullColor = input.color(color.new(#089981, 85), "Bullish OB", inline="obcol", group="Order Blocks") +obBearColor = input.color(color.new(#f23645, 85), "Bearish OB", inline="obcol", group="Order Blocks") +obMitigatedColor = input.color(color.new(color.gray, 90), "Mitigated", group="Order Blocks") +obExtend = input.bool(false, "Extend Order Blocks", group="Order Blocks") + +// Entry Signal Settings +entryMethod = input.string("Close", "Entry Detection Method", options=["Close", "Wick", "50% Penetration"], group="Entry Signals", + tooltip="Close: Candle close in OB | Wick: Any touch | 50%: Price reaches OB midpoint") +showEntryLabels = input.bool(true, "Show Entry Labels", group="Entry Signals") +showTPSL = input.bool(true, "Show TP/SL Lines", group="Entry Signals") +extendTPSL = input.bool(true, "Extend TP/SL Lines", group="Entry Signals") +tpColor = input.color(color.new(#089981, 0), "TP Color", inline="tpsl", group="Entry Signals") +slColor = input.color(color.new(#f23645, 0), "SL Color", inline="tpsl", group="Entry Signals") +defaultRR = input.float(2.0, "Default Risk:Reward", minval=1.0, maxval=10.0, step=0.5, group="Entry Signals", + tooltip="Used when no structure level found for TP") + +// Alert Settings +enableAlerts = input.bool(true, "Enable Alerts", group="Alerts") + +// Debug Settings +showDebugPlots = input.bool(false, "Show Debug Plots", group="Debug", + tooltip="Show debugging information in Data Window") + +// ════════════════════════════════════════════════════════════════════════════════ +// TYPE DEFINITIONS +// ════════════════════════════════════════════════════════════════════════════════ + +type OrderBlock + float top + float bottom + float mid + int location + bool isBullish + bool isMitigated + int mitigatedBar + box displayBox + +type SwingPoint + float price + int barIndex + bool isHigh + +type MarketStructure + int trend // 1 = bullish, -1 = bearish, 0 = neutral + float lastHighBreak + float lastLowBreak + int lastBreakBar + string lastBreakType // "BOS" or "CHoCH" + SwingPoint lastHigh + SwingPoint lastLow + +type TradeSignal + bool isActive + bool isBullish + float entryPrice + float tpPrice + float slPrice + int entryBar + string status // "active", "tp_hit", "sl_hit" + label entryLabel + line tpLine + line slLine + box obBox + +// ════════════════════════════════════════════════════════════════════════════════ +// GLOBAL VARIABLES +// ════════════════════════════════════════════════════════════════════════════════ + +var MarketStructure ms = MarketStructure.new( + trend=0, + lastHighBreak=na, + lastLowBreak=na, + lastBreakBar=na, + lastBreakType=na, + lastHigh=SwingPoint.new(na, na, true), + lastLow=SwingPoint.new(na, na, false)) + +var OrderBlock[] bullishOBs = array.new() +var OrderBlock[] bearishOBs = array.new() + +var TradeSignal activeSignal = TradeSignal.new( + isActive=false, + isBullish=na, + entryPrice=na, + tpPrice=na, + slPrice=na, + entryBar=na, + status="inactive", + entryLabel=na, + tpLine=na, + slLine=na, + obBox=na) + +var label[] structLabels = array.new