openbroker 1.0.54 → 1.0.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/SKILL.md +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/scripts/core/client.ts +35 -16
- package/scripts/operations/bracket.ts +4 -2
- package/scripts/operations/chase.ts +3 -1
- package/scripts/operations/limit-order.ts +4 -1
- package/scripts/operations/market-order.ts +4 -1
- package/scripts/operations/scale.ts +4 -1
- package/scripts/operations/trigger-order.ts +4 -1
- package/scripts/operations/twap.ts +3 -1
- package/scripts/plugin/tools.ts +17 -6
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Open Broker will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.0.55] - 2026-03-09
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Leverage Control**: All trading commands now support `--leverage` flag to set leverage when opening positions
|
|
9
|
+
- Main perps: sets cross margin leverage before ordering
|
|
10
|
+
- HIP-3 perps: sets isolated margin at specified leverage (capped at asset's max)
|
|
11
|
+
- CLI: `--leverage 10` on `market`, `limit`, `trigger`, `bracket`, `chase`, `twap`, `scale`
|
|
12
|
+
- Plugin: `leverage` parameter on `ob_buy`, `ob_sell`, `ob_limit`, `ob_twap`, `ob_bracket`, `ob_chase`
|
|
13
|
+
|
|
5
14
|
## [1.0.54] - 2026-03-09
|
|
6
15
|
|
|
7
16
|
### Fixed
|
package/SKILL.md
CHANGED
|
@@ -4,7 +4,7 @@ description: Hyperliquid trading plugin with background position monitoring. Exe
|
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: Requires Node.js 22+, network access to api.hyperliquid.xyz
|
|
6
6
|
homepage: https://www.npmjs.com/package/openbroker
|
|
7
|
-
metadata: {"author": "monemetrics", "version": "1.0.
|
|
7
|
+
metadata: {"author": "monemetrics", "version": "1.0.55", "openclaw": {"requires": {"bins": ["openbroker"], "env": ["HYPERLIQUID_PRIVATE_KEY"]}, "primaryEnv": "HYPERLIQUID_PRIVATE_KEY", "install": [{"id": "node", "kind": "node", "package": "openbroker", "bins": ["openbroker"], "label": "Install openbroker (npm)"}]}}
|
|
8
8
|
allowed-tools: ob_account ob_positions ob_funding ob_markets ob_search ob_spot ob_fills ob_orders ob_order_status ob_fees ob_candles ob_funding_history ob_trades ob_rate_limit ob_funding_scan ob_buy ob_sell ob_limit ob_trigger ob_tpsl ob_cancel ob_twap ob_bracket ob_chase ob_watcher_status Bash(openbroker:*)
|
|
9
9
|
---
|
|
10
10
|
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
package/scripts/core/client.ts
CHANGED
|
@@ -1127,18 +1127,20 @@ export class HyperliquidClient {
|
|
|
1127
1127
|
* 1. Set isolated margin mode (required for HIP-3)
|
|
1128
1128
|
* 2. Transfer USDC from main perp to the HIP-3 dex (each dex has its own balance)
|
|
1129
1129
|
*/
|
|
1130
|
-
private async ensureHip3Ready(coin: string, notional: number): Promise<void> {
|
|
1130
|
+
private async ensureHip3Ready(coin: string, notional: number, leverage?: number): Promise<void> {
|
|
1131
1131
|
if (!this.isHip3(coin)) return;
|
|
1132
1132
|
|
|
1133
1133
|
const dexInfo = this.coinDexMap.get(coin);
|
|
1134
1134
|
if (!dexInfo?.dexName) return;
|
|
1135
1135
|
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1136
|
+
const maxLev = this.hip3MaxLeverageMap.get(coin) ?? 10;
|
|
1137
|
+
const effectiveLev = Math.min(leverage ?? maxLev, maxLev);
|
|
1138
|
+
|
|
1139
|
+
// Set isolated margin on first order per asset, or when leverage changes
|
|
1140
|
+
if (!this.hip3IsolatedSet.has(coin) || leverage) {
|
|
1141
|
+
this.log(`HIP-3 asset ${coin} (dex: ${dexInfo.dexName}) — setting isolated margin at ${effectiveLev}x`);
|
|
1140
1142
|
try {
|
|
1141
|
-
await this.updateLeverage(coin,
|
|
1143
|
+
await this.updateLeverage(coin, effectiveLev, false); // false = isolated
|
|
1142
1144
|
this.hip3IsolatedSet.add(coin);
|
|
1143
1145
|
} catch (err) {
|
|
1144
1146
|
this.log(`Failed to set isolated margin for ${coin}:`, err instanceof Error ? err.message : String(err));
|
|
@@ -1147,8 +1149,7 @@ export class HyperliquidClient {
|
|
|
1147
1149
|
}
|
|
1148
1150
|
|
|
1149
1151
|
// Transfer USDC to the HIP-3 dex to cover margin
|
|
1150
|
-
const
|
|
1151
|
-
const requiredMargin = notional / maxLev;
|
|
1152
|
+
const requiredMargin = notional / effectiveLev;
|
|
1152
1153
|
// Add 20% buffer for fees and slippage
|
|
1153
1154
|
const transferAmount = Math.ceil(requiredMargin * 1.2 * 100) / 100;
|
|
1154
1155
|
|
|
@@ -1175,13 +1176,20 @@ export class HyperliquidClient {
|
|
|
1175
1176
|
price: number,
|
|
1176
1177
|
orderType: { limit: { tif: 'Gtc' | 'Ioc' | 'Alo' } },
|
|
1177
1178
|
reduceOnly: boolean = false,
|
|
1178
|
-
includeBuilder: boolean = true
|
|
1179
|
+
includeBuilder: boolean = true,
|
|
1180
|
+
leverage?: number
|
|
1179
1181
|
): Promise<OrderResponse> {
|
|
1180
1182
|
this.requireTrading();
|
|
1181
1183
|
await this.getMetaAndAssetCtxs();
|
|
1182
1184
|
|
|
1185
|
+
// Set leverage if specified (for main perps, cross margin; for HIP-3, handled in ensureHip3Ready)
|
|
1186
|
+
if (leverage && !this.isHip3(coin)) {
|
|
1187
|
+
this.log(`Setting leverage for ${coin} to ${leverage}x cross`);
|
|
1188
|
+
await this.updateLeverage(coin, leverage, true);
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1183
1191
|
// HIP-3 perps: set isolated margin + transfer USDC to dex
|
|
1184
|
-
await this.ensureHip3Ready(coin, size * price);
|
|
1192
|
+
await this.ensureHip3Ready(coin, size * price, leverage);
|
|
1185
1193
|
|
|
1186
1194
|
const assetIndex = this.getAssetIndex(coin);
|
|
1187
1195
|
const szDecimals = this.getSzDecimals(coin);
|
|
@@ -1230,7 +1238,8 @@ export class HyperliquidClient {
|
|
|
1230
1238
|
coin: string,
|
|
1231
1239
|
isBuy: boolean,
|
|
1232
1240
|
size: number,
|
|
1233
|
-
slippageBps?: number
|
|
1241
|
+
slippageBps?: number,
|
|
1242
|
+
leverage?: number
|
|
1234
1243
|
): Promise<OrderResponse> {
|
|
1235
1244
|
await this.getMetaAndAssetCtxs();
|
|
1236
1245
|
|
|
@@ -1256,7 +1265,8 @@ export class HyperliquidClient {
|
|
|
1256
1265
|
limitPrice,
|
|
1257
1266
|
{ limit: { tif: 'Ioc' } },
|
|
1258
1267
|
false,
|
|
1259
|
-
true
|
|
1268
|
+
true,
|
|
1269
|
+
leverage
|
|
1260
1270
|
);
|
|
1261
1271
|
}
|
|
1262
1272
|
|
|
@@ -1266,7 +1276,8 @@ export class HyperliquidClient {
|
|
|
1266
1276
|
size: number,
|
|
1267
1277
|
price: number,
|
|
1268
1278
|
tif: 'Gtc' | 'Ioc' | 'Alo' = 'Gtc',
|
|
1269
|
-
reduceOnly: boolean = false
|
|
1279
|
+
reduceOnly: boolean = false,
|
|
1280
|
+
leverage?: number
|
|
1270
1281
|
): Promise<OrderResponse> {
|
|
1271
1282
|
return this.order(
|
|
1272
1283
|
coin,
|
|
@@ -1275,7 +1286,8 @@ export class HyperliquidClient {
|
|
|
1275
1286
|
price,
|
|
1276
1287
|
{ limit: { tif } },
|
|
1277
1288
|
reduceOnly,
|
|
1278
|
-
true
|
|
1289
|
+
true,
|
|
1290
|
+
leverage
|
|
1279
1291
|
);
|
|
1280
1292
|
}
|
|
1281
1293
|
|
|
@@ -1296,13 +1308,20 @@ export class HyperliquidClient {
|
|
|
1296
1308
|
triggerPrice: number,
|
|
1297
1309
|
limitPrice: number,
|
|
1298
1310
|
tpsl: 'tp' | 'sl',
|
|
1299
|
-
reduceOnly: boolean = true
|
|
1311
|
+
reduceOnly: boolean = true,
|
|
1312
|
+
leverage?: number
|
|
1300
1313
|
): Promise<OrderResponse> {
|
|
1301
1314
|
this.requireTrading();
|
|
1302
1315
|
await this.getMetaAndAssetCtxs();
|
|
1303
1316
|
|
|
1317
|
+
// Set leverage if specified (for main perps)
|
|
1318
|
+
if (leverage && !this.isHip3(coin)) {
|
|
1319
|
+
this.log(`Setting leverage for ${coin} to ${leverage}x cross`);
|
|
1320
|
+
await this.updateLeverage(coin, leverage, true);
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1304
1323
|
// HIP-3 perps: set isolated margin + transfer USDC to dex
|
|
1305
|
-
await this.ensureHip3Ready(coin, size * limitPrice);
|
|
1324
|
+
await this.ensureHip3Ready(coin, size * limitPrice, leverage);
|
|
1306
1325
|
|
|
1307
1326
|
const assetIndex = this.getAssetIndex(coin);
|
|
1308
1327
|
const szDecimals = this.getSzDecimals(coin);
|
|
@@ -24,6 +24,7 @@ Options:
|
|
|
24
24
|
--tp Take profit distance in % from entry
|
|
25
25
|
--sl Stop loss distance in % from entry
|
|
26
26
|
--slippage Slippage for market entry in bps (default: 50)
|
|
27
|
+
--leverage Set leverage (e.g., 10 for 10x). Cross for main perps, isolated for HIP-3
|
|
27
28
|
--dry Dry run - show bracket plan without executing
|
|
28
29
|
|
|
29
30
|
Take Profit / Stop Loss:
|
|
@@ -66,6 +67,7 @@ async function main() {
|
|
|
66
67
|
const tpPct = parseFloat(args.tp as string);
|
|
67
68
|
const slPct = parseFloat(args.sl as string);
|
|
68
69
|
const slippage = args.slippage ? parseInt(args.slippage as string) : undefined;
|
|
70
|
+
const leverage = args.leverage ? parseInt(args.leverage as string) : undefined;
|
|
69
71
|
const dryRun = args.dry as boolean;
|
|
70
72
|
|
|
71
73
|
if (!coin || !side || isNaN(size) || isNaN(tpPct) || isNaN(slPct)) {
|
|
@@ -171,7 +173,7 @@ async function main() {
|
|
|
171
173
|
let actualEntry = entry;
|
|
172
174
|
|
|
173
175
|
if (entryType === 'market') {
|
|
174
|
-
const entryResponse = await client.marketOrder(coin, isLong, size, slippage);
|
|
176
|
+
const entryResponse = await client.marketOrder(coin, isLong, size, slippage, leverage);
|
|
175
177
|
|
|
176
178
|
if (entryResponse.status === 'ok' && entryResponse.response && typeof entryResponse.response === 'object') {
|
|
177
179
|
const status = entryResponse.response.data.statuses[0];
|
|
@@ -189,7 +191,7 @@ async function main() {
|
|
|
189
191
|
process.exit(1);
|
|
190
192
|
}
|
|
191
193
|
} else {
|
|
192
|
-
const entryResponse = await client.limitOrder(coin, isLong, size, entry, 'Gtc', false);
|
|
194
|
+
const entryResponse = await client.limitOrder(coin, isLong, size, entry, 'Gtc', false, leverage);
|
|
193
195
|
|
|
194
196
|
if (entryResponse.status === 'ok' && entryResponse.response && typeof entryResponse.response === 'object') {
|
|
195
197
|
const status = entryResponse.response.data.statuses[0];
|
|
@@ -23,6 +23,7 @@ Options:
|
|
|
23
23
|
--timeout Max time to chase in seconds (default: 300 = 5 min)
|
|
24
24
|
--interval Update interval in ms (default: 2000)
|
|
25
25
|
--max-chase Max price to chase to in bps from start (default: 100 = 1%)
|
|
26
|
+
--leverage Set leverage (e.g., 10 for 10x). Cross for main perps, isolated for HIP-3
|
|
26
27
|
--reduce Reduce-only order
|
|
27
28
|
--dry Dry run - show chase parameters without executing
|
|
28
29
|
|
|
@@ -54,6 +55,7 @@ async function main() {
|
|
|
54
55
|
const timeoutSec = args.timeout ? parseInt(args.timeout as string) : 300;
|
|
55
56
|
const intervalMs = args.interval ? parseInt(args.interval as string) : 2000;
|
|
56
57
|
const maxChaseBps = args['max-chase'] ? parseInt(args['max-chase'] as string) : 100;
|
|
58
|
+
const leverage = args.leverage ? parseInt(args.leverage as string) : undefined;
|
|
57
59
|
const reduceOnly = args.reduce as boolean;
|
|
58
60
|
const dryRun = args.dry as boolean;
|
|
59
61
|
|
|
@@ -168,7 +170,7 @@ async function main() {
|
|
|
168
170
|
// Place new order
|
|
169
171
|
process.stdout.write(`[${iteration}] Mid: ${formatUsd(currentMid)} → Order: ${formatUsd(orderPrice)}... `);
|
|
170
172
|
|
|
171
|
-
const response = await client.limitOrder(coin, isBuy, size, orderPrice, 'Alo', reduceOnly);
|
|
173
|
+
const response = await client.limitOrder(coin, isBuy, size, orderPrice, 'Alo', reduceOnly, leverage);
|
|
172
174
|
|
|
173
175
|
if (response.status === 'ok' && response.response && typeof response.response === 'object') {
|
|
174
176
|
const status = response.response.data.statuses[0];
|
|
@@ -23,6 +23,7 @@ Options:
|
|
|
23
23
|
GTC = Good Till Cancel (rests on book)
|
|
24
24
|
IOC = Immediate Or Cancel (fills or cancels)
|
|
25
25
|
ALO = Add Liquidity Only (post-only, maker only)
|
|
26
|
+
--leverage Set leverage (e.g., 10 for 10x). Cross for main perps, isolated for HIP-3
|
|
26
27
|
--reduce Reduce-only order (default: false)
|
|
27
28
|
--dry Dry run - show order details without executing
|
|
28
29
|
|
|
@@ -42,6 +43,7 @@ async function main() {
|
|
|
42
43
|
const size = parseFloat(args.size as string);
|
|
43
44
|
const price = parseFloat(args.price as string);
|
|
44
45
|
const tifArg = (args.tif as string)?.toUpperCase() || 'GTC';
|
|
46
|
+
const leverage = args.leverage ? parseInt(args.leverage as string) : undefined;
|
|
45
47
|
const reduceOnly = args.reduce as boolean;
|
|
46
48
|
const dryRun = args.dry as boolean;
|
|
47
49
|
|
|
@@ -107,6 +109,7 @@ async function main() {
|
|
|
107
109
|
console.log(`Notional: ${formatUsd(notional)}`);
|
|
108
110
|
console.log(`Time in Force: ${tif}`);
|
|
109
111
|
console.log(`Reduce Only: ${reduceOnly ? 'Yes' : 'No'}`);
|
|
112
|
+
if (leverage) console.log(`Leverage: ${leverage}x`);
|
|
110
113
|
console.log(`Builder Fee: ${client.builderInfo.f / 10} bps`);
|
|
111
114
|
|
|
112
115
|
// Warning if order would be aggressively priced
|
|
@@ -121,7 +124,7 @@ async function main() {
|
|
|
121
124
|
|
|
122
125
|
console.log('\nSubmitting...');
|
|
123
126
|
|
|
124
|
-
const response = await client.limitOrder(coin, isBuy, size, price, tif, reduceOnly);
|
|
127
|
+
const response = await client.limitOrder(coin, isBuy, size, price, tif, reduceOnly, leverage);
|
|
125
128
|
|
|
126
129
|
console.log('\nResult');
|
|
127
130
|
console.log('------');
|
|
@@ -19,6 +19,7 @@ Options:
|
|
|
19
19
|
--side Order side: buy or sell
|
|
20
20
|
--size Order size in base asset
|
|
21
21
|
--slippage Slippage tolerance in bps (default: from config, usually 50 = 0.5%)
|
|
22
|
+
--leverage Set leverage (e.g., 10 for 10x). Cross for main perps, isolated for HIP-3
|
|
22
23
|
--reduce Reduce-only order (default: false)
|
|
23
24
|
--dry Dry run - show order details without executing
|
|
24
25
|
--verbose Show full API request/response for debugging
|
|
@@ -44,6 +45,7 @@ async function main() {
|
|
|
44
45
|
const side = args.side as string;
|
|
45
46
|
const size = parseFloat(args.size as string);
|
|
46
47
|
const slippage = args.slippage ? parseInt(args.slippage as string) : undefined;
|
|
48
|
+
const leverage = args.leverage ? parseInt(args.leverage as string) : undefined;
|
|
47
49
|
const reduceOnly = args.reduce as boolean;
|
|
48
50
|
const dryRun = args.dry as boolean;
|
|
49
51
|
|
|
@@ -103,6 +105,7 @@ async function main() {
|
|
|
103
105
|
console.log(`Limit Price: ${formatUsd(limitPrice)} (${slippageBps} bps slippage)`);
|
|
104
106
|
console.log(`Notional: ~${formatUsd(notional)}`);
|
|
105
107
|
console.log(`Reduce Only: ${reduceOnly ? 'Yes' : 'No'}`);
|
|
108
|
+
if (leverage) console.log(`Leverage: ${leverage}x`);
|
|
106
109
|
console.log(`Builder Fee: ${client.builderInfo.f / 10} bps`);
|
|
107
110
|
|
|
108
111
|
if (dryRun) {
|
|
@@ -112,7 +115,7 @@ async function main() {
|
|
|
112
115
|
|
|
113
116
|
console.log('\nExecuting...');
|
|
114
117
|
|
|
115
|
-
const response = await client.marketOrder(coin, isBuy, size, slippage);
|
|
118
|
+
const response = await client.marketOrder(coin, isBuy, size, slippage, leverage);
|
|
116
119
|
|
|
117
120
|
console.log('\nResult');
|
|
118
121
|
console.log('------');
|
|
@@ -25,6 +25,7 @@ Options:
|
|
|
25
25
|
- linear: more size at better prices
|
|
26
26
|
- exponential: much more size at better prices
|
|
27
27
|
- flat: equal size at all levels
|
|
28
|
+
--leverage Set leverage (e.g., 10 for 10x). Cross for main perps, isolated for HIP-3
|
|
28
29
|
--reduce Reduce-only orders (for scaling out of position)
|
|
29
30
|
--tif Time in force: GTC, ALO (default: GTC)
|
|
30
31
|
--dry Dry run - show order plan without executing
|
|
@@ -108,6 +109,7 @@ async function main() {
|
|
|
108
109
|
const numLevels = parseInt(args.levels as string);
|
|
109
110
|
const rangePct = parseFloat(args.range as string);
|
|
110
111
|
const distribution = (args.distribution as string || 'linear') as 'linear' | 'exponential' | 'flat';
|
|
112
|
+
const leverage = args.leverage ? parseInt(args.leverage as string) : undefined;
|
|
111
113
|
const reduceOnly = args.reduce as boolean;
|
|
112
114
|
const tifArg = ((args.tif as string)?.toUpperCase() || 'GTC');
|
|
113
115
|
const dryRun = args.dry as boolean;
|
|
@@ -208,7 +210,8 @@ async function main() {
|
|
|
208
210
|
level.size,
|
|
209
211
|
level.price,
|
|
210
212
|
tif,
|
|
211
|
-
reduceOnly
|
|
213
|
+
reduceOnly,
|
|
214
|
+
leverage
|
|
212
215
|
);
|
|
213
216
|
|
|
214
217
|
if (response.status === 'ok' && response.response && typeof response.response === 'object') {
|
|
@@ -23,6 +23,7 @@ Options:
|
|
|
23
23
|
--type Order type: tp (take profit) or sl (stop loss)
|
|
24
24
|
--limit Limit price when triggered (default: trigger price for TP, with slippage for SL)
|
|
25
25
|
--slippage Slippage for SL in bps (default: 100 = 1%)
|
|
26
|
+
--leverage Set leverage (e.g., 10 for 10x). Cross for main perps, isolated for HIP-3
|
|
26
27
|
--reduce Reduce-only order (default: true for TP/SL)
|
|
27
28
|
--dry Dry run - show order without placing
|
|
28
29
|
|
|
@@ -62,6 +63,7 @@ async function main() {
|
|
|
62
63
|
const orderType = args.type as string;
|
|
63
64
|
const limitPriceOverride = args.limit ? parseFloat(args.limit as string) : undefined;
|
|
64
65
|
const slippageBps = args.slippage ? parseInt(args.slippage as string) : 100;
|
|
66
|
+
const leverage = args.leverage ? parseInt(args.leverage as string) : undefined;
|
|
65
67
|
const reduceOnly = args.reduce !== 'false'; // Default true
|
|
66
68
|
const dryRun = args.dry as boolean;
|
|
67
69
|
|
|
@@ -167,7 +169,8 @@ async function main() {
|
|
|
167
169
|
triggerPrice,
|
|
168
170
|
limitPrice,
|
|
169
171
|
tpsl,
|
|
170
|
-
reduceOnly
|
|
172
|
+
reduceOnly,
|
|
173
|
+
leverage
|
|
171
174
|
);
|
|
172
175
|
|
|
173
176
|
console.log('\nResult');
|
|
@@ -23,6 +23,7 @@ Options:
|
|
|
23
23
|
--intervals Number of slices (default: calculates based on duration)
|
|
24
24
|
--randomize Randomize timing by ±X percent (default: 0)
|
|
25
25
|
--slippage Slippage tolerance in bps per slice (default: 50)
|
|
26
|
+
--leverage Set leverage (e.g., 10 for 10x). Cross for main perps, isolated for HIP-3
|
|
26
27
|
--dry Dry run - show execution plan without trading
|
|
27
28
|
|
|
28
29
|
Examples:
|
|
@@ -57,6 +58,7 @@ async function main() {
|
|
|
57
58
|
const intervals = args.intervals ? parseInt(args.intervals as string) : Math.max(6, Math.floor(duration / 300)); // default: 1 slice per 5 min
|
|
58
59
|
const randomize = args.randomize ? parseInt(args.randomize as string) : 0;
|
|
59
60
|
const slippage = args.slippage ? parseInt(args.slippage as string) : undefined;
|
|
61
|
+
const leverage = args.leverage ? parseInt(args.leverage as string) : undefined;
|
|
60
62
|
const dryRun = args.dry as boolean;
|
|
61
63
|
|
|
62
64
|
if (!coin || !side || isNaN(totalSize) || isNaN(duration)) {
|
|
@@ -146,7 +148,7 @@ async function main() {
|
|
|
146
148
|
};
|
|
147
149
|
|
|
148
150
|
try {
|
|
149
|
-
const response = await client.marketOrder(coin, isBuy, sliceSize, slippage);
|
|
151
|
+
const response = await client.marketOrder(coin, isBuy, sliceSize, slippage, leverage);
|
|
150
152
|
|
|
151
153
|
if (response.status === 'ok' && response.response && typeof response.response === 'object') {
|
|
152
154
|
const statuses = response.response.data.statuses;
|
package/scripts/plugin/tools.ts
CHANGED
|
@@ -743,6 +743,7 @@ export function createTools(watcher: PositionWatcher | null): PluginTool[] {
|
|
|
743
743
|
coin: { type: 'string', description: 'Asset symbol (ETH, BTC, SOL, etc.)' },
|
|
744
744
|
size: { type: 'number', description: 'Order size in base asset' },
|
|
745
745
|
slippage: { type: 'number', description: 'Slippage tolerance in bps (default: 50)' },
|
|
746
|
+
leverage: { type: 'number', description: 'Set leverage (e.g., 10 for 10x). Cross for main perps, isolated for HIP-3' },
|
|
746
747
|
dry: { type: 'boolean', description: 'Preview without executing' },
|
|
747
748
|
},
|
|
748
749
|
required: ['coin', 'size'],
|
|
@@ -757,6 +758,7 @@ export function createTools(watcher: PositionWatcher | null): PluginTool[] {
|
|
|
757
758
|
const coin = normalizeCoin(params.coin as string);
|
|
758
759
|
const size = params.size as number;
|
|
759
760
|
const slippageBps = (params.slippage as number) ?? client.builderInfo.f;
|
|
761
|
+
const leverage = params.leverage as number | undefined;
|
|
760
762
|
|
|
761
763
|
const mids = await client.getAllMids();
|
|
762
764
|
const midPrice = parseFloat(mids[coin]);
|
|
@@ -775,11 +777,12 @@ export function createTools(watcher: PositionWatcher | null): PluginTool[] {
|
|
|
775
777
|
midPrice,
|
|
776
778
|
slippagePrice,
|
|
777
779
|
slippageBps,
|
|
780
|
+
leverage,
|
|
778
781
|
});
|
|
779
782
|
}
|
|
780
783
|
|
|
781
|
-
const result = await client.marketOrder(coin, true, parseFloat(roundedSize), slippageBps);
|
|
782
|
-
return json({ action: 'buy', coin, size: roundedSize, result });
|
|
784
|
+
const result = await client.marketOrder(coin, true, parseFloat(roundedSize), slippageBps, leverage);
|
|
785
|
+
return json({ action: 'buy', coin, size: roundedSize, leverage, result });
|
|
783
786
|
},
|
|
784
787
|
},
|
|
785
788
|
|
|
@@ -792,6 +795,7 @@ export function createTools(watcher: PositionWatcher | null): PluginTool[] {
|
|
|
792
795
|
coin: { type: 'string', description: 'Asset symbol (ETH, BTC, SOL, etc.)' },
|
|
793
796
|
size: { type: 'number', description: 'Order size in base asset' },
|
|
794
797
|
slippage: { type: 'number', description: 'Slippage tolerance in bps (default: 50)' },
|
|
798
|
+
leverage: { type: 'number', description: 'Set leverage (e.g., 10 for 10x). Cross for main perps, isolated for HIP-3' },
|
|
795
799
|
dry: { type: 'boolean', description: 'Preview without executing' },
|
|
796
800
|
},
|
|
797
801
|
required: ['coin', 'size'],
|
|
@@ -806,6 +810,7 @@ export function createTools(watcher: PositionWatcher | null): PluginTool[] {
|
|
|
806
810
|
const coin = normalizeCoin(params.coin as string);
|
|
807
811
|
const size = params.size as number;
|
|
808
812
|
const slippageBps = (params.slippage as number) ?? client.builderInfo.f;
|
|
813
|
+
const leverage = params.leverage as number | undefined;
|
|
809
814
|
|
|
810
815
|
const mids = await client.getAllMids();
|
|
811
816
|
const midPrice = parseFloat(mids[coin]);
|
|
@@ -824,11 +829,12 @@ export function createTools(watcher: PositionWatcher | null): PluginTool[] {
|
|
|
824
829
|
midPrice,
|
|
825
830
|
slippagePrice,
|
|
826
831
|
slippageBps,
|
|
832
|
+
leverage,
|
|
827
833
|
});
|
|
828
834
|
}
|
|
829
835
|
|
|
830
|
-
const result = await client.marketOrder(coin, false, parseFloat(roundedSize), slippageBps);
|
|
831
|
-
return json({ action: 'sell', coin, size: roundedSize, result });
|
|
836
|
+
const result = await client.marketOrder(coin, false, parseFloat(roundedSize), slippageBps, leverage);
|
|
837
|
+
return json({ action: 'sell', coin, size: roundedSize, leverage, result });
|
|
832
838
|
},
|
|
833
839
|
},
|
|
834
840
|
|
|
@@ -843,6 +849,7 @@ export function createTools(watcher: PositionWatcher | null): PluginTool[] {
|
|
|
843
849
|
size: { type: 'number', description: 'Order size in base asset' },
|
|
844
850
|
price: { type: 'number', description: 'Limit price' },
|
|
845
851
|
tif: { type: 'string', enum: ['GTC', 'IOC', 'ALO'], description: 'Time in force (default: GTC)' },
|
|
852
|
+
leverage: { type: 'number', description: 'Set leverage (e.g., 10 for 10x). Cross for main perps, isolated for HIP-3' },
|
|
846
853
|
reduce: { type: 'boolean', description: 'Reduce-only order' },
|
|
847
854
|
dry: { type: 'boolean', description: 'Preview without executing' },
|
|
848
855
|
},
|
|
@@ -860,6 +867,7 @@ export function createTools(watcher: PositionWatcher | null): PluginTool[] {
|
|
|
860
867
|
const size = params.size as number;
|
|
861
868
|
const price = params.price as number;
|
|
862
869
|
const tif = ((params.tif as string) || 'GTC').toLowerCase();
|
|
870
|
+
const leverage = params.leverage as number | undefined;
|
|
863
871
|
const reduceOnly = (params.reduce as boolean) || false;
|
|
864
872
|
|
|
865
873
|
const szDecimals = await client.getSzDecimals(coin);
|
|
@@ -884,9 +892,9 @@ export function createTools(watcher: PositionWatcher | null): PluginTool[] {
|
|
|
884
892
|
}
|
|
885
893
|
|
|
886
894
|
const result = await client.limitOrder(
|
|
887
|
-
coin, isBuy, parseFloat(roundedSize), parseFloat(roundedPrice), sdkTif, reduceOnly,
|
|
895
|
+
coin, isBuy, parseFloat(roundedSize), parseFloat(roundedPrice), sdkTif, reduceOnly, leverage,
|
|
888
896
|
);
|
|
889
|
-
return json({ action: 'limit', coin, side: params.side, size: roundedSize, price: roundedPrice, result });
|
|
897
|
+
return json({ action: 'limit', coin, side: params.side, size: roundedSize, price: roundedPrice, leverage, result });
|
|
890
898
|
},
|
|
891
899
|
},
|
|
892
900
|
|
|
@@ -1068,6 +1076,7 @@ export function createTools(watcher: PositionWatcher | null): PluginTool[] {
|
|
|
1068
1076
|
duration: { type: 'number', description: 'Duration in seconds' },
|
|
1069
1077
|
intervals: { type: 'number', description: 'Number of slices' },
|
|
1070
1078
|
randomize: { type: 'number', description: 'Randomize timing by this % (0-50)' },
|
|
1079
|
+
leverage: { type: 'number', description: 'Set leverage (e.g., 10 for 10x)' },
|
|
1071
1080
|
dry: { type: 'boolean', description: 'Preview without executing' },
|
|
1072
1081
|
},
|
|
1073
1082
|
required: ['coin', 'side', 'size', 'duration'],
|
|
@@ -1102,6 +1111,7 @@ export function createTools(watcher: PositionWatcher | null): PluginTool[] {
|
|
|
1102
1111
|
sl: { type: 'number', description: 'Stop loss percentage from entry' },
|
|
1103
1112
|
entry: { type: 'string', enum: ['market', 'limit'], description: 'Entry type (default: market)' },
|
|
1104
1113
|
price: { type: 'number', description: 'Entry price (required if entry=limit)' },
|
|
1114
|
+
leverage: { type: 'number', description: 'Set leverage (e.g., 10 for 10x)' },
|
|
1105
1115
|
dry: { type: 'boolean', description: 'Preview without executing' },
|
|
1106
1116
|
},
|
|
1107
1117
|
required: ['coin', 'side', 'size', 'tp', 'sl'],
|
|
@@ -1134,6 +1144,7 @@ export function createTools(watcher: PositionWatcher | null): PluginTool[] {
|
|
|
1134
1144
|
size: { type: 'number', description: 'Order size' },
|
|
1135
1145
|
offset: { type: 'number', description: 'Tick offset from best price (default: 1)' },
|
|
1136
1146
|
timeout: { type: 'number', description: 'Timeout in seconds' },
|
|
1147
|
+
leverage: { type: 'number', description: 'Set leverage (e.g., 10 for 10x)' },
|
|
1137
1148
|
dry: { type: 'boolean', description: 'Preview without executing' },
|
|
1138
1149
|
},
|
|
1139
1150
|
required: ['coin', 'side', 'size'],
|