Repository Public
1/**2 * Shapes the Futures terminal codes against: the core models are the repository's own (type-only imports, erased at build), the3 * route answers follow the table "API contract (wave 2: read-only and paper)" of docs/v4/DERIVATIVES-ARCHITECTURE.md.4 */5import type { DecStr } from '../../../../packages/derivatives/src/decimal.ts';6import type { AccountState, Book, Candle, Fill, FundingPayment, Instrument, Order, OrderRequest, Position, PublicTrade, Ticker, VenueId } from '../../../../packages/derivatives/src/models.ts';7import type { AccountMode, RiskCode, RiskPolicy, RiskResult } from '../../../../packages/derivatives/src/risk.ts';8import type { Capabilities } from '../../../../packages/derivatives/src/venue.ts';910export type { AccountMode, AccountState, Book, Candle, Capabilities, DecStr, Fill, FundingPayment, Instrument, Order, OrderRequest, Position, PublicTrade, RiskCode, RiskPolicy, RiskResult, Ticker, VenueId };1112export const INTERVALS = ['1m', '5m', '15m', '1h', '4h', '1d'] as const;13export type Interval = (typeof INTERVALS)[number];14export const INTERVAL_MS: Record<Interval, number> = { '1m': 60_000, '5m': 300_000, '15m': 900_000, '1h': 3_600_000, '4h': 14_400_000, '1d': 86_400_000 };1516export type VenueStatus = 'ok' | 'degraded' | 'down';17export interface VenueInfo { id: VenueId; name: string; network: string; capabilities: Capabilities; status: VenueStatus; lastOkAt: number | null; restriction: string | null;18 /** can a paper account exist there (the backend sends it; derived when absent, see `paperAllowed`) */ paper?: boolean; /** false on GMX */ orderBook?: boolean; lastError?: string | null }19export interface VenueReadError { venue: string; message: string }2021/** what GMX has instead of a book (packages/derivatives/src/venues/gmx/adapter.ts, `GmxLiquidity`); every field optional here: the panel shows what it gets */22export interface Liquidity {23 openInterestLongUsd?: DecStr; openInterestShortUsd?: DecStr; maxOpenInterestLongUsd?: DecStr; maxOpenInterestShortUsd?: DecStr;24 availableLiquidityLongUsd?: DecStr; availableLiquidityShortUsd?: DecStr; capacityLongUsd?: DecStr; capacityShortUsd?: DecStr;25 /** per hour, fraction; positive = the side RECEIVES, negative = the side PAYS */26 fundingRateLongPerHour?: DecStr; fundingRateShortPerHour?: DecStr; borrowingRateLongPerHour?: DecStr; borrowingRateShortPerHour?: DecStr; netRateLongPerHour?: DecStr; netRateShortPerHour?: DecStr;27 priceImpact?: { factorPositive?: DecStr; factorNegative?: DecStr; exponentPositive?: DecStr; exponentNegative?: DecStr; maxFactorPositive?: DecStr; maxFactorNegative?: DecStr };28 positionFeeFactor?: { balanceImproved?: DecStr; balanceNotImproved?: DecStr };29 oracleMin?: DecStr; oracleMax?: DecStr; ts?: number;30}31export interface Market { instrument: Instrument; ticker: Ticker; book: Book | null; liquidity: Liquidity | null; trades: PublicTrade[]; errors: { book?: string; trades?: string; liquidity?: string } }32export interface FundingHistory { history: { ts: number; rate: DecStr }[]; intervalSec: number }3334export interface CompareRow { venue: VenueId; instrument: string; mark: DecStr; index: DecStr | null;35 /** per hour, normalised: what longs pay (negative = longs receive) */ funding: DecStr | null; /** the venue's own figure and interval */ fundingVenue: { rate: DecStr | null; intervalSec: number | null };36 spreadBps: DecStr | null; depthUsd1pct: DecStr | null; depthBidUsd1pct: DecStr | null; depthAskUsd1pct: DecStr | null; restriction: string | null; takerFeeBps: DecStr | null; maxLeverage: DecStr; collateral: string; settlement: string; notes: string[] }3738export interface DerivAccount { id: string; venue: VenueId; network: string; kind: 'paper' | 'venue'; mode: AccountMode; label: string; policy: RiskPolicy;39 state: AccountState; positions: Position[]; openOrders: Order[]; initialCollateral?: DecStr;40 settings?: { leverage: DecStr; leverageByInstrument: Record<string, DecStr>; takerFeeRate: DecStr; makerFeeRate: DecStr; maintenanceMarginFraction: DecStr };41 totals?: { realizedPnl: DecStr; feesPaid: DecStr; fundingNet: DecStr; liquidations: number } }42export interface RiskEvent { id: string; ts: number; kind: string; /** risk code of a refusal, when there is one */ code: string | null; instrument: string | null; detail: string }43export interface EquityPoint { ts: number; equity: DecStr }44export interface AccountDetail extends DerivAccount { orders: Order[]; fills: Fill[]; funding: FundingPayment[]; riskEvents: RiskEvent[]; equityHistory: EquityPoint[] }4546export interface EstimateValue { value: DecStr | null; source: 'estimate'; method: string }47export interface OrderEstimate { notional: DecStr; initialMargin: DecStr; fee: DecStr; avgFillPrice: DecStr | null; slippageBps: DecStr | null; liquidationPrice: EstimateValue | null; freeCollateralAfter: DecStr;48 filledSize?: DecStr; restingSize?: DecStr; /** what the paper engine would answer */ status?: Order['status']; rejectReason?: string | null; leverage?: DecStr; /** worst price the server derived */ price?: DecStr | null }49export interface Preview { risk: RiskResult; estimate: OrderEstimate | null; request: OrderRequest | null }50/** body of preview / place: an OrderRequest without clientId, plus the leverage to use on this instrument */51export type OrderBody = Omit<OrderRequest, 'clientId'> & { leverage?: DecStr; /** market orders with `price: null`: the server derives the worst price from the book (1–500) */ slippageBps?: number };52export interface Placed { order: Order; fills: Fill[] }53export interface Watch { state: AccountState; positions: Position[]; openOrders: Order[] }5455export type StreamStatus = 'connected' | 'reconnecting' | 'stale';56export const instrumentId = (venue: string, symbol: string) => `${venue}:${symbol}`;57export const venueOf = (id: string) => id.slice(0, Math.max(0, id.indexOf(':'))) as VenueId;58