import {z} from 'zod' export type ManualOrderIndicator = 'MANUAL_ORDER_INDICATOR_MANUAL' | 'MANUAL_ORDER_INDICATOR_AUTOMATED'; export type Amount = {value: unknown, currency: string}; export type SlippageTolerance = {currentPrice?: Amount | undefined, bips?: (number | null) | undefined, ticks?: (number | null) | undefined}; export type ClosePositionOrderRequest = {marketSlug: string, manualOrderIndicator?: ManualOrderIndicator | undefined, synchronousExecution?: boolean | undefined, maxBlockTime?: unknown | undefined, slippageTolerance?: SlippageTolerance | undefined}; export type CreateApiV1OrderClosePositionArgs = {body: ClosePositionOrderRequest}; export type CreateApiV1OrderClosePositionOptions = {baseUrl?: string | undefined, XPMAccessKey?: string | undefined, XPMTimestamp?: string | undefined, XPMSignature?: string | undefined, fetch?: typeof fetch | undefined}; export const orderType = z.enum(["ORDER_TYPE_MARKET_TO_LIMIT", "ORDER_TYPE_LIMIT", "ORDER_TYPE_STOP", "ORDER_TYPE_STOP_LIMIT"]); export const side = z.enum(["SIDE_BUY", "SIDE_SELL"]); export const timeInForce = z.enum(["TIME_IN_FORCE_DAY", "TIME_IN_FORCE_GOOD_TILL_CANCEL", "TIME_IN_FORCE_IMMEDIATE_OR_CANCEL", "TIME_IN_FORCE_GOOD_TILL_TIME", "TIME_IN_FORCE_FILL_OR_KILL"]); export const orderState = z.enum(["ORDER_STATE_PARTIALLY_FILLED", "ORDER_STATE_FILLED", "ORDER_STATE_CANCELED", "ORDER_STATE_REPLACED", "ORDER_STATE_REJECTED", "ORDER_STATE_EXPIRED", "ORDER_STATE_PENDING_NEW", "ORDER_STATE_PENDING_REPLACE", "ORDER_STATE_PENDING_CANCEL", "ORDER_STATE_PENDING_RISK"]); export const selfMatchPreventionInstruction = z.enum(["SELF_MATCH_PREVENTION_INSTRUCTION_REJECT_AGGRESSOR", "SELF_MATCH_PREVENTION_INSTRUCTION_CANCEL_RESTING", "SELF_MATCH_PREVENTION_INSTRUCTION_REMOVE_BOTH"]); export const orderCapacity = z.enum(["ORDER_CAPACITY_AGENCY", "ORDER_CAPACITY_PRINCIPAL", "ORDER_CAPACITY_PROPRIETARY", "ORDER_CAPACITY_INDIVIDUAL", "ORDER_CAPACITY_RISKLESS_PRINCIPAL", "ORDER_CAPACITY_AGENT_FOR_OTHER_MEMBER"]); export const manualOrderIndicator = z.enum(["MANUAL_ORDER_INDICATOR_MANUAL", "MANUAL_ORDER_INDICATOR_AUTOMATED"]); export const order = z.object({id: z.string().optional(), type: orderType.optional(), side: side.optional(), orderQty: z.string().optional(), symbol: z.string().optional(), clordId: z.string().optional(), timeInForce: timeInForce.optional(), account: z.string().optional(), cumQty: z.string().optional(), avgPx: z.string().optional(), leavesQty: z.string().optional(), state: orderState.optional(), participant: z.string().optional(), price: z.string().optional(), insertTime: z.string().optional(), stopPrice: z.string().optional(), minQty: z.string().optional(), createTime: z.string().optional(), allOrNone: z.boolean().optional(), crossId: z.string().optional(), hostCrossId: z.string().optional(), submittingParticipant: z.string().optional(), clientAccountId: z.string().optional(), clientParticipantId: z.string().optional(), parentOrderId: z.string().optional(), commissionsBasisPoints: z.string().optional(), participateDontInitiate: z.boolean().optional(), cashOrderQty: z.string().optional(), strictLimit: z.boolean().optional(), goodTillTime: z.string().optional(), bestLimit: z.boolean().optional(), immediatelyExecutableLimit: z.boolean().optional(), lastTradeId: z.string().optional(), commissionNotionalTotalCollected: z.string().optional(), selfMatchPreventionInstruction: selfMatchPreventionInstruction.optional(), orderCapacity: orderCapacity.optional(), ignorePriceValidityChecks: z.boolean().optional(), lastTransactTime: z.string().optional(), makerCommissionsBasisPoints: z.string().optional(), manualOrderIndicator: manualOrderIndicator.optional(), fractionalQuantityScale: z.string().optional(), priceToQuantityFilled: z.record(z.string(), z.string()).optional()}); export const executionType = z.enum(["EXECUTION_TYPE_PARTIAL_FILL", "EXECUTION_TYPE_FILL", "EXECUTION_TYPE_CANCELED", "EXECUTION_TYPE_REPLACE", "EXECUTION_TYPE_REJECTED", "EXECUTION_TYPE_EXPIRED", "EXECUTION_TYPE_DONE_FOR_DAY"]); export const ordRejectReason = z.enum(["ORD_REJECT_REASON_UNKNOWN_SYMBOL", "ORD_REJECT_REASON_EXCHANGE_CLOSED", "ORD_REJECT_REASON_INCORRECT_QUANTITY", "ORD_REJECT_REASON_INVALID_PRICE_INCREMENT", "ORD_REJECT_REASON_INCORRECT_ORDER_TYPE", "ORD_REJECT_REASON_PRICE_OUT_OF_BOUNDS", "ORD_REJECT_REASON_NO_LIQUIDITY"]); export const legPrice = z.object({symbol: z.string().optional(), anchor: z.boolean().optional(), px: z.string().optional(), qty: z.string().optional(), side: z.string().optional(), referencePx: z.string().optional()}); export const unsolicitedCxlReason = z.enum(["UNSOLICITED_CXL_REASON_CONNECTION_LOSS", "UNSOLICITED_CXL_REASON_LOGOUT", "UNSOLICITED_CXL_REASON_EXCHANGE_OPTION", "UNSOLICITED_CXL_REASON_OTHER"]); export const date = z.object({year: z.number().int().optional(), month: z.number().int().optional(), day: z.number().int().optional()}); export const execution = z.object({id: z.string().optional(), order: order.optional(), lastShares: z.string().optional(), lastPx: z.string().optional(), type: executionType.optional(), text: z.string().optional(), orderRejectReason: ordRejectReason.optional(), transactTime: z.string().optional(), legPrices: z.array(legPrice).optional(), tradeId: z.string().optional(), aggressor: z.boolean().optional(), commissionNotionalCollected: z.string().optional(), unsolicitedCancelReason: unsolicitedCxlReason.optional(), traceId: z.string().optional(), commissionSpreadPx: z.string().optional(), transactTradeDate: date.optional()}); export const closePositionOrderResponse = z.object({id: z.string().optional(), executions: z.array(execution).optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Close Position Order * * POST /v1/order/close-position */ export const createApiV1OrderClosePosition = async (args: CreateApiV1OrderClosePositionArgs, options?: CreateApiV1OrderClosePositionOptions) => { const {baseUrl = "https://api.polymarket.us", fetch: fetchFn = fetch, XPMAccessKey, XPMTimestamp, XPMSignature} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (XPMAccessKey !== undefined) headers.set("X-PM-Access-Key", XPMAccessKey) if (XPMTimestamp !== undefined) headers.set("X-PM-Timestamp", XPMTimestamp) if (XPMSignature !== undefined) headers.set("X-PM-Signature", XPMSignature) const url = `${baseUrl.replace(/\/+$/, '')}/v1/order/close-position${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(closePositionOrderResponse, await res.json()) };