@danielgroen/dxtrade-api 1.0.10 → 1.0.12
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 +34 -8
- package/dist/index.d.mts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +31 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +31 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -14,12 +14,12 @@ npm install dxtrade-api
|
|
|
14
14
|
## Quick Start
|
|
15
15
|
|
|
16
16
|
```ts
|
|
17
|
-
import { DxtradeClient,
|
|
17
|
+
import { DxtradeClient, ORDER_TYPE, SIDE, BROKER } from "dxtrade-api";
|
|
18
18
|
|
|
19
19
|
const client = new DxtradeClient({
|
|
20
20
|
username: "your_username",
|
|
21
21
|
password: "your_password",
|
|
22
|
-
broker: "
|
|
22
|
+
broker: "LARKFUNDING",
|
|
23
23
|
accountId: "optional_account_id",
|
|
24
24
|
});
|
|
25
25
|
|
|
@@ -30,9 +30,9 @@ const symbol = suggestions[0];
|
|
|
30
30
|
|
|
31
31
|
const order = await client.submitOrder({
|
|
32
32
|
symbol: symbol.name,
|
|
33
|
-
side:
|
|
33
|
+
side: SIDE.BUY,
|
|
34
34
|
quantity: 0.01,
|
|
35
|
-
orderType:
|
|
35
|
+
orderType: ORDER_TYPE.MARKET,
|
|
36
36
|
instrumentId: symbol.id,
|
|
37
37
|
});
|
|
38
38
|
|
|
@@ -45,10 +45,11 @@ console.log(`Order ${order.orderId}: ${order.status}`);
|
|
|
45
45
|
|---|---|---|---|
|
|
46
46
|
| `username` | `string` | Yes | DXtrade account username |
|
|
47
47
|
| `password` | `string` | Yes | DXtrade account password |
|
|
48
|
-
| `broker` | `string` | Yes | Broker identifier (e.g. `"
|
|
48
|
+
| `broker` | `string` | Yes | Broker identifier (e.g. `"LARKFUNDING"`, `"EIGHTCAP"`) |
|
|
49
49
|
| `accountId` | `string` | No | Account ID to auto-switch after login |
|
|
50
50
|
| `brokerUrls` | `Record<string, string>` | No | Custom broker URL mapping |
|
|
51
51
|
| `retries` | `number` | No | Retry count for failed requests (default: 3) |
|
|
52
|
+
| `debug` | `boolean \| string` | No | Enable debug logging (`true` for all, or a WS message type to filter) |
|
|
52
53
|
| `callbacks` | `DxtradeCallbacks` | No | Event callbacks |
|
|
53
54
|
|
|
54
55
|
## Built-in Brokers
|
|
@@ -56,9 +57,9 @@ console.log(`Order ${order.orderId}: ${order.status}`);
|
|
|
56
57
|
```ts
|
|
57
58
|
import { BROKER } from "dxtrade-api";
|
|
58
59
|
|
|
59
|
-
BROKER.
|
|
60
|
-
BROKER.EIGHTCAP
|
|
61
|
-
BROKER.FTMO
|
|
60
|
+
BROKER.LARKFUNDING // "https://trade.gooeytrade.com"
|
|
61
|
+
BROKER.EIGHTCAP // "https://trader.dx-eightcap.com"
|
|
62
|
+
BROKER.FTMO // "https://dxtrade.ftmo.com"
|
|
62
63
|
```
|
|
63
64
|
|
|
64
65
|
## API
|
|
@@ -74,15 +75,33 @@ BROKER.FTMO // "https://trade.dx-ftmo.com"
|
|
|
74
75
|
|
|
75
76
|
- `client.getSymbolSuggestions(text)` — Search for symbols
|
|
76
77
|
- `client.getSymbolInfo(symbol)` — Get instrument info (volume limits, lot size)
|
|
78
|
+
- `client.getSymbolLimits()` — Get order size limits and stop/limit distances for all symbols
|
|
79
|
+
- `client.getInstruments(params?)` — Get all available instruments, optionally filtered by partial match (e.g. `{ type: "FOREX" }`)
|
|
77
80
|
|
|
78
81
|
### Trading
|
|
79
82
|
|
|
80
83
|
- `client.submitOrder(params)` — Submit an order and wait for WebSocket confirmation
|
|
81
84
|
|
|
85
|
+
### Account
|
|
86
|
+
|
|
87
|
+
- `client.getAccountMetrics()` — Get account metrics (equity, balance, margin, open P&L, etc.)
|
|
88
|
+
- `client.getTradeJournal({ from, to })` — Fetch trade journal entries for a date range (Unix timestamps)
|
|
89
|
+
|
|
82
90
|
### Analytics
|
|
83
91
|
|
|
84
92
|
- `client.getAssessments(params)` — Fetch PnL assessments for a date range
|
|
85
93
|
|
|
94
|
+
## Enums
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
import { ORDER_TYPE, SIDE, ACTION, TIF } from "dxtrade-api";
|
|
98
|
+
|
|
99
|
+
ORDER_TYPE.MARKET | ORDER_TYPE.LIMIT | ORDER_TYPE.STOP
|
|
100
|
+
SIDE.BUY | SIDE.SELL
|
|
101
|
+
ACTION.OPENING | ACTION.CLOSING
|
|
102
|
+
TIF.GTC | TIF.DAY | TIF.GTD
|
|
103
|
+
```
|
|
104
|
+
|
|
86
105
|
## Callbacks
|
|
87
106
|
|
|
88
107
|
```ts
|
|
@@ -105,6 +124,13 @@ cp .env.example .env # fill in credentials
|
|
|
105
124
|
npm run example:connect
|
|
106
125
|
npm run example:order
|
|
107
126
|
npm run example:assessments
|
|
127
|
+
npm run example:account
|
|
128
|
+
npm run example:instruments
|
|
129
|
+
npm run example:instruments:forex
|
|
130
|
+
npm run example:symbol
|
|
131
|
+
npm run example:symbol:btc
|
|
132
|
+
npm run example:trade-journal
|
|
133
|
+
npm run example:debug
|
|
108
134
|
```
|
|
109
135
|
|
|
110
136
|
## DXtrade API Docs
|
package/dist/index.d.mts
CHANGED
|
@@ -12,6 +12,10 @@ declare const endpoints: {
|
|
|
12
12
|
submitOrder: (base: string) => string;
|
|
13
13
|
assessments: (base: string) => string;
|
|
14
14
|
websocket: (base: string) => string;
|
|
15
|
+
tradeJournal: (base: string, params: {
|
|
16
|
+
from: number;
|
|
17
|
+
to: number;
|
|
18
|
+
}) => string;
|
|
15
19
|
};
|
|
16
20
|
|
|
17
21
|
declare enum ORDER_TYPE {
|
|
@@ -186,7 +190,7 @@ declare namespace Assessments {
|
|
|
186
190
|
from: number;
|
|
187
191
|
to: number;
|
|
188
192
|
instrument: string;
|
|
189
|
-
subtype?:
|
|
193
|
+
subtype?: "Agriculture" | "Cash CFD" | "Cash II CFD" | "Cash III CFD" | "Commodities" | "Crypto I CFD" | "Crypto II CFD" | "Equities I CFD" | "Equities II CFD" | "Exotics" | "Forex" | "Metals CFD" | null;
|
|
190
194
|
}
|
|
191
195
|
interface Response {
|
|
192
196
|
totalPL?: number;
|
|
@@ -272,6 +276,10 @@ declare class DxtradeClient {
|
|
|
272
276
|
getSymbolLimits(): Promise<Symbol.Limits[]>;
|
|
273
277
|
submitOrder(params: Order.SubmitParams): Promise<Order.Update>;
|
|
274
278
|
getAccountMetrics(): Promise<Account.Metrics>;
|
|
279
|
+
getTradeJournal(params: {
|
|
280
|
+
from: number;
|
|
281
|
+
to: number;
|
|
282
|
+
}): Promise<any>;
|
|
275
283
|
getInstruments(params?: Partial<Instrument.Info>): Promise<Instrument.Info[]>;
|
|
276
284
|
getAssessments(params: Assessments.Params): Promise<Assessments.Response>;
|
|
277
285
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,10 @@ declare const endpoints: {
|
|
|
12
12
|
submitOrder: (base: string) => string;
|
|
13
13
|
assessments: (base: string) => string;
|
|
14
14
|
websocket: (base: string) => string;
|
|
15
|
+
tradeJournal: (base: string, params: {
|
|
16
|
+
from: number;
|
|
17
|
+
to: number;
|
|
18
|
+
}) => string;
|
|
15
19
|
};
|
|
16
20
|
|
|
17
21
|
declare enum ORDER_TYPE {
|
|
@@ -186,7 +190,7 @@ declare namespace Assessments {
|
|
|
186
190
|
from: number;
|
|
187
191
|
to: number;
|
|
188
192
|
instrument: string;
|
|
189
|
-
subtype?:
|
|
193
|
+
subtype?: "Agriculture" | "Cash CFD" | "Cash II CFD" | "Cash III CFD" | "Commodities" | "Crypto I CFD" | "Crypto II CFD" | "Equities I CFD" | "Equities II CFD" | "Exotics" | "Forex" | "Metals CFD" | null;
|
|
190
194
|
}
|
|
191
195
|
interface Response {
|
|
192
196
|
totalPL?: number;
|
|
@@ -272,6 +276,10 @@ declare class DxtradeClient {
|
|
|
272
276
|
getSymbolLimits(): Promise<Symbol.Limits[]>;
|
|
273
277
|
submitOrder(params: Order.SubmitParams): Promise<Order.Update>;
|
|
274
278
|
getAccountMetrics(): Promise<Account.Metrics>;
|
|
279
|
+
getTradeJournal(params: {
|
|
280
|
+
from: number;
|
|
281
|
+
to: number;
|
|
282
|
+
}): Promise<any>;
|
|
275
283
|
getInstruments(params?: Partial<Instrument.Info>): Promise<Instrument.Info[]>;
|
|
276
284
|
getAssessments(params: Assessments.Params): Promise<Assessments.Response>;
|
|
277
285
|
}
|
package/dist/index.js
CHANGED
|
@@ -58,7 +58,8 @@ var endpoints = {
|
|
|
58
58
|
instrumentInfo: (base, symbol, tzOffset) => `${base}/api/instruments/info?symbol=${symbol}&timezoneOffset=${tzOffset}&withExDividends=true`,
|
|
59
59
|
submitOrder: (base) => `${base}/api/orders/single`,
|
|
60
60
|
assessments: (base) => `${base}/api/assessments`,
|
|
61
|
-
websocket: (base) => `wss://${base.split("//")[1]}/client/connector` + websocketQuery
|
|
61
|
+
websocket: (base) => `wss://${base.split("//")[1]}/client/connector` + websocketQuery,
|
|
62
|
+
tradeJournal: (base, params) => `${base}/api/tradejournal?from=${params.from}&to=${params.to}`
|
|
62
63
|
};
|
|
63
64
|
|
|
64
65
|
// src/constants/enums.ts
|
|
@@ -227,6 +228,32 @@ async function getAccountMetrics(ctx, timeout = 3e4) {
|
|
|
227
228
|
});
|
|
228
229
|
});
|
|
229
230
|
}
|
|
231
|
+
async function getTradeJournal(ctx, params) {
|
|
232
|
+
ctx.ensureSession();
|
|
233
|
+
try {
|
|
234
|
+
const cookieStr = Cookies.serialize(ctx.cookies);
|
|
235
|
+
const response = await retryRequest(
|
|
236
|
+
{
|
|
237
|
+
method: "GET",
|
|
238
|
+
url: endpoints.tradeJournal(ctx.broker, params),
|
|
239
|
+
headers: { ...baseHeaders(), Cookie: cookieStr }
|
|
240
|
+
},
|
|
241
|
+
ctx.retries
|
|
242
|
+
);
|
|
243
|
+
if (response.status === 200) {
|
|
244
|
+
const setCookies = response.headers["set-cookie"] ?? [];
|
|
245
|
+
const incoming = Cookies.parse(setCookies);
|
|
246
|
+
ctx.cookies = Cookies.merge(ctx.cookies, incoming);
|
|
247
|
+
return response.data;
|
|
248
|
+
} else {
|
|
249
|
+
ctx.throwError("TRADE_JOURNAL_ERROR", `Login failed: ${response.status}`);
|
|
250
|
+
}
|
|
251
|
+
} catch (error) {
|
|
252
|
+
if (error instanceof DxtradeError) throw error;
|
|
253
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
254
|
+
ctx.throwError("TRADE_JOURNAL_ERROR", `Trade journal error: ${message}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
230
257
|
|
|
231
258
|
// src/domains/assessments/assessments.ts
|
|
232
259
|
async function getAssessments(ctx, params) {
|
|
@@ -708,6 +735,9 @@ var DxtradeClient = class {
|
|
|
708
735
|
async getAccountMetrics() {
|
|
709
736
|
return getAccountMetrics(this._ctx);
|
|
710
737
|
}
|
|
738
|
+
async getTradeJournal(params) {
|
|
739
|
+
return getTradeJournal(this._ctx, params);
|
|
740
|
+
}
|
|
711
741
|
async getInstruments(params = {}) {
|
|
712
742
|
return getInstruments(this._ctx, params);
|
|
713
743
|
}
|
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/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 assessments: (base: string) => `${base}/api/assessments`,\n\n websocket: (base: string) => `wss://${base.split(\"//\")[1]}/client/connector` + websocketQuery,\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 { 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 { 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","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 { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\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.type === WS_MESSAGE.POSITIONS) {\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, Symbol } from \"./domains\";\nimport {\n login,\n fetchCsrf,\n switchAccount,\n connect,\n getAccountMetrics,\n getAssessments,\n getInstruments,\n getSymbolLimits,\n getSymbolSuggestions,\n getSymbolInfo,\n submitOrder,\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 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"]}
|
|
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/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 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 { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\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.type === WS_MESSAGE.POSITIONS) {\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, Symbol } from \"./domains\";\nimport {\n login,\n fetchCsrf,\n switchAccount,\n connect,\n getAccountMetrics,\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 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"]}
|
package/dist/index.mjs
CHANGED
|
@@ -14,7 +14,8 @@ var endpoints = {
|
|
|
14
14
|
instrumentInfo: (base, symbol, tzOffset) => `${base}/api/instruments/info?symbol=${symbol}&timezoneOffset=${tzOffset}&withExDividends=true`,
|
|
15
15
|
submitOrder: (base) => `${base}/api/orders/single`,
|
|
16
16
|
assessments: (base) => `${base}/api/assessments`,
|
|
17
|
-
websocket: (base) => `wss://${base.split("//")[1]}/client/connector` + websocketQuery
|
|
17
|
+
websocket: (base) => `wss://${base.split("//")[1]}/client/connector` + websocketQuery,
|
|
18
|
+
tradeJournal: (base, params) => `${base}/api/tradejournal?from=${params.from}&to=${params.to}`
|
|
18
19
|
};
|
|
19
20
|
|
|
20
21
|
// src/constants/enums.ts
|
|
@@ -183,6 +184,32 @@ async function getAccountMetrics(ctx, timeout = 3e4) {
|
|
|
183
184
|
});
|
|
184
185
|
});
|
|
185
186
|
}
|
|
187
|
+
async function getTradeJournal(ctx, params) {
|
|
188
|
+
ctx.ensureSession();
|
|
189
|
+
try {
|
|
190
|
+
const cookieStr = Cookies.serialize(ctx.cookies);
|
|
191
|
+
const response = await retryRequest(
|
|
192
|
+
{
|
|
193
|
+
method: "GET",
|
|
194
|
+
url: endpoints.tradeJournal(ctx.broker, params),
|
|
195
|
+
headers: { ...baseHeaders(), Cookie: cookieStr }
|
|
196
|
+
},
|
|
197
|
+
ctx.retries
|
|
198
|
+
);
|
|
199
|
+
if (response.status === 200) {
|
|
200
|
+
const setCookies = response.headers["set-cookie"] ?? [];
|
|
201
|
+
const incoming = Cookies.parse(setCookies);
|
|
202
|
+
ctx.cookies = Cookies.merge(ctx.cookies, incoming);
|
|
203
|
+
return response.data;
|
|
204
|
+
} else {
|
|
205
|
+
ctx.throwError("TRADE_JOURNAL_ERROR", `Login failed: ${response.status}`);
|
|
206
|
+
}
|
|
207
|
+
} catch (error) {
|
|
208
|
+
if (error instanceof DxtradeError) throw error;
|
|
209
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
210
|
+
ctx.throwError("TRADE_JOURNAL_ERROR", `Trade journal error: ${message}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
186
213
|
|
|
187
214
|
// src/domains/assessments/assessments.ts
|
|
188
215
|
async function getAssessments(ctx, params) {
|
|
@@ -664,6 +691,9 @@ var DxtradeClient = class {
|
|
|
664
691
|
async getAccountMetrics() {
|
|
665
692
|
return getAccountMetrics(this._ctx);
|
|
666
693
|
}
|
|
694
|
+
async getTradeJournal(params) {
|
|
695
|
+
return getTradeJournal(this._ctx, params);
|
|
696
|
+
}
|
|
667
697
|
async getInstruments(params = {}) {
|
|
668
698
|
return getInstruments(this._ctx, params);
|
|
669
699
|
}
|
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/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 assessments: (base: string) => `${base}/api/assessments`,\n\n websocket: (base: string) => `wss://${base.split(\"//\")[1]}/client/connector` + websocketQuery,\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 { 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 { 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","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 { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\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.type === WS_MESSAGE.POSITIONS) {\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, Symbol } from \"./domains\";\nimport {\n login,\n fetchCsrf,\n switchAccount,\n connect,\n getAccountMetrics,\n getAssessments,\n getInstruments,\n getSymbolLimits,\n getSymbolSuggestions,\n getSymbolInfo,\n submitOrder,\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 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"]}
|
|
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/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 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 { endpoints, DxtradeError } from \"@/constants\";\nimport { WS_MESSAGE } from \"@/constants/enums\";\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.type === WS_MESSAGE.POSITIONS) {\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, Symbol } from \"./domains\";\nimport {\n login,\n fetchCsrf,\n switchAccount,\n connect,\n getAccountMetrics,\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 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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danielgroen/dxtrade-api",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"description": "DXtrade trading API client library",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"=============== Examples ===============": "",
|
|
25
25
|
"example:debug": "tsx examples/debug.ts",
|
|
26
26
|
"example:account": "tsx examples/account-metrics.ts",
|
|
27
|
+
"example:trade-journal": "tsx examples/trade-journal.ts",
|
|
27
28
|
"example:connect": "tsx examples/connect.ts",
|
|
28
29
|
"example:order": "tsx examples/submit-order.ts",
|
|
29
30
|
"example:assessments": "tsx examples/get-assessments.ts",
|