Chiến lược chu kỳ Halving của Bitcoin

HALVING DCA CYCLE
Ngày tạo: 2025-10-09 11:10:40 sửa đổi lần cuối: 2025-10-09 11:10:40
sao chép: 10 Số nhấp chuột: 166
2
tập trung vào
319
Người theo dõi

Chiến lược chu kỳ Halving của Bitcoin Chiến lược chu kỳ Halving của Bitcoin

Chiến lược giảm nửa chu kỳ: Dữ liệu lịch sử cho thấy lợi nhuận trung bình trên 1000%

Đây không phải là một chiến lược phân tích kỹ thuật khác, mà là một khuôn khổ đầu tư dài hạn dựa trên chu kỳ phân nửa 4 năm của Bitcoin. Dữ liệu phản hồi cho thấy: Mua và bán theo thời gian phân nửa nghiêm ngặt, lợi nhuận cao nhất trong một chu kỳ có thể lên đến 2000%.

Logic cốt lõi đơn giản và thô bạo: mua khi giảm một nửa, thu lợi nhuận theo từng đợt sau 40-80 tuần, xây dựng lại kho sau 135 tuần. Nghe có vẻ dễ dàng, nhưng cần có ý chí cứng rắn để thực hiện.

Khung hoạt động ba giai đoạn: Chọn thời điểm chính xác hơn so với dự đoán truyền thống

Giai đoạn 1: Giảm thời gian mua một nửa (0-40 tuần) Tạo kho ngay sau khi sự kiện giảm phân nửa xảy ra, điểm vào trung tâm của toàn bộ chiến lược. Dữ liệu lịch sử cho thấy 40 tuần sau khi giảm phân nửa là giai đoạn tích lũy tốt nhất, khi đó tâm trạng thị trường thường chưa phản ứng đầy đủ với ảnh hưởng của việc giảm cung.

Giai đoạn II: Kết thúc lợi nhuận ((40-80 tuần) Khoảng 40-80 tuần sau khi giảm một nửa là cửa sổ vàng trong lịch sử của giá bitcoin. 78 tuần sau khi giảm một nửa năm 2016 Bitcoin đã tăng hơn 3000% và tương tự sau khi giảm một nửa năm 2020. Cửa sổ thời gian này không phải là phỏng đoán, mà là suy luận toán học dựa trên cơ sở cung cấp và nhu cầu.

Giai đoạn 3: Thời gian xây dựng thị trường bạch kim (sau 135 tuần) 135 tuần sau khi giảm một nửa thường đi vào thị trường gấu sâu, khi đó khởi động chiến lược DCA. Lựa chọn thời gian này tốt hơn so với đầu tư mù quáng, vì tránh đầu tư không hiệu quả ở đỉnh thị trường bò.

Kiểm soát rủi ro: Không phải là chiến lược chiến thắng, cần có kỷ luật nghiêm ngặt

Rủi ro lớn nhất: thiếu thực thi Kẻ thù lớn nhất của chiến lược không phải là biến động của thị trường, mà là nhân bản. Mua bán khi giảm một nửa cần phải hoạt động ngược lại khi thị trường bi quan, và kiếm lợi nhuận cần phải giữ bình tĩnh trong lúc vui vẻ. Lịch sử cho thấy 90% người không thể thực hiện đầy đủ.

Yêu cầu quản lý tài chính Chỉ nên đầu tư không quá 20% tổng tài sản một lần, vì một chu kỳ có thể phải đối mặt với sự rút lui hơn 80%. Thị trường gấu năm 2018 đã giảm từ 20.000 USD xuống còn 3.200 USD, thậm chí phải chịu tổn thất lớn ngay cả khi mua vào thời điểm “đúng”.

Rủi ro thay đổi môi trường thị trường Chiến lược này dựa trên dữ liệu 3 chu kỳ đầy đủ trong lịch sử, nhưng thị trường Bitcoin đang trưởng thành. Các yếu tố như dòng tiền của tổ chức, sự chấp thuận của ETF có thể thay đổi quy luật chu kỳ truyền thống. Hiệu suất trong quá khứ không đại diện cho lợi nhuận trong tương lai, đây không phải là chuyện vớ vẩn.

Cài đặt tham số: dựa trên mô hình toán học thay vì phán đoán chủ quan

Bắt đầu 40 tuần lợi nhuậnTheo tính toán cân bằng cung cầu sau khi giảm một nửa lịch sử, lợi nhuận quá sớm có thể sẽ bỏ lỡ đợt tăng trưởng chính, và quá muộn có thể sẽ nằm ở điểm cao.

Kết thúc 80 tuần lợi nhuậnTrong khi đó, giá cả đã tăng mạnh trong khoảng thời gian gần đây nhất, trong khi giá cả đã giảm mạnh trong khoảng thời gian gần đây nhất, trong khoảng thời gian gần đây nhất.

135 tuần DCA khởi độngCác nhà đầu tư cho rằng thị trường này có thể có lợi nhuận tốt nhất khi bắt đầu đầu tư vào thị trường.

Lời khuyên chiến đấu: phù hợp với nhà đầu tư dài hạn, không phù hợp với giao dịch ngắn hạn

Chiến lược này phù hợp với các quỹ có chu kỳ đầu tư hơn 5 năm, không phù hợp với các nhà đầu tư đang cần tiền hoặc có khả năng chịu rủi ro thấp. Một chu kỳ cần phải chịu đựng giai đoạn lỗ hổng 2-3 năm, áp lực tâm lý rất lớn.

Chiến lược chiến thắng không phải là dự đoán giá trong ngắn hạn, mà là nắm bắt chu kỳ cung cầu dài hạn. Việc Bitcoin giảm một nửa là sự kiện chắc chắn, nhưng thời gian và mức độ phản ứng của giá vẫn còn không chắc chắn.

Một lời nhắc nhở quan trọngĐây là một chiến lược đầu tư rủi ro cao, có thể mất toàn bộ vốn. Dữ liệu phản hồi lịch sử không đảm bảo lợi nhuận trong tương lai, hãy đánh giá đầy đủ khả năng chịu rủi ro của mình trước khi đầu tư.

Mã nguồn chiến lược
/*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)