
多指数突破と逆転の取引戦略は,指数と価格の行動を技術的に分析する,市場における2つの主要な取引機会を捉えるための量化取引方法である.この戦略は,移動平均,相対的に強い指数 (RSI),平均リアルレンジ (ATR) および取引量加重平均価格 (VWAP) などの複数の技術指標を巧妙に統合し,開盤区間突破 (ORB) の仕組みを導入し,入場シグナルの信頼性を高めます.この戦略は,二重目的のストップデザインを採用し,自動でストップ損失を平衡の損失点に調整するリスク管理機構を備えています.
この戦略の核心となる原則は,複数の指標をフィルタリングして確認し,潜在的に有利な取引機会の3つのカテゴリーを特定することです.
逆転取引信号:
トレンドブレイク信号:
オープン区間突破 (ORB) 信号:
戦略はATR指標を使用して動的ストップロスを計算し,特定の周期の最低価格/最高価格を遡って設定し,ATR値の倍数 (デフォルト0.5) を加減します.入場後,戦略は2つのストップストップ目標を設定します.
最初のストップ目標が達成されると,戦略は自動的にストップを入場価格に調整し,既得利益を効果的に保護する.
多様な入場信号戦略は,反転,突破,開場区間を突破する3つの異なる入場シグナルを統合することで,多種多様な市場環境に適応し,取引機会を効果的に増加させながら,高い信号品質を維持します.
リスクの管理戦略は,分級のストップメカニズムを採用し,利益の一部を保持しながら,潜在的により大きな利益を維持します.最初のストップ目標に達すると,自動的にストップ損失を利益の均衡点に調整し,利益を走らせながら資本を保護します.
ダイナミックストップ損失計算:ATR指標を用いたストップポジションの計算により,ストップレベルは市場の波動的な動向に合わせて調整され,現在の市場状況をより正確に反映し,過度に緊密なまたは過度に緩やかなストップ設定を避ける.
取引量確認:特にORB信号に取引量確認メカニズムを導入し,開拓区間の平均取引量の特定の倍数を超える取引量の要求を突破し,低品質の突破を効果的にフィルターする.
トレンドフィルター長期トレンドの方向を200期簡易移動平均 ((SMA200) で判断し,取引の方向が主要トレンドと一致していることを確認し,取引の成功率を向上させる.
資金管理統合戦略: 資金管理機構を組み込み,取引ごとに使用する資金の割合を制限する (デフォルトの50%の資本),資金の多様化配置を確保し,単一の取引のリスクのを減らす.
解決策:価格行動パターンの認識などの前向きな指標を増やすか,より長い周期の移動平均のパラメータを縮小して,市場の変化への感受性を高めるかを検討する.
解決方法: 適切なパラメータ最適化方法 (前向き検証,モンテカルロ模擬など) を採用し,過度な最適化を避けるか,固定パラメータを使用し,より堅牢な規則設計に焦点を当てます.
解決策は,より厳格な信号優先システムを作ること,または,取引が高い確率でしか実行されないことを保証する追加の確認メカニズムを導入することです.
解決方法: オプションのヘッジ戦略を使用するか,高波動性のある市場条件下でストップ距離を増やすか,一時的にポジションサイズを下げるかを検討する.
解決策:全局的なリスク管理を実施し,総ポジションの規模を制限するか,異なる資産クラス間の分散取引を行い,関連性のリスクを軽減する.
最適化理由:従来の固定重量指標の組み合わせは,異なる市場段階に適応することが困難であり,機械学習は,歴史データから最適な指標の組み合わせのパターンを自動的に学習することができます.
最適化理由:市場の情勢は短期的な価格動向に顕著な影響を与える.このような指標を統合することで,市場の転換点を早期に捉え,入場と出場のタイミングを最適化することができる.
最適化理由: 固定のリスク・リターン比は,異なる市場環境で柔軟性がない可能性があり,ダイナミックな調整により,高波動市場ではより遠方の目標,低波動市場ではより保守的な目標が設定できます.
最適化理由:市場の活動は,1日の異なる時間帯で顕著な差異を示し,時間フィルタリングは,戦略が最も有利な取引時間に集中するのを助けます.
最適化理由: リスクは市場の変動と直接に関連しており,動的ポジション管理により,より一貫したリスクレベルを維持し,長期のリスク調整後の収益を改善することができる.
多指数突破と逆転取引戦略は,複数の技術分析方法を融合した総合的な量化取引システムであり,逆転,トレンド突破と開拓区間の突破信号を統合し,優れたリスク管理と資金管理機構を組み合わせて,さまざまな市場環境における取引機会を捉えることを目的としています. 戦略の核心的な優点は,信号の多様性,リスク管理の改善,パラメータのカスタマイズ性の強さであり,特に短期間の取引に適しています.
/*backtest
start: 2025-01-01 00:00:00
end: 2025-03-31 00:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
strategy("Reversal & Breakout Strategy with ORB", overlay=true, pyramiding=2, initial_capital=50000)
// --- Inputs ---
ema9Length = input.int(9, "9 EMA Length", minval=1)
ema20Length = input.int(20, "20 EMA Length", minval=1)
sma50Length = input.int(50, "50 SMA Length", minval=1)
sma200Length = input.int(200, "200 SMA Length", minval=1)
rsiLength = input.int(14, "RSI Length", minval=1)
rsiOverbought = input.int(70, "RSI Overbought", minval=0, maxval=100)
rsiOversold = input.int(30, "RSI Oversold", minval=0, maxval=100)
atrLength = input.int(14, "ATR Length", minval=1)
stopMulti = input.float(0.5, "Stop Loss ATR Multiplier", minval=0.1, step=0.1)
stopLookback = input.int(7, "Stop Loss Lookback", minval=1)
rr1 = input.float(0.5, "Risk:Reward Target 1", minval=0.1, step=0.1)
rr2 = input.float(1.1, "Risk:Reward Target 2", minval=0.1, step=0.1)
target1Percent = input.float(25, "Profit % Target 1", minval=0, maxval=100)
orbBars = input.int(15, "Opening Range Bars", minval=1, tooltip="Number of bars to define the opening range (e.g., 15 bars = 30 min on 2-min chart)")
volThreshold = input.float(1.5, "Volume Threshold Multiplier", minval=1.0, step=0.1, tooltip="Volume must be this multiple of the opening range average")
// --- Indicators ---
// Moving Averages
ema9 = ta.ema(close, ema9Length)
ema20 = ta.ema(close, ema20Length)
sma50 = ta.sma(close, sma50Length)
sma200 = ta.sma(close, sma200Length)
// VWAP
vwapValue = ta.vwap(close)
// RSI
rsi = ta.rsi(close, rsiLength)
// ATR
atr = ta.atr(atrLength)
// --- Opening Range Breakout ---
var float openingRangeHigh = na
var float openingRangeLow = na
var float openingRangeAvgVol = na
if bar_index < orbBars
openingRangeHigh := na
openingRangeLow := na
openingRangeAvgVol := na
else if bar_index == orbBars
openingRangeHigh := ta.highest(high, orbBars)
openingRangeLow := ta.lowest(low, orbBars)
openingRangeAvgVol := ta.sma(volume, orbBars)
orbLong = not na(openingRangeHigh) and ta.crossover(close, openingRangeHigh) and volume > openingRangeAvgVol * volThreshold
orbShort = not na(openingRangeLow) and ta.crossunder(close, openingRangeLow) and volume > openingRangeAvgVol * volThreshold
// --- Trend Detection ---
trendUp = close > sma200
trendDown = close < sma200
// --- Reversal Conditions ---
reversalLong = ta.crossover(close, sma50) and rsi < rsiOversold and close < vwapValue and trendUp
reversalShort = ta.crossunder(close, sma50) and rsi > rsiOverbought and close > vwapValue and trendDown
// --- Range Breakout Conditions ---
breakoutLong = ta.crossover(ema9, ema20) and close > vwapValue and trendUp
breakoutShort = ta.crossunder(ema9, ema20) and close < vwapValue and trendDown
// Combine conditions
longCondition = (reversalLong or breakoutLong or orbLong)
shortCondition = (reversalShort or breakoutShort or orbShort)
// --- Calculate Position Size ---
equityPerPosition = 25000.0 // $50,000 / 2 positions
positionSizeLong = math.floor(equityPerPosition / close)
positionSizeShort = math.floor(equityPerPosition / close)
// --- Stop Loss Calculation ---
longStop = ta.lowest(low, stopLookback) - (atr * stopMulti)
shortStop = ta.highest(high, stopLookback) + (atr * stopMulti)
// --- Variables to Store Trade Levels ---
var float tradeStop = na
var float tradeTarget1 = na
var float tradeTarget2 = na
var float initialPositionSize = na
var bool breakEvenSet = false // Track if stop has been moved to break-even
var float stopLevel = na // Dedicated variable for stop loss in exits
var float target1Level = na // Dedicated variable for first take profit
var float target2Level = na // Dedicated variable for second take profit
var float qtyTotal = na // Track total quantity
// --- Reset Levels Before New Trade ---
var bool newTrade = false
if longCondition or shortCondition
newTrade := true
else
newTrade := false
if strategy.position_size == 0 and newTrade
tradeStop := na
tradeTarget1 := na
tradeTarget2 := na
stopLevel := na
target1Level := na
target2Level := na
initialPositionSize := na
qtyTotal := na
breakEvenSet := false
// --- Strategy Entries ---
if longCondition and strategy.position_size == 0
strategy.entry("Long", strategy.long, qty=positionSizeLong * 2)
tradeStop := longStop
stopLevel := longStop
stopDistance = close - tradeStop
tradeTarget1 := close + (stopDistance * rr1)
tradeTarget2 := close + (stopDistance * rr2)
target1Level := tradeTarget1
target2Level := tradeTarget2
initialPositionSize := positionSizeLong * 2
qtyTotal := positionSizeLong * 2
breakEvenSet := false // Reset break-even flag
if shortCondition and strategy.position_size == 0
strategy.entry("Short", strategy.short, qty=positionSizeShort * 2)
tradeStop := shortStop
stopLevel := shortStop
stopDistance = tradeStop - close
tradeTarget1 := close - (stopDistance * rr1)
tradeTarget2 := close - (stopDistance * rr2)
target1Level := tradeTarget1
target2Level := tradeTarget2
initialPositionSize := positionSizeShort * 2
qtyTotal := positionSizeShort * 2
breakEvenSet := false // Reset break-even flag
// --- Trade Exits ---
if strategy.position_size > 0
qty_tp1 = qtyTotal * (target1Percent / 100)
qty_tp2 = qtyTotal * ((100 - target1Percent) / 100)
strategy.exit("Long Exit 1", "Long", qty=qty_tp1, stop=stopLevel, limit=target1Level)
strategy.exit("Long Exit 2", "Long", qty=qty_tp2, stop=stopLevel, limit=target2Level)
if strategy.position_size < 0
qty_tp1 = qtyTotal * (target1Percent / 100)
qty_tp2 = qtyTotal * ((100 - target1Percent) / 100)
strategy.exit("Short Exit 1", "Short", qty=qty_tp1, stop=stopLevel, limit=target1Level)
strategy.exit("Short Exit 2", "Short", qty=qty_tp2, stop=stopLevel, limit=target2Level)
// --- Move Stop to Break-even ---
if strategy.position_size != 0 and not na(initialPositionSize) and not breakEvenSet
if math.abs(strategy.position_size) < math.abs(initialPositionSize)
tradeStop := strategy.position_avg_price
stopLevel := strategy.position_avg_price
tradeTarget1 := na // Clear first target for plotting
breakEvenSet := true // Mark break-even as set
// --- Manual Close Fallback ---
if strategy.position_size > 0
if close >= target2Level or close <= stopLevel
strategy.close("Long", qty=qtyTotal, comment="Manual Close")
if strategy.position_size < 0
if close <= target2Level or close >= stopLevel
strategy.close("Short", qty=qtyTotal, comment="Manual Close")
// --- Reset Levels When No Position ---
if strategy.position_size == 0 and not newTrade
tradeStop := na
tradeTarget1 := na
tradeTarget2 := na
stopLevel := na
target1Level := na
target2Level := na
initialPositionSize := na
qtyTotal := na
breakEvenSet := false
// --- Plotting ---
plot(tradeStop, title="Stop Loss", color=color.red, linewidth=1, style=plot.style_linebr)
plot(tradeTarget1, title="Take Profit 1", color=color.green, linewidth=1, style=plot.style_linebr)
plot(tradeTarget2, title="Take Profit 2", color=color.blue, linewidth=1, style=plot.style_linebr)