ビットコイン半減期サイクル戦略

HALVING DCA CYCLE
作成日: 2025-10-09 11:10:40 最終変更日: 2025-10-09 11:10:40
コピー: 10 クリック数: 166
2
フォロー
319
フォロワー

ビットコイン半減期サイクル戦略 ビットコイン半減期サイクル戦略

半減期戦略:過去データによると,平均リターンは1000%以上

これは技術分析の戦略ではなく,ビットコインの4年半減周期に基づく長期投資の枠組みである. 回顧データによると,半減時間ノードを厳格に順守して取引を行うことで,単周期で最高リターンは2000%以上に達する. しかし,急に興奮しないでください. この戦略は,非常に強力な実行力とリスク承受力を必要とします.

中核の論理は単純で粗です 半分に減った時に購入し,40〜80週間後に分量で利益を得て,135週間後に倉庫を再建します. 簡単そうですが,それを行うには鉄の意志が必要です.

3段階の操作フレームワーク:伝統的な定投よりも正確なタイミング

ステージ1:購入期間を半分に減らします (0-40週間) 半減の発生直後に倉庫を建設することは,全戦略の核心的な入口点である. 半減の後の40週間の期間が,市場情緒が通常供給の減少の影響に完全に反応していないときに,最高の蓄積期であることを示している.

ステージII:利潤の結束 ((40〜80週間) 減半後の40〜80週は,ビットコインの価格が爆発した黄金の窓である. 2016年の減半後の78週は,ビットコインが3000%以上上昇し,2020年の減半後の同様の状況である. この時間窓は推測ではなく,供給・需要の基本に基づいた数学的な推論である.

第3段階:熊市建置期 ((135週間後) 半減後135週は通常,深部熊市に入り,この時点でDCA戦略を起動する.このタイミングは,牛市高点の無効投入を回避したため,盲投よりも良い選択である.

リスク管理: 安定した勝利戦略ではなく,厳格な規律が必要

リスクの最大は 執行力不足 戦略の最大の敵は市場の波動ではなく,人間の性質である. 減半時に買い,市場の悲観的な時に逆操作し,利益を得るために狂気の時に冷静に保つ必要がある. 歴史は,90%の人が完全に実行できないことを示している.

資金管理要求 単一のサイクルで80%以上の引き下げが起こり得るため,総資産の20%を超えないようにお勧めします. 2018年の熊市は2万ドルから3200ドルまで下がり, “正しい”タイミングで購入しても大きな浮動損失を負います.

市場環境の変化のリスク 戦略は,過去3つの完全なサイクルデータに基づいているが,ビットコイン市場は成熟している. 機関資金の流入,ETFの承認などの要因は,従来のサイクル法則を変えることができる. 過去のパフォーマンスは,将来の収益を意味しない,これは空談ではない.

パラメータ設定:数学モデルに基づく主観的な判断ではなく

40週間の利益の始まり価格の上昇は,過去半分の供給と需要の均衡点から計算すると, 利益が早すぎると, 利益の上昇が遅すぎると, 利益の上昇が遅くなる.

80週間の利益の終わり株価が半減後80週は高値の確率の区間であり,この時期は,株価の上昇を貪るのではなく,株価を減量し始める必要があります.

135週DCA開始熊市の下部地域では統計的に最適解で,この時点で投資を始めるリスクと利益の比率が最適である.

長期投資者向けで,短期取引には向かない

この戦略は,5年以上の投資サイクルを持つ資金に適しており,お金の急需やリスクの承受能力が低い投資家に適していません.単一のサイクルには2-3年の浮動期が必要であり,心理的ストレスが大きいです.

戦略の勝利率は,短期的な価格を予測することではなく,長期の需要・供給サイクルを把握することにある.ビットコインの半減は確実な出来事であるが,価格反応の時間と幅は依然として不確実である.

重要なこと:これは高リスクの投資戦略で,資本の全損失の可能性がある. 過去の反省データは将来の収益を保証するものではありません.投資する前に,自身のリスク承受能力を十分に評価してください.

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

//@version=6
strategy(title='Bitcoin Halving Cycle Profit - Backtesting', shorttitle='BTC Halv', overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100, initial_capital=10000, commission_type=strategy.commission.percent, commission_value=0.1)

// ════════════════════════════════════════════════════════════════════════════════════════════════
// CONFIGURATION & INPUTS
// ════════════════════════════════════════════════════════════════════════════════════════════════

// Backtesting Settings
enableBacktesting = input.bool(true, "Enable Backtesting", group="Backtesting Settings")
enableShortTrades = input.bool(true, "Enable Short Trades", group="Backtesting Settings")
positionSize = input.float(100, "Position Size (%)", minval=10, maxval=100, group="Backtesting Settings")
slippage = input.float(0.05, "Slippage (%)", minval=0, maxval=1, group="Backtesting Settings")

// Main Settings
showHalvingLines = input.bool(true, "Show Halving Lines", group="Display Options")
showProfitZones = input.bool(true, "Show Profit Zones", group="Display Options")
showBackgroundGradient = input.bool(true, "Show Background Gradient", group="Display Options")
showLabels = input.bool(true, "Show Labels", group="Display Options")
showDCAZone = input.bool(true, "Show DCA Zone", group="Display Options")
showInfoTable = input.bool(true, "Show Info Table", group="Display Options")
showTradeSignals = input.bool(true, "Show Trade Signals", group="Display Options")

// Table Settings
tablePosition = input.string("Top Right", "Table Position", options=["Top Left", "Top Right", "Bottom Left", "Bottom Right"], group="Table Settings")
tableSize = input.string("Normal", "Table Size", options=["Small", "Normal", "Large"], group="Table Settings")
tableTransparency = input.int(10, "Table Transparency", minval=0, maxval=50, group="Table Settings")

// Professional Dark Theme Color Scheme
colorHalving = input.color(color.new(#ff6b35, 0), "Halving Line Color", group="Colors")
colorProfitStart = input.color(color.new(#4ecdc4, 0), "Profit Start Color", group="Colors")
colorProfitEnd = input.color(color.new(#ff6b6b, 0), "Profit End Color", group="Colors")
colorDCA = input.color(color.new(#ffd93d, 0), "DCA Color", group="Colors")
colorBackground = input.color(color.new(#4ecdc4, 92), "Background Color", group="Colors")

// Timing Settings
profitStartWeeks = input.int(40, "Profit Start (Weeks)", minval=1, group="Timing")
profitEndWeeks = input.int(80, "Profit End (Weeks)", minval=1, group="Timing")
dcaStartWeeks = input.int(135, "DCA Start (Weeks)", minval=1, group="Timing")

// ════════════════════════════════════════════════════════════════════════════════════════════════
// HELPER FUNCTIONS
// ════════════════════════════════════════════════════════════════════════════════════════════════

// Get table position
getTablePosition() =>
    switch tablePosition
        "Top Left" => position.top_left
        "Top Right" => position.top_right
        "Bottom Left" => position.bottom_left
        "Bottom Right" => position.bottom_right
        => position.top_right

// Get table text size
getTableTextSize() =>
    switch tableSize
        "Small" => size.tiny
        "Normal" => size.small
        "Large" => size.normal
        => size.small

// Get table header text size
getTableHeaderSize() =>
    switch tableSize
        "Small" => size.small
        "Normal" => size.normal
        "Large" => size.large
        => size.normal

// Calculate weeks from halving date
weeksFromHalving(halvingTimestamp) =>
    (time - halvingTimestamp) / (7 * 24 * 60 * 60 * 1000)

// Check if current time is within profit zone
inProfitZone(halvingTimestamp) =>
    weeks = weeksFromHalving(halvingTimestamp)
    weeks >= profitStartWeeks and weeks <= profitEndWeeks

// Check if current time is within DCA zone  
inDCAZone(halvingTimestamp) =>
    weeks = weeksFromHalving(halvingTimestamp)
    weeks >= dcaStartWeeks

// ════════════════════════════════════════════════════════════════════════════════════════════════
// HALVING DATES & DATA
// ════════════════════════════════════════════════════════════════════════════════════════════════

// Historical halving dates
halving1 = timestamp(2012, 11, 28)
halving2 = timestamp(2016, 7, 9)
halving3 = timestamp(2020, 5, 11)
halving4 = timestamp(2024, 4, 19)

// Store halving data
type HalvingData
    float timestamp
    string label
    string emoji
    color lineColor

halvings = array.new<HalvingData>()
array.push(halvings, HalvingData.new(halving1, "1st Halving\n2012", "⛏️", colorHalving))
array.push(halvings, HalvingData.new(halving2, "2nd Halving\n2016", "⛏️⛏️", colorHalving))
array.push(halvings, HalvingData.new(halving3, "3rd Halving\n2020", "⛏️⛏️⛏️", colorHalving))
array.push(halvings, HalvingData.new(halving4, "4th Halving\n2024", "⛏️⛏️⛏️⛏️", colorHalving))

// Get current cycle status
getCurrentCycleStatus() =>
    var string result = "⏳ Pre-Halving Phase"
    for i = array.size(halvings) - 1 to 0 by 1
        halvingData = array.get(halvings, i)
        if time >= halvingData.timestamp
            weeks = weeksFromHalving(halvingData.timestamp)
            if weeks <= profitStartWeeks
                result := "🔶 Accumulation Phase"
                break
            else if weeks <= profitEndWeeks
                result := "🟢 Profit Taking Phase"
                break
            else if weeks <= dcaStartWeeks
                result := "⚠️ Bear Market Phase"
                break
            else
                result := "🟡 DCA Phase"
                break
    result

// Get weeks until next phase
getWeeksUntilNextPhase() =>
    var float result = na
    for i = array.size(halvings) - 1 to 0 by 1
        halvingData = array.get(halvings, i)
        if time >= halvingData.timestamp
            weeks = weeksFromHalving(halvingData.timestamp)
            if weeks <= profitStartWeeks
                result := profitStartWeeks - weeks
                break
            else if weeks <= profitEndWeeks
                result := profitEndWeeks - weeks
                break
            else if weeks <= dcaStartWeeks
                result := dcaStartWeeks - weeks
                break
            else
                result := na
                break
    result

// Get next phase date
getNextPhaseDate() =>
    var float result = na
    for i = array.size(halvings) - 1 to 0 by 1
        halvingData = array.get(halvings, i)
        if time >= halvingData.timestamp
            weeks = weeksFromHalving(halvingData.timestamp)
            if weeks <= profitStartWeeks
                result := halvingData.timestamp + (profitStartWeeks * 7 * 24 * 60 * 60 * 1000)
                break
            else if weeks <= profitEndWeeks
                result := halvingData.timestamp + (profitEndWeeks * 7 * 24 * 60 * 60 * 1000)
                break
            else if weeks <= dcaStartWeeks
                result := halvingData.timestamp + (dcaStartWeeks * 7 * 24 * 60 * 60 * 1000)
                break
            else
                result := na
                break
    result

// Get current phase name
getCurrentPhaseName() =>
    var string result = "Pre-Halving"
    for i = array.size(halvings) - 1 to 0 by 1
        halvingData = array.get(halvings, i)
        if time >= halvingData.timestamp
            weeks = weeksFromHalving(halvingData.timestamp)
            if weeks <= profitStartWeeks
                result := "Accumulation"
                break
            else if weeks <= profitEndWeeks
                result := "Profit Taking"
                break
            else if weeks <= dcaStartWeeks
                result := "Bear Market"
                break
            else
                result := "DCA"
                break
    result

// Get next phase name
getNextPhaseName() =>
    var string result = "Accumulation"
    for i = array.size(halvings) - 1 to 0 by 1
        halvingData = array.get(halvings, i)
        if time >= halvingData.timestamp
            weeks = weeksFromHalving(halvingData.timestamp)
            if weeks <= profitStartWeeks
                result := "Profit Taking"
                break
            else if weeks <= profitEndWeeks
                result := "Bear Market"
                break
            else if weeks <= dcaStartWeeks
                result := "DCA"
                break
            else
                result := "Next Halving"
                break
    result

// Get phase countdown variables
getPhaseCountdown() =>
    var float currentHalvingTimestamp = na
    var float profitStartWeeksLeft = na
    var float profitEndWeeksLeft = na
    var float dcaStartWeeksLeft = na
    var string profitStartDateText = "N/A"
    var string profitEndDateText = "N/A"
    var string dcaStartDateText = "N/A"
    var string nextPhaseName = "N/A"
    var string nextPhaseDateText = "N/A"
    
    for i = array.size(halvings) - 1 to 0 by 1
        halvingData = array.get(halvings, i)
        if time >= halvingData.timestamp
            currentHalvingTimestamp := halvingData.timestamp
            weeks = weeksFromHalving(halvingData.timestamp)
            
            // Calculate countdowns
            profitStartWeeksLeft := profitStartWeeks - weeks
            profitEndWeeksLeft := profitEndWeeks - weeks
            dcaStartWeeksLeft := dcaStartWeeks - weeks
            
            // Calculate dates
            profitStartDate = halvingData.timestamp + (profitStartWeeks * 7 * 24 * 60 * 60 * 1000)
            profitEndDate = halvingData.timestamp + (profitEndWeeks * 7 * 24 * 60 * 60 * 1000)
            dcaStartDate = halvingData.timestamp + (dcaStartWeeks * 7 * 24 * 60 * 60 * 1000)
            
            profitStartDateText := str.format("{0,date,yyyy-MM-dd}", profitStartDate)
            profitEndDateText := str.format("{0,date,yyyy-MM-dd}", profitEndDate)
            dcaStartDateText := str.format("{0,date,yyyy-MM-dd}", dcaStartDate)
            
            // Get next phase
            if weeks <= profitStartWeeks
                nextPhaseName := "Profit Taking"
                nextPhaseDateText := profitStartDateText
                break
            else if weeks <= profitEndWeeks
                nextPhaseName := "Bear Market"
                nextPhaseDateText := profitEndDateText
                break
            else if weeks <= dcaStartWeeks
                nextPhaseName := "DCA"
                nextPhaseDateText := dcaStartDateText
                break
            else
                nextPhaseName := "Next Halving"
                nextPhaseDateText := "N/A"
                break
    
    [profitStartWeeksLeft, profitEndWeeksLeft, dcaStartWeeksLeft, profitStartDateText, profitEndDateText, dcaStartDateText, nextPhaseName, nextPhaseDateText]

// ════════════════════════════════════════════════════════════════════════════════════════════════
// BACKTESTING LOGIC
// ════════════════════════════════════════════════════════════════════════════════════════════════

// Variables for tracking signals
var bool longSignal = false
var bool shortSignal = false
var bool buyAtHalving = false
var bool buyAtDCA = false
var bool sellAtProfitEnd = false
var bool shortAtProfitEnd = false
var bool coverAtDCA = false

// Reset signals
longSignal := false
shortSignal := false
buyAtHalving := false
buyAtDCA := false
sellAtProfitEnd := false
shortAtProfitEnd := false
coverAtDCA := false

// Check for buy signals (Halving and DCA zones)
for i = 0 to array.size(halvings) - 1
    halvingData = array.get(halvings, i)
    weeks = weeksFromHalving(halvingData.timestamp)
    
    // Buy at halving (within 1 week of halving)
    if math.abs(weeks) < 1 and weeks >= 0
        buyAtHalving := true
        longSignal := true
    
    // Buy at DCA start
    if math.abs(weeks - dcaStartWeeks) < 0.5
        buyAtDCA := true
        longSignal := true
    
    // Sell at profit end
    if math.abs(weeks - profitEndWeeks) < 0.5
        sellAtProfitEnd := true
        if enableShortTrades
            shortAtProfitEnd := true
            shortSignal := true
    
    // Cover short at DCA (same time as long entry)
    if math.abs(weeks - dcaStartWeeks) < 0.5 and enableShortTrades
        coverAtDCA := true

// Execute trades
if enableBacktesting
    // Long entries
    if longSignal and (buyAtHalving or buyAtDCA)
        strategy.close("SHORT", comment="Cover Short")
        strategy.entry("LONG", strategy.long, qty=positionSize/100 * strategy.equity/close, comment=buyAtHalving ? "Buy at Halving" : "Buy at DCA")
    
    // Long exit and short entry
    if sellAtProfitEnd and strategy.position_size > 0
        strategy.close("LONG", comment="Sell at Profit End")
        if enableShortTrades and shortAtProfitEnd
            strategy.entry("SHORT", strategy.short, qty=positionSize/100 * strategy.equity/close, comment="Short at Profit End")
    
    // Short cover (already handled above with long entry)

// ════════════════════════════════════════════════════════════════════════════════════════════════
// VISUAL ELEMENTS
// ════════════════════════════════════════════════════════════════════════════════════════════════

// Trade signals visualization
if showTradeSignals
    if longSignal and buyAtHalving
        label.new(bar_index, low, "🟢 BUY\nHALVING", style=label.style_label_up, color=color.new(color.green, 0), textcolor=color.white, size=size.normal)
    
    if longSignal and buyAtDCA
        label.new(bar_index, low, "🟢 BUY\nDCA", style=label.style_label_up, color=color.new(color.green, 0), textcolor=color.white, size=size.normal)
    
    if sellAtProfitEnd
        label.new(bar_index, high, "🔴 SELL\nPROFIT END", style=label.style_label_down, color=color.new(color.red, 0), textcolor=color.white, size=size.normal)
    
    if shortAtProfitEnd and enableShortTrades
        label.new(bar_index, high, "🔴 SHORT\nPROFIT END", style=label.style_label_down, color=color.new(color.orange, 0), textcolor=color.white, size=size.normal)

// Background gradient for profit zones
var bool showBgGradient = false
if showBackgroundGradient
    for i = 0 to array.size(halvings) - 1
        halvingData = array.get(halvings, i)
        if inProfitZone(halvingData.timestamp)
            showBgGradient := true
            break
        else
            showBgGradient := false

bgcolor(showBackgroundGradient and showBgGradient ? colorBackground : na)


// ════════════════════════════════════════════════════════════════════════════════════════════════
// PROFESSIONAL DARK THEME TABLE - ALWAYS VISIBLE
// ════════════════════════════════════════════════════════════════════════════════════════════════

// Get position variables
var string currentPosition = "FLAT"
var color positionColor = color.new(#cccccc, 0)
var string positionEmoji = "⚪"

// Update position variables
currentPosition := strategy.position_size > 0 ? "LONG" : strategy.position_size < 0 ? "SHORT" : "FLAT"
positionColor := strategy.position_size > 0 ? color.new(#00ff88, 0) : strategy.position_size < 0 ? color.new(#ff4444, 0) : color.new(#cccccc, 0)
positionEmoji := strategy.position_size > 0 ? "🟢" : strategy.position_size < 0 ? "🔴" : "⚪"

// Get phase countdown data
[profitStartWeeksLeft, profitEndWeeksLeft, dcaStartWeeksLeft, profitStartDateText, profitEndDateText, dcaStartDateText, nextPhaseName, nextPhaseDateText] = getPhaseCountdown()

// ════════════════════════════════════════════════════════════════════════════════════════════════
// ALERTS
// ════════════════════════════════════════════════════════════════════════════════════════════════

// Enhanced alerts with trade signals
for i = 0 to array.size(halvings) - 1
    halvingData = array.get(halvings, i)
    weeks = weeksFromHalving(halvingData.timestamp)
    
    if math.abs(weeks) < 0.1 and weeks >= 0
        alert("🟢 Bitcoin Halving Cycle: BUY SIGNAL at halving event!", alert.freq_once_per_bar)
    
    if math.abs(weeks - profitEndWeeks) < 0.1
        alert("🔴 Bitcoin Halving Cycle: SELL SIGNAL - Last call for profit taking! (" + str.tostring(profitEndWeeks) + " weeks post-halving)", alert.freq_once_per_bar)
    
    if math.abs(weeks - dcaStartWeeks) < 0.1
        alert("🟡 Bitcoin Halving Cycle: BUY SIGNAL - DCA accumulation phase has begun! (" + str.tostring(dcaStartWeeks) + " weeks post-halving)", alert.freq_once_per_bar)