@danielgroen/dxtrade-api 1.0.23 → 1.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants/brokers.ts","../src/constants/endpoints.ts","../src/constants/enums.ts","../src/constants/errors.ts","../src/domains/account/account.ts","../src/utils/cookies.ts","../src/utils/headers.ts","../src/utils/retry.ts","../src/utils/websocket.ts","../src/domains/assessments/assessments.ts","../src/domains/instrument/instrument.ts","../src/domains/ohlc/ohlc.ts","../src/domains/order/order.ts","../src/domains/symbol/symbol.ts","../src/domains/position/position.ts","../src/domains/session/session.ts","../src/client.ts"],"sourcesContent":["export const BROKER = {\n LARKFUNDING: \"https://trade.gooeytrade.com\",\n EIGHTCAP: \"https://trader.dx-eightcap.com\",\n FTMO: \"https://dxtrade.ftmo.com\",\n} as const;\n","function websocketQuery(atmosphereId?: string | null): string {\n const trackingId = atmosphereId ?? \"0\";\n return (\n `?X-Atmosphere-tracking-id=${trackingId}&X-Atmosphere-Framework=2.3.2-javascript` +\n `&X-Atmosphere-Transport=websocket&X-Atmosphere-TrackMessageSize=true` +\n `&Content-Type=text/x-gwt-rpc;%20charset=UTF-8&X-atmo-protocol=true` +\n `&sessionState=dx-new&guest-mode=false`\n );\n}\n\nexport const endpoints = {\n login: (base: string) => `${base}/api/auth/login`,\n\n switchAccount: (base: string, id: string) => `${base}/api/accounts/switch?accountId=${id}`,\n\n suggest: (base: string, text: string) => `${base}/api/suggest?text=${text}`,\n\n instrumentInfo: (base: string, symbol: string, tzOffset: number) =>\n `${base}/api/instruments/info?symbol=${symbol}&timezoneOffset=${tzOffset}&withExDividends=true`,\n\n submitOrder: (base: string) => `${base}/api/orders/single`,\n\n closePosition: (base: string) => `${base}/api/positions/close`,\n\n cancelOrder: (base: string, accountId: string, orderChainId: number) =>\n `${base}/api/orders/cancel?accountId=${accountId}&orderChainId=${orderChainId}`,\n\n assessments: (base: string) => `${base}/api/assessments`,\n\n websocket: (base: string, atmosphereId?: string | null) =>\n `wss://${base.split(\"//\")[1]}/client/connector` + websocketQuery(atmosphereId),\n\n tradeJournal: (base: string, params: { from: number; to: number }) =>\n `${base}/api/tradejournal?from=${params.from}&to=${params.to}`,\n\n tradeHistory: (base: string, params: { from: number; to: number }) =>\n `${base}/api/history?from=${params.from}&to=${params.to}&orderId=`,\n\n subscribeInstruments: (base: string) => `${base}/api/instruments/subscribeInstrumentSymbols`,\n\n charts: (base: string) => `${base}/api/charts`,\n};\n","export enum ORDER_TYPE {\n MARKET = \"MARKET\",\n LIMIT = \"LIMIT\",\n STOP = \"STOP\",\n}\n\nexport enum SIDE {\n BUY = \"BUY\",\n SELL = \"SELL\",\n}\n\nexport enum ACTION {\n OPENING = \"OPENING\",\n CLOSING = \"CLOSING\",\n}\n\nexport enum TIF {\n GTC = \"GTC\",\n DAY = \"DAY\",\n GTD = \"GTD\",\n}\n\nexport enum ERROR {\n NO_SESSION = \"NO_SESSION\",\n\n // Session\n LOGIN_FAILED = \"LOGIN_FAILED\",\n LOGIN_ERROR = \"LOGIN_ERROR\",\n CSRF_NOT_FOUND = \"CSRF_NOT_FOUND\",\n CSRF_ERROR = \"CSRF_ERROR\",\n ACCOUNT_SWITCH_ERROR = \"ACCOUNT_SWITCH_ERROR\",\n\n // Market data\n NO_SUGGESTIONS = \"NO_SUGGESTIONS\",\n SUGGEST_ERROR = \"SUGGEST_ERROR\",\n NO_SYMBOL_INFO = \"NO_SYMBOL_INFO\",\n SYMBOL_INFO_ERROR = \"SYMBOL_INFO_ERROR\",\n INSTRUMENTS_TIMEOUT = \"INSTRUMENTS_TIMEOUT\",\n INSTRUMENTS_ERROR = \"INSTRUMENTS_ERROR\",\n LIMITS_TIMEOUT = \"LIMITS_TIMEOUT\",\n LIMITS_ERROR = \"LIMITS_ERROR\",\n OHLC_TIMEOUT = \"OHLC_TIMEOUT\",\n OHLC_ERROR = \"OHLC_ERROR\",\n\n // Trading\n ORDER_ERROR = \"ORDER_ERROR\",\n ORDERS_TIMEOUT = \"ORDERS_TIMEOUT\",\n ORDERS_ERROR = \"ORDERS_ERROR\",\n CANCEL_ORDER_ERROR = \"CANCEL_ORDER_ERROR\",\n POSITION_CLOSE_ERROR = \"POSITION_CLOSE_ERROR\",\n POSITION_METRICS_TIMEOUT = \"POSITION_METRICS_TIMEOUT\",\n POSITION_METRICS_ERROR = \"POSITION_METRICS_ERROR\",\n\n // Account\n ACCOUNT_METRICS_TIMEOUT = \"ACCOUNT_METRICS_TIMEOUT\",\n ACCOUNT_METRICS_ERROR = \"ACCOUNT_METRICS_ERROR\",\n ACCOUNT_POSITIONS_TIMEOUT = \"ACCOUNT_POSITIONS_TIMEOUT\",\n ACCOUNT_POSITIONS_ERROR = \"ACCOUNT_POSITIONS_ERROR\",\n TRADE_JOURNAL_ERROR = \"TRADE_JOURNAL_ERROR\",\n TRADE_HISTORY_ERROR = \"TRADE_HISTORY_ERROR\",\n\n // Analytics\n ASSESSMENTS_ERROR = \"ASSESSMENTS_ERROR\",\n}\n\nexport enum WS_MESSAGE {\n ACCOUNT_METRICS = \"ACCOUNT_METRICS\",\n ACCOUNTS = \"ACCOUNTS\",\n AVAILABLE_WATCHLISTS = \"AVAILABLE_WATCHLISTS\",\n CHART_FEED_SUBTOPIC = \"chartFeedSubtopic\",\n INSTRUMENTS = \"INSTRUMENTS\",\n // INSTRUMENT_METRICS = \"INSTRUMENT_METRICS\",\n LIMITS = \"LIMITS\",\n MESSAGE = \"MESSAGE\",\n ORDERS = \"ORDERS\",\n POSITIONS = \"POSITIONS\",\n POSITION_METRICS = \"POSITION_METRICS\",\n POSITION_CASH_TRANSFERS = \"POSITION_CASH_TRANSFERS\",\n PRIVATE_LAYOUT_NAMES = \"PRIVATE_LAYOUT_NAMES\",\n SHARED_PROPERTIES_MESSAGE = \"SHARED_PROPERTIES_MESSAGE\",\n TRADE_STATUSES = \"TRADE_STATUSES\",\n USER_LOGIN_INFO = \"USER_LOGIN_INFO\",\n}\n\nexport namespace WS_MESSAGE {\n export enum SUBTOPIC {\n BIG_CHART_COMPONENT = \"BigChartComponentPresenter-4\",\n }\n}\n","export class DxtradeError extends Error {\n public code: string;\n\n constructor(code: string, message: string) {\n super(message);\n this.name = \"DxtradeError\";\n this.code = code;\n }\n}\n","import WebSocket from \"ws\";\nimport { WS_MESSAGE, ERROR, endpoints, DxtradeError } from \"@/constants\";\nimport { Cookies, parseWsData, shouldLog, debugLog, retryRequest, baseHeaders } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Account } from \".\";\n\nexport async function getAccountMetrics(ctx: ClientContext, timeout = 30_000): Promise<Account.Metrics> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.broker, ctx.atmosphereId);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(ERROR.ACCOUNT_METRICS_TIMEOUT, \"Account metrics timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.ACCOUNT_METRICS) {\n clearTimeout(timer);\n ws.close();\n const body = msg.body as { allMetrics: Account.Metrics };\n resolve(body.allMetrics);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(ERROR.ACCOUNT_METRICS_ERROR, `Account metrics error: ${error.message}`));\n });\n });\n}\n\nexport async function getTradeHistory(\n ctx: ClientContext,\n params: { from: number; to: number },\n): Promise<Account.TradeHistory[]> {\n ctx.ensureSession();\n\n try {\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.tradeHistory(ctx.broker, params),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n ctx.retries,\n );\n\n if (response.status === 200) {\n const setCookies = response.headers[\"set-cookie\"] ?? [];\n const incoming = Cookies.parse(setCookies);\n ctx.cookies = Cookies.merge(ctx.cookies, incoming);\n return response.data as Account.TradeHistory[];\n } else {\n ctx.throwError(ERROR.TRADE_HISTORY_ERROR, `Trade history failed: ${response.status}`);\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(ERROR.TRADE_HISTORY_ERROR, `Trade history error: ${message}`);\n }\n}\n\nexport async function getTradeJournal(ctx: ClientContext, params: { from: number; to: number }): Promise<any> {\n ctx.ensureSession();\n\n try {\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.tradeJournal(ctx.broker, params),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n ctx.retries,\n );\n\n if (response.status === 200) {\n const setCookies = response.headers[\"set-cookie\"] ?? [];\n const incoming = Cookies.parse(setCookies);\n ctx.cookies = Cookies.merge(ctx.cookies, incoming);\n return response.data;\n } else {\n ctx.throwError(ERROR.TRADE_JOURNAL_ERROR, `Login failed: ${response.status}`);\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(ERROR.TRADE_JOURNAL_ERROR, `Trade journal error: ${message}`);\n }\n}\n","export class Cookies {\n static parse(setCookieHeaders: string[]): Record<string, string> {\n const cookies: Record<string, string> = {};\n\n for (const cookie of setCookieHeaders) {\n const [nameValue] = cookie.split(\";\");\n const eqIndex = nameValue.indexOf(\"=\");\n if (eqIndex === -1) continue;\n const name = nameValue.slice(0, eqIndex).trim();\n const value = nameValue.slice(eqIndex + 1).trim();\n cookies[name] = value;\n }\n\n return cookies;\n }\n\n static serialize(cookies: Record<string, string>): string {\n return Object.entries(cookies)\n .map(([key, value]) => `${key}=${value}`)\n .join(\"; \");\n }\n\n static merge(existing: Record<string, string>, incoming: Record<string, string>): Record<string, string> {\n return { ...existing, ...incoming };\n }\n}\n","export function baseHeaders(): Record<string, string> {\n return {\n \"Content-Type\": \"application/json; charset=UTF-8\",\n \"Accept-Language\": \"en-US,en;q=0.9\",\n };\n}\n\nexport function authHeaders(csrf: string, cookieStr: string): Record<string, string> {\n return {\n ...baseHeaders(),\n \"X-CSRF-Token\": csrf,\n \"X-Requested-With\": \"XMLHttpRequest\",\n Accept: \"*/*\",\n Cookie: cookieStr,\n };\n}\n\nexport function cookieOnlyHeaders(cookieStr: string): Record<string, string> {\n return { Cookie: cookieStr };\n}\n","import axios, { type AxiosRequestConfig, type AxiosResponse, isAxiosError } from \"axios\";\n\nexport async function retryRequest(config: AxiosRequestConfig, retries = 3): Promise<AxiosResponse> {\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n return await axios(config);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n console.warn(`[dxtrade-api] Attempt ${attempt} failed: ${message}`, config.url);\n if (isAxiosError(error) && error.response?.status === 429) throw error;\n if (attempt === retries) throw error;\n await new Promise((res) => setTimeout(res, 1000 * attempt));\n }\n }\n throw new Error(\"[dxtrade-api] Failed after retries\");\n}\n","import { appendFileSync, writeFileSync } from \"fs\";\nimport type WebSocket from \"ws\";\nimport type { WsPayload } from \"./websocket.types\";\n\nexport type { WsPayload } from \"./websocket.types\";\n\nconst DEBUG_LOG = \"debug.log\";\n\nexport function shouldLog(msg: WsPayload | string, debug: boolean | string): boolean {\n if (!debug) return false;\n if (debug === true || debug === \"true\") return true;\n if (typeof msg === \"string\") return false;\n const filters = (debug as string).split(\",\").map((s) => s.trim().toUpperCase());\n return filters.includes(msg.type);\n}\n\nexport function debugLog(msg: WsPayload | string): void {\n appendFileSync(DEBUG_LOG, JSON.stringify(msg) + \"\\n\");\n}\n\nexport function clearDebugLog(): void {\n writeFileSync(DEBUG_LOG, \"\");\n}\n\nexport function parseAtmosphereId(data: WebSocket.Data): string | null {\n const raw = data.toString();\n const parts = raw.split(\"|\");\n if (parts.length >= 2 && /^[0-9a-f-]{36}$/.test(parts[1])) {\n return parts[1];\n }\n return null;\n}\n\nexport function parseWsData(data: WebSocket.Data): WsPayload | string {\n const raw = data.toString();\n const pipeIndex = raw.indexOf(\"|\");\n if (pipeIndex === -1) return raw;\n\n try {\n return JSON.parse(raw.slice(pipeIndex + 1)) as WsPayload;\n } catch {\n return raw;\n }\n}\n","import { endpoints, DxtradeError, ERROR } from \"@/constants\";\nimport { Cookies, authHeaders, retryRequest } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Assessments } from \".\";\n\nexport async function getAssessments(ctx: ClientContext, params: Assessments.Params): Promise<Assessments.Response> {\n ctx.ensureSession();\n\n try {\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.assessments(ctx.broker),\n data: {\n from: params.from,\n instrument: params.instrument,\n subtype: params.subtype ?? null,\n to: params.to,\n },\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n\n return response.data as Assessments.Response;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(ERROR.ASSESSMENTS_ERROR, `Error fetching assessments: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError, WS_MESSAGE, ERROR } from \"@/constants\";\nimport { Cookies, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Instrument } from \".\";\n\nexport async function getInstruments(\n ctx: ClientContext,\n params: Partial<Instrument.Info> = {},\n timeout = 30_000,\n): Promise<Instrument.Info[]> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.broker, ctx.atmosphereId);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(ERROR.INSTRUMENTS_TIMEOUT, \"Instruments request timed out\"));\n }, timeout);\n\n let instruments: Instrument.Info[] = [];\n let settleTimer: ReturnType<typeof setTimeout> | null = null;\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.INSTRUMENTS) {\n instruments.push(...(msg.body as Instrument.Info[]));\n\n // Reset settle timer on each batch — resolve once no more arrive\n if (settleTimer) clearTimeout(settleTimer);\n settleTimer = setTimeout(() => {\n clearTimeout(timer);\n ws.close();\n resolve(\n instruments.filter((instrument) => {\n for (const key in params) {\n if (params[key as keyof Instrument.Info] !== instrument[key as keyof Instrument.Info]) {\n return false;\n }\n }\n return true;\n }),\n );\n }, 0);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(ERROR.INSTRUMENTS_ERROR, `Instruments error: ${error.message}`));\n });\n });\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError, WS_MESSAGE, ERROR } from \"@/constants\";\nimport { Cookies, authHeaders, retryRequest, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { OHLC } from \".\";\n\nexport async function getOHLC(ctx: ClientContext, params: OHLC.Params, timeout = 30_000): Promise<OHLC.Bar[]> {\n ctx.ensureSession();\n\n const { symbol, resolution = 60, range = 432_000, maxBars = 3500, priceField = \"bid\" } = params;\n const wsUrl = endpoints.websocket(ctx.broker, ctx.atmosphereId);\n const cookieStr = Cookies.serialize(ctx.cookies);\n const headers = authHeaders(ctx.csrf!, cookieStr);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n const bars: OHLC.Bar[] = [];\n let putsSent = false;\n let initSettleTimer: ReturnType<typeof setTimeout> | null = null;\n let barSettleTimer: ReturnType<typeof setTimeout> | null = null;\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(ERROR.OHLC_TIMEOUT, \"OHLC data timed out\"));\n }, timeout);\n\n function cleanup() {\n clearTimeout(timer);\n if (initSettleTimer) clearTimeout(initSettleTimer);\n if (barSettleTimer) clearTimeout(barSettleTimer);\n ws.close();\n }\n\n async function sendPuts() {\n putsSent = true;\n try {\n await retryRequest(\n {\n method: \"PUT\",\n url: endpoints.subscribeInstruments(ctx.broker),\n data: { instruments: [symbol] },\n headers,\n },\n ctx.retries,\n );\n await retryRequest(\n {\n method: \"PUT\",\n url: endpoints.charts(ctx.broker),\n data: {\n chartIds: [],\n requests: [\n {\n aggregationPeriodSeconds: resolution,\n extendedSession: true,\n forexPriceField: priceField,\n id: 0,\n maxBarsCount: maxBars,\n range,\n studySubscription: [],\n subtopic: WS_MESSAGE.SUBTOPIC.BIG_CHART_COMPONENT,\n symbol,\n },\n ],\n },\n headers,\n },\n ctx.retries,\n );\n } catch (error: unknown) {\n cleanup();\n const message = error instanceof Error ? error.message : \"Unknown error\";\n reject(new DxtradeError(ERROR.OHLC_ERROR, `Error fetching OHLC data: ${message}`));\n }\n }\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n if (typeof msg === \"string\") return;\n\n // Wait for init burst to settle before sending PUTs\n if (!putsSent) {\n if (initSettleTimer) clearTimeout(initSettleTimer);\n initSettleTimer = setTimeout(() => sendPuts(), 1000);\n return;\n }\n\n // Collect chart bars\n const body = msg.body as Record<string, unknown>;\n if (body?.subtopic !== WS_MESSAGE.SUBTOPIC.BIG_CHART_COMPONENT) return;\n\n if (Array.isArray(body.data)) {\n bars.push(...(body.data as OHLC.Bar[]));\n }\n\n if (barSettleTimer) clearTimeout(barSettleTimer);\n if (body.snapshotEnd) {\n cleanup();\n resolve(bars);\n } else {\n barSettleTimer = setTimeout(() => {\n cleanup();\n resolve(bars);\n }, 2000);\n }\n });\n\n ws.on(\"error\", (error) => {\n cleanup();\n reject(new DxtradeError(ERROR.OHLC_ERROR, `OHLC WebSocket error: ${error.message}`));\n });\n });\n}\n","import crypto from \"crypto\";\nimport WebSocket from \"ws\";\nimport { endpoints, ORDER_TYPE, SIDE, ACTION, DxtradeError, ERROR } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport { Cookies, authHeaders, retryRequest, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport { getSymbolInfo } from \"../symbol/symbol\";\nimport type { Order, Message } from \".\";\n\nfunction createOrderListener(\n wsUrl: string,\n cookieStr: string,\n timeout = 30_000,\n debug: boolean | string = false,\n): { promise: Promise<Order.Update>; ready: Promise<void> } {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n let settled = false;\n\n const ready = new Promise<void>((resolve) => {\n ws.on(\"open\", resolve);\n });\n\n const promise = new Promise<Order.Update>((resolve, reject) => {\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n ws.close();\n reject(new Error(\"[dxtrade-api] Order update timed out\"));\n }, timeout);\n\n function done(err: Error | null, result?: Order.Update) {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n ws.close();\n if (err) reject(err);\n else resolve(result!);\n }\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, debug)) debugLog(msg);\n if (typeof msg === \"string\") return;\n\n // Trade log messages (fills and rejections come through here)\n if (msg.type === WS_MESSAGE.MESSAGE) {\n const messages = msg.body as Message.Entry[];\n const orderMsg = messages?.findLast?.(\n (m) => m.messageCategory === \"TRADE_LOG\" && m.messageType === \"ORDER\" && !m.historyMessage,\n );\n if (!orderMsg) return;\n\n const params = orderMsg.parametersTO as Message.OrderParams;\n if (params.orderStatus === \"REJECTED\") {\n const reason = params.rejectReason?.key ?? \"Unknown reason\";\n done(new Error(`[dxtrade-api] Order rejected: ${reason}`));\n } else if (params.orderStatus === \"FILLED\") {\n done(null, {\n orderId: params.orderKey,\n status: params.orderStatus,\n symbol: params.symbol,\n filledQuantity: params.filledQuantity,\n filledPrice: params.filledPrice,\n });\n }\n return;\n }\n\n // Order updates (also carry fills)\n if (msg.type === WS_MESSAGE.ORDERS) {\n const body = (msg.body as Order.Update[])?.[0];\n if (!body?.orderId) return;\n\n if (body.status === \"REJECTED\") {\n done(new Error(`[dxtrade-api] Order rejected: ${body.statusDescription ?? \"Unknown reason\"}`));\n } else if (body.status === \"FILLED\") {\n done(null, body);\n }\n }\n });\n\n ws.on(\"error\", (error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n ws.close();\n reject(new Error(`[dxtrade-api] WebSocket order listener error: ${error.message}`));\n });\n });\n\n return { promise, ready };\n}\n\nexport async function getOrders(ctx: ClientContext, timeout = 30_000): Promise<Order.Get[]> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.broker, ctx.atmosphereId);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(ERROR.ORDERS_TIMEOUT, \"Orders request timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.ORDERS) {\n clearTimeout(timer);\n ws.close();\n resolve(msg.body as Order.Get[]);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(ERROR.ORDERS_ERROR, `Orders error: ${error.message}`));\n });\n });\n}\n\nexport async function cancelOrder(ctx: ClientContext, orderChainId: number): Promise<void> {\n ctx.ensureSession();\n\n const accountId = ctx.accountId ?? ctx.config.accountId;\n if (!accountId) {\n ctx.throwError(ERROR.CANCEL_ORDER_ERROR, \"accountId is required to cancel an order\");\n }\n\n try {\n await retryRequest(\n {\n method: \"DELETE\",\n url: endpoints.cancelOrder(ctx.broker, accountId, orderChainId),\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message =\n error instanceof Error ? ((error as any).response?.data?.message ?? error.message) : \"Unknown error\";\n ctx.throwError(ERROR.CANCEL_ORDER_ERROR, `Cancel order error: ${message}`);\n }\n}\n\nexport async function cancelAllOrders(ctx: ClientContext): Promise<void> {\n const orders = await getOrders(ctx);\n const pending = orders.filter((o) => !o.finalStatus);\n\n for (const order of pending) {\n await cancelOrder(ctx, order.orderId);\n }\n}\n\nexport async function submitOrder(ctx: ClientContext, params: Order.SubmitParams): Promise<Order.Update> {\n ctx.ensureSession();\n\n const {\n symbol,\n side,\n quantity,\n orderType,\n orderCode,\n price,\n instrumentId,\n stopLoss,\n takeProfit,\n positionEffect = ACTION.OPENING,\n positionCode,\n tif = \"GTC\",\n expireDate,\n metadata,\n } = params;\n const info = await getSymbolInfo(ctx, symbol);\n const units = Math.round(quantity * info.lotSize);\n const qty = side === SIDE.BUY ? units : -units;\n const priceParam = orderType === ORDER_TYPE.STOP ? \"stopPrice\" : \"limitPrice\";\n\n const orderData: Record<string, unknown> = {\n directExchange: false,\n legs: [\n {\n ...(instrumentId != null && { instrumentId }),\n ...(positionCode != null && { positionCode }),\n positionEffect,\n ratioQuantity: 1,\n symbol,\n },\n ],\n orderSide: side,\n orderType,\n quantity: qty,\n requestId: orderCode ?? `gwt-uid-931-${crypto.randomUUID()}`,\n timeInForce: tif,\n ...(expireDate != null && { expireDate }),\n ...(metadata != null && { metadata }),\n };\n\n if (price != null && orderType !== ORDER_TYPE.MARKET) {\n orderData[priceParam] = price;\n }\n\n if (stopLoss) {\n orderData.stopLoss = {\n ...(stopLoss.offset != null && { fixedOffset: stopLoss.offset }),\n ...(stopLoss.price != null && { fixedPrice: stopLoss.price }),\n priceFixed: stopLoss.price != null,\n orderChainId: 0,\n orderId: 0,\n orderType: ORDER_TYPE.STOP,\n quantityForProtection: qty,\n removed: false,\n };\n }\n\n if (takeProfit) {\n orderData.takeProfit = {\n ...(takeProfit.offset != null && { fixedOffset: takeProfit.offset }),\n ...(takeProfit.price != null && { fixedPrice: takeProfit.price }),\n priceFixed: takeProfit.price != null,\n orderChainId: 0,\n orderId: 0,\n orderType: ORDER_TYPE.LIMIT,\n quantityForProtection: qty,\n removed: false,\n };\n }\n\n try {\n // Open WS listener BEFORE submitting so we don't miss the response\n const wsUrl = endpoints.websocket(ctx.broker, ctx.atmosphereId);\n const cookieStr = Cookies.serialize(ctx.cookies);\n const listener = createOrderListener(wsUrl, cookieStr, 30_000, ctx.debug);\n await listener.ready;\n\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.submitOrder(ctx.broker),\n data: orderData,\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n\n ctx.callbacks.onOrderPlaced?.(response.data as Order.Response);\n\n const orderUpdate = await listener.promise;\n\n ctx.callbacks.onOrderUpdate?.(orderUpdate);\n return orderUpdate;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message =\n error instanceof Error ? ((error as any).response?.data?.message ?? error.message) : \"Unknown error\";\n ctx.throwError(ERROR.ORDER_ERROR, `Error submitting order: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError, WS_MESSAGE, ERROR } from \"@/constants\";\nimport { Cookies, baseHeaders, retryRequest, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Symbol } from \".\";\n\nexport async function getSymbolSuggestions(ctx: ClientContext, text: string): Promise<Symbol.Suggestion[]> {\n ctx.ensureSession();\n\n try {\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.suggest(ctx.broker, text),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n ctx.retries,\n );\n\n const suggests = response.data?.suggests;\n if (!suggests?.length) {\n ctx.throwError(ERROR.NO_SUGGESTIONS, \"No symbol suggestions found\");\n }\n return suggests as Symbol.Suggestion[];\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(ERROR.SUGGEST_ERROR, `Error getting symbol suggestions: ${message}`);\n }\n}\n\nexport async function getSymbolInfo(ctx: ClientContext, symbol: string): Promise<Symbol.Info> {\n ctx.ensureSession();\n\n try {\n const offsetMinutes = Math.abs(new Date().getTimezoneOffset());\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.instrumentInfo(ctx.broker, symbol, offsetMinutes),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n ctx.retries,\n );\n\n if (!response.data) {\n ctx.throwError(ERROR.NO_SYMBOL_INFO, \"No symbol info returned\");\n }\n return response.data as Symbol.Info;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(ERROR.SYMBOL_INFO_ERROR, `Error getting symbol info: ${message}`);\n }\n}\n\nexport async function getSymbolLimits(ctx: ClientContext, timeout = 30_000): Promise<Symbol.Limits[]> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.broker, ctx.atmosphereId);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(ERROR.LIMITS_TIMEOUT, \"Symbol limits request timed out\"));\n }, timeout);\n\n let limits: Symbol.Limits[] = [];\n let settleTimer: ReturnType<typeof setTimeout> | null = null;\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.LIMITS) {\n const batch = msg.body as Symbol.Limits[];\n if (batch.length === 0) return;\n\n limits.push(...batch);\n\n if (settleTimer) clearTimeout(settleTimer);\n settleTimer = setTimeout(() => {\n clearTimeout(timer);\n ws.close();\n resolve(limits);\n }, 0);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(ERROR.LIMITS_ERROR, `Symbol limits error: ${error.message}`));\n });\n });\n}\n","import WebSocket from \"ws\";\nimport { WS_MESSAGE, ERROR, endpoints, DxtradeError } from \"@/constants\";\nimport { Cookies, parseWsData, shouldLog, debugLog, retryRequest, authHeaders } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Position } from \".\";\n\nexport async function getPositions(ctx: ClientContext): Promise<Position.Get[]> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.broker, ctx.atmosphereId);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(ERROR.ACCOUNT_POSITIONS_TIMEOUT, \"Account positions timed out\"));\n }, 30_000);\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.POSITIONS) {\n clearTimeout(timer);\n ws.close();\n resolve(msg.body as Position.Get[]);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(ERROR.ACCOUNT_POSITIONS_ERROR, `Account positions error: ${error.message}`));\n });\n });\n}\n\nexport async function getPositionMetrics(ctx: ClientContext, timeout = 30_000): Promise<Position.Metrics[]> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.broker, ctx.atmosphereId);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(ERROR.POSITION_METRICS_TIMEOUT, \"Position metrics timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.POSITION_METRICS) {\n clearTimeout(timer);\n ws.close();\n resolve(msg.body as Position.Metrics[]);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(ERROR.POSITION_METRICS_ERROR, `Position metrics error: ${error.message}`));\n });\n });\n}\n\nexport async function closeAllPositions(ctx: ClientContext): Promise<void> {\n const positions = await getPositions(ctx);\n\n for (const pos of positions) {\n const closeData: Position.Close = {\n legs: [\n {\n instrumentId: pos.positionKey.instrumentId,\n positionCode: pos.positionKey.positionCode,\n positionEffect: \"CLOSING\",\n ratioQuantity: 1,\n symbol: pos.positionKey.positionCode,\n },\n ],\n limitPrice: 0,\n orderType: \"MARKET\",\n quantity: -pos.quantity,\n timeInForce: \"GTC\",\n };\n await closePosition(ctx, closeData);\n }\n}\n\nexport async function closePosition(ctx: ClientContext, data: Position.Close): Promise<void> {\n try {\n await retryRequest(\n {\n method: \"POST\",\n url: endpoints.closePosition(ctx.broker),\n data,\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n // TODO:: Check response just like in order submit\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message =\n error instanceof Error ? ((error as any).response?.data?.message ?? error.message) : \"Unknown error\";\n ctx.throwError(ERROR.POSITION_CLOSE_ERROR, `Position close error: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError, ERROR } from \"@/constants\";\nimport {\n Cookies,\n authHeaders,\n cookieOnlyHeaders,\n retryRequest,\n clearDebugLog,\n parseAtmosphereId,\n parseWsData,\n shouldLog,\n debugLog,\n} from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\n\ninterface HandshakeResult {\n atmosphereId: string | null;\n accountId: string | null;\n}\n\nfunction waitForHandshake(\n wsUrl: string,\n cookieStr: string,\n timeout = 30_000,\n debug: boolean | string = false,\n): Promise<HandshakeResult> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n let atmosphereId: string | null = null;\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new Error(\"[dxtrade-api] Handshake timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\n if (!atmosphereId) {\n atmosphereId = parseAtmosphereId(data);\n }\n\n const msg = parseWsData(data);\n if (shouldLog(msg, debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.accountId) {\n clearTimeout(timer);\n ws.close();\n resolve({ atmosphereId, accountId: msg.accountId });\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new Error(`[dxtrade-api] WebSocket handshake error: ${error.message}`));\n });\n });\n}\n\nexport async function login(ctx: ClientContext): Promise<void> {\n try {\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.login(ctx.broker),\n data: {\n username: ctx.config.username,\n password: ctx.config.password,\n\n // TODO:: take a look at this below, domain nor vendor seems required. it works if i comment out both.\n // however i still use it since i see brokers use it as well in the login endpoint.\n\n // domain: ctx.config.broker,\n vendor: ctx.config.broker,\n\n // END TODO::\n },\n headers: { \"Content-Type\": \"application/json\" },\n },\n ctx.retries,\n );\n\n if (response.status === 200) {\n const setCookies = response.headers[\"set-cookie\"] ?? [];\n const incoming = Cookies.parse(setCookies);\n ctx.cookies = Cookies.merge(ctx.cookies, incoming);\n ctx.callbacks.onLogin?.();\n } else {\n ctx.throwError(ERROR.LOGIN_FAILED, `Login failed: ${response.status}`);\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(ERROR.LOGIN_ERROR, `Login error: ${message}`);\n }\n}\n\nexport async function fetchCsrf(ctx: ClientContext): Promise<void> {\n try {\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: ctx.broker,\n headers: { ...cookieOnlyHeaders(cookieStr), Referer: ctx.broker },\n },\n ctx.retries,\n );\n\n const csrfMatch = response.data?.match(/name=\"csrf\" content=\"([^\"]+)\"/);\n if (csrfMatch) {\n ctx.csrf = csrfMatch[1];\n } else {\n ctx.throwError(ERROR.CSRF_NOT_FOUND, \"CSRF token not found\");\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(ERROR.CSRF_ERROR, `CSRF fetch error: ${message}`);\n }\n}\n\nexport async function switchAccount(ctx: ClientContext, accountId: string): Promise<void> {\n ctx.ensureSession();\n\n try {\n await retryRequest(\n {\n method: \"POST\",\n url: endpoints.switchAccount(ctx.broker, accountId),\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n ctx.callbacks.onAccountSwitch?.(accountId);\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(ERROR.ACCOUNT_SWITCH_ERROR, `Error switching account: ${message}`);\n }\n}\n\nexport async function connect(ctx: ClientContext): Promise<void> {\n await login(ctx);\n await fetchCsrf(ctx);\n if (ctx.debug) clearDebugLog();\n\n const cookieStr = Cookies.serialize(ctx.cookies);\n const handshake = await waitForHandshake(endpoints.websocket(ctx.broker), cookieStr, 30_000, ctx.debug);\n ctx.atmosphereId = handshake.atmosphereId;\n ctx.accountId = handshake.accountId;\n\n if (ctx.config.accountId) {\n await switchAccount(ctx, ctx.config.accountId);\n const reconnect = await waitForHandshake(\n endpoints.websocket(ctx.broker, ctx.atmosphereId),\n Cookies.serialize(ctx.cookies),\n 30_000,\n ctx.debug,\n );\n ctx.atmosphereId = reconnect.atmosphereId;\n ctx.accountId = reconnect.accountId;\n }\n}\n","import { DxtradeError, ERROR } from \"@/constants\";\nimport type { ClientContext, DxtradeConfig } from \"./client.types\";\nimport type { Account, Assessments, Instrument, OHLC, Order, Position, Symbol } from \"./domains\";\nimport {\n login,\n fetchCsrf,\n switchAccount,\n connect,\n getAccountMetrics,\n getTradeHistory,\n getPositions,\n getPositionMetrics,\n closePosition,\n closeAllPositions,\n getAssessments,\n getInstruments,\n getSymbolLimits,\n getSymbolSuggestions,\n getOHLC,\n getSymbolInfo,\n getOrders,\n cancelOrder,\n cancelAllOrders,\n submitOrder,\n getTradeJournal,\n} from \"@/domains\";\n\n/**\n * Client for interacting with the DXtrade trading API.\n *\n * @example\n * ```ts\n * import { DxtradeClient, ORDER_TYPE, SIDE, BROKER } from \"dxtrade-api\";\n *\n * const client = new DxtradeClient({\n * username: \"your_username\",\n * password: \"your_password\",\n * broker: BROKER.FTMO,\n * });\n *\n * await client.connect();\n * ```\n */\nexport class DxtradeClient {\n private _ctx: ClientContext;\n\n constructor(config: DxtradeConfig) {\n const callbacks = config.callbacks ?? {};\n\n this._ctx = {\n config,\n callbacks,\n cookies: {},\n csrf: null,\n accountId: config.accountId ?? null,\n atmosphereId: null,\n broker: config.broker,\n retries: config.retries ?? 3,\n debug: config.debug ?? false,\n ensureSession() {\n if (!this.csrf) {\n throw new DxtradeError(\n ERROR.NO_SESSION,\n \"No active session. Call login() and fetchCsrf() or connect() first.\",\n );\n }\n },\n throwError(code: string, message: string): never {\n const error = new DxtradeError(code, message);\n callbacks.onError?.(error);\n throw error;\n },\n };\n }\n\n /** Authenticate with the broker using username and password. */\n public async login(): Promise<void> {\n return login(this._ctx);\n }\n\n /** Fetch the CSRF token required for authenticated requests. */\n public async fetchCsrf(): Promise<void> {\n return fetchCsrf(this._ctx);\n }\n\n /** Switch to a specific trading account by ID. */\n public async switchAccount(accountId: string): Promise<void> {\n return switchAccount(this._ctx, accountId);\n }\n\n /** Connect to the broker: login, fetch CSRF, WebSocket handshake, and optional account switch. */\n public async connect(): Promise<void> {\n return connect(this._ctx);\n }\n\n /** Search for symbols matching the given text (e.g. \"EURUSD\", \"BTC\"). */\n public async getSymbolSuggestions(text: string): Promise<Symbol.Suggestion[]> {\n return getSymbolSuggestions(this._ctx, text);\n }\n\n /** Get detailed instrument info for a symbol, including volume limits and lot size. */\n public async getSymbolInfo(symbol: string): Promise<Symbol.Info> {\n return getSymbolInfo(this._ctx, symbol);\n }\n\n /** Get order size limits and stop/limit distances for all symbols. */\n public async getSymbolLimits(): Promise<Symbol.Limits[]> {\n return getSymbolLimits(this._ctx);\n }\n\n /**\n * Submit a trading order and wait for WebSocket confirmation.\n * Supports market, limit, and stop orders with optional stop loss and take profit.\n */\n public async submitOrder(params: Order.SubmitParams): Promise<Order.Update> {\n return submitOrder(this._ctx, params);\n }\n\n /** Get all pending/open orders via WebSocket. */\n public async getOrders(): Promise<Order.Get[]> {\n return getOrders(this._ctx);\n }\n\n /** Cancel a single pending order by its order chain ID. */\n public async cancelOrder(orderChainId: number): Promise<void> {\n return cancelOrder(this._ctx, orderChainId);\n }\n\n /** Cancel all pending orders. */\n public async cancelAllOrders(): Promise<void> {\n return cancelAllOrders(this._ctx);\n }\n\n /** Get account metrics including equity, balance, margin, and open P&L. */\n public async getAccountMetrics(): Promise<Account.Metrics> {\n return getAccountMetrics(this._ctx);\n }\n\n /** Get all open positions via WebSocket. */\n public async getPositions(): Promise<Position.Get[]> {\n return getPositions(this._ctx);\n }\n\n /**\n * Close a position. Supports partial closes by specifying a quantity smaller than the full position size.\n */\n public async closePosition(position: Position.Close): Promise<void> {\n return closePosition(this._ctx, position);\n }\n\n /** Close all open positions with market orders. */\n public async closeAllPositions(): Promise<void> {\n return closeAllPositions(this._ctx);\n }\n\n /** Get position-level P&L metrics via WebSocket. */\n public async getPositionMetrics(): Promise<Position.Metrics[]> {\n return getPositionMetrics(this._ctx);\n }\n\n /**\n * Fetch trade journal entries for a date range.\n * @param params.from - Start timestamp (Unix ms)\n * @param params.to - End timestamp (Unix ms)\n */\n public async getTradeJournal(params: { from: number; to: number }): Promise<any> {\n return getTradeJournal(this._ctx, params);\n }\n\n /**\n * Fetch trade history for a date range.\n * @param params.from - Start timestamp (Unix ms)\n * @param params.to - End timestamp (Unix ms)\n */\n public async getTradeHistory(params: { from: number; to: number }): Promise<Account.TradeHistory[]> {\n return getTradeHistory(this._ctx, params);\n }\n\n /** Get all available instruments, optionally filtered by partial match (e.g. `{ type: \"FOREX\" }`). */\n public async getInstruments(params: Partial<Instrument.Info> = {}): Promise<Instrument.Info[]> {\n return getInstruments(this._ctx, params);\n }\n\n /** Fetch PnL assessments for an instrument within a date range. */\n public async getAssessments(params: Assessments.Params): Promise<Assessments.Response> {\n return getAssessments(this._ctx, params);\n }\n\n /**\n * Fetch OHLC price bars for a symbol.\n * @param params.symbol - Instrument symbol (e.g. \"EURUSD\")\n * @param params.resolution - Bar period in seconds (default: 60 = 1 min)\n * @param params.range - Lookback window in seconds (default: 432000 = 5 days)\n * @param params.maxBars - Maximum bars to return (default: 3500)\n * @param params.priceField - \"bid\" or \"ask\" (default: \"bid\")\n */\n public async getOHLC(params: OHLC.Params): Promise<OHLC.Bar[]> {\n return getOHLC(this._ctx, params);\n }\n}\n"],"mappings":"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","names":["ORDER_TYPE","SIDE","ACTION","TIF","ERROR","WS_MESSAGE","SUBTOPIC","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket"]}
1
+ {"version":3,"sources":["../src/constants/brokers.ts","../src/constants/endpoints.ts","../src/constants/enums.ts","../src/constants/errors.ts","../src/domains/account/account.ts","../src/utils/cookies.ts","../src/utils/headers.ts","../src/utils/retry.ts","../src/utils/websocket.ts","../src/utils/ws-manager.ts","../src/domains/assessments/assessments.ts","../src/domains/instrument/instrument.ts","../src/domains/ohlc/ohlc.ts","../src/domains/order/order.ts","../src/domains/symbol/symbol.ts","../src/domains/position/position.ts","../src/domains/session/session.ts","../src/client.ts"],"sourcesContent":["export const BROKER = {\n LARKFUNDING: \"https://trade.gooeytrade.com\",\n EIGHTCAP: \"https://trader.dx-eightcap.com\",\n FTMO: \"https://dxtrade.ftmo.com\",\n} as const;\n","function websocketQuery(atmosphereId?: string | null): string {\n const trackingId = atmosphereId ?? \"0\";\n return (\n `?X-Atmosphere-tracking-id=${trackingId}&X-Atmosphere-Framework=2.3.2-javascript` +\n `&X-Atmosphere-Transport=websocket&X-Atmosphere-TrackMessageSize=true` +\n `&Content-Type=text/x-gwt-rpc;%20charset=UTF-8&X-atmo-protocol=true` +\n `&sessionState=dx-new&guest-mode=false`\n );\n}\n\nexport const endpoints = {\n login: (base: string) => `${base}/api/auth/login`,\n\n switchAccount: (base: string, id: string) => `${base}/api/accounts/switch?accountId=${id}`,\n\n suggest: (base: string, text: string) => `${base}/api/suggest?text=${text}`,\n\n instrumentInfo: (base: string, symbol: string, tzOffset: number) =>\n `${base}/api/instruments/info?symbol=${symbol}&timezoneOffset=${tzOffset}&withExDividends=true`,\n\n submitOrder: (base: string) => `${base}/api/orders/single`,\n\n closePosition: (base: string) => `${base}/api/positions/close`,\n\n cancelOrder: (base: string, accountId: string, orderChainId: number) =>\n `${base}/api/orders/cancel?accountId=${accountId}&orderChainId=${orderChainId}`,\n\n assessments: (base: string) => `${base}/api/assessments`,\n\n websocket: (base: string, atmosphereId?: string | null) =>\n `wss://${base.split(\"//\")[1]}/client/connector` + websocketQuery(atmosphereId),\n\n tradeJournal: (base: string, params: { from: number; to: number }) =>\n `${base}/api/tradejournal?from=${params.from}&to=${params.to}`,\n\n tradeHistory: (base: string, params: { from: number; to: number }) =>\n `${base}/api/history?from=${params.from}&to=${params.to}`,\n\n subscribeInstruments: (base: string) => `${base}/api/instruments/subscribeInstrumentSymbols`,\n\n charts: (base: string) => `${base}/api/charts`,\n};\n","export enum ORDER_TYPE {\n MARKET = \"MARKET\",\n LIMIT = \"LIMIT\",\n STOP = \"STOP\",\n}\n\nexport enum SIDE {\n BUY = \"BUY\",\n SELL = \"SELL\",\n}\n\nexport enum ACTION {\n OPENING = \"OPENING\",\n CLOSING = \"CLOSING\",\n}\n\nexport enum TIF {\n GTC = \"GTC\",\n DAY = \"DAY\",\n GTD = \"GTD\",\n}\n\nexport enum ERROR {\n NO_SESSION = \"NO_SESSION\",\n\n // Session\n LOGIN_FAILED = \"LOGIN_FAILED\",\n LOGIN_ERROR = \"LOGIN_ERROR\",\n CSRF_NOT_FOUND = \"CSRF_NOT_FOUND\",\n CSRF_ERROR = \"CSRF_ERROR\",\n ACCOUNT_SWITCH_ERROR = \"ACCOUNT_SWITCH_ERROR\",\n\n // Market data\n NO_SUGGESTIONS = \"NO_SUGGESTIONS\",\n SUGGEST_ERROR = \"SUGGEST_ERROR\",\n NO_SYMBOL_INFO = \"NO_SYMBOL_INFO\",\n SYMBOL_INFO_ERROR = \"SYMBOL_INFO_ERROR\",\n INSTRUMENTS_TIMEOUT = \"INSTRUMENTS_TIMEOUT\",\n INSTRUMENTS_ERROR = \"INSTRUMENTS_ERROR\",\n LIMITS_TIMEOUT = \"LIMITS_TIMEOUT\",\n LIMITS_ERROR = \"LIMITS_ERROR\",\n OHLC_TIMEOUT = \"OHLC_TIMEOUT\",\n OHLC_ERROR = \"OHLC_ERROR\",\n\n // Trading\n ORDER_ERROR = \"ORDER_ERROR\",\n ORDERS_TIMEOUT = \"ORDERS_TIMEOUT\",\n ORDERS_ERROR = \"ORDERS_ERROR\",\n CANCEL_ORDER_ERROR = \"CANCEL_ORDER_ERROR\",\n POSITION_CLOSE_ERROR = \"POSITION_CLOSE_ERROR\",\n POSITION_METRICS_TIMEOUT = \"POSITION_METRICS_TIMEOUT\",\n POSITION_METRICS_ERROR = \"POSITION_METRICS_ERROR\",\n\n // Account\n ACCOUNT_METRICS_TIMEOUT = \"ACCOUNT_METRICS_TIMEOUT\",\n ACCOUNT_METRICS_ERROR = \"ACCOUNT_METRICS_ERROR\",\n ACCOUNT_POSITIONS_TIMEOUT = \"ACCOUNT_POSITIONS_TIMEOUT\",\n ACCOUNT_POSITIONS_ERROR = \"ACCOUNT_POSITIONS_ERROR\",\n TRADE_JOURNAL_ERROR = \"TRADE_JOURNAL_ERROR\",\n TRADE_HISTORY_ERROR = \"TRADE_HISTORY_ERROR\",\n\n // Analytics\n ASSESSMENTS_ERROR = \"ASSESSMENTS_ERROR\",\n\n // Rate limiting\n RATE_LIMITED = \"RATE_LIMITED\",\n\n // WebSocket manager\n WS_MANAGER_ERROR = \"WS_MANAGER_ERROR\",\n STREAM_REQUIRES_CONNECT = \"STREAM_REQUIRES_CONNECT\",\n}\n\nexport enum WS_MESSAGE {\n ACCOUNT_METRICS = \"ACCOUNT_METRICS\",\n ACCOUNTS = \"ACCOUNTS\",\n AVAILABLE_WATCHLISTS = \"AVAILABLE_WATCHLISTS\",\n CHART_FEED_SUBTOPIC = \"chartFeedSubtopic\",\n INSTRUMENTS = \"INSTRUMENTS\",\n // INSTRUMENT_METRICS = \"INSTRUMENT_METRICS\",\n LIMITS = \"LIMITS\",\n MESSAGE = \"MESSAGE\",\n ORDERS = \"ORDERS\",\n POSITIONS = \"POSITIONS\",\n POSITION_METRICS = \"POSITION_METRICS\",\n POSITION_CASH_TRANSFERS = \"POSITION_CASH_TRANSFERS\",\n PRIVATE_LAYOUT_NAMES = \"PRIVATE_LAYOUT_NAMES\",\n SHARED_PROPERTIES_MESSAGE = \"SHARED_PROPERTIES_MESSAGE\",\n TRADE_STATUSES = \"TRADE_STATUSES\",\n USER_LOGIN_INFO = \"USER_LOGIN_INFO\",\n}\n\nexport namespace WS_MESSAGE {\n export enum SUBTOPIC {\n BIG_CHART_COMPONENT = \"BigChartComponentPresenter-4\",\n OHLC_STREAM = \"OHLCStreamPresenter-0\",\n }\n}\n","export class DxtradeError extends Error {\n public code: string;\n\n constructor(code: string, message: string) {\n super(message);\n this.name = \"DxtradeError\";\n this.code = code;\n }\n}\n","import WebSocket from \"ws\";\nimport { WS_MESSAGE, ERROR, endpoints, DxtradeError } from \"@/constants\";\nimport { Cookies, parseWsData, shouldLog, debugLog, retryRequest, baseHeaders, authHeaders } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Account } from \".\";\n\nexport async function getAccountMetrics(ctx: ClientContext, timeout = 30_000): Promise<Account.Metrics> {\n ctx.ensureSession();\n\n if (ctx.wsManager) {\n const body = await ctx.wsManager.waitFor<{ allMetrics: Account.Metrics }>(WS_MESSAGE.ACCOUNT_METRICS, timeout);\n return body.allMetrics;\n }\n\n const wsUrl = endpoints.websocket(ctx.broker, ctx.atmosphereId);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(ERROR.ACCOUNT_METRICS_TIMEOUT, \"Account metrics timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.ACCOUNT_METRICS) {\n clearTimeout(timer);\n ws.close();\n const body = msg.body as { allMetrics: Account.Metrics };\n resolve(body.allMetrics);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(ERROR.ACCOUNT_METRICS_ERROR, `Account metrics error: ${error.message}`));\n });\n });\n}\n\nexport async function getTradeHistory(\n ctx: ClientContext,\n params: { from: number; to: number },\n): Promise<Account.TradeHistory[]> {\n ctx.ensureSession();\n\n try {\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.tradeHistory(ctx.broker, params),\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n\n if (response.status === 200) {\n const setCookies = response.headers[\"set-cookie\"] ?? [];\n const incoming = Cookies.parse(setCookies);\n ctx.cookies = Cookies.merge(ctx.cookies, incoming);\n return response.data as Account.TradeHistory[];\n } else {\n ctx.throwError(ERROR.TRADE_HISTORY_ERROR, `Trade history failed: ${response.status}`);\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(ERROR.TRADE_HISTORY_ERROR, `Trade history error: ${message}`);\n }\n}\n\nexport async function getTradeJournal(ctx: ClientContext, params: { from: number; to: number }): Promise<any> {\n ctx.ensureSession();\n\n try {\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.tradeJournal(ctx.broker, params),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n ctx.retries,\n );\n\n if (response.status === 200) {\n const setCookies = response.headers[\"set-cookie\"] ?? [];\n const incoming = Cookies.parse(setCookies);\n ctx.cookies = Cookies.merge(ctx.cookies, incoming);\n return response.data;\n } else {\n ctx.throwError(ERROR.TRADE_JOURNAL_ERROR, `Login failed: ${response.status}`);\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(ERROR.TRADE_JOURNAL_ERROR, `Trade journal error: ${message}`);\n }\n}\n","export class Cookies {\n static parse(setCookieHeaders: string[]): Record<string, string> {\n const cookies: Record<string, string> = {};\n\n for (const cookie of setCookieHeaders) {\n const [nameValue] = cookie.split(\";\");\n const eqIndex = nameValue.indexOf(\"=\");\n if (eqIndex === -1) continue;\n const name = nameValue.slice(0, eqIndex).trim();\n const value = nameValue.slice(eqIndex + 1).trim();\n cookies[name] = value;\n }\n\n return cookies;\n }\n\n static serialize(cookies: Record<string, string>): string {\n return Object.entries(cookies)\n .map(([key, value]) => `${key}=${value}`)\n .join(\"; \");\n }\n\n static merge(existing: Record<string, string>, incoming: Record<string, string>): Record<string, string> {\n return { ...existing, ...incoming };\n }\n}\n","export function baseHeaders(): Record<string, string> {\n return {\n \"Content-Type\": \"application/json; charset=UTF-8\",\n \"Accept-Language\": \"en-US,en;q=0.9\",\n };\n}\n\nexport function authHeaders(csrf: string, cookieStr: string): Record<string, string> {\n return {\n ...baseHeaders(),\n \"X-CSRF-Token\": csrf,\n \"X-Requested-With\": \"XMLHttpRequest\",\n Accept: \"*/*\",\n Cookie: cookieStr,\n };\n}\n\nexport function cookieOnlyHeaders(cookieStr: string): Record<string, string> {\n return { Cookie: cookieStr };\n}\n","import axios, { type AxiosRequestConfig, type AxiosResponse, isAxiosError } from \"axios\";\nimport { DxtradeError, ERROR } from \"@/constants\";\n\nexport async function retryRequest(config: AxiosRequestConfig, retries = 3): Promise<AxiosResponse> {\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n return await axios(config);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n console.warn(`[dxtrade-api] Attempt ${attempt} failed: ${message}`, config.url);\n if (isAxiosError(error) && error.response?.status === 429) {\n throw new DxtradeError(ERROR.RATE_LIMITED, \"Rate limited (429). Too many requests — try again later.\");\n }\n if (attempt === retries) throw error;\n await new Promise((res) => setTimeout(res, 1000 * attempt));\n }\n }\n throw new Error(\"[dxtrade-api] Failed after retries\");\n}\n","import { appendFileSync, writeFileSync } from \"fs\";\nimport type WebSocket from \"ws\";\nimport type { WsPayload } from \"./websocket.types\";\n\nexport type { WsPayload } from \"./websocket.types\";\n\nconst DEBUG_LOG = \"debug.log\";\n\nexport function shouldLog(msg: WsPayload | string, debug: boolean | string): boolean {\n if (!debug) return false;\n if (debug === true || debug === \"true\") return true;\n if (typeof msg === \"string\") return false;\n const filters = (debug as string).split(\",\").map((s) => s.trim().toUpperCase());\n return filters.includes(msg.type);\n}\n\nexport function debugLog(msg: WsPayload | string): void {\n appendFileSync(DEBUG_LOG, JSON.stringify(msg) + \"\\n\");\n}\n\nexport function clearDebugLog(): void {\n writeFileSync(DEBUG_LOG, \"\");\n}\n\nexport function parseAtmosphereId(data: WebSocket.Data): string | null {\n const raw = data.toString();\n const parts = raw.split(\"|\");\n if (parts.length >= 2 && /^[0-9a-f-]{36}$/.test(parts[1])) {\n return parts[1];\n }\n return null;\n}\n\nexport function parseWsData(data: WebSocket.Data): WsPayload | string {\n const raw = data.toString();\n const pipeIndex = raw.indexOf(\"|\");\n if (pipeIndex === -1) return raw;\n\n try {\n return JSON.parse(raw.slice(pipeIndex + 1)) as WsPayload;\n } catch {\n return raw;\n }\n}\n","import { EventEmitter } from \"events\";\nimport WebSocket from \"ws\";\nimport { parseWsData, shouldLog, debugLog } from \"./websocket\";\nimport type { WsPayload } from \"./websocket.types\";\n\nexport class WsManager extends EventEmitter {\n private _ws: WebSocket | null = null;\n private _cache: Map<string, unknown> = new Map();\n\n connect(wsUrl: string, cookieStr: string, debug: boolean | string = false): Promise<void> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n ws.on(\"open\", () => {\n this._ws = ws;\n resolve();\n });\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, debug)) debugLog(msg);\n if (typeof msg === \"string\") return;\n\n const payload = msg as WsPayload;\n this._cache.set(payload.type, payload.body);\n this.emit(payload.type, payload.body);\n });\n\n ws.on(\"error\", (error) => {\n if (!this._ws) {\n return reject(error);\n }\n this.emit(\"error\", error);\n });\n\n ws.on(\"close\", () => {\n this._ws = null;\n this.emit(\"close\");\n });\n });\n }\n\n waitFor<T>(type: string, timeout = 30_000): Promise<T> {\n const cached = this._cache.get(type);\n if (cached !== undefined) {\n return Promise.resolve(cached as T);\n }\n\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n this.removeListener(type, onMessage);\n reject(new Error(`WsManager: timed out waiting for ${type}`));\n }, timeout);\n\n const onMessage = (body: T) => {\n clearTimeout(timer);\n resolve(body);\n };\n\n this.once(type, onMessage);\n });\n }\n\n getCached<T>(type: string): T | undefined {\n return this._cache.get(type) as T | undefined;\n }\n\n close(): void {\n if (this._ws) {\n this._ws.close();\n this._ws = null;\n }\n this._cache.clear();\n this.removeAllListeners();\n }\n\n get isConnected(): boolean {\n return this._ws !== null && this._ws.readyState === WebSocket.OPEN;\n }\n}\n","import { endpoints, DxtradeError, ERROR } from \"@/constants\";\nimport { Cookies, authHeaders, retryRequest } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Assessments } from \".\";\n\nexport async function getAssessments(ctx: ClientContext, params: Assessments.Params): Promise<Assessments.Response> {\n ctx.ensureSession();\n\n try {\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.assessments(ctx.broker),\n data: {\n from: params.from,\n instrument: params.instrument,\n subtype: params.subtype ?? null,\n to: params.to,\n },\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n\n return response.data as Assessments.Response;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(ERROR.ASSESSMENTS_ERROR, `Error fetching assessments: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError, WS_MESSAGE, ERROR } from \"@/constants\";\nimport { Cookies, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Instrument } from \".\";\n\nexport async function getInstruments(\n ctx: ClientContext,\n params: Partial<Instrument.Info> = {},\n timeout = 30_000,\n): Promise<Instrument.Info[]> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.broker, ctx.atmosphereId);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(ERROR.INSTRUMENTS_TIMEOUT, \"Instruments request timed out\"));\n }, timeout);\n\n let instruments: Instrument.Info[] = [];\n let settleTimer: ReturnType<typeof setTimeout> | null = null;\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.INSTRUMENTS) {\n instruments.push(...(msg.body as Instrument.Info[]));\n\n // Reset settle timer on each batch — resolve once no more arrive\n if (settleTimer) clearTimeout(settleTimer);\n settleTimer = setTimeout(() => {\n clearTimeout(timer);\n ws.close();\n resolve(\n instruments.filter((instrument) => {\n for (const key in params) {\n if (params[key as keyof Instrument.Info] !== instrument[key as keyof Instrument.Info]) {\n return false;\n }\n }\n return true;\n }),\n );\n }, 200);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(ERROR.INSTRUMENTS_ERROR, `Instruments error: ${error.message}`));\n });\n });\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError, WS_MESSAGE, ERROR } from \"@/constants\";\nimport { Cookies, authHeaders, retryRequest, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { OHLC } from \".\";\n\nexport async function streamOHLC(\n ctx: ClientContext,\n params: OHLC.Params,\n callback: (bars: OHLC.Bar[]) => void,\n): Promise<() => void> {\n if (!ctx.wsManager) {\n ctx.throwError(\n ERROR.STREAM_REQUIRES_CONNECT,\n \"Streaming requires a persistent WebSocket. Use connect() instead of auth().\",\n );\n }\n\n const { symbol, resolution = 60, range = 432_000, maxBars = 3500, priceField = \"bid\" } = params;\n const subtopic = WS_MESSAGE.SUBTOPIC.OHLC_STREAM;\n const headers = authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies));\n const snapshotBars: OHLC.Bar[] = [];\n let snapshotDone = false;\n let resolveSnapshot: (() => void) | null = null;\n\n const onChartFeed = (body: Record<string, unknown>) => {\n if (body?.subtopic !== subtopic) return;\n const data = body.data as OHLC.Bar[] | undefined;\n if (!Array.isArray(data)) return;\n\n if (!snapshotDone) {\n snapshotBars.push(...data);\n if (body.snapshotEnd) {\n snapshotDone = true;\n callback([...snapshotBars]);\n resolveSnapshot?.();\n }\n } else {\n callback(data);\n }\n };\n\n ctx.wsManager.on(WS_MESSAGE.CHART_FEED_SUBTOPIC, onChartFeed);\n\n try {\n await retryRequest(\n {\n method: \"PUT\",\n url: endpoints.subscribeInstruments(ctx.broker),\n data: { instruments: [symbol] },\n headers,\n },\n ctx.retries,\n );\n await retryRequest(\n {\n method: \"PUT\",\n url: endpoints.charts(ctx.broker),\n data: {\n chartIds: [],\n requests: [\n {\n aggregationPeriodSeconds: resolution,\n extendedSession: true,\n forexPriceField: priceField,\n id: 0,\n maxBarsCount: maxBars,\n range,\n studySubscription: [],\n subtopic,\n symbol,\n },\n ],\n },\n headers,\n },\n ctx.retries,\n );\n } catch (error: unknown) {\n ctx.wsManager.removeListener(WS_MESSAGE.CHART_FEED_SUBTOPIC, onChartFeed);\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(ERROR.OHLC_ERROR, `OHLC stream subscription error: ${message}`);\n }\n\n await new Promise<void>((resolve, reject) => {\n if (snapshotDone) return resolve();\n\n const timer = setTimeout(() => {\n if (snapshotBars.length > 0) {\n snapshotDone = true;\n callback([...snapshotBars]);\n resolve();\n } else {\n ctx.wsManager?.removeListener(WS_MESSAGE.CHART_FEED_SUBTOPIC, onChartFeed);\n reject(new DxtradeError(ERROR.OHLC_TIMEOUT, \"OHLC stream snapshot timed out\"));\n }\n }, 30_000);\n\n resolveSnapshot = () => {\n clearTimeout(timer);\n resolve();\n };\n });\n\n return () => {\n ctx.wsManager?.removeListener(WS_MESSAGE.CHART_FEED_SUBTOPIC, onChartFeed);\n };\n}\n\nexport async function getOHLC(ctx: ClientContext, params: OHLC.Params, timeout = 30_000): Promise<OHLC.Bar[]> {\n ctx.ensureSession();\n\n const { symbol, resolution = 60, range = 432_000, maxBars = 3500, priceField = \"bid\" } = params;\n const wsUrl = endpoints.websocket(ctx.broker, ctx.atmosphereId);\n const cookieStr = Cookies.serialize(ctx.cookies);\n const headers = authHeaders(ctx.csrf!, cookieStr);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n const bars: OHLC.Bar[] = [];\n let putsSent = false;\n let initSettleTimer: ReturnType<typeof setTimeout> | null = null;\n let barSettleTimer: ReturnType<typeof setTimeout> | null = null;\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(ERROR.OHLC_TIMEOUT, \"OHLC data timed out\"));\n }, timeout);\n\n function cleanup() {\n clearTimeout(timer);\n if (initSettleTimer) clearTimeout(initSettleTimer);\n if (barSettleTimer) clearTimeout(barSettleTimer);\n ws.close();\n }\n\n async function sendPuts() {\n putsSent = true;\n try {\n await retryRequest(\n {\n method: \"PUT\",\n url: endpoints.subscribeInstruments(ctx.broker),\n data: { instruments: [symbol] },\n headers,\n },\n ctx.retries,\n );\n await retryRequest(\n {\n method: \"PUT\",\n url: endpoints.charts(ctx.broker),\n data: {\n chartIds: [],\n requests: [\n {\n aggregationPeriodSeconds: resolution,\n extendedSession: true,\n forexPriceField: priceField,\n id: 0,\n maxBarsCount: maxBars,\n range,\n studySubscription: [],\n subtopic: WS_MESSAGE.SUBTOPIC.BIG_CHART_COMPONENT,\n symbol,\n },\n ],\n },\n headers,\n },\n ctx.retries,\n );\n } catch (error: unknown) {\n cleanup();\n const message = error instanceof Error ? error.message : \"Unknown error\";\n reject(new DxtradeError(ERROR.OHLC_ERROR, `Error fetching OHLC data: ${message}`));\n }\n }\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n if (typeof msg === \"string\") return;\n\n // Wait for init burst to settle before sending PUTs\n if (!putsSent) {\n if (initSettleTimer) clearTimeout(initSettleTimer);\n initSettleTimer = setTimeout(() => sendPuts(), 1000);\n return;\n }\n\n // Collect chart bars\n const body = msg.body as Record<string, unknown>;\n if (body?.subtopic !== WS_MESSAGE.SUBTOPIC.BIG_CHART_COMPONENT) return;\n\n if (Array.isArray(body.data)) {\n bars.push(...(body.data as OHLC.Bar[]));\n }\n\n if (barSettleTimer) clearTimeout(barSettleTimer);\n if (body.snapshotEnd) {\n cleanup();\n resolve(bars);\n } else {\n barSettleTimer = setTimeout(() => {\n cleanup();\n resolve(bars);\n }, 2000);\n }\n });\n\n ws.on(\"error\", (error) => {\n cleanup();\n reject(new DxtradeError(ERROR.OHLC_ERROR, `OHLC WebSocket error: ${error.message}`));\n });\n });\n}\n","import crypto from \"crypto\";\nimport WebSocket from \"ws\";\nimport { endpoints, ORDER_TYPE, SIDE, ACTION, DxtradeError, ERROR } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\nimport { Cookies, authHeaders, retryRequest, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport { getSymbolInfo } from \"../symbol/symbol\";\nimport type { Order, Message } from \".\";\n\nfunction createOrderListener(\n wsUrl: string,\n cookieStr: string,\n timeout = 30_000,\n debug: boolean | string = false,\n): { promise: Promise<Order.Update>; ready: Promise<void> } {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n let settled = false;\n\n const ready = new Promise<void>((resolve) => {\n ws.on(\"open\", resolve);\n });\n\n const promise = new Promise<Order.Update>((resolve, reject) => {\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n ws.close();\n reject(new Error(\"[dxtrade-api] Order update timed out\"));\n }, timeout);\n\n function done(err: Error | null, result?: Order.Update) {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n ws.close();\n if (err) reject(err);\n else resolve(result!);\n }\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, debug)) debugLog(msg);\n if (typeof msg === \"string\") return;\n\n // Trade log messages (fills and rejections come through here)\n if (msg.type === WS_MESSAGE.MESSAGE) {\n const messages = msg.body as Message.Entry[];\n const orderMsg = messages?.findLast?.(\n (m) => m.messageCategory === \"TRADE_LOG\" && m.messageType === \"ORDER\" && !m.historyMessage,\n );\n if (!orderMsg) return;\n\n const params = orderMsg.parametersTO as Message.OrderParams;\n if (params.orderStatus === \"REJECTED\") {\n const reason = params.rejectReason?.key ?? \"Unknown reason\";\n done(new Error(`[dxtrade-api] Order rejected: ${reason}`));\n } else if (params.orderStatus === \"FILLED\") {\n done(null, {\n orderId: params.orderKey,\n status: params.orderStatus,\n symbol: params.symbol,\n filledQuantity: params.filledQuantity,\n filledPrice: params.filledPrice,\n });\n }\n return;\n }\n\n // Order updates (also carry fills)\n if (msg.type === WS_MESSAGE.ORDERS) {\n const body = (msg.body as Order.Update[])?.[0];\n if (!body?.orderId) return;\n\n if (body.status === \"REJECTED\") {\n done(new Error(`[dxtrade-api] Order rejected: ${body.statusDescription ?? \"Unknown reason\"}`));\n } else if (body.status === \"FILLED\") {\n done(null, body);\n }\n }\n });\n\n ws.on(\"error\", (error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n ws.close();\n reject(new Error(`[dxtrade-api] WebSocket order listener error: ${error.message}`));\n });\n });\n\n return { promise, ready };\n}\n\nexport async function getOrders(ctx: ClientContext, timeout = 30_000): Promise<Order.Get[]> {\n ctx.ensureSession();\n\n if (ctx.wsManager) {\n return ctx.wsManager.waitFor<Order.Get[]>(WS_MESSAGE.ORDERS, timeout);\n }\n\n const wsUrl = endpoints.websocket(ctx.broker, ctx.atmosphereId);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(ERROR.ORDERS_TIMEOUT, \"Orders request timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.ORDERS) {\n clearTimeout(timer);\n ws.close();\n resolve(msg.body as Order.Get[]);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(ERROR.ORDERS_ERROR, `Orders error: ${error.message}`));\n });\n });\n}\n\nexport async function cancelOrder(ctx: ClientContext, orderChainId: number): Promise<void> {\n ctx.ensureSession();\n\n const accountId = ctx.accountId ?? ctx.config.accountId;\n if (!accountId) {\n ctx.throwError(ERROR.CANCEL_ORDER_ERROR, \"accountId is required to cancel an order\");\n }\n\n try {\n await retryRequest(\n {\n method: \"DELETE\",\n url: endpoints.cancelOrder(ctx.broker, accountId, orderChainId),\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message =\n error instanceof Error ? ((error as any).response?.data?.message ?? error.message) : \"Unknown error\";\n ctx.throwError(ERROR.CANCEL_ORDER_ERROR, `Cancel order error: ${message}`);\n }\n}\n\nexport async function cancelAllOrders(ctx: ClientContext): Promise<void> {\n const orders = await getOrders(ctx);\n const pending = orders.filter((o) => !o.finalStatus);\n\n for (const order of pending) {\n await cancelOrder(ctx, order.orderId);\n }\n}\n\nexport async function submitOrder(ctx: ClientContext, params: Order.SubmitParams): Promise<Order.Update> {\n ctx.ensureSession();\n\n const {\n symbol,\n side,\n quantity,\n orderType,\n orderCode,\n price,\n instrumentId,\n stopLoss,\n takeProfit,\n positionEffect = ACTION.OPENING,\n positionCode,\n tif = \"GTC\",\n expireDate,\n metadata,\n } = params;\n const info = await getSymbolInfo(ctx, symbol);\n const units = Math.round(quantity * info.lotSize);\n const qty = side === SIDE.BUY ? units : -units;\n const priceParam = orderType === ORDER_TYPE.STOP ? \"stopPrice\" : \"limitPrice\";\n\n const orderData: Record<string, unknown> = {\n directExchange: false,\n legs: [\n {\n ...(instrumentId != null && { instrumentId }),\n ...(positionCode != null && { positionCode }),\n positionEffect,\n ratioQuantity: 1,\n symbol,\n },\n ],\n orderSide: side,\n orderType,\n quantity: qty,\n requestId: orderCode ?? `gwt-uid-931-${crypto.randomUUID()}`,\n timeInForce: tif,\n ...(expireDate != null && { expireDate }),\n ...(metadata != null && { metadata }),\n };\n\n if (price != null && orderType !== ORDER_TYPE.MARKET) {\n orderData[priceParam] = price;\n }\n\n if (stopLoss) {\n orderData.stopLoss = {\n ...(stopLoss.offset != null && { fixedOffset: stopLoss.offset }),\n ...(stopLoss.price != null && { fixedPrice: stopLoss.price }),\n priceFixed: stopLoss.price != null,\n orderChainId: 0,\n orderId: 0,\n orderType: ORDER_TYPE.STOP,\n quantityForProtection: qty,\n removed: false,\n };\n }\n\n if (takeProfit) {\n orderData.takeProfit = {\n ...(takeProfit.offset != null && { fixedOffset: takeProfit.offset }),\n ...(takeProfit.price != null && { fixedPrice: takeProfit.price }),\n priceFixed: takeProfit.price != null,\n orderChainId: 0,\n orderId: 0,\n orderType: ORDER_TYPE.LIMIT,\n quantityForProtection: qty,\n removed: false,\n };\n }\n\n try {\n // Open WS listener BEFORE submitting so we don't miss the response\n const wsUrl = endpoints.websocket(ctx.broker, ctx.atmosphereId);\n const cookieStr = Cookies.serialize(ctx.cookies);\n const listener = createOrderListener(wsUrl, cookieStr, 30_000, ctx.debug);\n await listener.ready;\n\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.submitOrder(ctx.broker),\n data: orderData,\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n\n ctx.callbacks.onOrderPlaced?.(response.data as Order.Response);\n\n const orderUpdate = await listener.promise;\n\n ctx.callbacks.onOrderUpdate?.(orderUpdate);\n return orderUpdate;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message =\n error instanceof Error ? ((error as any).response?.data?.message ?? error.message) : \"Unknown error\";\n ctx.throwError(ERROR.ORDER_ERROR, `Error submitting order: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError, WS_MESSAGE, ERROR } from \"@/constants\";\nimport { Cookies, baseHeaders, retryRequest, parseWsData, shouldLog, debugLog } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Symbol } from \".\";\n\nexport async function getSymbolSuggestions(ctx: ClientContext, text: string): Promise<Symbol.Suggestion[]> {\n ctx.ensureSession();\n\n try {\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.suggest(ctx.broker, text),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n ctx.retries,\n );\n\n const suggests = response.data?.suggests;\n if (!suggests?.length) {\n ctx.throwError(ERROR.NO_SUGGESTIONS, \"No symbol suggestions found\");\n }\n return suggests as Symbol.Suggestion[];\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(ERROR.SUGGEST_ERROR, `Error getting symbol suggestions: ${message}`);\n }\n}\n\nexport async function getSymbolInfo(ctx: ClientContext, symbol: string): Promise<Symbol.Info> {\n ctx.ensureSession();\n\n try {\n const offsetMinutes = Math.abs(new Date().getTimezoneOffset());\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: endpoints.instrumentInfo(ctx.broker, symbol, offsetMinutes),\n headers: { ...baseHeaders(), Cookie: cookieStr },\n },\n ctx.retries,\n );\n\n if (!response.data) {\n ctx.throwError(ERROR.NO_SYMBOL_INFO, \"No symbol info returned\");\n }\n return response.data as Symbol.Info;\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(ERROR.SYMBOL_INFO_ERROR, `Error getting symbol info: ${message}`);\n }\n}\n\nexport async function getSymbolLimits(ctx: ClientContext, timeout = 30_000): Promise<Symbol.Limits[]> {\n ctx.ensureSession();\n\n const wsUrl = endpoints.websocket(ctx.broker, ctx.atmosphereId);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(ERROR.LIMITS_TIMEOUT, \"Symbol limits request timed out\"));\n }, timeout);\n\n let limits: Symbol.Limits[] = [];\n let settleTimer: ReturnType<typeof setTimeout> | null = null;\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.LIMITS) {\n const batch = msg.body as Symbol.Limits[];\n if (batch.length === 0) return;\n\n limits.push(...batch);\n\n if (settleTimer) clearTimeout(settleTimer);\n settleTimer = setTimeout(() => {\n clearTimeout(timer);\n ws.close();\n resolve(limits);\n }, 200);\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(ERROR.LIMITS_ERROR, `Symbol limits error: ${error.message}`));\n });\n });\n}\n","import WebSocket from \"ws\";\nimport { WS_MESSAGE, ERROR, endpoints, DxtradeError } from \"@/constants\";\nimport { Cookies, parseWsData, shouldLog, debugLog, retryRequest, authHeaders } from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\nimport type { Position } from \".\";\n\nfunction mergePositionsWithMetrics(positions: Position.Get[], metrics: Position.Metrics[]): Position.Full[] {\n const metricsMap = new Map(metrics.map((m) => [m.uid, m]));\n return positions.map((pos) => {\n const m = metricsMap.get(pos.uid);\n return {\n ...pos,\n margin: m?.margin ?? 0,\n plOpen: m?.plOpen ?? 0,\n plClosed: m?.plClosed ?? 0,\n totalCommissions: m?.totalCommissions ?? 0,\n totalFinancing: m?.totalFinancing ?? 0,\n plRate: m?.plRate ?? 0,\n averagePrice: m?.averagePrice ?? 0,\n marketValue: m?.marketValue ?? 0,\n };\n });\n}\n\nexport function streamPositions(ctx: ClientContext, callback: (positions: Position.Full[]) => void): () => void {\n if (!ctx.wsManager) {\n ctx.throwError(\n ERROR.STREAM_REQUIRES_CONNECT,\n \"Streaming requires a persistent WebSocket. Use connect() instead of auth().\",\n );\n }\n\n const emit = () => {\n const positions = ctx.wsManager!.getCached<Position.Get[]>(WS_MESSAGE.POSITIONS);\n const metrics = ctx.wsManager!.getCached<Position.Metrics[]>(WS_MESSAGE.POSITION_METRICS);\n if (positions && metrics) {\n callback(mergePositionsWithMetrics(positions, metrics));\n }\n };\n\n const onPositions = () => emit();\n const onMetrics = () => emit();\n\n ctx.wsManager.on(WS_MESSAGE.POSITIONS, onPositions);\n ctx.wsManager.on(WS_MESSAGE.POSITION_METRICS, onMetrics);\n\n emit();\n\n return () => {\n ctx.wsManager?.removeListener(WS_MESSAGE.POSITIONS, onPositions);\n ctx.wsManager?.removeListener(WS_MESSAGE.POSITION_METRICS, onMetrics);\n };\n}\n\nexport async function getPositions(ctx: ClientContext): Promise<Position.Full[]> {\n ctx.ensureSession();\n\n if (ctx.wsManager) {\n const [positions, metrics] = await Promise.all([\n ctx.wsManager.waitFor<Position.Get[]>(WS_MESSAGE.POSITIONS),\n ctx.wsManager.waitFor<Position.Metrics[]>(WS_MESSAGE.POSITION_METRICS),\n ]);\n return mergePositionsWithMetrics(positions, metrics);\n }\n\n const wsUrl = endpoints.websocket(ctx.broker, ctx.atmosphereId);\n const cookieStr = Cookies.serialize(ctx.cookies);\n\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n let positions: Position.Get[] | null = null;\n let metrics: Position.Metrics[] | null = null;\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new DxtradeError(ERROR.ACCOUNT_POSITIONS_TIMEOUT, \"Account positions timed out\"));\n }, 30_000);\n\n ws.on(\"message\", (data) => {\n const msg = parseWsData(data);\n if (shouldLog(msg, ctx.debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.type === WS_MESSAGE.POSITIONS) {\n positions = msg.body as Position.Get[];\n }\n if (msg.type === WS_MESSAGE.POSITION_METRICS) {\n metrics = msg.body as Position.Metrics[];\n }\n if (positions && metrics) {\n clearTimeout(timer);\n ws.close();\n resolve(mergePositionsWithMetrics(positions, metrics));\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new DxtradeError(ERROR.ACCOUNT_POSITIONS_ERROR, `Account positions error: ${error.message}`));\n });\n });\n}\n\nexport async function closeAllPositions(ctx: ClientContext): Promise<void> {\n const positions = await getPositions(ctx);\n\n for (const pos of positions) {\n const closeData: Position.Close = {\n legs: [\n {\n instrumentId: pos.positionKey.instrumentId,\n positionCode: pos.positionKey.positionCode,\n positionEffect: \"CLOSING\",\n ratioQuantity: 1,\n symbol: pos.positionKey.positionCode,\n },\n ],\n limitPrice: 0,\n orderType: \"MARKET\",\n quantity: -pos.quantity,\n timeInForce: \"GTC\",\n };\n await closePosition(ctx, closeData);\n }\n}\n\nexport async function closePosition(ctx: ClientContext, data: Position.Close): Promise<void> {\n try {\n await retryRequest(\n {\n method: \"POST\",\n url: endpoints.closePosition(ctx.broker),\n data,\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n // TODO:: Check response just like in order submit\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message =\n error instanceof Error ? ((error as any).response?.data?.message ?? error.message) : \"Unknown error\";\n ctx.throwError(ERROR.POSITION_CLOSE_ERROR, `Position close error: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError, ERROR } from \"@/constants\";\nimport {\n Cookies,\n WsManager,\n authHeaders,\n cookieOnlyHeaders,\n retryRequest,\n clearDebugLog,\n parseAtmosphereId,\n parseWsData,\n shouldLog,\n debugLog,\n} from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\n\ninterface HandshakeResult {\n atmosphereId: string | null;\n accountId: string | null;\n}\n\nfunction waitForHandshake(\n wsUrl: string,\n cookieStr: string,\n timeout = 30_000,\n debug: boolean | string = false,\n): Promise<HandshakeResult> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(wsUrl, { headers: { Cookie: cookieStr } });\n let atmosphereId: string | null = null;\n\n const timer = setTimeout(() => {\n ws.close();\n reject(new Error(\"[dxtrade-api] Handshake timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\n if (!atmosphereId) {\n atmosphereId = parseAtmosphereId(data);\n }\n\n const msg = parseWsData(data);\n if (shouldLog(msg, debug)) debugLog(msg);\n\n if (typeof msg === \"string\") return;\n if (msg.accountId) {\n clearTimeout(timer);\n ws.close();\n resolve({ atmosphereId, accountId: msg.accountId });\n }\n });\n\n ws.on(\"error\", (error) => {\n clearTimeout(timer);\n ws.close();\n reject(new Error(`[dxtrade-api] WebSocket handshake error: ${error.message}`));\n });\n });\n}\n\nexport async function login(ctx: ClientContext): Promise<void> {\n try {\n const response = await retryRequest(\n {\n method: \"POST\",\n url: endpoints.login(ctx.broker),\n data: {\n username: ctx.config.username,\n password: ctx.config.password,\n\n // TODO:: take a look at this below, domain nor vendor seems required. it works if i comment out both.\n // however i still use it since i see brokers use it as well in the login endpoint.\n\n // domain: ctx.config.broker,\n vendor: ctx.config.broker,\n\n // END TODO::\n },\n headers: { \"Content-Type\": \"application/json\" },\n },\n ctx.retries,\n );\n\n if (response.status === 200) {\n const setCookies = response.headers[\"set-cookie\"] ?? [];\n const incoming = Cookies.parse(setCookies);\n ctx.cookies = Cookies.merge(ctx.cookies, incoming);\n ctx.callbacks.onLogin?.();\n } else {\n ctx.throwError(ERROR.LOGIN_FAILED, `Login failed: ${response.status}`);\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(ERROR.LOGIN_ERROR, `Login error: ${message}`);\n }\n}\n\nexport async function fetchCsrf(ctx: ClientContext): Promise<void> {\n try {\n const cookieStr = Cookies.serialize(ctx.cookies);\n const response = await retryRequest(\n {\n method: \"GET\",\n url: ctx.broker,\n headers: { ...cookieOnlyHeaders(cookieStr), Referer: ctx.broker },\n },\n ctx.retries,\n );\n\n const csrfMatch = response.data?.match(/name=\"csrf\" content=\"([^\"]+)\"/);\n if (csrfMatch) {\n ctx.csrf = csrfMatch[1];\n } else {\n ctx.throwError(ERROR.CSRF_NOT_FOUND, \"CSRF token not found\");\n }\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(ERROR.CSRF_ERROR, `CSRF fetch error: ${message}`);\n }\n}\n\nexport async function switchAccount(ctx: ClientContext, accountId: string): Promise<void> {\n ctx.ensureSession();\n\n try {\n await retryRequest(\n {\n method: \"POST\",\n url: endpoints.switchAccount(ctx.broker, accountId),\n headers: authHeaders(ctx.csrf!, Cookies.serialize(ctx.cookies)),\n },\n ctx.retries,\n );\n ctx.callbacks.onAccountSwitch?.(accountId);\n } catch (error: unknown) {\n if (error instanceof DxtradeError) throw error;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n ctx.throwError(ERROR.ACCOUNT_SWITCH_ERROR, `Error switching account: ${message}`);\n }\n}\n\nexport async function auth(ctx: ClientContext): Promise<void> {\n await login(ctx);\n await fetchCsrf(ctx);\n if (ctx.debug) clearDebugLog();\n\n const cookieStr = Cookies.serialize(ctx.cookies);\n const handshake = await waitForHandshake(endpoints.websocket(ctx.broker), cookieStr, 30_000, ctx.debug);\n ctx.atmosphereId = handshake.atmosphereId;\n ctx.accountId = handshake.accountId;\n\n if (ctx.config.accountId) {\n await switchAccount(ctx, ctx.config.accountId);\n const reconnect = await waitForHandshake(\n endpoints.websocket(ctx.broker, ctx.atmosphereId),\n Cookies.serialize(ctx.cookies),\n 30_000,\n ctx.debug,\n );\n ctx.atmosphereId = reconnect.atmosphereId;\n ctx.accountId = reconnect.accountId;\n }\n}\n\nexport async function connect(ctx: ClientContext): Promise<void> {\n await auth(ctx);\n\n const wsManager = new WsManager();\n const wsUrl = endpoints.websocket(ctx.broker, ctx.atmosphereId);\n const cookieStr = Cookies.serialize(ctx.cookies);\n await wsManager.connect(wsUrl, cookieStr, ctx.debug);\n ctx.wsManager = wsManager;\n}\n\nexport function disconnect(ctx: ClientContext): void {\n if (ctx.wsManager) {\n ctx.wsManager.close();\n ctx.wsManager = null;\n }\n}\n","import { DxtradeError, ERROR } from \"@/constants\";\nimport type { ClientContext, DxtradeConfig } from \"./client.types\";\nimport type { Account, Assessments, Instrument, OHLC, Order, Position, Symbol } from \"./domains\";\nimport {\n login,\n fetchCsrf,\n switchAccount,\n auth,\n connect,\n disconnect,\n getAccountMetrics,\n getTradeHistory,\n getPositions,\n closePosition,\n closeAllPositions,\n streamPositions,\n getAssessments,\n getInstruments,\n getSymbolLimits,\n getSymbolSuggestions,\n getOHLC,\n streamOHLC,\n getSymbolInfo,\n getOrders,\n cancelOrder,\n cancelAllOrders,\n submitOrder,\n getTradeJournal,\n} from \"@/domains\";\n\nclass PositionsDomain {\n constructor(private _ctx: ClientContext) {}\n\n /** Get all open positions with P&L metrics merged. */\n get(): Promise<Position.Full[]> {\n return getPositions(this._ctx);\n }\n\n /** Close a position. Supports partial closes by specifying a quantity smaller than the full position size. */\n close(params: Position.Close): Promise<void> {\n return closePosition(this._ctx, params);\n }\n\n /** Close all open positions with market orders. */\n closeAll(): Promise<void> {\n return closeAllPositions(this._ctx);\n }\n\n /** Stream real-time position updates with P&L metrics. Requires connect(). Returns unsubscribe function. */\n stream(callback: (positions: Position.Full[]) => void): () => void {\n return streamPositions(this._ctx, callback);\n }\n}\n\nclass OrdersDomain {\n constructor(private _ctx: ClientContext) {}\n\n /** Get all pending/open orders via WebSocket. */\n get(): Promise<Order.Get[]> {\n return getOrders(this._ctx);\n }\n\n /**\n * Submit a trading order and wait for WebSocket confirmation.\n * Supports market, limit, and stop orders with optional stop loss and take profit.\n */\n submit(params: Order.SubmitParams): Promise<Order.Update> {\n return submitOrder(this._ctx, params);\n }\n\n /** Cancel a single pending order by its order chain ID. */\n cancel(orderChainId: number): Promise<void> {\n return cancelOrder(this._ctx, orderChainId);\n }\n\n /** Cancel all pending orders. */\n cancelAll(): Promise<void> {\n return cancelAllOrders(this._ctx);\n }\n}\n\nclass AccountDomain {\n constructor(private _ctx: ClientContext) {}\n\n /** Get account metrics including equity, balance, margin, and open P&L. */\n metrics(): Promise<Account.Metrics> {\n return getAccountMetrics(this._ctx);\n }\n\n /**\n * Fetch trade journal entries for a date range.\n * @param params.from - Start timestamp (Unix ms)\n * @param params.to - End timestamp (Unix ms)\n */\n tradeJournal(params: { from: number; to: number }): Promise<any> {\n return getTradeJournal(this._ctx, params);\n }\n\n /**\n * Fetch trade history for a date range.\n * @param params.from - Start timestamp (Unix ms)\n * @param params.to - End timestamp (Unix ms)\n */\n tradeHistory(params: { from: number; to: number }): Promise<Account.TradeHistory[]> {\n return getTradeHistory(this._ctx, params);\n }\n}\n\nclass SymbolsDomain {\n constructor(private _ctx: ClientContext) {}\n\n /** Search for symbols matching the given text (e.g. \"EURUSD\", \"BTC\"). */\n search(text: string): Promise<Symbol.Suggestion[]> {\n return getSymbolSuggestions(this._ctx, text);\n }\n\n /** Get detailed instrument info for a symbol, including volume limits and lot size. */\n info(symbol: string): Promise<Symbol.Info> {\n return getSymbolInfo(this._ctx, symbol);\n }\n\n /** Get order size limits and stop/limit distances for all symbols. */\n limits(): Promise<Symbol.Limits[]> {\n return getSymbolLimits(this._ctx);\n }\n}\n\nclass InstrumentsDomain {\n constructor(private _ctx: ClientContext) {}\n\n /** Get all available instruments, optionally filtered by partial match (e.g. `{ type: \"FOREX\" }`). */\n get(params: Partial<Instrument.Info> = {}): Promise<Instrument.Info[]> {\n return getInstruments(this._ctx, params);\n }\n}\n\nclass OhlcDomain {\n constructor(private _ctx: ClientContext) {}\n\n /**\n * Fetch OHLC price bars for a symbol.\n * @param params.symbol - Instrument symbol (e.g. \"EURUSD\")\n * @param params.resolution - Bar period in seconds (default: 60 = 1 min)\n * @param params.range - Lookback window in seconds (default: 432000 = 5 days)\n * @param params.maxBars - Maximum bars to return (default: 3500)\n * @param params.priceField - \"bid\" or \"ask\" (default: \"bid\")\n */\n get(params: OHLC.Params): Promise<OHLC.Bar[]> {\n return getOHLC(this._ctx, params);\n }\n\n /** Stream real-time OHLC bar updates. Requires connect(). Returns unsubscribe function. */\n stream(params: OHLC.Params, callback: (bars: OHLC.Bar[]) => void): Promise<() => void> {\n return streamOHLC(this._ctx, params, callback);\n }\n}\n\nclass AssessmentsDomain {\n constructor(private _ctx: ClientContext) {}\n\n /** Fetch PnL assessments for an instrument within a date range. */\n get(params: Assessments.Params): Promise<Assessments.Response> {\n return getAssessments(this._ctx, params);\n }\n}\n\n/**\n * Client for interacting with the DXtrade trading API.\n *\n * @example\n * ```ts\n * import { DxtradeClient, ORDER_TYPE, SIDE, BROKER } from \"dxtrade-api\";\n *\n * const client = new DxtradeClient({\n * username: \"your_username\",\n * password: \"your_password\",\n * broker: BROKER.FTMO,\n * });\n *\n * await client.connect();\n * ```\n */\nexport class DxtradeClient {\n private _ctx: ClientContext;\n\n /** Position operations: get, close, metrics, streaming. */\n public readonly positions: PositionsDomain;\n /** Order operations: get, submit, cancel. */\n public readonly orders: OrdersDomain;\n /** Account operations: metrics, trade journal, trade history. */\n public readonly account: AccountDomain;\n /** Symbol operations: search, info, limits. */\n public readonly symbols: SymbolsDomain;\n /** Instrument operations: get (with optional filtering). */\n public readonly instruments: InstrumentsDomain;\n /** OHLC price bar operations: get, stream. */\n public readonly ohlc: OhlcDomain;\n /** PnL assessment operations: get. */\n public readonly assessments: AssessmentsDomain;\n\n constructor(config: DxtradeConfig) {\n const callbacks = config.callbacks ?? {};\n\n this._ctx = {\n config,\n callbacks,\n cookies: {},\n csrf: null,\n accountId: config.accountId ?? null,\n atmosphereId: null,\n wsManager: null,\n broker: config.broker,\n retries: config.retries ?? 3,\n debug: config.debug ?? false,\n ensureSession() {\n if (!this.csrf) {\n throw new DxtradeError(ERROR.NO_SESSION, \"No active session. Call auth() or connect() first.\");\n }\n },\n throwError(code: string, message: string): never {\n const error = new DxtradeError(code, message);\n callbacks.onError?.(error);\n throw error;\n },\n };\n\n this.positions = new PositionsDomain(this._ctx);\n this.orders = new OrdersDomain(this._ctx);\n this.account = new AccountDomain(this._ctx);\n this.symbols = new SymbolsDomain(this._ctx);\n this.instruments = new InstrumentsDomain(this._ctx);\n this.ohlc = new OhlcDomain(this._ctx);\n this.assessments = new AssessmentsDomain(this._ctx);\n }\n\n /** Authenticate with the broker using username and password. */\n public async login(): Promise<void> {\n return login(this._ctx);\n }\n\n /** Fetch the CSRF token required for authenticated requests. */\n public async fetchCsrf(): Promise<void> {\n return fetchCsrf(this._ctx);\n }\n\n /** Switch to a specific trading account by ID. */\n public async switchAccount(accountId: string): Promise<void> {\n return switchAccount(this._ctx, accountId);\n }\n\n /** Authenticate and establish a session: login, fetch CSRF, WebSocket handshake, and optional account switch. */\n public async auth(): Promise<void> {\n return auth(this._ctx);\n }\n\n /** Connect to the broker with a persistent WebSocket: auth + persistent WS for data reuse and streaming. */\n public async connect(): Promise<void> {\n return connect(this._ctx);\n }\n\n /** Close the persistent WebSocket connection. */\n public disconnect(): void {\n return disconnect(this._ctx);\n }\n}\n"],"mappings":"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","names":["ORDER_TYPE","SIDE","ACTION","TIF","ERROR","WS_MESSAGE","SUBTOPIC","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket"]}
package/llms.txt CHANGED
@@ -18,46 +18,54 @@ const client = new DxtradeClient({
18
18
  accountId: "optional_account_id",
19
19
  });
20
20
 
21
- await client.connect();
21
+ await client.connect(); // auth + persistent WebSocket (recommended)
22
+ // or: await client.auth(); // lightweight, no persistent WS
22
23
 
23
24
  ## Available Methods
24
25
 
25
26
  ### Session
26
- - client.connect() — Login, fetch CSRF, WebSocket handshake, optional account switch. Call this first.
27
- - client.login() — Authenticate with broker (called automatically by connect)
28
- - client.fetchCsrf() — Fetch CSRF token (called automatically by connect)
27
+ - client.connect() — Auth + persistent WebSocket. Recommended for most use cases. Call this first.
28
+ - client.auth() — Lightweight: login, fetch CSRF, WebSocket handshake, optional account switch. No persistent WS.
29
+ - client.disconnect() — Close the persistent WebSocket connection
30
+ - client.login() — Authenticate with broker (called automatically by connect/auth)
31
+ - client.fetchCsrf() — Fetch CSRF token (called automatically by connect/auth)
29
32
  - client.switchAccount(accountId: string) — Switch to a specific trading account
30
33
 
31
- ### Market Data
32
- - client.getSymbolSuggestions(text: string) — Search symbols by name, returns Symbol.Suggestion[]
33
- - client.getSymbolInfo(symbol: string) — Get instrument info (volume limits, lot size), returns Symbol.Info
34
- - client.getSymbolLimits() — Get order size limits for all symbols, returns Symbol.Limits[]
35
- - client.getInstruments(params?: Partial<Instrument.Info>) — Get all instruments, optionally filtered (e.g. { type: "FOREX" })
36
- - client.getOHLC(params: OHLC.Params) — Fetch OHLC price bars for a symbol, returns OHLC.Bar[]
37
- Required params: symbol (string)
38
- Optional params: resolution (seconds, default 300), range (seconds, default 345600), maxBars (default 3500), priceField ("bid" | "ask", default "bid")
39
-
40
- ### Trading
41
- - client.submitOrder(params: Order.SubmitParams) — Submit order and wait for WebSocket confirmation, returns Order.Update
34
+ ### Positions
35
+ - client.positions.get() — Get all open positions with P&L metrics merged (margin, plOpen, marketValue, etc.), returns Position.Full[]
36
+ - client.positions.close(params: Position.Close) — Close a position (supports partial closes via the quantity field)
37
+ - client.positions.closeAll() — Close all open positions with market orders
38
+ - client.positions.stream(callback: (positions: Position.Full[]) => void) Stream real-time position updates with live P&L (requires connect()). Returns unsubscribe function.
39
+
40
+ ### Orders
41
+ - client.orders.get() Get all pending/open orders, returns Order.Get[]
42
+ - client.orders.submit(params: Order.SubmitParams) — Submit order and wait for WebSocket confirmation, returns Order.Update
42
43
  Required params: symbol, side (SIDE.BUY | SIDE.SELL), quantity, orderType (ORDER_TYPE.MARKET | LIMIT | STOP), instrumentId
43
44
  Optional params: limitPrice, stopPrice, stopLoss, takeProfit, timeInForce (TIF.GTC | DAY | GTD)
44
- - client.getOrders() — Get all pending/open orders via WebSocket, returns Order.Get[]
45
- - client.cancelOrder(orderChainId: number) — Cancel a single pending order by its order chain ID
46
- - client.cancelAllOrders() — Cancel all pending orders (fetches orders then cancels each)
47
-
48
- ### Positions
49
- - client.getPositions() — Get all open positions via WebSocket, returns Position.Get[]
50
- - client.closePosition(params: Position.Close) — Close a position (supports partial closes via the quantity field)
51
- - client.closeAllPositions() — Close all open positions with market orders
52
- - client.getPositionMetrics() — Get position-level P&L metrics via WebSocket, returns Position.Metrics[]
45
+ - client.orders.cancel(orderChainId: number) — Cancel a single pending order by its order chain ID
46
+ - client.orders.cancelAll() — Cancel all pending orders (fetches orders then cancels each)
53
47
 
54
48
  ### Account
55
- - client.getAccountMetrics() — Get equity, balance, margin, open P&L, returns Account.Metrics
56
- - client.getTradeJournal({ from: number, to: number }) — Fetch trade journal for date range (Unix timestamps)
57
- - client.getTradeHistory({ from: number, to: number }) — Fetch trade history for date range (Unix timestamps), returns Account.TradeHistory[]
49
+ - client.account.metrics() — Get equity, balance, margin, open P&L, returns Account.Metrics
50
+ - client.account.tradeJournal({ from: number, to: number }) — Fetch trade journal for date range (Unix timestamps)
51
+ - client.account.tradeHistory({ from: number, to: number }) — Fetch trade history for date range (Unix timestamps), returns Account.TradeHistory[]
52
+
53
+ ### Symbols
54
+ - client.symbols.search(text: string) — Search symbols by name, returns Symbol.Suggestion[]
55
+ - client.symbols.info(symbol: string) — Get instrument info (volume limits, lot size), returns Symbol.Info
56
+ - client.symbols.limits() — Get order size limits for all symbols, returns Symbol.Limits[]
57
+
58
+ ### Instruments
59
+ - client.instruments.get(params?: Partial<Instrument.Info>) — Get all instruments, optionally filtered (e.g. { type: "FOREX" })
60
+
61
+ ### OHLC
62
+ - client.ohlc.get(params: OHLC.Params) — Fetch OHLC price bars for a symbol, returns OHLC.Bar[]
63
+ Required params: symbol (string)
64
+ Optional params: resolution (seconds, default 300), range (seconds, default 345600), maxBars (default 3500), priceField ("bid" | "ask", default "bid")
65
+ - client.ohlc.stream(params: OHLC.Params, callback: (bars: OHLC.Bar[]) => void) — Stream real-time OHLC bar updates (requires connect()). Returns Promise<() => void>. Callback receives snapshot bars first, then live updates.
58
66
 
59
- ### Analytics
60
- - client.getAssessments(params: Assessments.Params) — Fetch PnL assessments for a date range
67
+ ### Assessments
68
+ - client.assessments.get(params: Assessments.Params) — Fetch PnL assessments for a date range
61
69
 
62
70
  ## Enums
63
71
 
@@ -85,4 +93,4 @@ const client = new DxtradeClient({
85
93
  ## Error Handling
86
94
 
87
95
  All errors are instances of DxtradeError with properties: code (string) and message (string).
88
- Common error codes: NO_SESSION, ORDER_TIMEOUT, ORDER_ERROR, POSITION_CLOSE_ERROR.
96
+ Common error codes: NO_SESSION, ORDER_TIMEOUT, ORDER_ERROR, POSITION_CLOSE_ERROR, STREAM_REQUIRES_CONNECT.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danielgroen/dxtrade-api",
3
- "version": "1.0.23",
3
+ "version": "1.0.25",
4
4
  "description": "Unofficial TypeScript client for the DXtrade trading API. Connect, trade, and manage positions on any broker that supports DXtrade.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -24,23 +24,24 @@
24
24
  "test": "vitest run",
25
25
  "test:watch": "vitest",
26
26
  "=============== Examples ===============": "",
27
- "example:debug": "tsx examples/debug.ts",
28
- "example:account": "tsx examples/account-metrics.ts",
29
- "example:trade-journal": "tsx examples/trade-journal.ts",
30
27
  "example:connect": "tsx examples/connect.ts",
31
- "example:positions": "tsx examples/positions.ts",
32
- "example:close-position": "tsx examples/close-position.ts",
33
- "example:close-all-positions": "tsx examples/close-all-positions.ts",
34
- "example:position-metrics": "tsx examples/position-metrics.ts",
35
- "example:orders": "tsx examples/orders.ts",
36
- "example:assessments": "tsx examples/get-assessments.ts",
37
- "example:assessments:btc": "tsx examples/get-assessments.ts BTCUSD",
38
- "example:instruments": "tsx examples/instruments.ts",
39
- "example:instruments:forex": "tsx examples/instruments.ts FOREX",
40
- "example:symbol": "tsx examples/symbol-info.ts",
41
- "example:ohlc": "tsx examples/ohlc.ts",
42
- "example:trade-history": "tsx examples/trade-history.ts",
43
- "example:symbol:btc": "tsx examples/symbol-info.ts BTCUSD",
28
+ "example:positions:get": "tsx examples/positions.get.ts",
29
+ "example:positions:close": "tsx examples/positions.close.ts",
30
+ "example:positions:close-all": "tsx examples/positions.close-all.ts",
31
+ "example:positions:stream": "tsx examples/positions.stream.ts",
32
+ "example:orders:submit": "tsx examples/orders.submit.ts",
33
+ "example:account:metrics": "tsx examples/account.metrics.ts",
34
+ "example:account:trade-journal": "tsx examples/account.trade-journal.ts",
35
+ "example:account:trade-history": "tsx examples/account.trade-history.ts",
36
+ "example:symbols:info": "tsx examples/symbols.info.ts",
37
+ "example:symbols:info:btc": "tsx examples/symbols.info.ts BTCUSD",
38
+ "example:instruments:get": "tsx examples/instruments.get.ts",
39
+ "example:instruments:get:forex": "tsx examples/instruments.get.ts FOREX",
40
+ "example:ohlc:get": "tsx examples/ohlc.get.ts",
41
+ "example:ohlc:stream": "tsx examples/ohlc.stream.ts",
42
+ "example:ohlc:stream:btc": "tsx examples/ohlc.stream.ts BTCUSD",
43
+ "example:assessments:get": "tsx examples/assessments.get.ts",
44
+ "example:assessments:get:btc": "tsx examples/assessments.get.ts BTCUSD",
44
45
  "============= Git =============": "",
45
46
  "commit": "COMMITIZEN=1 cz",
46
47
  "prepare": "sh scripts/setup-hooks.sh",