jcc_hyper_tool 0.1.1

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.
Files changed (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +394 -0
  3. package/dist/cli/confirm.d.ts +2 -0
  4. package/dist/cli/confirm.d.ts.map +1 -0
  5. package/dist/cli/confirm.js +22 -0
  6. package/dist/cli/confirm.js.map +1 -0
  7. package/dist/cli/index.d.ts +3 -0
  8. package/dist/cli/index.d.ts.map +1 -0
  9. package/dist/cli/index.js +189 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/cli/perpKline.d.ts +19 -0
  12. package/dist/cli/perpKline.d.ts.map +1 -0
  13. package/dist/cli/perpKline.js +39 -0
  14. package/dist/cli/perpKline.js.map +1 -0
  15. package/dist/cli/stateCli.d.ts +3 -0
  16. package/dist/cli/stateCli.d.ts.map +1 -0
  17. package/dist/cli/stateCli.js +158 -0
  18. package/dist/cli/stateCli.js.map +1 -0
  19. package/dist/cli/strategyCli.d.ts +3 -0
  20. package/dist/cli/strategyCli.d.ts.map +1 -0
  21. package/dist/cli/strategyCli.js +198 -0
  22. package/dist/cli/strategyCli.js.map +1 -0
  23. package/dist/cli/tradingCli.d.ts +3 -0
  24. package/dist/cli/tradingCli.d.ts.map +1 -0
  25. package/dist/cli/tradingCli.js +587 -0
  26. package/dist/cli/tradingCli.js.map +1 -0
  27. package/dist/cli/util.d.ts +28 -0
  28. package/dist/cli/util.d.ts.map +1 -0
  29. package/dist/cli/util.js +62 -0
  30. package/dist/cli/util.js.map +1 -0
  31. package/dist/core/config.d.ts +32 -0
  32. package/dist/core/config.d.ts.map +1 -0
  33. package/dist/core/config.js +101 -0
  34. package/dist/core/config.js.map +1 -0
  35. package/dist/core/errors.d.ts +9 -0
  36. package/dist/core/errors.d.ts.map +1 -0
  37. package/dist/core/errors.js +17 -0
  38. package/dist/core/errors.js.map +1 -0
  39. package/dist/core/hyperliquid/asset.d.ts +24 -0
  40. package/dist/core/hyperliquid/asset.d.ts.map +1 -0
  41. package/dist/core/hyperliquid/asset.js +88 -0
  42. package/dist/core/hyperliquid/asset.js.map +1 -0
  43. package/dist/core/hyperliquid/candles.d.ts +24 -0
  44. package/dist/core/hyperliquid/candles.d.ts.map +1 -0
  45. package/dist/core/hyperliquid/candles.js +113 -0
  46. package/dist/core/hyperliquid/candles.js.map +1 -0
  47. package/dist/core/hyperliquid/client.d.ts +36 -0
  48. package/dist/core/hyperliquid/client.d.ts.map +1 -0
  49. package/dist/core/hyperliquid/client.js +92 -0
  50. package/dist/core/hyperliquid/client.js.map +1 -0
  51. package/dist/core/hyperliquid/exchange.d.ts +14 -0
  52. package/dist/core/hyperliquid/exchange.d.ts.map +1 -0
  53. package/dist/core/hyperliquid/exchange.js +42 -0
  54. package/dist/core/hyperliquid/exchange.js.map +1 -0
  55. package/dist/core/hyperliquid/exchangeParse.d.ts +7 -0
  56. package/dist/core/hyperliquid/exchangeParse.d.ts.map +1 -0
  57. package/dist/core/hyperliquid/exchangeParse.js +44 -0
  58. package/dist/core/hyperliquid/exchangeParse.js.map +1 -0
  59. package/dist/core/hyperliquid/float.d.ts +6 -0
  60. package/dist/core/hyperliquid/float.d.ts.map +1 -0
  61. package/dist/core/hyperliquid/float.js +24 -0
  62. package/dist/core/hyperliquid/float.js.map +1 -0
  63. package/dist/core/hyperliquid/klineCoin.d.ts +10 -0
  64. package/dist/core/hyperliquid/klineCoin.d.ts.map +1 -0
  65. package/dist/core/hyperliquid/klineCoin.js +90 -0
  66. package/dist/core/hyperliquid/klineCoin.js.map +1 -0
  67. package/dist/core/hyperliquid/orders.d.ts +91 -0
  68. package/dist/core/hyperliquid/orders.d.ts.map +1 -0
  69. package/dist/core/hyperliquid/orders.js +116 -0
  70. package/dist/core/hyperliquid/orders.js.map +1 -0
  71. package/dist/core/hyperliquid/prefixedPerpCoin.d.ts +3 -0
  72. package/dist/core/hyperliquid/prefixedPerpCoin.d.ts.map +1 -0
  73. package/dist/core/hyperliquid/prefixedPerpCoin.js +10 -0
  74. package/dist/core/hyperliquid/prefixedPerpCoin.js.map +1 -0
  75. package/dist/core/hyperliquid/signed-exchange.d.ts +10 -0
  76. package/dist/core/hyperliquid/signed-exchange.d.ts.map +1 -0
  77. package/dist/core/hyperliquid/signed-exchange.js +23 -0
  78. package/dist/core/hyperliquid/signed-exchange.js.map +1 -0
  79. package/dist/core/hyperliquid/signing.d.ts +23 -0
  80. package/dist/core/hyperliquid/signing.d.ts.map +1 -0
  81. package/dist/core/hyperliquid/signing.js +65 -0
  82. package/dist/core/hyperliquid/signing.js.map +1 -0
  83. package/dist/core/hyperliquid/types.d.ts +11 -0
  84. package/dist/core/hyperliquid/types.d.ts.map +1 -0
  85. package/dist/core/hyperliquid/types.js +2 -0
  86. package/dist/core/hyperliquid/types.js.map +1 -0
  87. package/dist/core/hyperliquid/watchOrders.d.ts +10 -0
  88. package/dist/core/hyperliquid/watchOrders.d.ts.map +1 -0
  89. package/dist/core/hyperliquid/watchOrders.js +38 -0
  90. package/dist/core/hyperliquid/watchOrders.js.map +1 -0
  91. package/dist/core/state/bracketReconcile.d.ts +23 -0
  92. package/dist/core/state/bracketReconcile.d.ts.map +1 -0
  93. package/dist/core/state/bracketReconcile.js +297 -0
  94. package/dist/core/state/bracketReconcile.js.map +1 -0
  95. package/dist/core/state/cancelOpenPlan.d.ts +23 -0
  96. package/dist/core/state/cancelOpenPlan.d.ts.map +1 -0
  97. package/dist/core/state/cancelOpenPlan.js +126 -0
  98. package/dist/core/state/cancelOpenPlan.js.map +1 -0
  99. package/dist/core/state/gcTradeState.d.ts +13 -0
  100. package/dist/core/state/gcTradeState.d.ts.map +1 -0
  101. package/dist/core/state/gcTradeState.js +48 -0
  102. package/dist/core/state/gcTradeState.js.map +1 -0
  103. package/dist/core/state/gridReconcile.d.ts +46 -0
  104. package/dist/core/state/gridReconcile.d.ts.map +1 -0
  105. package/dist/core/state/gridReconcile.js +307 -0
  106. package/dist/core/state/gridReconcile.js.map +1 -0
  107. package/dist/core/state/intentFactory.d.ts +58 -0
  108. package/dist/core/state/intentFactory.d.ts.map +1 -0
  109. package/dist/core/state/intentFactory.js +95 -0
  110. package/dist/core/state/intentFactory.js.map +1 -0
  111. package/dist/core/state/present.d.ts +17 -0
  112. package/dist/core/state/present.d.ts.map +1 -0
  113. package/dist/core/state/present.js +100 -0
  114. package/dist/core/state/present.js.map +1 -0
  115. package/dist/core/state/runCancelOpen.d.ts +32 -0
  116. package/dist/core/state/runCancelOpen.d.ts.map +1 -0
  117. package/dist/core/state/runCancelOpen.js +101 -0
  118. package/dist/core/state/runCancelOpen.js.map +1 -0
  119. package/dist/core/state/runReconcile.d.ts +20 -0
  120. package/dist/core/state/runReconcile.d.ts.map +1 -0
  121. package/dist/core/state/runReconcile.js +248 -0
  122. package/dist/core/state/runReconcile.js.map +1 -0
  123. package/dist/core/state/schema.d.ts +1161 -0
  124. package/dist/core/state/schema.d.ts.map +1 -0
  125. package/dist/core/state/schema.js +151 -0
  126. package/dist/core/state/schema.js.map +1 -0
  127. package/dist/core/state/snapshot.d.ts +22 -0
  128. package/dist/core/state/snapshot.d.ts.map +1 -0
  129. package/dist/core/state/snapshot.js +115 -0
  130. package/dist/core/state/snapshot.js.map +1 -0
  131. package/dist/core/state/statePaths.d.ts +2 -0
  132. package/dist/core/state/statePaths.d.ts.map +1 -0
  133. package/dist/core/state/statePaths.js +7 -0
  134. package/dist/core/state/statePaths.js.map +1 -0
  135. package/dist/core/state/store.d.ts +12 -0
  136. package/dist/core/state/store.d.ts.map +1 -0
  137. package/dist/core/state/store.js +95 -0
  138. package/dist/core/state/store.js.map +1 -0
  139. package/dist/core/state/types.d.ts +40 -0
  140. package/dist/core/state/types.d.ts.map +1 -0
  141. package/dist/core/state/types.js +2 -0
  142. package/dist/core/state/types.js.map +1 -0
  143. package/dist/core/trading.d.ts +8 -0
  144. package/dist/core/trading.d.ts.map +1 -0
  145. package/dist/core/trading.js +22 -0
  146. package/dist/core/trading.js.map +1 -0
  147. package/dist/core/wallet.d.ts +3 -0
  148. package/dist/core/wallet.d.ts.map +1 -0
  149. package/dist/core/wallet.js +14 -0
  150. package/dist/core/wallet.js.map +1 -0
  151. package/dist/daemon/index.d.ts +3 -0
  152. package/dist/daemon/index.d.ts.map +1 -0
  153. package/dist/daemon/index.js +104 -0
  154. package/dist/daemon/index.js.map +1 -0
  155. package/dist/meta/version.d.ts +2 -0
  156. package/dist/meta/version.d.ts.map +1 -0
  157. package/dist/meta/version.js +12 -0
  158. package/dist/meta/version.js.map +1 -0
  159. package/dist/strategies/grid.d.ts +46 -0
  160. package/dist/strategies/grid.d.ts.map +1 -0
  161. package/dist/strategies/grid.js +101 -0
  162. package/dist/strategies/grid.js.map +1 -0
  163. package/package.json +46 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 JCC Dex
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,394 @@
1
+ # jcc_hyper_tool
2
+
3
+ 面向 Hyperliquid 永续合约的命令行工具:
4
+
5
+ - **Phase 1**:只读 `/info` 查询
6
+ - **Phase 2**:签名 `/exchange`(下单 / 撤单)+ HTTP 轮询 `watch`
7
+ - **Phase 3**:基础 **grid** 策略(在价格区间内批量挂限价)
8
+ - **Phase 4**:**本地 JSON 状态**(默认 **`~/.jcc_hyper_tool/trade-state.json`**;根或子命令 **`--state-file`** 可改路径;根 **`--no-state`** 可关闭挂单类命令的读写)+ **`state reconcile`** / **`state cancel-open`**,跟踪 bracket / grid 意图,并在入场视为成交后再推进 TP/SL
9
+
10
+ 私钥**仅**通过**环境变量**提供,请勿写入仓库或配置文件;变量名、何时必填与安全注意见 **[环境变量](#环境变量)**。
11
+
12
+ 按场景整理的「复制即用」指令集见 **[Manual.md](./Manual.md)**(README 侧重完整说明,Manual 侧重实际命令)。
13
+
14
+ ## 安装与运行
15
+
16
+ 需要 **Node.js 20+**。安装发布包或按你的方式把 CLI 放进 **PATH** 后,终端中应能直接执行 **`jcc_hyper_tool`**(同包还提供 **`jcc_hyper_daemon`**,见 **[守护进程(定时循环)](#守护进程定时循环)**)。
17
+
18
+ **本文档中所有命令示例一律写作 `jcc_hyper_tool …`**,与是否从 npm 全局安装、`npm link` 或其它包装方式无关;子命令与参数相同。
19
+
20
+ ## 守护进程(定时循环)
21
+
22
+ **`jcc_hyper_daemon`** 按固定间隔反复 **`spawn`** 一次 **`jcc_hyper_tool`**:每次子进程退出后等待 **`--interval`** 秒再运行下一轮。子命令与参数必须写在 **`--`** 之后(与 `git` 等工具的 pass-through 习惯一致)。
23
+
24
+ ```bash
25
+ jcc_hyper_daemon --interval 60 -- state reconcile --state-file ~/.jcc_hyper_tool/trade-state.json
26
+ jcc_hyper_daemon --once -- config print
27
+ ```
28
+
29
+ 选项摘要:
30
+
31
+ - **`-i, --interval <seconds>`**:周期间隔,默认 `60`。
32
+ - **`--once`**:只跑一轮子命令后退出(便于脚本自检)。
33
+ - **`--jcc-bin <path>`**:显式指定 `jcc_hyper_tool` 可执行文件;否则读取环境变量 **`JCC_HYPER_TOOL_BIN`**,若也未设置,则用**当前 Node** 调起与本包一同发布的 **`cli/index.js`**(与是否把 `jcc_hyper_tool` 装入 PATH 无关)。
34
+
35
+ 收到 **`SIGINT` / `SIGTERM`** 时守护进程会立即退出。更详细的示例见 **[Manual.md → jcc_hyper_daemon](./Manual.md#jcc_hyper_daemon)**。
36
+
37
+ ## 从源码参与开发
38
+
39
+ 在克隆下来的仓库根目录:
40
+
41
+ ```bash
42
+ npm ci
43
+ npm test
44
+ npm run lint
45
+ ```
46
+
47
+ 执行 `npm install` / `npm ci` 后,脚本 **`prepare` 会运行 `npm run build`**,生成 `dist/`。若你**尚未**把 CLI 安装到全局 PATH,可临时用下表调用(**`--` 后面的参数与正文示例中跟在 `jcc_hyper_tool` 后的内容一致**):
48
+
49
+ | 方式 | 示例 |
50
+ | ------------------------ | ------------------------------------------------------------------------------------------------------- |
51
+ | **npx**(在任意目录) | `npx jcc_hyper_tool perp meta` |
52
+ | **npm script** | `npm run cli -- perp meta` |
53
+ | **默认测试网(script)** | `npm run cli:testnet -- perp meta`(等价于命令前加 `--network testnet`) |
54
+ | **直接 node** | `node dist/cli/index.js perp meta` |
55
+ | **npm link** | 在仓库根目录执行 `npm link`,之后可在任意目录运行 `jcc_hyper_tool …` |
56
+ | **守护进程(开发)** | `npm run daemon -- --interval 60 -- state reconcile --state-file ./x.json`(同 **`jcc_hyper_daemon`**) |
57
+
58
+ 若已安装但仍提示 **`jcc_hyper_tool: command not found`**,检查 PATH。若在仓库里用 **`npx`** 报 **`dist/cli/index.js` 不存在**,执行 **`npm run build`**(或重新安装以触发 `prepare`)。
59
+
60
+ ## 环境变量
61
+
62
+ 本 CLI **不会**自动读取项目里的 **`.env` 文件**;变量须由 shell、`direnv`、容器编排、CI 密钥管理等注入到进程环境(开发时也可在终端里 `export …`)。仓库根目录的 **`.env.example`** 仅作命名和用途示例,**不要**把真实私钥写入仓库或配置文件。
63
+
64
+ ### 网络与 API
65
+
66
+ | 变量 | 说明 |
67
+ | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
68
+ | `JCC_HYPER_NETWORK` | 全局 **`--network`** 的默认值:`mainnet` 或 `testnet`。不传 CLI 且未设置时 **默认为 `mainnet`**。与 **[测试网](#测试网)** 行为一致。 |
69
+ | `JCC_HYPER_API_URL` 或 `HYPERLIQUID_API_URL` | 可选:覆盖 **`/info` / `/exchange` 所用 HTTP 源**(仅 **`https://` 或 `http://` 的 origin**,误写 `.../info` 会被规范成 origin)。同全局 **`--api-url`**。 |
70
+
71
+ ### 钱包私钥(签名 / `--live`)
72
+
73
+ | 变量 | 说明 |
74
+ | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
75
+ | `JCC_HYPER_WALLET_PRIVATE_KEY` 或 `HYPERLIQUID_PRIVATE_KEY` | **以太坊格式私钥**,用于 **EIP-712 签名**并调用 **`POST /exchange`**。任一存在即可;若两者都设置,**优先使用** `JCC_HYPER_WALLET_PRIVATE_KEY`。支持 `0x` 前缀或 64 位十六进制字符串(程序会规范为 `0x…`)。**必须**在下述场景前设置:**`--live`** 下单、撤单、对账里需要真上报、以及依赖签名的子命令。**Dry-run**(默认)**不访问 `/exchange`**,一般**无需**私钥。 |
76
+
77
+ **安全**:勿将私钥写入 README、脚本仓库、cron 明文、`git` 历史或聊天;测试请用 **Hyperliquid 测试网 + 一次性密钥**(见 **[测试网](#测试网)**)。
78
+
79
+ ### 钱包地址(只读或约束)
80
+
81
+ | 变量 | 说明 |
82
+ | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
83
+ | `JCC_HYPER_WALLET_ADDRESS` 或 `HYPERLIQUID_ADDRESS` | 可选:**`0x` + 40 位十六进制**。用于 **`/info` 账户类**查询(如 `positions`、`orders list`、`fills`、`watch orders`)在未设置私钥时指定「查谁」;也可与私钥同时设置,若与私钥推导地址不一致,程序会 **报错** 以防选错账户。 |
84
+
85
+ ### 一览(快速查阅)
86
+
87
+ | 变量 | 用途摘要 |
88
+ | ---------------------------------------------------------- | --------------------------------------- |
89
+ | `HYPERLIQUID_PRIVATE_KEY` / `JCC_HYPER_WALLET_PRIVATE_KEY` | 签名与 **`--live`**;dry-run 通常不需要 |
90
+ | `HYPERLIQUID_ADDRESS` / `JCC_HYPER_WALLET_ADDRESS` | 可选账户地址;只读查询或与私钥交叉校验 |
91
+ | `JCC_HYPER_NETWORK` | 默认 `mainnet` \| `testnet` |
92
+ | `JCC_HYPER_API_URL` / `HYPERLIQUID_API_URL` | 可选 API origin,同 **`--api-url`** |
93
+
94
+ ### 示例(勿照抄私钥值)
95
+
96
+ ```bash
97
+ export JCC_HYPER_NETWORK=testnet
98
+ export HYPERLIQUID_PRIVATE_KEY='0x……' # 或 JCC_HYPER_WALLET_PRIVATE_KEY
99
+ jcc_hyper_tool wallet address
100
+ jcc_hyper_tool order place --coin BTC --side buy --limit-px 1 --sz 0.001 --tif Gtc --live
101
+ ```
102
+
103
+ ## 测试网
104
+
105
+ Hyperliquid 提供 **[测试网 / 预览环境](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api)**,API 源为 **`https://api.hyperliquid-testnet.xyz`**(与主网相同的 `/info`、`/exchange` 路径)。本 CLI 在指定 **`--network testnet`** 或环境变量 **`JCC_HYPER_NETWORK=testnet`**(见 **[环境变量](#环境变量) → 网络与 API**)时使用该端点。**`/exchange` 签名**走 HL 的测试环境(与 Python SDK 中 main / test 的区分一致),**不是主网**。
106
+
107
+ - **示例**:
108
+ `jcc_hyper_tool --network testnet perp meta`
109
+ `jcc_hyper_tool --network testnet wallet address`
110
+ - **网页端**(资金 / 行情):[https://app.hyperliquid-testnet.xyz](https://app.hyperliquid-testnet.xyz) — 请使用**一次性密钥**,勿复用主网私钥。
111
+
112
+ 若既不传 `--network`,也未设置 `JCC_HYPER_NETWORK`,**默认为主网**。
113
+
114
+ ## 命令说明
115
+
116
+ 全局选项:`--network mainnet|testnet`、`--api-url <origin>`、`-v` / `--verbose`、**`--state-file <path>`**(覆盖默认 **`~/.jcc_hyper_tool/trade-state.json`**)、**`--no-state`**(本次调用中 **`order place` / `order tpsl` / `strategy grid`** 不写、不读 trade state;与 **`state …`** 子命令同用会报错)。
117
+
118
+ ### 只读查询(Phase 1)
119
+
120
+ - `config print`、`wallet address`
121
+ - `perp meta`、`perp mid <coin>`、`perp book <coin>`、**`perp kline <coin>`**(K 线 / OHLCV,见下)
122
+ - `positions`、`orders list [--coin COIN]`、`fills`
123
+
124
+ **`perp kline <coin>`** — 调用 `/info` 的 **`candleSnapshot`**,返回与 API 一致的 JSON(通常为数组;字段含 `t,T,s,i,o,h,l,c,v,n`,精度保持字符串形式)。
125
+
126
+ - **必填**:**`--interval`**(如 `5m`、`1h`、`1d`)。
127
+ - **时间范围**:
128
+ - **不传** **`--start-time` / `--end-time`**:自动使用「截止到当前时间」的**默认回看区间**(由周期决定,见下表)。
129
+ - **手动**:须**同时**传入 **`--start-time`** 与 **`--end-time`**(Unix **毫秒**正整数,且 `start-time` ≤ `end-time`)。只传其一会报错。
130
+ - **默认回看(不传时间时,`endTime = 本地请求时刻`,`startTime = endTime − 回看长度)**:
131
+
132
+ | 周期 | 默认回看 |
133
+ | -------- | --------------------------------------------------------------------------------------------- |
134
+ | `5m` | **24 小时**(约 288 根,适合看盘日内结构) |
135
+ | `1h` | **30 天** |
136
+ | `1d` | **365 天** |
137
+ | 其余周期 | 代码内按粒度递增设定(如 `1m` 24h、`15m` 7d、`4h` 90d、`1w` 约 2 年等),避免单次请求根数过大 |
138
+
139
+ - **允许的 interval**:`1m`、`3m`、`5m`、`15m`、`30m`、`1h`、`2h`、`4h`、`8h`、`12h`、`1d`、`3d`、`1w`、`1M`。
140
+ - **全局选项**:**`--network`**、**`--api-url`**;加 **`-v`** 可在默认窗口模式下打印一行 stderr 提示。
141
+
142
+ 示例(**仅用默认窗口**,无需时间参数):
143
+
144
+ ```bash
145
+ jcc_hyper_tool perp kline BTC --interval 5m
146
+ jcc_hyper_tool perp kline ETH --interval 1d
147
+ ```
148
+
149
+ 示例(**5m**,显式时间戳):
150
+
151
+ ```bash
152
+ jcc_hyper_tool perp kline BTC --interval 5m \
153
+ --start-time 1704067200000 --end-time 1704153600000
154
+ ```
155
+
156
+ 示例(**1d**,显式时间戳):
157
+
158
+ ```bash
159
+ jcc_hyper_tool perp kline ETH --interval 1d \
160
+ --start-time 1704067200000 --end-time 1735689600000
161
+ ```
162
+
163
+ 示例(**HIP-3** `deployer:ASSET`,默认 **1h** 窗口):
164
+
165
+ ```bash
166
+ jcc_hyper_tool perp kline xyz:CL --interval 1h
167
+ ```
168
+
169
+ HIP-3 合约名称形如 `deployer:ASSET`(例如 `xyz:CL`)。调用 `/info` 的 `allMids` 时需要正确的 **`dex`**(部署方);本 CLI 在 `perp mid` 中会从 `coin` 里 `:` 前缀推断(也可用 **`--dex`** 覆盖)。**REST 里的 `coin` 字符串可能与网页 URL 路径不一致** — 若接口返回 `null` 或异常,请用 `perp meta --dex xyz` 核对 `universe[].name`(例如 WTI 类原油在 API 快照里常为 `xyz:CL`,而非路径里的 `xyz:WTIOIL`)。
170
+
171
+ ### 交易(Phase 2)
172
+
173
+ 官方 HTTP 接口说明见 [Exchange endpoint](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint)。签名遵循 Python SDK 的 `action_hash` + phantom **EIP-712** `Agent`(链 ID `1337`,域名为 `Exchange`)。
174
+
175
+ - **`jcc_hyper_tool order place`** — 构造**限价单** wire;默认输出 **dry-run** JSON(无需私钥、不访问交易所)。
176
+ - **`--live`** — 签名并 `POST /exchange`(需要私钥)。提交前须在终端输入 **`YES`**,除非使用 **`--assume-yes`**。
177
+ - **`--state-file <path>`**(可选)— 覆盖根默认路径;在未使用根 **`--no-state`** 时,会在本地写入 / 更新 **`single_limit`** 意图(详见 **Phase 4**)。
178
+ - 示例:
179
+ `jcc_hyper_tool order place --coin ETH --side buy --limit-px 2000 --sz 0.01 --tif Gtc`
180
+
181
+ - **`jcc_hyper_tool order tpsl`** — **触发类**止盈 / 止损(`--tpsl tp|sl`,wire 为 `t.trigger`)。必填:`--coin`、`--side`、`--sz`、`--trigger-px`、`--tpsl`。二选一:**`--is-market`**(触发后按市价成交)或 **`--limit-px`**(触发后限价),不可同时使用。默认 **仅减仓(reduce-only)**;**`--no-reduce-only`** 允许加仓(与 **`--grouping positionTpsl`** 互斥)。可选 **`--grouping na|normalTpsl|positionTpsl`**(默认 **`na`**);**`positionTpsl`** 下 **`--sz 0`** 表示按仓位全量 TP/SL。另有:`--cloid`、**`--dex`**(HIP-3;省略时从 `--coin` 的 `deployer:` 前缀推断,与 `order place` 一致)、**`--live`**、**`--assume-yes`**、**`--state-file`**(写入 **`standalone_tpsl`**,见 Phase 4)。默认 dry-run;**`--live`** 行为类似 `order place`(除非 **`--assume-yes`** 否则需输入 **`YES`**)。**风险**:务必先 dry-run;**`--live`** 请仅在测试网 + 一次性密钥上初次验证。
182
+ - 测试网 dry-run(触发后市价):
183
+ `jcc_hyper_tool --network testnet order tpsl --coin BTC --side sell --sz 0.001 --trigger-px 95000 --tpsl sl --is-market`
184
+ - 测试网 dry-run(整仓 TP/SL,`sz=0`,`positionTpsl`):
185
+ `jcc_hyper_tool --network testnet order tpsl --coin BTC --side sell --sz 0 --trigger-px 94000 --tpsl sl --is-market --grouping positionTpsl`
186
+
187
+ - **`jcc_hyper_tool order cancel`** — 默认 dry-run;**`--live`** 为真实撤单。
188
+
189
+ - **`jcc_hyper_tool order bracket`** — 创建 **bracket** 意图(入场限价 → 仅在对账认为入场已成交后再挂 TP/SL),**须有可写的 state 路径**(默认文件或 **`--state-file`**);**不可用 **`--no-state`**。保护腿默认 **reduce-only**。触发方式与单项 tpsl 类似:**`--is-market`** 或 **`--protection-limit-px`**(互斥)。随后对该意图执行一次 **`state reconcile`**(无 **`--live`** 则为 dry)。完整参数见下文 **Bracket(`order bracket`)\*\* 一节。
190
+
191
+ - **`jcc_hyper_tool watch orders`** — 轮询 `openOrders`,在 oid 集合或 payload 变化时打印 JSON 行。选项:`--poll-ms`、`--coin`、`--full`。
192
+
193
+ ### 策略(Phase 3)
194
+
195
+ **`jcc_hyper_tool strategy grid`** — 在 **`--lower`** 与 **`--upper`** 之间按 **`--grids`** 档均匀铺限价,每档 **`--order-sz`**。默认输出 **dry-run** JSON(含解析后的 `prices` 与 `action`)。**`--live`** 时签名并 POST `/exchange`,与 `order place` 类似(需私钥;除非 **`--assume-yes`** 否则输入 **`YES`**)。
196
+
197
+ - **`--bias symmetric`**(默认):区间中点**以下**价位为**买**,**以上**为**卖**;恰好落在中点时约定为**买**(文档化边界情况)。
198
+ - **`--bias long`** / **`--bias short`**:每一档全部为买或全部为卖。
199
+ - **`--tif`**、**`--reduce-only`**:含义与单笔 `order place` 相同。
200
+ - **HIP-3**:可选 **`--dex`** 解析 `meta`;省略且 `coin` 形如 `deployer:ASSET` 时从前缀推断(与 `perp mid` 思路一致)。
201
+ - **`--max-orders`**:可选,限制**本批次**包含的订单数量(从低价端起截断)。HL 对批量大小另有上限;网格过大可能失败或有风险 — 请从小 `grids` 与 dry-run 开始。
202
+
203
+ Dry-run 示例:
204
+
205
+ `jcc_hyper_tool strategy grid --coin ETH --lower 2000 --upper 2200 --grids 5 --order-sz 0.01 --bias symmetric --tif Gtc`
206
+
207
+ - **`--state-file <path>`**(可选)— 覆盖根默认;未使用 **`--no-state`** 时写入网格意图;配合 **`--live`** 时尝试从响应解析 **oid** 写回各 **leg**,便于 **`state reconcile`**。
208
+
209
+ ---
210
+
211
+ ## 实战:单边 / 双边网格、定时补单、一键撤销
212
+
213
+ (与 **Phase 4** 默认 state 路径、`state cancel-open` 行为一致,详见下文 **[本地状态与对账(Phase 4)](#本地状态与对账phase-4)**。)
214
+
215
+ 本 CLI **不会替你自动「成交后在对侧按价差补单」**;典型做法是:**用脚本读行情或读 `state` + 你自己的步长公式**,算出新的区间后再调一次 **`strategy grid --live`**。下面用 **`ST`** 表示你的 `coin`;**`/path/to/state.json`** 在示例里显式写出,若你使用默认 state 文件,可省略所有 **`--state-file`**(见上文全局选项)。
216
+
217
+ ### 1)按某一价格区间挂网格(单次)
218
+
219
+ 理解 **`--bias`**:
220
+
221
+ | 模式 | `--bias` | 行为 |
222
+ | ------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
223
+ | **双边 / 居中对称** | `symmetric`(默认) | 区间**下半**挂 **买**、**上半**挂 **卖**(恰好落在中点时约定为买,见源码 **`annotateGridSides`**)。一般让区间包住「现价 ± 带宽」。须 **`upper` &gt; `lower`** 且 **`grids` ≥ 1**。 |
224
+ | **单边只做买** | `long` | 每一档都是 **买**(例如只在下方接货)。 |
225
+ | **单边只做卖** | `short` | 每一档都是 **卖**(例如只在上方出货)。 |
226
+
227
+ 先 **dry-run**(无需私钥)看 `prices` 与 `action`:
228
+
229
+ ```bash
230
+ jcc_hyper_tool strategy grid --coin ST --lower 100 --upper 110 --grids 5 --order-sz 0.01 \
231
+ --bias symmetric --tif Gtc --state-file ./trade-state.json
232
+ ```
233
+
234
+ 测试网真实下单(务必 **先 dry、小单、一次性密钥**):
235
+
236
+ ```bash
237
+ jcc_hyper_tool --network testnet strategy grid --coin ST --lower 100 --upper 110 --grids 5 \
238
+ --order-sz 0.01 --bias long --tif Gtc --state-file ./trade-state.json --live
239
+ ```
240
+
241
+ **`--max-orders N`** 可限制本批次只发前 N 档(从低价端起),适合与脚本分批发。
242
+
243
+ ### 2)「成交后在对侧」补网格:脚本 / cron 思路
244
+
245
+ 没有内置「每成交一格就 ±X 价格自动反手」的单一子命令,推荐循环或 **cron** 驱动的小脚本,每轮做四件事(顺序可按你策略调整):
246
+
247
+ 1. **对账**(把已不在簿上的 leg 记成 filled 等,并推进 bracket/grid 摘要):
248
+ `jcc_hyper_tool state reconcile --state-file ./trade-state.json`
249
+ 若需真实补挂 bracket 腿,再加 **`--live`**(本 README 不展开策略细节;网格续挂主要用下一步)。
250
+ 2. **取参考价**:自己的 REST / `perp mid ST`,或从 **`state list --state-file ...`** 的 JSON 看当前各 intent 阶段(不保证含最新成交价,价源仍以 HL 为准)。
251
+ 3. **按你的规则算新区间**:例如「上次中枢 `mid`,买单成交后在对侧卖单挂在 `mid + step`」——在脚本里用任意语言实现 `lower/upper/grids`。
252
+ 4. **再发一批网格**(仅当你明确要加新单时):
253
+ `jcc_hyper_tool strategy grid ... --state-file ./trade-state.json --live`
254
+
255
+ **cron** 示例(每分钟对账一次;按需改成你的路径与用户;**不要将私钥写进 crontab 明文**,用登录 shell 已从环境注入为例):
256
+
257
+ ```cron
258
+ * * * * * /usr/bin/jcc_hyper_tool state reconcile --state-file /you/trade-state.json >>/tmp/jcc-reconcile.log 2>&1
259
+ ```
260
+
261
+ 也可以用 **`while sleep 60`** 的循环脚本做「守护进程」式轮询;把对账 + 定价 + 补挂写进函数即可:
262
+
263
+ ```bash
264
+ #!/usr/bin/env bash
265
+ set -euo pipefail
266
+ STATE="${JCC_TRADE_STATE:-$HOME/.jcc_hyper_tool/trade-state.json}"
267
+
268
+ while true; do
269
+ jcc_hyper_tool state reconcile --state-file "$STATE"
270
+ # TODO: 用 perp mid / 自管价格 + 你的 step 算出 LOWER UPPER,再决定是否补单,例如:
271
+ # jcc_hyper_tool strategy grid --coin ETH --lower "$LOWER" --upper "$UPPER" \
272
+ # --grids 5 --order-sz 0.01 --bias symmetric --tif Gtc --state-file "$STATE" \
273
+ # --live --assume-yes
274
+ sleep 60
275
+ done
276
+ ```
277
+
278
+ **注意**:上面仅作结构示例;**`--assume-yes`** 跳过确认,务必在测试网或小资金上验证后再用于自动化。
279
+
280
+ ### 3)紧急情况:一键撤掉 state 里仍在簿上的单
281
+
282
+ 对已写入默认或指定 **trade-state** 里的 **`single_limit` / `standalone_tpsl` / `bracket` 各腿 oid / `grid` legs**,可用 **`state cancel-open`**:**先比对 openOrders**,只对**仍在挂单列表里**的 oid 发撤单。
283
+
284
+ 预览(不 POST **`/exchange` 撤单**;仍会按规则 **GC** 精简本地文件):
285
+
286
+ ```bash
287
+ jcc_hyper_tool state cancel-open
288
+ jcc_hyper_tool state cancel-open --state-file ./trade-state.json
289
+ ```
290
+
291
+ 真实撤单(需私钥;默认终端输入 **`YES`**;cron / 脚本可慎用 **`--assume-yes`**):
292
+
293
+ ```bash
294
+ jcc_hyper_tool state cancel-open --live
295
+ jcc_hyper_tool state cancel-open --state-file ./trade-state.json --live --assume-yes
296
+ ```
297
+
298
+ 只针对某条 intent:
299
+
300
+ ```bash
301
+ jcc_hyper_tool state cancel-open --state-file ./trade-state.json --intent <意图UUID> --live
302
+ ```
303
+
304
+ 撤单成功后同样会做一次 **GC**,终态 intent 会从文件里删掉,事件一并收缩,避免 state 无限长大。
305
+
306
+ ---
307
+
308
+ ## 本地状态与对账(Phase 4)
309
+
310
+ **默认**使用 **`~/.jcc_hyper_tool/trade-state.json`**;根 **`--state-file`** 或各子命令 **`--state-file`** 可覆盖。**`--no-state`** 时 **`order place` / `order tpsl` / `strategy grid`** 不写 state;**`order bracket`** 与 **`state`** 子命令不可用 **`--no-state`**。Phase 4 使用本地 JSON 保存「意图」与阶段变更,面向**任务可读**的追踪,而不是 HL 原始 payload 的完整镜像。
311
+
312
+ ### 状态文件结构
313
+
314
+ - **`version`**:当前固定为 `1`。
315
+ - **`intents`**:多条意图,键为意图 id(一般为 UUID)。类型包括:
316
+ - **`bracket`**:入场限价 + 成交后再挂 TP/SL(保护单默认 **reduce-only**)。
317
+ - **`grid`**:网格参数 + 每一档 **leg**(含 oid、阶段等)。
318
+ - **`single_limit`**:单笔限价(配合 `order place --state-file`)。
319
+ - **`standalone_tpsl`**:独立触发单(配合 `order tpsl --state-file`)。
320
+ - **`events`**:与该意图相关的事件日志。
321
+ - **写入**:先写同目录临时文件再 **`rename`**,尽量原子化;重复对账依赖 **`dedupeKeys`**(`plan:*` / `done:*`),避免在同一模式下重复生成同一类「拟执行动作」。
322
+
323
+ 未使用根 **`--no-state`** 时,**`order place` / `order tpsl` / `strategy grid`** 会默认写入默认 state 文件(或根 / 子命令 **`--state-file`** 指定路径)。**`--no-state`** 则完全不写、不读。
324
+
325
+ ### `state` 子命令(**`--state-file`** 可省略,与根默认路径一致)
326
+
327
+ | 子命令 | 作用 |
328
+ | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
329
+ | **`state reconcile`** | 读状态 → 拉 **openOrders** 与 **clearinghouseState(仓位)** → 推进 bracket/grid 状态机 → **默认只输出 dry-run 计划**;加 **`--live`** 则在确认后真实下单 / 撤单(需私钥;可用 **`--assume-yes`** 跳过交互)。**`--intent <id>`** 可只处理一条意图。写回前会 **GC** 终态意图。 |
330
+ | **`state cancel-open`** | 从 state 收集 oid,与 **`openOrders`** 求交后按 **coin / assetIndex** 批量撤单;默认 **dry** 只出计划;**`--live`** 真实撤单(**`--assume-yes`** 可非交互)。结束后 **GC** 本地 state。 |
331
+ | **`state list`** | 以任务可读方式列出全部意图摘要(阶段、下一步提示等)。 |
332
+ | **`state show <intentId>`** | 单条意图的结构化详情 + 最近相关事件。 |
333
+ | **`state events <intentId>`** | 该意图的事件流;支持 **`--tail N`**、**`--newest-first`**。 |
334
+ | **`state request-cancel <intentId>`** | 为 **bracket** 打上「请求撤销入场」标记;后续 **`reconcile`** 在合适阶段尝试撤销仍在簿上的入场单。 |
335
+
336
+ 说明:**dry-run 对账**会为已展示的计划写入 **`plan:*`**,避免连续两次 dry-run 重复打印同一批动作;**`--live`** **不会**因有 **`plan:*`** 而跳过真实下单,成功后会记 **`done:*`** 并清除对应 **`plan:*`**。
337
+
338
+ ### Bracket(`order bracket`)
339
+
340
+ 实现「**入场成交后再挂 TP/SL**」,降低保护单过早触发带来的异常风险。
341
+
342
+ - **须有可写 state**(默认文件或 **`--state-file`**);不可用 **`--no-state`**。
343
+ - **必填**:**`--coin`**、**`--side`**(buy/sell)、**`--limit-px`**(入场限价)、**`--sz`**、**`--tp`**(止盈触发价)、**`--sl`**(止损触发价)。
344
+ - **保护腿**:**`--is-market`**(触发后市价)或 **`--protection-limit-px`**(触发后限价,TP/SL 共用该限价语义);二者互斥。
345
+ - **可选**:**`--tif`**、**`--reduce-only`**(入场腿)、**`--expires-in-ms`**(相对 TTL,超时进入过期分支)、**`--dex`**、**`--live`** / **`--assume-yes`**。
346
+ - **流程**:先写入 bracket 意图,再对该 **intent id** 执行一次 **`reconcile`**(dry 或 live)。live 且有多步动作时通常会有一次确认(**`--assume-yes`** 可跳过)。
347
+
348
+ ### 与现有命令的组合
349
+
350
+ - **`order place`**(默认写 state,除非 **`--no-state`**):dry / live 都会维护 **`single_limit`**(路径为默认或显式 **`--state-file`**);live 成功后尝试解析 **oid**。
351
+ - **`order tpsl`**:同上 → **`standalone_tpsl`**。
352
+ - **`strategy grid`**:同上 → **`grid`**;live 后为各 leg 绑定 **oid**。
353
+
354
+ ### 示例
355
+
356
+ ```bash
357
+ # 1)创建 bracket 意图并 dry-run 对账(写入 plan:*,不向交易所下单)
358
+ jcc_hyper_tool order bracket --coin BTC --side buy --limit-px 95000 --sz 0.01 \
359
+ --tp 98000 --sl 93000 --state-file ./trade-state.json --is-market
360
+
361
+ # 2)任务可读列表
362
+ jcc_hyper_tool state list --state-file ./trade-state.json
363
+
364
+ # 3)只 reconcile 一条意图(dry-run)
365
+ jcc_hyper_tool state reconcile --state-file ./trade-state.json --intent <意图UUID>
366
+
367
+ # 4)真实执行对账产生的动作(务必先在测试网验证)
368
+ jcc_hyper_tool state reconcile --state-file ./trade-state.json --live --assume-yes
369
+ ```
370
+
371
+ ### 风险与局限
372
+
373
+ - 状态机依赖 **HTTP 快照**(挂单 + 仓位),与撮合最终结果可能有延迟;请以**交易所界面与官方 API**为准交叉核对。
374
+ - 网格某一档「挂单消失」在 MVP 中倾向记为 **filled**;若实际为用户撤单,摘要不保证与主观语义完全一致。
375
+ - 任何 **`--live`** 请先在 **testnet** + **一次性密钥**验证;优先 **dry-run**。
376
+
377
+ ---
378
+
379
+ ## 校验与测试
380
+
381
+ 仓库内跑静态检查与单元测试:
382
+
383
+ ```bash
384
+ npm run lint && npm run typecheck && npm run test
385
+ ```
386
+
387
+ 手工烟测(与上文示例一致,需已能在终端执行 **`jcc_hyper_tool`**):
388
+
389
+ ```bash
390
+ jcc_hyper_tool --network testnet perp meta
391
+ jcc_hyper_tool order place --network testnet --coin BTC --side buy --limit-px 1 --sz 0.001 --tif Gtc
392
+ ```
393
+
394
+ 单元测试中对网络请求使用 **mock**,不代表真实 HL 行为;端到端请使用 **Hyperliquid 测试网** 与 **一次性私钥** 手动验证。
@@ -0,0 +1,2 @@
1
+ export declare function requireStdinYes(prompt: string): Promise<void>;
2
+ //# sourceMappingURL=confirm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm.d.ts","sourceRoot":"","sources":["../../src/cli/confirm.ts"],"names":[],"mappings":"AAEA,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBnE"}
@@ -0,0 +1,22 @@
1
+ import readline from "node:readline";
2
+ export async function requireStdinYes(prompt) {
3
+ const rl = readline.createInterface({
4
+ input: process.stdin,
5
+ output: process.stderr,
6
+ });
7
+ try {
8
+ const line = await new Promise((resolve, reject) => {
9
+ rl.once("SIGINT", () => {
10
+ reject(Object.assign(new Error("^C"), { name: "SIGINT" }));
11
+ });
12
+ rl.question(prompt, resolve);
13
+ });
14
+ if (line.trim() !== "YES") {
15
+ throw new Error(`Aborted (expected exactly YES). Got: '${line}'`);
16
+ }
17
+ }
18
+ finally {
19
+ rl.close();
20
+ }
21
+ }
22
+ //# sourceMappingURL=confirm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm.js","sourceRoot":"","sources":["../../src/cli/confirm.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAc;IAClD,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IACH,IAAI,CAAC;QACH,MAAM,IAAI,GAAW,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACzD,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;gBACrB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;YAC7D,CAAC,CAAC,CAAC;YACH,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,KAAK,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,yCAAyC,IAAI,GAAG,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}