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 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.54", "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)"}]}}
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
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "openbroker",
3
3
  "name": "OpenBroker — Hyperliquid Trading",
4
- "version": "1.0.54",
4
+ "version": "1.0.55",
5
5
  "description": "Trade on Hyperliquid DEX with background position monitoring",
6
6
  "configSchema": {
7
7
  "type": "object",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openbroker",
3
- "version": "1.0.54",
3
+ "version": "1.0.55",
4
4
  "description": "Hyperliquid trading CLI - execute orders, manage positions, and run trading strategies",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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
- // Set isolated margin on first order per asset
1137
- if (!this.hip3IsolatedSet.has(coin)) {
1138
- const maxLev = this.hip3MaxLeverageMap.get(coin) ?? 10;
1139
- this.log(`HIP-3 asset ${coin} (dex: ${dexInfo.dexName}) setting isolated margin at ${maxLev}x`);
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, maxLev, false); // false = isolated
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 maxLev = this.hip3MaxLeverageMap.get(coin) ?? 10;
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;
@@ -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'],