@vike-io/cli 0.14.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/README.md +32 -14
- package/package.json +4 -4
- package/skills/vike/SKILL.md +75 -37
- package/skills/vike-alerts-setup/SKILL.md +42 -10
- package/skills/vike-alerts-webhook/SKILL.md +18 -10
- package/skills/vike-candles/SKILL.md +10 -2
- package/skills/vike-core/SKILL.md +6 -3
- package/skills/vike-daily-brief/SKILL.md +68 -0
- package/skills/vike-follow-the-money/SKILL.md +60 -0
- package/skills/vike-hl-asset-briefing/SKILL.md +48 -0
- package/skills/vike-hl-builder-intel/SKILL.md +39 -0
- package/skills/vike-hl-cohort-backtest/SKILL.md +61 -0
- package/skills/vike-hl-cohort-positioning/SKILL.md +58 -0
- package/skills/vike-hl-liquidation-radar/SKILL.md +49 -0
- package/skills/vike-hl-position-match/SKILL.md +4 -3
- package/skills/vike-hl-top-traders/SKILL.md +22 -9
- package/skills/vike-hl-trader-profile/SKILL.md +65 -0
- package/skills/vike-perp-crowding/SKILL.md +49 -0
- package/skills/vike-perp-funding/SKILL.md +4 -1
- package/skills/vike-perp-overview/SKILL.md +23 -3
- package/skills/vike-pm-l2-archive/SKILL.md +50 -0
- package/skills/vike-pm-market-diligence/SKILL.md +60 -0
- package/skills/vike-polymarket-market-detail/SKILL.md +20 -15
- package/skills/vike-polymarket-markets/SKILL.md +2 -1
- package/skills/vike-polymarket-smart-money/SKILL.md +1 -0
- package/skills/vike-polymarket-trader/SKILL.md +2 -1
- package/skills/vike-smart-money-discovery/SKILL.md +4 -3
- package/skills/vike-stream/SKILL.md +99 -0
- package/skills/vike-token-holder-diligence/SKILL.md +58 -0
- package/skills/vike-token-holders/SKILL.md +6 -4
- package/skills/vike-token-research/SKILL.md +6 -6
- package/skills/vike-token-screener/SKILL.md +3 -3
- package/skills/vike-token-search/SKILL.md +2 -1
- package/skills/vike-token-smart-money-trend/SKILL.md +57 -0
- package/skills/vike-token-transfers/SKILL.md +8 -6
- package/skills/vike-wallet-balances/SKILL.md +9 -7
- package/skills/vike-wallet-batch/SKILL.md +3 -3
- package/skills/vike-wallet-compare/SKILL.md +2 -2
- package/skills/vike-wallet-counterparties/SKILL.md +2 -2
- package/skills/vike-wallet-discover/SKILL.md +3 -1
- package/skills/vike-wallet-ens/SKILL.md +2 -2
- package/skills/vike-wallet-label-provenance/SKILL.md +5 -4
- package/skills/vike-wallet-pnl-history/SKILL.md +2 -2
- package/skills/vike-wallet-portfolio/SKILL.md +10 -8
- package/skills/vike-wallet-summary/SKILL.md +6 -6
- package/skills/vike-wallet-trace/SKILL.md +4 -3
- package/skills/vike-wallet-transactions/SKILL.md +2 -2
- package/skills/vike-wallet-who-is/SKILL.md +50 -0
- package/skills/vike-wallets-related/SKILL.md +52 -0
- package/skills.sh.json +34 -12
- package/src/commands/alerts.js +85 -15
- package/src/commands/call.js +32 -0
- package/src/commands/candles.js +11 -15
- package/src/commands/doctor.js +4 -4
- package/src/commands/hl.js +274 -0
- package/src/commands/perp.js +5 -5
- package/src/commands/polymarket.js +105 -5
- package/src/commands/search.js +10 -0
- package/src/commands/stream.js +308 -0
- package/src/commands/token.js +2 -0
- package/src/commands/tool-command.js +27 -0
- package/src/commands/wallet.js +21 -0
- package/src/index.js +10 -1
- package/src/mcp-client.js +37 -16
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vike-hl-trader-profile
|
|
3
|
+
description: Full profile of one Hyperliquid wallet - equity, open positions, cohort labels, lifetime PnL against deposits, win rate and risk metrics, per-symbol record, closed trades, funding paid, deposits and withdrawals, orders, TWAPs, leverage changes, liquidations, builder routing, and a live feed of its fills. Use when the user gives a Hyperliquid address and asks "is this trader any good" / "profile this HL wallet" / "what is this wallet's track record" / "show the fills, funding or deposits of 0x..." / "watch this trader".
|
|
4
|
+
allowed-tools: Bash(vike-data:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# vike-hl-trader-profile
|
|
8
|
+
|
|
9
|
+
One address, answered from the wallet's own data (not from scanning a leaderboard). 1 credit per call. Get the address from `vike-hl-top-traders`, `vike-hl-position-match`, `hl market --view positions` or `vike-data search <name>` (its `traders` section).
|
|
10
|
+
|
|
11
|
+
## Chain
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
W=0xfc667adba8d4837586078f4fdcdc29804337ca06
|
|
15
|
+
vike-data hl wallet $W --window 30d --json # equity, open_positions, cohorts, lifetime, ledger_by_type, metrics
|
|
16
|
+
vike-data hl wallet $W --view trades_summary --window 30d --json # closed/open trades, medians, per-symbol record
|
|
17
|
+
vike-data hl wallet-trades $W --limit 50 --json # closed round trips, newest close first
|
|
18
|
+
vike-data hl wallet-activity $W --view funding --limit 50 --json # funding paid or received
|
|
19
|
+
vike-data hl wallet-activity $W --view ledger --limit 50 --json # deposits, withdrawals, sends, vault events
|
|
20
|
+
vike-data hl liquidations --wallet $W --json # has it been liquidated
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Optional, by question: `hl wallet-activity $W --view fills --symbol BTC` (raw fills), `--view builders` (which front-ends it routes through), `hl orders --view wallet --address $W` (what became of its orders, 7 days by default, at most 30), `hl twaps --wallet $W`, `hl leverage-changes --wallet $W`, `hl market --view positions --wallet $W` (open positions with liquidation price). `--window` is `1d|7d|30d|all` (default `all`); page with `nextCursor` -> `--cursor`.
|
|
24
|
+
|
|
25
|
+
## Reading
|
|
26
|
+
|
|
27
|
+
- **A wallet we hold nothing for is an error**, not zeros: `hl wallet` exits 1 with "no Hyperliquid data for wallet 0x...". Say "no Hyperliquid history for this address", not "a flat trader" or "the tool failed". `last_fill_ts` is `null` for a wallet with no fill; `has_metrics: false` on an active wallet means no trades in the window, which is not zero skill.
|
|
28
|
+
- `equity.account_value` is the live account; `cash_balance_usd` can be hugely negative on a cross-margin account next to a healthy account value: don't quote it as cash.
|
|
29
|
+
- **Units**: `*_usd` and `account_value` are USD. `win_rate`, `long_win_rate` are FRACTIONS (0.49 = 49%); `pnl_pct`, `roi`, `*_drawdown_pct` are percents. `perp top-traders` returns `win_rate_pct` as a percent: never mix the two in one table.
|
|
30
|
+
- **`max_drawdown_pct`** is a percent from 0 to 100 of the wallet's own equity (deposits and withdrawals taken out) over the window; `null` means too little equity history to say, not 0. `calmar_ratio` and `recovery_factor` derive from it and are `null` with it.
|
|
31
|
+
- **Lifetime vs ledger**: compare `lifetime.cum_realized_pnl` with `net_deposit_usd` before praising PnL. The ledger records `send` one-sided and signed, so net-flow sums from it lean negative; trust `deposit` and `withdraw`, treat `send` as movement to or from other accounts.
|
|
32
|
+
- **Mean vs median** (`trades_summary`): a few large trades drive the mean (a live 30-day record: `avg_gain` $73.6k against `median_gain` $4.5k). Report medians beside means, with `payoff_ratio`, `profit_factor`, `expectancy`.
|
|
33
|
+
- `trade_count` here counts open and closed trades; the leaderboard counts only completed trades, so the two never match.
|
|
34
|
+
- **Funding**: `payment_usd` is signed from the wallet's side, negative = the wallet PAID. **Fees**: a negative `fee` on a fill is a maker rebate.
|
|
35
|
+
- Cohorts (`size`, `pnl`, style tags) are today's labels. `avg_leverage` is the notional-weighted leverage of the open positions (real since 2026-10-25); 0 = no open position, not unlevered.
|
|
36
|
+
- Identity: a Hyperliquid address is an EVM address; `vike-data labels <addr>` may name it. Sub-accounts and vaults are separate addresses with no merge.
|
|
37
|
+
|
|
38
|
+
## Watch it live
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
vike-data stream hl --channel hl.fills hl.liquidations hl.ledger --filter wallet=$W --filter min_usd=0
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`hl.fills` alone defaults to fills of $1,000 or more; `min_usd=0` is every fill. A stored rule instead: `vike-data alerts create --type hl_wallet --wallet $W ...` (see `vike-alerts-setup`).
|
|
45
|
+
|
|
46
|
+
## Verdict rubric (rules of thumb, not tool output)
|
|
47
|
+
|
|
48
|
+
| Pattern | Label |
|
|
49
|
+
|---|---|
|
|
50
|
+
| positive `lifetime.cum_realized_pnl` AND window `profit_factor` above 1.5 AND 50+ closed trades AND positive median gain | **Consistent** |
|
|
51
|
+
| big PnL, `win_rate` near 0.5, mean far above median | **Few large winners** (size matters more than hit rate) |
|
|
52
|
+
| high win rate on fewer than 10 closed trades | **Unverified** |
|
|
53
|
+
| `net_deposit_usd` much larger than `cum_realized_pnl` | **Equity driven by deposits**, not trading |
|
|
54
|
+
| realized PnL positive but `total_unrealized_pnl` very negative on a large open book | **Open risk** |
|
|
55
|
+
|
|
56
|
+
## Anti-patterns
|
|
57
|
+
|
|
58
|
+
- Don't call a wallet "the best trader" from a 1d or 7d window, or from one number.
|
|
59
|
+
- Don't give copy-trade advice. The record is past, one venue, labels as of today.
|
|
60
|
+
- Don't read a `null` drawdown as 0.
|
|
61
|
+
|
|
62
|
+
## Pairs well with
|
|
63
|
+
|
|
64
|
+
- `vike-hl-top-traders` (rankings), `vike-hl-position-match` (find the wallet), `vike-wallet-who-is` (on-chain identity)
|
|
65
|
+
- `vike-hl-cohort-positioning` for how that cohort is positioned
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vike-perp-crowding
|
|
3
|
+
description: Is a perpetual-futures symbol crowded one way - funding paid, open interest net of the price move and the long/short lean on each venue, compared with the symbol's own last week, plus the Hyperliquid funding history and wallet-cohort lean. Use when the user asks "is BTC long crowded" / "is ETH positioning stretched across exchanges" / "is open interest rising with price" / "are traders over-leveraged long on SOL".
|
|
4
|
+
allowed-tools: Bash(vike-data:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# vike-perp-crowding
|
|
8
|
+
|
|
9
|
+
Three lenses on one symbol, about 6 credits. No lens has a validated threshold: judge each against the symbol's OWN last week and report what agrees, never a score. Base asset only (`BTC`, not `BTCUSDT`). Open interest and long/short have no command of their own: they are `vike-data call`.
|
|
10
|
+
|
|
11
|
+
## Chain
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
S=BTC
|
|
15
|
+
vike-data perp funding --symbol $S --json # funding on every venue now
|
|
16
|
+
vike-data hl market --view hourly --symbols $S --days 7 --json # Hyperliquid funding, open interest and close per hour
|
|
17
|
+
vike-data call perp_open_interest --args '{"symbol":"BTC","hours":168}' # hourly oi_usd per venue
|
|
18
|
+
vike-data call perp_long_short --args '{"symbol":"BTC","hours":168}' # hourly long_short_ratio per venue, with `basis`
|
|
19
|
+
vike-data candles hl $S --interval 1h --limit 169 --json # price over the same hours, to net it out of OI
|
|
20
|
+
vike-data hl cohort-metrics $S --axis size --hours 1 --json # optional: whales on Hyperliquid
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Without `hours` both `call`s return the newest print per venue; `"exchange":"binance"` narrows to one venue.
|
|
24
|
+
|
|
25
|
+
## Lens 1: funding
|
|
26
|
+
|
|
27
|
+
Raw `funding_rate` is per interval and `interval_h` differs (Hyperliquid 1h, most CEXs 8h): `daily_pct = funding_rate x 24 / interval_h x 100`. Positive = longs pay. `perp funding` is a snapshot, so for the CEXs say "above/below the other venues"; Hyperliquid's own funding history is in the hourly panel, so judge it against its week.
|
|
28
|
+
|
|
29
|
+
## Lens 2: open interest net of price
|
|
30
|
+
|
|
31
|
+
`oi_usd` is USD notional = contracts x mark price, so it rises with price on its own. Over the same hours: `contracts_change% ~ oi_change% - price_change%`. OI rising faster than price = new positions; falling while price rises = positions closing. Venues in `stale_venues` are not in `venues` and never in a total. The series is `[hour, oi_usd]` pairs, `hours + 1` points, the first hour partial.
|
|
32
|
+
|
|
33
|
+
## Lens 3: who leans
|
|
34
|
+
|
|
35
|
+
`long_share` / `short_share` are fractions of 1; `long_short_ratio` = long / short, above 1 long-heavy. **Each venue counts something different** and the row says so in `basis`: binance = top traders by positions, okx and gate = top traders by accounts, bybit = all accounts. Never average across venues; compare each venue with its own 7-day range. About 40 major symbols per venue; other symbols return empty lists and a `note`, not zeros. Hyperliquid cohorts (`bias` -1..+1 of notional, sum rungs by notional) are wallets, not accounts counted by a venue.
|
|
36
|
+
|
|
37
|
+
## Verdict
|
|
38
|
+
|
|
39
|
+
State which lenses point the same way and which do not. Illustrative wording, not live data: "funding positive on most venues, contracts rising on binance but falling on hyperliquid, long ratio at its 7-day high on binance only: mixed, not crowded". Name "crowded long" only when funding, net OI and at least two bases agree and sit at the top of their own week.
|
|
40
|
+
|
|
41
|
+
## Anti-patterns
|
|
42
|
+
|
|
43
|
+
- Don't read `oi_usd` growth as new longs, or a long/short ratio as dollars.
|
|
44
|
+
- Don't average ratios across venues or compare bases; don't forecast a squeeze.
|
|
45
|
+
- Don't leave stale venues in the comparison.
|
|
46
|
+
|
|
47
|
+
## Pairs well with
|
|
48
|
+
|
|
49
|
+
- `vike-perp-funding`, `vike-perp-overview`, `vike-hl-cohort-positioning`, `vike-hl-asset-briefing`, `vike-candles`
|
|
@@ -75,8 +75,11 @@ A funding arb at 0.4–1% daily is real. Anything much higher on a liquid pair i
|
|
|
75
75
|
- Don't blindly pick the lowest-funding venue without checking `vol_24h_usd` — Hyperliquid funding looks great on small alts but the book can be thin.
|
|
76
76
|
- Don't read `funding_rate` of an 8h venue against a 1h venue without normalising.
|
|
77
77
|
- Don't promise a price comparison from this tool: for price gaps across venues use `vike-perp-overview` (`perp spreads`).
|
|
78
|
+
- The arb list often leads with thin tokens: run mode B and read `vol_24h_usd` on both legs before calling a row a trade.
|
|
79
|
+
- Funding is the cost of carrying a position, not how crowded it is: for open interest and long/short per venue see `vike-perp-overview`, and `vike-perp-crowding` for the combined read.
|
|
78
80
|
|
|
79
81
|
## Pairs well with
|
|
80
82
|
|
|
81
|
-
- `vike-perp-overview` for cross-venue price gaps and the market snapshot
|
|
83
|
+
- `vike-perp-overview` for cross-venue price gaps, open interest, long/short and the market snapshot
|
|
84
|
+
- `vike-perp-crowding` to put a funding number next to open interest and positioning; `vike-hl-asset-briefing` for one Hyperliquid symbol
|
|
82
85
|
- `vike-hl-top-traders` to see how Hyperliquid's best traders are doing
|
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vike-perp-overview
|
|
3
|
-
description: Perp-market snapshot and
|
|
3
|
+
description: Perp-market snapshot and the venue-level reads of one symbol — the top funding arbs, the widest perp price gaps between venues, the Hyperliquid leaderboard, open interest per venue and each venue's long/short lean. Use when the user asks "what's happening in perps today" / "perp market overview" / "any perp arb today" / "price differences across exchanges" / "where's X cheapest" / "open interest of X" / "long short ratio of X".
|
|
4
4
|
allowed-tools: Bash(vike-data:*)
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# vike-perp-overview
|
|
8
8
|
|
|
9
|
-
One-shot market overview for perpetuals, plus the cross-venue price-gap
|
|
9
|
+
One-shot market overview for perpetuals, plus the cross-venue price-gap, open-interest and long/short tools. There is **no market-wide volume or per-venue mark-price tool**; say so if asked (Hyperliquid's own open interest is `vike-data hl market --json`).
|
|
10
|
+
|
|
11
|
+
## Open interest and long/short (one symbol, per venue)
|
|
12
|
+
|
|
13
|
+
These two tools have no command of their own; `vike-data call` prints their raw JSON (1 credit each):
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
vike-data call perp_open_interest --args '{"symbol":"BTC"}' # newest print per venue
|
|
17
|
+
vike-data call perp_open_interest --args '{"symbol":"BTC","exchange":"binance","hours":48}' # hourly series, 1-168
|
|
18
|
+
vike-data call perp_long_short --args '{"symbol":"ETH"}'
|
|
19
|
+
vike-data call perp_long_short --args '{"symbol":"ETH","exchange":"okx","hours":24}'
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Pass the base asset (`BTC`, not `BTCUSDT`); `exchange` is lower case.
|
|
23
|
+
|
|
24
|
+
- **`oi_usd` is USD notional** (open contracts x mark price when polled): not a contract count, so venues add up, and it moves with price even when no position opens or closes. Venues: aster, binance, bitget, bybit, hyperliquid, kucoin, okx. A venue silent for over an hour is under `stale_venues` and NOT in `venues`: never add it into a total.
|
|
25
|
+
- **`long_share` / `short_share` are fractions of 1**; `long_short_ratio` = long / short, above 1 = long-heavy. **Each venue counts something different, named in the row's `basis`**: binance top traders by positions; okx and gate top traders by accounts; bybit all accounts. Never average across venues; compare a venue with its own history.
|
|
26
|
+
- About 40 major symbols per venue: any other symbol returns empty lists and a `note`, never zeros.
|
|
27
|
+
- Whether a symbol is crowded: `vike-perp-crowding`.
|
|
10
28
|
|
|
11
29
|
## Price spreads
|
|
12
30
|
|
|
@@ -52,7 +70,7 @@ wait
|
|
|
52
70
|
## When to skip the 3-call snapshot
|
|
53
71
|
|
|
54
72
|
- User asked about one symbol's funding or venues → `vike-perp-funding`.
|
|
55
|
-
- User asked about one HL trader → `vike-hl-top-traders
|
|
73
|
+
- User asked about one HL trader → `vike-hl-trader-profile` (or `vike-hl-top-traders` for a ranking).
|
|
56
74
|
- User only wants price gaps → run `perp spreads` alone.
|
|
57
75
|
|
|
58
76
|
## Anti-patterns
|
|
@@ -66,4 +84,6 @@ wait
|
|
|
66
84
|
## Pairs well with
|
|
67
85
|
|
|
68
86
|
- `vike-perp-funding` for the funding deep dive and one-symbol venue comparison
|
|
87
|
+
- `vike-perp-crowding` for funding + open interest net of price + long/short on one symbol
|
|
69
88
|
- `vike-hl-top-traders` for the leaderboard filters and how to read its columns
|
|
89
|
+
- `vike-daily-brief` for the perp section inside a cross-market brief
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vike-pm-l2-archive
|
|
3
|
+
description: Find and fetch the free Polymarket L2 archive - daily Parquet files of the full order-book events, the trade tape and top-of-book quotes, whole or cut per market family such as BTC 5-minute up/down - with their sizes, a 7-day download link, and the on-chain outcomes to join them to. Says when the API tape is enough instead. Use when the user asks "get me Polymarket order book history" / "BTC 5m up/down L2 data for last week" / "download the Polymarket trades for a day" / "data to backtest a Polymarket strategy".
|
|
4
|
+
allowed-tools: Bash(vike-data:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# vike-pm-l2-archive
|
|
8
|
+
|
|
9
|
+
The archive is one Parquet file per UTC day and stream, recorded since 2026-07-25, free under CC BY 4.0 (credit "Polymarket L2 archive (c) Vike (vike.io/data), CC BY 4.0"). `vike-data` lists files and resolves links; **it never downloads.** 1 credit per call.
|
|
10
|
+
|
|
11
|
+
## Chain
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
vike-data polymarket archive --view datasets --asset btc --tenor 5m --stream trades --date-from 2026-10-15 --date-to 2026-10-17 --json
|
|
15
|
+
vike-data polymarket archive --view url --stream trades --date 2026-10-16 --json # multi-asset file, one day
|
|
16
|
+
vike-data polymarket archive --view url --stream trades --asset btc --tenor 5m --date 2026-10-16 --json # family file
|
|
17
|
+
vike-data polymarket settlements --slug-prefix btc-updown-5m- --from-ms <start> --to-ms <end> --limit 1000 --json # how each market resolved
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Streams: `book_events` (full L2: snapshots, `price_change` deltas, trades, tick-size and status markers), `trades` (taker tape), `l1_quotes` (derived top of book). A row carries `date`, `stream`, `layout` (`flat` = every market, `family` = one asset and tenor), `bytes`, `rows`, `url`. `datasets` pages with `--limit` (max 1000) and `--offset` against `total`.
|
|
21
|
+
|
|
22
|
+
## Pick the right file
|
|
23
|
+
|
|
24
|
+
- `--asset` and `--tenor` go together or not at all, and either one hides every flat file. Without them `datasets` mixes both layouts: filter on `layout`, or the same day appears twice.
|
|
25
|
+
- **Check `bytes` first.** Measured 2026-10-19: one day of `trades` about 12 MB; a BTC 5m family `trades` day 3-5 MB; one day of `book_events` **8.5 GB (532 million rows)**. Tell the user before any `book_events` download, and prefer the family file for one asset.
|
|
26
|
+
- A few hours or one token: use the API, not a bulk file: `vike-data polymarket tape --token-id <id> --from-ms ... --to-ms ... --event-type trade` (at most 24 h a call, no wallets), `vike-data polymarket market-trades <condition_id>` (with wallets) or `vike-data candles polymarket <token_id>`.
|
|
27
|
+
|
|
28
|
+
## Fetch (outside this skill's tool grant; hand the user the command)
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
curl -C - -o trades-2026-10-16.parquet "<url from the row>"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The link needs no API key and is valid for 7 days (`expires_at`): treat it as a secret, don't paste it anywhere shared. **Download the file whole and read the local copy** with DuckDB, polars or pyarrow: pointing a reader at the URL turns one file into thousands of range requests. The manifest and a small sample need no key at all: `https://data.vike.io/archive/manifest.json`, `https://data.vike.io/archive/samples/`.
|
|
35
|
+
|
|
36
|
+
## Reading the files
|
|
37
|
+
|
|
38
|
+
- The L2 tape carries no wallet addresses, only size and time. Prices are probabilities, sizes are shares.
|
|
39
|
+
- On the API tape a `0` in `best_bid`, `best_ask`, `price` or `size` on a row type that does not populate it means absent, not zero; check the schema in the manifest before assuming the same of a Parquet column.
|
|
40
|
+
- Join across files on the outcome token id; `settlements` rows carry `token_ids` and `winning_token_id` for the join to outcomes.
|
|
41
|
+
|
|
42
|
+
## Anti-patterns
|
|
43
|
+
|
|
44
|
+
- Don't promise a download from the CLI, and don't fetch `book_events` days to answer a question the API tape can.
|
|
45
|
+
- Don't redistribute without the attribution above.
|
|
46
|
+
|
|
47
|
+
## Pairs well with
|
|
48
|
+
|
|
49
|
+
- `vike-pm-market-diligence` (ids and one market live), `vike-candles` (probability bars), `vike-polymarket-markets`
|
|
50
|
+
- The Hyperliquid twin: `vike-data hl archive --view url --dataset fills --date 2026-10-16` (daily fills and positions files)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vike-pm-market-diligence
|
|
3
|
+
description: Full due diligence on one Polymarket market - finding it, spread and depth from the order book, recorded activity, large recent prints, who traded and who holds each side, on-chain resolution status and smart-money context, then a live feed of its trades and price moves. Handles the condition id versus token id split. Use when the user asks "is this Polymarket market liquid" / "who is on each side of this market" / "has this market resolved on-chain" / "check this prediction market before I trade" / "diligence on this Polymarket market".
|
|
4
|
+
allowed-tools: Bash(vike-data:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# vike-pm-market-diligence
|
|
8
|
+
|
|
9
|
+
About 18 credits for every step with two outcomes and three holders. Run only the sections the question needs.
|
|
10
|
+
|
|
11
|
+
**Two ids, never interchangeable.** A market has one `condition_id` (`0x` + 64 hex) and one OUTCOME TOKEN id per outcome (a long decimal number). `polymarket market`, `market-trades` and `settlement` take the condition id; `orderbook`, `market-stats`, `tape` and `candles polymarket` take a token id and answer nothing useful for a condition id. Token ids come from `clob_token_ids` in `polymarket market` (same order as its `outcomes`) or `outcomes[].token_id` in `polymarket markets`. **Map outcomes to ids by their label** everywhere else: `polymarket markets` has listed `No` before `Yes` and `Down` before `Up`.
|
|
12
|
+
|
|
13
|
+
## Chain
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
vike-data search "fed rate cut december" --json # 1 `markets` section; a polymarket.com link works too
|
|
17
|
+
vike-data polymarket markets --view search --query fed-rate-cut --json # 1 condition_id, token_ids, neg_risk, active/closed by slug
|
|
18
|
+
CID=0xbac62ac581be240787167755692fda4e07b3f42fb24f61a5d73c06731f8ed158
|
|
19
|
+
vike-data polymarket market $CID --json # 2 detail: outcomes, holders, last 100 trades, stats
|
|
20
|
+
vike-data polymarket orderbook <token_id> --depth 5 --json # 1 per outcome: spread and depth
|
|
21
|
+
vike-data polymarket market-stats <token_id> --json # 1 what is recorded for this token
|
|
22
|
+
vike-data polymarket tape --token-id <token_id> --from-ms <now-1h> --to-ms <now> --event-type trade --limit 1000 --json # 1 large prints
|
|
23
|
+
vike-data polymarket market-trades $CID --from-ms <now-24h> --limit 500 --json # 1 trades WITH wallets, newest first
|
|
24
|
+
vike-data polymarket settlement $CID --json # 1 on-chain resolution
|
|
25
|
+
vike-data polymarket wallet <proxy_wallet> --json # 2 each: the top 3 holders
|
|
26
|
+
vike-data polymarket smart-money --mode flows --hours 24 --json # 2 is this market in the cohort's flows
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Reading
|
|
30
|
+
|
|
31
|
+
- **`market`**: `question`, `end_date`, `active`, `closed`, `accepting_orders`, `resolution`, `volume_24h`, `liquidity`, `outcomes`, `clob_token_ids`, hourly `yes_series` / `no_series` (first and second outcome, named so even on Up/Down markets), `yes_holders` / `no_holders` (30 each: `proxy_wallet`, `net_shares`, `cost_basis`, `volume_usd`, `trades`), the latest 100 `trades` with wallets, and `stats`. No live quote, no cohort block, no fee rate.
|
|
32
|
+
- **Resolved or not**: an `end_date` in the past only means the end has passed: a market can stay `active` with `resolution: null` and `settlement` = `[]` for weeks. `settlement` returns one row (`winning_index`, `winning_outcome`, `winning_token_id`, `payouts`, `resolved_block`, `resolved_ts_ms`) once the chain resolved it; `[]` means not resolved on chain, not that the market is open (a voided market has none). Take the resolution time from `resolved_ts_ms`, not `resolution.resolved_at`.
|
|
33
|
+
- **`orderbook`** rows: `as_of_ts` (ms, the snapshot actually used: can be days old for a quiet or finished market), `side`, `level` (1 = best), `price` (a probability), `size` (shares), asks before bids. Keep one row per (`side`, `level`), take level 1 on each side for the spread, sum sizes within 5 cents for depth. A side can be missing, so no spread exists.
|
|
34
|
+
- **`market-stats`**: `trade_volume` is in SHARES, not dollars. `total_events: 0` means never recorded: re-check the token id before calling a market dead.
|
|
35
|
+
- **`tape`**: `ts` ms, `price` a probability, `size` shares, `side`. The window is at most 24 hours and `--to-ms` is exclusive; page while `has_more` with `--cursor`. It holds NO wallets.
|
|
36
|
+
- **`market-trades`**: wallets per fill. One row is one ORDER's fill, not one match: a match is the resting `maker` rows plus one `taker` row of their summed size, so never add `size * price` over both roles. `proxy_wallet` is Polymarket's proxy, not necessarily the person's own address.
|
|
37
|
+
- **Holders**: `polymarket wallet <proxy_wallet>` gives `realized_pnl_usd`, `resolved_markets`, volume-weighted `hit_rate` (a fraction) and `hit_rate_ci`, plus `correlated` wallets. Quote `hit_rate` only with 10 or more `resolved_markets`. A holder's `cost_basis` against the current mid says whether they are in profit on paper.
|
|
38
|
+
- **Smart money** (wallets with $1k+ realized PnL on 5+ resolved markets): look for the `condition_id` in the `flows` / `mispricings` lists. Absence from a top list is not evidence.
|
|
39
|
+
|
|
40
|
+
## Watch it live
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
vike-data stream polymarket --channel pm.trades pm.price_moves pm.resolutions --filter market=$CID
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`--filter` applies to every `--channel` of the command, and `market` is the only key all three take: a `role` filter here is refused (`bad_subscription`, exit 1). To count each match once, keep the taker rows of `pm.trades` with jq: `... | jq -c 'select(.type=="event" and .event.source=="pm.trades" and .event.data.role=="taker")'`. Don't start a second `stream polymarket` for it: one key holds one connection per path, and the second replaces the first (`4410`). `pm.trades` carries the trader's wallet; `pm.price_moves` is a move of 0.05 or more within five minutes; `pm.resolutions` the on-chain resolution.
|
|
47
|
+
|
|
48
|
+
## Answer template
|
|
49
|
+
|
|
50
|
+
> `<question>` ends `<end_date>`; `<open | past end, unresolved | resolved on-chain to X at T>`. `<Yes/Up>` mid `<m>`; spread `<s>`, depth to 5c `<n>` shares each side (book as of `<as_of_ts>`); 24h volume `$V`, liquidity `$L`. Largest prints last hour: `<size @ price>`. Top holders: `<n>` wallets hold `<outcome>`, cost basis `<c>`; `<k>` have 10+ resolved markets (hit rates `<...>`). Cohort: `<in flows | not in the top list>`. Quotes are probabilities, not dollars.
|
|
51
|
+
|
|
52
|
+
## Anti-patterns
|
|
53
|
+
|
|
54
|
+
- Don't pass a condition id to `orderbook`, `market-stats` or `tape`, and don't call a market "dead" on zero stats.
|
|
55
|
+
- Don't say "insider" or "manipulated" from holders and flows: they show who is on a side, not why.
|
|
56
|
+
- Don't read the first row of `outcomes[]` as Yes.
|
|
57
|
+
|
|
58
|
+
## Pairs well with
|
|
59
|
+
|
|
60
|
+
- `vike-polymarket-market-detail`, `vike-polymarket-trader`, `vike-polymarket-smart-money`, `vike-candles` (probability history), `vike-pm-l2-archive` (bulk history)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vike-polymarket-market-detail
|
|
3
|
-
description:
|
|
3
|
+
description: Read one Polymarket market by condition_id - question, outcomes and their token ids, resolution, an hourly probability series, the top 30 holders of each side, the latest 100 trades with wallets, and trade statistics. Use after vike-polymarket-markets when the user asks about one specific market, its holders or what its token ids are.
|
|
4
4
|
allowed-tools: Bash(vike-data:*)
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -9,35 +9,40 @@ allowed-tools: Bash(vike-data:*)
|
|
|
9
9
|
## Command
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
vike-data polymarket market <condition_id> [--json]
|
|
12
|
+
vike-data polymarket market <condition_id> [--json] # 2 credits
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
`condition_id` is
|
|
15
|
+
`condition_id` is `0x` + 64 hex digits, from `vike-data polymarket markets` (or `vike-data search <words or polymarket.com link>`). It is NOT a token id.
|
|
16
16
|
|
|
17
17
|
## Example
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
20
|
vike-data polymarket markets --category Crypto --limit 5 --json
|
|
21
21
|
# → pick a condition_id from the output, then:
|
|
22
|
-
vike-data polymarket market
|
|
22
|
+
vike-data polymarket market 0xbac62ac581be240787167755692fda4e07b3f42fb24f61a5d73c06731f8ed158 --json
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
## What it returns
|
|
26
26
|
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
27
|
+
- Metadata: `question`, `slug`, `category` (can be an empty string), `end_date`, `active`, `closed`, `accepting_orders`, `volume_24h`, total volume, `liquidity`.
|
|
28
|
+
- `outcomes` (labels) and `clob_token_ids`, in the same order: these token ids feed `candles polymarket`, `polymarket orderbook`, `market-stats` and `tape`. Match outcomes to ids by position HERE and by label everywhere else: `polymarket markets` can list the outcomes in another order.
|
|
29
|
+
- `resolution`: `null` while unresolved. Its `resolved_at` can repeat `end_date`; the on-chain time is `resolved_ts_ms` in `vike-data polymarket settlement <condition_id>`.
|
|
30
|
+
- `yes_series` / `no_series`: hourly `mid` for the first and second outcome (named yes/no even on Up/Down or team markets).
|
|
31
|
+
- `yes_holders` / `no_holders`: up to 30 wallets per side with `proxy_wallet`, `net_shares`, `cost_basis`, `volume_usd`, `trades`.
|
|
32
|
+
- `trades`: the latest 100, WITH `proxy_wallet`, `outcome`, `side`, `size` (shares), `price` (probability), `usd`.
|
|
33
|
+
- `stats`: trade and wallet counts, volume, first and last seen.
|
|
34
|
+
|
|
35
|
+
There is no live quote block (take bid/ask/mid from `polymarket markets` or `polymarket orderbook`), no smart-money block (use `polymarket smart-money`) and no fee rate.
|
|
33
36
|
|
|
34
37
|
## Anti-patterns
|
|
35
38
|
|
|
36
|
-
- Don't claim a market is "manipulated"
|
|
37
|
-
-
|
|
39
|
+
- Don't claim a market is "manipulated" or has "insiders" from holders or trades alone; they show who is on a side, not why.
|
|
40
|
+
- `end_date` passed is not resolved: a market can stay `active` with `resolution: null`. Confirm with `polymarket settlement`.
|
|
41
|
+
- Only the latest 100 trades are returned: for a window use `polymarket market-trades` (with wallets) or `polymarket tape` (no wallets).
|
|
38
42
|
|
|
39
43
|
## Pairs well with
|
|
40
44
|
|
|
41
|
-
- `vike-
|
|
42
|
-
- `vike-polymarket-
|
|
43
|
-
- `vike-
|
|
45
|
+
- `vike-pm-market-diligence` — the full playbook (spread, depth, large prints, settlement, holders' records)
|
|
46
|
+
- `vike-polymarket-trader` — profile any holder's `proxy_wallet`
|
|
47
|
+
- `vike-polymarket-smart-money` (`--mode mispricings`) — markets where the cohort bought below the current mid
|
|
48
|
+
- `vike-candles` — probability history for a token id
|
|
@@ -28,7 +28,7 @@ One row per market, ranked by **24h volume only** (there is no liquidity or vola
|
|
|
28
28
|
|
|
29
29
|
`condition_id`, `slug`, `question`, `end_date`, `ended` (true once `end_date` has passed), `volume_24h` (USD), `liquidity`, `latest_ts`, and `outcomes`: a list with one entry per outcome leg, each with `token_id`, `outcome` (Yes / No or the leg's name), `mid`, `bid`, `ask`, `snap_vol_24h`.
|
|
30
30
|
|
|
31
|
-
The `token_id` of each leg is what `vike-data candles polymarket <token_id
|
|
31
|
+
The `token_id` of each leg is what `vike-data candles polymarket <token_id>`, `polymarket orderbook`, `market-stats` and `tape --token-id` need, so none of them needs a detail call. Read the leg by its `outcome` label, not by position: rows have listed `No` before `Yes` and `Down` before `Up`. The `condition_id` is the other id (for `polymarket market`, `market-trades` and `settlement`); never pass it where a token id is wanted.
|
|
32
32
|
|
|
33
33
|
## Reading the data
|
|
34
34
|
|
|
@@ -45,5 +45,6 @@ The `token_id` of each leg is what `vike-data candles polymarket <token_id>` nee
|
|
|
45
45
|
## Pairs well with
|
|
46
46
|
|
|
47
47
|
- `vike-polymarket-market-detail` — deep-dive on one market once you have its condition_id
|
|
48
|
+
- `vike-pm-market-diligence` — spread, depth, large prints, holders and on-chain resolution of one market
|
|
48
49
|
- `vike-polymarket-smart-money` — which markets cohort wallets are buying, and a full market overview
|
|
49
50
|
- `vike-candles` — probability history for a leg's `token_id`
|
|
@@ -80,4 +80,5 @@ Trim aggressively if the user asked a narrower question. About 5 credits for the
|
|
|
80
80
|
|
|
81
81
|
- `vike-polymarket-markets` — the trending list without the cohort view
|
|
82
82
|
- `vike-polymarket-market-detail` — drill into a flagged market
|
|
83
|
+
- `vike-pm-market-diligence` — spread, depth, holders and resolution of a flagged market
|
|
83
84
|
- `vike-polymarket-trader` — profile the top wallets active in flagged markets
|
|
@@ -54,5 +54,6 @@ There is no `hit_rate_pct`, `volume_<window>_usd` or `trades_<window>` field.
|
|
|
54
54
|
|
|
55
55
|
## Pairs well with
|
|
56
56
|
|
|
57
|
-
- `vike-polymarket-market-detail` — see which markets they're currently in
|
|
57
|
+
- `vike-polymarket-market-detail` — see which markets they're currently in (its holder lists give the `proxy_wallet` addresses to profile here)
|
|
58
|
+
- `vike-pm-market-diligence` — the market-level playbook that ends with this wallet check
|
|
58
59
|
- `vike-polymarket-smart-money` — whether the profitable-wallet cohort is moving in the same markets
|
|
@@ -6,7 +6,7 @@ allowed-tools: Bash(vike-data:*)
|
|
|
6
6
|
|
|
7
7
|
# vike-smart-money-discovery
|
|
8
8
|
|
|
9
|
-
Composite playbook built on `token screener --smart-money-only`. Smart money here means the cohort behind the screener's `smart_inflow` and `--smart-money-only`, which exist for **Ethereum only** (a 400 on bsc and
|
|
9
|
+
Composite playbook built on `token screener --smart-money-only`. Smart money here means the cohort behind the screener's `smart_inflow` and `--smart-money-only`, which exist for **Ethereum only** (a 400 on bsc, base and hyperevm).
|
|
10
10
|
|
|
11
11
|
**What this can and cannot say.** It can say which tokens the cohort is flowing into and how much, and who the biggest net buyers of a token are. It cannot list which of those buyers belong to the cohort: no tool returns cohort membership. State that limit in the answer.
|
|
12
12
|
|
|
@@ -25,10 +25,10 @@ vike-data token screener --chain ethereum --window 7d --sort smart_inflow --smar
|
|
|
25
25
|
### B. Who is accumulating it?
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
vike-data token transfers <addr> --tab bought --period 7d --json
|
|
28
|
+
vike-data token transfers <addr> --tab bought --period 7d --hide-contracts --json
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
The list is the **top 10 by
|
|
31
|
+
The list is the **top 10 net buyers by net USD**, not the cohort (a buyer's `net_usd` is negative; `net_tokens` is the net in whole tokens). `--hide-contracts` leaves out the pools and routers we know of; a row can still be an exchange or an unmarked contract.
|
|
32
32
|
|
|
33
33
|
### C. Strip the intermediaries
|
|
34
34
|
|
|
@@ -63,6 +63,7 @@ Screener (3 credits) + `token transfers` (2) + `wallet batch` (2) + up to 5 × `
|
|
|
63
63
|
|
|
64
64
|
## Pairs well with
|
|
65
65
|
|
|
66
|
+
- `vike-token-smart-money-trend` for whether the cohort is entering, holding or exiting ONE token over 24h / 7d / 30d / 90d
|
|
66
67
|
- `vike-token-screener` for the filters and the column meanings
|
|
67
68
|
- `vike-token-research` for the price/flow context
|
|
68
69
|
- `vike-perp-funding` if the token has a perp listing (positioning bias)
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vike-stream
|
|
3
|
+
description: Live events over WebSocket with `vike-data stream` - Hyperliquid fills, liquidations, positions, liquidation risk, order walls, closed candles, TWAPs, ledger, leverage changes and funding; HL cohort flow, indices and cohort bias; on-chain transfers on eth, bsc, base and hyperevm; Polymarket trades, resolutions, price moves and new markets - printed as NDJSON, resumed by cursor after any drop. Use when the user wants to "watch", "tail", "follow live", "stream" or "be notified as it happens" rather than query history.
|
|
4
|
+
allowed-tools: Bash(vike-data:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# vike-stream
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
vike-data stream <hl|hl-cohorts|onchain|polymarket> --channel <channel...> [--filter key=value ...] [--cursor <cursor>]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Connects to `wss://stream.vike.io/v1/stream/<path>` with the API key in the `X-API-KEY` header, subscribes once per
|
|
14
|
+
`--channel`, and prints one JSON object per line on stdout: every `event` frame and every `gap` frame, exactly as the
|
|
15
|
+
server sent them. Status lines (subscribed, reconnecting, errors) go to stderr. It runs until Ctrl-C.
|
|
16
|
+
|
|
17
|
+
| Path | Channels |
|
|
18
|
+
|---|---|
|
|
19
|
+
| `hl` | `hl.fills`, `hl.liquidations`, `hl.positions`, `hl.liq_risk`, `hl.order_walls`, `hl.candles`, `hl.twaps`, `hl.ledger`, `hl.leverage`, `hl.funding` |
|
|
20
|
+
| `hl-cohorts` | `hl.cohort_flow`, `hl.indices`, `hl.cohort_bias` |
|
|
21
|
+
| `onchain` | `chain.transfers` |
|
|
22
|
+
| `polymarket` | `pm.trades`, `pm.resolutions`, `pm.price_moves`, `pm.new_markets` |
|
|
23
|
+
|
|
24
|
+
The server decides what each path serves: `vike-data stream info` prints the current channels and filter keys, and a
|
|
25
|
+
channel the path does not serve is refused with `unknown_channel` and the list. The CLI has no channel list of its own.
|
|
26
|
+
|
|
27
|
+
`hl.candles` is the Hyperliquid candle stream: closed bars, filtered by `coin`, `interval` (`1m 5m 15m 30m 1h 4h 1d`),
|
|
28
|
+
`market` (`perp` or `spot`) and `dex` (`HL` or a HIP-3 dex). The old `wss://data.vike.io/v1/stream` is closed (410).
|
|
29
|
+
|
|
30
|
+
## Examples
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Hyperliquid BTC and ETH fills of $100k or more, by smart wallets
|
|
34
|
+
vike-data stream hl --channel hl.fills --filter coin=BTC,ETH --filter min_usd=100000 --filter "pnl_cohort=3x smart,2x smart"
|
|
35
|
+
|
|
36
|
+
# Live 1-minute and 1-hour BTC and ETH perp candles (closed bars)
|
|
37
|
+
vike-data stream hl --channel hl.candles --filter coin=BTC,ETH --filter interval=1m,1h --filter market=perp
|
|
38
|
+
|
|
39
|
+
# Every liquidation and every fill of one wallet, on one connection
|
|
40
|
+
vike-data stream hl --channel hl.liquidations hl.fills --filter wallet=0x1111111111111111111111111111111111111111
|
|
41
|
+
|
|
42
|
+
# USDC transfers on base of 1M USDC or more (min_amount is in tokens; min_usd would drop the unpriced events)
|
|
43
|
+
vike-data stream onchain --channel chain.transfers --filter chain=base --filter token=0x833589fcd6edb6e08f4c7c32d4f71b54bda02913 --filter min_amount=1000000
|
|
44
|
+
|
|
45
|
+
# Keep only the events, with jq
|
|
46
|
+
vike-data stream polymarket --channel pm.trades --filter min_usd=10000 | jq -c 'select(.type == "event") | .event'
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`--filter` applies to every `--channel` of the command; a key the channel does not take is refused by the server
|
|
50
|
+
with the key's name. List keys (`wallet`, `coin`, `token`, `market`, `chain`, cohorts, ...) take comma-separated
|
|
51
|
+
values and repeat; `side`, `direction`, `event`, `axis`, `move`, `role` take one value; `true` / `false` is sent as a yes/no (`contract=false`); `min_usd`, `min_amount`, `min_move`
|
|
52
|
+
take a number. Channel fields and filter keys: https://vike.io/docs/data/reference/stream-channels
|
|
53
|
+
|
|
54
|
+
## Without a socket
|
|
55
|
+
|
|
56
|
+
These are MCP calls: they open no connection, so they never replace one.
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
vike-data stream info --json # every path, channel, filter key, limit and close code
|
|
60
|
+
vike-data stream check hl.fills --filter coin=BTC --filter min_usd=50000 # the server's own validator; exit 1 if refused
|
|
61
|
+
vike-data stream events hl.liquidations --filter coin=BTC --since-ms 1793178870000 --json # stored events (3 days), paged by --cursor
|
|
62
|
+
vike-data stream connections --hours 24 --json # your recent connections: who closed whom (4410), events sent
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Run `stream check` before a long-running `stream`: it shows the filter exactly as the server will apply it (with
|
|
66
|
+
the `hl.fills` default `min_usd` of 1000 added) or the server's error naming the bad key.
|
|
67
|
+
|
|
68
|
+
## Reading the output
|
|
69
|
+
|
|
70
|
+
- Keep the **frame's** `cursor` (the top-level one, not `event.cursor`) of the last line you handled. `--cursor <it>`
|
|
71
|
+
on the next run resumes from there, up to 3 days back; older is `cursor_expired` and the stream continues from now.
|
|
72
|
+
- The CLI resumes by itself after any drop (restart, network, slow reader) from the last cursor of each subscription.
|
|
73
|
+
Delivery is at least once: drop a repeated `event.event_id`.
|
|
74
|
+
- A `gap` frame (`reason: channel_idle`) means the channel was not running between `from` and `to` (nobody was
|
|
75
|
+
subscribed). It does not mean nothing happened; read that window from the REST endpoints or the `hl` / `polymarket`
|
|
76
|
+
commands. For what a socket missed while the channel was running, `vike-data stream events <channel> --cursor <c>`.
|
|
77
|
+
- `hl.fills` without `min_usd` gets a $1,000 floor; `min_usd=0` is every fill (hundreds per second).
|
|
78
|
+
`chain.transfers` unfiltered is a firehose; transfers are priced after they are streamed, so `min_usd` on it drops almost every event: filter by `wallet`, `token` (with `min_amount`), `entity`, `wallet_type` or `contract=false`.
|
|
79
|
+
|
|
80
|
+
## One connection per key
|
|
81
|
+
|
|
82
|
+
On each path, one API key holds one connection; an account holds at most 3. A second program on the same key and
|
|
83
|
+
path takes over, and the first exits with `replaced (4410)` and does not reconnect (two programs reconnecting would
|
|
84
|
+
take the connection from each other forever). Give each program its own key (`VIKE_API_KEY=... vike-data stream ...`).
|
|
85
|
+
`vike-data stream connections` shows which of your connections closed which.
|
|
86
|
+
Exit 1 also on `HTTP 401` / `4401` (the key) and on a refused subscription (`bad_subscription`, `unknown_channel`).
|
|
87
|
+
|
|
88
|
+
## Anti-patterns
|
|
89
|
+
|
|
90
|
+
- Don't run two `vike-data stream` processes on the same key and path: they replace each other.
|
|
91
|
+
- Don't treat silence as "nothing happened" in the first minutes: an idle channel starts on demand (up to ~12 minutes
|
|
92
|
+
for `hl.indices` and `hl.liq_risk`).
|
|
93
|
+
- Don't use the stream for history: it keeps 3 days. Use the query commands.
|
|
94
|
+
|
|
95
|
+
## Pairs well with
|
|
96
|
+
|
|
97
|
+
- `vike-alerts-setup`: a stored rule that notifies by webhook without a running process.
|
|
98
|
+
- `vike-hl-top-traders`: pick the wallets to put in a `wallet` filter.
|
|
99
|
+
- Playbooks with a live section: `vike-hl-liquidation-radar` (`hl.liq_risk`, `hl.liquidations`), `vike-follow-the-money` (`chain.transfers`), `vike-hl-cohort-positioning` (`hl.cohort_bias`, `hl.indices`), `vike-hl-trader-profile`, `vike-pm-market-diligence`.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vike-token-holder-diligence
|
|
3
|
+
description: Due diligence on who sits at the top of a token - the largest balances with their share of supply, how much of it is exchanges, contracts, labelled users, unlabelled or fresh wallets, which holders carry a risk flag, and whether they are selling now. Use when the user asks "is this token held by real wallets" / "are the top holders of X exchanges or contracts" / "how concentrated is X" / "holder quality of X" / "any fresh or flagged wallets among X holders".
|
|
4
|
+
allowed-tools: Bash(vike-data:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# vike-token-holder-diligence
|
|
8
|
+
|
|
9
|
+
Classify the top 50 wallets of one token by what they are. About 10 credits.
|
|
10
|
+
|
|
11
|
+
## Chain
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
vike-data token search ENA --chain ethereum --limit 3 --json # 0 take the canonical address
|
|
15
|
+
# 2 top holders by on-chain BALANCE, with supply_pct (the `token holders` command ranks by net inflow only)
|
|
16
|
+
vike-data call token_holders --args '{"token_address":"0x57e114b691db790c35207b2e685d4a43181e6061","chain":"ethereum","limit":50,"sort":"balance"}'
|
|
17
|
+
vike-data token holders 0x57e114b691db790c35207b2e685d4a43181e6061 --chain ethereum --limit 50 --json # 2 by net inflow: who moved the most
|
|
18
|
+
vike-data wallet batch <the 50 wallets> --chain ethereum --json # 2 one call (max 100)
|
|
19
|
+
vike-data token transfers 0x57e114b691db790c35207b2e685d4a43181e6061 --tab sold --period 7d --chain ethereum --hide-contracts --json # 2 are they selling now?
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Chains: `ethereum`, `bsc`, `base`, `hyperevm`. `sort: "balance"` is not served on every chain (the error names it); fall back to the flow ranking and say so. Holder calls scan the whole chain for the token and can take tens of seconds on a busy one: run each once. Add `"exclude_exchanges": true` to the `call` arguments to drop exchange-labelled wallets.
|
|
23
|
+
|
|
24
|
+
## Reading
|
|
25
|
+
|
|
26
|
+
- **Balance ranking** adds `balance`, `value_usd`, `supply_pct`, `balance_basis`, `balance_approximate`, `candidate_coverage`. The candidates are the wallets with the largest net inflow and volume, so a holder outside both is not in the list: `candidate_coverage` is the share of total supply the candidates hold. `balance_approximate: true` = a balance could not be read or the supply is unknown. `balance_basis: "unsupported"` = that row is still ranked by flow (as for a chain's native coin).
|
|
27
|
+
- **Flow ranking**: `net_flow_usd` is cumulative net inflow over recorded history, not a balance. A row with huge `volume_usd` and a small net is an intermediary.
|
|
28
|
+
- Holder rows carry `entity` and `wallet_type`; `wallet batch` adds `confidence` and `risk_flag`.
|
|
29
|
+
|
|
30
|
+
Group the 50 rows and sum `supply_pct` (or `net_flow_usd` on the flow list) per group:
|
|
31
|
+
|
|
32
|
+
| Group | Rule | Meaning |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| Exchange / custody | `wallet_type = cex` | aggregates many retail holders |
|
|
35
|
+
| Contract / system | `dex`, `system` or any other non-`user` type | pools, routers, vaults: not a holder opinion |
|
|
36
|
+
| Labelled users | `user` with an `entity` | a named person or fund |
|
|
37
|
+
| Unlabelled | empty | unknown, say so |
|
|
38
|
+
| Fresh | `first_seen` within 7 days | new money; a launch-day cluster is a flag |
|
|
39
|
+
| Risk-flagged | non-empty `risk_flag` | quote the flag verbatim |
|
|
40
|
+
|
|
41
|
+
Also read: `tx_count` 1-2 with a large balance = an airdrop or OTC receiver that may never have sold; `last_active` months old = dormant. On the `--tab sold` list, a top holder among the net sellers is the signal; `--hide-contracts` leaves out the pools and routers we know of.
|
|
42
|
+
|
|
43
|
+
## Answer template
|
|
44
|
+
|
|
45
|
+
> Top 50 by balance hold `X%` of supply (candidates cover `C%`): exchanges `A%`, contracts `B%`, labelled users `D%`, unlabelled `E%`; `N` wallets first seen in the last 7 days hold `F%`; `K` wallets are risk-flagged (`<flags>`). `<M>` of them are net sellers this week. `<Balances approximate / flow ranking only on this chain: say so.>`
|
|
46
|
+
|
|
47
|
+
For what one wallet holds across its tokens: `vike-data wallet balances <addr> --chains <chain>` (3 credits, cap at 5 wallets).
|
|
48
|
+
|
|
49
|
+
## Anti-patterns
|
|
50
|
+
|
|
51
|
+
- Don't present the top-50 sum as the token's full concentration: the list is candidates, not every holder.
|
|
52
|
+
- Don't call a token a rug or safe from this alone. It is one signal.
|
|
53
|
+
- Don't count the exchange group as "retail" or as one holder: it is custody for many.
|
|
54
|
+
|
|
55
|
+
## Pairs well with
|
|
56
|
+
|
|
57
|
+
- `vike-token-holders` (the flow list), `vike-token-transfers` (who is buying or selling now), `vike-wallet-who-is` on any single holder
|
|
58
|
+
- `vike-wallets-related` when several unlabelled top holders look like one cluster
|