openbroker 1.9.1 → 1.9.3
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 +10 -0
- package/README.md +11 -0
- package/SKILL.md +58 -1
- package/bin/cli.ts +3 -0
- package/dist/auto/cli.js +3 -0
- package/dist/auto/examples/dca.d.ts +2 -1
- package/dist/auto/examples/dca.d.ts.map +1 -1
- package/dist/auto/examples/dca.js +19 -1
- package/dist/auto/examples/funding-arb.d.ts +2 -1
- package/dist/auto/examples/funding-arb.d.ts.map +1 -1
- package/dist/auto/examples/funding-arb.js +19 -2
- package/dist/auto/examples/grid.d.ts +2 -1
- package/dist/auto/examples/grid.d.ts.map +1 -1
- package/dist/auto/examples/grid.js +18 -2
- package/dist/auto/examples/mm-maker.d.ts +2 -1
- package/dist/auto/examples/mm-maker.d.ts.map +1 -1
- package/dist/auto/examples/mm-maker.js +18 -2
- package/dist/auto/examples/mm-spread.d.ts +2 -1
- package/dist/auto/examples/mm-spread.d.ts.map +1 -1
- package/dist/auto/examples/mm-spread.js +18 -2
- package/dist/auto/examples/price-alert.d.ts +2 -1
- package/dist/auto/examples/price-alert.d.ts.map +1 -1
- package/dist/auto/examples/price-alert.js +1 -0
- package/dist/auto/guardrails.d.ts +19 -0
- package/dist/auto/guardrails.d.ts.map +1 -0
- package/dist/auto/guardrails.js +575 -0
- package/dist/auto/guardrails.test.d.ts +2 -0
- package/dist/auto/guardrails.test.d.ts.map +1 -0
- package/dist/auto/guardrails.test.js +173 -0
- package/dist/auto/loader.d.ts +3 -3
- package/dist/auto/loader.d.ts.map +1 -1
- package/dist/auto/loader.js +25 -3
- package/dist/auto/runtime.d.ts.map +1 -1
- package/dist/auto/runtime.js +38 -20
- package/dist/auto/types.d.ts +43 -0
- package/dist/auto/types.d.ts.map +1 -1
- package/dist/lib.d.ts +2 -0
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +1 -0
- package/dist/setup/install.d.ts +3 -0
- package/dist/setup/install.d.ts.map +1 -0
- package/dist/setup/install.js +113 -0
- package/package.json +4 -3
- package/scripts/auto/cli.ts +3 -0
- package/scripts/auto/examples/dca.ts +21 -2
- package/scripts/auto/examples/funding-arb.ts +21 -3
- package/scripts/auto/examples/grid.ts +20 -3
- package/scripts/auto/examples/mm-maker.ts +20 -3
- package/scripts/auto/examples/mm-spread.ts +20 -3
- package/scripts/auto/examples/price-alert.ts +3 -1
- package/scripts/auto/guardrails.test.ts +227 -0
- package/scripts/auto/guardrails.ts +700 -0
- package/scripts/auto/loader.ts +41 -4
- package/scripts/auto/runtime.ts +38 -22
- package/scripts/auto/types.ts +54 -0
- package/scripts/lib.ts +10 -0
- package/scripts/setup/install.ts +146 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,9 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Open Broker will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.9.2] - 2026-06-22
|
|
6
|
+
|
|
7
|
+
### Breaking
|
|
8
|
+
- Every automation must now export a validated `guardrails` policy. Monitoring scripts use `{ mode: 'read-only' }`; trading scripts must declare explicit market, notional, exposure, leverage, margin, open-order, rate, slippage, market-order, and account-wide-cancel limits.
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Added runtime guardrail enforcement around every supported `api.client` write method, including bulk and HIP-4 outcome methods that were previously missing from dry-run and audit interception.
|
|
12
|
+
- Added fail-closed account preflight checks, explicit leverage enforcement for risk-increasing perp orders, rolling order-rate limits, audit records for blocked writes, and unit coverage for schema and runtime behavior.
|
|
13
|
+
|
|
5
14
|
## [1.9.1] - 2026-06-22
|
|
6
15
|
|
|
7
16
|
### Changed
|
|
17
|
+
- Added `openbroker install --codex` and `npx openbroker@latest install --codex` for one-command Codex skill installation, persistent CLI installation, and restricted API-wallet onboarding.
|
|
8
18
|
- Made restricted API-wallet onboarding the recommended interactive default.
|
|
9
19
|
- Added `openbroker setup --api-wallet` for deterministic agent setup without the wallet-selection prompt.
|
|
10
20
|
- Updated the Codex skill to install the CLI, hand the browser approval URL to the user, wait for authorization, and verify the connected master account without exposing private keys.
|
package/README.md
CHANGED
|
@@ -8,6 +8,16 @@ Hyperliquid trading CLI. Execute orders, manage positions, and run trading strat
|
|
|
8
8
|
npm install -g openbroker
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
### Codex: one-command install
|
|
12
|
+
|
|
13
|
+
Install the Codex skill, persistent CLI, and restricted API-wallet onboarding flow:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx openbroker@latest install --codex
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
When the command prints an approval URL, open it and connect the funded master Hyperliquid account you want OpenBroker to trade on. Restart Codex or start a new thread when setup finishes, then invoke `$openbroker`.
|
|
20
|
+
|
|
11
21
|
## Quick Start
|
|
12
22
|
|
|
13
23
|
```bash
|
|
@@ -27,6 +37,7 @@ openbroker search --query GOLD # Find markets
|
|
|
27
37
|
### Setup
|
|
28
38
|
|
|
29
39
|
```bash
|
|
40
|
+
npx openbroker@latest install --codex # Codex skill + CLI + API-wallet onboarding
|
|
30
41
|
openbroker setup --api-wallet # Recommended: restricted agent wallet + browser approval
|
|
31
42
|
openbroker setup # Interactive; API wallet is the default
|
|
32
43
|
```
|
package/SKILL.md
CHANGED
|
@@ -21,7 +21,15 @@ Use the `openbroker` CLI as the canonical interface. Prefer structured JSON outp
|
|
|
21
21
|
|
|
22
22
|
Use the following flow when the user asks to install, set up, or use OpenBroker. Do not ask the user for a private key.
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
For a fresh Codex installation, prefer the unified harness installer:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx --yes openbroker@latest install --codex
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
This installs or updates the Codex skill, installs the persistent `openbroker` CLI, and starts restricted API-wallet onboarding. Keep the command attached while it prints the browser approval link and polls for authorization.
|
|
31
|
+
|
|
32
|
+
If the unified installer is unavailable or the skill is already installed, first check whether Node.js 22+ and the CLI are installed:
|
|
25
33
|
|
|
26
34
|
```bash
|
|
27
35
|
node --version
|
|
@@ -212,6 +220,54 @@ Run flags:
|
|
|
212
220
|
|
|
213
221
|
Bundled examples are **references, not production strategies**. Read them for API patterns, then write a purpose-built script with explicit sizing, exit logic, and failure behavior.
|
|
214
222
|
|
|
223
|
+
### Required guardrail contract
|
|
224
|
+
|
|
225
|
+
Every automation module must export both `guardrails` and a default factory. Validation runs before the factory or any `onStart` hook. A missing, malformed, or internally inconsistent policy prevents startup.
|
|
226
|
+
|
|
227
|
+
Use a read-only policy for monitoring and alerting:
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
import type { AutomationAPI, AutomationGuardrails } from 'openbroker';
|
|
231
|
+
|
|
232
|
+
export const guardrails: AutomationGuardrails = { mode: 'read-only' };
|
|
233
|
+
|
|
234
|
+
export default function monitor(api: AutomationAPI) {
|
|
235
|
+
api.on('price_change', ({ coin, changePct }) => api.log.info(`${coin}: ${changePct}%`));
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Read-only mode blocks every client write. Trading policies must declare every field below:
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
import type { AutomationAPI, AutomationGuardrails } from 'openbroker';
|
|
243
|
+
|
|
244
|
+
export const guardrails: AutomationGuardrails = {
|
|
245
|
+
mode: 'trading',
|
|
246
|
+
allowedMarkets: ['ETH'], // ETH, xyz:CL, spot:HYPE, or #<outcome encoding>
|
|
247
|
+
maxOrderUsd: 500,
|
|
248
|
+
maxPositionUsd: 1_000,
|
|
249
|
+
maxTotalExposureUsd: 2_500,
|
|
250
|
+
maxLeverage: 2,
|
|
251
|
+
maxMarginUsedPct: 50,
|
|
252
|
+
maxOpenOrders: 10,
|
|
253
|
+
maxOrdersPerMinute: 6,
|
|
254
|
+
maxSlippageBps: 50,
|
|
255
|
+
allowMarketOrders: true,
|
|
256
|
+
allowAccountWideCancel: false,
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
export default function strategy(api: AutomationAPI) {
|
|
260
|
+
// Risk-increasing perp orders must pass leverage explicitly.
|
|
261
|
+
api.onStart(() => api.client.limitOrder('ETH', true, 0.1, 2_000, 'Gtc', false, 2));
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
When allowed markets depend on `--set` values, export a factory such as `guardrails({ config }) { ... }`; the returned object is still strictly validated. Wildcard markets and unknown policy fields are rejected.
|
|
266
|
+
|
|
267
|
+
All `api.client` write methods cross the runtime policy proxy in live and `--dry` modes. Before risk-increasing orders, the runtime refreshes account positions, spot balances, prices, margin, and open orders; calculates projected per-market and total exposure; enforces leverage, margin, order-count, rate, market-order, and slippage limits; then either submits or throws `GuardrailViolation`. Blocks are logged and written to the audit trail as `guardrail_block`. Cancellations and genuinely risk-reducing orders remain available when exposure or margin is already above its cap, but market allowlists and explicit account-wide-cancel policy still apply. Administrative writes such as `approveBuilderFee` are always blocked inside automations.
|
|
268
|
+
|
|
269
|
+
Treat `api.client` as the only supported execution path. Automation files are trusted TypeScript running in-process, not an OS sandbox; direct exchange SDK imports would bypass the runtime boundary and must not be generated or accepted during review.
|
|
270
|
+
|
|
215
271
|
### Automation API essentials
|
|
216
272
|
|
|
217
273
|
- `api.client` — full Hyperliquid client.
|
|
@@ -219,6 +275,7 @@ Bundled examples are **references, not production strategies**. Read them for AP
|
|
|
219
275
|
- `api.state` — persisted state; survives restarts.
|
|
220
276
|
- `api.audit.record(...)` / `api.audit.metric(...)` — durable observability.
|
|
221
277
|
- `api.dryRun` — whether writes are intercepted.
|
|
278
|
+
- `api.guardrails` — validated policy currently enforced by the runtime.
|
|
222
279
|
|
|
223
280
|
Core events include `tick`, `price_change`, `funding_update`, `position_opened`, `position_closed`, `position_changed`, `pnl_threshold`, `margin_warning`, `order_filled`, `order_update`, and `liquidation`.
|
|
224
281
|
|
package/bin/cli.ts
CHANGED
|
@@ -11,6 +11,7 @@ const scriptsDir = path.resolve(__dirname, '../scripts');
|
|
|
11
11
|
|
|
12
12
|
const commands: Record<string, { script: string; description: string }> = {
|
|
13
13
|
// Setup
|
|
14
|
+
'install': { script: 'setup/install.ts', description: 'Install OpenBroker for an agent harness' },
|
|
14
15
|
'setup': { script: 'setup/onboard.ts', description: 'Interactive setup wizard' },
|
|
15
16
|
'onboard': { script: 'setup/onboard.ts', description: 'Interactive setup wizard' },
|
|
16
17
|
'approve-builder': { script: 'setup/approve-builder.ts', description: 'Approve builder fee' },
|
|
@@ -68,6 +69,7 @@ Open Broker - Hyperliquid Trading CLI
|
|
|
68
69
|
Usage: openbroker <command> [options]
|
|
69
70
|
|
|
70
71
|
Setup:
|
|
72
|
+
install Install OpenBroker for Codex or another agent harness
|
|
71
73
|
setup One-command setup (wallet + config + builder approval)
|
|
72
74
|
|
|
73
75
|
Info Commands:
|
|
@@ -136,6 +138,7 @@ Utility:
|
|
|
136
138
|
approve-builder Check or retry builder fee approval
|
|
137
139
|
|
|
138
140
|
Examples:
|
|
141
|
+
npx openbroker@latest install --codex # Install skill + CLI + API-wallet setup
|
|
139
142
|
openbroker setup --api-wallet # Recommended restricted API-wallet setup
|
|
140
143
|
openbroker account # View account info
|
|
141
144
|
openbroker buy --coin ETH --size 0.1 # Market buy 0.1 ETH
|
package/dist/auto/cli.js
CHANGED
|
@@ -47,6 +47,8 @@ Scripts are loaded from:
|
|
|
47
47
|
3. Bundled examples (via --example)
|
|
48
48
|
|
|
49
49
|
Writing an automation:
|
|
50
|
+
export const guardrails = { mode: 'read-only' };
|
|
51
|
+
|
|
50
52
|
export default function(api) {
|
|
51
53
|
api.on('price_change', async ({ coin, changePct }) => {
|
|
52
54
|
api.log.info(\`\${coin} moved \${changePct.toFixed(2)}%\`);
|
|
@@ -187,6 +189,7 @@ function listCommand() {
|
|
|
187
189
|
if (automations.length === 0 && examples.length === 0) {
|
|
188
190
|
console.log('No automations found in ~/.openbroker/automations/');
|
|
189
191
|
console.log('\nCreate a .ts file there with:');
|
|
192
|
+
console.log(" export const guardrails = { mode: 'read-only' };");
|
|
190
193
|
console.log(' export default function(api) { ... }');
|
|
191
194
|
console.log('\nOr run a bundled example: openbroker auto examples');
|
|
192
195
|
return;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { AutomationAPI, AutomationConfig } from '../types.js';
|
|
1
|
+
import type { AutomationAPI, AutomationConfig, AutomationGuardrailContext, AutomationGuardrails } from '../types.js';
|
|
2
2
|
export declare const config: AutomationConfig;
|
|
3
|
+
export declare function guardrails({ config: values }: AutomationGuardrailContext): AutomationGuardrails;
|
|
3
4
|
export default function dca(api: AutomationAPI): void;
|
|
4
5
|
//# sourceMappingURL=dca.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dca.d.ts","sourceRoot":"","sources":["../../../scripts/auto/examples/dca.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"dca.d.ts","sourceRoot":"","sources":["../../../scripts/auto/examples/dca.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAErH,eAAO,MAAM,MAAM,EAAE,gBAQpB,CAAC;AAEF,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,0BAA0B,GAAG,oBAAoB,CAiB/F;AAED,MAAM,CAAC,OAAO,UAAU,GAAG,CAAC,GAAG,EAAE,aAAa,QAyD7C"}
|
|
@@ -8,6 +8,24 @@ export const config = {
|
|
|
8
8
|
count: { type: 'number', description: 'Total number of purchases', default: 24 },
|
|
9
9
|
},
|
|
10
10
|
};
|
|
11
|
+
export function guardrails({ config: values }) {
|
|
12
|
+
const amount = Number(values.amount ?? 100);
|
|
13
|
+
const count = Number(values.count ?? 24);
|
|
14
|
+
return {
|
|
15
|
+
mode: 'trading',
|
|
16
|
+
allowedMarkets: [String(values.coin ?? 'HYPE')],
|
|
17
|
+
maxOrderUsd: amount * 1.1,
|
|
18
|
+
maxPositionUsd: amount * count * 1.1,
|
|
19
|
+
maxTotalExposureUsd: amount * count * 1.1,
|
|
20
|
+
maxLeverage: 1,
|
|
21
|
+
maxMarginUsedPct: 50,
|
|
22
|
+
maxOpenOrders: 5,
|
|
23
|
+
maxOrdersPerMinute: 5,
|
|
24
|
+
maxSlippageBps: 50,
|
|
25
|
+
allowMarketOrders: true,
|
|
26
|
+
allowAccountWideCancel: false,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
11
29
|
export default function dca(api) {
|
|
12
30
|
const COIN = api.state.get('coin', 'HYPE');
|
|
13
31
|
const AMOUNT_USD = api.state.get('amount', 100);
|
|
@@ -33,7 +51,7 @@ export default function dca(api) {
|
|
|
33
51
|
}
|
|
34
52
|
const size = AMOUNT_USD / price;
|
|
35
53
|
api.log.info(`[${purchased + 1}/${MAX_PURCHASES}] Buying ~$${AMOUNT_USD} of ${COIN} @ $${price.toFixed(2)}`);
|
|
36
|
-
const response = await api.client.marketOrder(COIN, true, size);
|
|
54
|
+
const response = await api.client.marketOrder(COIN, true, size, undefined, 1);
|
|
37
55
|
if (response.status === 'ok' && response.response && typeof response.response === 'object') {
|
|
38
56
|
const status = response.response.data.statuses[0];
|
|
39
57
|
if (status?.filled) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { AutomationAPI, AutomationConfig } from '../types.js';
|
|
1
|
+
import type { AutomationAPI, AutomationConfig, AutomationGuardrailContext, AutomationGuardrails } from '../types.js';
|
|
2
2
|
export declare const config: AutomationConfig;
|
|
3
|
+
export declare function guardrails({ config: values }: AutomationGuardrailContext): AutomationGuardrails;
|
|
3
4
|
export default function fundingArb(api: AutomationAPI): void;
|
|
4
5
|
//# sourceMappingURL=funding-arb.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"funding-arb.d.ts","sourceRoot":"","sources":["../../../scripts/auto/examples/funding-arb.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"funding-arb.d.ts","sourceRoot":"","sources":["../../../scripts/auto/examples/funding-arb.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAErH,eAAO,MAAM,MAAM,EAAE,gBASpB,CAAC;AAEF,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,0BAA0B,GAAG,oBAAoB,CAgB/F;AAED,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,GAAG,EAAE,aAAa,QAkFpD"}
|
|
@@ -9,6 +9,23 @@ export const config = {
|
|
|
9
9
|
closeAt: { type: 'number', description: 'Close when funding drops below this %', default: 5 },
|
|
10
10
|
},
|
|
11
11
|
};
|
|
12
|
+
export function guardrails({ config: values }) {
|
|
13
|
+
const sizeUsd = Number(values.sizeUsd ?? 5000);
|
|
14
|
+
return {
|
|
15
|
+
mode: 'trading',
|
|
16
|
+
allowedMarkets: [String(values.coin ?? 'HYPE')],
|
|
17
|
+
maxOrderUsd: sizeUsd * 1.1,
|
|
18
|
+
maxPositionUsd: sizeUsd * 1.1,
|
|
19
|
+
maxTotalExposureUsd: sizeUsd * 1.1,
|
|
20
|
+
maxLeverage: 1,
|
|
21
|
+
maxMarginUsedPct: 50,
|
|
22
|
+
maxOpenOrders: 5,
|
|
23
|
+
maxOrdersPerMinute: 4,
|
|
24
|
+
maxSlippageBps: 50,
|
|
25
|
+
allowMarketOrders: true,
|
|
26
|
+
allowAccountWideCancel: false,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
12
29
|
export default function fundingArb(api) {
|
|
13
30
|
const COIN = api.state.get('coin', 'HYPE');
|
|
14
31
|
const SIZE_USD = api.state.get('sizeUsd', 5000);
|
|
@@ -38,7 +55,7 @@ export default function fundingArb(api) {
|
|
|
38
55
|
if (shouldClose) {
|
|
39
56
|
api.log.info(`Funding dropped to ${annualizedPct.toFixed(2)}% (below ${CLOSE_AT}%), closing ${positionSide}`);
|
|
40
57
|
const closeIsBuy = positionSide === 'short';
|
|
41
|
-
await api.client.marketOrder(coin, closeIsBuy, positionSize);
|
|
58
|
+
await api.client.marketOrder(coin, closeIsBuy, positionSize, undefined, 1);
|
|
42
59
|
inPosition = false;
|
|
43
60
|
api.state.set('inPosition', false);
|
|
44
61
|
api.log.info(`Position closed. Funding collected: ~$${totalFunding.toFixed(2)}`);
|
|
@@ -56,7 +73,7 @@ export default function fundingArb(api) {
|
|
|
56
73
|
const price = parseFloat(mids[coin]);
|
|
57
74
|
const size = SIZE_USD / price;
|
|
58
75
|
api.log.info(`Funding at ${annualizedPct.toFixed(2)}% — opening ${side} ${size.toFixed(6)} ${coin}`);
|
|
59
|
-
const response = await api.client.marketOrder(coin, !shouldShort, size);
|
|
76
|
+
const response = await api.client.marketOrder(coin, !shouldShort, size, undefined, 1);
|
|
60
77
|
if (response.status === 'ok' && response.response && typeof response.response === 'object') {
|
|
61
78
|
const status = response.response.data.statuses[0];
|
|
62
79
|
if (status?.filled) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { AutomationAPI, AutomationConfig } from '../types.js';
|
|
1
|
+
import type { AutomationAPI, AutomationConfig, AutomationGuardrailContext, AutomationGuardrails } from '../types.js';
|
|
2
2
|
export declare const config: AutomationConfig;
|
|
3
|
+
export declare function guardrails({ config: values }: AutomationGuardrailContext): AutomationGuardrails;
|
|
3
4
|
export default function grid(api: AutomationAPI): void;
|
|
4
5
|
//# sourceMappingURL=grid.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../../../scripts/auto/examples/grid.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../../../scripts/auto/examples/grid.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAErH,eAAO,MAAM,MAAM,EAAE,gBAUpB,CAAC;AAEF,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,0BAA0B,GAAG,oBAAoB,CAe/F;AASD,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,GAAG,EAAE,aAAa,QA+G9C"}
|
|
@@ -10,6 +10,22 @@ export const config = {
|
|
|
10
10
|
mode: { type: 'string', description: 'Grid mode: neutral, long, or short', default: 'neutral' },
|
|
11
11
|
},
|
|
12
12
|
};
|
|
13
|
+
export function guardrails({ config: values }) {
|
|
14
|
+
return {
|
|
15
|
+
mode: 'trading',
|
|
16
|
+
allowedMarkets: [String(values.coin ?? 'HYPE')],
|
|
17
|
+
maxOrderUsd: 10_000,
|
|
18
|
+
maxPositionUsd: 25_000,
|
|
19
|
+
maxTotalExposureUsd: 25_000,
|
|
20
|
+
maxLeverage: 1,
|
|
21
|
+
maxMarginUsedPct: 50,
|
|
22
|
+
maxOpenOrders: 25,
|
|
23
|
+
maxOrdersPerMinute: 25,
|
|
24
|
+
maxSlippageBps: 50,
|
|
25
|
+
allowMarketOrders: false,
|
|
26
|
+
allowAccountWideCancel: false,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
13
29
|
export default function grid(api) {
|
|
14
30
|
const COIN = api.state.get('coin', 'HYPE');
|
|
15
31
|
const GRIDS = api.state.get('grids', 10);
|
|
@@ -43,7 +59,7 @@ export default function grid(api) {
|
|
|
43
59
|
if (Math.abs(price - mid) / mid < 0.001)
|
|
44
60
|
continue;
|
|
45
61
|
const level = { price, side, size: SIZE };
|
|
46
|
-
const response = await api.client.limitOrder(COIN, side === 'buy', SIZE, price, 'Gtc', false);
|
|
62
|
+
const response = await api.client.limitOrder(COIN, side === 'buy', SIZE, price, 'Gtc', false, 1);
|
|
47
63
|
if (response.status === 'ok' && response.response && typeof response.response === 'object') {
|
|
48
64
|
const status = response.response.data.statuses[0];
|
|
49
65
|
if (status?.resting) {
|
|
@@ -84,7 +100,7 @@ export default function grid(api) {
|
|
|
84
100
|
const oppositePrice = level.side === 'buy' ? level.price + spacing : level.price - spacing;
|
|
85
101
|
if (oppositePrice < lower || oppositePrice > upper)
|
|
86
102
|
continue;
|
|
87
|
-
const response = await api.client.limitOrder(COIN, oppositeSide === 'buy', SIZE, oppositePrice, 'Gtc', false);
|
|
103
|
+
const response = await api.client.limitOrder(COIN, oppositeSide === 'buy', SIZE, oppositePrice, 'Gtc', false, 1);
|
|
88
104
|
if (response.status === 'ok' && response.response && typeof response.response === 'object') {
|
|
89
105
|
const status = response.response.data.statuses[0];
|
|
90
106
|
if (status?.resting) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { AutomationAPI, AutomationConfig } from '../types.js';
|
|
1
|
+
import type { AutomationAPI, AutomationConfig, AutomationGuardrailContext, AutomationGuardrails } from '../types.js';
|
|
2
2
|
export declare const config: AutomationConfig;
|
|
3
|
+
export declare function guardrails({ config: values }: AutomationGuardrailContext): AutomationGuardrails;
|
|
3
4
|
export default function mmMaker(api: AutomationAPI): void;
|
|
4
5
|
//# sourceMappingURL=mm-maker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mm-maker.d.ts","sourceRoot":"","sources":["../../../scripts/auto/examples/mm-maker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"mm-maker.d.ts","sourceRoot":"","sources":["../../../scripts/auto/examples/mm-maker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAErH,eAAO,MAAM,MAAM,EAAE,gBASpB,CAAC;AAEF,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,0BAA0B,GAAG,oBAAoB,CAe/F;AAED,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,GAAG,EAAE,aAAa,QA6GjD"}
|
|
@@ -9,6 +9,22 @@ export const config = {
|
|
|
9
9
|
skewFactor: { type: 'number', description: 'Inventory skew aggressiveness', default: 2.0 },
|
|
10
10
|
},
|
|
11
11
|
};
|
|
12
|
+
export function guardrails({ config: values }) {
|
|
13
|
+
return {
|
|
14
|
+
mode: 'trading',
|
|
15
|
+
allowedMarkets: [String(values.coin ?? 'HYPE')],
|
|
16
|
+
maxOrderUsd: 10_000,
|
|
17
|
+
maxPositionUsd: 25_000,
|
|
18
|
+
maxTotalExposureUsd: 25_000,
|
|
19
|
+
maxLeverage: 1,
|
|
20
|
+
maxMarginUsedPct: 50,
|
|
21
|
+
maxOpenOrders: 10,
|
|
22
|
+
maxOrdersPerMinute: 60,
|
|
23
|
+
maxSlippageBps: 25,
|
|
24
|
+
allowMarketOrders: false,
|
|
25
|
+
allowAccountWideCancel: false,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
12
28
|
export default function mmMaker(api) {
|
|
13
29
|
const COIN = api.state.get('coin', 'HYPE');
|
|
14
30
|
const SIZE = api.state.get('size', 0.1);
|
|
@@ -85,7 +101,7 @@ export default function mmMaker(api) {
|
|
|
85
101
|
}
|
|
86
102
|
// Place ALO bid
|
|
87
103
|
if (shouldBid && !bidOid && safeBid < book.bestAsk) {
|
|
88
|
-
const resp = await api.client.limitOrder(COIN, true, SIZE, safeBid, 'Alo', false);
|
|
104
|
+
const resp = await api.client.limitOrder(COIN, true, SIZE, safeBid, 'Alo', false, 1);
|
|
89
105
|
if (resp.status === 'ok' && resp.response && typeof resp.response === 'object') {
|
|
90
106
|
const s = resp.response.data.statuses[0];
|
|
91
107
|
if (s?.resting) {
|
|
@@ -99,7 +115,7 @@ export default function mmMaker(api) {
|
|
|
99
115
|
}
|
|
100
116
|
// Place ALO ask
|
|
101
117
|
if (shouldAsk && !askOid && safeAsk > book.bestBid) {
|
|
102
|
-
const resp = await api.client.limitOrder(COIN, false, SIZE, safeAsk, 'Alo', false);
|
|
118
|
+
const resp = await api.client.limitOrder(COIN, false, SIZE, safeAsk, 'Alo', false, 1);
|
|
103
119
|
if (resp.status === 'ok' && resp.response && typeof resp.response === 'object') {
|
|
104
120
|
const s = resp.response.data.statuses[0];
|
|
105
121
|
if (s?.resting) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { AutomationAPI, AutomationConfig } from '../types.js';
|
|
1
|
+
import type { AutomationAPI, AutomationConfig, AutomationGuardrailContext, AutomationGuardrails } from '../types.js';
|
|
2
2
|
export declare const config: AutomationConfig;
|
|
3
|
+
export declare function guardrails({ config: values }: AutomationGuardrailContext): AutomationGuardrails;
|
|
3
4
|
export default function mmSpread(api: AutomationAPI): void;
|
|
4
5
|
//# sourceMappingURL=mm-spread.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mm-spread.d.ts","sourceRoot":"","sources":["../../../scripts/auto/examples/mm-spread.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"mm-spread.d.ts","sourceRoot":"","sources":["../../../scripts/auto/examples/mm-spread.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAErH,eAAO,MAAM,MAAM,EAAE,gBASpB,CAAC;AAEF,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,0BAA0B,GAAG,oBAAoB,CAe/F;AAED,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAG,EAAE,aAAa,QAmGlD"}
|
|
@@ -9,6 +9,22 @@ export const config = {
|
|
|
9
9
|
skewFactor: { type: 'number', description: 'Inventory skew aggressiveness', default: 2.0 },
|
|
10
10
|
},
|
|
11
11
|
};
|
|
12
|
+
export function guardrails({ config: values }) {
|
|
13
|
+
return {
|
|
14
|
+
mode: 'trading',
|
|
15
|
+
allowedMarkets: [String(values.coin ?? 'HYPE')],
|
|
16
|
+
maxOrderUsd: 10_000,
|
|
17
|
+
maxPositionUsd: 25_000,
|
|
18
|
+
maxTotalExposureUsd: 25_000,
|
|
19
|
+
maxLeverage: 1,
|
|
20
|
+
maxMarginUsedPct: 50,
|
|
21
|
+
maxOpenOrders: 10,
|
|
22
|
+
maxOrdersPerMinute: 60,
|
|
23
|
+
maxSlippageBps: 25,
|
|
24
|
+
allowMarketOrders: false,
|
|
25
|
+
allowAccountWideCancel: false,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
12
28
|
export default function mmSpread(api) {
|
|
13
29
|
const COIN = api.state.get('coin', 'HYPE');
|
|
14
30
|
const SIZE = api.state.get('size', 0.1);
|
|
@@ -82,7 +98,7 @@ export default function mmSpread(api) {
|
|
|
82
98
|
}
|
|
83
99
|
// Place new quotes
|
|
84
100
|
if (shouldBid && !bidOid) {
|
|
85
|
-
const resp = await api.client.limitOrder(COIN, true, SIZE, targetBid, 'Gtc', false);
|
|
101
|
+
const resp = await api.client.limitOrder(COIN, true, SIZE, targetBid, 'Gtc', false, 1);
|
|
86
102
|
if (resp.status === 'ok' && resp.response && typeof resp.response === 'object') {
|
|
87
103
|
const s = resp.response.data.statuses[0];
|
|
88
104
|
if (s?.resting) {
|
|
@@ -92,7 +108,7 @@ export default function mmSpread(api) {
|
|
|
92
108
|
}
|
|
93
109
|
}
|
|
94
110
|
if (shouldAsk && !askOid) {
|
|
95
|
-
const resp = await api.client.limitOrder(COIN, false, SIZE, targetAsk, 'Gtc', false);
|
|
111
|
+
const resp = await api.client.limitOrder(COIN, false, SIZE, targetAsk, 'Gtc', false, 1);
|
|
96
112
|
if (resp.status === 'ok' && resp.response && typeof resp.response === 'object') {
|
|
97
113
|
const s = resp.response.data.statuses[0];
|
|
98
114
|
if (s?.resting) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { AutomationAPI, AutomationConfig } from '../types.js';
|
|
1
|
+
import type { AutomationAPI, AutomationConfig, AutomationGuardrails } from '../types.js';
|
|
2
2
|
export declare const config: AutomationConfig;
|
|
3
|
+
export declare const guardrails: AutomationGuardrails;
|
|
3
4
|
export default function priceAlert(api: AutomationAPI): void;
|
|
4
5
|
//# sourceMappingURL=price-alert.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"price-alert.d.ts","sourceRoot":"","sources":["../../../scripts/auto/examples/price-alert.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"price-alert.d.ts","sourceRoot":"","sources":["../../../scripts/auto/examples/price-alert.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEzF,eAAO,MAAM,MAAM,EAAE,gBAQpB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,oBAA4C,CAAC;AAEtE,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,GAAG,EAAE,aAAa,QAgFpD"}
|
|
@@ -9,6 +9,7 @@ export const config = {
|
|
|
9
9
|
below: { type: 'number', description: 'Alert when price goes below this level (0 = disabled)', default: 0 },
|
|
10
10
|
},
|
|
11
11
|
};
|
|
12
|
+
export const guardrails = { mode: 'read-only' };
|
|
12
13
|
export default function priceAlert(api) {
|
|
13
14
|
const COIN = api.state.get('coin', 'BTC');
|
|
14
15
|
const THRESHOLD = api.state.get('threshold', 0.1);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { HyperliquidClient } from '../core/client.js';
|
|
2
|
+
import type { AutomationGuardrailContext, AutomationGuardrails, AutomationGuardrailsExport, AutomationLogger } from './types.js';
|
|
3
|
+
export declare const CLIENT_WRITE_METHODS: Set<string>;
|
|
4
|
+
export declare class GuardrailViolation extends Error {
|
|
5
|
+
readonly code: string;
|
|
6
|
+
constructor(code: string, message: string);
|
|
7
|
+
}
|
|
8
|
+
export declare function canonicalMarket(market: string): string;
|
|
9
|
+
export declare function validateAutomationGuardrails(value: unknown): AutomationGuardrails;
|
|
10
|
+
export declare function resolveAutomationGuardrails(exported: AutomationGuardrailsExport, context: AutomationGuardrailContext): AutomationGuardrails;
|
|
11
|
+
export interface GuardrailedClientOptions {
|
|
12
|
+
policy: AutomationGuardrails;
|
|
13
|
+
rawClient: HyperliquidClient;
|
|
14
|
+
log: AutomationLogger;
|
|
15
|
+
onViolation?: (error: GuardrailViolation, method: string, args: unknown[]) => void;
|
|
16
|
+
}
|
|
17
|
+
/** Wrap a client so every public write method crosses the validated policy boundary. */
|
|
18
|
+
export declare function createGuardrailedClient(executionClient: HyperliquidClient, options: GuardrailedClientOptions): HyperliquidClient;
|
|
19
|
+
//# sourceMappingURL=guardrails.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardrails.d.ts","sourceRoot":"","sources":["../../scripts/auto/guardrails.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,KAAK,EACV,0BAA0B,EAC1B,oBAAoB,EACpB,0BAA0B,EAC1B,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,oBAAoB,aAQ/B,CAAC;AAiBH,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAK1C;AAgCD,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAOtD;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,CAuDjF;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,0BAA0B,EACpC,OAAO,EAAE,0BAA0B,GAClC,oBAAoB,CAUtB;AAuTD,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,GAAG,EAAE,gBAAgB,CAAC;IACtB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACpF;AAED,wFAAwF;AACxF,wBAAgB,uBAAuB,CACrC,eAAe,EAAE,iBAAiB,EAClC,OAAO,EAAE,wBAAwB,GAChC,iBAAiB,CA6NnB"}
|