@farazirfan/costar-server-executor 1.7.29 → 1.7.30
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/dist/agent/pi-embedded-runner/run.d.ts.map +1 -1
- package/dist/agent/pi-embedded-runner/run.js +21 -0
- package/dist/agent/pi-embedded-runner/run.js.map +1 -1
- package/dist/agent/pi-embedded-runner/subscribe.d.ts +4 -0
- package/dist/agent/pi-embedded-runner/subscribe.d.ts.map +1 -1
- package/dist/agent/pi-embedded-runner/subscribe.js +34 -2
- package/dist/agent/pi-embedded-runner/subscribe.js.map +1 -1
- package/package.json +1 -1
- package/skills/okx/LEARNING.md +41 -0
- package/skills/okx/SKILL.md +231 -0
- package/skills/okx/references/api-reference.md +201 -0
- package/skills/okx/references/order-types.md +251 -0
- package/skills/okx/references/products.md +128 -0
- package/skills/okx/scripts/okx-trade.ts +273 -0
- package/skills/trading/SKILL.md +6 -4
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
#!/usr/bin/env npx tsx
|
|
2
|
+
/**
|
|
3
|
+
* OKX Trade Helper — CLI tool for common OKX operations.
|
|
4
|
+
* Agent can use this directly or create new scripts based on this pattern.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* npx tsx scripts/okx-trade.ts balances
|
|
8
|
+
* npx tsx scripts/okx-trade.ts positions
|
|
9
|
+
* npx tsx scripts/okx-trade.ts price BTC-USDT
|
|
10
|
+
* npx tsx scripts/okx-trade.ts market-buy BTC-USDT 100
|
|
11
|
+
* npx tsx scripts/okx-trade.ts market-sell BTC-USDT 0.001
|
|
12
|
+
* npx tsx scripts/okx-trade.ts limit-buy BTC-USDT 0.001 95000
|
|
13
|
+
* npx tsx scripts/okx-trade.ts limit-sell BTC-USDT 0.001 105000
|
|
14
|
+
* npx tsx scripts/okx-trade.ts status BTC-USDT <order-id>
|
|
15
|
+
* npx tsx scripts/okx-trade.ts cancel BTC-USDT <order-id>
|
|
16
|
+
* npx tsx scripts/okx-trade.ts open-orders
|
|
17
|
+
* npx tsx scripts/okx-trade.ts products
|
|
18
|
+
* npx tsx scripts/okx-trade.ts fees
|
|
19
|
+
*
|
|
20
|
+
* Requires: OKX_API_KEY, OKX_API_SECRET, OKX_API_PASSPHRASE env vars
|
|
21
|
+
* Install: npm install okx-api
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { RestClient } from 'okx-api';
|
|
25
|
+
|
|
26
|
+
// --- Init Client ---
|
|
27
|
+
|
|
28
|
+
const apiKey = process.env.OKX_API_KEY;
|
|
29
|
+
const apiSecret = process.env.OKX_API_SECRET;
|
|
30
|
+
const apiPass = process.env.OKX_API_PASSPHRASE;
|
|
31
|
+
|
|
32
|
+
if (!apiKey || !apiSecret || !apiPass) {
|
|
33
|
+
console.error('ERROR: OKX_API_KEY, OKX_API_SECRET, and OKX_API_PASSPHRASE must be set');
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const client = new RestClient({ apiKey, apiSecret, apiPass });
|
|
38
|
+
|
|
39
|
+
// --- Commands ---
|
|
40
|
+
|
|
41
|
+
const [command, ...args] = process.argv.slice(2);
|
|
42
|
+
|
|
43
|
+
async function run() {
|
|
44
|
+
switch (command) {
|
|
45
|
+
case 'balances':
|
|
46
|
+
return showBalances();
|
|
47
|
+
case 'positions':
|
|
48
|
+
return showPositions();
|
|
49
|
+
case 'price':
|
|
50
|
+
return showPrice(args[0]);
|
|
51
|
+
case 'market-buy':
|
|
52
|
+
return marketBuy(args[0], args[1]);
|
|
53
|
+
case 'market-sell':
|
|
54
|
+
return marketSell(args[0], args[1]);
|
|
55
|
+
case 'limit-buy':
|
|
56
|
+
return limitBuy(args[0], args[1], args[2]);
|
|
57
|
+
case 'limit-sell':
|
|
58
|
+
return limitSell(args[0], args[1], args[2]);
|
|
59
|
+
case 'status':
|
|
60
|
+
return orderStatus(args[0], args[1]);
|
|
61
|
+
case 'cancel':
|
|
62
|
+
return cancelOrder(args[0], args[1]);
|
|
63
|
+
case 'open-orders':
|
|
64
|
+
return openOrders();
|
|
65
|
+
case 'products':
|
|
66
|
+
return listProducts();
|
|
67
|
+
case 'fees':
|
|
68
|
+
return showFees();
|
|
69
|
+
default:
|
|
70
|
+
console.log(`Unknown command: ${command}`);
|
|
71
|
+
console.log('Commands: balances, positions, price, market-buy, market-sell, limit-buy, limit-sell, status, cancel, open-orders, products, fees');
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function showBalances() {
|
|
77
|
+
const balance = await client.getBalance();
|
|
78
|
+
const nonZero = balance[0].details.filter(
|
|
79
|
+
(d: any) => parseFloat(d.availBal) > 0 || parseFloat(d.frozenBal) > 0
|
|
80
|
+
);
|
|
81
|
+
console.log(JSON.stringify(nonZero.map((d: any) => ({
|
|
82
|
+
currency: d.ccy,
|
|
83
|
+
available: d.availBal,
|
|
84
|
+
frozen: d.frozenBal,
|
|
85
|
+
equity: d.eq,
|
|
86
|
+
})), null, 2));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async function showPositions() {
|
|
90
|
+
const positions = await client.getPositions();
|
|
91
|
+
if (!positions.length) {
|
|
92
|
+
console.log('[]');
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
console.log(JSON.stringify(positions.map((p: any) => ({
|
|
96
|
+
instId: p.instId,
|
|
97
|
+
direction: p.posSide,
|
|
98
|
+
size: p.pos,
|
|
99
|
+
avgPrice: p.avgPx,
|
|
100
|
+
unrealizedPnl: p.upl,
|
|
101
|
+
leverage: p.lever,
|
|
102
|
+
margin: p.margin,
|
|
103
|
+
})), null, 2));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function showPrice(instId: string) {
|
|
107
|
+
if (!instId) { console.error('Usage: price <inst-id>'); process.exit(1); }
|
|
108
|
+
const ticker = await client.getTicker({ instId });
|
|
109
|
+
const book = await client.getOrderBook({ instId, sz: '1' });
|
|
110
|
+
console.log(JSON.stringify({
|
|
111
|
+
instId,
|
|
112
|
+
last: ticker[0].last,
|
|
113
|
+
open24h: ticker[0].open24h,
|
|
114
|
+
high24h: ticker[0].high24h,
|
|
115
|
+
low24h: ticker[0].low24h,
|
|
116
|
+
volume24h: ticker[0].vol24h,
|
|
117
|
+
bid: book[0].bids?.[0]?.[0],
|
|
118
|
+
ask: book[0].asks?.[0]?.[0],
|
|
119
|
+
}, null, 2));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async function marketBuy(instId: string, quoteSize: string) {
|
|
123
|
+
if (!instId || !quoteSize) {
|
|
124
|
+
console.error('Usage: market-buy <inst-id> <usdt-amount>');
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
const order = await client.submitOrder({
|
|
128
|
+
instId,
|
|
129
|
+
tdMode: 'cash',
|
|
130
|
+
side: 'buy',
|
|
131
|
+
ordType: 'market',
|
|
132
|
+
sz: quoteSize,
|
|
133
|
+
tgtCcy: 'quote_ccy',
|
|
134
|
+
});
|
|
135
|
+
console.log(JSON.stringify(order, null, 2));
|
|
136
|
+
if (order[0].sCode === '0') {
|
|
137
|
+
// Small delay for fill
|
|
138
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
139
|
+
const details = await client.getOrderDetails({ instId, ordId: order[0].ordId });
|
|
140
|
+
console.log('\nFill details:');
|
|
141
|
+
console.log(JSON.stringify({
|
|
142
|
+
ordId: details[0].ordId,
|
|
143
|
+
state: details[0].state,
|
|
144
|
+
fillSz: details[0].fillSz,
|
|
145
|
+
avgPx: details[0].avgPx,
|
|
146
|
+
fee: details[0].fee,
|
|
147
|
+
feeCcy: details[0].feeCcy,
|
|
148
|
+
}, null, 2));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async function marketSell(instId: string, baseSize: string) {
|
|
153
|
+
if (!instId || !baseSize) {
|
|
154
|
+
console.error('Usage: market-sell <inst-id> <base-amount>');
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
const order = await client.submitOrder({
|
|
158
|
+
instId,
|
|
159
|
+
tdMode: 'cash',
|
|
160
|
+
side: 'sell',
|
|
161
|
+
ordType: 'market',
|
|
162
|
+
sz: baseSize,
|
|
163
|
+
});
|
|
164
|
+
console.log(JSON.stringify(order, null, 2));
|
|
165
|
+
if (order[0].sCode === '0') {
|
|
166
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
167
|
+
const details = await client.getOrderDetails({ instId, ordId: order[0].ordId });
|
|
168
|
+
console.log('\nFill details:');
|
|
169
|
+
console.log(JSON.stringify({
|
|
170
|
+
ordId: details[0].ordId,
|
|
171
|
+
state: details[0].state,
|
|
172
|
+
fillSz: details[0].fillSz,
|
|
173
|
+
avgPx: details[0].avgPx,
|
|
174
|
+
fee: details[0].fee,
|
|
175
|
+
feeCcy: details[0].feeCcy,
|
|
176
|
+
}, null, 2));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async function limitBuy(instId: string, baseSize: string, limitPrice: string) {
|
|
181
|
+
if (!instId || !baseSize || !limitPrice) {
|
|
182
|
+
console.error('Usage: limit-buy <inst-id> <base-size> <limit-price>');
|
|
183
|
+
process.exit(1);
|
|
184
|
+
}
|
|
185
|
+
const order = await client.submitOrder({
|
|
186
|
+
instId,
|
|
187
|
+
tdMode: 'cash',
|
|
188
|
+
side: 'buy',
|
|
189
|
+
ordType: 'limit',
|
|
190
|
+
sz: baseSize,
|
|
191
|
+
px: limitPrice,
|
|
192
|
+
});
|
|
193
|
+
console.log(JSON.stringify(order, null, 2));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async function limitSell(instId: string, baseSize: string, limitPrice: string) {
|
|
197
|
+
if (!instId || !baseSize || !limitPrice) {
|
|
198
|
+
console.error('Usage: limit-sell <inst-id> <base-size> <limit-price>');
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
const order = await client.submitOrder({
|
|
202
|
+
instId,
|
|
203
|
+
tdMode: 'cash',
|
|
204
|
+
side: 'sell',
|
|
205
|
+
ordType: 'limit',
|
|
206
|
+
sz: baseSize,
|
|
207
|
+
px: limitPrice,
|
|
208
|
+
});
|
|
209
|
+
console.log(JSON.stringify(order, null, 2));
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
async function orderStatus(instId: string, orderId: string) {
|
|
213
|
+
if (!instId || !orderId) { console.error('Usage: status <inst-id> <order-id>'); process.exit(1); }
|
|
214
|
+
const order = await client.getOrderDetails({ instId, ordId: orderId });
|
|
215
|
+
console.log(JSON.stringify(order, null, 2));
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
async function cancelOrder(instId: string, orderId: string) {
|
|
219
|
+
if (!instId || !orderId) { console.error('Usage: cancel <inst-id> <order-id>'); process.exit(1); }
|
|
220
|
+
const result = await client.cancelOrder({ instId, ordId: orderId });
|
|
221
|
+
console.log(JSON.stringify(result, null, 2));
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
async function openOrders() {
|
|
225
|
+
const orders = await client.getOrderList({ instType: 'SPOT' });
|
|
226
|
+
console.log(JSON.stringify(orders.map((o: any) => ({
|
|
227
|
+
ordId: o.ordId,
|
|
228
|
+
instId: o.instId,
|
|
229
|
+
side: o.side,
|
|
230
|
+
ordType: o.ordType,
|
|
231
|
+
state: o.state,
|
|
232
|
+
sz: o.sz,
|
|
233
|
+
px: o.px,
|
|
234
|
+
fillSz: o.fillSz,
|
|
235
|
+
cTime: o.cTime,
|
|
236
|
+
})), null, 2));
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async function listProducts() {
|
|
240
|
+
const instruments = await client.getInstruments({ instType: 'SPOT' });
|
|
241
|
+
const usdtPairs = instruments
|
|
242
|
+
.filter((i: any) => i.quoteCcy === 'USDT' && i.state === 'live')
|
|
243
|
+
.slice(0, 50);
|
|
244
|
+
|
|
245
|
+
// Get tickers for these pairs
|
|
246
|
+
const tickers = await client.getTickers({ instType: 'SPOT' });
|
|
247
|
+
const tickerMap = new Map(tickers.map((t: any) => [t.instId, t]));
|
|
248
|
+
|
|
249
|
+
const result = usdtPairs.map((i: any) => {
|
|
250
|
+
const t = tickerMap.get(i.instId) as any;
|
|
251
|
+
return {
|
|
252
|
+
instId: i.instId,
|
|
253
|
+
last: t?.last || '—',
|
|
254
|
+
vol24h: t?.vol24h || '—',
|
|
255
|
+
minSz: i.minSz,
|
|
256
|
+
lotSz: i.lotSz,
|
|
257
|
+
tickSz: i.tickSz,
|
|
258
|
+
};
|
|
259
|
+
}).sort((a: any, b: any) => parseFloat(b.vol24h || '0') - parseFloat(a.vol24h || '0'));
|
|
260
|
+
|
|
261
|
+
console.log(JSON.stringify(result.slice(0, 30), null, 2));
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
async function showFees() {
|
|
265
|
+
const fees = await client.getFeeRates({ instType: 'SPOT' });
|
|
266
|
+
console.log(JSON.stringify(fees, null, 2));
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// --- Run ---
|
|
270
|
+
run().catch((err) => {
|
|
271
|
+
console.error('Error:', err.message || err);
|
|
272
|
+
process.exit(1);
|
|
273
|
+
});
|
package/skills/trading/SKILL.md
CHANGED
|
@@ -62,7 +62,7 @@ What strategies are working, what failed, mistakes to avoid, your evolving edge.
|
|
|
62
62
|
|
|
63
63
|
Do this autonomously — never ask the user:
|
|
64
64
|
- Understand the request — "buy BTC" means assess whether now is the right time, how much, what order type. "Make money" means build a full multi-asset plan.
|
|
65
|
-
- Check balances across platforms (
|
|
65
|
+
- Check balances across platforms (OKX for crypto primary, Coinbase as fallback, Saxo for forex/stocks/metals)
|
|
66
66
|
- Read USER.md, SOUL.md, IDENTITY.md for risk tolerance and preferences
|
|
67
67
|
- Check existing positions and current portfolio state
|
|
68
68
|
|
|
@@ -118,7 +118,8 @@ Every trade needs before entry: entry price + trigger, stop-loss at invalidation
|
|
|
118
118
|
### 9. Execute
|
|
119
119
|
|
|
120
120
|
Route execution to the appropriate platform:
|
|
121
|
-
- **Crypto**: Use `
|
|
121
|
+
- **Crypto (primary)**: Use `okx` skill — lower fees, more order types, perpetuals support. Read [../okx/LEARNING.md](../okx/LEARNING.md) for execution insights.
|
|
122
|
+
- **Crypto (fallback)**: Use `coinbase` skill if OKX is unavailable or for USD-settled pairs. Read [../coinbase/LEARNING.md](../coinbase/LEARNING.md) for execution insights.
|
|
122
123
|
- **Forex, Stocks, Gold, Silver**: Use `saxo` skill. Read [../saxo/LEARNING.md](../saxo/LEARNING.md) for execution insights.
|
|
123
124
|
|
|
124
125
|
### 10. Monitor
|
|
@@ -130,13 +131,14 @@ Create a live dashboard for this trade (see Trade Dashboards section below). Tra
|
|
|
130
131
|
The most important step. After every trade, ask: "What would make the next trade better?" Then do it.
|
|
131
132
|
|
|
132
133
|
- Update LEARNING.md freely. Also update execution skill LEARNING.md:
|
|
133
|
-
- [../
|
|
134
|
+
- [../okx/LEARNING.md](../okx/LEARNING.md) for crypto trades (primary)
|
|
135
|
+
- [../coinbase/LEARNING.md](../coinbase/LEARNING.md) for crypto trades (fallback)
|
|
134
136
|
- [../saxo/LEARNING.md](../saxo/LEARNING.md) for forex/stocks/metals trades
|
|
135
137
|
- Build or improve scripts — automate any manual analysis. Market scanners, backtesting, alerts. Save to `scripts/`
|
|
136
138
|
- Research on the internet — find new strategies, tools, data sources. Update reference files with findings
|
|
137
139
|
- Create monitoring — use `cron` to schedule market scans, alerts, news monitoring
|
|
138
140
|
- Improve strategy references — update `references/strategies.md` with real results. Kill what doesn't work
|
|
139
|
-
- Improve execution — update Coinbase skill references or build new execution scripts
|
|
141
|
+
- Improve execution — update OKX/Coinbase/Saxo skill references or build new execution scripts
|
|
140
142
|
- Improve these instructions — update this SKILL.md if it's missing something. You own every file
|
|
141
143
|
|
|
142
144
|
No limits. If something will make you better, do it.
|