What
The Scrypt FIX API documents an OrdType that is not in the WebSocket/AsyncAPI spec:
40 OrdType ... A = LimitAllIn, requested price/size includes fees
(FIX PDF, "New Order Single" message, Tag 40)
Confirmed by Scrypt FAQ phrasing ("The price you see is what you get") — an order placed with OrdType: A treats the submitted LIMIT Price as the all-in execution price including the spread-embedded commission. The venue will not fill above (BUY) or below (SELL) that bound, fees included.
If accepted over our WebSocket connection too, this is the architecturally correct replacement for the applyPriceCap workaround introduced in #3738. Instead of clamping the LIMIT to reference × (1 ± maxDeviation) and hoping Scrypt's embedded spread doesn't push the effective price past the cap, LimitAllIn makes the cap definitionally binding.
Why this matters
Today's applyPriceCap (in ScryptService after #3738) bounds the quoted price, not the effective cost. If Scrypt's quote moves below the cap but the embedded commission pushes the real fill above what the cap was meant to express, we silently overpay — exactly the 2026-05-21 failure mode #3738 is designed to prevent. LimitAllIn closes that gap.
Open questions to answer in sandbox first
- Does the WebSocket accept
OrdType: "LimitAllIn" (or "A")? The AsyncAPI spec only enumerates [Market, Limit, RFQ]. Send a test order on wss://demo.scrypt.swiss/ws/v1 and observe the ExecutionReport — accepted, rejected, or silently downgraded?
- If accepted, does the venue actually reject fills past the all-in price, or does it just target that price like a normal LIMIT? The FIX doc is unambiguous ("includes fees") but verify empirically.
Price semantics: same quote-per-base convention as regular Limit, or different? Order State Change Matrices in the FIX PDF should clarify.
- OrderQty interpretation: still in base currency, or in
Currency (field 15) terms? FIX doc says "requested price/size includes fees" — does "size includes fees" mean the venue deducts fee from the filled quantity?
Currency (FIX Tag 15): optional field defaulting to the base currency. Worth testing both base and quote currencies as the requested size unit for LimitAllIn — different from regular Limit?
- Cumulative fee reporting: FIX surfaces
CumFee (Tag 4016) and CumAmt (Tag 4015) on ExecutionReport. The WebSocket AsyncAPI spec exposes per-fill LastFee + FeeCurrency. Verify both paths populate consistently for LimitAllIn fills.
Implementation sketch (only after sandbox confirms)
// ScryptOrderType enum (scrypt.dto.ts): add LIMIT_ALL_IN = 'LimitAllIn'
// ScryptService.sell — when priceCap is provided, prefer LimitAllIn over plain Limit:
private async placeAndReturnId(
symbol: string,
side: ScryptOrderSide,
orderQty: number,
price: number,
allIn = false,
): Promise<string> {
const ordType = allIn ? ScryptOrderType.LIMIT_ALL_IN : ScryptOrderType.LIMIT;
// ...
}
// applyPriceCap returns the cap value directly (not min/max of orderbook),
// because the LimitAllIn cap is binding by definition.
Risks / what to watch
Acceptance criteria
References
What
The Scrypt FIX API documents an
OrdTypethat is not in the WebSocket/AsyncAPI spec:Confirmed by Scrypt FAQ phrasing ("The price you see is what you get") — an order placed with
OrdType: Atreats the submitted LIMITPriceas the all-in execution price including the spread-embedded commission. The venue will not fill above (BUY) or below (SELL) that bound, fees included.If accepted over our WebSocket connection too, this is the architecturally correct replacement for the
applyPriceCapworkaround introduced in #3738. Instead of clamping the LIMIT toreference × (1 ± maxDeviation)and hoping Scrypt's embedded spread doesn't push the effective price past the cap,LimitAllInmakes the cap definitionally binding.Why this matters
Today's
applyPriceCap(inScryptServiceafter #3738) bounds the quoted price, not the effective cost. If Scrypt's quote moves below the cap but the embedded commission pushes the real fill above what the cap was meant to express, we silently overpay — exactly the 2026-05-21 failure mode #3738 is designed to prevent.LimitAllIncloses that gap.Open questions to answer in sandbox first
OrdType: "LimitAllIn"(or"A")? The AsyncAPI spec only enumerates[Market, Limit, RFQ]. Send a test order onwss://demo.scrypt.swiss/ws/v1and observe theExecutionReport— accepted, rejected, or silently downgraded?Pricesemantics: samequote-per-baseconvention as regular Limit, or different? Order State Change Matrices in the FIX PDF should clarify.Currency(field 15) terms? FIX doc says "requested price/size includes fees" — does "size includes fees" mean the venue deducts fee from the filled quantity?Currency(FIX Tag 15): optional field defaulting to the base currency. Worth testing both base and quote currencies as the requested size unit forLimitAllIn— different from regular Limit?CumFee(Tag 4016) andCumAmt(Tag 4015) on ExecutionReport. The WebSocket AsyncAPI spec exposes per-fillLastFee+FeeCurrency. Verify both paths populate consistently forLimitAllInfills.Implementation sketch (only after sandbox confirms)
Risks / what to watch
LimitAllInit might fall back to plain Limit without telling us — undermining the safety guarantee. Always assert the ExecutionReport'sOrdTypeechoes our request.OrderQtydifferently underLimitAllIn, our amount-conversion math (scrypt.service.ts:284-289) needs adjusting.Acceptance criteria
OrdType: "LimitAllIn"(or doesn't)OrdTypeenum + service-level opt-in for the LM adapterScryptAdapterswitchessellIfDeficit/sell/buyto useLimitAllInwhen apriceCapis in effect; documentation in the adapter and the docs READMEReferences
src/integration/exchange/docs/scrypt-fix-api.pdf, "New Order Single" section, Tag 40LimitAllIn):src/integration/exchange/docs/scrypt-asyncapi.yaml:3145LimitAllInif available over WS