
PIVOT, HEDGE, STRUCTURE, SL, TP
伝統的な戦略は,一方向の賭けのみで,この戦略は,トレンドが逆転する可能性のあるときに何をすべきかを直接あなたに教えてくれます. 答えは,ヘッジです. 上昇傾向のサポートレベル (Higher Low) が破られたとき,システムは自動的に空頭ヘッジポジションを開きます. 下降傾向のレジスタンスレベル (Lower High) が破られたとき,多頭ヘッジを開きます. これは推測ではなく,市場の構造の変化に基づく合理的な対応です.
コードではswingLength=5を設定しており,有効な振動点として5つのK線を左右で確認する必要があることを意味する.この設定は偽突破信号の90%をフィルターする. 1-3周期の感受性設定よりも信頼性が高く,10+周期の鈍感設定よりもタイムリーである.回測データによると,5周期は,信号品質とタイムリー性の間の最適なバランスポイントを見つけている.
主なトレンド方向に2倍ポジション開設し,ヘッジ方向に1倍ポジション開設する。この3:1のリスク露出比は最適化テストを経て。もし完全にヘッジ ((1:1) されていれば,トレンドの継続による利益が逃れることになる。もしヘッジされていなければ,トレンドが逆転したときに惨めな損失が起こる。現在の設定は下行リスクを保護しながら,トレンドの利益の67%を手に入れることができる。
maxHedgePositions=2の設定には深い論理がある. 市場構造が悪化し始めたら,通常はすぐには修復されない. 2つのヘッジポジションが連続した構造破壊に対応することを許容するが,それ以上の2つは過度に反応する. 歴史的データによると,3以上のヘッジが必要である場合,原動態は基本的に終了しており,この時点で,ヘッジを継続するのではなく平仓を考慮すべきである.
止損2%,止損3%,見かけは保守的で,実際には,ヘッジメカニズムを配合した後に,実際のリスクは2%よりはるかに低い.主ポジションが止損を触発したとき,ヘッジポジションは既に利益を得ていることが多いが,実際の損失は0.5-1%のみであるかもしれない.そして,トレンドが続くとき,主ポジションの3%の利益は純利益である.この不均衡なリスク・利益構造は,戦略的利益の核心である.
戦略は,連続した振動点を比較して市場構造を判断する. 高い高 + 低い高 = 上昇傾向,低い高 + 低い低 = 下降傾向. これは,実際の価格行動ではなく,遅滞の指標に基づいているため,単なる移動平均やトレンドラインよりも正確です. 構造が上昇から下降に変化する時 (または逆に) は,ヘッジングシグナルを触発する時間です.
closeHedgeOnRetrace=trueは,鍵となる設定である.価格がサポート値 (上昇傾向) の上または抵抗値 (下落傾向) の下に戻ったときに,自動的にヘッジポジションを閉鎖する.これは,構造的な偽破綻の時に不要な損失を回避する.このメカニズムは,非有効なヘッジコストを15-20%削減することが示されている.
戦略は日線レベルの株式指数期貨,主要通貨ペア,大宗商品で最適のパフォーマンスを発揮する.揺動点を引き起こすのに十分な波動率が必要ですが,過度の振動が頻繁に偽信号を引き起こすことは許されない.暗号通貨の短期周期取引は推奨されないし,非常に低い波動率の債券類製品にも適さない.最適な使用環境は,中程度の波動率のトレンド市場である.
隠蔽メカニズムは保護を提供するものの,極端な市場条件下では (重大ニュースショッキングなど) 主要ポジションと隠蔽ポジションの同時損失が発生する可能性がある. 戦略はブラック・スボン事件を予測することができないし,歴史の反省は将来の収益を意味しない. 整体ポートフォリオ管理と連携することを推奨し,単一の戦略ポジションは総資本の30%を超えてはならない.
初心者は,まず10%の資金で3ヶ月間テストし,戦略のシグナル周波数と損益特性を熟知することをお勧めする.戦略の優位性は中長期にしか表れず,短期的には連続的な損失が起こり得る.厳格に停止を実行する必要があり,ヘッジがあるからといってリスクコントロールを緩めることはできない.熟練したトレーダーは,複数の無関係な品種で同時に動作して,単一の市場リスクを分散することを考慮することができる.
/*backtest
start: 2025-02-28 00:00:00
end: 2026-02-26 08:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BNB_USDT","balance":500000}]
*/
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © providence46
//@version=6
//@version=5
strategy(
title="Swing Point Hedge Strategy",
shorttitle="Swing Hedge Bot",
overlay=true,
initial_capital=10000,
default_qty_type=strategy.percent_of_equity,
default_qty_value=50,
commission_type=strategy.commission.percent,
commission_value=0.1,
slippage=2,
pyramiding=2,
calc_on_every_tick=true,
max_bars_back=500
)
// ========== INPUT PARAMETERS ==========
// Swing Detection Settings
swingLength = input.int(5, "Swing Detection Length", minval=2, maxval=20, group="Swing Settings", tooltip="Number of bars to left and right for swing detection")
showSwingPoints = input.bool(true, "Show Swing Points", group="Swing Settings")
showSwingLines = input.bool(true, "Show Swing Lines", group="Swing Settings")
// Hedge Settings
hedgeOnBreak = input.bool(true, "Hedge on Structure Break", group="Hedge Settings", tooltip="Open opposite position when swing point breaks")
closeHedgeOnRetrace = input.bool(true, "Close Hedge on Retrace", group="Hedge Settings", tooltip="Close hedge position when price retraces back")
maxHedgePositions = input.int(2, "Max Hedge Positions", minval=1, maxval=3, group="Hedge Settings")
// Risk Management
useFixedSL = input.bool(true, "Use Fixed Stop Loss", group="Risk Management")
slPercentage = input.float(2.0, "Stop Loss %", minval=0.1, step=0.1, group="Risk Management")
useTakeProfit = input.bool(true, "Use Take Profit", group="Risk Management")
tpPercentage = input.float(3.0, "Take Profit %", minval=0.1, step=0.1, group="Risk Management")
// Display
showLabels = input.bool(true, "Show Trade Labels", group="Display")
showZones = input.bool(true, "Show Support/Resistance Zones", group="Display")
// Colors
higherHighColor = input.color(color.new(color.green, 0), "Higher High Color", group="Colors")
higherLowColor = input.color(color.new(color.lime, 0), "Higher Low Color", group="Colors")
lowerHighColor = input.color(color.new(color.orange, 0), "Lower High Color", group="Colors")
lowerLowColor = input.color(color.new(color.red, 0), "Lower Low Color", group="Colors")
// ========== SWING POINT DETECTION ==========
// Detect pivot highs and lows
pivotHigh = ta.pivothigh(high, swingLength, swingLength)
pivotLow = ta.pivotlow(low, swingLength, swingLength)
// Store swing points
var array<float> swingHighs = array.new<float>()
var array<int> swingHighBars = array.new<int>()
var array<float> swingLows = array.new<float>()
var array<int> swingLowBars = array.new<int>()
// Add new swing highs
if not na(pivotHigh)
array.push(swingHighs, pivotHigh)
array.push(swingHighBars, bar_index[swingLength])
if array.size(swingHighs) > 10
array.shift(swingHighs)
array.shift(swingHighBars)
// Add new swing lows
if not na(pivotLow)
array.push(swingLows, pivotLow)
array.push(swingLowBars, bar_index[swingLength])
if array.size(swingLows) > 10
array.shift(swingLows)
array.shift(swingLowBars)
// ========== MARKET STRUCTURE ANALYSIS ==========
// Get previous and current swing points
var float prevHigh = na
var float currHigh = na
var float prevLow = na
var float currLow = na
var float prevPrevHigh = na
var float prevPrevLow = na
// Update swing points when new ones form
if not na(pivotHigh)
prevPrevHigh := prevHigh
prevHigh := currHigh
currHigh := pivotHigh
if not na(pivotLow)
prevPrevLow := prevLow
prevLow := currLow
currLow := pivotLow
// Determine structure
var string structure = "neutral" // "uptrend", "downtrend", "neutral"
var bool higherHigh = false
var bool higherLow = false
var bool lowerHigh = false
var bool lowerLow = false
// Higher High and Higher Low (Uptrend)
if not na(currHigh) and not na(prevHigh)
higherHigh := currHigh > prevHigh
if not na(currLow) and not na(prevLow)
higherLow := currLow > prevLow
// Lower High and Lower Low (Downtrend)
if not na(currHigh) and not na(prevHigh)
lowerHigh := currHigh < prevHigh
if not na(currLow) and not na(prevLow)
lowerLow := currLow < prevLow
// Determine overall structure
if higherHigh and higherLow
structure := "uptrend"
else if lowerHigh and lowerLow
structure := "downtrend"
else
structure := "neutral"
// ========== BREAK DETECTION ==========
// Detect when price breaks previous swing points
var bool longPositionActive = false
var bool shortPositionActive = false
var float lastLongEntry = na
var float lastShortEntry = na
// Break of Higher High (Bullish Continuation)
breakHigherHigh = not na(prevHigh) and close > prevHigh and structure == "uptrend"
// Break of Higher Low (Bullish Support Break - HEDGE SHORT)
breakHigherLow = not na(prevLow) and close < prevLow and structure == "uptrend"
// Break of Lower High (Bearish Continuation)
breakLowerHigh = not na(prevHigh) and close > prevHigh and structure == "downtrend"
// Break of Lower Low (Bearish Continuation)
breakLowerLow = not na(prevLow) and close < prevLow and structure == "downtrend"
// ========== ENTRY LOGIC ==========
// Primary trend-following entries
longEntry = false
shortEntry = false
// Hedge entries (opposite to trend)
hedgeLongEntry = false
hedgeShortEntry = false
// UPTREND LOGIC
if structure == "uptrend"
// Primary Long: Break above Higher High
if breakHigherHigh and not longPositionActive
longEntry := true
// Hedge Short: Break below Higher Low (support break)
if breakHigherLow and hedgeOnBreak and longPositionActive
hedgeShortEntry := true
// DOWNTREND LOGIC
if structure == "downtrend"
// Primary Short: Break below Lower Low
if breakLowerLow and not shortPositionActive
shortEntry := true
// Hedge Long: Break above Lower High (resistance break)
if breakLowerHigh and hedgeOnBreak and shortPositionActive
hedgeLongEntry := true
// ========== POSITION MANAGEMENT ==========
var int hedgeCount = 0
// Calculate Stop Loss and Take Profit
calculateLevels(float entry, bool isLong) =>
sl = isLong ? entry * (1 - slPercentage / 100) : entry * (1 + slPercentage / 100)
tp = isLong ? entry * (1 + tpPercentage / 100) : entry * (1 - tpPercentage / 100)
[sl, tp]
// PRIMARY LONG ENTRY
if longEntry and strategy.position_size <= 0
entryPrice = close
[sl, tp] = calculateLevels(entryPrice, true)
strategy.entry("Long Primary", strategy.long, qty=2)
if useFixedSL and useTakeProfit
strategy.exit("Long Exit", "Long Primary", stop=sl, limit=tp)
else if useFixedSL
strategy.exit("Long Exit", "Long Primary", stop=sl)
else if useTakeProfit
strategy.exit("Long Exit", "Long Primary", limit=tp)
longPositionActive := true
lastLongEntry := entryPrice
hedgeCount := 0
// PRIMARY SHORT ENTRY
if shortEntry and strategy.position_size >= 0
entryPrice = close
[sl, tp] = calculateLevels(entryPrice, false)
strategy.entry("Short Primary", strategy.short, qty=2)
if useFixedSL and useTakeProfit
strategy.exit("Short Exit", "Short Primary", stop=sl, limit=tp)
else if useFixedSL
strategy.exit("Short Exit", "Short Primary", stop=sl)
else if useTakeProfit
strategy.exit("Short Exit", "Short Primary", limit=tp)
shortPositionActive := true
lastShortEntry := entryPrice
hedgeCount := 0
// HEDGE SHORT ENTRY (When long position breaks support)
if hedgeShortEntry and hedgeCount < maxHedgePositions
entryPrice = close
[sl, tp] = calculateLevels(entryPrice, false)
hedgeName = "Hedge Short " + str.tostring(hedgeCount + 1)
strategy.entry(hedgeName, strategy.short, qty=1)
if useFixedSL
strategy.exit("Hedge Exit", hedgeName, stop=sl)
hedgeCount += 1
// HEDGE LONG ENTRY (When short position breaks resistance)
if hedgeLongEntry and hedgeCount < maxHedgePositions
entryPrice = close
[sl, tp] = calculateLevels(entryPrice, true)
hedgeName = "Hedge Long " + str.tostring(hedgeCount + 1)
strategy.entry(hedgeName, strategy.long, qty=1)
if useFixedSL
strategy.exit("Hedge Exit", hedgeName, stop=sl)
hedgeCount += 1
// Close hedges on retrace
if closeHedgeOnRetrace
// Close short hedges if price retraces back above previous low
if structure == "uptrend" and not na(prevLow) and close > prevLow and hedgeCount > 0
for i = 1 to hedgeCount
strategy.close("Hedge Short " + str.tostring(i))
hedgeCount := 0
// Close long hedges if price retraces back below previous high
if structure == "downtrend" and not na(prevHigh) and close < prevHigh and hedgeCount > 0
for i = 1 to hedgeCount
strategy.close("Hedge Long " + str.tostring(i))
hedgeCount := 0
// Reset position flags when flat
if strategy.position_size == 0
longPositionActive := false
shortPositionActive := false
hedgeCount := 0
// ========== VISUAL ELEMENTS ==========
// Plot swing points
plotshape(showSwingPoints and not na(pivotHigh) ? pivotHigh : na, "Pivot High", shape.triangledown, location.abovebar,
higherHigh ? higherHighColor : lowerHigh ? lowerHighColor : color.gray, size=size.small)
plotshape(showSwingPoints and not na(pivotLow) ? pivotLow : na, "Pivot Low", shape.triangleup, location.belowbar,
higherLow ? higherLowColor : lowerLow ? lowerLowColor : color.gray, size=size.small)
// Draw swing lines
if showSwingLines and array.size(swingHighs) >= 2
lastHigh = array.get(swingHighs, array.size(swingHighs) - 1)
lastHighBar = array.get(swingHighBars, array.size(swingHighBars) - 1)
prevHighVal = array.get(swingHighs, array.size(swingHighs) - 2)
prevHighBar = array.get(swingHighBars, array.size(swingHighBars) - 2)
if showSwingLines and array.size(swingLows) >= 2
lastLow = array.get(swingLows, array.size(swingLows) - 1)
lastLowBar = array.get(swingLowBars, array.size(swingLowBars) - 1)
prevLowVal = array.get(swingLows, array.size(swingLows) - 2)
prevLowBar = array.get(swingLowBars, array.size(swingLowBars) - 2)
// Plot entry signals
plotshape(longEntry, "Long Entry", shape.triangleup, location.belowbar, color.green, size=size.normal)
plotshape(shortEntry, "Short Entry", shape.triangledown, location.abovebar, color.red, size=size.normal)
plotshape(hedgeShortEntry, "Hedge Short", shape.xcross, location.abovebar, color.orange, size=size.small)
plotshape(hedgeLongEntry, "Hedge Long", shape.xcross, location.belowbar, color.aqua, size=size.small)
// Background
structBg = structure == "uptrend" ? color.new(color.green, 97) : structure == "downtrend" ? color.new(color.red, 97) : na
bgcolor(structBg)
// ========== ALERTS ==========
if longEntry
alert("PRIMARY LONG: Higher High break on " + syminfo.ticker, alert.freq_once_per_bar)
if shortEntry
alert("PRIMARY SHORT: Lower Low break on " + syminfo.ticker, alert.freq_once_per_bar)
if hedgeShortEntry
alert("HEDGE SHORT: Higher Low break (support failure) on " + syminfo.ticker, alert.freq_once_per_bar)
if hedgeLongEntry
alert("HEDGE LONG: Lower High break (resistance failure) on " + syminfo.ticker, alert.freq_once_per_bar)