开盘区间突破与公平价值缺口结合策略

ORB FVG SMC RRR ATR VWAP RSI TZ
创建日期: 2025-06-26 09:24:20 最后修改: 2025-06-26 09:24:20
复制: 1 点击次数: 359
avatar of ianzeng123 ianzeng123
2
关注
319
关注者

开盘区间突破与公平价值缺口结合策略 开盘区间突破与公平价值缺口结合策略

概述

开盘区间突破与公平价值缺口结合策略是一种结合了开盘区间突破(ORB)和智能资金概念(SMC)中公平价值缺口(FVG)的量化交易策略。该策略首先定义了交易日初期的价格区间(通常为开盘后的5分钟),然后寻找价格突破该区间边界时与公平价值缺口相交的情况作为交易信号。策略设计适用于特定时间段内的日内交易,特别是美国市场的常规交易时段,并通过风险管理机制控制每笔交易的风险敞口。

策略原理

该策略的核心原理基于两个关键的技术分析概念:

  1. 开盘区间突破(ORB) - 策略首先确定交易日开盘后特定时间段(默认为5分钟)内的最高价和最低价,形成一个价格区间。这个区间被视为市场参与者对当日价格走势的初步判断,突破该区间可能预示着短期趋势的形成。

  2. 公平价值缺口(FVG) - 来自智能资金概念(SMC)的分析方法,当前高点低于前前蜡烛的低点时形成看涨FVG,当前低点高于前前蜡烛的高点时形成看跌FVG。这些缺口被认为是价格未来可能回补的区域,代表着市场结构中的不平衡。

策略的交易信号产生于以下条件: - 当看涨FVG与ORB上边界相交时(前一根蜡烛的开盘价低于ORB高点,收盘价高于ORB高点),触发做多信号 - 当看跌FVG与ORB下边界相交时(前一根蜡烛的开盘价高于ORB低点,收盘价低于ORB低点),触发做空信号

交易执行时,策略采用基于风险的头寸管理方法,根据止损距离计算每笔交易的具体头寸大小,以确保每笔交易的风险敞口一致。止损设置在做多交易的前一根蜡烛低点或做空交易的前一根蜡烛高点,获利目标则基于预设的风险回报比率(默认为2.0)。所有未平仓的交易在交易时段结束时自动平仓,确保不持有隔夜头寸。

策略优势

  1. 结合多种技术分析方法 - 通过整合ORB和FVG两种技术分析方法,策略能够过滤掉单一指标可能产生的虚假信号,提高交易信号的质量。

  2. 明确的交易时间框架 - 策略明确定义了交易的时间范围(信号期和交易期),有助于交易者专注于市场最活跃且信号质量最高的时段,避免在低活跃度时段的无效交易。

  3. 基于风险的头寸管理 - 策略采用基于风险的头寸计算方法,确保每笔交易风险占账户总资金的比例一致(默认为1%),有利于长期资金管理和风险控制。

  4. 灵活的参数配置 - 策略提供了多个可调参数,包括交易时段设置、ORB持续时间、信号期持续时间、风险比例和风险回报比率等,使交易者可以根据不同市场和个人风险偏好进行优化。

  5. 可视化辅助 - 策略提供了丰富的可视化元素,包括ORB水平线、交易信号标记、不同交易时段的背景高亮以及实时统计数据表格,便于交易者监控和分析策略执行情况。

  6. 支持多头寸管理 - 策略设计支持同时持有多个交易头寸(通过pyramiding参数控制),允许在同一交易日内捕捉多个交易机会,提高资金利用效率。

策略风险

  1. 特定市场依赖性 - 该策略主要针对美国股票市场的常规交易时段设计,在其他市场或交易时段可能效果不佳。不同市场的开盘特征和波动模式差异较大,需要针对性调整参数。

  2. 参数敏感性 - 策略性能对多个关键参数敏感,如ORB持续时间、信号期长度和风险回报比率等。不当的参数设置可能导致过度交易或错过重要交易机会。

  3. 市场状态依赖 - 在高波动性或低波动性市场环境下,策略表现可能不一致。特别是在低波动市场中,ORB区间可能过窄,导致频繁触发虚假突破信号。

  4. 止损位置风险 - 策略使用前一根蜡烛的高/低点作为止损位置,在快速市场中这可能导致止损位置过宽,从而降低风险回报比或导致过小的头寸规模。

  5. 依赖历史价格模式 - 策略假设FVG区域和ORB突破具有预测意义,但市场效率提高或交易环境变化可能削弱这些模式的有效性。

  6. 技术执行风险 - 在实际交易中,可能面临滑点、订单执行延迟等问题,影响实际交易结果与回测结果的一致性。

策略优化方向

  1. 动态ORB持续时间 - 可以考虑根据市场波动性自动调整ORB的持续时间,例如在高波动市场环境下使用更长的ORB时间以避免虚假突破,在低波动环境下缩短ORB时间以捕捉更多交易机会。

  2. 添加过滤条件 - 引入额外的过滤条件提高信号质量,如结合整体市场趋势方向(只在上升趋势中做多,下降趋势中做空),或者添加成交量确认(只有当突破伴随成交量增加时才交易)。

  3. 优化止损位置 - 考虑使用基于ATR或波动率的动态止损设置,替代当前基于前一根蜡烛高低点的固定止损方法,可能提供更合理的风险控制。

  4. 添加部分获利机制 - 实施分段获利策略,例如在达到1:1风险回报比时平掉部分头寸,剩余部分设置追踪止损或更远的获利目标,以平衡锁定利润和追踪趋势的需求。

  5. 时间过滤 - 加入时间过滤器,避开已知的低质量交易时段,如午餐时间的低波动期或重要经济数据发布前后的高波动期。

  6. 增加适应性参数 - 引入自适应参数,使策略能够根据最近的市场表现自动调整参数,如动态调整风险回报比率或根据最近的胜率调整风险百分比。

总结

开盘区间突破与公平价值缺口结合策略是一种精心设计的日内交易系统,通过结合ORB和FVG两种技术分析方法,寻找高概率交易机会。该策略在明确定义的交易时段内运行,采用基于风险的头寸管理方法,并提供丰富的可视化和统计工具辅助交易决策。

策略的主要优势在于其清晰的交易逻辑、灵活的参数设置和全面的风险管理机制。然而,策略也面临市场依赖性、参数敏感性和市场状态依赖等风险。为提高策略稳健性,建议考虑动态参数调整、增加过滤条件、优化止损方法和实施分段获利机制等优化方向。

需要注意的是,该策略并非适用于所有市场环境和所有交易品种,交易者应在实际应用前进行充分的回测和前向测试,确保策略与自身的风险偏好和交易目标相符合。通过持续优化和适应市场变化,该策略有潜力成为日内交易者工具箱中的有效工具。

策略源码
/*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)
相关推荐