Skip to content

Commit 785ff8c

Browse files
authored
feat(perps): [perps-controller] Add Chase, TWAP, and Scale order types (#9832)
## Explanation `@metamask/perps-controller` supported six order types — `market`, `limit`, and the four trigger placements — all of which resolve to a single order submitted through one code path. Chase, TWAP and Scale are execution *strategies*: one request expands into a schedule of orders, and each needs a different submission path, a different cancellation path, and rules of its own. None of that was expressible. This adds `twap`, `scale` and `chase` to `OrderType`, with the parameters, validation, placement and cancellation each needs. **Protocol research (the ticket's open question).** Answered from the SDK the package already depends on, `@nktkas/hyperliquid@0.33.1`: TWAP **is** native (`twapOrder` / `twapCancel`, with their own endpoints); Scale is **not** — it is a batch of ordinary limit orders; Chase is **not** — no such action exists anywhere in the SDK, so it is emulated client-side. The SDK schema also pins the TWAP window to a whole number of minutes in `[5, 1440]`, stricter than the ticket's "twapDuration > 0", so validation enforces the real bound. **What each placement does.** - **TWAP** is submitted through the venue's TWAP action rather than the order book, and returns the venue's TWAP id. Cancelling it uses the TWAP cancel endpoint, never the order-book cancel. - **Scale** fans out `scaleNumOrders` limit orders on an inclusive ladder between `scaleMinPrice` and `scaleMaxPrice`, submitted as one batch so the ladder rests together or fails together. Sizes are split in whole units of the asset's size grid, so the rungs sum to exactly the submitted size. Children come back as `OrderResult.childOrderIds`; the returned handle cancels all of them at once. - **Chase** rests a post-only order at the near touch and returns a session handle immediately; a background tick re-prices it as the touch moves, stopping at the repricing cap, at the window deadline, when the order leaves the book, on cancel, or on `disconnect()`. **Notable API effects.** `OrderType` is a wider union, which is breaking in the same way the trigger types were in 11.0.0: consumer signatures that narrow it back to a smaller set must widen. `OrderParams` gains eight optional strategy fields, `OrderResult` gains `childOrderIds`, and `CancelOrderParams` gains an optional `orderType` that selects the cancellation path — omitting it, which every existing caller does, keeps today's behaviour exactly. Invalid strategy parameters (inverted scale range, out-of-range TWAP duration, a strategy field on a non-strategy order, a limit price on a strategy) are rejected with a typed `PERPS_ERROR_CODES` value before any network call. The public model stays provider-agnostic — no venue vocabulary reaches `OrderParams`, `OrderResult` or `CancelOrderParams`. The one genuinely venue-specific constant is named for its venue, `HYPERLIQUID_TWAP_LIMITS`, beside the existing `HYPERLIQUID_ORDER_LIMITS`. One incidental fix: `TriggerOrderType` was `Exclude<OrderType, 'market' | 'limit'>`, so the three new members would have been silently absorbed into the trigger union and started demanding a trigger price. It is now spelled out. The resolved type is unchanged for existing consumers. **Validation.** 108 new unit tests across three suites, driving the real provider against a stubbed exchange client and asserting the exact actions submitted — that a TWAP reaches the TWAP action and not the order action, that its cancel reaches the TWAP cancel endpoint and not the order cancel, the exact scale ladder prices and the size split, the post-only chase placement at the touch and its re-pricing loop, and that no exchange call is made for an invalid placement. The full package suite passes with coverage thresholds met, the root build emits the new symbols, and the six pre-existing order suites pass unmodified. A live read against HyperLiquid testnet confirms the controller still instantiates and reads positions, orders and account state with the widened union in place. **Follow-ups, deliberately out of scope.** Strategy-handle correlation is session-scoped (children remain cancellable via `childOrderIds` after a restart); TWAP progress is not surfaced in controller state, because the venue reports TWAPs through feeds the open-orders normalisation does not read; and strategy placements are refused on sub-exchange (HIP-3) markets, whose pre-order margin transfer and rollback are wired into the single-order submit path. ## References - https://consensyssoftware.atlassian.net/browse/TAT-3723 - Client follow-up: mobile/extension order forms need to send the new fields and to pass `orderType` when cancelling a strategy handle. UI for these order types is explicitly out of scope here. ## Checklist - [x] I've updated the test suite for new or updated code as appropriate - [x] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [x] I've communicated my changes to consumers by [updating changelogs for packages I've changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md) - [x] I've introduced [breaking changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md) in this PR and have prepared draft pull requests for clients and consumer packages to resolve them - The `OrderType` widening is breaking in the same way as the trigger types in 11.0.0 and is marked **BREAKING** in the changelog, but no client draft PRs are prepared yet: the client work is a separate ticket, and no consumer in this repo narrows `OrderType`. ## **Screenshots/Recordings** <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **High Risk** > Widens the public `OrderType` union (breaking) and adds new signed trading paths, including a client-side chase loop with disconnect/cancel races and concurrency limits. > > **Overview** > Adds **strategy order types** `twap`, `scale`, and `chase` to `OrderType`, so one `placeOrder` request can expand into an execution schedule instead of a single resting order. > > **TWAP** goes through HyperLiquid’s native TWAP action/cancel. **Scale** submits a batch limit ladder and tracks children under a group handle. **Chase** is emulated client-side: a post-only order rests one tick inside the spread and is cancel/replaced as the touch moves, bounded by interval, duration, and repricing caps. > > `OrderResult.orderId` is a strategy *handle* for these types, with exchange ids in `childOrderIds`. `CancelOrderParams.orderType` selects the strategy cancel path; omitting it keeps ordinary single-order cancel. `editOrder` rejects strategy edits. Invalid strategy params fail with new typed `PERPS_ERROR_CODES` before signing. > > Also **breaks** consumers that narrow `OrderType`, narrows single-order helpers/`closePosition` to `OrdinaryOrderType`, and spells out `TriggerOrderType` so the new types are not pulled into the trigger union. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 2a22d0e. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent f2cf82d commit 785ff8c

14 files changed

Lines changed: 6673 additions & 242 deletions

packages/perps-controller/CHANGELOG.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,53 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- **BREAKING:** Add strategy placement order types to `OrderType`: `twap`, `scale`, and `chase`, placeable through `placeOrder` alongside the existing `market`, `limit`, and trigger types ([#9832](https://github.com/MetaMask/core/pull/9832))
13+
- `OrderType` is a wider union again, so — exactly as for the trigger types added in 11.0.0 — any consumer signature that narrows it back to a smaller set no longer accepts a value typed `OrderType`. Such signatures must widen to `OrderType` or narrow explicitly at the call site.
14+
- A strategy placement expands one request into an execution schedule rather than a single resting order, so `OrderResult.orderId` carries a _handle_ — a venue TWAP id, or a client-generated group/session id — rather than an exchange order id. Its documentation says so; the individual exchange ids are in `childOrderIds`.
15+
- `twap` slices the size over `OrderParams.twapDuration` whole minutes, optionally randomizing slice timing with `OrderParams.twapRandomize`. On HyperLiquid it is submitted through the venue's own TWAP action, not the order book, and `HYPERLIQUID_TWAP_LIMITS` bounds the window to 5–1440 minutes.
16+
- `scale` fans out `OrderParams.scaleNumOrders` limit orders on an inclusive price ladder between `OrderParams.scaleMinPrice` and `OrderParams.scaleMaxPrice`, submitted as a single batch. Sizes are split in whole units of the asset's size grid, so the rungs sum to exactly the submitted size. The batch is not atomic — the venue can rest some rungs and reject others — so `OrderResult.submittedSize` reports only the rungs that actually rested.
17+
- The venue applies its minimum order value to what it receives, not to the strategy total: a `scale` ladder's notional must leave every submitted rung above the per-order minimum, and a `twap`'s total must clear the venue's own minimum TWAP size (`HYPERLIQUID_TWAP_LIMITS.MinNotionalUsd`). Both are rejected locally rather than by the exchange. The ladder check needs the asset's size grid, so it runs during placement — before anything is signed — rather than in `validateOrder`, which cannot see the grid and could only guess.
18+
- A `chase` verifies its order is still live whenever its own price stops showing on the book, so an order that fills without the loop noticing ends the session and releases its concurrency slot instead of holding both until the window closes.
19+
- A `chase` interrupted by `disconnect` resolves as a failure with `ORDER_CHASE_ABANDONED` rather than a success, because no strategy is running behind it. Interrupted anywhere before its submission it signs nothing at all. Interrupted while that submission is in flight — the one window it cannot check ahead of — it tries to take the order back before returning, through the client it signed with rather than one asked for after the teardown, so an account switch cannot strand it. That attempt is best-effort: the venue can refuse the cancel, and the transport underneath the client may already be closing. When it does not take, the order is reported in `OrderResult.childOrderIds`, where the ordinary single-order cancel can still reach it for as long as the provider signs as the account that placed it.
20+
- `chase` prices against a book with _every_ chase this provider is running on that side netted out, not only its own order. Two chases each netting only themselves would read the other as the external touch and improve on it in turn, walking each other across an unchanged market. Resting inside the spread makes the chase its own best bid or ask, so reading the raw book would show its own quote as the touch and stop it re-pricing.
21+
- At most `CHASE_ORDER_CONFIG.MaxActiveSessions` chases run at once, matching the venue's documented cap; a further placement is refused with `ORDER_CHASE_LIMIT_REACHED` before any signing setup or leverage change, and a placement reserves its slot for the round trips before its session registers so concurrent placements cannot overshoot.
22+
- `chase` re-prices by cancelling and re-placing, and sizes each replacement from what the cancelled order left unfilled — read after the cancel has landed, when no further fill can reach it — so a child that partially filled is not re-placed at the original size.
23+
- `chase` rests a post-only order one tick inside the spread — above the best bid for a buy, below the best ask for a sell, joining the touch when the spread is a single tick — and re-prices it as the touch moves, bounded by `OrderParams.chaseIntervalMs`, `OrderParams.chaseMaxDurationMs`, and `OrderParams.chaseMaxRepricings` (see the newly exported `CHASE_ORDER_CONFIG` for the defaults). No supported venue exposes a native chase action, so it is emulated client-side; the re-pricing loop is stopped by `cancelOrder` and by `disconnect`.
24+
- The params model stays provider-agnostic: no protocol vocabulary appears in `OrderParams`, so a second provider can map the same fields onto its own execution primitives.
25+
- **BREAKING:** Narrow `CalculateOrderPriceAndSizeParams.orderType` and `BuildOrdersArrayParams.orderType` to the new `OrdinaryOrderType` (`Exclude<OrderType, StrategyOrderType>`) ([#9832](https://github.com/MetaMask/core/pull/9832))
26+
- These helpers resolve a single order the exchange can be handed directly. A strategy placement derives its own prices and sizes and never reaches them; passing one would price a `chase` as a limit order it carries no price for, and serialize a `twap` or `scale` as an ordinary market order.
27+
- **BREAKING:** Narrow `ClosePositionParams.orderType` to `Exclude<OrderType, StrategyOrderType>` ([#9832](https://github.com/MetaMask/core/pull/9832))
28+
- `closePosition` has no path that executes a strategy placement and `ClosePositionParams` carries none of the fields one needs, so the strategy types are refused at the type level rather than at runtime. A consumer passing a value typed `OrderType` into this field must narrow it at the call site.
29+
- **BREAKING:** Add nineteen `PERPS_ERROR_CODES` entries covering strategy placement, editing and cancellation: `ORDER_STRATEGY_PARAMS_NOT_SUPPORTED`, `ORDER_STRATEGY_FIELD_UNSUPPORTED`, `ORDER_STRATEGY_MARKET_UNSUPPORTED`, `ORDER_STRATEGY_HANDLE_UNKNOWN`, `ORDER_STRATEGY_CANCEL_INCOMPLETE`, `ORDER_EDIT_STRATEGY_UNSUPPORTED`, `ORDER_TWAP_DURATION_REQUIRED`, `ORDER_TWAP_DURATION_INVALID`, `ORDER_TWAP_NOTIONAL_TOO_SMALL`, `ORDER_SCALE_RANGE_REQUIRED`, `ORDER_SCALE_RANGE_INVALID`, `ORDER_SCALE_COUNT_INVALID`, `ORDER_SCALE_SIZE_TOO_SMALL`, `ORDER_SCALE_NOTIONAL_TOO_SMALL`, `ORDER_CHASE_INTERVAL_INVALID`, `ORDER_CHASE_DURATION_INVALID`, `ORDER_CHASE_LIMIT_REACHED`, `ORDER_CHASE_ABANDONED`, and `ORDER_CHASE_TOUCH_UNAVAILABLE` ([#9832](https://github.com/MetaMask/core/pull/9832))
30+
- Like `EXCHANGE_ACCOUNT_NOT_FOUND` and the multi-sig codes in 11.0.0, this widens the exported `PerpsErrorCode` union, so consumers that key an exhaustive `Record<PerpsErrorCode, …>` stop compiling until they add an entry for every new code. Both first-party clients do: Mobile's `app/components/UI/Perps/utils/translatePerpsError.ts` and Extension's `ui/components/app/perps/utils/translate-perps-error.ts`.
31+
- These cover the rejections this package decides for itself: each is a typed code rather than an opaque exchange error, and none of them reaches the venue as a signed request. Most are decided before any request at all. The exceptions are the ladder's `ORDER_SCALE_SIZE_TOO_SMALL` and `ORDER_SCALE_NOTIONAL_TOO_SMALL`, which need the asset's size precision and so follow one read of its metadata, and `ORDER_CHASE_TOUCH_UNAVAILABLE`, which follows the order-book read — all still before anything is signed. A submission the venue itself rejects is not among them: as for an ordinary order, that surfaces through the provider's existing error mapping carrying the venue's own message. `ORDER_STRATEGY_CANCEL_INCOMPLETE` and `ORDER_CHASE_ABANDONED` describe what happened after a request and are not rejections at all.
32+
- What the non-parameter codes mean: `ORDER_STRATEGY_MARKET_UNSUPPORTED` — a strategy was requested on a market the provider cannot run it on (on HyperLiquid, a HIP-3 sub-exchange). `ORDER_EDIT_STRATEGY_UNSUPPORTED``editOrder` cannot modify a strategy placement. `ORDER_STRATEGY_HANDLE_UNKNOWN``cancelOrder` was given a strategy handle this provider does not hold. `ORDER_STRATEGY_CANCEL_INCOMPLETE` — a cancel left part of the placement resting, and the handle stays valid for a retry. `ORDER_CHASE_TOUCH_UNAVAILABLE` — the order book had no price on the side a chase must rest at. `ORDER_CHASE_LIMIT_REACHED` — the venue's cap on simultaneous chases is already in use. `ORDER_CHASE_ABANDONED` — the provider was torn down while a chase was being placed.
33+
- Add `CancelOrderParams.orderType`, which selects the cancellation path for a strategy handle: the venue's TWAP cancel action for `twap`, a batch cancel of every child for `scale`, and stopping the session plus cancelling its live order for `chase` ([#9832](https://github.com/MetaMask/core/pull/9832))
34+
- Omitting it — what every existing caller does — cancels a single resting order exactly as before.
35+
- A cancel that leaves part of a strategy resting returns `ORDER_STRATEGY_CANCEL_INCOMPLETE` and keeps the handle valid, so the caller can retry with it.
36+
- `editOrder` now rejects a strategy placement with `ORDER_EDIT_STRATEGY_UNSUPPORTED` instead of submitting it as an ordinary order modification ([#9832](https://github.com/MetaMask/core/pull/9832))
37+
- A strategy placement is not a single resting order, so there is nothing to rewrite: the edit would have gone through as a plain market/limit modification and quietly dropped the TWAP schedule, the ladder, or the chase loop. Cancel by the strategy handle and place again.
38+
- A cancel refused because the order had already filled or been cancelled now completes rather than reporting `ORDER_STRATEGY_CANCEL_INCOMPLETE` ([#9832](https://github.com/MetaMask/core/pull/9832))
39+
- The venue answers a cancel it cannot match with a rejection, but nothing of that order is resting, which is what the caller asked for. Only a rejection that leaves the order on the book keeps the strategy handle open for a retry.
40+
- Add `OrderResult.childOrderIds`, the exchange ids a strategy placement expanded into ([#9832](https://github.com/MetaMask/core/pull/9832))
41+
- For a `scale` ladder these stay valid — the rungs are placed once and never replaced — so a consumer that has lost the session-scoped handle can still cancel them through the existing batch cancel.
42+
- For a `chase` this is only the order resting at placement time. The strategy cancels and re-places as the touch moves, and each replacement's id is held in the session rather than reported here, so the value goes stale on the first re-price; cancel a live chase by its handle.
43+
- Add `OrderParams.twapDuration`, `OrderParams.twapRandomize`, `OrderParams.scaleMinPrice`, `OrderParams.scaleMaxPrice`, `OrderParams.scaleNumOrders`, `OrderParams.chaseIntervalMs`, `OrderParams.chaseMaxDurationMs`, and `OrderParams.chaseMaxRepricings` ([#9832](https://github.com/MetaMask/core/pull/9832))
44+
- Each field is required by the placement that owns it and rejected on every other one, so a stray field can never be silently dropped. A strategy placement also rejects `price`, `triggerPrice`, `timeInForce`, `clientOrderId`, and attached TP/SL, all of which the strategy decides for itself or cannot express — a TWAP action carries no client id, a scale ladder is many orders where a client id must be unique per order, and a chase replaces its order on every re-price.
45+
- Invalid parameters are rejected with a typed `PERPS_ERROR_CODES` value, and nothing invalid is ever signed; see the new error codes entry below for the full list and for which few are decided after a read rather than before any request.
46+
- Add `twap`, `scale` and `chase` to `PERPS_EVENT_VALUE.ORDER_TYPE`, which dashboards key on and which `TradingService` emits verbatim ([#9832](https://github.com/MetaMask/core/pull/9832))
47+
- Add the `StrategyOrderType` and `OrdinaryOrderType` types, plus `STRATEGY_ORDER_TYPES`, `isStrategyOrderType`, `SCALE_ORDER_COUNT`, `computeScalePriceLadder`, `splitScaleSizes`, `computeChaseQuotePrice`, `getPriceTick`, `CHASE_ORDER_CONFIG`, and `HYPERLIQUID_TWAP_LIMITS` ([#9832](https://github.com/MetaMask/core/pull/9832))
48+
49+
### Changed
50+
51+
- `getTriggerExecution` now reports `'limit'` for `scale` and `chase`, which rest limit orders on the book without carrying an `OrderParams.price`, and `'market'` for `twap`, whose suborders cross it ([#9832](https://github.com/MetaMask/core/pull/9832))
52+
- This is what decides the fee tier and the max order value, so a scale ladder and a chase are no longer quoted at the taker rate or held to the tighter market-order cap. `calculateFees` additionally quotes `chase` at the maker rate regardless of `isMaker`, because a post-only order can only fill as a maker.
53+
- `isLimitExecutionOrderType` is unchanged: it answers the narrower question of whether `OrderParams.price` carries a real limit price, which for a strategy placement it does not.
54+
- `TriggerOrderType` is now spelled out as `'stop_market' | 'stop_limit' | 'take_profit_market' | 'take_profit_limit'` instead of being derived as `Exclude<OrderType, 'market' | 'limit'>` ([#9832](https://github.com/MetaMask/core/pull/9832))
55+
- The resolved type is unchanged for existing consumers. Deriving it meant that any order type added to `OrderType` that was neither `market` nor `limit` was pulled into the trigger union automatically and started demanding a trigger price it had no concept of.
56+
1057
## [11.0.0]
1158

1259
### Added

packages/perps-controller/src/constants/eventNames.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,10 @@ export const PERPS_EVENT_VALUE = {
260260
STOP_LIMIT: 'stop_limit',
261261
TAKE_PROFIT_MARKET: 'take_profit_market',
262262
TAKE_PROFIT_LIMIT: 'take_profit_limit',
263+
// Strategy placements, likewise emitted verbatim.
264+
TWAP: 'twap',
265+
SCALE: 'scale',
266+
CHASE: 'chase',
263267
},
264268
ORDER_TYPE_CAPITALIZED: {
265269
MARKET: 'market',

packages/perps-controller/src/constants/perpsConfig.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,36 @@ export const ORDER_SLIPPAGE_CONFIG = {
113113
DefaultLimitSlippageBps: 100,
114114
} as const;
115115

116+
/**
117+
* Defaults and bounds for the emulated `chase` placement.
118+
*
119+
* No supported venue exposes a chase as an API action — HyperLiquid documents it
120+
* as running client-side — so the strategy is run here: a post-only order rests
121+
* one tick inside the spread and is cancelled and re-placed as the touch moves.
122+
* The poll floor and the repricing cap exist to keep a chase from turning into a
123+
* cancel/replace loop against a venue's rate limits. Protocol-agnostic — a
124+
* provider that gains a native chase ignores these entirely.
125+
*/
126+
export const CHASE_ORDER_CONFIG = {
127+
/** How often the touch is re-read when the caller does not say. */
128+
DefaultIntervalMs: 3000,
129+
/** Floor on the poll interval, whatever the caller asks for. */
130+
MinIntervalMs: 1000,
131+
/** How long a chase runs before it stops re-pricing and rests. */
132+
DefaultMaxDurationMs: 60_000,
133+
/** How many cancel/replace cycles a single chase may perform. */
134+
DefaultMaxRepricings: 20,
135+
/**
136+
* How many chases may run at once.
137+
*
138+
* HyperLiquid documents a cap of five simultaneously active chase orders. It
139+
* is a venue rule rather than controller policy, but it is spelled here
140+
* alongside the rest of the chase configuration because an emulated chase is
141+
* the only thing that can enforce it.
142+
*/
143+
MaxActiveSessions: 5,
144+
} as const;
145+
116146
/**
117147
* Bounds and step for the user-configurable max slippage preference (basis points).
118148
* Shared by the controller (`setMaxSlippage`) and UI (`slippageConfig.ts`).
@@ -252,6 +282,28 @@ export const TP_SL_CONFIG = {
252282
UsePositionBoundTpsl: true,
253283
} as const;
254284

285+
/**
286+
* Bounds applied to a HyperLiquid TWAP placement.
287+
*
288+
* The pinned HyperLiquid SDK (0.33.1) validates the TWAP duration as a safe
289+
* integer in `[5, 1440]` before signing, although the venue currently documents
290+
* a maximum of seven days (`10080` minutes). The controller exposes the SDK's
291+
* narrower cap until that dependency supports the venue limit, avoiding an
292+
* opaque SDK error. `MinNotionalUsd` is the venue's documented minimum *total*
293+
* order size for a TWAP, which it enforces instead of the per-order minimum —
294+
* its suborders are its own business.
295+
*
296+
* Carries the venue prefix, like `HYPERLIQUID_ORDER_LIMITS`, because these are
297+
* venue/SDK constraints rather than controller policy.
298+
*
299+
* From: https://hyperliquid.gitbook.io/hyperliquid-docs/trading/order-types
300+
*/
301+
export const HYPERLIQUID_TWAP_LIMITS = {
302+
MinDurationMinutes: 5,
303+
MaxDurationMinutes: 1440,
304+
MinNotionalUsd: 100,
305+
} as const;
306+
255307
/**
256308
* HyperLiquid order limits based on leverage
257309
* From: https://hyperliquid.gitbook.io/hyperliquid-docs/trading/contract-specifications

packages/perps-controller/src/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ export type {
158158
TradeConfiguration,
159159
OrderType,
160160
TriggerOrderType,
161+
StrategyOrderType,
162+
OrdinaryOrderType,
161163
OrderExecution,
162164
TriggerDirection,
163165
TpslLinkage,
@@ -437,10 +439,12 @@ export {
437439
WITHDRAWAL_CONSTANTS,
438440
VALIDATION_THRESHOLDS,
439441
ORDER_SLIPPAGE_CONFIG,
442+
CHASE_ORDER_CONFIG,
440443
MAX_SLIPPAGE_BOUNDS,
441444
PERFORMANCE_CONFIG,
442445
TP_SL_CONFIG,
443446
HYPERLIQUID_ORDER_LIMITS,
447+
HYPERLIQUID_TWAP_LIMITS,
444448
CLOSE_POSITION_CONFIG,
445449
MARGIN_ADJUSTMENT_CONFIG,
446450
DATA_LAKE_API_CONFIG,
@@ -482,12 +486,19 @@ export {
482486
} from './utils/index.js';
483487
export {
484488
TRIGGER_ORDER_TYPES,
489+
STRATEGY_ORDER_TYPES,
490+
SCALE_ORDER_COUNT,
485491
isTriggerOrderType,
492+
isStrategyOrderType,
486493
isLimitExecutionOrderType,
487494
getTriggerExecution,
488495
getTriggerDirection,
489496
buildTriggerOrderType,
490497
buildPositionTriggerOrderFromOrder,
498+
computeScalePriceLadder,
499+
computeChaseQuotePrice,
500+
getPriceTick,
501+
splitScaleSizes,
491502
} from './utils/index.js';
492503
export {
493504
adaptTriggerOrderTypeFromSDK,

0 commit comments

Comments
 (0)