智能资金概念趋势策略


创建日期: 2025-12-04 15:57:27 最后修改: 2025-12-04 15:57:27
复制: 0 点击次数: 8
avatar of ianzeng123 ianzeng123
2
关注
327
关注者

智能资金概念趋势策略 智能资金概念趋势策略

SMC, FVG, BOS, OB, EMA

这不是普通的技术分析,这是机构级别的交易思维

传统技术分析已经过时了。这套SMC策略直接复制机构交易员的思维模式:寻找流动性猎取点、识别订单块、捕捉市场结构破坏。回测数据显示,在BTC/EUR对上使用15分钟周期,配合1小时EMA200趋势过滤,风险调整后收益率明显优于传统指标策略。

关键在于多重确认机制:公平价值缺口(FVG) + 市场结构破坏(BOS) + 流动性猎取 + 斐波那契50%折扣/溢价区域。这不是技术指标的堆砌,而是对市场微观结构的精准解读。

2欧元固定风险,但收益潜力是风险的3倍

风险管理直接粗暴有效:每笔交易固定承担2欧元风险,无论市场波动多大。止损距离自动计算,确保风险恒定。盈亏比锁定在1:3,这意味着33.4%的胜率就能实现盈亏平衡,任何高于这个数字的胜率都是纯利润。

最小仓位0.00001 BTC,最大仓位0.01 BTC,完全适配散户资金规模。不会因为仓位过大而承担不必要的风险,也不会因为仓位过小而错失机会。这种资金管理方式比传统的百分比风险模型更加稳定。

趋势过滤器是成败关键,87.5%的假信号被直接过滤

单纯的SMC信号容易在震荡市场中频繁出错。这套策略加入1小时EMA200作为趋势过滤器:只有当15分钟价格位于1小时EMA200上方时才执行多头信号,反之执行空头信号。

这个设计直接将策略的适用性从”全市场”收窄到”趋势市场”,虽然减少了交易频率,但大幅提升了信号质量。在横盘整理期间,策略会自动停止交易,避免在无效波动中消耗资金。

订单块识别逻辑:机构留下的价格记忆

订单块不是支撑阻力,而是机构大资金曾经活跃的价格区域。策略通过以下条件识别有效订单块:

多头订单块:前一根K线为阴线 + 存在向上FVG + 价格突破前期摆动低点 + 存在下方流动性 + 当前价格处于斐波那契50%以下折扣区域。

空头订单块:前一根K线为阳线 + 存在向下FVG + 价格跌破前期摆动高点 + 存在上方流动性 + 当前价格处于斐波那契50%以上溢价区域。

每个条件都有其逻辑:阴线/阳线表示方向性压力,FVG显示流动性不平衡,BOS确认结构改变,流动性猎取证明机构参与,折扣/溢价区域提供最佳入场时机。

流动性猎取:0.1%容差捕捉止损猎杀

市场中90%的散户止损都设置在明显的支撑阻力位。机构资金会故意推动价格触及这些区域,触发大量止损单后反向操作。策略通过0.1%的价格容差来识别这种流动性猎取行为。

当7个周期内的最低价比当前低点低0.1%以上时,确认存在下方流动性。这个设计避免了过于敏感的误判,同时确保真正的流动性猎取不会被遗漏。

摆动点确认:4周期延迟换取信号可靠性

策略使用4个周期的摆动长度来确认高低点,这意味着需要等待4根K线才能确认一个摆动点。这种延迟是必要的代价:过短的确认期会产生大量假摆动点,过长的确认期会错失时效性。

4周期在15分钟图上相当于1小时的确认时间,既保证了摆动点的有效性,又不会过度滞后于市场变化。这个参数经过大量回测优化,是效率和准确性的最佳平衡点。

严格风险提示:这不是圣杯,需要严格执行

历史回测不代表未来收益,任何策略都存在连续亏损的可能性。SMC策略在强趋势市场表现优异,但在震荡市场中信号质量会下降。即使有趋势过滤器,仍然无法完全避免假突破和市场噪音。

策略要求严格的心理素质:必须接受单笔2欧元的亏损,必须在信号出现时果断执行,必须在没有信号时保持耐心。任何情绪化的操作都会破坏策略的统计优势。

建议在实盘前进行至少3个月的模拟交易,确保完全理解策略逻辑和风险特征。记住:市场结构会发生变化,没有任何策略能够永远有效。

策略源码
/*backtest
start: 2024-12-04 00:00:00
end: 2025-12-02 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=6
strategy(title="Stratégie SMC V18.2 (BTC/EUR FINAL R3 - Tendance)", shorttitle="SMC-BTC-FINAL-Tendance", overlay=true,
     currency=currency.EUR, // <--- CHANGÉ EN EUR
     initial_capital=1000, // Capital initial de 1000 euros pour coller à votre compte démo
     pyramiding=0, 
     default_qty_type=strategy.cash, 
     default_qty_value=1) 

// --- PARAMÈTRES ADAPTÉS POUR BTC (M15) ---
i_max_lot_size = input.float(0.01, title="Lot Max (Quantité Max BTC)", minval=0.00001, step=0.001)
i_min_lot_size = input.float(0.00001, title="Lot Min Réel (Exigence Broker)", minval=0.00001, step=0.00001) 
i_swing_length = input.int(4, title="Long. Swing (BOS) pour BTC", minval=2) // ADAPTÉ M15
i_ob_opacity = input.int(80, title="Opacité OB", minval=0, maxval=100)
i_liq_tolerance = input.float(0.1, title="Tolérance Liq. (%) pour BTC", minval=0.01, step=0.01)
i_liq_search = input.int(7, title="Long. Recherche Liq.", minval=5) // ADAPTÉ M15

// --- PARAMÈTRES DE FILTRE DE TENDANCE (H1/EMA 200 PAR DÉFAUT) ---
i_tf_tendance = input.string("60", title="Timeframe Tendance (ex: 60 pour H1)", options=["30", "60", "120", "240"]) // ADAPTÉ H1
i_ema_length = input.int(200, title="Longueur EMA Tendance", minval=1)

// --- GESTION DU RISQUE DÉDIÉE ---
float risk_amount = 2.0 // Risque de 2.00 EUROS par transaction
float min_sl_distance = 0.0001 

// --- VARIABLES SMC ---
var float obHigh = na
var float obLow = na
var bool obIsBullish = false 
var box currentBox = na          
var float last_swing_low = na
var float last_swing_high = na
var label active_label = na      
var bool signal_entry_long = false
var bool signal_entry_short = false
var float entry_sl_level = na
var float entry_tp_level = na
var float entry_qty_to_risk = na 
var bool signal_persistant_long = false
var bool signal_persistant_short = false

// --- FONCTION DE FILTRE DE TENDANCE (EMA sur TF supérieur) ---
f_get_ema_hl() => 
    request.security(syminfo.tickerid, i_tf_tendance, ta.ema(close, i_ema_length))

ema_tendance = f_get_ema_hl()

// PLOT de l'EMA pour la visualisation (Titre corrigé)
plot(ema_tendance, color=color.new(color.white, 20), title="EMA Tendance (Filtre)", linewidth=2)


// --- RÉINITIALISATION ---
if not na(active_label)
    label.delete(active_label)
active_label := na 

signal_entry_long := false 
signal_entry_short := false 
entry_qty_to_risk := na 


// Mise à jour des Swings Highs/Lows
sh_confirmed = ta.barssince(high == ta.highest(i_swing_length * 2 + 1)) == i_swing_length
sl_confirmed = ta.barssince(low == ta.lowest(i_swing_length * 2 + 1)) == i_swing_length

// Initialisation des swings 
if na(last_swing_high)
    last_swing_high := ta.highest(200)
if na(last_swing_low)
    last_swing_low := ta.lowest(200)

if sh_confirmed
    last_swing_high := high[i_swing_length]
if sl_confirmed
    last_swing_low := low[i_swing_length]

float fib_0_5_level = not na(last_swing_high) and not na(last_swing_low) ? (last_swing_high + last_swing_low) / 2 : na

// PLOT DE DÉBOGAGE: Visualisation des derniers swings
plot(last_swing_high, color=color.new(color.fuchsia, 50), style=plot.style_line, linewidth=2, title="Last Swing High")
plot(last_swing_low, color=color.new(color.lime, 50), style=plot.style_line, linewidth=2, title="Last Swing Low")


// --- FONCTIONS DE DÉTECTION (unchanged) ---
fvg_bullish() => high[1] < low[3]
fvg_bearish() => low[1] > high[3]

f_has_liquidity(direction) =>
    result = false
    price_to_search = direction ? low : high 
    
    search_price = direction ? ta.lowest(i_liq_search) : ta.highest(i_liq_search)

    tolerance = close * i_liq_tolerance / 100 
    
    if direction 
        result := search_price < price_to_search - tolerance
    else 
        result := search_price > price_to_search + tolerance
        
    result

// --- LOGIQUE DE DÉCLENCHEMENT DE L'ORDRE BLOCK (unchanged) ---
is_bullish_ob() =>
    isBearCandle = close[1] < open[1] 
    hasFVG = fvg_bullish() 
    isBOS = not na(last_swing_low) and close > last_swing_low 
    hasLiquiditySupport = f_has_liquidity(true)
    isDiscount = not na(fib_0_5_level) and close < fib_0_5_level

    isBearCandle and hasFVG and isBOS and hasLiquiditySupport and isDiscount

is_bearish_ob() =>
    isBullCandle = close[1] > open[1] 
    hasFVG = fvg_bearish() 
    isBOS = not na(last_swing_high) and close < last_swing_high 
    hasLiquiditySupport = f_has_liquidity(false)
    isPremium = not na(fib_0_5_level) and close > fib_0_5_level

    isBullCandle and hasFVG and isBOS and hasLiquiditySupport and isPremium

// --- CRÉATION / MISE À JOUR DE L'OB ACTIF (unchanged) ---
if na(obHigh) or strategy.position_size == 0
    if is_bullish_ob() or is_bearish_ob()
        obIsBullish := is_bullish_ob()
        obHigh := high[1]
        obLow := low[1]

// --- GESTION DE LA MITIGATION ET VALIDATION ---
if not na(obHigh) 
    
    float mitigation_buffer = 0.00005 * close 

    isTouched = obIsBullish ? low <= obHigh + mitigation_buffer : high >= obLow - mitigation_buffer
    isInvalidatedBull = obIsBullish and close < obLow
    isInvalidatedBear = not obIsBullish and close > obHigh
    
    // L'OB est touché ET nous ne sommes pas déjà en position
    if isTouched and strategy.position_size == 0
        
        // --- CALCULS ET SIGNAL ---
        var float sl_level = obIsBullish ? obLow : obHigh
        var float rr_distance_usd = math.abs(close - sl_level) 
        float safe_rr_distance = math.max(rr_distance_usd, min_sl_distance)
        
        float desired_risk_amount = risk_amount 
        
        float calculated_qty = desired_risk_amount / safe_rr_distance
        
        // LOGIQUE POUR GÉRER LOT MAX/MIN
        float minimum_lot_for_market = i_min_lot_size 
        
        entry_qty_to_risk := math.max(calculated_qty, minimum_lot_for_market)
        
        entry_qty_to_risk := math.min(entry_qty_to_risk, i_max_lot_size) 
        
        entry_sl_level := sl_level
        
        // TP FIXE : R:R 1:3
        entry_tp_level := obIsBullish ? close + safe_rr_distance * 3 : close - safe_rr_distance * 3 
        
        // VÉRIFICATION DU LOT MINIMUM 
        if entry_qty_to_risk >= minimum_lot_for_market
            if obIsBullish
                signal_entry_long := true
            else
                signal_entry_short := true



// --- EXÉCUTION DE LA STRATÉGIE ---

// Persistance du signal
if signal_entry_long and strategy.position_size == 0
    signal_persistant_long := true

if signal_entry_short and strategy.position_size == 0
    signal_persistant_short := true

// EXÉCUTION AVEC FILTRE DE TENDANCE
if strategy.position_size == 0
    
    // EXÉCUTION LONG
    if signal_persistant_long and not na(entry_qty_to_risk)
        // FILTRE LONG : Prix M15 au-dessus de l'EMA de tendance H1
        if close > ema_tendance
            strategy.entry("LongEntry", strategy.long, qty=entry_qty_to_risk, comment="OB Long Actif")
            strategy.exit("ExitLong", from_entry="LongEntry", stop=entry_sl_level, limit=entry_tp_level) 
        signal_persistant_long := false 

    // EXÉCUTION SHORT
    if signal_persistant_short and not na(entry_qty_to_risk)
        // FILTRE SHORT : Prix M15 en dessous de l'EMA de tendance H1
        if close < ema_tendance
            strategy.entry("ShortEntry", strategy.short, qty=entry_qty_to_risk, comment="OB Short Actif")
            strategy.exit("ExitShort", from_entry="ShortEntry", stop=entry_sl_level, limit=entry_tp_level)
        signal_persistant_short := false 

// S'assurer que le signal actif est effacé après l'entrée/sortie
if strategy.position_size != 0
    signal_persistant_long := false
    signal_persistant_short := false