Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
df10a28
Add vercel.json for static frontend deployment
claude May 14, 2026
40d2c15
Add Python trading bot with phase/TA/wallet-based entry triggers
claude May 15, 2026
ffe8c7e
Fix leverage math, add dynamic phase exit and phase duration prediction
claude May 15, 2026
56508fa
Add strategy backtester with synthetic Wyckoff cycle data
claude May 15, 2026
efe74cd
Add phase recorder and analyzer for self-improving duration forecasts
claude May 15, 2026
570335c
Track phase_log.jsonl in git with auto-push and 14-day rolling window
claude May 15, 2026
2a7b9cc
Add phase history recording, stats table, and CSV export to dashboard
claude May 15, 2026
685ff75
Add PWA support: manifest, service worker, icons, install prompt
claude May 15, 2026
507153a
Redesign dashboard with Token Terminal-inspired light theme
claude May 15, 2026
e2ed8c0
Change accent color to light blue (#2563EB)
claude May 16, 2026
57dd7e4
Switch to dark terminal theme: black bg, terminal green, light blue
claude May 16, 2026
8439ac2
Add README.md based on project structure
RavellerH May 16, 2026
1c6fb88
Merge pull request #1 from RavellerH/A
RavellerH May 16, 2026
07f0fd8
Add MVRV Monitor tab for BTC, ETH, SOL, HYPE
claude May 16, 2026
9723e18
Add Intel page to dev branch: cryptowatch.id-inspired redesign
claude May 16, 2026
ef96bf8
Merge MVRV Monitor PR — resolve conflicts with Intel page changes
claude May 16, 2026
48b43fc
Add Position Health scoring to Overview
claude May 16, 2026
1054a71
Add health score breakdown modal (click badge to open)
claude May 16, 2026
2e74cfe
Add Journal + Position Tracker (intent, thesis, stop planner)
claude May 16, 2026
a2984df
Add Indicators page: F&G, BMSB, Pi Cycle, floor prices + health score…
claude May 16, 2026
2a46725
Add Smart Money monitor: Nansen netflows, auto-refresh, flow alerts
claude May 17, 2026
ffd9ef8
Add Vercel serverless proxy for Nansen API (fixes CORS)
claude May 17, 2026
c660aff
Add Analytics page — Tier 1/2/3 ML & AI trade analysis
claude May 21, 2026
4633582
Add hourly data logger to Supabase
claude May 22, 2026
9fe8ce8
Add spot holdings to overview; fix spot PnL; add Now price to perp table
claude May 22, 2026
e9fd311
Add TA recommendation engine with Signal tab for position modal
claude May 23, 2026
cab2a96
Add CVD+OI engine to ta-signal.js; CVD scanner CSS
claude May 23, 2026
6438746
Sync mobile-friendly UI changes to dev branch
claude May 23, 2026
ebe987b
Sync chart + money flow changes to dev branch
claude May 23, 2026
d81a144
Sync HYPE Intel panel to dev branch
claude May 23, 2026
445983a
Sync ta-signal.js with HYPE Intel + money flow signals
claude May 23, 2026
2814d05
Fix spot holdings: fall back to perp mark price when spot ctx has no …
claude May 23, 2026
11536b8
Fix CVD chart canvas overflow on Android (Phases tab)
claude May 23, 2026
fdc5800
Overhaul Trades, Funding, Flows tabs UI/UX
claude May 23, 2026
a6d28d8
Simplify Trades/Funding/Flows tabs, add historical IDR rates
claude May 23, 2026
bf44560
Fix account value for Hyperliquid unified accounts
claude May 23, 2026
0f39ae2
Fix total portfolio for unified account (revert broken approach)
claude May 23, 2026
708cd14
Update README to reflect current app state
claude May 24, 2026
ebeb496
Speed up Phases/CVD/OI loading on GitHub Pages
claude May 24, 2026
6a942e4
Make CVD charts lazy — don't block trading signal view
claude May 24, 2026
28bcfc1
Replace Chart.js CVD charts with SVG sparklines + add Cloudflare Work…
claude May 24, 2026
ca19e3c
Fix OI sparkline data: fetch Binance OI history for CVD chart rows
claude May 24, 2026
11e735b
Deduplicate TTL cache boilerplate in ta-signal.js
claude May 25, 2026
e7a4084
Add docs.html — sidebar-nav documentation page
claude May 25, 2026
7fef839
Add prev/next navigation and back-to-top to docs page
claude May 25, 2026
8ad8789
Add Recent PnL widget to Portfolio summary tab
claude May 26, 2026
0f6be4e
feat: make Recent PnL widget collapsible
claude May 26, 2026
7527137
fix: show net PnL summary in header when Recent PnL widget is collapsed
claude May 26, 2026
920f31a
feat: add favicon link tags to index.html and docs.html
claude May 26, 2026
652c9f9
fix: replace broken bias threshold with scored funding+momentum bias
claude May 26, 2026
1878413
feat: market detail modal with phase, TA signals, L/S ratio, OI spark…
claude May 26, 2026
7107abd
feat: order scenario analysis card on Portfolio tab
claude May 26, 2026
bf831f7
fix: order scenarios % margin impact and liq-before-SL warning
claude May 26, 2026
621f5fc
fix: bump service worker to hype-v8 to flush stale cached JS
claude May 26, 2026
7d4d1e8
feat: Recent PnL widget starts collapsed by default
claude May 26, 2026
96efdda
fix: apply code review fixes (critical + high priority)
claude May 26, 2026
ac99aff
docs: update README to reflect reliability and security fixes
claude May 28, 2026
c61d9bf
feat(bot): add Senpi AI-inspired signal architecture and DSL exit engine
claude May 29, 2026
96dbba7
feat(frontend): add Signals tab — Senpi AI-inspired confluence scanner
claude May 29, 2026
a5e9794
perf+feat: sync new features and optimize fetch patterns from gh-pages
claude May 30, 2026
5420da3
perf: cache portfolio chart data to stop re-fetching on every tab switch
claude May 30, 2026
a87f5d6
docs: add full feature audit — features, bot, apis, gaps
claude May 31, 2026
74ad312
fix: add Telegram command handler — bot now responds to messages
claude May 31, 2026
e63c559
Add Cloudflare Workers configuration
cloudflare-workers-and-pages[bot] May 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ __pycache__/
*.pyo
.DS_Store
backend/wallets.json

# wrangler files
.wrangler
.dev.vars*
!.dev.vars.example
!.env.example
209 changes: 209 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
# Hype — Hyperliquid Dashboard

A personal trading dashboard for [Hyperliquid](https://hyperliquid.xyz). Runs entirely in the browser — no backend required for the web UI. Directly queries the Hyperliquid public API and connects over WebSocket for live price feeds.

**Live:** [ravellerh.github.io/Hype](https://ravellerh.github.io/Hype)

---

## Tabs

| Tab | What it does |
|-----|-------------|
| **Portfolio** | Account value, open perp positions, spot holdings, unrealized PnL, open orders, portfolio growth chart, health score with risk flags. Supports unified accounts. |
| **Trades** | Fill history split into Perp / Spot sub-tabs. Coin filter, realized PnL, win rate, fees. Sorted latest-first, 100 rows per view. |
| **Funding** | Funding paid/received over 7 / 30 / 90 days. Daily bar chart, by-coin breakdown with avg rate, cost-alert pills for positions bleeding funding. |
| **Flows** | Deposit & withdrawal history with historical USD/IDR rate at the exact transaction date (fetched from frankfurter.app), running balance, cumulative flow chart. |
| **Live** | WebSocket price monitor — live mark prices and 24h change for all perp markets. |
| **Markets** | Global market overview — volume, OI, funding, 24h change across all Hyperliquid perps. |
| **Phases** | Wyckoff market-phase detector (Accumulation / Markup / Distribution / Markdown / Neutral) per coin and interval. |
| **Intel** | Smart-money wallet tracking — open positions and recent trades of known top traders. |
| **MVRV** | On-chain MVRV-Z score and market cycle context. |
| **AI** | AI-assisted trade analysis and market commentary. |
| **Watchlist** | Monitor any Hyperliquid address. Get alerts on position changes. |
| **Journal** | Personal trade journal — log entries, notes, outcome tagging. |
| **Indicators** | Technical indicator dashboard — RSI, MACD, Bollinger Bands across timeframes. |
| **Smart Money** | Aggregated signal feed from tracked whale wallets. |
| **Analytics** | PnL analytics, fee breakdown, win/loss streaks, equity curve. |
| **KB** | Personal knowledge base for trading notes and playbooks. |

---

## Key Features

- **Unified account support** — correctly reads `crossMarginSummary` vs `marginSummary` for accounts where spot USDC is perp collateral
- **IDR conversion** — all monetary values can be viewed in Indonesian Rupiah using live and historical rates; Flows tab shows the exact IDR value at the time of each deposit/withdrawal
- **Real-time WebSocket** — live prices, position updates, and wallet-change alerts without polling; exponential backoff reconnect (3 s → 30 s max) prevents hammering the server during outages
- **Portfolio health score** — composite risk score with per-position flags (leverage, liquidation distance, smart-money divergence, BMSB)
- **PWA** — installable on iOS, Android, and desktop; works offline for cached views
- **No sign-in** — enter any wallet address; read-only, no keys required

---

## Architecture

```
Hype/
├── frontend/ # Static SPA — the main dashboard (no backend needed)
│ ├── js/app.js # All UI logic, API calls, WebSocket, charts
│ └── css/styles.css
├── index.html # Entry point (gh-pages root)
├── styles.css
├── app.js
├── *.js # Feature modules (intel, analytics, journal, kb, …)
├── backend/ # Optional FastAPI server (Telegram alerts, phase scheduling)
│ ├── main.py
│ ├── phase_detector.py
│ ├── wallet_tracker.py
│ ├── telegram_bot.py
│ └── requirements.txt
├── bot/ # Optional autonomous trading bot
│ ├── main.py # Trading loop
│ ├── phase_analyzer.py
│ ├── risk_manager.py
│ ├── backtest.py
│ └── requirements.txt
└── vercel.json # Frontend deploy config
```

The frontend calls the Hyperliquid public API (`api.hyperliquid.xyz`) and `frankfurter.app` (exchange rates) directly from the browser. The backend and bot are optional extras for Telegram notifications and automated trading.

The backend uses a shared persistent `httpx.AsyncClient` (connection pooling) for all Hyperliquid API calls, and parallelises independent fetches with `asyncio.gather` where possible.

---

## Quick Start

### Dashboard only (no backend)

Open [ravellerh.github.io/Hype](https://ravellerh.github.io/Hype) in a browser, or self-host the static files anywhere.

### Self-host on Vercel

```bash
git clone https://github.com/ravellerh/hype.git
cd hype
vercel --prod
```

### Run with backend (Telegram alerts + phase scheduling)

```bash
git clone https://github.com/ravellerh/hype.git
cd hype
cp .env.example .env
# fill in PRIMARY_WALLET, TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID
chmod +x start.sh
./start.sh # starts FastAPI at http://localhost:8000
```

### Trading bot (optional, trades on your behalf)

```bash
cd bot
cp .env.example .env # fill in HL_PRIVATE_KEY, HL_WALLET_ADDRESS
pip install -r requirements.txt
python main.py
```

---

## Trading Bot

Entry requires **all** of:

| Condition | Default |
|-----------|---------|
| Coin phase | Wyckoff Accumulation (4h) |
| Phase confidence | ≥ 40 % |
| Accumulation age | Not late-stage (< 80 % of typical duration) |
| 1h TA | EMA bullish + MACD bullish + RSI > 50 |
| 15m TA | MACD bullish + RSI > 50 |
| Volume vs average | ≥ 1.2× |
| Funding rate | < 0.20 %/8h (not crowded) |
| Smart-wallet longs | ≥ 1 confirmed wallet |
| Confluence score | ≥ 5 / 10 (multi-pillar scoring) |
| BTC macro gate | BTC 4h move not > −3 % (hostile) |
| Risk guardrails | Daily loss < 3 %, no streak of ≥ 3 straight losses |

Confluence score (0–10) weights: phase confidence (0–3 pts), 1h TA signals (0–3 pts), 15m momentum (0–1 pt), volume strength (0–1 pt), smart-wallet consensus (0–2 pts). Leverage scales 3×–10× with score.

**LLM veto layer** (optional): when `ANTHROPIC_API_KEY` is set, Claude reviews signals scoring ≥ 6 as a final judgment gate, filtering ~30–40 % of borderline entries.

Risk defaults:

| Parameter | Value |
|-----------|-------|
| Margin per trade | 10 % of account |
| Leverage | 3×–10× (scales with confluence score) |
| Stop-loss | 8 % |
| Take-profit | 75 % (fallback) |
| Max open bot positions | 3 |
| Per-asset loss cooldown | 120 min |

**Exit strategy:**
- **DSL ratcheting trail** — at +10 % gain: locks 3.5 %; at +20 %: locks 11 %; at +35 %: locks 24.5 %. Inspired by Senpi AI's two-phase DSL exit engine.
- **Phase exit** — closes on flip to Distribution / Markdown.
- **Breakeven trail** — fallback SL move to entry + 0.3 % buffer when phase reaches Markup.

**Risk guardrails** — halt new entries if: daily realised loss > 3 % of account, or 3+ consecutive losses (24 h cooldown), or individual asset lost (120 min cooldown).

Backtest: `cd bot && python backtest.py`

---

## Environment Variables

| Variable | Where | Description |
|----------|-------|-------------|
| `PRIMARY_WALLET` | `.env` | Hyperliquid address to monitor |
| `TELEGRAM_BOT_TOKEN` | `.env` | Dashboard Telegram bot token |
| `TELEGRAM_CHAT_ID` | `.env` | Dashboard Telegram chat ID |
| `POLL_INTERVAL` | `.env` | Wallet poll interval in seconds (default 30) |
| `ALLOWED_ORIGINS` | `.env` | Comma-separated CORS origins (default `http://localhost:8000,http://127.0.0.1:8000`) |
| `HL_PRIVATE_KEY` | `bot/.env` | Private key for bot trading |
| `HL_WALLET_ADDRESS` | `bot/.env` | Bot wallet address |
| `TG_TOKEN` | `bot/.env` | Bot Telegram token |
| `TG_CHAT_ID` | `bot/.env` | Bot Telegram chat ID |
| `ANTHROPIC_API_KEY` | `bot/.env` | Enables LLM veto layer (Claude reviews top signals) |

---

## Reliability & Security Notes

| Area | Detail |
|------|--------|
| **WS reconnect** | Exponential backoff — 3 s, 6 s, 12 s, 24 s, 30 s max. Retry counter resets on successful connect. |
| **Silent refresh** | 60 s auto-refresh is concurrency-guarded; a second call while one is in flight is a no-op. Scroll position is preserved if the user hasn't moved. |
| **Market modal** | Stale-request cancellation — clicking a coin while the previous modal is still loading discards the old result. |
| **Chart.js** | Indicator sparklines destroy the previous Chart instance before re-creating to prevent canvas memory leaks. |
| **Backend HTTP** | Single shared `httpx.AsyncClient` with connection pooling replaces per-call client construction. |
| **MVRV endpoint** | CoinGecko chart fetches for all coins are parallelised; previously ran sequentially. |
| **Polling failures** | Backend counts consecutive poll errors and sends a Telegram alert after 5 in a row. |
| **CORS** | Restricted to `localhost` by default; override via `ALLOWED_ORIGINS` env var for custom deployments. |
| **Telegram config** | Bot token validated against `<id>:<hash>` format before being written to `.env`. |

---

## Tech Stack

| Layer | Technology |
|-------|-----------|
| Frontend | Vanilla JS, CSS custom properties, Chart.js |
| Real-time | Hyperliquid WebSocket API |
| Exchange rates | frankfurter.app (historical USD/IDR) |
| PWA | Web App Manifest + Service Worker |
| Backend (optional) | Python 3.11+, FastAPI, APScheduler |
| Bot SDK | hyperliquid-python-sdk |
| Notifications | python-telegram-bot |
| Deploy | GitHub Pages (frontend), Vercel, or any static host |

---

## License

MIT
33 changes: 33 additions & 0 deletions api/claude.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
export default async function handler(req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
if (req.method === 'OPTIONS') return res.status(200).end();

const { prompt, key } = req.body || {};
const apiKey = key || process.env.ANTHROPIC_API_KEY;
if (!apiKey) return res.status(400).json({ error: 'No API key provided' });
if (!prompt) return res.status(400).json({ error: 'No prompt provided' });

const resp = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': apiKey,
'anthropic-version': '2023-06-01',
},
body: JSON.stringify({
model: 'claude-haiku-4-5-20251001',
max_tokens: 1024,
messages: [{ role: 'user', content: prompt }],
}),
});

if (!resp.ok) {
const err = await resp.json().catch(() => ({}));
return res.status(resp.status).json({ error: err.error?.message || `Anthropic ${resp.status}` });
}

const data = await resp.json();
return res.json({ text: data.content?.[0]?.text || '' });
}
44 changes: 44 additions & 0 deletions api/nansen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const NANSEN_BASE = 'https://api.nansen.ai/api/v1';

export default async function handler(req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
if (req.method === 'OPTIONS') return res.status(200).end();

const apiKey = req.query.key || process.env.NANSEN_API_KEY;
if (!apiKey) return res.status(400).json({ error: 'No API key' });

const chains = ['ethereum', 'solana', 'base', 'arbitrum', 'optimism', 'bnb', 'hyperevm'];
const headers = { 'Content-Type': 'application/json', 'apikey': apiKey };

const [netflowRes, holdingsRes] = await Promise.allSettled([
fetch(`${NANSEN_BASE}/smart-money/netflow`, {
method: 'POST',
headers,
body: JSON.stringify({ chains, pagination: { page: 1, per_page: 100 } })
}),
fetch(`${NANSEN_BASE}/smart-money/holdings`, {
method: 'POST',
headers,
body: JSON.stringify({ chains })
})
]);

let netflows = [], holdings = null;

if (netflowRes.status === 'fulfilled' && netflowRes.value.ok) {
netflows = await netflowRes.value.json();
} else {
const status = netflowRes.status === 'fulfilled' ? netflowRes.value.status : 0;
if (status === 401 || status === 403) {
return res.status(401).json({ error: 'Invalid Nansen API key' });
}
}

if (holdingsRes.status === 'fulfilled' && holdingsRes.value.ok) {
holdings = await holdingsRes.value.json();
}

return res.json({ netflows, holdings, fetched_at: Date.now() });
}
7 changes: 7 additions & 0 deletions backend/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,10 @@

HL_API_URL = "https://api.hyperliquid.xyz/info"
HL_WS_URL = "wss://api.hyperliquid.xyz/ws"

WATCH_COINS = ["BTC", "ETH", "SOL", "HYPE", "SUI", "AVAX"]
PHASE_RECORD_INTERVAL = 3600 # record every hour (seconds)
PHASE_RETENTION_DAYS = 14 # keep 2 weeks of history
PHASE_LOG_CSV = os.path.join(os.path.dirname(__file__), "phase_log.csv")

NANSEN_API_KEY = os.getenv("NANSEN_API_KEY", "nsn_26ca358673bb886639703ba43524fead")
Loading