
Это не очередная стратегия технического анализа, а долгосрочная инвестиционная структура, основанная на четырехлетнем цикле полураспада биткоина. Отзывные данные показывают, что максимальная доходность за один цикл может достигать 2000% или более. Но не спешите радоваться, эта стратегия требует высокой исполнительности и рискованности.
Основная логика простая и грубая: покупать при сокращении вдвое, получать прибыль за 40 - 80 недель, восстанавливать склад через 135 недель. Звучит легко, но это требует железной воли.
Этап I: сокращение сроков покупки вдвое (от 0 до 40 недель) Основная точка входа в стратегию заключается в создании запасов сразу после события по сокращению на половину. Исторические данные показывают, что наилучший период накопления происходит в течение 40 недель после сокращения на половину, когда рыночные настроения обычно не полностью реагируют на снижение предложения.
Этап II: получение прибыли в конце срока ((40-80 недель) 40-80 недель после полуразделения - это золотая окна для исторического взрыва цены биткоина. После полуразделения в 2016 году биткойн вырос более чем на 3000% за 78 недель, а после полуразделения в 2020 году - аналогично. Это временное окно не является предположением, а основывается на математических выводах в области основ спроса и предложения.
Третий этап: период строительства биржевых позиций (после 135 недель) Спустя 135 недель после уменьшения вдвое обычно вступают в глубокие медвежие рынки, в это время запускается стратегия DCA. Этот момент выбора лучше, чем слепое фиксирование, поскольку избегается неэффективный вклад в бычьи рынки.
Самый большой риск: неэффективность Самый большой враг стратегии - не рыночные колебания, а человеческая природа. Чтобы купить в два раза меньше, нужно действовать в обратном направлении, когда рынок пессимистичен, а чтобы получить прибыль, нужно сохранять спокойствие во время балани. История показывает, что 90% людей не могут полностью выполнить.
Требования к управлению деньгами Рекомендуется вложить не более 20% от общего количества активов за один раз, так как в одном цикле может быть более 80% отступлений. В 2018 году медвежий рынок упал с 20 000 долларов до 3 200 долларов, и даже если купить в “правильное” время, вы можете понести огромные убытки.
Риск изменения рыночной среды Стратегия основана на исторических данных трех полных циклов, но биткойн-рынок созревает. Такие факторы, как приток институционального капитала, одобрение ETF, могут изменить традиционные циклические законы.
Начало 40-недельной прибылиНа основании исторического уменьшения на половину, преждевременная прибыль может пропустить основную волну, а поздняя может оказаться на пике.
80 недель прибылиИсторические данные показывают, что 80 недель после уменьшения вдвое - это высокий вероятный диапазон, когда цена достигнет максимума.
135 недель DCAВ то же время, в некоторых странах, например, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае.
Эта стратегия подходит для средств с инвестиционным циклом более пяти лет, не подходит для инвесторов, которые остро нуждаются в деньгах или имеют низкую устойчивость к риску.
Стратегическая победа заключается не в прогнозировании краткосрочной цены, а в понимании длительного цикла спроса и предложения. Половина биткоина является определенным событием, но время и степень реакции цены остаются неопределенными.
Важное напоминаниеЭто высокорисковая инвестиционная стратегия, возможна полная потеря капитала. Исторические данные не гарантируют будущую прибыль. Перед инвестированием полностью оценить свою способность нести риск.
/*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)