Files
himself65__finance-skills/opencli-plugins/hyperliquid/lib/candles.js
T
Alex Yang 8072082fda feat: add hyperliquid-reader skill + opencli plugin (#76)
* feat: add hyperliquid-reader skill + opencli plugin

Add a read-only Hyperliquid (app.hyperliquid.xyz) reader, mirroring the
tradingview-reader pattern. Unlike TradingView's CDP attach, Hyperliquid
exposes a fully public info API (POST https://api.hyperliquid.xyz/info),
so this needs no API key, wallet, login, or desktop app.

opencli plugin (opencli-plugins/hyperliquid/) — 12 read-only commands:
- Market data: markets, spot-markets, mids, book, candles,
  funding-history, funding-compare (cross-venue HL/Binance/Bybit
  funding-arb screen).
- Account by 0x address: account, positions, spot-balances,
  open-orders, fills.

Skill (plugins/data-providers/skills/hyperliquid-reader/) — SKILL.md
(5-step + error reference), README.md, references/commands.md.

Registrations: root opencli-plugin.json, data-providers plugin.json
(description + keywords), marketplace.json, root README table.

Verification: 31 unit tests pass against captured live wire shapes;
all 12 command data paths smoke-tested end-to-end against the live API.
SKILL.md description is 1019 chars (< 1024 lint cap), no angle brackets.

No trade execution: the plugin exposes no write/exchange endpoints.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

* refactor: scope hyperliquid-reader to market data only

Drop the account-by-address commands (account, positions, spot-balances,
open-orders, fills) and their lib/account.js + lib/orders.js helpers and
tests. Remove the now-unused normalizeAddress helper from lib/api.js.

The reader is now market-data only: markets, spot-markets, mids, book,
candles, funding-history, funding-compare (7 commands). Updated SKILL.md,
both READMEs, references/commands.md, the plugin/marketplace manifests,
and the root README table accordingly.

21 unit tests pass; all 7 market-data data paths re-verified live.
2026-06-07 16:21:26 -07:00

38 lines
866 B
JavaScript

/**
* Candle helpers for `candleSnapshot`.
* Wire row: { t (open ms), T (close ms), s (coin), i (interval), o, h, l, c, v, n }.
*/
import { num, isoTime } from './api.js';
/** Supported interval → milliseconds. Used to derive a startTime from a count. */
export const INTERVAL_MS = {
'1m': 60_000,
'3m': 180_000,
'5m': 300_000,
'15m': 900_000,
'30m': 1_800_000,
'1h': 3_600_000,
'2h': 7_200_000,
'4h': 14_400_000,
'8h': 28_800_000,
'12h': 43_200_000,
'1d': 86_400_000,
'3d': 259_200_000,
'1w': 604_800_000,
'1M': 2_592_000_000,
};
/** Normalize raw candle rows to OHLCV with ISO open time. */
export function normalizeCandles(rows) {
return (rows ?? []).map((c) => ({
time: isoTime(c.t),
open: num(c.o),
high: num(c.h),
low: num(c.l),
close: num(c.c),
volume: num(c.v),
trades: c.n ?? null,
}));
}