Skip to content
markpaper

src/markets/types.ts

v0.2.0 · 3.1 KB

Download file
// Types of the `symbols` query and the decoded perp product.

/** Order types of the venue (appendix bits 10..9): 0 DEFAULT (GTC limit), 1 IOC, 2 FOK, 3 POST_ONLY. */
export type OrderType = 'default' | 'ioc' | 'fok' | 'post_only';

/**
 * `trading_status` values seen in `symbols`. `live` / `post_only` / `not_tradable` were observed live
 * (2026-09-10/11); `reduce_only` / `soft_reduce_only` come from documentation only.
 */
export type TradingStatus = 'live' | 'post_only' | 'reduce_only' | 'soft_reduce_only' | 'not_tradable';

export const TRADING_STATUSES: readonly TradingStatus[] = [
  'live',
  'post_only',
  'reduce_only',
  'soft_reduce_only',
  'not_tradable',
];

/** Raw shape of one `symbols` entry as the gateway sends it (all numbers are x18 strings). */
export interface RawSymbol {
  type: 'perp' | 'spot';
  product_id: number;
  symbol: string;
  price_increment_x18: string;
  size_increment: string;
  min_size: string;
  maker_fee_rate_x18?: string;
  taker_fee_rate_x18?: string;
  long_weight_initial_x18: string;
  long_weight_maintenance_x18?: string;
  max_open_interest_x18?: string | null;
  trading_status: string;
  isolated_only?: boolean;
}

/** Raw `data` of `{type:'symbols'}`: an OBJECT keyed by symbol, not an array. */
export interface RawSymbolsResponse {
  symbols: Record<string, RawSymbol>;
}

/** One decoded perp product. Exact grid values are x18 bigints; doubles are for display and rough maths. */
export interface PerpProduct {
  /** Coin name without the `-PERP` suffix: `'BTC'`, `'INTC'`. */
  readonly coin: string;
  /** Venue symbol, equal to the key in `symbols`: `'BTC-PERP'`. */
  readonly symbol: string;
  /** Product id; also the `verifyingContract` of `place_order` signatures. */
  readonly productId: number;
  /** Tick (`price_increment_x18`). */
  readonly tickX18: bigint;
  /** Lot (`size_increment`, x18 despite the missing suffix). */
  readonly lotX18: bigint;
  /** Minimum notional in quote units (`min_size`, x18): $100 on every market as of 2026-09. */
  readonly minSizeX18: bigint;
  readonly makerFeeRateX18: bigint | null;
  readonly takerFeeRateX18: bigint | null;
  readonly longWeightInitialX18: bigint;
  readonly longWeightMaintenanceX18: bigint | null;
  readonly maxOpenInterestX18: bigint | null;
  /** Known status, or the raw string when the venue introduced a new one. */
  readonly tradingStatus: TradingStatus | (string & {});
  readonly isolatedOnly: boolean;
  /** Tick as a double. */
  readonly tick: number;
  /** Lot as a double. */
  readonly lot: number;
  /** Minimum notional as a double (USDT0). */
  readonly minNotionalUsd: number;
  /** `long_weight_initial` as a fraction in (0, 1). */
  readonly longWeightInitial: number;
  /** Effective maximum leverage implied by the weight (see `maxLeverageFromWeights`). */
  readonly maxLeverage: number;
}

/** Decoded universe keyed by coin (`'BTC'`), plus a product-id index. */
export interface PerpUniverse {
  readonly byCoin: ReadonlyMap<string, PerpProduct>;
  readonly byProductId: ReadonlyMap<number, PerpProduct>;
  /** Symbols of spot entries that were skipped. */
  readonly skippedSpot: readonly string[];
}
All files