COMPLETE PIVOT from ML trading optimizer to on-chain metrics monitor. Architecture: - Playwright scrapes LookIntoBitcoin Plotly Dash charts for real on-chain data - 10 proven metrics: Puell Multiple, MVRV Z-Score, Fear & Greed, Reserve Risk, RHODL Ratio, NUPL, LTH Realized Price, 200W SMA, Hash Ribbons, Drawdown - Each metric scores 0-10, composite 0-100 - No ML, no black box — every signal transparent and traceable - Historical backtest validates scoring against actual BTC forward returns - Recency-weighted analysis accounts for diminishing cycle returns Full documentation in ARCHITECTURE.md
263 lines
9.6 KiB
Markdown
263 lines
9.6 KiB
Markdown
# Bitcoin Accumulation Zone Monitor — Architecture & Logic
|
|
|
|
## Overview
|
|
|
|
This is **NOT** a trading bot or ML predictor. It monitors proven Bitcoin on-chain metrics that have historically signaled optimal accumulation (buying) zones for long-term holders. Each metric scores 0-10 points, producing a composite score of 0-100.
|
|
|
|
**Philosophy:** Every signal is transparent and traceable. No black box. The metrics used have correctly identified every major Bitcoin cycle bottom since 2010.
|
|
|
|
## How It Works
|
|
|
|
### Data Pipeline
|
|
|
|
```
|
|
LookIntoBitcoin.com ──┐
|
|
(Playwright scraper) │
|
|
├──> data/cache.json (current values, refreshed every 15min)
|
|
alternative.me API ────┤ data/history.json (full history back to 2010, refreshed weekly)
|
|
│
|
|
CoinGecko API ─────────┘
|
|
│
|
|
▼
|
|
Scoring Engine (scoring/engine.py)
|
|
│
|
|
▼
|
|
Composite Score 0-100
|
|
│
|
|
┌────┴────┐
|
|
▼ ▼
|
|
Dashboard Backtest Engine
|
|
(live) (historical validation)
|
|
```
|
|
|
|
### Data Sources
|
|
|
|
All data is scraped or fetched from free sources — **no API keys required**.
|
|
|
|
| Source | Method | Data |
|
|
|--------|--------|------|
|
|
| LookIntoBitcoin / BitcoinMagazinePro | Playwright browser scraping of Plotly Dash charts | Puell Multiple, MVRV Z-Score, Reserve Risk, RHODL Ratio, NUPL, 200W SMA, LTH Realized Price, LTH Supply, Hash Ribbons, Pi Cycle |
|
|
| alternative.me | Free REST API | Fear & Greed Index (daily, back to Feb 2018) |
|
|
| CoinGecko | Free REST API | BTC price, market cap, 24h change |
|
|
|
|
#### Scraping Method (LookIntoBitcoin)
|
|
|
|
The site uses Plotly Dash charts. We intercept the `_dash-update-component` XHR response which contains the full chart data as JSON:
|
|
|
|
```python
|
|
page.on("response", handler) # Intercept XHR
|
|
page.goto("https://www.lookintobitcoin.com/charts/puell-multiple/")
|
|
# Response contains: response['chart']['figure']['data'] → list of trace objects
|
|
# Each trace: {name: str, x: [dates], y: [values]}
|
|
```
|
|
|
|
This gives us the **complete historical time series** (5000+ data points per metric going back to 2010) without needing any API key.
|
|
|
|
## Scoring System
|
|
|
|
### Individual Metrics (0-10 each)
|
|
|
|
#### 1. Fear & Greed Index (source: alternative.me)
|
|
Measures market sentiment from social media, surveys, and momentum.
|
|
|
|
| F&G Value | Classification | Score |
|
|
|-----------|---------------|-------|
|
|
| 0-10 | Extreme Fear | 10 |
|
|
| 11-25 | Fear | 7 |
|
|
| 26-45 | Neutral-low | 4 |
|
|
| 46-55 | Neutral | 2 |
|
|
| 56-75 | Greed | 1 |
|
|
| 76-100 | Extreme Greed | 0 |
|
|
|
|
**Logic:** "Be fearful when others are greedy, be greedy when others are fearful." — Buffett. Extreme Fear has historically coincided with cycle bottoms.
|
|
|
|
#### 2. Puell Multiple (source: LookIntoBitcoin)
|
|
Measures miner revenue relative to 365-day average. When miners earn very little (low Puell), they're capitulating — historically a bottom signal.
|
|
|
|
| Puell Value | Meaning | Score |
|
|
|-------------|---------|-------|
|
|
| < 0.3 | Deep miner capitulation | 10 |
|
|
| 0.3-0.5 | Miner stress | 8 |
|
|
| 0.5-0.8 | Below average revenue | 5 |
|
|
| 0.8-1.2 | Normal | 3 |
|
|
| 1.2-2.0 | Above average | 1 |
|
|
| > 2.0 | Miner euphoria | 0 |
|
|
|
|
**Historical accuracy:** Puell < 0.5 identified the Dec 2018, Mar 2020, and Jun 2022 bottoms.
|
|
|
|
#### 3. MVRV Z-Score (source: LookIntoBitcoin)
|
|
Compares market value to realized value. Negative Z-Score means the market is valued below what everyone paid — extreme undervaluation.
|
|
|
|
| Z-Score | Meaning | Score |
|
|
|---------|---------|-------|
|
|
| < 0 | Below realized value | 10 |
|
|
| 0-0.5 | Undervalued | 8 |
|
|
| 0.5-1.5 | Fair value | 5 |
|
|
| 1.5-3.0 | Overvalued | 2 |
|
|
| 3.0-5.0 | Very overvalued | 1 |
|
|
| > 5.0 | Extreme overvaluation | 0 |
|
|
|
|
**Historical accuracy:** Every time MVRV Z-Score went below 0, buying led to >200% returns within 2 years (100% hit rate across all cycles).
|
|
|
|
#### 4. Drawdown from ATH (calculated from price)
|
|
How far BTC has fallen from its all-time high. Larger drawdowns = better buying opportunity historically.
|
|
|
|
| Drawdown | Score |
|
|
|----------|-------|
|
|
| > 70% | 10 |
|
|
| 50-70% | 8 |
|
|
| 30-50% | 6 |
|
|
| 20-30% | 4 |
|
|
| 10-20% | 2 |
|
|
| < 10% | 0 |
|
|
|
|
#### 5. Price vs 200-Week SMA (source: LookIntoBitcoin)
|
|
The 200-week moving average has historically acted as the absolute floor in bear markets.
|
|
|
|
| Position | Score |
|
|
|----------|-------|
|
|
| Below 200W SMA | 10 |
|
|
| 0-20% above | 6 |
|
|
| 20-50% above | 3 |
|
|
| 50-100% above | 1 |
|
|
| > 100% above | 0 |
|
|
|
|
#### 6. Reserve Risk (source: LookIntoBitcoin)
|
|
Measures the confidence of long-term holders relative to the price. Low Reserve Risk = high confidence among HODLers + low price = excellent time to buy.
|
|
|
|
| Reserve Risk | Score |
|
|
|--------------|-------|
|
|
| < 0.002 | 10 |
|
|
| 0.002-0.005 | 7 |
|
|
| 0.005-0.01 | 4 |
|
|
| 0.01-0.02 | 2 |
|
|
| > 0.02 | 0 |
|
|
|
|
#### 7. RHODL Ratio (source: LookIntoBitcoin)
|
|
Ratio of 1-week old coins to 1-2 year old coins. Low ratio = long-term holders dominating (accumulation). High ratio = short-term speculation (distribution).
|
|
|
|
| RHODL | Score |
|
|
|-------|-------|
|
|
| < 100 | 10 |
|
|
| 100-500 | 7 |
|
|
| 500-2000 | 4 |
|
|
| 2000-10000 | 1 |
|
|
| > 10000 | 0 |
|
|
|
|
#### 8. NUPL — Net Unrealized Profit/Loss (source: LookIntoBitcoin)
|
|
Shows what fraction of market cap is unrealized profit. Negative = market is at a loss (capitulation). Above 0.75 = euphoria.
|
|
|
|
| NUPL | Phase | Score |
|
|
|------|-------|-------|
|
|
| < 0 | Capitulation | 10 |
|
|
| 0-0.25 | Hope/Fear | 7 |
|
|
| 0.25-0.5 | Optimism | 4 |
|
|
| 0.5-0.75 | Belief/Greed | 1 |
|
|
| > 0.75 | Euphoria | 0 |
|
|
|
|
#### 9. LTH Realized Price vs Spot (source: LookIntoBitcoin)
|
|
Long-Term Holder Realized Price = average cost basis of coins held >155 days. When spot price drops below this, even diamond hands are underwater — extreme value.
|
|
|
|
| Position | Score |
|
|
|----------|-------|
|
|
| Price below LTH RP | 10 |
|
|
| 0-20% above | 6 |
|
|
| 20-50% above | 3 |
|
|
| > 50% above | 1 |
|
|
|
|
#### 10. Hash Ribbons / Miner Capitulation (source: LookIntoBitcoin)
|
|
When miners capitulate (hash rate declining), it signals maximum pain. The recovery signal (hash rate resuming growth) has been a reliable buy signal.
|
|
|
|
| Signal | Score |
|
|
|--------|-------|
|
|
| Active buy signal | 10 |
|
|
| Recent recovery | 6 |
|
|
| Normal | 3 |
|
|
| Miner euphoria | 0 |
|
|
|
|
### Composite Score
|
|
|
|
```
|
|
Total Score = Sum of all individual metric scores (0-100)
|
|
```
|
|
|
|
| Score Range | Assessment | Action |
|
|
|-------------|------------|--------|
|
|
| 85-100 | Extreme Accumulation Zone | Strong buy — historically rare, ~4x per decade |
|
|
| 70-84 | Strong Accumulation | Buy — excellent long-term entry |
|
|
| 55-69 | Moderate Opportunity | Consider buying — decent entry |
|
|
| 40-54 | Neutral | Hold — not compelling either way |
|
|
| 25-39 | Caution | Reduce or wait — market heating up |
|
|
| 0-24 | Extreme Caution | Do NOT buy — historically the worst times |
|
|
|
|
## Backtest Engine
|
|
|
|
### Purpose
|
|
Reconstruct the composite score historically and compare against actual BTC forward returns to validate the scoring system's accuracy.
|
|
|
|
### Methodology
|
|
|
|
1. **Historical Reconstruction:** Using scraped historical data (2010-present), calculate what each metric's score would have been on every day
|
|
2. **Forward Returns:** For each historical day, calculate what BTC actually returned over the next 30, 90, 180, and 365 days
|
|
3. **Score Bracket Analysis:** Group days by score bracket and calculate average forward returns, win rates, max drawdowns
|
|
4. **Recency Weighting:** More recent cycles weighted higher because BTC's cycle-over-cycle returns diminish as it matures:
|
|
- 2022-present: 4x weight
|
|
- 2020-2021: 3x weight
|
|
- 2018-2019: 2x weight
|
|
- Before 2018: 1x weight
|
|
5. **Cycle-Separated Results:** Returns shown per cycle (Cycle 3: 2016-2019, Cycle 4: 2020-2023, Cycle 5: 2024+)
|
|
|
|
### Diminishing Returns Adjustment
|
|
|
|
Bitcoin's gains decrease every cycle. A score of 90 in 2018 led to different outcomes than a score of 90 in 2022:
|
|
- The backtest separates results by cycle
|
|
- Current expectations are based on the 2 most recent comparable cycles
|
|
- Adaptive thresholds recalculate based on rolling 2-year windows
|
|
|
|
## Architecture
|
|
|
|
```
|
|
/opt/apps/btc-ml-optimizer/
|
|
├── dashboard/
|
|
│ └── server.py # FastAPI + inline HTML/JS dashboard
|
|
├── scrapers/
|
|
│ ├── __init__.py
|
|
│ ├── lookintobitcoin.py # Playwright scraper for on-chain charts
|
|
│ ├── history_collector.py # Full historical data collection
|
|
│ ├── fear_greed.py # alternative.me Fear & Greed API
|
|
│ └── price.py # CoinGecko BTC price API
|
|
├── scoring/
|
|
│ ├── __init__.py
|
|
│ └── engine.py # Scoring logic and thresholds
|
|
├── backtesting/
|
|
│ ├── __init__.py
|
|
│ └── engine.py # Historical backtest calculations
|
|
├── data/
|
|
│ ├── cache.json # Current metric values (refreshed every 15min)
|
|
│ └── history.json # Full historical data (refreshed weekly)
|
|
├── config/
|
|
│ ├── thresholds.json # Configurable scoring thresholds
|
|
│ └── llm_settings.json # Optional LLM provider config for AI commentary
|
|
├── llm_client/
|
|
│ └── analyzer.py # Optional LLM integration for signal analysis
|
|
└── README.md
|
|
```
|
|
|
|
## Infrastructure
|
|
|
|
- **Server:** Main VPS (Hostinger), Tailscale IP 100.94.106.120
|
|
- **Port:** 3088
|
|
- **Process Manager:** pm2 (`btc-ml-optimizer`)
|
|
- **Dashboard URL:** http://100.94.106.120:3088
|
|
- **Backtest URL:** http://100.94.106.120:3088/backtest
|
|
- **Git Repo:** https://git.bizzle.lol/bizzle/btc-accumulation-monitor
|
|
|
|
## Dependencies
|
|
|
|
- Python 3.13
|
|
- FastAPI + uvicorn
|
|
- Playwright (Chromium, headless)
|
|
- requests
|
|
- No ML libraries required
|
|
- No paid API keys required
|