トレンドラダー平均化戦略: 市場が横ばいになったときにエレガントに「横ばい」になる方法とは?

ADX EMA ATR DI
作成日: 2025-10-09 14:28:37 最終変更日: 2025-10-09 14:28:37
コピー: 0 クリック数: 268
2
フォロー
319
フォロワー

トレンドラダー平均化戦略: 市場が横ばいになったときにエレガントに「横ばい」になる方法とは? トレンドラダー平均化戦略: 市場が横ばいになったときにエレガントに「横ばい」になる方法とは?

なぜ伝統的なトレンドトラッキング戦略が 揺れ動いている都市で”転覆”を繰り返すのか?

量子取引の専門家として,よく聞かれる質問は,なぜトレンドマーケットで上手くいった戦略が,急激な変動で急激に後退するのかということです.

答えは簡単です: ほとんどのトレンド追跡戦略は”トレンド強迫症”に苦しんでいます. どの市場環境でも高頻度取引を維持しようとし,基本的な事実を無視しています.市場の70%は横横の振動状態です.

今日分析する”トレンド・エスカレート・平均戦略”は,まさにこの痛みを解決する面白い解決策を提示しています.トレンドマーケットで積極的で,揺れ動いている市場では”優雅に平ら”

“梯子の平均”とは何か? トレンド追跡の定義は?

伝統的な移動平均策には致命的な欠陥があります.それらは常に変化しています.市場が強気なトレンドであれ横軸の振動であれ,平均線は価格の変動に合わせて常に調整され,大量に偽のシグナルをもたらします.

平均は,平均の階層から,平均の階層へと,平均線は特定の条件で”凍結”されます.

具体的には以下の通りです.

  1. トレンドステート検知市場動向の強さを判断するADXの指標

    • ADX > 25: 強いトレンド市場
    • 平均線傾き < 0.3%:横軸市場
  2. 動的均線切換

    • 強いトレンドの場合:正常に追跡するEMA ((21)
    • 横盤時:均線で水平位置に”凍結”し,サポート/レジスタンスを形成する

このデザインの素晴らしさは市場環境によって戦略が異なる”性格”を 表現できるようにしていますはトレンドに敏感で,震動に安定している.

“トレンドキャプチャー”の仕組みは?

この戦略は,基本の階層平均の仕組みに加えて,トレンドキャプチャモジュールも組み込んでいます.

迅速な反転メカニズム

  • 市場が平らになったばかりのトレンドが逆転したときに
  • 3サイクルで新しいポジションを迅速に作る
  • 条件:ADX > 30とDI+とDI−の差値 > 10

このデザインは,従来の戦略の重要な問題である,トレンドの逆転の初期に ポジションを迅速に調整する方法

このシナリオを想像してみてください: ストップ・ロスのために多頭ポジションを平らにしたばかりで,市場がすぐに強い下落のトレンドに突入します. 従来の戦略は,新しいシグナルが確認されるのを待つ必要がありますが,この”トレンドキャッチ”システムは,3サイクルで空頭ポジションを迅速に構築できます.

リスクマネジメント:なぜ市場状態を区分する?

この戦略から学ぶべきことは異なるリスク管理機構

横軸市場におけるリスク管理

  • ストップ・ローンは,梯子の平均線に近い位置に調整されます.
  • ATRの倍数を減らし,ストップを締めくくく
  • ターゲットビットの設定は保守的です.

トレンド市場のリスク管理

  • 標準ATR倍数による止損
  • 階段式移動止損を有効にする
  • 価格の変動を許容する

このデザインは,重要な取引哲学を表現しています.異なる市場環境は異なるリスクの好みを要求します横軸市場では,もっと慎重に,トレンド市場では,もっと利潤を走らせる必要がある.

階段式移動ストップ:利益の保護とトレンド追跡のバランスをとる方法

伝統的な移動止損は,過度に機械化され,過度に厳格化されすぎると,早めに退場させられるか,過度に緩やかになり,利益を効果的に守ることができない.この戦略の梯子の移動止損は,よりスマートな解決策を提供します.

階層設定の論理

  • ATRの動的計算による階段間隔
  • 階層を最大5つ設定する
  • ストップダメージは1つの階段を突破するごとに上昇します.

このデザインの利点は,利益を守る一方で,トレンドに十分な余地を与えるのです

具体的には,どのような注意が必要でしょうか?

私の実務経験から,このような戦略を使うには,以下の点に注意する必要があります.

  1. パラメータ最適化の罠ADXの値を過度に最適化しないでください. 25〜30の数字はほとんどの市場で安定しています.

  2. 市場の適応性この戦略は,極端な波動の環境でATR倍数を調整する必要がある可能性のある,波動性の適度な市場に適しています.

  3. 資金管理: 単一のポジションは総資金の10%を超えないようにお勧めします. 特にトレンドキャプチャ機能が有効である場合.

  4. 罠を捉える市場が揺れ動いているとき,特に頻繁に取引される場合,スライドポイントや手数料の影響に注意してください.

この戦略の革新的価値はどこにあるのか?

この戦略は,数値化戦略の発展の観点から見て,重要な進化の方向を表しています.シングルロジックからマルチステート・アダプテーションへの移行

伝統的な戦略は,すべての市場状況に対して,一定の論理を用いて対処しようとしますが,この戦略は”場所の都合”の良さを示しています.

  • トレンドマーケットで 激進的なトレンドフォロワーのように振る舞う
  • 市場が揺れ動いている時,保守的な区間トレーダーのように振る舞う

このデザインは,戦略開発者にとって重要なインスピレーションとなる.戦略は”市場感知”の能力を持つべきで, 盲目的に固定された論理に従わないべきです.

最後に,強調しておきたいのは,どんな戦略も万能ではないということです. この梯子平均戦略は理論的には優雅ですが,実際の応用では,特定の市場環境と個人のリスクの好みに合わせて調整する必要があります.戦略は,常に,あなたにとって最適です.

ストラテジーソースコード
/*backtest
start: 2024-10-09 00:00:00
end: 2025-10-07 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"SOL_USDT","balance":500000}]
*/

//@version=5
strategy("Trend Following Ladder Average Strategy", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=10)

// ═══════════════════════════════════════════════════════════════════════════════
// SETTINGS AND PARAMETERS
// ═══════════════════════════════════════════════════════════════════════════════

// Ladder Average Settings
ma_length = input.int(title="Average Period", defval=21, minval=5)
ma_type = input.string(title="Average Type", defval="EMA", options=["SMA", "EMA", "WMA"])

// Trend Strength Settings
adx_length = input.int(title="Trend Strength Period (ADX)", defval=14, minval=5)
trend_threshold = input.float(title="Trend Strength Threshold", defval=25.0, minval=10.0, step=5.0)
sideways_slope_threshold = input.float(title="Sideways Market Slope Threshold", defval=0.3, minval=0.1, step=0.1)

// Trend Catching Settings
enable_trend_catch = input.bool(title="Trend Catching System", defval=true)
trend_catch_adx_threshold = input.float(title="Trend Catch ADX Threshold", defval=30.0, minval=20.0, step=5.0)
trend_catch_di_diff = input.float(title="DI+ DI- Difference Threshold", defval=10.0, minval=5.0, step=2.5)
quick_entry_bars = input.int(title="Quick Entry Waiting Bars", defval=3, minval=1, maxval=10)

// ATR and Volatility Settings
atr_length = input.int(title="ATR Period", defval=14, minval=1)
atr_multiplier = input.float(title="ATR Multiplier", defval=2.0, minval=0.1, step=0.1)

// Ladder Trailing Stop Settings
ladder_step = input.float(title="Ladder Step Size (%)", defval=1.0, minval=0.1, step=0.1)
max_ladders = input.int(title="Maximum Ladder Count", defval=5, minval=2, maxval=10)

// Stop Loss and Take Profit Settings
use_stop_loss = input.bool(title="Use Stop Loss", defval=false)
use_take_profit = input.bool(title="Use Take Profit", defval=false)
use_trailing_stop = input.bool(title="Use Trailing Stop", defval=true)

sl_type = input.string(title="Stop Loss Type", defval="ATR", options=["ATR", "Percent", "Points"])
sl_atr_multiplier = input.float(title="SL ATR Multiplier", defval=2.0, minval=0.5, step=0.1)
sl_percent = input.float(title="SL Percent (%)", defval=2.0, minval=0.1, step=0.1)
sl_points = input.float(title="SL Points", defval=100, minval=1)

tp_type = input.string(title="Take Profit Type", defval="ATR", options=["ATR", "Percent", "Points", "Risk/Reward"])
tp_atr_multiplier = input.float(title="TP ATR Multiplier", defval=3.0, minval=0.5, step=0.1)
tp_percent = input.float(title="TP Percent (%)", defval=3.0, minval=0.1, step=0.1)
tp_points = input.float(title="TP Points", defval=150, minval=1)
tp_risk_reward = input.float(title="Risk/Reward Ratio", defval=2.0, minval=0.5, step=0.1)

// Horizontal Level Settings
horizontal_lookback = input.int(title="Horizontal Level Stabilization Period", defval=10, minval=3)

// ═══════════════════════════════════════════════════════════════════════════════
// INDICATORS AND CALCULATIONS
// ═══════════════════════════════════════════════════════════════════════════════

// ATR calculation
atr_value = ta.atr(atr_length)

// Moving Average calculation
ma_value = ma_type == "SMA" ? ta.sma(close, ma_length) : ma_type == "EMA" ? ta.ema(close, ma_length) : ma_type == "WMA" ? ta.wma(close, ma_length) : ta.ema(close, ma_length)

// ADX (Trend Strength) calculation - Manual calculation
tr = math.max(high - low, math.max(math.abs(high - close[1]), math.abs(low - close[1])))
plus_dm = high - high[1] > low[1] - low ? math.max(high - high[1], 0) : 0
minus_dm = low[1] - low > high - high[1] ? math.max(low[1] - low, 0) : 0
plus_di = 100 * ta.rma(plus_dm, adx_length) / ta.rma(tr, adx_length)
minus_di = 100 * ta.rma(minus_dm, adx_length) / ta.rma(tr, adx_length)
adx_value = 100 * ta.rma(math.abs(plus_di - minus_di) / (plus_di + minus_di), adx_length)

// MA slope calculation (for sideways market detection)
ma_slope = (ma_value - ma_value[5]) / ma_value[5] * 100

// Trend state detection
is_strong_trend = adx_value > trend_threshold
is_sideways_by_slope = math.abs(ma_slope) < sideways_slope_threshold
is_sideways = not is_strong_trend or is_sideways_by_slope

// Trend direction detection (DI+ vs DI-)
is_uptrend = plus_di > minus_di
is_downtrend = minus_di > plus_di
di_difference = math.abs(plus_di - minus_di)

// Strong trend momentum detection
strong_uptrend = adx_value > trend_catch_adx_threshold and plus_di > minus_di and di_difference > trend_catch_di_diff
strong_downtrend = adx_value > trend_catch_adx_threshold and minus_di > plus_di and di_difference > trend_catch_di_diff

// Position tracking system
var bool just_closed_long = false
var bool just_closed_short = false
var int bars_since_close = 0

// Position closure tracking - Fixed
if strategy.position_size == 0 and strategy.position_size[1] != 0
    if strategy.position_size[1] > 0
        just_closed_long := true
        just_closed_short := false
    else
        just_closed_short := true  
        just_closed_long := false
    bars_since_close := 0
else if strategy.position_size == 0
    bars_since_close += 1
    if bars_since_close > quick_entry_bars
        just_closed_long := false
        just_closed_short := false
else
    just_closed_long := false
    just_closed_short := false
    bars_since_close := 0

// Ladder Average System
var float ladder_ma = na
var float horizontal_level = na
var int sideways_count = 0

// Trend-following ladder average
if is_strong_trend and not is_sideways_by_slope
    // Normal MA tracking in strong trend
    ladder_ma := ma_value
    sideways_count := 0
else
    // When trend weakens or in sideways market
    sideways_count += 1
    if sideways_count >= horizontal_lookback or na(horizontal_level)
        horizontal_level := ma_value
    ladder_ma := horizontal_level

// Market state
market_state = is_strong_trend and not is_sideways_by_slope ? "TREND" : "SIDEWAYS"

// Volatility measurement
volatility = atr_value / close * 100

// ═══════════════════════════════════════════════════════════════════════════════
// STOP LOSS AND TAKE PROFIT CALCULATIONS
// ═══════════════════════════════════════════════════════════════════════════════

// Stop Loss calculation function
calculate_stop_loss(entry_price_val, is_long) =>
    sl_value = sl_type == "ATR" ? (is_long ? entry_price_val - (atr_value * sl_atr_multiplier) : entry_price_val + (atr_value * sl_atr_multiplier)) : sl_type == "Percent" ? (is_long ? entry_price_val * (1 - sl_percent / 100) : entry_price_val * (1 + sl_percent / 100)) : sl_type == "Points" ? (is_long ? entry_price_val - sl_points : entry_price_val + sl_points) : (is_long ? entry_price_val - (atr_value * sl_atr_multiplier) : entry_price_val + (atr_value * sl_atr_multiplier))
    sl_adjusted = if is_sideways
        is_long ? math.min(sl_value, ladder_ma - atr_value * 0.5) : math.max(sl_value, ladder_ma + atr_value * 0.5)
    else
        sl_value
    sl_adjusted

// Take Profit calculation function
calculate_take_profit(entry_price_val, stop_loss_val, is_long) =>
    tp_value = tp_type == "ATR" ? (is_long ? entry_price_val + (atr_value * tp_atr_multiplier) : entry_price_val - (atr_value * tp_atr_multiplier)) : tp_type == "Percent" ? (is_long ? entry_price_val * (1 + tp_percent / 100) : entry_price_val * (1 - tp_percent / 100)) : tp_type == "Points" ? (is_long ? entry_price_val + tp_points : entry_price_val - tp_points) : tp_type == "Risk/Reward" ? (is_long ? entry_price_val + (math.abs(entry_price_val - stop_loss_val) * tp_risk_reward) : entry_price_val - (math.abs(entry_price_val - stop_loss_val) * tp_risk_reward)) : (is_long ? entry_price_val + (atr_value * tp_atr_multiplier) : entry_price_val - (atr_value * tp_atr_multiplier))
    tp_adjusted = if is_sideways
        is_long ? math.max(tp_value, ladder_ma + atr_value * 1.5) : math.min(tp_value, ladder_ma - atr_value * 1.5)
    else
        tp_value
    tp_adjusted

var float current_sl = na
var float current_tp = na

// ═══════════════════════════════════════════════════════════════════════════════
// ENTRY SIGNALS
// ═══════════════════════════════════════════════════════════════════════════════

// Normal entry conditions
normal_long = strategy.position_size == 0 and ((is_strong_trend and close > ladder_ma and close[1] <= ladder_ma[1]) or (is_sideways and close < ladder_ma and close > ladder_ma - atr_value))
normal_short = strategy.position_size == 0 and ((is_strong_trend and close < ladder_ma and close[1] >= ladder_ma[1]) or (is_sideways and close > ladder_ma and close < ladder_ma + atr_value))

// Trend catching entry conditions
trend_catch_long = enable_trend_catch and strategy.position_size == 0 and just_closed_short and bars_since_close <= quick_entry_bars and strong_uptrend and close > close[1] and close > ladder_ma
trend_catch_short = enable_trend_catch and strategy.position_size == 0 and just_closed_long and bars_since_close <= quick_entry_bars and strong_downtrend and close < close[1] and close < ladder_ma

// Strong momentum entry conditions (even if no position closed, but strong trend exists)
momentum_long = enable_trend_catch and strategy.position_size == 0 and strong_uptrend and close > ladder_ma and close > close[1] and close > open
momentum_short = enable_trend_catch and strategy.position_size == 0 and strong_downtrend and close < ladder_ma and close < close[1] and close < open

// Combined entry conditions
long_condition = normal_long or trend_catch_long or momentum_long
short_condition = normal_short or trend_catch_short or momentum_short

// Entry type determination
entry_type = if trend_catch_long or trend_catch_short
    "TREND_CATCH"
else if momentum_long or momentum_short
    "MOMENTUM"
else
    market_state

// ═══════════════════════════════════════════════════════════════════════════════
// LADDER TRAILING STOP SYSTEM
// ═══════════════════════════════════════════════════════════════════════════════

var float[] ladder_levels = array.new<float>()
var float current_trailing_stop = na
var float entry_price = na

// Calculate ladder levels function
calculate_ladder_levels(entry_price_val, is_long) =>
    ladder_array = array.new<float>()
    base_level = ladder_ma
    for i = 1 to max_ladders
        level_value = if is_long
            base_level + (atr_value * atr_multiplier * i * ladder_step / 100)
        else
            base_level - (atr_value * atr_multiplier * i * ladder_step / 100)
        array.push(ladder_array, level_value)
    ladder_array

// Trailing stop update function
update_trailing_stop(entry_price_val, current_price, is_long) =>
    stop_level = if is_long
        initial_stop = is_sideways ? ladder_ma - atr_value : entry_price_val - (atr_value * atr_multiplier)
        new_stop = initial_stop
        if array.size(ladder_levels) > 0
            for i = 0 to array.size(ladder_levels) - 1
                level_value = array.get(ladder_levels, i)
                if current_price >= level_value
                    adjusted_stop = is_sideways ? ladder_ma : entry_price_val + (atr_value * atr_multiplier * (i + 1) * 0.3)
                    if adjusted_stop > new_stop
                        new_stop := adjusted_stop
        new_stop
    else
        initial_stop = is_sideways ? ladder_ma + atr_value : entry_price_val + (atr_value * atr_multiplier)
        new_stop = initial_stop
        if array.size(ladder_levels) > 0
            for i = 0 to array.size(ladder_levels) - 1
                level_value = array.get(ladder_levels, i)
                if current_price <= level_value
                    adjusted_stop = is_sideways ? ladder_ma : entry_price_val - (atr_value * atr_multiplier * (i + 1) * 0.3)
                    if adjusted_stop < new_stop
                        new_stop := adjusted_stop
        new_stop
    stop_level

// ═══════════════════════════════════════════════════════════════════════════════
// POSITION MANAGEMENT
// ═══════════════════════════════════════════════════════════════════════════════

// Long position entry
if long_condition
    strategy.entry("Long", strategy.long, comment="Long: " + market_state)
    entry_price := close
    ladder_levels := calculate_ladder_levels(close, true)
    
    // Stop Loss calculation (only if active)
    if use_stop_loss
        current_sl := calculate_stop_loss(close, true)
    
    // Take Profit calculation (only if active)
    if use_take_profit
        temp_sl = use_stop_loss ? current_sl : close - (atr_value * sl_atr_multiplier)
        current_tp := calculate_take_profit(close, temp_sl, true)
    
    // Trailing stop initialization (only if active)
    if use_trailing_stop
        current_trailing_stop := is_sideways ? ladder_ma - atr_value : close - (atr_value * atr_multiplier)

// Short position entry
if short_condition
    strategy.entry("Short", strategy.short, comment="Short: " + market_state)
    entry_price := close
    ladder_levels := calculate_ladder_levels(close, false)
    
    // Stop Loss calculation (only if active)
    if use_stop_loss
        current_sl := calculate_stop_loss(close, false)
    
    // Take Profit calculation (only if active)
    if use_take_profit
        temp_sl = use_stop_loss ? current_sl : close + (atr_value * sl_atr_multiplier)
        current_tp := calculate_take_profit(close, temp_sl, false)
    
    // Trailing stop initialization (only if active)
    if use_trailing_stop
        current_trailing_stop := is_sideways ? ladder_ma + atr_value : close + (atr_value * atr_multiplier)

// Position exit management
if strategy.position_size > 0  // Long position
    // If using fixed SL/TP
    if use_stop_loss and use_take_profit
        strategy.exit("Long Exit", "Long", stop=current_sl, limit=current_tp, comment="SL/TP")
    else if use_stop_loss and not use_take_profit
        strategy.exit("Long Exit", "Long", stop=current_sl, comment="SL Only")
    else if not use_stop_loss and use_take_profit
        strategy.exit("Long Exit", "Long", limit=current_tp, comment="TP Only")
    
    // If using trailing stop (optional)
    if use_trailing_stop
        current_trailing_stop := update_trailing_stop(entry_price, close, true)
        if close <= current_trailing_stop
            strategy.close("Long", comment="Trailing Stop")

if strategy.position_size < 0  // Short position
    // If using fixed SL/TP
    if use_stop_loss and use_take_profit
        strategy.exit("Short Exit", "Short", stop=current_sl, limit=current_tp, comment="SL/TP")
    else if use_stop_loss and not use_take_profit
        strategy.exit("Short Exit", "Short", stop=current_sl, comment="SL Only")
    else if not use_stop_loss and use_take_profit
        strategy.exit("Short Exit", "Short", limit=current_tp, comment="TP Only")
    
    // If using trailing stop (optional)
    if use_trailing_stop
        current_trailing_stop := update_trailing_stop(entry_price, close, false)
        if close >= current_trailing_stop
            strategy.close("Short", comment="Trailing Stop")



// ═══════════════════════════════════════════════════════════════════════════════
// VISUALIZATION
// ═══════════════════════════════════════════════════════════════════════════════

// Ladder Average plot
plot(ladder_ma, color=is_sideways ? color.orange : (ma_slope > 0 ? color.green : color.red), linewidth=3, title="Ladder Average")

// Horizontal level plot
plot(is_sideways ? horizontal_level : na, color=color.yellow, style=plot.style_circles, linewidth=2, title="Horizontal Level")

// ATR-based bands
upper_band = ladder_ma + atr_value
lower_band = ladder_ma - atr_value
plot(upper_band, color=color.new(color.blue, 70), title="Upper ATR Band")
plot(lower_band, color=color.new(color.blue, 70), title="Lower ATR Band")

// Stop Loss and Take Profit plots (only if active)
plot(strategy.position_size != 0 and use_stop_loss ? current_sl : na, color=color.red, style=plot.style_circles, linewidth=2, title="Stop Loss")
plot(strategy.position_size != 0 and use_take_profit ? current_tp : na, color=color.green, style=plot.style_circles, linewidth=2, title="Take Profit")

// Trailing stop plot (only if active)
plot(strategy.position_size > 0 and use_trailing_stop ? current_trailing_stop : na, color=color.orange, style=plot.style_stepline, linewidth=2, title="Long Trailing Stop")
plot(strategy.position_size < 0 and use_trailing_stop ? current_trailing_stop : na, color=color.orange, style=plot.style_stepline, linewidth=2, title="Short Trailing Stop")

// Market state background color
bgcolor(is_sideways ? color.new(color.yellow, 95) : (is_strong_trend ? color.new(color.green, 98) : color.new(color.gray, 98)), title="Market State")