mirror of
https://github.com/luxfi/ai.git
synced 2026-10-30 17:02:43 +00:00
274 lines
10 KiB
Python
274 lines
10 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Bitcoin Tokenomics Visualization
|
|
Creates charts showing supply distribution and inflation rates over time
|
|
"""
|
|
|
|
import json
|
|
import matplotlib.pyplot as plt
|
|
import matplotlib.dates as mdates
|
|
from datetime import datetime
|
|
import numpy as np
|
|
|
|
|
|
def load_data():
|
|
"""Load the calculated tokenomics data."""
|
|
with open('/Users/z/work/lux/ai/bitcoin_tokenomics_data.json', 'r') as f:
|
|
return json.load(f)
|
|
|
|
|
|
def plot_supply_curve(data):
|
|
"""
|
|
Plot Bitcoin supply accumulation over time.
|
|
"""
|
|
schedule = data['halving_schedule']
|
|
|
|
# Extract data
|
|
years = [event['years_from_genesis'] for event in schedule]
|
|
supply = [event['cumulative_supply_btc'] for event in schedule]
|
|
|
|
# Create figure
|
|
fig, ax = plt.subplots(figsize=(14, 8))
|
|
|
|
# Plot supply curve
|
|
ax.plot(years, supply, linewidth=2.5, color='#F7931A', label='Cumulative Supply')
|
|
|
|
# Add milestone markers
|
|
milestones = [
|
|
(4, 10500000, '50%'),
|
|
(8, 15750000, '75%'),
|
|
(13.6, 18900000, '90%'),
|
|
(27, 20790000, '99%'),
|
|
(40, 20979000, '99.9%')
|
|
]
|
|
|
|
for year, supply_val, label in milestones:
|
|
ax.plot(year, supply_val, 'ro', markersize=8)
|
|
ax.annotate(label, xy=(year, supply_val), xytext=(year+2, supply_val),
|
|
fontsize=10, color='red', fontweight='bold')
|
|
|
|
# Add 21M cap line
|
|
ax.axhline(y=21000000, color='black', linestyle='--', linewidth=2,
|
|
label='21M Hard Cap', alpha=0.7)
|
|
|
|
# Formatting
|
|
ax.set_xlabel('Years from Genesis (2009)', fontsize=12, fontweight='bold')
|
|
ax.set_ylabel('Cumulative Supply (BTC)', fontsize=12, fontweight='bold')
|
|
ax.set_title('Bitcoin Supply Distribution Over Time', fontsize=16, fontweight='bold')
|
|
ax.legend(fontsize=11, loc='lower right')
|
|
ax.grid(True, alpha=0.3)
|
|
ax.set_xlim(0, 60)
|
|
ax.set_ylim(0, 22000000)
|
|
|
|
# Format y-axis
|
|
ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, p: f'{int(x/1e6)}M'))
|
|
|
|
plt.tight_layout()
|
|
plt.savefig('/Users/z/work/lux/ai/bitcoin_supply_curve.png', dpi=300, bbox_inches='tight')
|
|
print("Supply curve saved to: /Users/z/work/lux/ai/bitcoin_supply_curve.png")
|
|
|
|
|
|
def plot_inflation_rates(data):
|
|
"""
|
|
Plot inflation rate decay over time.
|
|
"""
|
|
schedule = data['halving_schedule']
|
|
|
|
# Extract data (skip epoch 0 which has infinite inflation)
|
|
valid_events = [e for e in schedule[1:30] if e['inflation_rate_percent'] != 'N/A']
|
|
years = [event['years_from_genesis'] for event in valid_events]
|
|
inflation = [event['inflation_rate_percent'] for event in valid_events]
|
|
|
|
# Create figure with two subplots
|
|
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 10))
|
|
|
|
# Plot 1: Linear scale (first 40 years)
|
|
mask = np.array(years) <= 40
|
|
ax1.plot(np.array(years)[mask], np.array(inflation)[mask],
|
|
linewidth=2.5, color='#F7931A', marker='o', markersize=6)
|
|
|
|
# Add reference lines
|
|
ax1.axhline(y=2.0, color='green', linestyle='--', linewidth=1.5,
|
|
label='Fed Target (2%)', alpha=0.7)
|
|
ax1.axhline(y=1.5, color='brown', linestyle='--', linewidth=1.5,
|
|
label='Gold (~1.5%)', alpha=0.7)
|
|
|
|
ax1.set_xlabel('Years from Genesis (2009)', fontsize=12, fontweight='bold')
|
|
ax1.set_ylabel('Annual Inflation Rate (%)', fontsize=12, fontweight='bold')
|
|
ax1.set_title('Bitcoin Inflation Rate Decay (Linear Scale)', fontsize=14, fontweight='bold')
|
|
ax1.legend(fontsize=10)
|
|
ax1.grid(True, alpha=0.3)
|
|
ax1.set_xlim(0, 40)
|
|
|
|
# Plot 2: Log scale (all epochs)
|
|
ax2.semilogy(years, inflation, linewidth=2.5, color='#F7931A',
|
|
marker='o', markersize=5)
|
|
|
|
ax2.axhline(y=2.0, color='green', linestyle='--', linewidth=1.5,
|
|
label='Fed Target (2%)', alpha=0.7)
|
|
ax2.axhline(y=1.5, color='brown', linestyle='--', linewidth=1.5,
|
|
label='Gold (~1.5%)', alpha=0.7)
|
|
|
|
ax2.set_xlabel('Years from Genesis (2009)', fontsize=12, fontweight='bold')
|
|
ax2.set_ylabel('Annual Inflation Rate (%, log scale)', fontsize=12, fontweight='bold')
|
|
ax2.set_title('Bitcoin Inflation Rate Decay (Logarithmic Scale)', fontsize=14, fontweight='bold')
|
|
ax2.legend(fontsize=10)
|
|
ax2.grid(True, alpha=0.3, which='both')
|
|
ax2.set_xlim(0, 120)
|
|
|
|
plt.tight_layout()
|
|
plt.savefig('/Users/z/work/lux/ai/bitcoin_inflation_rates.png', dpi=300, bbox_inches='tight')
|
|
print("Inflation rates saved to: /Users/z/work/lux/ai/bitcoin_inflation_rates.png")
|
|
|
|
|
|
def plot_issuance_schedule(data):
|
|
"""
|
|
Plot block reward and annual issuance over time.
|
|
"""
|
|
schedule = data['halving_schedule']
|
|
|
|
years = [event['years_from_genesis'] for event in schedule[:20]]
|
|
rewards = [event['reward_btc'] for event in schedule[:20]]
|
|
annual_issuance = [event['annual_issuance_btc'] for event in schedule[:20]]
|
|
|
|
# Create figure with two y-axes
|
|
fig, ax1 = plt.subplots(figsize=(14, 8))
|
|
|
|
color1 = '#F7931A'
|
|
ax1.set_xlabel('Years from Genesis (2009)', fontsize=12, fontweight='bold')
|
|
ax1.set_ylabel('Block Reward (BTC)', fontsize=12, fontweight='bold', color=color1)
|
|
ax1.semilogy(years, rewards, color=color1, linewidth=2.5, marker='o',
|
|
markersize=7, label='Block Reward')
|
|
ax1.tick_params(axis='y', labelcolor=color1)
|
|
ax1.grid(True, alpha=0.3, which='both')
|
|
|
|
# Second y-axis
|
|
ax2 = ax1.twinx()
|
|
color2 = 'darkblue'
|
|
ax2.set_ylabel('Annual Issuance (BTC)', fontsize=12, fontweight='bold', color=color2)
|
|
ax2.semilogy(years, annual_issuance, color=color2, linewidth=2.5,
|
|
marker='s', markersize=6, linestyle='--', label='Annual Issuance')
|
|
ax2.tick_params(axis='y', labelcolor=color2)
|
|
|
|
# Title
|
|
ax1.set_title('Bitcoin Block Reward and Annual Issuance Schedule',
|
|
fontsize=16, fontweight='bold')
|
|
|
|
# Legends
|
|
lines1, labels1 = ax1.get_legend_handles_labels()
|
|
lines2, labels2 = ax2.get_legend_handles_labels()
|
|
ax1.legend(lines1 + lines2, labels1 + labels2, loc='upper right', fontsize=11)
|
|
|
|
plt.tight_layout()
|
|
plt.savefig('/Users/z/work/lux/ai/bitcoin_issuance_schedule.png', dpi=300, bbox_inches='tight')
|
|
print("Issuance schedule saved to: /Users/z/work/lux/ai/bitcoin_issuance_schedule.png")
|
|
|
|
|
|
def plot_security_budget(data):
|
|
"""
|
|
Plot security budget projection.
|
|
"""
|
|
schedule = data['halving_schedule']
|
|
|
|
years = [event['years_from_genesis'] for event in schedule[:25]]
|
|
btc_price = 100000 # Assume $100k BTC
|
|
|
|
# Calculate security budget at different BTC prices
|
|
rewards = [event['annual_issuance_btc'] for event in schedule[:25]]
|
|
|
|
budget_50k = [r * 50000 / 1e9 for r in rewards] # In billions USD
|
|
budget_100k = [r * 100000 / 1e9 for r in rewards]
|
|
budget_200k = [r * 200000 / 1e9 for r in rewards]
|
|
|
|
# Create figure
|
|
fig, ax = plt.subplots(figsize=(14, 8))
|
|
|
|
ax.semilogy(years, budget_50k, linewidth=2.5, label='BTC = $50k', marker='o')
|
|
ax.semilogy(years, budget_100k, linewidth=2.5, label='BTC = $100k', marker='s')
|
|
ax.semilogy(years, budget_200k, linewidth=2.5, label='BTC = $200k', marker='^')
|
|
|
|
# Add critical threshold line (estimated)
|
|
ax.axhline(y=10, color='red', linestyle='--', linewidth=2,
|
|
label='Est. Min Security Budget ($10B/yr)', alpha=0.7)
|
|
|
|
ax.set_xlabel('Years from Genesis (2009)', fontsize=12, fontweight='bold')
|
|
ax.set_ylabel('Annual Security Budget (Billions USD, log scale)',
|
|
fontsize=12, fontweight='bold')
|
|
ax.set_title('Bitcoin Security Budget Projection (Block Rewards Only)',
|
|
fontsize=16, fontweight='bold')
|
|
ax.legend(fontsize=11, loc='upper right')
|
|
ax.grid(True, alpha=0.3, which='both')
|
|
ax.set_xlim(0, 100)
|
|
|
|
plt.tight_layout()
|
|
plt.savefig('/Users/z/work/lux/ai/bitcoin_security_budget.png', dpi=300, bbox_inches='tight')
|
|
print("Security budget saved to: /Users/z/work/lux/ai/bitcoin_security_budget.png")
|
|
|
|
|
|
def plot_supply_distribution(data):
|
|
"""
|
|
Plot distribution of supply across epochs.
|
|
"""
|
|
schedule = data['halving_schedule']
|
|
|
|
epochs = [event['halving'] for event in schedule[:10]]
|
|
supply_per_epoch = []
|
|
|
|
for i in range(10):
|
|
if i == 0:
|
|
supply = schedule[i+1]['cumulative_supply_btc']
|
|
else:
|
|
supply = (schedule[i+1]['cumulative_supply_btc'] -
|
|
schedule[i]['cumulative_supply_btc'])
|
|
supply_per_epoch.append(supply)
|
|
|
|
# Create pie chart
|
|
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 8))
|
|
|
|
# Pie chart
|
|
colors = plt.cm.YlOrRd(np.linspace(0.3, 0.9, 10))
|
|
wedges, texts, autotexts = ax1.pie(supply_per_epoch, labels=[f'Epoch {i}' for i in epochs],
|
|
autopct='%1.1f%%', startangle=90, colors=colors,
|
|
textprops={'fontsize': 10})
|
|
|
|
ax1.set_title('Bitcoin Supply Distribution by Epoch\n(First 10 Halvings)',
|
|
fontsize=14, fontweight='bold')
|
|
|
|
# Bar chart
|
|
ax2.bar(epochs, supply_per_epoch, color=colors, edgecolor='black', linewidth=1.5)
|
|
ax2.set_xlabel('Halving Epoch', fontsize=12, fontweight='bold')
|
|
ax2.set_ylabel('BTC Issued in Epoch (Millions)', fontsize=12, fontweight='bold')
|
|
ax2.set_title('BTC Issuance by Epoch', fontsize=14, fontweight='bold')
|
|
ax2.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, p: f'{x/1e6:.1f}M'))
|
|
ax2.grid(True, alpha=0.3, axis='y')
|
|
|
|
plt.tight_layout()
|
|
plt.savefig('/Users/z/work/lux/ai/bitcoin_supply_distribution.png', dpi=300, bbox_inches='tight')
|
|
print("Supply distribution saved to: /Users/z/work/lux/ai/bitcoin_supply_distribution.png")
|
|
|
|
|
|
def main():
|
|
"""Generate all visualizations."""
|
|
print("Loading Bitcoin tokenomics data...")
|
|
data = load_data()
|
|
|
|
print("\nGenerating visualizations...\n")
|
|
|
|
plot_supply_curve(data)
|
|
plot_inflation_rates(data)
|
|
plot_issuance_schedule(data)
|
|
plot_security_budget(data)
|
|
plot_supply_distribution(data)
|
|
|
|
print("\nAll visualizations complete!")
|
|
print("\nGenerated files:")
|
|
print(" - bitcoin_supply_curve.png")
|
|
print(" - bitcoin_inflation_rates.png")
|
|
print(" - bitcoin_issuance_schedule.png")
|
|
print(" - bitcoin_security_budget.png")
|
|
print(" - bitcoin_supply_distribution.png")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|