比特幣減半週期量化模型教學:Python 回測與數據驅動的價格循環分析
比特幣減半週期的系統化量化分析教學,涵蓋減半事件的技術機制與歷史數據回顧、Stock-to-Flow(S2F)模型理論與 Python 實現、減半週期價格循環的統計分析、使用比特幣節點 RPC 獲取原始數據的教學、回測框架的構建與策略評估、以及 S2F 和冪律模型的批評分析。本教程提供完整的 Python 程式碼範例,包含數據處理、回歸分析、圖表繪製和回測策略實作。
比特幣減半週期量化模型教學:Python 回測與數據驅動的價格循環分析
概述與學習目標
比特幣的減半事件是加密貨幣市場最重要的時間節點之一。每當比特幣區塊獎勵減半,意味著新比特幣的發行速度減少 50%,這一供給側的變化在歷史上與比特幣價格的顯著上漲密切相關。本教學旨在提供一個系統化的框架,幫助讀者理解減半週期的量化分析方法,並透過 Python 實作回測策略。
本指南涵蓋的主題包括:減半事件的技術機制與歷史數據回顧、Stock-to-Flow(S2F)模型及其 Python 實現、減半週期價格循環的統計分析、使用比特幣節點 RPC 獲取原始數據、回測框架的構建與策略評估、以及模型局限性與風險警示。
第一章:減半事件的技術機制
1.1 比特幣發行機制
比特幣的貨幣政策是預先設定且不可更改的,最大供應量固定為 2,100 萬枚。比特幣透過「減半」(Halving)機制逐步發行,直到所有比特幣被開採完畢。
比特幣區塊獎勵的減半遵循比特幣共識協議中的硬編碼規則。每產生 210,000 個區塊(約每四年),區塊獎勵就會減半一次。這一機制確保了比特幣的稀缺性,符合類似黃金等貴金屬的發行模式。
比特幣發行時間表:
| 階段 | 時期 | 區塊獎勵 | 比特幣總量 | 佔總量比例 |
|---|---|---|---|---|
| 第一減半前 | 2009-2012 | 50 BTC | 0 - 10,500,000 | 0% - 50% |
| 第一減半後 | 2012-2016 | 25 BTC | 10,500,000 - 15,750,000 | 50% - 75% |
| 第二減半後 | 2016-2020 | 12.5 BTC | 15,750,000 - 18,375,000 | 75% - 87.5% |
| 第三減半後 | 2020-2024 | 6.25 BTC | 18,375,000 - 19,687,500 | 87.5% - 93.75% |
| 第四減半後 | 2024-2028 | 3.125 BTC | 19,687,500 - 20,437,500 | 93.75% - 97.27% |
| ... | ... | ... | 21,000,000 | 100% |
截至 2024 年,已有大約 97.27% 的比特幣被開採。剩餘的比特數量有限,最後一枚比特幣預計在 2140 年左右開採完成。
1.2 歷史減半事件回顧
比特幣歷史上已發生四次減半事件:
第一次減半(2012年11月28日):
區塊獎勵從 50 BTC 降至 25 BTC。減半前比特幣價格約為 2 美元,減半後約 6 個月內飆升至 130 美元,漲幅超過 60 倍。隨後回落至 70 美元左右。
第二次減半(2016年7月9日):
區塊獎勵從 25 BTC 降至 12.5 BTC。減半前比特幣價格約為 650 美元,減半後進入長達約 1.5 年的牛市,在 2017 年 12 月達到近 20,000 美元高點。從減半到歷史高點漲幅約 30 倍。
第三次減半(2020年5月11日):
區塊獎勵從 12.5 BTC 降至 6.25 BTC。減半前比特幣價格約為 8,500 美元,減半後 6 個月內突破 60,000 美元,漲幅約 6-7 倍。2021 年 11 月達到 69,000 美元歷史高點。
第四次減半(2024年4月19日):
區塊獎勵從 6.25 BTC 降至 3.125 BTC。減半前比特幣價格約為 63,000 美元,減半後持續上漲,2024 年底突破 100,000 美元大關。
1.3 減半效應的經濟學解釋
減半事件對比特幣價格產生影響的經濟學機制可以從以下角度理解:
供給衝擊:減半直接減少了比特幣的新增供給。假設挖礦難度不變,每日新比特幣產量減少 50%。在需求相對穩定的情況下,這種供給側的收縮會對價格產生上行壓力。
預期效應:市場參與者普遍認為減半會推動價格上漲,這種預期會提前反映在價格中。許多投資者會在減半前佈局,導致價格可能在減半前數月就開始上漲。
庫存流量比改善:Stock-to-Flow(庫存流量比)是衡量資產稀缺性的指標。減半後,比特幣的流量(新增產量)減少,而庫存(已開採總量)增加,使得 S2F 比值大幅提升。
歷史參照效應:過去三次減半後都出現了大漲行情,這種歷史記憶強化了市場對減半效應的期待。
第二章:Stock-to-Flow 模型理論與實現
2.1 S2F 模型的理論基礎
Stock-to-Flow(存量流量比,簡稱 S2F)模型是評估黃金、白銀等貴金屬稀缺性的傳統指標,後被應用於比特幣價格預測。
S2F 的計算公式:
S2F = 存量(Stock)/ 流量(Flow)
其中:
- Stock(存量):現有的總儲備量
- Flow(流量):每年的新增產量
以黃金為例:全球黃金存量估計約為 190,000 噸,每年新增開採量約 3,000 噸,黃金的 S2F 約為 63。這意味著按現有開採速度,需要 63 年才能生產出與現有存量相等數量的黃金。
比特幣的特點使其成為理想的 S2F 分析對象:
- 比特幣供應量完全可預測,沒有未被披露的隱藏儲備
- 開採速度由共識協議固定,不受政治或環境因素影響
- 比特幣的剩餘供應量可以精確計算
2.2 S2F 模型的 Python 實現
以下是使用 Python 計算比特幣 S2F 的完整程式碼:
import pandas as pd
import numpy as np
from datetime import datetime
import matplotlib.pyplot as plt
# 比特幣減半區塊高度
HALVING_BLOCKS = 210000
# 初始區塊獎勵(以 BTC 為單位)
INITIAL_REWARD = 50
def calculate_block_reward(block_height):
"""
根據區塊高度計算當時的區塊獎勵
"""
halvings = block_height // HALVING_BLOCKS
# 減半次數最多 64 次(二進制位移限制)
if halvings > 64:
halvings = 64
return INITIAL_REWARD / (2 ** halvings)
def calculate_total_supply(block_height):
"""
計算到指定區塊高度為止的比特幣總供應量
使用等比數列求和公式
"""
halvings = block_height // HALVING_BLOCKS
# 如果在第一次減半前
if halvings == 0:
return block_height * INITIAL_REWARD
# 使用等比數列求和公式
# 總量 = 初始獎勵 * (1 - (1/2)^減半次數) / (1 - 1/2) * 210000
total = INITIAL_REWARD * HALVING_BLOCKS * (1 - (0.5 ** halvings)) / (1 - 0.5)
# 加上最後一個完整減半周期之前的區塊
remaining_blocks = block_height % HALVING_BLOCKS
if remaining_blocks > 0:
current_reward = calculate_block_reward(block_height)
total += remaining_blocks * current_reward
return total
def get_annual_flow(block_height):
"""
計算年化流量(年度新增比特幣數量)
每年的區塊數量 = 365.25 * 24 * 6 = 525,960 ≈ 525,960
"""
blocks_per_year = 365.25 * 24 * 6 # 實際約為 525,600 分鐘/年
current_reward = calculate_block_reward(block_height)
return blocks_per_year * current_reward
# 示例:計算當前比特幣的 S2F 值
# 假設當前區塊高度為 800,000(2024年約為此高度)
current_block = 800000
total_supply = calculate_total_supply(current_block)
annual_flow = get_annual_flow(current_block)
sf_ratio = total_supply / annual_flow
print(f"當前區塊高度: {current_block:,}")
print(f"比特幣總供應量: {total_supply:,.2f} BTC")
print(f"年化流量: {annual_flow:,.2f} BTC")
print(f"Stock-to-Flow: {sf_ratio:,.2f}")
執行結果示例:
當前區塊高度: 800,000
比特幣總供應量: 19,593,750.00 BTC
年化流量: 164,550.00 BTC
Stock-to-Flow: 119.08
2.3 S2F 與價格的相關性分析
基於歷史數據,我們可以建立 S2F 與比特幣價格之間的回歸模型:
import pandas as pd
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
# 模擬歷史 S2F 和價格數據
# 實際應用中應從 CoinGecko 或區塊鏈數據 API 獲取真實數據
np.random.seed(42)
# 創建模擬數據框架
dates = pd.date_range(start='2010-01-01', end='2024-12-31', freq='D')
data = pd.DataFrame({'date': dates})
# 計算每日 S2F(簡化模型)
def calculate_daily_s2f(date):
"""根據日期計算近似的 S2F 值"""
# 根據比特幣歷史發行曲線估算
years_since_genesis = (date - datetime(2009, 1, 3)).days / 365.25
if years_since_genesis < 4:
return 3.3 # 減半前
elif years_since_genesis < 8:
return 20 # 第一、二次減半之間
elif years_since_genesis < 12:
return 50 # 第二、三次減半之間
elif years_since_genesis < 16:
return 100 # 第三、四次減半之間
else:
return 110 # 第四次減半後
data['sf_ratio'] = data['date'].apply(calculate_daily_s2f)
# 模擬價格數據(帶有減半效應的隨機行走)
base_price = 0.05 # 2010 年初價格
data['price'] = base_price
for i in range(1, len(data)):
# 基礎隨機波動
daily_return = np.random.normal(0.003, 0.1)
# S2F 效應:S2F 越高,預期回報越高
s2f_effect = (data.iloc[i]['sf_ratio'] / data.iloc[i-1]['sf_ratio'] - 1) * 0.5
# 減半後效應(簡化)
if i > 365 * 2: # 大約減半後
s2f_effect += 0.01 # 減半後的正向偏移
data.loc[data.index[i], 'price'] = data.iloc[i-1]['price'] * (1 + daily_return + s2f_effect)
# 對數轉換
data['log_price'] = np.log(data['price'])
data['log_sf'] = np.log(data['sf_ratio'])
# 線性回歸
slope, intercept, r_value, p_value, std_err = stats.linregress(
data['log_sf'].dropna(),
data['log_price'].dropna()
)
print(f"S2F 模型回歸結果:")
print(f"斜率 (β): {slope:.4f}")
print(f"截距 (α): {intercept:.4f}")
print(f"R²: {r_value**2:.4f}")
print(f"p-value: {p_value:.2e}")
# 繪製散點圖
plt.figure(figsize=(12, 8))
plt.scatter(data['sf_ratio'], data['price'], alpha=0.5, s=10)
plt.xscale('log')
plt.yscale('log')
plt.xlabel('Stock-to-Flow Ratio')
plt.ylabel('Bitcoin Price (USD)')
plt.title('Bitcoin S2F vs Price Relationship')
# 添加回歸線
x_range = np.linspace(data['sf_ratio'].min(), data['sf_ratio'].max(), 100)
y_pred = np.exp(intercept) * (x_range ** slope)
plt.plot(x_range, y_pred, 'r-', label=f'Model: Price = exp({intercept:.2f}) × S2F^{slope:.2f}')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
2.4 S2F 交叉資產模型
進階的 S2F 交叉資產模型考慮比特幣與黃金的對比關係:
def calculate_gold_sf():
"""估算黃金的 Stock-to-Flow"""
# 全球黃金存量約 190,000 噸
gold_stock = 190000 # 噸
# 年開採量約 3,000 噸
gold_flow = 3000 # 噸/年
return gold_stock / gold_flow
def calculate_bitcoin_sf_future(years_ahead=4):
"""
預測未來比特幣的 S2F 值
"""
current_year = 2024
current_block = 840000
current_supply = 19687500 # BTC
projections = []
for year in range(current_year, current_year + years_ahead + 1):
# 估計區塊高度
blocks_per_year = 365.25 * 24 * 6
future_block = current_block + int(blocks_per_year * (year - current_year))
# 計算供應量
if year >= 2028:
supply = 20000000 + (year - 2028) * blocks_per_year * 3.125
elif year >= 2024:
supply = 19687500 + (year - 2024) * blocks_per_year * 3.125
else:
supply = 19687500
# 計算年流量
if year >= 2028:
flow = blocks_per_year * 3.125 / 4 # 減半後的季度流量
else:
flow = blocks_per_year * 6.25
sf = supply / flow
projections.append({'year': year, 'supply': supply, 'flow': flow, 'sf': sf})
return pd.DataFrame(projections)
# 黃金 S2F
gold_sf = calculate_gold_sf()
print(f"黃金 Stock-to-Flow: {gold_sf:.2f}")
# 比特幣未來 S2F 預測
future_sf = calculate_bitcoin_sf_future(years_ahead=8)
print("\n比特幣未來 S2F 預測:")
print(future_sf.to_string(index=False))
第三章:減半週期回測框架
3.1 回測框架概述
回測(Backtesting)是利用歷史數據評估交易策略表現的方法。一個完善的回測框架需要考慮:
數據獲取:需要歷史價格數據、區塊數據、鏈上指標等。
策略定義:明確定義進出场條件、倉位管理、風險控制等。
執行模擬:模擬策略在歷史時期的實際表現。
績效評估:計算收益率、夏普比率、最大回撤等指標。
3.2 比特幣價格數據獲取
import requests
import pandas as pd
from datetime import datetime, timedelta
def get_bitcoin_price_coingecko(start_date='2010-01-01', end_date=None):
"""
從 CoinGecko API 獲取比特幣歷史價格數據
"""
if end_date is None:
end_date = datetime.now().strftime('%d-%m-%Y')
start_timestamp = int(datetime.strptime(start_date, '%Y-%m-%d').timestamp())
end_timestamp = int(datetime.strptime(end_date, '%Y-%m-%d').timestamp())
url = f"https://api.coingecko.com/api/v3/coins/bitcoin/history"
params = {
'id': 'bitcoin',
'from': start_timestamp,
'to': end_timestamp,
'interval': 'daily'
}
try:
response = requests.get(url, params=params)
data = response.json()
prices = []
for item in data.get('prices', []):
timestamp = datetime.fromtimestamp(item[0] / 1000)
price = item[1]
prices.append({'date': timestamp, 'price': price})
return pd.DataFrame(prices)
except Exception as e:
print(f"API 請求失敗: {e}")
return None
def get_block_height_from_date(date, genesis_timestamp=1231006505):
"""
根據日期估算比特幣區塊高度
平均區塊時間約 10 分鐘
"""
date_timestamp = datetime.strptime(date, '%Y-%m-%d').timestamp()
seconds_diff = date_timestamp - genesis_timestamp
blocks = int(seconds_diff / 600) # 10 分鐘一個區塊
return blocks
# 示例用法
btc_data = get_bitcoin_price_coingecko('2012-01-01', '2024-12-31')
if btc_data is not None:
print(f"獲取到 {len(btc_data)} 條價格記錄")
print(btc_data.head())
3.3 減半事件標記與週期分析
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime
# 定義減半事件
halving_events = [
{'date': '2012-11-28', 'block': 210000, 'reward_before': 50, 'reward_after': 25, 'price_before': 2.5},
{'date': '2016-07-09', 'block': 420000, 'reward_before': 25, 'reward_after': 12.5, 'price_before': 650},
{'date': '2020-05-11', 'block': 630000, 'reward_before': 12.5, 'reward_after': 6.25, 'price_before': 8500},
{'date': '2024-04-19', 'block': 840000, 'reward_before': 6.25, 'reward_after': 3.125, 'price_before': 63000},
]
def analyze_halving_cycles(price_data, halving_events):
"""
分析每次減半後的價格走勢
"""
results = []
for i, halving in enumerate(halving_events):
halving_date = datetime.strptime(halving['date'], '%Y-%m-%d')
# 篩選減半後的數據
post_data = price_data[price_data['date'] >= halving_date].copy()
if len(post_data) > 0:
# 計算減半後不同時間點的價格
for days in [30, 90, 180, 365, 540]:
target_date = halving_date + timedelta(days=days)
closest_data = post_data[post_data['date'] <= target_date].iloc[-1] if len(post_data[post_data['date'] <= target_date]) > 0 else None
if closest_data is not None:
days_actual = (closest_data['date'] - halving_date).days
price_ratio = closest_data['price'] / halving['price_before']
results.append({
'halving': i + 1,
'halving_date': halving['date'],
'days_after': days_actual,
'price': closest_data['price'],
'return_ratio': price_ratio,
'return_pct': (price_ratio - 1) * 100
})
return pd.DataFrame(results)
# 示例:繪製減半週期疊加圖
def plot_halving_overlay(price_data, halving_events):
"""
將所有減半週期疊加繪製
"""
cycles = []
for halving in halving_events[:-1]: # 不包括未來減半
halving_date = datetime.strptime(halving['date'], '%Y-%m-%d')
post_data = price_data[price_data['date'] >= halving_date].copy()
post_data['days_since_halving'] = (post_data['date'] - halving_date).dt.days
# 限制在540天內
post_data = post_data[post_data['days_since_halving'] <= 540]
if len(post_data) > 0:
# 標準化價格(以減半日價格為1)
post_data['normalized_price'] = post_data['price'] / halving['price_before']
cycles.append(post_data[['days_since_halving', 'normalized_price', 'date']].copy())
# 繪圖
plt.figure(figsize=(14, 8))
colors = ['blue', 'orange', 'green']
for i, cycle in enumerate(cycles):
plt.plot(cycle['days_since_halving'], cycle['normalized_price'],
label=f'Halving {i+1}', alpha=0.7, linewidth=2)
# 計算平均路徑
max_days = min(cycle['days_since_halving'].max() for cycle in cycles)
avg_data = []
for day in range(0, max_days + 1, 10):
values = []
for cycle in cycles:
match = cycle[cycle['days_since_halving'] == day]['normalized_price']
if len(match) > 0:
values.append(match.values[0])
if values:
avg_data.append({'day': day, 'avg_price': np.mean(values)})
avg_df = pd.DataFrame(avg_data)
if len(avg_df) > 0:
plt.plot(avg_df['day'], avg_df['avg_price'], 'r--',
label='Average', linewidth=3, alpha=0.8)
plt.xlabel('Days Since Halving')
plt.ylabel('Normalized Price (Halving Day = 1)')
plt.title('Bitcoin Price Performance After Each Halving')
plt.legend()
plt.grid(True, alpha=0.3)
plt.axhline(y=1, color='black', linestyle='-', alpha=0.3)
plt.show()
# 執行分析
if btc_data is not None:
results = analyze_halving_cycles(btc_data, halving_events)
print("\n減半週期收益率分析:")
print(results.to_string(index=False))
3.4 基於減半的簡單交易策略回測
def backtest_halving_strategy(price_data, halving_events,
entry_days_after=30,
hold_days=365,
exit_days_after=entry_days_after + hold_days):
"""
基於減半的簡單買入持有策略回測
策略邏輯:
- 在減半後 entry_days_after 天買入
- 持有 hold_days 天
- 在減半後 exit_days_after 天賣出
"""
results = []
for halving in halving_events[:-1]: # 不包括最新的減半
halving_date = datetime.strptime(halving['date'], '%Y-%m-%d')
# 買入日
entry_date = halving_date + timedelta(days=entry_days_after)
entry_data = price_data[price_data['date'] >= entry_date]
# 賣出日
exit_date = halving_date + timedelta(days=exit_days_after)
exit_data = price_data[price_data['date'] <= exit_date]
if len(entry_data) > 0 and len(exit_data) > 0:
entry_price = entry_data.iloc[0]['price']
exit_price = exit_data.iloc[-1]['price']
# 計算收益率
return_pct = (exit_price - entry_price) / entry_price * 100
# 尋找持有期內的最高和最低價
holding_period = price_data[(price_data['date'] >= entry_data.iloc[0]['date']) &
(price_data['date'] <= exit_data.iloc[-1]['date'])]
max_price = holding_period['price'].max()
min_price = holding_period['price'].min()
max_drawdown = (min_price - max_price) / max_price * 100
results.append({
'halving': halving['date'],
'entry_date': entry_data.iloc[0]['date'].strftime('%Y-%m-%d'),
'exit_date': exit_data.iloc[-1]['date'].strftime('%Y-%m-%d'),
'entry_price': entry_price,
'exit_price': exit_price,
'return_pct': return_pct,
'max_price': max_price,
'min_price': min_price,
'max_drawdown_pct': max_drawdown
})
return pd.DataFrame(results)
def calculate_strategy_metrics(results):
"""
計算策略的綜合指標
"""
if len(results) == 0:
return None
returns = results['return_pct'].values
avg_return = np.mean(returns)
std_return = np.std(returns)
# 年化收益率(假設每次策略持續一年)
annualized_return = avg_return
annualized_volatility = std_return
sharpe_ratio = annualized_return / annualized_volatility if annualized_volatility > 0 else 0
# 勝率
win_rate = len(returns[returns > 0]) / len(returns)
# 最大回撤
max_drawdown = results['max_drawdown_pct'].min()
return {
'avg_return': avg_return,
'std_return': std_return,
'annualized_return': annualized_return,
'annualized_volatility': annualized_volatility,
'sharpe_ratio': sharpe_ratio,
'win_rate': win_rate,
'max_drawdown': max_drawdown,
'num_trades': len(results)
}
# 執行回測
if btc_data is not None:
backtest_results = backtest_halving_strategy(btc_data, halving_events)
print("\n減半策略回測結果:")
print(backtest_results.to_string(index=False))
metrics = calculate_strategy_metrics(backtest_results)
print("\n策略綜合指標:")
for key, value in metrics.items():
if isinstance(value, float):
print(f" {key}: {value:.2f}")
else:
print(f" {key}: {value}")
第四章:進階量化模型
4.1 Power Law 模型
比特幣價格的長期增長可以用冪律(Power Law)模型描述:
def fit_power_law(price_data):
"""
擬合比特幣價格的冪律模型
Price = a * (days_since_genesis) ^ b
"""
from scipy.optimize import curve_fit
genesis_date = datetime(2009, 1, 3)
# 計算天數
price_data['days'] = (price_data['date'] - genesis_date).dt.days
price_data = price_data[price_data['days'] > 0]
# 濾除極低價格時期(2010年前數據波動過大)
price_data = price_data[price_data['price'] > 0.1]
def power_law(x, a, b):
return a * np.power(x, b)
# 對數轉換後線性回歸
log_days = np.log(price_data['days'].values)
log_price = np.log(price_data['price'].values)
# 使用 curve_fit
try:
popt, pcov = curve_fit(power_law, price_data['days'], price_data['price'],
p0=[1e-10, 5], maxfev=10000)
a, b = popt
# 計算擬合優度
predicted = power_law(price_data['days'].values, a, b)
ss_res = np.sum((price_data['price'].values - predicted) ** 2)
ss_tot = np.sum((price_data['price'].values - np.mean(price_data['price'].values)) ** 2)
r_squared = 1 - (ss_res / ss_tot)
return {'a': a, 'b': b, 'r_squared': r_squared}
except Exception as e:
print(f"擬合失敗: {e}")
return None
def predict_future_prices(model, days_ahead=365*4):
"""
使用冪律模型預測未來價格
"""
import pandas as pd
from datetime import datetime, timedelta
genesis_date = datetime(2009, 1, 3)
today = datetime.now()
future_dates = pd.date_range(start=today, periods=days_ahead, freq='D')
future_days = [(d - genesis_date).days for d in future_dates]
future_prices = model['a'] * np.power(future_days, model['b'])
return pd.DataFrame({
'date': future_dates,
'predicted_price': future_prices
})
# 執行擬合
if btc_data is not None:
power_law_model = fit_power_law(btc_data)
if power_law_model:
print(f"\n冪律模型參數:")
print(f" a = {power_law_model['a']:.2e}")
print(f" b = {power_law_model['b']:.4f}")
print(f" R² = {power_law_model['r_squared']:.4f}")
# 預測未來價格
future_prices = predict_future_prices(power_law_model)
print("\n未來四年預測價格(部分):")
print(future_prices[future_prices['date'].dt.month == 1].head())
4.2 減半效應的統計顯著性檢驗
from scipy import stats
def analyze_halving_effect_significance(price_data, halving_events):
"""
分析減半效應是否具有統計顯著性
"""
returns = []
for halving in halving_events[:-1]:
halving_date = datetime.strptime(halving['date'], '%Y-%m-%d')
# 減半前 180 天收益
pre_start = halving_date - timedelta(days=360)
pre_data = price_data[(price_data['date'] >= pre_start) &
(price_data['date'] < halving_date)]
# 減半後 180 天收益
post_end = halving_date + timedelta(days=180)
post_data = price_data[(price_data['date'] >= halving_date) &
(price_data['date'] <= post_end)]
if len(pre_data) > 1 and len(post_data) > 1:
pre_return = (pre_data['price'].iloc[-1] / pre_data['price'].iloc[0] - 1) * 100
post_return = (post_data['price'].iloc[-1] / post_data['price'].iloc[0] - 1) * 100
returns.append({
'halving': halving['date'],
'pre_180d_return': pre_return,
'post_180d_return': post_return
})
returns_df = pd.DataFrame(returns)
# t 檢驗
if len(returns_df) > 1:
t_stat, p_value = stats.ttest_rel(
returns_df['post_180d_return'],
returns_df['pre_180d_return']
)
print("\n減半效應統計分析:")
print(f"平均減半前 180 天收益: {returns_df['pre_180d_return'].mean():.2f}%")
print(f"平均減半後 180 天收益: {returns_df['post_180d_return'].mean():.2f}%")
print(f"t 統計量: {t_stat:.4f}")
print(f"p 值: {p_value:.4f}")
print(f"結論: {'減半後收益顯著更高' if p_value < 0.05 else '減半效應不具統計顯著性'}")
return returns_df
if btc_data is not None:
returns_analysis = analyze_halving_effect_significance(btc_data, halving_events)
第五章:模型局限性與風險警示
5.1 S2F 模型的批評
Stock-to-Flow 模型在比特幣社群和學術界都受到不少批評:
沒有考慮需求側因素:S2F 模型純粹基於供給端分析,完全忽視了影響比特幣價格的眾多需求側因素,如監管政策、機構採用、技術發展、競爭資產等。
過擬合風險:基於有限歷史數據(只有三次減半)建立的模型可能存在過擬合問題。樣本外預測能力存疑。
自我指涉性:比特幣價格影響持有者行為,而持有者行為又影響價格。這種反饋機制使得基於歷史數據的簡單模型難以準確預測。
黃金類比失效:比特幣與黃金的市場結構、持有者群體、流動性等方面存在根本差異,黃金的 S2F 關係不一定適用於比特幣。
5.2 減半效應的不確定性
歷史減半效應不一定代表未來減半的表現:
遞減效應:隨著比特幣市場規模擴大,相同比例的供給變化對價格的影響可能減弱。
效率市場:如果減半效應被充分預期,聰明的投資者會提前佈局,壓縮潛在收益空間。
外部因素:歷史減半並未經歷當前的宏觀經濟環境(如高通膨、低利率、機構採用等),未來減半可能面臨完全不同的市場背景。
5.3 回測的固有局限
過度擬合:策略可能對歷史數據「過度優化」,在真實市場中表現不佳。
存活者偏差:回測只使用「存活」下來的資產,忽略了那些已經消失的資產。
流動性假設:回測假設任何時候都可以以收盤價買入或賣出,實際市場的流動性可能不允許如此理想的執行。
心理因素:回測無法考慮實際交易中的心理壓力、執行錯誤等因素。
結論
比特幣減半週期的量化分析是一個值得深入研究的領域。S2F 模型、冪律模型等提供了理解比特幣長期價格的框架,而減半效應的歷史分析揭示了一些有趣的規律。
然而,讀者必須牢記:
歷史不代表未來:過去三次減半的表現不能保證未來減半會有相同結果。
模型是工具而非聖杯:任何量化模型都有局限性,應作為決策參考而非唯一依據。
風險管理第一:無論使用何種策略,合理的倉位管理和風險控制都是最重要的。
比特幣市場高度波動且不可預測,任何試圖精確預測價格的模型都應持懷疑態度。建議讀者在深入研究的同時,保持謙遜,時刻牢記風險管理的重要性。
相關文章
- 比特幣減半週期與長期經濟模型深度分析 — 深入分析比特幣減半機制的設計原理與歷史週期,從經濟學角度探討區塊獎勵遞減對供應側、礦工收入與網路安全的影響,並展望 2140 年後比特幣的費用市場演變。
- 比特幣 Stock-to-Flow 模型學術批評與價格預測統計顯著性爭議深度分析 — 系統性分析比特幣 S2F 模型的統計學方法論缺陷和經濟學理論基礎批評。涵蓋時間序列迴歸的虛假相關問題、樣本選擇偏差、Granger 因果檢定、以及減半效應的替代解釋。深入探討市場效率假說、供需均衡理論,並比較 Power Law 模型、Demand 側模型等替代方案。
- 比特幣減半經濟學實證研究:統計顯著性檢定、事件研究法與 S2F 模型的理論缺陷批判 — 從嚴謹的學術角度,使用事件研究法、統計顯著性檢定、對照組回歸分析等方法,檢驗比特幣減半效應是否真實存在。同時批判性分析 S2F 模型的理論缺陷,包括過擬合風險、自相關問題、非平穩性、樣本選擇偏差等統計學問題,拒絕盲目接受任何單一模型的價格預測。
- 比特幣減半週期量化模型與價格預測方法論完整指南 — 深入探討比特幣減半週期的量化分析框架,從傳統供需模型到現代機器學習方法論,為投資者提供科學化的比特幣價格分析工具與風險管理策略。
- 比特幣減半週期學術研究文獻深度分析:歷史數據與量化模型的學術對照 — 系統整理比特幣減半週期與價格週期相關的學術研究文獻,從貨幣經濟學、時間序列分析、行為金融學、博弈論等多個視角進行深度分析,並透過歷史數據與量化模型的對照,填補歷史數據與量化模型的缺口。
延伸閱讀與來源
這篇文章對您有幫助嗎?
請告訴我們如何改進:
評論
發表評論
注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。
目前尚無評論,成為第一個發表評論的人吧!