
The Opening Range Breakout with Fair Value Gap Integration Strategy is a quantitative trading approach that combines Opening Range Breakout (ORB) with Fair Value Gap (FVG) concepts from Smart Money Concepts (SMC). This strategy first defines a price range during the initial period of the trading day (typically the first 5 minutes after market open), then looks for trading signals when price breaks through this range boundary while intersecting with a Fair Value Gap. The strategy is designed for intraday trading within specific timeframes, particularly during regular trading hours in the US market, and incorporates risk management mechanisms to control exposure for each trade.
The core principles of this strategy are based on two key technical analysis concepts:
Opening Range Breakout (ORB) - The strategy first identifies the highest and lowest prices within a specific timeframe after market open (default is 5 minutes), forming a price range. This range is viewed as the initial judgment of market participants regarding the day’s price movement, and a breakout from this range may indicate the formation of a short-term trend.
Fair Value Gap (FVG) - An analytical method from Smart Money Concepts (SMC), a bullish FVG forms when the current high is lower than the low of the candle before the previous one, and a bearish FVG forms when the current low is higher than the high of the candle before the previous one. These gaps are considered areas where price may potentially return to fill, representing imbalances in market structure.
Trading signals are generated under the following conditions: - A long signal is triggered when a bullish FVG intersects with the upper ORB boundary (the previous candle’s opening price is below the ORB high, and its closing price is above the ORB high) - A short signal is triggered when a bearish FVG intersects with the lower ORB boundary (the previous candle’s opening price is above the ORB low, and its closing price is below the ORB low)
During trade execution, the strategy employs a risk-based position sizing method, calculating the specific position size for each trade based on the stop-loss distance to ensure consistent risk exposure. Stop-loss is set at the previous candle’s low for long trades or the previous candle’s high for short trades, while the profit target is based on a preset risk-reward ratio (default is 2.0). All open positions are automatically closed at the end of the trading session, ensuring no overnight exposure.
Integration of Multiple Technical Analysis Methods - By combining ORB and FVG technical analysis methods, the strategy can filter out false signals that might be generated by a single indicator, improving the quality of trading signals.
Clear Trading Timeframe - The strategy clearly defines the trading timeframe (signal period and trading period), helping traders focus on the most active market periods with the highest signal quality, avoiding ineffective trades during low-activity periods.
Risk-Based Position Sizing - The strategy uses a risk-based position calculation method, ensuring that each trade risks a consistent percentage of the total account capital (default is 1%), which is beneficial for long-term capital management and risk control.
Flexible Parameter Configuration - The strategy offers multiple adjustable parameters, including trading session settings, ORB duration, signal period duration, risk percentage, and risk-reward ratio, allowing traders to optimize according to different markets and personal risk preferences.
Visual Aids - The strategy provides rich visualization elements, including ORB horizontal lines, trade signal markers, background highlights for different trading periods, and a real-time statistics table, facilitating monitoring and analysis of strategy execution.
Support for Multiple Positions - The strategy design supports holding multiple trading positions simultaneously (controlled by the pyramiding parameter), allowing the capture of multiple trading opportunities within the same trading day, improving capital utilization efficiency.
Market Specificity - The strategy is primarily designed for regular trading hours in the US stock market and may not perform well in other markets or trading sessions. Opening characteristics and volatility patterns vary significantly across different markets, requiring targeted parameter adjustments.
Parameter Sensitivity - Strategy performance is sensitive to several key parameters, such as ORB duration, signal period length, and risk-reward ratio. Inappropriate parameter settings may lead to overtrading or missing important trading opportunities.
Market State Dependency - Strategy performance may be inconsistent in high-volatility or low-volatility market environments. Particularly in low-volatility markets, the ORB range may be too narrow, leading to frequent false breakout signals.
Stop-Loss Placement Risk - The strategy uses the previous candle’s high/low as stop-loss positions, which in fast markets may result in overly wide stop-loss distances, reducing the risk-reward ratio or leading to excessively small position sizes.
Reliance on Historical Price Patterns - The strategy assumes that FVG areas and ORB breakouts have predictive significance, but increased market efficiency or changes in trading environments may weaken the effectiveness of these patterns.
Technical Execution Risk - In actual trading, issues such as slippage and order execution delays may affect the consistency between actual trading results and backtesting results.
Dynamic ORB Duration - Consider automatically adjusting the ORB duration based on market volatility, such as using a longer ORB time in high-volatility market environments to avoid false breakouts, and shortening ORB time in low-volatility environments to capture more trading opportunities.
Add Filtering Conditions - Introduce additional filtering conditions to improve signal quality, such as aligning with the overall market trend direction (only going long in uptrends, short in downtrends), or adding volume confirmation (only trading when breakouts are accompanied by increased volume).
Optimize Stop-Loss Placement - Consider using dynamic stop-loss settings based on ATR or volatility, replacing the current fixed stop-loss method based on previous candle high/low points, which may provide more reasonable risk control.
Add Partial Profit-Taking Mechanism - Implement a tiered profit-taking strategy, such as closing part of the position when reaching a 1:1 risk-reward ratio, with the remaining portion set with a trailing stop or a more distant profit target, balancing the need to lock in profits and follow trends.
Time Filtering - Add time filters to avoid known low-quality trading periods, such as low-volatility lunch hours or high-volatility periods before and after important economic data releases.
Increase Adaptive Parameters - Introduce self-adaptive parameters allowing the strategy to automatically adjust based on recent market performance, such as dynamically adjusting the risk-reward ratio or adjusting the risk percentage based on recent win rates.
The Opening Range Breakout with Fair Value Gap Integration Strategy is a meticulously designed intraday trading system that seeks high-probability trading opportunities by combining ORB and FVG technical analysis methods. The strategy operates within clearly defined trading sessions, employs risk-based position sizing, and provides rich visualization and statistical tools to aid trading decisions.
The main advantages of the strategy lie in its clear trading logic, flexible parameter settings, and comprehensive risk management mechanisms. However, the strategy also faces risks such as market dependency, parameter sensitivity, and market state dependency. To enhance strategy robustness, it is recommended to consider dynamic parameter adjustments, additional filtering conditions, optimized stop-loss methods, and tiered profit-taking mechanisms.
It should be noted that this strategy is not suitable for all market environments and all trading instruments. Traders should conduct thorough backtesting and forward testing before actual application to ensure the strategy aligns with their risk preferences and trading objectives. Through continuous optimization and adaptation to market changes, this strategy has the potential to become an effective tool in the intraday trader’s toolkit.
/*backtest
start: 2025-06-18 00:00:00
end: 2025-06-25 00:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/
// Based on https://www.youtube.com/watch?v=mzFXoK2pbNE
//@version=5
strategy("[Myth Busting] [ORB] Casper SMC - 16 Jun", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100, initial_capital=10000, pyramiding = 10)
// Input settings
show_orb = input.bool(true, "Show 5m Opening Range")
show_signals = input.bool(true, "Show FVG Intersection Signals")
show_stats = input.bool(true, "Show Statistics Table")
risk_per_trade = input.float(1.0, "Risk Per Trade (%)", minval=0.1, maxval=10.0, step=0.1)
use_stop_loss = input.bool(true, "Use Stop Loss")
use_take_profit = input.bool(true, "Use Take Profit")
risk_reward_ratio = input.float(2.0, "Risk:Reward Ratio", minval=1.0, step=0.1)
// Session time inputs
session_start_hour = input.int(9, "Session Start Hour", minval=0, maxval=23, group="Session Settings")
session_start_minute = input.int(30, "Session Start Minute", minval=0, maxval=59, group="Session Settings")
session_end_hour = input.int(16, "Session End Hour", minval=0, maxval=23, group="Session Settings")
session_end_minute = input.int(0, "Session End Minute", minval=0, maxval=59, group="Session Settings")
session_timezone = input.string("America/New_York", "Session Timezone", group="Session Settings")
orb_duration_minutes = input.int(5, "ORB Duration (Minutes)", minval=1, maxval=60, group="Session Settings")
signal_end_offset = input.int(90, "Signal Period Duration (Minutes)", minval=30, maxval=300, group="Session Settings")
// Style settings
orb_high_color = input.color(color.new(color.green, 50), "ORB High Color")
orb_low_color = input.color(color.new(color.red, 50), "ORB Low Color")
bullish_signal_color = input.color(color.green, "Bullish Signal Color")
bearish_signal_color = input.color(color.red, "Bearish Signal Color")
// Variables to store ORB levels
var float orb_high = na
var float orb_low = na
var int orb_start_time = na
var int orb_end_time = na
var bool orb_set = false
// Position tracking
var int position_counter = 0
var int active_positions = 0
// Function to get current time in specified timezone
get_session_time() =>
current_hour = hour(time, session_timezone)
current_minute = minute(time, session_timezone)
current_hour * 60 + current_minute
// Calculate session times in minutes
session_start_minutes = session_start_hour * 60 + session_start_minute
session_end_minutes = session_end_hour * 60 + session_end_minute
orb_end_minutes = session_start_minutes + orb_duration_minutes
signal_end_minutes = session_start_minutes + signal_end_offset
// Check if we're in the ORB period
is_orb_period() =>
current_time = get_session_time()
current_time >= session_start_minutes and current_time < orb_end_minutes
// Check if we're in the signal period
is_signal_period() =>
current_time = get_session_time()
current_time >= orb_end_minutes and current_time < signal_end_minutes
// Check if we're in the overall trading session
is_trading_session() =>
current_time = get_session_time()
current_time >= session_start_minutes and current_time < session_end_minutes
// Reset ORB at the start of each trading session
new_session = is_trading_session() and not is_trading_session()[1]
if new_session or ta.change(dayofweek)
orb_high := na
orb_low := na
orb_start_time := na
orb_end_time := na
orb_set := false
position_counter := 0
// Capture ORB levels during the ORB period
if is_orb_period()
if na(orb_high) or na(orb_low)
orb_high := high
orb_low := low
orb_start_time := time
else
orb_high := math.max(orb_high, high)
orb_low := math.min(orb_low, low)
orb_end_time := time
// Mark ORB as set after the period ends
if not is_orb_period() and not na(orb_high) and not orb_set
orb_set := true
// Fair Value Gap detection
bullish_fvg = high[2] < low and not na(orb_high)
bearish_fvg = low[2] > high and not na(orb_low)
// Check for FVG intersection with ORB boundaries during signal period
bullish_intersection = false
bearish_intersection = false
// Count active positions
active_positions := strategy.opentrades
if is_signal_period() and orb_set
// Bullish FVG intersecting upper boundary
if bullish_fvg
if open[1] <= orb_high and close[1] >= orb_high
bullish_intersection := true
// Bearish FVG intersecting lower boundary
if bearish_fvg
if open[1] >= orb_low and close[1] <= orb_low
bearish_intersection := true
// Calculate position size based on risk per trade
calculate_position_size(entry, stop, is_long) =>
risk_amount = strategy.equity * (risk_per_trade / 100)
price_diff = is_long ? entry - stop : stop - entry
position_size = risk_amount / price_diff
position_size
// Strategy execution - Modified for multiple positions
if bullish_intersection
position_counter += 1
entry_price = close
stop_loss_price = low[1]
risk = entry_price - stop_loss_price
take_profit_price = entry_price + (risk * risk_reward_ratio)
// Calculate position size
qty = calculate_position_size(entry_price, stop_loss_price, true)
// Create unique entry ID
entry_id = "Long_" + str.tostring(position_counter)
exit_id = "LongExit_" + str.tostring(position_counter)
// Enter long position
strategy.entry(entry_id, strategy.long, qty=qty)
// Set stop loss and take profit
if use_stop_loss
strategy.exit(exit_id, entry_id, stop=stop_loss_price, limit=use_take_profit ? take_profit_price : na)
if bearish_intersection
position_counter += 1
entry_price = close
stop_loss_price = high[1]
risk = stop_loss_price - entry_price
take_profit_price = entry_price - (risk * risk_reward_ratio)
// Calculate position size
qty = calculate_position_size(entry_price, stop_loss_price, false)
// Create unique entry ID
entry_id = "Short_" + str.tostring(position_counter)
exit_id = "ShortExit_" + str.tostring(position_counter)
// Enter short position
strategy.entry(entry_id, strategy.short, qty=qty)
// Set stop loss and take profit
if use_stop_loss
strategy.exit(exit_id, entry_id, stop=stop_loss_price, limit=use_take_profit ? take_profit_price : na)
// Close all positions at end of trading session
if not is_trading_session() and strategy.position_size != 0
strategy.close_all("End of Trading Session")
// Plot ORB levels
plot(show_orb and orb_set ? orb_high : na, "ORB High", color=orb_high_color, linewidth=2, style=plot.style_line)
plot(show_orb and orb_set ? orb_low : na, "ORB Low", color=orb_low_color, linewidth=2, style=plot.style_line)
// Plot intersection signals
plotshape(series=show_signals and bullish_intersection, title="Bullish FVG Intersection", style=shape.triangleup, location=location.belowbar, color=bullish_signal_color, size=size.normal)
plotshape(series=show_signals and bearish_intersection, title="Bearish FVG Intersection", style=shape.triangledown, location=location.abovebar, color=bearish_signal_color, size=size.normal)
// Background highlights for different session periods
bgcolor(is_orb_period() ? color.new(color.yellow, 90) : na, title="ORB Period")
bgcolor(is_signal_period() and orb_set ? color.new(color.blue, 95) : na, title="Signal Period")
bgcolor(is_trading_session() and not is_signal_period() and not is_orb_period() ? color.new(color.gray, 98) : na, title="Trading Session")
// Plot session boundaries
plot(is_trading_session() ? high : na, "Session High", color=color.new(color.orange, 80), linewidth=1)
plot(is_trading_session() ? low : na, "Session Low", color=color.new(color.orange, 80), linewidth=1)