
Il ne s’agit pas d’une stratégie d’analyse technique, mais d’un cadre d’investissement à long terme basé sur le cycle de demi-vie de 4 ans de Bitcoin. Les données de retracement montrent que les achats et les ventes sont effectués strictement selon les nœuds de demi-vie et que les gains maximaux d’un cycle peuvent atteindre plus de 2000%.
La logique de base est simple et grossière: acheter en réduisant de moitié, réaliser des bénéfices en lots après 40 à 80 semaines, reconstruire un entrepôt après 135 semaines. Cela semble facile, mais cela demande une volonté d’acier.
Phase 1: Réduction de moitié de la période d’achat (de 0 à 40 semaines) La mise en place d’un stock immédiatement après un événement de réduction de moitié est le point d’entrée central de toute la stratégie. Les données historiques montrent que la période d’accumulation optimale est de 40 semaines après la réduction de moitié, période pendant laquelle le sentiment du marché n’a généralement pas encore complètement réagi à la diminution de l’offre.
Phase II: La période de maturité des bénéfices (de 40 à 80 semaines) La période de 40 à 80 semaines après la demi-décision est la fenêtre d’or pour l’explosion historique du prix du bitcoin. Après la demi-décision de 2016, le bitcoin a augmenté de plus de 3000% pendant 78 semaines, ce qui est similaire après la demi-décision de 2020. Cette fenêtre de temps n’est pas une spéculation, mais une déduction mathématique basée sur les fondamentaux de l’offre et de la demande.
Phase III: La période de mise en place du marché boursier (après 135 semaines) Après 135 semaines de réduction de moitié, on entre généralement dans une période de baisse profonde, au cours de laquelle la stratégie DCA est lancée. Ce moment est préférable à un placement à l’aveugle, car il évite les inefficacités de la période de hausse.
Le plus grand risque: l’inefficacité de l’exécution Le plus grand ennemi de la stratégie n’est pas la volatilité du marché, mais la nature humaine. Acheter à moitié nécessite de faire marche arrière quand le marché est pessimiste, et gagner à moitié nécessite de rester calme pendant le carnaval. L’histoire montre que 90% des gens ne peuvent pas exécuter complètement.
Les exigences en matière de gestion des fonds Il est recommandé de ne pas investir plus de 20% du total des actifs en une seule fois, car un cycle peut faire face à plus de 80% de retraits. Le marché baissier de 2018 est passé de 20 000 \( à 3 200 \), même en achetant au “bon” moment.
Risques liés à l’évolution du marché La stratégie est basée sur trois cycles complets de données historiques, mais le marché du bitcoin est en train de mûrir. Des facteurs tels que l’afflux de fonds institutionnels, l’approbation des ETF peuvent modifier les règles cycliques traditionnelles. Les performances passées ne représentent pas les gains futurs, ce n’est pas du n’importe quoi.
Les 40 premières semainesLe prix de l’or a été réduit de moitié par rapport à l’équilibre de l’offre et de la demande historique, ce qui signifie que les bénéfices prématurés pourraient passer à côté de la hausse principale et que les bénéfices trop tardifs pourraient se situer au sommet.
Fin de 80 semaines de bénéficeLes données historiques montrent que 80 semaines après la réduction de la moitié sont des périodes de forte probabilité de pic. Il faut donc commencer à réduire les stocks par tranches et ne pas être avide de la dernière partie de la hausse.
Début de la DCA à la 135e semaineLe meilleur résultat statistique est celui de la zone inférieure de la Bourse, où le rapport risque/bénéfice est le plus élevé.
Cette stratégie est adaptée aux investisseurs ayant un cycle d’investissement de plus de 5 ans, mais pas pour les investisseurs qui ont un besoin urgent d’argent ou une faible tolérance au risque. Un seul cycle nécessite une période de fléchissement de 2 à 3 ans, ce qui est très stressant.
La stratégie gagnante ne consiste pas à prédire le prix à court terme, mais à saisir le cycle de l’offre et de la demande à long terme. La réduction de moitié du bitcoin est un événement de certitude, mais le temps et l’ampleur de la réaction des prix restent incertains.
Un rappel importantIl s’agit d’une stratégie d’investissement à haut risque, avec la possibilité de perte totale du capital. Les données historiques ne garantissent pas les gains futurs. Avant d’investir, veuillez évaluer pleinement votre capacité à supporter le risque.
/*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)