okx-trade-cli 1.0.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/LICENSE +21 -0
- package/README.md +104 -0
- package/dist/index.js +778 -0
- package/dist/index.js.map +1 -0
- package/package.json +40 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 okx-hub
|
|
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,104 @@
|
|
|
1
|
+
# okx-trade-cli
|
|
2
|
+
|
|
3
|
+
## English
|
|
4
|
+
|
|
5
|
+
Command line tool for OKX. Supports market data, account queries, spot and swap
|
|
6
|
+
trading, and configuration management.
|
|
7
|
+
|
|
8
|
+
### Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install -g okx-trade-cli
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Configure credentials
|
|
15
|
+
|
|
16
|
+
Create `~/.okx/config.toml`:
|
|
17
|
+
|
|
18
|
+
```toml
|
|
19
|
+
default_profile = "demo"
|
|
20
|
+
|
|
21
|
+
[profiles.live]
|
|
22
|
+
api_key = "your-live-api-key"
|
|
23
|
+
secret_key = "your-live-secret-key"
|
|
24
|
+
passphrase = "your-live-passphrase"
|
|
25
|
+
|
|
26
|
+
[profiles.demo]
|
|
27
|
+
api_key = "your-demo-api-key"
|
|
28
|
+
secret_key = "your-demo-secret-key"
|
|
29
|
+
passphrase = "your-demo-passphrase"
|
|
30
|
+
demo = true
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Quick usage
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
okx market ticker BTC-USDT
|
|
37
|
+
okx market orderbook BTC-USDT --sz 5
|
|
38
|
+
okx account balance
|
|
39
|
+
okx spot orders
|
|
40
|
+
okx swap positions
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Examples
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
okx market candles BTC-USDT --bar 1H --limit 10
|
|
47
|
+
okx account balance BTC,ETH
|
|
48
|
+
okx spot place --instId BTC-USDT --side buy --ordType market --sz 100
|
|
49
|
+
okx swap leverage --instId BTC-USDT-SWAP --lever 10 --mgnMode cross
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
For more details, see the repository README.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 中文
|
|
57
|
+
|
|
58
|
+
OKX 命令行工具,支持行情、账户查询、现货与合约交易,以及配置管理。
|
|
59
|
+
|
|
60
|
+
### 安装
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm install -g okx-trade-cli
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 配置凭证
|
|
67
|
+
|
|
68
|
+
创建 `~/.okx/config.toml`:
|
|
69
|
+
|
|
70
|
+
```toml
|
|
71
|
+
default_profile = "demo"
|
|
72
|
+
|
|
73
|
+
[profiles.live]
|
|
74
|
+
api_key = "your-live-api-key"
|
|
75
|
+
secret_key = "your-live-secret-key"
|
|
76
|
+
passphrase = "your-live-passphrase"
|
|
77
|
+
|
|
78
|
+
[profiles.demo]
|
|
79
|
+
api_key = "your-demo-api-key"
|
|
80
|
+
secret_key = "your-demo-secret-key"
|
|
81
|
+
passphrase = "your-demo-passphrase"
|
|
82
|
+
demo = true
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 快速使用
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
okx market ticker BTC-USDT
|
|
89
|
+
okx market orderbook BTC-USDT --sz 5
|
|
90
|
+
okx account balance
|
|
91
|
+
okx spot orders
|
|
92
|
+
okx swap positions
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 示例
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
okx market candles BTC-USDT --bar 1H --limit 10
|
|
99
|
+
okx account balance BTC,ETH
|
|
100
|
+
okx spot place --instId BTC-USDT --side buy --ordType market --sz 100
|
|
101
|
+
okx swap leverage --instId BTC-USDT-SWAP --lever 10 --mgnMode cross
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
更多说明请参考仓库根目录 README。
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,778 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { parseArgs } from "util";
|
|
5
|
+
import { OkxRestClient, toToolErrorPayload } from "@okx-hub/core";
|
|
6
|
+
|
|
7
|
+
// src/config/loader.ts
|
|
8
|
+
import { loadConfig } from "@okx-hub/core";
|
|
9
|
+
function loadProfileConfig(opts) {
|
|
10
|
+
return loadConfig({
|
|
11
|
+
profile: opts.profile,
|
|
12
|
+
modules: opts.modules,
|
|
13
|
+
readOnly: opts.readOnly ?? false,
|
|
14
|
+
demo: opts.demo ?? false
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// src/formatter.ts
|
|
19
|
+
function printJson(data) {
|
|
20
|
+
process.stdout.write(JSON.stringify(data, null, 2) + "\n");
|
|
21
|
+
}
|
|
22
|
+
function printTable(rows) {
|
|
23
|
+
if (rows.length === 0) {
|
|
24
|
+
process.stdout.write("(no data)\n");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const keys = Object.keys(rows[0]);
|
|
28
|
+
const widths = keys.map(
|
|
29
|
+
(k) => Math.max(k.length, ...rows.map((r) => String(r[k] ?? "").length))
|
|
30
|
+
);
|
|
31
|
+
const header = keys.map((k, i) => k.padEnd(widths[i])).join(" ");
|
|
32
|
+
const divider = widths.map((w) => "-".repeat(w)).join(" ");
|
|
33
|
+
process.stdout.write(header + "\n" + divider + "\n");
|
|
34
|
+
for (const row of rows) {
|
|
35
|
+
process.stdout.write(
|
|
36
|
+
keys.map((k, i) => String(row[k] ?? "").padEnd(widths[i])).join(" ") + "\n"
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function printKv(obj, indent = 0) {
|
|
41
|
+
const pad = " ".repeat(indent);
|
|
42
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
43
|
+
if (v !== null && typeof v === "object" && !Array.isArray(v)) {
|
|
44
|
+
process.stdout.write(`${pad}${k}:
|
|
45
|
+
`);
|
|
46
|
+
printKv(v, indent + 2);
|
|
47
|
+
} else {
|
|
48
|
+
process.stdout.write(`${pad}${k.padEnd(20 - indent)} ${v}
|
|
49
|
+
`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// src/commands/market.ts
|
|
55
|
+
async function cmdMarketTicker(client, instId, json) {
|
|
56
|
+
const res = await client.publicGet("/api/v5/market/ticker", { instId });
|
|
57
|
+
const items = res.data;
|
|
58
|
+
if (json) return printJson(items);
|
|
59
|
+
if (!items?.length) {
|
|
60
|
+
process.stdout.write("No data\n");
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const t = items[0];
|
|
64
|
+
printKv({
|
|
65
|
+
instId: t["instId"],
|
|
66
|
+
last: t["last"],
|
|
67
|
+
"24h change %": t["sodUtc8"],
|
|
68
|
+
"24h high": t["high24h"],
|
|
69
|
+
"24h low": t["low24h"],
|
|
70
|
+
"24h vol": t["vol24h"],
|
|
71
|
+
time: new Date(Number(t["ts"])).toLocaleString()
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async function cmdMarketTickers(client, instType, json) {
|
|
75
|
+
const res = await client.publicGet("/api/v5/market/tickers", { instType });
|
|
76
|
+
const items = res.data;
|
|
77
|
+
if (json) return printJson(items);
|
|
78
|
+
printTable(
|
|
79
|
+
(items ?? []).map((t) => ({
|
|
80
|
+
instId: t["instId"],
|
|
81
|
+
last: t["last"],
|
|
82
|
+
"24h high": t["high24h"],
|
|
83
|
+
"24h low": t["low24h"],
|
|
84
|
+
"24h vol": t["vol24h"]
|
|
85
|
+
}))
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
async function cmdMarketOrderbook(client, instId, sz, json) {
|
|
89
|
+
const params = { instId };
|
|
90
|
+
if (sz !== void 0) params["sz"] = String(sz);
|
|
91
|
+
const res = await client.publicGet("/api/v5/market/books", params);
|
|
92
|
+
if (json) return printJson(res.data);
|
|
93
|
+
const book = res.data[0];
|
|
94
|
+
if (!book) {
|
|
95
|
+
process.stdout.write("No data\n");
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const asks = book["asks"].slice(0, 5);
|
|
99
|
+
const bids = book["bids"].slice(0, 5);
|
|
100
|
+
process.stdout.write("Asks (price / size):\n");
|
|
101
|
+
for (const [p, s] of asks.reverse()) process.stdout.write(` ${p.padStart(16)} ${s}
|
|
102
|
+
`);
|
|
103
|
+
process.stdout.write("Bids (price / size):\n");
|
|
104
|
+
for (const [p, s] of bids) process.stdout.write(` ${p.padStart(16)} ${s}
|
|
105
|
+
`);
|
|
106
|
+
}
|
|
107
|
+
async function cmdMarketCandles(client, instId, opts) {
|
|
108
|
+
const params = { instId };
|
|
109
|
+
if (opts.bar) params["bar"] = opts.bar;
|
|
110
|
+
if (opts.limit) params["limit"] = String(opts.limit);
|
|
111
|
+
const res = await client.publicGet("/api/v5/market/candles", params);
|
|
112
|
+
const candles = res.data;
|
|
113
|
+
if (opts.json) return printJson(candles);
|
|
114
|
+
printTable(
|
|
115
|
+
(candles ?? []).map(([ts, o, h, l, c, vol]) => ({
|
|
116
|
+
time: new Date(Number(ts)).toLocaleString(),
|
|
117
|
+
open: o,
|
|
118
|
+
high: h,
|
|
119
|
+
low: l,
|
|
120
|
+
close: c,
|
|
121
|
+
vol
|
|
122
|
+
}))
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// src/commands/account.ts
|
|
127
|
+
async function cmdAccountBalance(client, ccy, json) {
|
|
128
|
+
const params = {};
|
|
129
|
+
if (ccy) params["ccy"] = ccy;
|
|
130
|
+
const res = await client.privateGet("/api/v5/account/balance", params);
|
|
131
|
+
const data = res.data;
|
|
132
|
+
if (json) return printJson(data);
|
|
133
|
+
const details = data?.[0]?.["details"] ?? [];
|
|
134
|
+
printTable(
|
|
135
|
+
details.filter((d) => Number(d["eq"]) > 0).map((d) => ({
|
|
136
|
+
currency: d["ccy"],
|
|
137
|
+
equity: d["eq"],
|
|
138
|
+
available: d["availEq"],
|
|
139
|
+
frozen: d["frozenBal"]
|
|
140
|
+
}))
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// src/commands/spot.ts
|
|
145
|
+
async function cmdSpotOrders(client, opts) {
|
|
146
|
+
const endpoint = opts.status === "history" ? "/api/v5/trade/orders-history" : "/api/v5/trade/orders-pending";
|
|
147
|
+
const params = { instType: "SPOT" };
|
|
148
|
+
if (opts.instId) params["instId"] = opts.instId;
|
|
149
|
+
const res = await client.privateGet(endpoint, params);
|
|
150
|
+
const orders = res.data;
|
|
151
|
+
if (opts.json) return printJson(orders);
|
|
152
|
+
printTable(
|
|
153
|
+
(orders ?? []).map((o) => ({
|
|
154
|
+
ordId: o["ordId"],
|
|
155
|
+
instId: o["instId"],
|
|
156
|
+
side: o["side"],
|
|
157
|
+
type: o["ordType"],
|
|
158
|
+
price: o["px"],
|
|
159
|
+
size: o["sz"],
|
|
160
|
+
filled: o["fillSz"],
|
|
161
|
+
state: o["state"]
|
|
162
|
+
}))
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
async function cmdSpotPlace(client, opts) {
|
|
166
|
+
const body = {
|
|
167
|
+
instId: opts.instId,
|
|
168
|
+
tdMode: "cash",
|
|
169
|
+
side: opts.side,
|
|
170
|
+
ordType: opts.ordType,
|
|
171
|
+
sz: opts.sz
|
|
172
|
+
};
|
|
173
|
+
if (opts.px) body["px"] = opts.px;
|
|
174
|
+
const res = await client.privatePost("/api/v5/trade/order", body);
|
|
175
|
+
if (opts.json) return printJson(res.data);
|
|
176
|
+
const order = res.data[0];
|
|
177
|
+
process.stdout.write(`Order placed: ${order?.["ordId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
178
|
+
`);
|
|
179
|
+
}
|
|
180
|
+
async function cmdSpotCancel(client, instId, ordId, json) {
|
|
181
|
+
const res = await client.privatePost("/api/v5/trade/cancel-order", { instId, ordId });
|
|
182
|
+
if (json) return printJson(res.data);
|
|
183
|
+
const r = res.data[0];
|
|
184
|
+
process.stdout.write(`Cancelled: ${r?.["ordId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
185
|
+
`);
|
|
186
|
+
}
|
|
187
|
+
async function cmdSpotAlgoPlace(client, opts) {
|
|
188
|
+
const body = {
|
|
189
|
+
instId: opts.instId,
|
|
190
|
+
tdMode: "cash",
|
|
191
|
+
side: opts.side,
|
|
192
|
+
ordType: opts.ordType,
|
|
193
|
+
sz: opts.sz
|
|
194
|
+
};
|
|
195
|
+
if (opts.tpTriggerPx) body["tpTriggerPx"] = opts.tpTriggerPx;
|
|
196
|
+
if (opts.tpOrdPx) body["tpOrdPx"] = opts.tpOrdPx;
|
|
197
|
+
if (opts.slTriggerPx) body["slTriggerPx"] = opts.slTriggerPx;
|
|
198
|
+
if (opts.slOrdPx) body["slOrdPx"] = opts.slOrdPx;
|
|
199
|
+
const res = await client.privatePost("/api/v5/trade/order-algo", body);
|
|
200
|
+
if (opts.json) return printJson(res.data);
|
|
201
|
+
const order = res.data[0];
|
|
202
|
+
process.stdout.write(
|
|
203
|
+
`Algo order placed: ${order?.["algoId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
204
|
+
`
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
async function cmdSpotAlgoAmend(client, opts) {
|
|
208
|
+
const body = {
|
|
209
|
+
instId: opts.instId,
|
|
210
|
+
algoId: opts.algoId
|
|
211
|
+
};
|
|
212
|
+
if (opts.newSz) body["newSz"] = opts.newSz;
|
|
213
|
+
if (opts.newTpTriggerPx) body["newTpTriggerPx"] = opts.newTpTriggerPx;
|
|
214
|
+
if (opts.newTpOrdPx) body["newTpOrdPx"] = opts.newTpOrdPx;
|
|
215
|
+
if (opts.newSlTriggerPx) body["newSlTriggerPx"] = opts.newSlTriggerPx;
|
|
216
|
+
if (opts.newSlOrdPx) body["newSlOrdPx"] = opts.newSlOrdPx;
|
|
217
|
+
const res = await client.privatePost("/api/v5/trade/amend-algos", body);
|
|
218
|
+
if (opts.json) return printJson(res.data);
|
|
219
|
+
const r = res.data[0];
|
|
220
|
+
process.stdout.write(
|
|
221
|
+
`Algo order amended: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
222
|
+
`
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
async function cmdSpotAlgoCancel(client, instId, algoId, json) {
|
|
226
|
+
const res = await client.privatePost("/api/v5/trade/cancel-algos", [
|
|
227
|
+
{ algoId, instId }
|
|
228
|
+
]);
|
|
229
|
+
if (json) return printJson(res.data);
|
|
230
|
+
const r = res.data[0];
|
|
231
|
+
process.stdout.write(
|
|
232
|
+
`Algo order cancelled: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
233
|
+
`
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
async function cmdSpotAlgoOrders(client, opts) {
|
|
237
|
+
const endpoint = opts.status === "history" ? "/api/v5/trade/orders-algo-history" : "/api/v5/trade/orders-algo-pending";
|
|
238
|
+
const baseParams = { instType: "SPOT" };
|
|
239
|
+
if (opts.instId) baseParams["instId"] = opts.instId;
|
|
240
|
+
let orders;
|
|
241
|
+
if (opts.ordType) {
|
|
242
|
+
const res = await client.privateGet(endpoint, { ...baseParams, ordType: opts.ordType });
|
|
243
|
+
orders = res.data ?? [];
|
|
244
|
+
} else {
|
|
245
|
+
const [r1, r2] = await Promise.all([
|
|
246
|
+
client.privateGet(endpoint, { ...baseParams, ordType: "conditional" }),
|
|
247
|
+
client.privateGet(endpoint, { ...baseParams, ordType: "oco" })
|
|
248
|
+
]);
|
|
249
|
+
orders = [
|
|
250
|
+
...r1.data ?? [],
|
|
251
|
+
...r2.data ?? []
|
|
252
|
+
];
|
|
253
|
+
}
|
|
254
|
+
if (opts.json) return printJson(orders);
|
|
255
|
+
if (!(orders ?? []).length) {
|
|
256
|
+
process.stdout.write("No algo orders\n");
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
printTable(
|
|
260
|
+
orders.map((o) => ({
|
|
261
|
+
algoId: o["algoId"],
|
|
262
|
+
instId: o["instId"],
|
|
263
|
+
type: o["ordType"],
|
|
264
|
+
side: o["side"],
|
|
265
|
+
sz: o["sz"],
|
|
266
|
+
tpTrigger: o["tpTriggerPx"],
|
|
267
|
+
slTrigger: o["slTriggerPx"],
|
|
268
|
+
state: o["state"]
|
|
269
|
+
}))
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
async function cmdSpotFills(client, opts) {
|
|
273
|
+
const params = { instType: "SPOT" };
|
|
274
|
+
if (opts.instId) params["instId"] = opts.instId;
|
|
275
|
+
if (opts.ordId) params["ordId"] = opts.ordId;
|
|
276
|
+
const res = await client.privateGet("/api/v5/trade/fills", params);
|
|
277
|
+
const fills = res.data;
|
|
278
|
+
if (opts.json) return printJson(fills);
|
|
279
|
+
printTable(
|
|
280
|
+
(fills ?? []).map((f) => ({
|
|
281
|
+
instId: f["instId"],
|
|
282
|
+
side: f["side"],
|
|
283
|
+
fillPx: f["fillPx"],
|
|
284
|
+
fillSz: f["fillSz"],
|
|
285
|
+
fee: f["fee"],
|
|
286
|
+
ts: new Date(Number(f["ts"])).toLocaleString()
|
|
287
|
+
}))
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// src/commands/swap.ts
|
|
292
|
+
async function cmdSwapPositions(client, instId, json) {
|
|
293
|
+
const params = { instType: "SWAP" };
|
|
294
|
+
if (instId) params["instId"] = instId;
|
|
295
|
+
const res = await client.privateGet("/api/v5/account/positions", params);
|
|
296
|
+
const positions = res.data;
|
|
297
|
+
if (json) return printJson(positions);
|
|
298
|
+
const open = (positions ?? []).filter((p) => Number(p["pos"]) !== 0);
|
|
299
|
+
if (!open.length) {
|
|
300
|
+
process.stdout.write("No open positions\n");
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
printTable(
|
|
304
|
+
open.map((p) => ({
|
|
305
|
+
instId: p["instId"],
|
|
306
|
+
side: p["posSide"],
|
|
307
|
+
size: p["pos"],
|
|
308
|
+
avgPx: p["avgPx"],
|
|
309
|
+
upl: p["upl"],
|
|
310
|
+
uplRatio: p["uplRatio"],
|
|
311
|
+
lever: p["lever"]
|
|
312
|
+
}))
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
async function cmdSwapOrders(client, opts) {
|
|
316
|
+
const endpoint = opts.status === "history" ? "/api/v5/trade/orders-history" : "/api/v5/trade/orders-pending";
|
|
317
|
+
const params = { instType: "SWAP" };
|
|
318
|
+
if (opts.instId) params["instId"] = opts.instId;
|
|
319
|
+
const res = await client.privateGet(endpoint, params);
|
|
320
|
+
const orders = res.data;
|
|
321
|
+
if (opts.json) return printJson(orders);
|
|
322
|
+
printTable(
|
|
323
|
+
(orders ?? []).map((o) => ({
|
|
324
|
+
ordId: o["ordId"],
|
|
325
|
+
instId: o["instId"],
|
|
326
|
+
side: o["side"],
|
|
327
|
+
posSide: o["posSide"],
|
|
328
|
+
type: o["ordType"],
|
|
329
|
+
price: o["px"],
|
|
330
|
+
size: o["sz"],
|
|
331
|
+
state: o["state"]
|
|
332
|
+
}))
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
async function cmdSwapPlace(client, opts) {
|
|
336
|
+
const body = {
|
|
337
|
+
instId: opts.instId,
|
|
338
|
+
tdMode: opts.tdMode,
|
|
339
|
+
side: opts.side,
|
|
340
|
+
ordType: opts.ordType,
|
|
341
|
+
sz: opts.sz
|
|
342
|
+
};
|
|
343
|
+
if (opts.posSide) body["posSide"] = opts.posSide;
|
|
344
|
+
if (opts.px) body["px"] = opts.px;
|
|
345
|
+
const res = await client.privatePost("/api/v5/trade/order", body);
|
|
346
|
+
if (opts.json) return printJson(res.data);
|
|
347
|
+
const order = res.data[0];
|
|
348
|
+
process.stdout.write(`Order placed: ${order?.["ordId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
349
|
+
`);
|
|
350
|
+
}
|
|
351
|
+
async function cmdSwapCancel(client, instId, ordId, json) {
|
|
352
|
+
const res = await client.privatePost("/api/v5/trade/cancel-order", { instId, ordId });
|
|
353
|
+
if (json) return printJson(res.data);
|
|
354
|
+
const r = res.data[0];
|
|
355
|
+
process.stdout.write(`Cancelled: ${r?.["ordId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
356
|
+
`);
|
|
357
|
+
}
|
|
358
|
+
async function cmdSwapAlgoPlace(client, opts) {
|
|
359
|
+
const body = {
|
|
360
|
+
instId: opts.instId,
|
|
361
|
+
tdMode: opts.tdMode,
|
|
362
|
+
side: opts.side,
|
|
363
|
+
ordType: opts.ordType,
|
|
364
|
+
sz: opts.sz
|
|
365
|
+
};
|
|
366
|
+
if (opts.posSide) body["posSide"] = opts.posSide;
|
|
367
|
+
if (opts.tpTriggerPx) body["tpTriggerPx"] = opts.tpTriggerPx;
|
|
368
|
+
if (opts.tpOrdPx) body["tpOrdPx"] = opts.tpOrdPx;
|
|
369
|
+
if (opts.slTriggerPx) body["slTriggerPx"] = opts.slTriggerPx;
|
|
370
|
+
if (opts.slOrdPx) body["slOrdPx"] = opts.slOrdPx;
|
|
371
|
+
if (opts.reduceOnly !== void 0) body["reduceOnly"] = String(opts.reduceOnly);
|
|
372
|
+
const res = await client.privatePost("/api/v5/trade/order-algo", body);
|
|
373
|
+
if (opts.json) return printJson(res.data);
|
|
374
|
+
const order = res.data[0];
|
|
375
|
+
process.stdout.write(
|
|
376
|
+
`Algo order placed: ${order?.["algoId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
377
|
+
`
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
async function cmdSwapAlgoAmend(client, opts) {
|
|
381
|
+
const body = {
|
|
382
|
+
instId: opts.instId,
|
|
383
|
+
algoId: opts.algoId
|
|
384
|
+
};
|
|
385
|
+
if (opts.newSz) body["newSz"] = opts.newSz;
|
|
386
|
+
if (opts.newTpTriggerPx) body["newTpTriggerPx"] = opts.newTpTriggerPx;
|
|
387
|
+
if (opts.newTpOrdPx) body["newTpOrdPx"] = opts.newTpOrdPx;
|
|
388
|
+
if (opts.newSlTriggerPx) body["newSlTriggerPx"] = opts.newSlTriggerPx;
|
|
389
|
+
if (opts.newSlOrdPx) body["newSlOrdPx"] = opts.newSlOrdPx;
|
|
390
|
+
const res = await client.privatePost("/api/v5/trade/amend-algos", body);
|
|
391
|
+
if (opts.json) return printJson(res.data);
|
|
392
|
+
const r = res.data[0];
|
|
393
|
+
process.stdout.write(
|
|
394
|
+
`Algo order amended: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
395
|
+
`
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
async function cmdSwapAlgoCancel(client, instId, algoId, json) {
|
|
399
|
+
const res = await client.privatePost("/api/v5/trade/cancel-algos", [
|
|
400
|
+
{ algoId, instId }
|
|
401
|
+
]);
|
|
402
|
+
if (json) return printJson(res.data);
|
|
403
|
+
const r = res.data[0];
|
|
404
|
+
process.stdout.write(
|
|
405
|
+
`Algo order cancelled: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
406
|
+
`
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
async function cmdSwapAlgoOrders(client, opts) {
|
|
410
|
+
const endpoint = opts.status === "history" ? "/api/v5/trade/orders-algo-history" : "/api/v5/trade/orders-algo-pending";
|
|
411
|
+
const baseParams = { instType: "SWAP" };
|
|
412
|
+
if (opts.instId) baseParams["instId"] = opts.instId;
|
|
413
|
+
let orders;
|
|
414
|
+
if (opts.ordType) {
|
|
415
|
+
const res = await client.privateGet(endpoint, { ...baseParams, ordType: opts.ordType });
|
|
416
|
+
orders = res.data ?? [];
|
|
417
|
+
} else {
|
|
418
|
+
const [r1, r2] = await Promise.all([
|
|
419
|
+
client.privateGet(endpoint, { ...baseParams, ordType: "conditional" }),
|
|
420
|
+
client.privateGet(endpoint, { ...baseParams, ordType: "oco" })
|
|
421
|
+
]);
|
|
422
|
+
orders = [
|
|
423
|
+
...r1.data ?? [],
|
|
424
|
+
...r2.data ?? []
|
|
425
|
+
];
|
|
426
|
+
}
|
|
427
|
+
if (opts.json) return printJson(orders);
|
|
428
|
+
if (!(orders ?? []).length) {
|
|
429
|
+
process.stdout.write("No algo orders\n");
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
printTable(
|
|
433
|
+
orders.map((o) => ({
|
|
434
|
+
algoId: o["algoId"],
|
|
435
|
+
instId: o["instId"],
|
|
436
|
+
type: o["ordType"],
|
|
437
|
+
side: o["side"],
|
|
438
|
+
sz: o["sz"],
|
|
439
|
+
tpTrigger: o["tpTriggerPx"],
|
|
440
|
+
slTrigger: o["slTriggerPx"],
|
|
441
|
+
state: o["state"]
|
|
442
|
+
}))
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
async function cmdSwapSetLeverage(client, opts) {
|
|
446
|
+
const body = {
|
|
447
|
+
instId: opts.instId,
|
|
448
|
+
lever: opts.lever,
|
|
449
|
+
mgnMode: opts.mgnMode
|
|
450
|
+
};
|
|
451
|
+
if (opts.posSide) body["posSide"] = opts.posSide;
|
|
452
|
+
const res = await client.privatePost("/api/v5/account/set-leverage", body);
|
|
453
|
+
if (opts.json) return printJson(res.data);
|
|
454
|
+
const r = res.data[0];
|
|
455
|
+
process.stdout.write(`Leverage set: ${r?.["lever"]}x ${r?.["instId"]}
|
|
456
|
+
`);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// src/commands/config.ts
|
|
460
|
+
import { configFilePath as configFilePath2 } from "@okx-hub/core";
|
|
461
|
+
|
|
462
|
+
// src/config/toml.ts
|
|
463
|
+
import { writeFileSync, mkdirSync, existsSync } from "fs";
|
|
464
|
+
import { stringify } from "smol-toml";
|
|
465
|
+
import { configFilePath } from "@okx-hub/core";
|
|
466
|
+
function configDir() {
|
|
467
|
+
return configFilePath().replace(/\/config\.toml$/, "");
|
|
468
|
+
}
|
|
469
|
+
function writeCliConfig(config) {
|
|
470
|
+
const dir = configDir();
|
|
471
|
+
if (!existsSync(dir)) {
|
|
472
|
+
mkdirSync(dir, { recursive: true });
|
|
473
|
+
}
|
|
474
|
+
writeFileSync(configFilePath(), stringify(config), "utf-8");
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// src/commands/config.ts
|
|
478
|
+
import { existsSync as existsSync2, readFileSync } from "fs";
|
|
479
|
+
import { parse } from "smol-toml";
|
|
480
|
+
function readFullConfig() {
|
|
481
|
+
const path = configFilePath2();
|
|
482
|
+
if (!existsSync2(path)) return { profiles: {} };
|
|
483
|
+
const raw = readFileSync(path, "utf-8");
|
|
484
|
+
return parse(raw);
|
|
485
|
+
}
|
|
486
|
+
function cmdConfigShow(json) {
|
|
487
|
+
const config = readFullConfig();
|
|
488
|
+
if (json) return printJson(config);
|
|
489
|
+
process.stdout.write(`Config: ${configFilePath2()}
|
|
490
|
+
|
|
491
|
+
`);
|
|
492
|
+
process.stdout.write(`default_profile: ${config.default_profile ?? "(not set)"}
|
|
493
|
+
|
|
494
|
+
`);
|
|
495
|
+
for (const [name, profile] of Object.entries(config.profiles)) {
|
|
496
|
+
process.stdout.write(`[${name}]
|
|
497
|
+
`);
|
|
498
|
+
printKv({
|
|
499
|
+
api_key: profile.api_key ? "***" + profile.api_key.slice(-4) : "(not set)",
|
|
500
|
+
demo: profile.demo ?? false,
|
|
501
|
+
base_url: profile.base_url ?? "(default)"
|
|
502
|
+
}, 2);
|
|
503
|
+
process.stdout.write("\n");
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
function cmdConfigSet(key, value) {
|
|
507
|
+
const config = readFullConfig();
|
|
508
|
+
if (key === "default_profile") {
|
|
509
|
+
config.default_profile = value;
|
|
510
|
+
writeCliConfig(config);
|
|
511
|
+
process.stdout.write(`default_profile set to "${value}"
|
|
512
|
+
`);
|
|
513
|
+
} else {
|
|
514
|
+
process.stderr.write(`Unknown config key: ${key}
|
|
515
|
+
`);
|
|
516
|
+
process.exitCode = 1;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// src/index.ts
|
|
521
|
+
function printHelp() {
|
|
522
|
+
process.stdout.write(`
|
|
523
|
+
Usage: okx [--profile <name>] [--json] <command> [args]
|
|
524
|
+
|
|
525
|
+
Global Options:
|
|
526
|
+
--profile <name> Use a named profile from ~/.okx/config.toml
|
|
527
|
+
--json Output raw JSON
|
|
528
|
+
--help Show this help
|
|
529
|
+
|
|
530
|
+
Commands:
|
|
531
|
+
market ticker <instId>
|
|
532
|
+
market tickers <instType> (SPOT|SWAP|FUTURES|OPTION)
|
|
533
|
+
market orderbook <instId> [--sz <n>]
|
|
534
|
+
market candles <instId> [--bar <bar>] [--limit <n>]
|
|
535
|
+
|
|
536
|
+
account balance [<ccy>]
|
|
537
|
+
|
|
538
|
+
spot orders [--instId <id>] [--history]
|
|
539
|
+
spot fills [--instId <id>] [--ordId <id>]
|
|
540
|
+
spot place --instId <id> --side <buy|sell> --ordType <type> --sz <n> [--px <price>]
|
|
541
|
+
spot cancel <instId> --ordId <id>
|
|
542
|
+
spot algo orders [--instId <id>] [--history] [--ordType <conditional|oco>]
|
|
543
|
+
spot algo place --instId <id> --side <buy|sell> --sz <n> [--ordType <conditional|oco>]
|
|
544
|
+
[--tpTriggerPx <price>] [--tpOrdPx <price|-1>]
|
|
545
|
+
[--slTriggerPx <price>] [--slOrdPx <price|-1>]
|
|
546
|
+
spot algo amend --instId <id> --algoId <id> [--newSz <n>]
|
|
547
|
+
[--newTpTriggerPx <price>] [--newTpOrdPx <price|-1>]
|
|
548
|
+
[--newSlTriggerPx <price>] [--newSlOrdPx <price|-1>]
|
|
549
|
+
spot algo cancel --instId <id> --algoId <id>
|
|
550
|
+
|
|
551
|
+
swap positions [<instId>]
|
|
552
|
+
swap orders [--instId <id>] [--history]
|
|
553
|
+
swap place --instId <id> --side <buy|sell> --ordType <type> --sz <n> [--posSide <side>] [--px <price>] [--tdMode <cross|isolated>]
|
|
554
|
+
swap cancel <instId> --ordId <id>
|
|
555
|
+
swap leverage --instId <id> --lever <n> --mgnMode <cross|isolated> [--posSide <side>]
|
|
556
|
+
swap algo orders [--instId <id>] [--history] [--ordType <conditional|oco>]
|
|
557
|
+
swap algo place --instId <id> --side <buy|sell> --sz <n> [--ordType <conditional|oco>]
|
|
558
|
+
[--tpTriggerPx <price>] [--tpOrdPx <price|-1>]
|
|
559
|
+
[--slTriggerPx <price>] [--slOrdPx <price|-1>]
|
|
560
|
+
[--posSide <net|long|short>] [--tdMode <cross|isolated>] [--reduceOnly]
|
|
561
|
+
swap algo amend --instId <id> --algoId <id> [--newSz <n>]
|
|
562
|
+
[--newTpTriggerPx <price>] [--newTpOrdPx <price|-1>]
|
|
563
|
+
[--newSlTriggerPx <price>] [--newSlOrdPx <price|-1>]
|
|
564
|
+
swap algo cancel --instId <id> --algoId <id>
|
|
565
|
+
|
|
566
|
+
config show
|
|
567
|
+
config set <key> <value>
|
|
568
|
+
`);
|
|
569
|
+
}
|
|
570
|
+
async function main() {
|
|
571
|
+
const { values, positionals } = parseArgs({
|
|
572
|
+
args: process.argv.slice(2),
|
|
573
|
+
options: {
|
|
574
|
+
profile: { type: "string" },
|
|
575
|
+
json: { type: "boolean", default: false },
|
|
576
|
+
help: { type: "boolean", default: false },
|
|
577
|
+
// market candles
|
|
578
|
+
bar: { type: "string" },
|
|
579
|
+
limit: { type: "string" },
|
|
580
|
+
sz: { type: "string" },
|
|
581
|
+
// orders
|
|
582
|
+
instId: { type: "string" },
|
|
583
|
+
history: { type: "boolean", default: false },
|
|
584
|
+
ordId: { type: "string" },
|
|
585
|
+
// trade
|
|
586
|
+
side: { type: "string" },
|
|
587
|
+
ordType: { type: "string" },
|
|
588
|
+
px: { type: "string" },
|
|
589
|
+
posSide: { type: "string" },
|
|
590
|
+
tdMode: { type: "string" },
|
|
591
|
+
// leverage
|
|
592
|
+
lever: { type: "string" },
|
|
593
|
+
mgnMode: { type: "string" },
|
|
594
|
+
// algo orders
|
|
595
|
+
tpTriggerPx: { type: "string" },
|
|
596
|
+
tpOrdPx: { type: "string" },
|
|
597
|
+
slTriggerPx: { type: "string" },
|
|
598
|
+
slOrdPx: { type: "string" },
|
|
599
|
+
algoId: { type: "string" },
|
|
600
|
+
reduceOnly: { type: "boolean", default: false },
|
|
601
|
+
// algo amend
|
|
602
|
+
newSz: { type: "string" },
|
|
603
|
+
newTpTriggerPx: { type: "string" },
|
|
604
|
+
newTpOrdPx: { type: "string" },
|
|
605
|
+
newSlTriggerPx: { type: "string" },
|
|
606
|
+
newSlOrdPx: { type: "string" }
|
|
607
|
+
},
|
|
608
|
+
allowPositionals: true
|
|
609
|
+
});
|
|
610
|
+
if (values.help || positionals.length === 0) {
|
|
611
|
+
printHelp();
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
const [module, action, ...rest] = positionals;
|
|
615
|
+
const json = values.json ?? false;
|
|
616
|
+
if (module === "config") {
|
|
617
|
+
if (action === "show") return cmdConfigShow(json);
|
|
618
|
+
if (action === "set") return cmdConfigSet(rest[0], rest[1]);
|
|
619
|
+
process.stderr.write(`Unknown config command: ${action}
|
|
620
|
+
`);
|
|
621
|
+
process.exitCode = 1;
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
const config = loadProfileConfig({ profile: values.profile });
|
|
625
|
+
const client = new OkxRestClient(config);
|
|
626
|
+
if (module === "market") {
|
|
627
|
+
if (action === "ticker") return cmdMarketTicker(client, rest[0], json);
|
|
628
|
+
if (action === "tickers") return cmdMarketTickers(client, rest[0], json);
|
|
629
|
+
if (action === "orderbook")
|
|
630
|
+
return cmdMarketOrderbook(client, rest[0], values.sz ? Number(values.sz) : void 0, json);
|
|
631
|
+
if (action === "candles")
|
|
632
|
+
return cmdMarketCandles(client, rest[0], {
|
|
633
|
+
bar: values.bar,
|
|
634
|
+
limit: values.limit ? Number(values.limit) : void 0,
|
|
635
|
+
json
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
if (module === "account") {
|
|
639
|
+
if (action === "balance") return cmdAccountBalance(client, rest[0], json);
|
|
640
|
+
}
|
|
641
|
+
if (module === "spot") {
|
|
642
|
+
if (action === "orders")
|
|
643
|
+
return cmdSpotOrders(client, {
|
|
644
|
+
instId: values.instId,
|
|
645
|
+
status: values.history ? "history" : "open",
|
|
646
|
+
json
|
|
647
|
+
});
|
|
648
|
+
if (action === "fills")
|
|
649
|
+
return cmdSpotFills(client, { instId: values.instId, ordId: values.ordId, json });
|
|
650
|
+
if (action === "place")
|
|
651
|
+
return cmdSpotPlace(client, {
|
|
652
|
+
instId: values.instId,
|
|
653
|
+
side: values.side,
|
|
654
|
+
ordType: values.ordType,
|
|
655
|
+
sz: values.sz,
|
|
656
|
+
px: values.px,
|
|
657
|
+
json
|
|
658
|
+
});
|
|
659
|
+
if (action === "cancel")
|
|
660
|
+
return cmdSpotCancel(client, rest[0], values.ordId, json);
|
|
661
|
+
if (action === "algo") {
|
|
662
|
+
const subAction = rest[0];
|
|
663
|
+
if (subAction === "place")
|
|
664
|
+
return cmdSpotAlgoPlace(client, {
|
|
665
|
+
instId: values.instId,
|
|
666
|
+
side: values.side,
|
|
667
|
+
ordType: values.ordType ?? "conditional",
|
|
668
|
+
sz: values.sz,
|
|
669
|
+
tpTriggerPx: values.tpTriggerPx,
|
|
670
|
+
tpOrdPx: values.tpOrdPx,
|
|
671
|
+
slTriggerPx: values.slTriggerPx,
|
|
672
|
+
slOrdPx: values.slOrdPx,
|
|
673
|
+
json
|
|
674
|
+
});
|
|
675
|
+
if (subAction === "amend")
|
|
676
|
+
return cmdSpotAlgoAmend(client, {
|
|
677
|
+
instId: values.instId,
|
|
678
|
+
algoId: values.algoId,
|
|
679
|
+
newSz: values.newSz,
|
|
680
|
+
newTpTriggerPx: values.newTpTriggerPx,
|
|
681
|
+
newTpOrdPx: values.newTpOrdPx,
|
|
682
|
+
newSlTriggerPx: values.newSlTriggerPx,
|
|
683
|
+
newSlOrdPx: values.newSlOrdPx,
|
|
684
|
+
json
|
|
685
|
+
});
|
|
686
|
+
if (subAction === "cancel")
|
|
687
|
+
return cmdSpotAlgoCancel(client, values.instId, values.algoId, json);
|
|
688
|
+
if (subAction === "orders")
|
|
689
|
+
return cmdSpotAlgoOrders(client, {
|
|
690
|
+
instId: values.instId,
|
|
691
|
+
status: values.history ? "history" : "pending",
|
|
692
|
+
ordType: values.ordType,
|
|
693
|
+
json
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
if (module === "swap") {
|
|
698
|
+
if (action === "positions")
|
|
699
|
+
return cmdSwapPositions(client, rest[0] ?? values.instId, json);
|
|
700
|
+
if (action === "orders")
|
|
701
|
+
return cmdSwapOrders(client, {
|
|
702
|
+
instId: values.instId,
|
|
703
|
+
status: values.history ? "history" : "open",
|
|
704
|
+
json
|
|
705
|
+
});
|
|
706
|
+
if (action === "place")
|
|
707
|
+
return cmdSwapPlace(client, {
|
|
708
|
+
instId: values.instId,
|
|
709
|
+
side: values.side,
|
|
710
|
+
ordType: values.ordType,
|
|
711
|
+
sz: values.sz,
|
|
712
|
+
posSide: values.posSide,
|
|
713
|
+
px: values.px,
|
|
714
|
+
tdMode: values.tdMode ?? "cross",
|
|
715
|
+
json
|
|
716
|
+
});
|
|
717
|
+
if (action === "cancel")
|
|
718
|
+
return cmdSwapCancel(client, rest[0], values.ordId, json);
|
|
719
|
+
if (action === "leverage")
|
|
720
|
+
return cmdSwapSetLeverage(client, {
|
|
721
|
+
instId: values.instId,
|
|
722
|
+
lever: values.lever,
|
|
723
|
+
mgnMode: values.mgnMode,
|
|
724
|
+
posSide: values.posSide,
|
|
725
|
+
json
|
|
726
|
+
});
|
|
727
|
+
if (action === "algo") {
|
|
728
|
+
const subAction = rest[0];
|
|
729
|
+
if (subAction === "place")
|
|
730
|
+
return cmdSwapAlgoPlace(client, {
|
|
731
|
+
instId: values.instId,
|
|
732
|
+
side: values.side,
|
|
733
|
+
ordType: values.ordType ?? "conditional",
|
|
734
|
+
sz: values.sz,
|
|
735
|
+
posSide: values.posSide,
|
|
736
|
+
tdMode: values.tdMode ?? "cross",
|
|
737
|
+
tpTriggerPx: values.tpTriggerPx,
|
|
738
|
+
tpOrdPx: values.tpOrdPx,
|
|
739
|
+
slTriggerPx: values.slTriggerPx,
|
|
740
|
+
slOrdPx: values.slOrdPx,
|
|
741
|
+
reduceOnly: values.reduceOnly,
|
|
742
|
+
json
|
|
743
|
+
});
|
|
744
|
+
if (subAction === "amend")
|
|
745
|
+
return cmdSwapAlgoAmend(client, {
|
|
746
|
+
instId: values.instId,
|
|
747
|
+
algoId: values.algoId,
|
|
748
|
+
newSz: values.newSz,
|
|
749
|
+
newTpTriggerPx: values.newTpTriggerPx,
|
|
750
|
+
newTpOrdPx: values.newTpOrdPx,
|
|
751
|
+
newSlTriggerPx: values.newSlTriggerPx,
|
|
752
|
+
newSlOrdPx: values.newSlOrdPx,
|
|
753
|
+
json
|
|
754
|
+
});
|
|
755
|
+
if (subAction === "cancel")
|
|
756
|
+
return cmdSwapAlgoCancel(client, values.instId, values.algoId, json);
|
|
757
|
+
if (subAction === "orders")
|
|
758
|
+
return cmdSwapAlgoOrders(client, {
|
|
759
|
+
instId: values.instId,
|
|
760
|
+
status: values.history ? "history" : "pending",
|
|
761
|
+
ordType: values.ordType,
|
|
762
|
+
json
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
process.stderr.write(`Unknown command: ${module} ${action ?? ""}
|
|
767
|
+
`);
|
|
768
|
+
process.exitCode = 1;
|
|
769
|
+
}
|
|
770
|
+
main().catch((error) => {
|
|
771
|
+
const payload = toToolErrorPayload(error);
|
|
772
|
+
process.stderr.write(`Error: ${payload.message}
|
|
773
|
+
`);
|
|
774
|
+
if (payload.suggestion) process.stderr.write(`Hint: ${payload.suggestion}
|
|
775
|
+
`);
|
|
776
|
+
process.exitCode = 1;
|
|
777
|
+
});
|
|
778
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config/loader.ts","../src/formatter.ts","../src/commands/market.ts","../src/commands/account.ts","../src/commands/spot.ts","../src/commands/swap.ts","../src/commands/config.ts","../src/config/toml.ts"],"sourcesContent":["import { parseArgs } from \"node:util\";\nimport { OkxRestClient, toToolErrorPayload } from \"@okx-hub/core\";\nimport { loadProfileConfig } from \"./config/loader.js\";\nimport {\n cmdMarketTicker,\n cmdMarketTickers,\n cmdMarketOrderbook,\n cmdMarketCandles,\n} from \"./commands/market.js\";\nimport { cmdAccountBalance } from \"./commands/account.js\";\nimport {\n cmdSpotOrders,\n cmdSpotPlace,\n cmdSpotCancel,\n cmdSpotFills,\n cmdSpotAlgoPlace,\n cmdSpotAlgoAmend,\n cmdSpotAlgoCancel,\n cmdSpotAlgoOrders,\n} from \"./commands/spot.js\";\nimport {\n cmdSwapPositions,\n cmdSwapOrders,\n cmdSwapPlace,\n cmdSwapCancel,\n cmdSwapSetLeverage,\n cmdSwapAlgoPlace,\n cmdSwapAlgoAmend,\n cmdSwapAlgoCancel,\n cmdSwapAlgoOrders,\n} from \"./commands/swap.js\";\nimport { cmdConfigShow, cmdConfigSet } from \"./commands/config.js\";\n\nfunction printHelp(): void {\n process.stdout.write(`\nUsage: okx [--profile <name>] [--json] <command> [args]\n\nGlobal Options:\n --profile <name> Use a named profile from ~/.okx/config.toml\n --json Output raw JSON\n --help Show this help\n\nCommands:\n market ticker <instId>\n market tickers <instType> (SPOT|SWAP|FUTURES|OPTION)\n market orderbook <instId> [--sz <n>]\n market candles <instId> [--bar <bar>] [--limit <n>]\n\n account balance [<ccy>]\n\n spot orders [--instId <id>] [--history]\n spot fills [--instId <id>] [--ordId <id>]\n spot place --instId <id> --side <buy|sell> --ordType <type> --sz <n> [--px <price>]\n spot cancel <instId> --ordId <id>\n spot algo orders [--instId <id>] [--history] [--ordType <conditional|oco>]\n spot algo place --instId <id> --side <buy|sell> --sz <n> [--ordType <conditional|oco>]\n [--tpTriggerPx <price>] [--tpOrdPx <price|-1>]\n [--slTriggerPx <price>] [--slOrdPx <price|-1>]\n spot algo amend --instId <id> --algoId <id> [--newSz <n>]\n [--newTpTriggerPx <price>] [--newTpOrdPx <price|-1>]\n [--newSlTriggerPx <price>] [--newSlOrdPx <price|-1>]\n spot algo cancel --instId <id> --algoId <id>\n\n swap positions [<instId>]\n swap orders [--instId <id>] [--history]\n swap place --instId <id> --side <buy|sell> --ordType <type> --sz <n> [--posSide <side>] [--px <price>] [--tdMode <cross|isolated>]\n swap cancel <instId> --ordId <id>\n swap leverage --instId <id> --lever <n> --mgnMode <cross|isolated> [--posSide <side>]\n swap algo orders [--instId <id>] [--history] [--ordType <conditional|oco>]\n swap algo place --instId <id> --side <buy|sell> --sz <n> [--ordType <conditional|oco>]\n [--tpTriggerPx <price>] [--tpOrdPx <price|-1>]\n [--slTriggerPx <price>] [--slOrdPx <price|-1>]\n [--posSide <net|long|short>] [--tdMode <cross|isolated>] [--reduceOnly]\n swap algo amend --instId <id> --algoId <id> [--newSz <n>]\n [--newTpTriggerPx <price>] [--newTpOrdPx <price|-1>]\n [--newSlTriggerPx <price>] [--newSlOrdPx <price|-1>]\n swap algo cancel --instId <id> --algoId <id>\n\n config show\n config set <key> <value>\n`);\n}\n\nasync function main(): Promise<void> {\n const { values, positionals } = parseArgs({\n args: process.argv.slice(2),\n options: {\n profile: { type: \"string\" },\n json: { type: \"boolean\", default: false },\n help: { type: \"boolean\", default: false },\n // market candles\n bar: { type: \"string\" },\n limit: { type: \"string\" },\n sz: { type: \"string\" },\n // orders\n instId: { type: \"string\" },\n history: { type: \"boolean\", default: false },\n ordId: { type: \"string\" },\n // trade\n side: { type: \"string\" },\n ordType: { type: \"string\" },\n px: { type: \"string\" },\n posSide: { type: \"string\" },\n tdMode: { type: \"string\" },\n // leverage\n lever: { type: \"string\" },\n mgnMode: { type: \"string\" },\n // algo orders\n tpTriggerPx: { type: \"string\" },\n tpOrdPx: { type: \"string\" },\n slTriggerPx: { type: \"string\" },\n slOrdPx: { type: \"string\" },\n algoId: { type: \"string\" },\n reduceOnly: { type: \"boolean\", default: false },\n // algo amend\n newSz: { type: \"string\" },\n newTpTriggerPx: { type: \"string\" },\n newTpOrdPx: { type: \"string\" },\n newSlTriggerPx: { type: \"string\" },\n newSlOrdPx: { type: \"string\" },\n },\n allowPositionals: true,\n });\n\n if (values.help || positionals.length === 0) {\n printHelp();\n return;\n }\n\n const [module, action, ...rest] = positionals;\n const json = values.json ?? false;\n\n // config commands don't need a client\n if (module === \"config\") {\n if (action === \"show\") return cmdConfigShow(json);\n if (action === \"set\") return cmdConfigSet(rest[0], rest[1]);\n process.stderr.write(`Unknown config command: ${action}\\n`);\n process.exitCode = 1;\n return;\n }\n\n const config = loadProfileConfig({ profile: values.profile });\n const client = new OkxRestClient(config);\n\n if (module === \"market\") {\n if (action === \"ticker\") return cmdMarketTicker(client, rest[0], json);\n if (action === \"tickers\") return cmdMarketTickers(client, rest[0], json);\n if (action === \"orderbook\")\n return cmdMarketOrderbook(client, rest[0], values.sz ? Number(values.sz) : undefined, json);\n if (action === \"candles\")\n return cmdMarketCandles(client, rest[0], {\n bar: values.bar,\n limit: values.limit ? Number(values.limit) : undefined,\n json,\n });\n }\n\n if (module === \"account\") {\n if (action === \"balance\") return cmdAccountBalance(client, rest[0], json);\n }\n\n if (module === \"spot\") {\n if (action === \"orders\")\n return cmdSpotOrders(client, {\n instId: values.instId,\n status: values.history ? \"history\" : \"open\",\n json,\n });\n if (action === \"fills\")\n return cmdSpotFills(client, { instId: values.instId, ordId: values.ordId, json });\n if (action === \"place\")\n return cmdSpotPlace(client, {\n instId: values.instId!,\n side: values.side!,\n ordType: values.ordType!,\n sz: values.sz!,\n px: values.px,\n json,\n });\n if (action === \"cancel\")\n return cmdSpotCancel(client, rest[0], values.ordId!, json);\n if (action === \"algo\") {\n const subAction = rest[0];\n if (subAction === \"place\")\n return cmdSpotAlgoPlace(client, {\n instId: values.instId!,\n side: values.side!,\n ordType: values.ordType ?? \"conditional\",\n sz: values.sz!,\n tpTriggerPx: values.tpTriggerPx,\n tpOrdPx: values.tpOrdPx,\n slTriggerPx: values.slTriggerPx,\n slOrdPx: values.slOrdPx,\n json,\n });\n if (subAction === \"amend\")\n return cmdSpotAlgoAmend(client, {\n instId: values.instId!,\n algoId: values.algoId!,\n newSz: values.newSz,\n newTpTriggerPx: values.newTpTriggerPx,\n newTpOrdPx: values.newTpOrdPx,\n newSlTriggerPx: values.newSlTriggerPx,\n newSlOrdPx: values.newSlOrdPx,\n json,\n });\n if (subAction === \"cancel\")\n return cmdSpotAlgoCancel(client, values.instId!, values.algoId!, json);\n if (subAction === \"orders\")\n return cmdSpotAlgoOrders(client, {\n instId: values.instId,\n status: values.history ? \"history\" : \"pending\",\n ordType: values.ordType,\n json,\n });\n }\n }\n\n if (module === \"swap\") {\n if (action === \"positions\")\n return cmdSwapPositions(client, rest[0] ?? values.instId, json);\n if (action === \"orders\")\n return cmdSwapOrders(client, {\n instId: values.instId,\n status: values.history ? \"history\" : \"open\",\n json,\n });\n if (action === \"place\")\n return cmdSwapPlace(client, {\n instId: values.instId!,\n side: values.side!,\n ordType: values.ordType!,\n sz: values.sz!,\n posSide: values.posSide,\n px: values.px,\n tdMode: values.tdMode ?? \"cross\",\n json,\n });\n if (action === \"cancel\")\n return cmdSwapCancel(client, rest[0], values.ordId!, json);\n if (action === \"leverage\")\n return cmdSwapSetLeverage(client, {\n instId: values.instId!,\n lever: values.lever!,\n mgnMode: values.mgnMode!,\n posSide: values.posSide,\n json,\n });\n if (action === \"algo\") {\n const subAction = rest[0];\n if (subAction === \"place\")\n return cmdSwapAlgoPlace(client, {\n instId: values.instId!,\n side: values.side!,\n ordType: values.ordType ?? \"conditional\",\n sz: values.sz!,\n posSide: values.posSide,\n tdMode: values.tdMode ?? \"cross\",\n tpTriggerPx: values.tpTriggerPx,\n tpOrdPx: values.tpOrdPx,\n slTriggerPx: values.slTriggerPx,\n slOrdPx: values.slOrdPx,\n reduceOnly: values.reduceOnly,\n json,\n });\n if (subAction === \"amend\")\n return cmdSwapAlgoAmend(client, {\n instId: values.instId!,\n algoId: values.algoId!,\n newSz: values.newSz,\n newTpTriggerPx: values.newTpTriggerPx,\n newTpOrdPx: values.newTpOrdPx,\n newSlTriggerPx: values.newSlTriggerPx,\n newSlOrdPx: values.newSlOrdPx,\n json,\n });\n if (subAction === \"cancel\")\n return cmdSwapAlgoCancel(client, values.instId!, values.algoId!, json);\n if (subAction === \"orders\")\n return cmdSwapAlgoOrders(client, {\n instId: values.instId,\n status: values.history ? \"history\" : \"pending\",\n ordType: values.ordType,\n json,\n });\n }\n }\n\n process.stderr.write(`Unknown command: ${module} ${action ?? \"\"}\\n`);\n process.exitCode = 1;\n}\n\nmain().catch((error: unknown) => {\n const payload = toToolErrorPayload(error);\n process.stderr.write(`Error: ${payload.message}\\n`);\n if (payload.suggestion) process.stderr.write(`Hint: ${payload.suggestion}\\n`);\n process.exitCode = 1;\n});\n","import type { OkxConfig } from \"@okx-hub/core\";\nimport { loadConfig } from \"@okx-hub/core\";\n\nexport interface LoadProfileOptions {\n profile?: string;\n modules?: string;\n readOnly?: boolean;\n demo?: boolean;\n}\n\n/**\n * Load config for CLI commands.\n * Delegates to core's loadConfig which handles the full priority chain:\n * env vars > ~/.okx/config.toml (selected profile) > defaults\n */\nexport function loadProfileConfig(opts: LoadProfileOptions): OkxConfig {\n return loadConfig({\n profile: opts.profile,\n modules: opts.modules,\n readOnly: opts.readOnly ?? false,\n demo: opts.demo ?? false,\n });\n}\n","export function printJson(data: unknown): void {\n process.stdout.write(JSON.stringify(data, null, 2) + \"\\n\");\n}\n\nexport function printTable(rows: Record<string, unknown>[]): void {\n if (rows.length === 0) {\n process.stdout.write(\"(no data)\\n\");\n return;\n }\n const keys = Object.keys(rows[0]);\n const widths = keys.map((k) =>\n Math.max(k.length, ...rows.map((r) => String(r[k] ?? \"\").length)),\n );\n const header = keys.map((k, i) => k.padEnd(widths[i])).join(\" \");\n const divider = widths.map((w) => \"-\".repeat(w)).join(\" \");\n process.stdout.write(header + \"\\n\" + divider + \"\\n\");\n for (const row of rows) {\n process.stdout.write(\n keys.map((k, i) => String(row[k] ?? \"\").padEnd(widths[i])).join(\" \") + \"\\n\",\n );\n }\n}\n\nexport function printKv(obj: Record<string, unknown>, indent = 0): void {\n const pad = \" \".repeat(indent);\n for (const [k, v] of Object.entries(obj)) {\n if (v !== null && typeof v === \"object\" && !Array.isArray(v)) {\n process.stdout.write(`${pad}${k}:\\n`);\n printKv(v as Record<string, unknown>, indent + 2);\n } else {\n process.stdout.write(`${pad}${k.padEnd(20 - indent)} ${v}\\n`);\n }\n }\n}\n","import type { OkxRestClient } from \"@okx-hub/core\";\nimport { printJson, printKv, printTable } from \"../formatter.js\";\n\nexport async function cmdMarketTicker(\n client: OkxRestClient,\n instId: string,\n json: boolean,\n): Promise<void> {\n const res = await client.publicGet(\"/api/v5/market/ticker\", { instId });\n const items = res.data as Record<string, unknown>[];\n if (json) return printJson(items);\n if (!items?.length) { process.stdout.write(\"No data\\n\"); return; }\n const t = items[0];\n printKv({\n instId: t[\"instId\"],\n last: t[\"last\"],\n \"24h change %\": t[\"sodUtc8\"],\n \"24h high\": t[\"high24h\"],\n \"24h low\": t[\"low24h\"],\n \"24h vol\": t[\"vol24h\"],\n time: new Date(Number(t[\"ts\"])).toLocaleString(),\n });\n}\n\nexport async function cmdMarketTickers(\n client: OkxRestClient,\n instType: string,\n json: boolean,\n): Promise<void> {\n const res = await client.publicGet(\"/api/v5/market/tickers\", { instType });\n const items = res.data as Record<string, unknown>[];\n if (json) return printJson(items);\n printTable(\n (items ?? []).map((t) => ({\n instId: t[\"instId\"],\n last: t[\"last\"],\n \"24h high\": t[\"high24h\"],\n \"24h low\": t[\"low24h\"],\n \"24h vol\": t[\"vol24h\"],\n })),\n );\n}\n\nexport async function cmdMarketOrderbook(\n client: OkxRestClient,\n instId: string,\n sz: number | undefined,\n json: boolean,\n): Promise<void> {\n const params: Record<string, unknown> = { instId };\n if (sz !== undefined) params[\"sz\"] = String(sz);\n const res = await client.publicGet(\"/api/v5/market/books\", params);\n if (json) return printJson(res.data);\n const book = (res.data as Record<string, unknown>[])[0];\n if (!book) { process.stdout.write(\"No data\\n\"); return; }\n const asks = (book[\"asks\"] as string[][]).slice(0, 5);\n const bids = (book[\"bids\"] as string[][]).slice(0, 5);\n process.stdout.write(\"Asks (price / size):\\n\");\n for (const [p, s] of asks.reverse()) process.stdout.write(` ${p.padStart(16)} ${s}\\n`);\n process.stdout.write(\"Bids (price / size):\\n\");\n for (const [p, s] of bids) process.stdout.write(` ${p.padStart(16)} ${s}\\n`);\n}\n\nexport async function cmdMarketCandles(\n client: OkxRestClient,\n instId: string,\n opts: { bar?: string; limit?: number; json: boolean },\n): Promise<void> {\n const params: Record<string, unknown> = { instId };\n if (opts.bar) params[\"bar\"] = opts.bar;\n if (opts.limit) params[\"limit\"] = String(opts.limit);\n const res = await client.publicGet(\"/api/v5/market/candles\", params);\n const candles = res.data as string[][];\n if (opts.json) return printJson(candles);\n printTable(\n (candles ?? []).map(([ts, o, h, l, c, vol]) => ({\n time: new Date(Number(ts)).toLocaleString(),\n open: o, high: h, low: l, close: c, vol,\n })),\n );\n}\n","import type { OkxRestClient } from \"@okx-hub/core\";\nimport { printJson, printTable } from \"../formatter.js\";\n\nexport async function cmdAccountBalance(\n client: OkxRestClient,\n ccy: string | undefined,\n json: boolean,\n): Promise<void> {\n const params: Record<string, unknown> = {};\n if (ccy) params[\"ccy\"] = ccy;\n const res = await client.privateGet(\"/api/v5/account/balance\", params);\n const data = res.data as Record<string, unknown>[];\n if (json) return printJson(data);\n const details = (data?.[0]?.[\"details\"] as Record<string, unknown>[]) ?? [];\n printTable(\n details\n .filter((d) => Number(d[\"eq\"]) > 0)\n .map((d) => ({\n currency: d[\"ccy\"],\n equity: d[\"eq\"],\n available: d[\"availEq\"],\n frozen: d[\"frozenBal\"],\n })),\n );\n}\n","import type { OkxRestClient } from \"@okx-hub/core\";\nimport { printJson, printTable } from \"../formatter.js\";\n\nexport async function cmdSpotOrders(\n client: OkxRestClient,\n opts: { instId?: string; status: \"open\" | \"history\"; json: boolean },\n): Promise<void> {\n const endpoint =\n opts.status === \"history\"\n ? \"/api/v5/trade/orders-history\"\n : \"/api/v5/trade/orders-pending\";\n const params: Record<string, unknown> = { instType: \"SPOT\" };\n if (opts.instId) params[\"instId\"] = opts.instId;\n const res = await client.privateGet(endpoint, params);\n const orders = res.data as Record<string, unknown>[];\n if (opts.json) return printJson(orders);\n printTable(\n (orders ?? []).map((o) => ({\n ordId: o[\"ordId\"],\n instId: o[\"instId\"],\n side: o[\"side\"],\n type: o[\"ordType\"],\n price: o[\"px\"],\n size: o[\"sz\"],\n filled: o[\"fillSz\"],\n state: o[\"state\"],\n })),\n );\n}\n\nexport async function cmdSpotPlace(\n client: OkxRestClient,\n opts: {\n instId: string;\n side: string;\n ordType: string;\n sz: string;\n px?: string;\n json: boolean;\n },\n): Promise<void> {\n const body: Record<string, unknown> = {\n instId: opts.instId,\n tdMode: \"cash\",\n side: opts.side,\n ordType: opts.ordType,\n sz: opts.sz,\n };\n if (opts.px) body[\"px\"] = opts.px;\n const res = await client.privatePost(\"/api/v5/trade/order\", body);\n if (opts.json) return printJson(res.data);\n const order = (res.data as Record<string, unknown>[])[0];\n process.stdout.write(`Order placed: ${order?.[\"ordId\"]} (${order?.[\"sCode\"] === \"0\" ? \"OK\" : order?.[\"sMsg\"]})\\n`);\n}\n\nexport async function cmdSpotCancel(\n client: OkxRestClient,\n instId: string,\n ordId: string,\n json: boolean,\n): Promise<void> {\n const res = await client.privatePost(\"/api/v5/trade/cancel-order\", { instId, ordId });\n if (json) return printJson(res.data);\n const r = (res.data as Record<string, unknown>[])[0];\n process.stdout.write(`Cancelled: ${r?.[\"ordId\"]} (${r?.[\"sCode\"] === \"0\" ? \"OK\" : r?.[\"sMsg\"]})\\n`);\n}\n\nexport async function cmdSpotAlgoPlace(\n client: OkxRestClient,\n opts: {\n instId: string;\n side: string;\n ordType: string;\n sz: string;\n tpTriggerPx?: string;\n tpOrdPx?: string;\n slTriggerPx?: string;\n slOrdPx?: string;\n json: boolean;\n },\n): Promise<void> {\n const body: Record<string, unknown> = {\n instId: opts.instId,\n tdMode: \"cash\",\n side: opts.side,\n ordType: opts.ordType,\n sz: opts.sz,\n };\n if (opts.tpTriggerPx) body[\"tpTriggerPx\"] = opts.tpTriggerPx;\n if (opts.tpOrdPx) body[\"tpOrdPx\"] = opts.tpOrdPx;\n if (opts.slTriggerPx) body[\"slTriggerPx\"] = opts.slTriggerPx;\n if (opts.slOrdPx) body[\"slOrdPx\"] = opts.slOrdPx;\n const res = await client.privatePost(\"/api/v5/trade/order-algo\", body);\n if (opts.json) return printJson(res.data);\n const order = (res.data as Record<string, unknown>[])[0];\n process.stdout.write(\n `Algo order placed: ${order?.[\"algoId\"]} (${order?.[\"sCode\"] === \"0\" ? \"OK\" : order?.[\"sMsg\"]})\\n`,\n );\n}\n\nexport async function cmdSpotAlgoAmend(\n client: OkxRestClient,\n opts: {\n instId: string;\n algoId: string;\n newSz?: string;\n newTpTriggerPx?: string;\n newTpOrdPx?: string;\n newSlTriggerPx?: string;\n newSlOrdPx?: string;\n json: boolean;\n },\n): Promise<void> {\n const body: Record<string, unknown> = {\n instId: opts.instId,\n algoId: opts.algoId,\n };\n if (opts.newSz) body[\"newSz\"] = opts.newSz;\n if (opts.newTpTriggerPx) body[\"newTpTriggerPx\"] = opts.newTpTriggerPx;\n if (opts.newTpOrdPx) body[\"newTpOrdPx\"] = opts.newTpOrdPx;\n if (opts.newSlTriggerPx) body[\"newSlTriggerPx\"] = opts.newSlTriggerPx;\n if (opts.newSlOrdPx) body[\"newSlOrdPx\"] = opts.newSlOrdPx;\n const res = await client.privatePost(\"/api/v5/trade/amend-algos\", body);\n if (opts.json) return printJson(res.data);\n const r = (res.data as Record<string, unknown>[])[0];\n process.stdout.write(\n `Algo order amended: ${r?.[\"algoId\"]} (${r?.[\"sCode\"] === \"0\" ? \"OK\" : r?.[\"sMsg\"]})\\n`,\n );\n}\n\nexport async function cmdSpotAlgoCancel(\n client: OkxRestClient,\n instId: string,\n algoId: string,\n json: boolean,\n): Promise<void> {\n const res = await client.privatePost(\"/api/v5/trade/cancel-algos\", [\n { algoId, instId },\n ]);\n if (json) return printJson(res.data);\n const r = (res.data as Record<string, unknown>[])[0];\n process.stdout.write(\n `Algo order cancelled: ${r?.[\"algoId\"]} (${r?.[\"sCode\"] === \"0\" ? \"OK\" : r?.[\"sMsg\"]})\\n`,\n );\n}\n\nexport async function cmdSpotAlgoOrders(\n client: OkxRestClient,\n opts: { instId?: string; status: \"pending\" | \"history\"; ordType?: string; json: boolean },\n): Promise<void> {\n const endpoint =\n opts.status === \"history\"\n ? \"/api/v5/trade/orders-algo-history\"\n : \"/api/v5/trade/orders-algo-pending\";\n const baseParams: Record<string, unknown> = { instType: \"SPOT\" };\n if (opts.instId) baseParams[\"instId\"] = opts.instId;\n\n let orders: Record<string, unknown>[];\n if (opts.ordType) {\n const res = await client.privateGet(endpoint, { ...baseParams, ordType: opts.ordType });\n orders = (res.data as Record<string, unknown>[]) ?? [];\n } else {\n const [r1, r2] = await Promise.all([\n client.privateGet(endpoint, { ...baseParams, ordType: \"conditional\" }),\n client.privateGet(endpoint, { ...baseParams, ordType: \"oco\" }),\n ]);\n orders = [\n ...((r1.data as Record<string, unknown>[]) ?? []),\n ...((r2.data as Record<string, unknown>[]) ?? []),\n ];\n }\n\n if (opts.json) return printJson(orders);\n if (!(orders ?? []).length) { process.stdout.write(\"No algo orders\\n\"); return; }\n printTable(\n orders.map((o) => ({\n algoId: o[\"algoId\"],\n instId: o[\"instId\"],\n type: o[\"ordType\"],\n side: o[\"side\"],\n sz: o[\"sz\"],\n tpTrigger: o[\"tpTriggerPx\"],\n slTrigger: o[\"slTriggerPx\"],\n state: o[\"state\"],\n })),\n );\n}\n\nexport async function cmdSpotFills(\n client: OkxRestClient,\n opts: { instId?: string; ordId?: string; json: boolean },\n): Promise<void> {\n const params: Record<string, unknown> = { instType: \"SPOT\" };\n if (opts.instId) params[\"instId\"] = opts.instId;\n if (opts.ordId) params[\"ordId\"] = opts.ordId;\n const res = await client.privateGet(\"/api/v5/trade/fills\", params);\n const fills = res.data as Record<string, unknown>[];\n if (opts.json) return printJson(fills);\n printTable(\n (fills ?? []).map((f) => ({\n instId: f[\"instId\"],\n side: f[\"side\"],\n fillPx: f[\"fillPx\"],\n fillSz: f[\"fillSz\"],\n fee: f[\"fee\"],\n ts: new Date(Number(f[\"ts\"])).toLocaleString(),\n })),\n );\n}\n","import type { OkxRestClient } from \"@okx-hub/core\";\nimport { printJson, printTable } from \"../formatter.js\";\n\nexport async function cmdSwapPositions(\n client: OkxRestClient,\n instId: string | undefined,\n json: boolean,\n): Promise<void> {\n const params: Record<string, unknown> = { instType: \"SWAP\" };\n if (instId) params[\"instId\"] = instId;\n const res = await client.privateGet(\"/api/v5/account/positions\", params);\n const positions = res.data as Record<string, unknown>[];\n if (json) return printJson(positions);\n const open = (positions ?? []).filter((p) => Number(p[\"pos\"]) !== 0);\n if (!open.length) { process.stdout.write(\"No open positions\\n\"); return; }\n printTable(\n open.map((p) => ({\n instId: p[\"instId\"],\n side: p[\"posSide\"],\n size: p[\"pos\"],\n avgPx: p[\"avgPx\"],\n upl: p[\"upl\"],\n uplRatio: p[\"uplRatio\"],\n lever: p[\"lever\"],\n })),\n );\n}\n\nexport async function cmdSwapOrders(\n client: OkxRestClient,\n opts: { instId?: string; status: \"open\" | \"history\"; json: boolean },\n): Promise<void> {\n const endpoint =\n opts.status === \"history\"\n ? \"/api/v5/trade/orders-history\"\n : \"/api/v5/trade/orders-pending\";\n const params: Record<string, unknown> = { instType: \"SWAP\" };\n if (opts.instId) params[\"instId\"] = opts.instId;\n const res = await client.privateGet(endpoint, params);\n const orders = res.data as Record<string, unknown>[];\n if (opts.json) return printJson(orders);\n printTable(\n (orders ?? []).map((o) => ({\n ordId: o[\"ordId\"],\n instId: o[\"instId\"],\n side: o[\"side\"],\n posSide: o[\"posSide\"],\n type: o[\"ordType\"],\n price: o[\"px\"],\n size: o[\"sz\"],\n state: o[\"state\"],\n })),\n );\n}\n\nexport async function cmdSwapPlace(\n client: OkxRestClient,\n opts: {\n instId: string;\n side: string;\n ordType: string;\n sz: string;\n posSide?: string;\n px?: string;\n tdMode: string;\n json: boolean;\n },\n): Promise<void> {\n const body: Record<string, unknown> = {\n instId: opts.instId,\n tdMode: opts.tdMode,\n side: opts.side,\n ordType: opts.ordType,\n sz: opts.sz,\n };\n if (opts.posSide) body[\"posSide\"] = opts.posSide;\n if (opts.px) body[\"px\"] = opts.px;\n const res = await client.privatePost(\"/api/v5/trade/order\", body);\n if (opts.json) return printJson(res.data);\n const order = (res.data as Record<string, unknown>[])[0];\n process.stdout.write(`Order placed: ${order?.[\"ordId\"]} (${order?.[\"sCode\"] === \"0\" ? \"OK\" : order?.[\"sMsg\"]})\\n`);\n}\n\nexport async function cmdSwapCancel(\n client: OkxRestClient,\n instId: string,\n ordId: string,\n json: boolean,\n): Promise<void> {\n const res = await client.privatePost(\"/api/v5/trade/cancel-order\", { instId, ordId });\n if (json) return printJson(res.data);\n const r = (res.data as Record<string, unknown>[])[0];\n process.stdout.write(`Cancelled: ${r?.[\"ordId\"]} (${r?.[\"sCode\"] === \"0\" ? \"OK\" : r?.[\"sMsg\"]})\\n`);\n}\n\nexport async function cmdSwapAlgoPlace(\n client: OkxRestClient,\n opts: {\n instId: string;\n side: string;\n ordType: string;\n sz: string;\n posSide?: string;\n tdMode: string;\n tpTriggerPx?: string;\n tpOrdPx?: string;\n slTriggerPx?: string;\n slOrdPx?: string;\n reduceOnly?: boolean;\n json: boolean;\n },\n): Promise<void> {\n const body: Record<string, unknown> = {\n instId: opts.instId,\n tdMode: opts.tdMode,\n side: opts.side,\n ordType: opts.ordType,\n sz: opts.sz,\n };\n if (opts.posSide) body[\"posSide\"] = opts.posSide;\n if (opts.tpTriggerPx) body[\"tpTriggerPx\"] = opts.tpTriggerPx;\n if (opts.tpOrdPx) body[\"tpOrdPx\"] = opts.tpOrdPx;\n if (opts.slTriggerPx) body[\"slTriggerPx\"] = opts.slTriggerPx;\n if (opts.slOrdPx) body[\"slOrdPx\"] = opts.slOrdPx;\n if (opts.reduceOnly !== undefined) body[\"reduceOnly\"] = String(opts.reduceOnly);\n const res = await client.privatePost(\"/api/v5/trade/order-algo\", body);\n if (opts.json) return printJson(res.data);\n const order = (res.data as Record<string, unknown>[])[0];\n process.stdout.write(\n `Algo order placed: ${order?.[\"algoId\"]} (${order?.[\"sCode\"] === \"0\" ? \"OK\" : order?.[\"sMsg\"]})\\n`,\n );\n}\n\nexport async function cmdSwapAlgoAmend(\n client: OkxRestClient,\n opts: {\n instId: string;\n algoId: string;\n newSz?: string;\n newTpTriggerPx?: string;\n newTpOrdPx?: string;\n newSlTriggerPx?: string;\n newSlOrdPx?: string;\n json: boolean;\n },\n): Promise<void> {\n const body: Record<string, unknown> = {\n instId: opts.instId,\n algoId: opts.algoId,\n };\n if (opts.newSz) body[\"newSz\"] = opts.newSz;\n if (opts.newTpTriggerPx) body[\"newTpTriggerPx\"] = opts.newTpTriggerPx;\n if (opts.newTpOrdPx) body[\"newTpOrdPx\"] = opts.newTpOrdPx;\n if (opts.newSlTriggerPx) body[\"newSlTriggerPx\"] = opts.newSlTriggerPx;\n if (opts.newSlOrdPx) body[\"newSlOrdPx\"] = opts.newSlOrdPx;\n const res = await client.privatePost(\"/api/v5/trade/amend-algos\", body);\n if (opts.json) return printJson(res.data);\n const r = (res.data as Record<string, unknown>[])[0];\n process.stdout.write(\n `Algo order amended: ${r?.[\"algoId\"]} (${r?.[\"sCode\"] === \"0\" ? \"OK\" : r?.[\"sMsg\"]})\\n`,\n );\n}\n\nexport async function cmdSwapAlgoCancel(\n client: OkxRestClient,\n instId: string,\n algoId: string,\n json: boolean,\n): Promise<void> {\n const res = await client.privatePost(\"/api/v5/trade/cancel-algos\", [\n { algoId, instId },\n ]);\n if (json) return printJson(res.data);\n const r = (res.data as Record<string, unknown>[])[0];\n process.stdout.write(\n `Algo order cancelled: ${r?.[\"algoId\"]} (${r?.[\"sCode\"] === \"0\" ? \"OK\" : r?.[\"sMsg\"]})\\n`,\n );\n}\n\nexport async function cmdSwapAlgoOrders(\n client: OkxRestClient,\n opts: { instId?: string; status: \"pending\" | \"history\"; ordType?: string; json: boolean },\n): Promise<void> {\n const endpoint =\n opts.status === \"history\"\n ? \"/api/v5/trade/orders-algo-history\"\n : \"/api/v5/trade/orders-algo-pending\";\n const baseParams: Record<string, unknown> = { instType: \"SWAP\" };\n if (opts.instId) baseParams[\"instId\"] = opts.instId;\n\n let orders: Record<string, unknown>[];\n if (opts.ordType) {\n const res = await client.privateGet(endpoint, { ...baseParams, ordType: opts.ordType });\n orders = (res.data as Record<string, unknown>[]) ?? [];\n } else {\n const [r1, r2] = await Promise.all([\n client.privateGet(endpoint, { ...baseParams, ordType: \"conditional\" }),\n client.privateGet(endpoint, { ...baseParams, ordType: \"oco\" }),\n ]);\n orders = [\n ...((r1.data as Record<string, unknown>[]) ?? []),\n ...((r2.data as Record<string, unknown>[]) ?? []),\n ];\n }\n\n if (opts.json) return printJson(orders);\n if (!(orders ?? []).length) { process.stdout.write(\"No algo orders\\n\"); return; }\n printTable(\n orders.map((o) => ({\n algoId: o[\"algoId\"],\n instId: o[\"instId\"],\n type: o[\"ordType\"],\n side: o[\"side\"],\n sz: o[\"sz\"],\n tpTrigger: o[\"tpTriggerPx\"],\n slTrigger: o[\"slTriggerPx\"],\n state: o[\"state\"],\n })),\n );\n}\n\nexport async function cmdSwapSetLeverage(\n client: OkxRestClient,\n opts: { instId: string; lever: string; mgnMode: string; posSide?: string; json: boolean },\n): Promise<void> {\n const body: Record<string, unknown> = {\n instId: opts.instId,\n lever: opts.lever,\n mgnMode: opts.mgnMode,\n };\n if (opts.posSide) body[\"posSide\"] = opts.posSide;\n const res = await client.privatePost(\"/api/v5/account/set-leverage\", body);\n if (opts.json) return printJson(res.data);\n const r = (res.data as Record<string, unknown>[])[0];\n process.stdout.write(`Leverage set: ${r?.[\"lever\"]}x ${r?.[\"instId\"]}\\n`);\n}\n","import { readTomlProfile, configFilePath } from \"@okx-hub/core\";\nimport { writeCliConfig } from \"../config/toml.js\";\nimport { printJson, printKv } from \"../formatter.js\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { parse } from \"smol-toml\";\nimport type { OkxTomlConfig } from \"@okx-hub/core\";\n\nfunction readFullConfig(): OkxTomlConfig {\n const path = configFilePath();\n if (!existsSync(path)) return { profiles: {} };\n const raw = readFileSync(path, \"utf-8\");\n return parse(raw) as unknown as OkxTomlConfig;\n}\n\nexport function cmdConfigShow(json: boolean): void {\n const config = readFullConfig();\n if (json) return printJson(config);\n process.stdout.write(`Config: ${configFilePath()}\\n\\n`);\n process.stdout.write(`default_profile: ${config.default_profile ?? \"(not set)\"}\\n\\n`);\n for (const [name, profile] of Object.entries(config.profiles)) {\n process.stdout.write(`[${name}]\\n`);\n printKv({\n api_key: profile.api_key ? \"***\" + profile.api_key.slice(-4) : \"(not set)\",\n demo: profile.demo ?? false,\n base_url: profile.base_url ?? \"(default)\",\n }, 2);\n process.stdout.write(\"\\n\");\n }\n}\n\nexport function cmdConfigSet(key: string, value: string): void {\n const config = readFullConfig();\n if (key === \"default_profile\") {\n config.default_profile = value;\n writeCliConfig(config);\n process.stdout.write(`default_profile set to \"${value}\"\\n`);\n } else {\n process.stderr.write(`Unknown config key: ${key}\\n`);\n process.exitCode = 1;\n }\n}\n","import { writeFileSync, mkdirSync, existsSync } from \"node:fs\";\nimport { stringify } from \"smol-toml\";\nimport { configFilePath } from \"@okx-hub/core\";\nimport type { OkxTomlConfig } from \"@okx-hub/core\";\n\n// Re-export for backward compat within CLI\nexport type { OkxTomlConfig as CliConfig };\nexport { configFilePath as configPath };\n\nexport function configDir(): string {\n return configFilePath().replace(/\\/config\\.toml$/, \"\");\n}\n\nexport function writeCliConfig(config: OkxTomlConfig): void {\n const dir = configDir();\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(configFilePath(), stringify(config as unknown as Record<string, unknown>), \"utf-8\");\n}\n"],"mappings":"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","names":["configFilePath","existsSync","configFilePath"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "okx-trade-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "OKX CLI - Command line tool for OKX exchange",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"bin": {
|
|
9
|
+
"okx": "dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=18"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"okx",
|
|
23
|
+
"cli",
|
|
24
|
+
"trading"
|
|
25
|
+
],
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"smol-toml": "^1.3.4",
|
|
28
|
+
"@okx-hub/core": "1.0.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^25.2.2",
|
|
32
|
+
"tsup": "^8.5.1",
|
|
33
|
+
"typescript": "^5.9.3"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsup",
|
|
37
|
+
"typecheck": "tsc --noEmit",
|
|
38
|
+
"clean": "rm -rf dist"
|
|
39
|
+
}
|
|
40
|
+
}
|