Strategy · Pine Script v6 · On the chart

Daily Bias + FVG Strategy

by TradersPost· code credited to Based

This overlay strategy plots previous-day high and low, the daily open, and fair value gap zones on the price chart.

View on GitHub

Repaints

GitHub stars218on the repository
Pine versionv6current
Lines of code385
Settings21inputs
LicenceNone statedfile: MPL-2.0
Last update3 months ago23 Jul 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new strategy, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.

Source Code

385 lines of Pine Script v6 from projects/daily-bias-fvg-strategy.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

daily-bias-fvg-strategy.pine
// built with PineScript Agents by TradersPost
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Based on "The Ultimate Daily Bias Trading Strategy" by Lewis Kelly

//@version=6
//@strategy_alert_message {{strategy.order.alert_message}}
strategy("Daily Bias + FVG Strategy", overlay=true, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=2, commission_type=strategy.commission.percent, commission_value=0.1, slippage=1)

// ============================================================================
// INPUT SETTINGS
// ============================================================================

// Daily Bias Settings
grpBias = "Daily Bias Settings"
showDailyLevels = input.bool(true, "Show Previous Day High/Low", group=grpBias, tooltip="Display previous day's high and low levels")
showDailyOpen = input.bool(true, "Show Daily Open", group=grpBias, tooltip="Display current day's opening price")
biasLookback = input.int(1, "Lookback Days for Bias", minval=1, maxval=5, group=grpBias, tooltip="Number of days to look back for bias determination")

// Fair Value Gap Settings
grpFVG = "Fair Value Gap (FVG) Settings"
showFVG = input.bool(true, "Show Fair Value Gaps", group=grpFVG, tooltip="Display FVG zones on chart")
fvgMinSize = input.float(0.0001, "Minimum FVG Size", minval=0, step=0.0001, group=grpFVG, tooltip="Minimum gap size to qualify as FVG (in price)")
fvgMaxAge = input.int(50, "Max FVG Age (bars)", minval=10, maxval=200, group=grpFVG, tooltip="Maximum age of FVG before it expires")
mitigateFVG = input.bool(true, "Mitigate FVG on Touch", group=grpFVG, tooltip="Remove FVG when price touches it")

// Entry Settings
grpEntry = "Entry Settings"
entryTimeframe = input.timeframe("60", "Entry Timeframe", group=grpEntry, tooltip="Timeframe for entry signals (default: 1H)")
requireFVGEntry = input.bool(true, "Require FVG for Entry", group=grpEntry, tooltip="Only enter when price is in an FVG zone")
sessionFilter = input.bool(true, "Use Session Filter", group=grpEntry, tooltip="Only trade during active sessions")
sessionStart = input.session("0800-1600", "Trading Session", group=grpEntry, tooltip="Time window for taking trades")

// Risk Management
grpRisk = "Risk Management"
riskRewardRatio = input.float(5.0, "Risk:Reward Ratio", minval=1.0, maxval=10.0, step=0.5, group=grpRisk, tooltip="Target R:R ratio (1:5 = 5.0)")
useATRStop = input.bool(true, "Use ATR for Stop Loss", group=grpRisk, tooltip="Use ATR-based stop loss instead of fixed")
atrLength = input.int(14, "ATR Length", minval=5, maxval=50, group=grpRisk, tooltip="ATR period for stop loss calculation")
atrMultiplier = input.float(1.5, "ATR Multiplier", minval=0.5, maxval=5.0, step=0.1, group=grpRisk, tooltip="ATR multiplier for stop distance")
fixedStopPips = input.float(20.0, "Fixed Stop (pips)", minval=5, maxval=100, group=grpRisk, tooltip="Fixed stop loss in pips (if ATR disabled)")

// Visual Settings
grpVisual = "Visual Settings"
bullColor = input.color(color.new(color.green, 70), "Bullish Color", group=grpVisual)
bearColor = input.color(color.new(color.red, 70), "Bearish Color", group=grpVisual)
showLabels = input.bool(true, "Show Signal Labels", group=grpVisual)
showStats = input.bool(true, "Show Statistics Table", group=grpVisual)

// Debug Settings
grpDebug = "Debug Settings"
debugMode = input.bool(false, "Enable Debug Mode", group=grpDebug, tooltip="Show additional debug information")

// ============================================================================
// DAILY BIAS CALCULATION
// ============================================================================

// Get daily timeframe data
[dailyOpen, dailyHigh, dailyLow, dailyClose] = request.security(syminfo.tickerid, "D", [open, high, low, close], lookahead=barmerge.lookahead_on)
[prevDayHigh, prevDayLow, prevDayClose, prevDayOpen] = request.security(syminfo.tickerid, "D", [high[1], low[1], close[1], open[1]], lookahead=barmerge.lookahead_on)

// Calculate daily bias based on "One Candle Rule"
// Bullish: Previous candle wicked below prior low but closed inside range (bullish rejection)
// Bearish: Previous candle wicked above prior high but closed inside range (bearish rejection)

// Get data from 2 days ago for comparison
[twoDaysAgoHigh, twoDaysAgoLow] = request.security(syminfo.tickerid, "D", [high[2], low[2]], lookahead=barmerge.lookahead_on)

// Bullish bias conditions:
// 1. Yesterday's low went below 2-days-ago low (liquidity grab)
// 2. Yesterday closed above 2-days-ago low (rejection)
// 3. Yesterday closed in upper portion of its range
bullishWick = prevDayLow < twoDaysAgoLow
bullishClose = prevDayClose > twoDaysAgoLow
bullishCandleStructure = prevDayClose > prevDayOpen or (prevDayClose > (prevDayHigh + prevDayLow) / 2)
bullishBias = bullishWick and bullishClose and bullishCandleStructure

// Bearish bias conditions:
// 1. Yesterday's high went above 2-days-ago high (liquidity grab)
// 2. Yesterday closed below 2-days-ago high (rejection)
// 3. Yesterday closed in lower portion of its range
bearishWick = prevDayHigh > twoDaysAgoHigh
bearishClose = prevDayClose < twoDaysAgoHigh
bearishCandleStructure = prevDayClose < prevDayOpen or (prevDayClose < (prevDayHigh + prevDayLow) / 2)
bearishBias = bearishWick and bearishClose and bearishCandleStructure

// Track bias state
var int currentBias = 0  // 1 = bullish, -1 = bearish, 0 = neutral
if bullishBias
    currentBias := 1
else if bearishBias
    currentBias := -1

// ============================================================================
// FAIR VALUE GAP DETECTION
// ============================================================================

// FVG Types for tracking
type FVGZone
    float top
    float bottom
    int startBar
    bool isBullish
    bool isActive

// Arrays to store FVG zones
var array<FVGZone> bullishFVGs = array.new<FVGZone>()
var array<FVGZone> bearishFVGs = array.new<FVGZone>()

// Detect Bullish FVG: Gap between candle[2] high and candle[0] low
bullishFVGCondition = low > high[2] and (low - high[2]) >= fvgMinSize
if bullishFVGCondition and showFVG
    newFVG = FVGZone.new(low, high[2], bar_index, true, true)
    array.push(bullishFVGs, newFVG)

// Detect Bearish FVG: Gap between candle[2] low and candle[0] high
bearishFVGCondition = high < low[2] and (low[2] - high) >= fvgMinSize
if bearishFVGCondition and showFVG
    newFVG = FVGZone.new(low[2], high, bar_index, false, true)
    array.push(bearishFVGs, newFVG)

// Function to check if price is in any bullish FVG
isInBullishFVG() =>
    result = false
    if array.size(bullishFVGs) > 0
        for i = array.size(bullishFVGs) - 1 to 0
            fvg = array.get(bullishFVGs, i)
            if fvg.isActive and low <= fvg.top and high >= fvg.bottom
                result := true
                break
    result

// Function to check if price is in any bearish FVG
isInBearishFVG() =>
    result = false
    if array.size(bearishFVGs) > 0
        for i = array.size(bearishFVGs) - 1 to 0
            fvg = array.get(bearishFVGs, i)
            if fvg.isActive and high >= fvg.bottom and low <= fvg.top
                result := true
                break
    result

// Mitigate (deactivate) FVGs when price fills them
if mitigateFVG
    // Mitigate bullish FVGs
    if array.size(bullishFVGs) > 0
        for i = array.size(bullishFVGs) - 1 to 0
            fvg = array.get(bullishFVGs, i)
            if fvg.isActive
                // Mitigate if price trades through the zone
                if low <= fvg.bottom
                    fvg.isActive := false
                // Expire old FVGs
                if bar_index - fvg.startBar > fvgMaxAge
                    fvg.isActive := false

    // Mitigate bearish FVGs
    if array.size(bearishFVGs) > 0
        for i = array.size(bearishFVGs) - 1 to 0
            fvg = array.get(bearishFVGs, i)
            if fvg.isActive
                // Mitigate if price trades through the zone
                if high >= fvg.top
                    fvg.isActive := false
                // Expire old FVGs
                if bar_index - fvg.startBar > fvgMaxAge
                    fvg.isActive := false

// Clean up old FVGs to prevent array bloat
if array.size(bullishFVGs) > 100
    array.shift(bullishFVGs)
if array.size(bearishFVGs) > 100
    array.shift(bearishFVGs)

// ============================================================================
// SESSION FILTER
// ============================================================================

inSession = not sessionFilter or not na(time(timeframe.period, sessionStart))

// ============================================================================
// ENTRY CONDITIONS
// ============================================================================

// ATR for stop loss calculation
atr = ta.atr(atrLength)

// Power of Three concept:
// After daily bias is established, wait for manipulation (move against bias)
// Then enter on pullback to FVG in direction of bias

// Track if we've seen manipulation today
var bool manipulationSeen = false
var float manipulationHigh = na
var float manipulationLow = na

// Reset manipulation tracking on new day
if ta.change(time("D"))
    manipulationSeen := false
    manipulationHigh := na
    manipulationLow := na

// Detect manipulation (price moving against bias from daily open)
if currentBias == 1 and not manipulationSeen
    // For bullish bias, manipulation is a move below daily open
    if low < dailyOpen
        manipulationSeen := true
        manipulationLow := low

if currentBias == -1 and not manipulationSeen
    // For bearish bias, manipulation is a move above daily open
    if high > dailyOpen
        manipulationSeen := true
        manipulationHigh := high

// Entry conditions
priceInBullishFVG = isInBullishFVG()
priceInBearishFVG = isInBearishFVG()

// Long entry: Bullish bias + manipulation seen + price in bullish FVG (or FVG not required)
longCondition = currentBias == 1 and manipulationSeen and inSession and (not requireFVGEntry or priceInBullishFVG)

// Short entry: Bearish bias + manipulation seen + price in bearish FVG (or FVG not required)
shortCondition = currentBias == -1 and manipulationSeen and inSession and (not requireFVGEntry or priceInBearishFVG)

// ============================================================================
// STOP LOSS AND TAKE PROFIT CALCULATION
// ============================================================================

// Calculate stop loss distance
stopDistance = useATRStop ? atr * atrMultiplier : fixedStopPips * syminfo.mintick * 10

// Long trade levels
longStopLoss = low - stopDistance
longTakeProfit = close + (stopDistance * riskRewardRatio)

// Short trade levels
shortStopLoss = high + stopDistance
shortTakeProfit = close - (stopDistance * riskRewardRatio)

// ============================================================================
// STRATEGY EXECUTION
// ============================================================================

// Track if we have an open position
var bool inLongTrade = false
var bool inShortTrade = false

// Entry logic
if longCondition and not inLongTrade and not inShortTrade
    strategy.entry("Long", strategy.long)
    strategy.exit("Long Exit", "Long", stop=longStopLoss, limit=longTakeProfit)
    inLongTrade := true

if shortCondition and not inShortTrade and not inLongTrade
    strategy.entry("Short", strategy.short)
    strategy.exit("Short Exit", "Short", stop=shortStopLoss, limit=shortTakeProfit)
    inShortTrade := true

// Reset position tracking when trade closes
if strategy.position_size == 0
    inLongTrade := false
    inShortTrade := false

// ============================================================================
// VISUAL ELEMENTS
// ============================================================================

// Plot previous day levels
plot(showDailyLevels ? prevDayHigh : na, "Prev Day High", color=color.new(color.red, 50), style=plot.style_linebr, linewidth=1)
plot(showDailyLevels ? prevDayLow : na, "Prev Day Low", color=color.new(color.green, 50), style=plot.style_linebr, linewidth=1)
plot(showDailyOpen ? dailyOpen : na, "Daily Open", color=color.new(color.orange, 50), style=plot.style_linebr, linewidth=1)

// Background color for bias
biasColor = currentBias == 1 ? color.new(color.green, 95) : currentBias == -1 ? color.new(color.red, 95) : na
bgcolor(biasColor, title="Bias Background")

// Draw FVG boxes
var array<box> fvgBoxes = array.new<box>()

// Limit box drawing to prevent clutter
if barstate.islast and showFVG
    // Clear old boxes
    for i = array.size(fvgBoxes) - 1 to 0
        box.delete(array.get(fvgBoxes, i))
    array.clear(fvgBoxes)

    // Draw active bullish FVGs
    if array.size(bullishFVGs) > 0
        for i = math.max(0, array.size(bullishFVGs) - 10) to array.size(bullishFVGs) - 1
            fvg = array.get(bullishFVGs, i)
            if fvg.isActive
                b = box.new(fvg.startBar, fvg.top, bar_index, fvg.bottom, bgcolor=bullColor, border_color=color.green, border_width=1)
                array.push(fvgBoxes, b)

    // Draw active bearish FVGs
    if array.size(bearishFVGs) > 0
        for i = math.max(0, array.size(bearishFVGs) - 10) to array.size(bearishFVGs) - 1
            fvg = array.get(bearishFVGs, i)
            if fvg.isActive
                b = box.new(fvg.startBar, fvg.top, bar_index, fvg.bottom, bgcolor=bearColor, border_color=color.red, border_width=1)
                array.push(fvgBoxes, b)

// Signal labels
if showLabels and longCondition and not inLongTrade[1]
    label.new(bar_index, low, "LONG\nBias: Bullish\nFVG Entry", style=label.style_label_up, color=color.green, textcolor=color.white, size=size.small)

if showLabels and shortCondition and not inShortTrade[1]
    label.new(bar_index, high, "SHORT\nBias: Bearish\nFVG Entry", style=label.style_label_down, color=color.red, textcolor=color.white, size=size.small)

// ============================================================================
// STATISTICS TABLE
// ============================================================================

if showStats and barstate.islast
    var table statsTable = table.new(position.top_right, 2, 8, bgcolor=color.new(color.black, 80), border_width=1)

    // Headers
    table.cell(statsTable, 0, 0, "Daily Bias Strategy", text_color=color.white, text_size=size.normal, bgcolor=color.new(color.blue, 70), text_halign=text.align_center)
    table.merge_cells(statsTable, 0, 0, 1, 0)

    // Current bias
    biasText = currentBias == 1 ? "BULLISH" : currentBias == -1 ? "BEARISH" : "NEUTRAL"
    biasTextColor = currentBias == 1 ? color.green : currentBias == -1 ? color.red : color.gray
    table.cell(statsTable, 0, 1, "Current Bias:", text_color=color.white, text_size=size.small)
    table.cell(statsTable, 1, 1, biasText, text_color=biasTextColor, text_size=size.small)

    // Manipulation status
    manipText = manipulationSeen ? "YES" : "NO"
    manipColor = manipulationSeen ? color.green : color.orange
    table.cell(statsTable, 0, 2, "Manipulation:", text_color=color.white, text_size=size.small)
    table.cell(statsTable, 1, 2, manipText, text_color=manipColor, text_size=size.small)

    // Active FVGs
    activeBullFVG = 0
    activeBearFVG = 0
    if array.size(bullishFVGs) > 0
        for i = 0 to array.size(bullishFVGs) - 1
            if array.get(bullishFVGs, i).isActive
                activeBullFVG += 1
    if array.size(bearishFVGs) > 0
        for i = 0 to array.size(bearishFVGs) - 1
            if array.get(bearishFVGs, i).isActive
                activeBearFVG += 1

    table.cell(statsTable, 0, 3, "Bull FVGs:", text_color=color.white, text_size=size.small)
    table.cell(statsTable, 1, 3, str.tostring(activeBullFVG), text_color=color.green, text_size=size.small)

    table.cell(statsTable, 0, 4, "Bear FVGs:", text_color=color.white, text_size=size.small)
    table.cell(statsTable, 1, 4, str.tostring(activeBearFVG), text_color=color.red, text_size=size.small)

    // Session status
    sessionText = inSession ? "ACTIVE" : "CLOSED"
    sessionColor = inSession ? color.green : color.gray
    table.cell(statsTable, 0, 5, "Session:", text_color=color.white, text_size=size.small)
    table.cell(statsTable, 1, 5, sessionText, text_color=sessionColor, text_size=size.small)

    // Strategy performance
    table.cell(statsTable, 0, 6, "Win Rate:", text_color=color.white, text_size=size.small)
    winRate = strategy.wintrades / math.max(strategy.closedtrades, 1) * 100
    table.cell(statsTable, 1, 6, str.tostring(winRate, "#.##") + "%", text_color=color.white, text_size=size.small)

    table.cell(statsTable, 0, 7, "Profit Factor:", text_color=color.white, text_size=size.small)
    pf = strategy.grossprofit / math.max(strategy.grossloss, 1)
    table.cell(statsTable, 1, 7, str.tostring(pf, "#.##"), text_color=color.white, text_size=size.small)

// ============================================================================
// DEBUG MODE
// ============================================================================

if debugMode
    // Plot debug info
    plotchar(bullishBias, "Bullish Bias Signal", "▲", location.bottom, color.green, size=size.tiny)
    plotchar(bearishBias, "Bearish Bias Signal", "▼", location.top, color.red, size=size.tiny)
    plotchar(manipulationSeen, "Manipulation", "M", location.abovebar, color.orange, size=size.tiny)
    plotchar(priceInBullishFVG, "In Bull FVG", "B", location.belowbar, color.green, size=size.tiny)
    plotchar(priceInBearishFVG, "In Bear FVG", "S", location.abovebar, color.red, size=size.tiny)

// ============================================================================
// ALERTS
// ============================================================================

alertcondition(longCondition and not inLongTrade[1], "Long Signal", "Daily Bias Strategy: LONG signal - Bullish bias with FVG entry")
alertcondition(shortCondition and not inShortTrade[1], "Short Signal", "Daily Bias Strategy: SHORT signal - Bearish bias with FVG entry")
alertcondition(bullishBias and not bullishBias[1], "Bullish Bias Detected", "Daily Bias: New BULLISH bias detected")
alertcondition(bearishBias and not bearishBias[1], "Bearish Bias Detected", "Daily Bias: New BEARISH bias detected")

Overview

Daily Bias + FVG Strategy takes entries on a selectable timeframe when the FVG requirement and an optional session window allow them, then uses an ATR or fixed pip stop and a target set by the risk-reward input. Lookback days, minimum gap size, gap age, and mitigation on touch change the bias and zones. Signal labels and a statistics table can be shown. Higher-timeframe data is read with lookahead.

Details

Published by

TradersPost on GitHub

Code credit

Based, as written in the script's header

Type

Strategy, Pine Script v6

Draws

On the price chart

Category

SMC / ICT / price action, Support & resistance, Sessions & time, Volatility & bands

Markets

Forex

Timeframes

M15-H1

Risk Notes

  • Reads higher-timeframe data with lookahead on, so the history can show signals that were not there in real time

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Show Previous Day High/LowbooltrueshowDailyLevels
Show Daily OpenbooltrueshowDailyOpen
Lookback Days for Biasint1biasLookback
Show Fair Value GapsbooltrueshowFVG
Minimum FVG Sizefloat0.0001fvgMinSize
Max FVG Age (bars)int50fvgMaxAge
Mitigate FVG on TouchbooltruemitigateFVG
Entry Timeframetimeframe60entryTimeframe
Require FVG for EntrybooltruerequireFVGEntry
Use Session FilterbooltruesessionFilter
Trading Sessionsession0800-1600sessionStart
Risk:Reward Ratiofloat5.0riskRewardRatio
Show all 21 settings
SettingTypeDefaultVariable
Use ATR for Stop LossbooltrueuseATRStop
ATR Lengthint14atrLength
ATR Multiplierfloat1.5atrMultiplier
Fixed Stop (pips)float20.0fixedStopPips
Bullish Colorcolorcolor.new(color.green, 70)bullColor
Bearish Colorcolorcolor.new(color.red, 70)bearColor
Show Signal LabelsbooltrueshowLabels
Show Statistics TablebooltrueshowStats
Enable Debug ModeboolfalsedebugMode
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

P404 Smoke

by Musyimi97
16 stars

P404 Smoke is a price-chart strategy that sequences an optional higher-timeframe EMA bias, a liquidity range from recent pivots, a sweep of buy-side or sell-side liquidity, and a market structure shift within a set bar window. Comments state it then looks for

Strategy v5 SMC / ICT / price actionSupport & resistance
Updated 6 months ago · MIT GitHub repository of P404 Smoke

NQ 9:45-10:15 ICT Strategy

by eddiebelaval
7 stars

This ICT-based strategy trades during the 9:45 AM to 10:15 AM New York session window. It calculates a daily bias using a 20-period daily EMA and tracks previous day highs and lows to identify liquidity sweeps. The script refines order block entry levels and m

Strategy v6 SMC / ICT / price actionSessions & time Repaints
Updated 3 months ago · None stated GitHub repository of NQ 9:45-10:15 ICT Strategy
6 stars

This strategy combines Opening Range Breakout (ORB) mechanics with Inner Circle Trader (ICT) concepts like Fair Value Gaps, Order Blocks, and liquidity grabs. It identifies session opening ranges and generates signals when price breaks out with supporting rela

Strategy v5 BreakoutSMC / ICT / price action
Updated 7 months ago · None stated GitHub repository of Advanced ORB + ICT Strategy

Institutional HFT Engine - QuantAlgo

by thesenegalesehitch
4 stars

This strategy evaluates trading opportunities using a probabilistic scoring model combined with Smart Money Concepts (SMC) pattern detection, including Break of Structure (BOS), Fair Value Gaps (FVG), and Order Blocks. It overlays signals directly on the price

Strategy v6 SMC / ICT / price actionSessions & time
Updated 4 months ago · Custom licence GitHub repository of Institutional HFT Engine - QuantAlgo

This indicator combines six trading tools into a single chart overlay to optimize indicator limits. It calculates Bollinger Bands, projects weekend price boundaries, plots market structure elements like order blocks, breaker blocks, and MSB lines, marks New Yo

Indicator v6 Support & resistanceSMC / ICT / price action Repaints

More strategys

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers