@danielgroen/dxtrade-api 1.0.18 → 1.0.19
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.
- package/README.md +8 -8
- package/dist/index.d.mts +37 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +21 -0
- package/dist/index.mjs.map +1 -1
- package/llms.txt +79 -0
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -4,11 +4,17 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/@danielgroen/dxtrade-api)
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
[](https://github.com/danielgroen/dxtrade-api/actions/workflows/tests.yml)
|
|
7
|
-
[](https://github.com/danielgroen/dxtrade-api/actions/workflows/publish.yml)
|
|
8
8
|
|
|
9
9
|
[](https://demo.dx.trade/developers/#/)
|
|
10
10
|
|
|
11
|
-
TypeScript client
|
|
11
|
+
Unofficial TypeScript client for the DXtrade trading API. Connect, trade, and manage positions on any broker that supports DXtrade.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install dxtrade-api
|
|
17
|
+
```
|
|
12
18
|
|
|
13
19
|
## Features
|
|
14
20
|
|
|
@@ -25,12 +31,6 @@ TypeScript client library for the DXtrade trading API based upon Nodejs.
|
|
|
25
31
|
- [ ] Real-time price streaming
|
|
26
32
|
- [ ] Order history
|
|
27
33
|
|
|
28
|
-
## Install
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
npm install dxtrade-api
|
|
32
|
-
```
|
|
33
|
-
|
|
34
34
|
## Quick Start
|
|
35
35
|
|
|
36
36
|
```ts
|
package/dist/index.d.mts
CHANGED
|
@@ -299,25 +299,62 @@ declare namespace Symbol {
|
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
301
|
|
|
302
|
+
/**
|
|
303
|
+
* Client for interacting with the DXtrade trading API.
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* ```ts
|
|
307
|
+
* import { DxtradeClient, ORDER_TYPE, SIDE, BROKER } from "dxtrade-api";
|
|
308
|
+
*
|
|
309
|
+
* const client = new DxtradeClient({
|
|
310
|
+
* username: "your_username",
|
|
311
|
+
* password: "your_password",
|
|
312
|
+
* broker: BROKER.FTMO,
|
|
313
|
+
* });
|
|
314
|
+
*
|
|
315
|
+
* await client.connect();
|
|
316
|
+
* ```
|
|
317
|
+
*/
|
|
302
318
|
declare class DxtradeClient {
|
|
303
319
|
private _ctx;
|
|
304
320
|
constructor(config: DxtradeConfig);
|
|
321
|
+
/** Authenticate with the broker using username and password. */
|
|
305
322
|
login(): Promise<void>;
|
|
323
|
+
/** Fetch the CSRF token required for authenticated requests. */
|
|
306
324
|
fetchCsrf(): Promise<void>;
|
|
325
|
+
/** Switch to a specific trading account by ID. */
|
|
307
326
|
switchAccount(accountId: string): Promise<void>;
|
|
327
|
+
/** Connect to the broker: login, fetch CSRF, WebSocket handshake, and optional account switch. */
|
|
308
328
|
connect(): Promise<void>;
|
|
329
|
+
/** Search for symbols matching the given text (e.g. "EURUSD", "BTC"). */
|
|
309
330
|
getSymbolSuggestions(text: string): Promise<Symbol.Suggestion[]>;
|
|
331
|
+
/** Get detailed instrument info for a symbol, including volume limits and lot size. */
|
|
310
332
|
getSymbolInfo(symbol: string): Promise<Symbol.Info>;
|
|
333
|
+
/** Get order size limits and stop/limit distances for all symbols. */
|
|
311
334
|
getSymbolLimits(): Promise<Symbol.Limits[]>;
|
|
335
|
+
/**
|
|
336
|
+
* Submit a trading order and wait for WebSocket confirmation.
|
|
337
|
+
* Supports market, limit, and stop orders with optional stop loss and take profit.
|
|
338
|
+
*/
|
|
312
339
|
submitOrder(params: Order.SubmitParams): Promise<Order.Update>;
|
|
340
|
+
/** Get account metrics including equity, balance, margin, and open P&L. */
|
|
313
341
|
getAccountMetrics(): Promise<Account.Metrics>;
|
|
342
|
+
/** Get all open positions via WebSocket. */
|
|
314
343
|
getPositions(): Promise<Position.Get[]>;
|
|
344
|
+
/** Close a position. */
|
|
315
345
|
closePosition(position: Position.Close): Promise<void>;
|
|
346
|
+
/**
|
|
347
|
+
* Fetch trade journal entries for a date range.
|
|
348
|
+
* @param params.from - Start timestamp (Unix ms)
|
|
349
|
+
* @param params.to - End timestamp (Unix ms)
|
|
350
|
+
*/
|
|
316
351
|
getTradeJournal(params: {
|
|
317
352
|
from: number;
|
|
318
353
|
to: number;
|
|
319
354
|
}): Promise<any>;
|
|
355
|
+
/** Get all available instruments, optionally filtered by partial match (e.g. `{ type: "FOREX" }`). */
|
|
320
356
|
getInstruments(params?: Partial<Instrument.Info>): Promise<Instrument.Info[]>;
|
|
357
|
+
/** Fetch PnL assessments for an instrument within a date range. */
|
|
321
358
|
getAssessments(params: Assessments.Params): Promise<Assessments.Response>;
|
|
322
359
|
}
|
|
323
360
|
|
package/dist/index.d.ts
CHANGED
|
@@ -299,25 +299,62 @@ declare namespace Symbol {
|
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
301
|
|
|
302
|
+
/**
|
|
303
|
+
* Client for interacting with the DXtrade trading API.
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* ```ts
|
|
307
|
+
* import { DxtradeClient, ORDER_TYPE, SIDE, BROKER } from "dxtrade-api";
|
|
308
|
+
*
|
|
309
|
+
* const client = new DxtradeClient({
|
|
310
|
+
* username: "your_username",
|
|
311
|
+
* password: "your_password",
|
|
312
|
+
* broker: BROKER.FTMO,
|
|
313
|
+
* });
|
|
314
|
+
*
|
|
315
|
+
* await client.connect();
|
|
316
|
+
* ```
|
|
317
|
+
*/
|
|
302
318
|
declare class DxtradeClient {
|
|
303
319
|
private _ctx;
|
|
304
320
|
constructor(config: DxtradeConfig);
|
|
321
|
+
/** Authenticate with the broker using username and password. */
|
|
305
322
|
login(): Promise<void>;
|
|
323
|
+
/** Fetch the CSRF token required for authenticated requests. */
|
|
306
324
|
fetchCsrf(): Promise<void>;
|
|
325
|
+
/** Switch to a specific trading account by ID. */
|
|
307
326
|
switchAccount(accountId: string): Promise<void>;
|
|
327
|
+
/** Connect to the broker: login, fetch CSRF, WebSocket handshake, and optional account switch. */
|
|
308
328
|
connect(): Promise<void>;
|
|
329
|
+
/** Search for symbols matching the given text (e.g. "EURUSD", "BTC"). */
|
|
309
330
|
getSymbolSuggestions(text: string): Promise<Symbol.Suggestion[]>;
|
|
331
|
+
/** Get detailed instrument info for a symbol, including volume limits and lot size. */
|
|
310
332
|
getSymbolInfo(symbol: string): Promise<Symbol.Info>;
|
|
333
|
+
/** Get order size limits and stop/limit distances for all symbols. */
|
|
311
334
|
getSymbolLimits(): Promise<Symbol.Limits[]>;
|
|
335
|
+
/**
|
|
336
|
+
* Submit a trading order and wait for WebSocket confirmation.
|
|
337
|
+
* Supports market, limit, and stop orders with optional stop loss and take profit.
|
|
338
|
+
*/
|
|
312
339
|
submitOrder(params: Order.SubmitParams): Promise<Order.Update>;
|
|
340
|
+
/** Get account metrics including equity, balance, margin, and open P&L. */
|
|
313
341
|
getAccountMetrics(): Promise<Account.Metrics>;
|
|
342
|
+
/** Get all open positions via WebSocket. */
|
|
314
343
|
getPositions(): Promise<Position.Get[]>;
|
|
344
|
+
/** Close a position. */
|
|
315
345
|
closePosition(position: Position.Close): Promise<void>;
|
|
346
|
+
/**
|
|
347
|
+
* Fetch trade journal entries for a date range.
|
|
348
|
+
* @param params.from - Start timestamp (Unix ms)
|
|
349
|
+
* @param params.to - End timestamp (Unix ms)
|
|
350
|
+
*/
|
|
316
351
|
getTradeJournal(params: {
|
|
317
352
|
from: number;
|
|
318
353
|
to: number;
|
|
319
354
|
}): Promise<any>;
|
|
355
|
+
/** Get all available instruments, optionally filtered by partial match (e.g. `{ type: "FOREX" }`). */
|
|
320
356
|
getInstruments(params?: Partial<Instrument.Info>): Promise<Instrument.Info[]>;
|
|
357
|
+
/** Fetch PnL assessments for an instrument within a date range. */
|
|
321
358
|
getAssessments(params: Assessments.Params): Promise<Assessments.Response>;
|
|
322
359
|
}
|
|
323
360
|
|
package/dist/index.js
CHANGED
|
@@ -756,45 +756,66 @@ var DxtradeClient = class {
|
|
|
756
756
|
}
|
|
757
757
|
};
|
|
758
758
|
}
|
|
759
|
+
/** Authenticate with the broker using username and password. */
|
|
759
760
|
async login() {
|
|
760
761
|
return login(this._ctx);
|
|
761
762
|
}
|
|
763
|
+
/** Fetch the CSRF token required for authenticated requests. */
|
|
762
764
|
async fetchCsrf() {
|
|
763
765
|
return fetchCsrf(this._ctx);
|
|
764
766
|
}
|
|
767
|
+
/** Switch to a specific trading account by ID. */
|
|
765
768
|
async switchAccount(accountId) {
|
|
766
769
|
return switchAccount(this._ctx, accountId);
|
|
767
770
|
}
|
|
771
|
+
/** Connect to the broker: login, fetch CSRF, WebSocket handshake, and optional account switch. */
|
|
768
772
|
async connect() {
|
|
769
773
|
return connect(this._ctx);
|
|
770
774
|
}
|
|
775
|
+
/** Search for symbols matching the given text (e.g. "EURUSD", "BTC"). */
|
|
771
776
|
async getSymbolSuggestions(text) {
|
|
772
777
|
return getSymbolSuggestions(this._ctx, text);
|
|
773
778
|
}
|
|
779
|
+
/** Get detailed instrument info for a symbol, including volume limits and lot size. */
|
|
774
780
|
async getSymbolInfo(symbol) {
|
|
775
781
|
return getSymbolInfo(this._ctx, symbol);
|
|
776
782
|
}
|
|
783
|
+
/** Get order size limits and stop/limit distances for all symbols. */
|
|
777
784
|
async getSymbolLimits() {
|
|
778
785
|
return getSymbolLimits(this._ctx);
|
|
779
786
|
}
|
|
787
|
+
/**
|
|
788
|
+
* Submit a trading order and wait for WebSocket confirmation.
|
|
789
|
+
* Supports market, limit, and stop orders with optional stop loss and take profit.
|
|
790
|
+
*/
|
|
780
791
|
async submitOrder(params) {
|
|
781
792
|
return submitOrder(this._ctx, params);
|
|
782
793
|
}
|
|
794
|
+
/** Get account metrics including equity, balance, margin, and open P&L. */
|
|
783
795
|
async getAccountMetrics() {
|
|
784
796
|
return getAccountMetrics(this._ctx);
|
|
785
797
|
}
|
|
798
|
+
/** Get all open positions via WebSocket. */
|
|
786
799
|
async getPositions() {
|
|
787
800
|
return getPositions(this._ctx);
|
|
788
801
|
}
|
|
802
|
+
/** Close a position. */
|
|
789
803
|
async closePosition(position) {
|
|
790
804
|
return closePosition(this._ctx, position);
|
|
791
805
|
}
|
|
806
|
+
/**
|
|
807
|
+
* Fetch trade journal entries for a date range.
|
|
808
|
+
* @param params.from - Start timestamp (Unix ms)
|
|
809
|
+
* @param params.to - End timestamp (Unix ms)
|
|
810
|
+
*/
|
|
792
811
|
async getTradeJournal(params) {
|
|
793
812
|
return getTradeJournal(this._ctx, params);
|
|
794
813
|
}
|
|
814
|
+
/** Get all available instruments, optionally filtered by partial match (e.g. `{ type: "FOREX" }`). */
|
|
795
815
|
async getInstruments(params = {}) {
|
|
796
816
|
return getInstruments(this._ctx, params);
|
|
797
817
|
}
|
|
818
|
+
/** Fetch PnL assessments for an instrument within a date range. */
|
|
798
819
|
async getAssessments(params) {
|
|
799
820
|
return getAssessments(this._ctx, params);
|
|
800
821
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../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/order/order.ts","../src/domains/symbol/symbol.ts","../src/domains/position/position.ts","../src/domains/session/session.ts","../src/client.ts"],"sourcesContent":["export * from \"./constants\";\nexport type { DxtradeConfig, DxtradeCallbacks } from \"./client.types\";\nexport type { WsPayload } from \"./utils/websocket.types\";\nexport { DxtradeClient } from \"./client\";\n","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","const websocketQuery =\n `?X-Atmosphere-tracking-id=0&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\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 assessments: (base: string) => `${base}/api/assessments`,\n\n websocket: (base: string) => `wss://${base.split(\"//\")[1]}/client/connector` + websocketQuery,\n\n tradeJournal: (base: string, params: { from: number; to: number }) =>\n `${base}/api/tradejournal?from=${params.from}&to=${params.to}`,\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 WS_MESSAGE {\n ACCOUNT_METRICS = \"ACCOUNT_METRICS\",\n ACCOUNTS = \"ACCOUNTS\",\n AVAILABLE_WATCHLISTS = \"AVAILABLE_WATCHLISTS\",\n INSTRUMENTS = \"INSTRUMENTS\",\n LIMITS = \"LIMITS\",\n MESSAGE = \"MESSAGE\",\n ORDERS = \"ORDERS\",\n POSITIONS = \"POSITIONS\",\n POSITION_CASH_TRANSFERS = \"POSITION_CASH_TRANSFERS\",\n PRIVATE_LAYOUT_NAMES = \"PRIVATE_LAYOUT_NAMES\",\n SHARED_PROPERTIES_MESSAGE = \"SHARED_PROPERTIES_MESSAGE\",\n USER_LOGIN_INFO = \"USER_LOGIN_INFO\",\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, 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);\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(\"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(\"ACCOUNT_METRICS_ERROR\", `Account metrics error: ${error.message}`));\n });\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(\"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(\"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 } 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}`);\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 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 } 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(\"ASSESSMENTS_ERROR\", `Error fetching assessments: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\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);\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(\"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(\"INSTRUMENTS_ERROR\", `Instruments error: ${error.message}`));\n });\n });\n}\n","import crypto from \"crypto\";\nimport WebSocket from \"ws\";\nimport { endpoints, ORDER_TYPE, SIDE, ACTION, DxtradeError } 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 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);\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(\"ORDER_ERROR\", `Error submitting order: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\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(\"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(\"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(\"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(\"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);\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(\"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(\"LIMITS_ERROR\", `Symbol limits error: ${error.message}`));\n });\n });\n}\n","import WebSocket from \"ws\";\nimport { WS_MESSAGE, 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);\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(\"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(\"ACCOUNT_POSITIONS_ERROR\", `Account positions error: ${error.message}`));\n });\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(\"POSITION_CLOSE_ERROR\", `Position close error: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport {\n Cookies,\n authHeaders,\n cookieOnlyHeaders,\n retryRequest,\n clearDebugLog,\n parseWsData,\n shouldLog,\n debugLog,\n} from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\n\nfunction waitForHandshake(\n wsUrl: string,\n cookieStr: string,\n timeout = 30_000,\n debug: boolean | string = false,\n): Promise<void> {\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 Error(\"[dxtrade-api] Handshake timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\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();\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 domain: ctx.config.broker,\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(\"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(\"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(\"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(\"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(\"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 wsUrl = endpoints.websocket(ctx.broker);\n const cookieStr = Cookies.serialize(ctx.cookies);\n await waitForHandshake(wsUrl, cookieStr, 30_000, ctx.debug);\n\n if (ctx.config.accountId) {\n await switchAccount(ctx, ctx.config.accountId);\n await waitForHandshake(endpoints.websocket(ctx.broker), Cookies.serialize(ctx.cookies), 30_000, ctx.debug);\n }\n}\n","import { DxtradeError } from \"@/constants\";\nimport type { ClientContext, DxtradeConfig } from \"./client.types\";\nimport type { Account, Assessments, Instrument, Order, Position, Symbol } from \"./domains\";\nimport {\n login,\n fetchCsrf,\n switchAccount,\n connect,\n getAccountMetrics,\n getPositions,\n closePosition,\n getAssessments,\n getInstruments,\n getSymbolLimits,\n getSymbolSuggestions,\n getSymbolInfo,\n submitOrder,\n getTradeJournal,\n} from \"@/domains\";\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 broker: config.broker,\n retries: config.retries ?? 3,\n debug: config.debug ?? false,\n ensureSession() {\n if (!this.csrf) {\n throw new DxtradeError(\"NO_SESSION\", \"No active session. Call login() and fetchCsrf() 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\n public async login(): Promise<void> {\n return login(this._ctx);\n }\n\n public async fetchCsrf(): Promise<void> {\n return fetchCsrf(this._ctx);\n }\n\n public async switchAccount(accountId: string): Promise<void> {\n return switchAccount(this._ctx, accountId);\n }\n\n public async connect(): Promise<void> {\n return connect(this._ctx);\n }\n\n public async getSymbolSuggestions(text: string): Promise<Symbol.Suggestion[]> {\n return getSymbolSuggestions(this._ctx, text);\n }\n\n public async getSymbolInfo(symbol: string): Promise<Symbol.Info> {\n return getSymbolInfo(this._ctx, symbol);\n }\n\n public async getSymbolLimits(): Promise<Symbol.Limits[]> {\n return getSymbolLimits(this._ctx);\n }\n\n public async submitOrder(params: Order.SubmitParams): Promise<Order.Update> {\n return submitOrder(this._ctx, params);\n }\n\n public async getAccountMetrics(): Promise<Account.Metrics> {\n return getAccountMetrics(this._ctx);\n }\n\n public async getPositions(): Promise<Position.Get[]> {\n return getPositions(this._ctx);\n }\n\n public async closePosition(position: Position.Close): Promise<void> {\n return closePosition(this._ctx, position);\n }\n\n public async getTradeJournal(params: { from: number; to: number }): Promise<any> {\n return getTradeJournal(this._ctx, params);\n }\n\n public async getInstruments(params: Partial<Instrument.Info> = {}): Promise<Instrument.Info[]> {\n return getInstruments(this._ctx, params);\n }\n\n public async getAssessments(params: Assessments.Params): Promise<Assessments.Response> {\n return getAssessments(this._ctx, params);\n }\n}\n"],"mappings":"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","names":["ORDER_TYPE","SIDE","ACTION","TIF","WS_MESSAGE","axios","WebSocket","import_ws","WebSocket","import_ws","import_ws","WebSocket","WebSocket","crypto","import_ws","WebSocket","import_ws","WebSocket"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../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/order/order.ts","../src/domains/symbol/symbol.ts","../src/domains/position/position.ts","../src/domains/session/session.ts","../src/client.ts"],"sourcesContent":["export * from \"./constants\";\nexport type { DxtradeConfig, DxtradeCallbacks } from \"./client.types\";\nexport type { WsPayload } from \"./utils/websocket.types\";\nexport { DxtradeClient } from \"./client\";\n","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","const websocketQuery =\n `?X-Atmosphere-tracking-id=0&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\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 assessments: (base: string) => `${base}/api/assessments`,\n\n websocket: (base: string) => `wss://${base.split(\"//\")[1]}/client/connector` + websocketQuery,\n\n tradeJournal: (base: string, params: { from: number; to: number }) =>\n `${base}/api/tradejournal?from=${params.from}&to=${params.to}`,\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 WS_MESSAGE {\n ACCOUNT_METRICS = \"ACCOUNT_METRICS\",\n ACCOUNTS = \"ACCOUNTS\",\n AVAILABLE_WATCHLISTS = \"AVAILABLE_WATCHLISTS\",\n INSTRUMENTS = \"INSTRUMENTS\",\n LIMITS = \"LIMITS\",\n MESSAGE = \"MESSAGE\",\n ORDERS = \"ORDERS\",\n POSITIONS = \"POSITIONS\",\n POSITION_CASH_TRANSFERS = \"POSITION_CASH_TRANSFERS\",\n PRIVATE_LAYOUT_NAMES = \"PRIVATE_LAYOUT_NAMES\",\n SHARED_PROPERTIES_MESSAGE = \"SHARED_PROPERTIES_MESSAGE\",\n USER_LOGIN_INFO = \"USER_LOGIN_INFO\",\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, 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);\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(\"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(\"ACCOUNT_METRICS_ERROR\", `Account metrics error: ${error.message}`));\n });\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(\"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(\"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 } 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}`);\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 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 } 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(\"ASSESSMENTS_ERROR\", `Error fetching assessments: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\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);\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(\"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(\"INSTRUMENTS_ERROR\", `Instruments error: ${error.message}`));\n });\n });\n}\n","import crypto from \"crypto\";\nimport WebSocket from \"ws\";\nimport { endpoints, ORDER_TYPE, SIDE, ACTION, DxtradeError } 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 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);\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(\"ORDER_ERROR\", `Error submitting order: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\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(\"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(\"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(\"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(\"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);\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(\"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(\"LIMITS_ERROR\", `Symbol limits error: ${error.message}`));\n });\n });\n}\n","import WebSocket from \"ws\";\nimport { WS_MESSAGE, 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);\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(\"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(\"ACCOUNT_POSITIONS_ERROR\", `Account positions error: ${error.message}`));\n });\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(\"POSITION_CLOSE_ERROR\", `Position close error: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport {\n Cookies,\n authHeaders,\n cookieOnlyHeaders,\n retryRequest,\n clearDebugLog,\n parseWsData,\n shouldLog,\n debugLog,\n} from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\n\nfunction waitForHandshake(\n wsUrl: string,\n cookieStr: string,\n timeout = 30_000,\n debug: boolean | string = false,\n): Promise<void> {\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 Error(\"[dxtrade-api] Handshake timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\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();\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 domain: ctx.config.broker,\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(\"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(\"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(\"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(\"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(\"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 wsUrl = endpoints.websocket(ctx.broker);\n const cookieStr = Cookies.serialize(ctx.cookies);\n await waitForHandshake(wsUrl, cookieStr, 30_000, ctx.debug);\n\n if (ctx.config.accountId) {\n await switchAccount(ctx, ctx.config.accountId);\n await waitForHandshake(endpoints.websocket(ctx.broker), Cookies.serialize(ctx.cookies), 30_000, ctx.debug);\n }\n}\n","import { DxtradeError } from \"@/constants\";\nimport type { ClientContext, DxtradeConfig } from \"./client.types\";\nimport type { Account, Assessments, Instrument, Order, Position, Symbol } from \"./domains\";\nimport {\n login,\n fetchCsrf,\n switchAccount,\n connect,\n getAccountMetrics,\n getPositions,\n closePosition,\n getAssessments,\n getInstruments,\n getSymbolLimits,\n getSymbolSuggestions,\n getSymbolInfo,\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 broker: config.broker,\n retries: config.retries ?? 3,\n debug: config.debug ?? false,\n ensureSession() {\n if (!this.csrf) {\n throw new DxtradeError(\"NO_SESSION\", \"No active session. Call login() and fetchCsrf() 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\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 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 /** Close a position. */\n public async closePosition(position: Position.Close): Promise<void> {\n return closePosition(this._ctx, position);\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 /** 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"],"mappings":"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","names":["ORDER_TYPE","SIDE","ACTION","TIF","WS_MESSAGE","axios","WebSocket","import_ws","WebSocket","import_ws","import_ws","WebSocket","WebSocket","crypto","import_ws","WebSocket","import_ws","WebSocket"]}
|
package/dist/index.mjs
CHANGED
|
@@ -712,45 +712,66 @@ var DxtradeClient = class {
|
|
|
712
712
|
}
|
|
713
713
|
};
|
|
714
714
|
}
|
|
715
|
+
/** Authenticate with the broker using username and password. */
|
|
715
716
|
async login() {
|
|
716
717
|
return login(this._ctx);
|
|
717
718
|
}
|
|
719
|
+
/** Fetch the CSRF token required for authenticated requests. */
|
|
718
720
|
async fetchCsrf() {
|
|
719
721
|
return fetchCsrf(this._ctx);
|
|
720
722
|
}
|
|
723
|
+
/** Switch to a specific trading account by ID. */
|
|
721
724
|
async switchAccount(accountId) {
|
|
722
725
|
return switchAccount(this._ctx, accountId);
|
|
723
726
|
}
|
|
727
|
+
/** Connect to the broker: login, fetch CSRF, WebSocket handshake, and optional account switch. */
|
|
724
728
|
async connect() {
|
|
725
729
|
return connect(this._ctx);
|
|
726
730
|
}
|
|
731
|
+
/** Search for symbols matching the given text (e.g. "EURUSD", "BTC"). */
|
|
727
732
|
async getSymbolSuggestions(text) {
|
|
728
733
|
return getSymbolSuggestions(this._ctx, text);
|
|
729
734
|
}
|
|
735
|
+
/** Get detailed instrument info for a symbol, including volume limits and lot size. */
|
|
730
736
|
async getSymbolInfo(symbol) {
|
|
731
737
|
return getSymbolInfo(this._ctx, symbol);
|
|
732
738
|
}
|
|
739
|
+
/** Get order size limits and stop/limit distances for all symbols. */
|
|
733
740
|
async getSymbolLimits() {
|
|
734
741
|
return getSymbolLimits(this._ctx);
|
|
735
742
|
}
|
|
743
|
+
/**
|
|
744
|
+
* Submit a trading order and wait for WebSocket confirmation.
|
|
745
|
+
* Supports market, limit, and stop orders with optional stop loss and take profit.
|
|
746
|
+
*/
|
|
736
747
|
async submitOrder(params) {
|
|
737
748
|
return submitOrder(this._ctx, params);
|
|
738
749
|
}
|
|
750
|
+
/** Get account metrics including equity, balance, margin, and open P&L. */
|
|
739
751
|
async getAccountMetrics() {
|
|
740
752
|
return getAccountMetrics(this._ctx);
|
|
741
753
|
}
|
|
754
|
+
/** Get all open positions via WebSocket. */
|
|
742
755
|
async getPositions() {
|
|
743
756
|
return getPositions(this._ctx);
|
|
744
757
|
}
|
|
758
|
+
/** Close a position. */
|
|
745
759
|
async closePosition(position) {
|
|
746
760
|
return closePosition(this._ctx, position);
|
|
747
761
|
}
|
|
762
|
+
/**
|
|
763
|
+
* Fetch trade journal entries for a date range.
|
|
764
|
+
* @param params.from - Start timestamp (Unix ms)
|
|
765
|
+
* @param params.to - End timestamp (Unix ms)
|
|
766
|
+
*/
|
|
748
767
|
async getTradeJournal(params) {
|
|
749
768
|
return getTradeJournal(this._ctx, params);
|
|
750
769
|
}
|
|
770
|
+
/** Get all available instruments, optionally filtered by partial match (e.g. `{ type: "FOREX" }`). */
|
|
751
771
|
async getInstruments(params = {}) {
|
|
752
772
|
return getInstruments(this._ctx, params);
|
|
753
773
|
}
|
|
774
|
+
/** Fetch PnL assessments for an instrument within a date range. */
|
|
754
775
|
async getAssessments(params) {
|
|
755
776
|
return getAssessments(this._ctx, params);
|
|
756
777
|
}
|
package/dist/index.mjs.map
CHANGED
|
@@ -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/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","const websocketQuery =\n `?X-Atmosphere-tracking-id=0&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\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 assessments: (base: string) => `${base}/api/assessments`,\n\n websocket: (base: string) => `wss://${base.split(\"//\")[1]}/client/connector` + websocketQuery,\n\n tradeJournal: (base: string, params: { from: number; to: number }) =>\n `${base}/api/tradejournal?from=${params.from}&to=${params.to}`,\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 WS_MESSAGE {\n ACCOUNT_METRICS = \"ACCOUNT_METRICS\",\n ACCOUNTS = \"ACCOUNTS\",\n AVAILABLE_WATCHLISTS = \"AVAILABLE_WATCHLISTS\",\n INSTRUMENTS = \"INSTRUMENTS\",\n LIMITS = \"LIMITS\",\n MESSAGE = \"MESSAGE\",\n ORDERS = \"ORDERS\",\n POSITIONS = \"POSITIONS\",\n POSITION_CASH_TRANSFERS = \"POSITION_CASH_TRANSFERS\",\n PRIVATE_LAYOUT_NAMES = \"PRIVATE_LAYOUT_NAMES\",\n SHARED_PROPERTIES_MESSAGE = \"SHARED_PROPERTIES_MESSAGE\",\n USER_LOGIN_INFO = \"USER_LOGIN_INFO\",\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, 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);\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(\"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(\"ACCOUNT_METRICS_ERROR\", `Account metrics error: ${error.message}`));\n });\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(\"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(\"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 } 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}`);\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 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 } 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(\"ASSESSMENTS_ERROR\", `Error fetching assessments: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\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);\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(\"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(\"INSTRUMENTS_ERROR\", `Instruments error: ${error.message}`));\n });\n });\n}\n","import crypto from \"crypto\";\nimport WebSocket from \"ws\";\nimport { endpoints, ORDER_TYPE, SIDE, ACTION, DxtradeError } 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 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);\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(\"ORDER_ERROR\", `Error submitting order: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\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(\"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(\"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(\"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(\"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);\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(\"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(\"LIMITS_ERROR\", `Symbol limits error: ${error.message}`));\n });\n });\n}\n","import WebSocket from \"ws\";\nimport { WS_MESSAGE, 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);\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(\"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(\"ACCOUNT_POSITIONS_ERROR\", `Account positions error: ${error.message}`));\n });\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(\"POSITION_CLOSE_ERROR\", `Position close error: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport {\n Cookies,\n authHeaders,\n cookieOnlyHeaders,\n retryRequest,\n clearDebugLog,\n parseWsData,\n shouldLog,\n debugLog,\n} from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\n\nfunction waitForHandshake(\n wsUrl: string,\n cookieStr: string,\n timeout = 30_000,\n debug: boolean | string = false,\n): Promise<void> {\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 Error(\"[dxtrade-api] Handshake timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\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();\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 domain: ctx.config.broker,\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(\"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(\"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(\"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(\"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(\"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 wsUrl = endpoints.websocket(ctx.broker);\n const cookieStr = Cookies.serialize(ctx.cookies);\n await waitForHandshake(wsUrl, cookieStr, 30_000, ctx.debug);\n\n if (ctx.config.accountId) {\n await switchAccount(ctx, ctx.config.accountId);\n await waitForHandshake(endpoints.websocket(ctx.broker), Cookies.serialize(ctx.cookies), 30_000, ctx.debug);\n }\n}\n","import { DxtradeError } from \"@/constants\";\nimport type { ClientContext, DxtradeConfig } from \"./client.types\";\nimport type { Account, Assessments, Instrument, Order, Position, Symbol } from \"./domains\";\nimport {\n login,\n fetchCsrf,\n switchAccount,\n connect,\n getAccountMetrics,\n getPositions,\n closePosition,\n getAssessments,\n getInstruments,\n getSymbolLimits,\n getSymbolSuggestions,\n getSymbolInfo,\n submitOrder,\n getTradeJournal,\n} from \"@/domains\";\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 broker: config.broker,\n retries: config.retries ?? 3,\n debug: config.debug ?? false,\n ensureSession() {\n if (!this.csrf) {\n throw new DxtradeError(\"NO_SESSION\", \"No active session. Call login() and fetchCsrf() 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\n public async login(): Promise<void> {\n return login(this._ctx);\n }\n\n public async fetchCsrf(): Promise<void> {\n return fetchCsrf(this._ctx);\n }\n\n public async switchAccount(accountId: string): Promise<void> {\n return switchAccount(this._ctx, accountId);\n }\n\n public async connect(): Promise<void> {\n return connect(this._ctx);\n }\n\n public async getSymbolSuggestions(text: string): Promise<Symbol.Suggestion[]> {\n return getSymbolSuggestions(this._ctx, text);\n }\n\n public async getSymbolInfo(symbol: string): Promise<Symbol.Info> {\n return getSymbolInfo(this._ctx, symbol);\n }\n\n public async getSymbolLimits(): Promise<Symbol.Limits[]> {\n return getSymbolLimits(this._ctx);\n }\n\n public async submitOrder(params: Order.SubmitParams): Promise<Order.Update> {\n return submitOrder(this._ctx, params);\n }\n\n public async getAccountMetrics(): Promise<Account.Metrics> {\n return getAccountMetrics(this._ctx);\n }\n\n public async getPositions(): Promise<Position.Get[]> {\n return getPositions(this._ctx);\n }\n\n public async closePosition(position: Position.Close): Promise<void> {\n return closePosition(this._ctx, position);\n }\n\n public async getTradeJournal(params: { from: number; to: number }): Promise<any> {\n return getTradeJournal(this._ctx, params);\n }\n\n public async getInstruments(params: Partial<Instrument.Info> = {}): Promise<Instrument.Info[]> {\n return getInstruments(this._ctx, params);\n }\n\n public async getAssessments(params: Assessments.Params): Promise<Assessments.Response> {\n return getAssessments(this._ctx, params);\n }\n}\n"],"mappings":"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","names":["ORDER_TYPE","SIDE","ACTION","TIF","WS_MESSAGE","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/domains/assessments/assessments.ts","../src/domains/instrument/instrument.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","const websocketQuery =\n `?X-Atmosphere-tracking-id=0&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\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 assessments: (base: string) => `${base}/api/assessments`,\n\n websocket: (base: string) => `wss://${base.split(\"//\")[1]}/client/connector` + websocketQuery,\n\n tradeJournal: (base: string, params: { from: number; to: number }) =>\n `${base}/api/tradejournal?from=${params.from}&to=${params.to}`,\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 WS_MESSAGE {\n ACCOUNT_METRICS = \"ACCOUNT_METRICS\",\n ACCOUNTS = \"ACCOUNTS\",\n AVAILABLE_WATCHLISTS = \"AVAILABLE_WATCHLISTS\",\n INSTRUMENTS = \"INSTRUMENTS\",\n LIMITS = \"LIMITS\",\n MESSAGE = \"MESSAGE\",\n ORDERS = \"ORDERS\",\n POSITIONS = \"POSITIONS\",\n POSITION_CASH_TRANSFERS = \"POSITION_CASH_TRANSFERS\",\n PRIVATE_LAYOUT_NAMES = \"PRIVATE_LAYOUT_NAMES\",\n SHARED_PROPERTIES_MESSAGE = \"SHARED_PROPERTIES_MESSAGE\",\n USER_LOGIN_INFO = \"USER_LOGIN_INFO\",\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, 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);\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(\"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(\"ACCOUNT_METRICS_ERROR\", `Account metrics error: ${error.message}`));\n });\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(\"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(\"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 } 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}`);\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 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 } 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(\"ASSESSMENTS_ERROR\", `Error fetching assessments: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\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);\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(\"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(\"INSTRUMENTS_ERROR\", `Instruments error: ${error.message}`));\n });\n });\n}\n","import crypto from \"crypto\";\nimport WebSocket from \"ws\";\nimport { endpoints, ORDER_TYPE, SIDE, ACTION, DxtradeError } 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 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);\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(\"ORDER_ERROR\", `Error submitting order: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\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(\"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(\"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(\"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(\"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);\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(\"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(\"LIMITS_ERROR\", `Symbol limits error: ${error.message}`));\n });\n });\n}\n","import WebSocket from \"ws\";\nimport { WS_MESSAGE, 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);\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(\"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(\"ACCOUNT_POSITIONS_ERROR\", `Account positions error: ${error.message}`));\n });\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(\"POSITION_CLOSE_ERROR\", `Position close error: ${message}`);\n }\n}\n","import WebSocket from \"ws\";\nimport { endpoints, DxtradeError } from \"@/constants\";\nimport {\n Cookies,\n authHeaders,\n cookieOnlyHeaders,\n retryRequest,\n clearDebugLog,\n parseWsData,\n shouldLog,\n debugLog,\n} from \"@/utils\";\nimport type { ClientContext } from \"@/client.types\";\n\nfunction waitForHandshake(\n wsUrl: string,\n cookieStr: string,\n timeout = 30_000,\n debug: boolean | string = false,\n): Promise<void> {\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 Error(\"[dxtrade-api] Handshake timed out\"));\n }, timeout);\n\n ws.on(\"message\", (data) => {\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();\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 domain: ctx.config.broker,\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(\"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(\"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(\"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(\"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(\"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 wsUrl = endpoints.websocket(ctx.broker);\n const cookieStr = Cookies.serialize(ctx.cookies);\n await waitForHandshake(wsUrl, cookieStr, 30_000, ctx.debug);\n\n if (ctx.config.accountId) {\n await switchAccount(ctx, ctx.config.accountId);\n await waitForHandshake(endpoints.websocket(ctx.broker), Cookies.serialize(ctx.cookies), 30_000, ctx.debug);\n }\n}\n","import { DxtradeError } from \"@/constants\";\nimport type { ClientContext, DxtradeConfig } from \"./client.types\";\nimport type { Account, Assessments, Instrument, Order, Position, Symbol } from \"./domains\";\nimport {\n login,\n fetchCsrf,\n switchAccount,\n connect,\n getAccountMetrics,\n getPositions,\n closePosition,\n getAssessments,\n getInstruments,\n getSymbolLimits,\n getSymbolSuggestions,\n getSymbolInfo,\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 broker: config.broker,\n retries: config.retries ?? 3,\n debug: config.debug ?? false,\n ensureSession() {\n if (!this.csrf) {\n throw new DxtradeError(\"NO_SESSION\", \"No active session. Call login() and fetchCsrf() 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\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 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 /** Close a position. */\n public async closePosition(position: Position.Close): Promise<void> {\n return closePosition(this._ctx, position);\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 /** 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"],"mappings":"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","names":["ORDER_TYPE","SIDE","ACTION","TIF","WS_MESSAGE","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket","WebSocket"]}
|
package/llms.txt
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# DXtrade API
|
|
2
|
+
|
|
3
|
+
Unofficial TypeScript client for the DXtrade trading API.
|
|
4
|
+
Connect, trade, and manage positions on any broker that supports DXtrade.
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
npm install dxtrade-api
|
|
9
|
+
|
|
10
|
+
## Quick Start
|
|
11
|
+
|
|
12
|
+
import { DxtradeClient, ORDER_TYPE, SIDE, BROKER } from "dxtrade-api";
|
|
13
|
+
|
|
14
|
+
const client = new DxtradeClient({
|
|
15
|
+
username: "your_username",
|
|
16
|
+
password: "your_password",
|
|
17
|
+
broker: BROKER.FTMO,
|
|
18
|
+
accountId: "optional_account_id",
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
await client.connect();
|
|
22
|
+
|
|
23
|
+
## Available Methods
|
|
24
|
+
|
|
25
|
+
### 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)
|
|
29
|
+
- client.switchAccount(accountId: string) — Switch to a specific trading account
|
|
30
|
+
|
|
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
|
+
|
|
37
|
+
### Trading
|
|
38
|
+
- client.submitOrder(params: Order.SubmitParams) — Submit order and wait for WebSocket confirmation, returns Order.Update
|
|
39
|
+
Required params: symbol, side (SIDE.BUY | SIDE.SELL), quantity, orderType (ORDER_TYPE.MARKET | LIMIT | STOP), instrumentId
|
|
40
|
+
Optional params: limitPrice, stopPrice, stopLoss, takeProfit, timeInForce (TIF.GTC | DAY | GTD)
|
|
41
|
+
|
|
42
|
+
### Positions
|
|
43
|
+
- client.getPositions() — Get all open positions via WebSocket, returns Position.Get[]
|
|
44
|
+
- client.closePosition(params: Position.Close) — Close a position
|
|
45
|
+
|
|
46
|
+
### Account
|
|
47
|
+
- client.getAccountMetrics() — Get equity, balance, margin, open P&L, returns Account.Metrics
|
|
48
|
+
- client.getTradeJournal({ from: number, to: number }) — Fetch trade journal for date range (Unix timestamps)
|
|
49
|
+
|
|
50
|
+
### Analytics
|
|
51
|
+
- client.getAssessments(params: Assessments.Params) — Fetch PnL assessments for a date range
|
|
52
|
+
|
|
53
|
+
## Enums
|
|
54
|
+
|
|
55
|
+
import { ORDER_TYPE, SIDE, ACTION, TIF, BROKER } from "dxtrade-api";
|
|
56
|
+
|
|
57
|
+
ORDER_TYPE: MARKET, LIMIT, STOP
|
|
58
|
+
SIDE: BUY, SELL
|
|
59
|
+
ACTION: OPENING, CLOSING
|
|
60
|
+
TIF: GTC, DAY, GTD
|
|
61
|
+
BROKER: LARKFUNDING, EIGHTCAP, FTMO
|
|
62
|
+
|
|
63
|
+
## Callbacks
|
|
64
|
+
|
|
65
|
+
const client = new DxtradeClient({
|
|
66
|
+
...config,
|
|
67
|
+
callbacks: {
|
|
68
|
+
onLogin: () => {},
|
|
69
|
+
onAccountSwitch: (accountId: string) => {},
|
|
70
|
+
onOrderPlaced: (order: Order.Response) => {},
|
|
71
|
+
onOrderUpdate: (order: Order.Update) => {},
|
|
72
|
+
onError: (error: DxtradeError) => {},
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
## Error Handling
|
|
77
|
+
|
|
78
|
+
All errors are instances of DxtradeError with properties: code (string) and message (string).
|
|
79
|
+
Common error codes: NO_SESSION, ORDER_TIMEOUT, ORDER_ERROR, POSITION_CLOSE_ERROR.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danielgroen/dxtrade-api",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "DXtrade trading API
|
|
3
|
+
"version": "1.0.19",
|
|
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",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
|
-
"dist"
|
|
16
|
+
"dist",
|
|
17
|
+
"llms.txt"
|
|
17
18
|
],
|
|
18
19
|
"scripts": {
|
|
19
20
|
"================ Build ===============": "",
|