@danielgroen/dxtrade-api 1.0.24 → 1.0.26

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 CHANGED
@@ -26,7 +26,7 @@ npm install dxtrade-api
26
26
  - [x] Position metrics (per-position P&L)
27
27
  - [x] Account metrics, trade journal & trade history
28
28
  - [x] Symbol search & instrument info
29
- - [x] OHLC / price bar data
29
+ - [x] OHLC / price bar data (one-shot & streaming)
30
30
  - [x] PnL assessments
31
31
  - [x] Multi-broker support (FTMO, Eightcap, Lark Funding)
32
32
  - [x] Persistent WebSocket with `connect()`
@@ -34,7 +34,7 @@ npm install dxtrade-api
34
34
  - [x] Full TypeScript support
35
35
  - [ ] Batch orders
36
36
  - [ ] Modify existing orders
37
- - [ ] Real-time price streaming
37
+ - [x] Real-time OHLC streaming
38
38
 
39
39
  ## Quick Start
40
40
 
@@ -48,8 +48,8 @@ const client = new DxtradeClient({
48
48
  accountId: "optional_account_id",
49
49
  });
50
50
 
51
- // connect() = auth + persistent WebSocket (recommended)
52
- await client.connect();
51
+ // await client.auth(); // Auth only
52
+ await client.connect(); // Auth + persistent WebSocket (recommended)
53
53
 
54
54
  const suggestions = await client.symbols.search("EURUSD");
55
55
  const symbol = suggestions[0];
@@ -63,17 +63,17 @@ const order = await client.orders.submit({
63
63
  });
64
64
 
65
65
  console.log(`Order ${order.orderId}: ${order.status}`);
66
- client.disconnect();
66
+ client.disconnect(); // disconnect stream -- only needed if client.connect()
67
67
  ```
68
68
 
69
69
  ## Connection Modes
70
70
 
71
71
  ```ts
72
- // Persistent WebSocket (recommended) — reuses one WS for all data, enables streaming
72
+ // 1. Persistent WebSocket (recommended) — reuses one WS for all data, enables streaming
73
73
  await client.connect();
74
74
  client.disconnect(); // when done
75
75
 
76
- // Lightweight — auth only, each data call opens a temporary WebSocket
76
+ // 2. Lightweight — auth only, each data call opens a temporary WebSocket
77
77
  await client.auth();
78
78
  ```
79
79
 
@@ -113,11 +113,10 @@ BROKER.FTMO // "https://dxtrade.ftmo.com"
113
113
 
114
114
  ### Positions
115
115
 
116
- - `client.positions.get()` — Get all open positions
117
- - `client.positions.close(params)` — Close a position (supports partial closes via the quantity field)
116
+ - `client.positions.get()` — Get all open positions with P&L metrics merged (margin, plOpen, marketValue, etc.)
117
+ - `client.positions.close(positionCode, options?)` — Close a position by its position code. Returns `Position.Full` with P&L metrics. Options: `waitForClose: "stream" | "poll"`, `timeout` (ms, default 30000), `pollInterval` (ms, default 1000)
118
118
  - `client.positions.closeAll()` — Close all open positions with market orders
119
- - `client.positions.metrics()` — Get position-level P&L metrics
120
- - `client.positions.stream(callback)` — Stream real-time position updates (requires `connect()`). Returns an unsubscribe function.
119
+ - `client.positions.stream(callback)` — Stream real-time position updates with live P&L (requires `connect()`). Returns an unsubscribe function.
121
120
 
122
121
  ### Orders
123
122
 
@@ -145,6 +144,7 @@ BROKER.FTMO // "https://dxtrade.ftmo.com"
145
144
  ### OHLC
146
145
 
147
146
  - `client.ohlc.get(params)` — Fetch OHLC price bars for a symbol (resolution, range, maxBars, priceField)
147
+ - `client.ohlc.stream(params, callback)` — Stream real-time OHLC bar updates (requires `connect()`). Returns a promise that resolves with an unsubscribe function after the snapshot is received.
148
148
 
149
149
  ### Assessments
150
150
 
@@ -185,6 +185,7 @@ npm run example:debug
185
185
  npm run example:positions:get
186
186
  npm run example:positions:close
187
187
  npm run example:positions:close-all
188
+ npm run example:positions:close-by-code
188
189
  npm run example:positions:metrics
189
190
  npm run example:positions:stream
190
191
  npm run example:orders:submit
@@ -196,6 +197,8 @@ npm run example:symbols:info:btc
196
197
  npm run example:instruments:get
197
198
  npm run example:instruments:get:forex
198
199
  npm run example:ohlc:get
200
+ npm run example:ohlc:stream
201
+ npm run example:ohlc:stream:btc
199
202
  npm run example:assessments:get
200
203
  npm run example:assessments:get:btc
201
204
  ```
package/dist/index.d.mts CHANGED
@@ -67,7 +67,9 @@ declare enum ERROR {
67
67
  ORDERS_TIMEOUT = "ORDERS_TIMEOUT",
68
68
  ORDERS_ERROR = "ORDERS_ERROR",
69
69
  CANCEL_ORDER_ERROR = "CANCEL_ORDER_ERROR",
70
+ POSITION_NOT_FOUND = "POSITION_NOT_FOUND",
70
71
  POSITION_CLOSE_ERROR = "POSITION_CLOSE_ERROR",
72
+ POSITION_CLOSE_TIMEOUT = "POSITION_CLOSE_TIMEOUT",
71
73
  POSITION_METRICS_TIMEOUT = "POSITION_METRICS_TIMEOUT",
72
74
  POSITION_METRICS_ERROR = "POSITION_METRICS_ERROR",
73
75
  ACCOUNT_METRICS_TIMEOUT = "ACCOUNT_METRICS_TIMEOUT",
@@ -81,6 +83,19 @@ declare enum ERROR {
81
83
  WS_MANAGER_ERROR = "WS_MANAGER_ERROR",
82
84
  STREAM_REQUIRES_CONNECT = "STREAM_REQUIRES_CONNECT"
83
85
  }
86
+ declare enum MESSAGE_CATEGORY {
87
+ TRADE_LOG = "TRADE_LOG",
88
+ NOTIFICATION = "NOTIFICATION"
89
+ }
90
+ declare enum MESSAGE_TYPE {
91
+ ORDER = "ORDER",
92
+ INSTRUMENT_ACTIVATED = "INSTRUMENT_ACTIVATED"
93
+ }
94
+ declare enum ORDER_STATUS {
95
+ PLACED = "PLACED",
96
+ FILLED = "FILLED",
97
+ REJECTED = "REJECTED"
98
+ }
84
99
  declare enum WS_MESSAGE {
85
100
  ACCOUNT_METRICS = "ACCOUNT_METRICS",
86
101
  ACCOUNTS = "ACCOUNTS",
@@ -100,7 +115,8 @@ declare enum WS_MESSAGE {
100
115
  }
101
116
  declare namespace WS_MESSAGE {
102
117
  enum SUBTOPIC {
103
- BIG_CHART_COMPONENT = "BigChartComponentPresenter-4"
118
+ BIG_CHART_COMPONENT = "BigChartComponentPresenter-4",
119
+ OHLC_STREAM = "OHLCStreamPresenter-0"
104
120
  }
105
121
  }
106
122
 
@@ -109,6 +125,22 @@ declare class DxtradeError extends Error {
109
125
  constructor(code: string, message: string);
110
126
  }
111
127
 
128
+ declare class OrdersDomain {
129
+ private _ctx;
130
+ constructor(_ctx: ClientContext);
131
+ /** Get all pending/open orders via WebSocket. */
132
+ get(timeout?: number): Promise<Order.Get[]>;
133
+ /** Cancel a single pending order by its order chain ID. */
134
+ cancel(orderChainId: number): Promise<void>;
135
+ /** Cancel all pending orders. */
136
+ cancelAll(): Promise<void>;
137
+ /**
138
+ * Submit a trading order and wait for WebSocket confirmation.
139
+ * Supports market, limit, and stop orders with optional stop loss and take profit.
140
+ */
141
+ submit(params: Order.SubmitParams): Promise<Order.Update>;
142
+ }
143
+
112
144
  declare namespace Order {
113
145
  interface Get {
114
146
  account: string;
@@ -158,6 +190,7 @@ declare namespace Order {
158
190
  orderId: string;
159
191
  status: string;
160
192
  statusDescription?: string;
193
+ positionCode?: string;
161
194
  [key: string]: unknown;
162
195
  }
163
196
  interface Model {
@@ -262,6 +295,31 @@ interface WsPayload {
262
295
  type: string;
263
296
  }
264
297
 
298
+ declare class AccountDomain {
299
+ private _ctx;
300
+ constructor(_ctx: ClientContext);
301
+ /** Get account metrics including equity, balance, margin, and open P&L. */
302
+ metrics(timeout?: number): Promise<Account.Metrics>;
303
+ /**
304
+ * Fetch trade history for a date range.
305
+ * @param params.from - Start timestamp (Unix ms)
306
+ * @param params.to - End timestamp (Unix ms)
307
+ */
308
+ tradeHistory(params: {
309
+ from: number;
310
+ to: number;
311
+ }): Promise<Account.TradeHistory[]>;
312
+ /**
313
+ * Fetch trade journal entries for a date range.
314
+ * @param params.from - Start timestamp (Unix ms)
315
+ * @param params.to - End timestamp (Unix ms)
316
+ */
317
+ tradeJournal(params: {
318
+ from: number;
319
+ to: number;
320
+ }): Promise<any>;
321
+ }
322
+
265
323
  declare namespace Account {
266
324
  interface TradeHistory {
267
325
  orderId: number;
@@ -292,6 +350,13 @@ declare namespace Account {
292
350
  }
293
351
  }
294
352
 
353
+ declare class AssessmentsDomain {
354
+ private _ctx;
355
+ constructor(_ctx: ClientContext);
356
+ /** Fetch PnL assessments for an instrument within a date range. */
357
+ get(params: Assessments.Params): Promise<Assessments.Response>;
358
+ }
359
+
295
360
  declare namespace Assessments {
296
361
  interface Params {
297
362
  from: number;
@@ -305,6 +370,13 @@ declare namespace Assessments {
305
370
  }
306
371
  }
307
372
 
373
+ declare class InstrumentsDomain {
374
+ private _ctx;
375
+ constructor(_ctx: ClientContext);
376
+ /** Get all available instruments, optionally filtered by partial match (e.g. `{ type: "FOREX" }`). */
377
+ get(params?: Partial<Instrument.Info>, timeout?: number): Promise<Instrument.Info[]>;
378
+ }
379
+
308
380
  declare namespace Instrument {
309
381
  interface Info {
310
382
  id: number;
@@ -344,6 +416,22 @@ declare namespace Instrument {
344
416
  }
345
417
  }
346
418
 
419
+ declare class OhlcDomain {
420
+ private _ctx;
421
+ constructor(_ctx: ClientContext);
422
+ /** Stream real-time OHLC bar updates. Requires connect(). Returns unsubscribe function. */
423
+ stream(params: OHLC.Params, callback: (bars: OHLC.Bar[]) => void): Promise<() => void>;
424
+ /**
425
+ * Fetch OHLC price bars for a symbol.
426
+ * @param params.symbol - Instrument symbol (e.g. "EURUSD")
427
+ * @param params.resolution - Bar period in seconds (default: 60 = 1 min)
428
+ * @param params.range - Lookback window in seconds (default: 432000 = 5 days)
429
+ * @param params.maxBars - Maximum bars to return (default: 3500)
430
+ * @param params.priceField - "bid" or "ask" (default: "bid")
431
+ */
432
+ get(params: OHLC.Params, timeout?: number): Promise<OHLC.Bar[]>;
433
+ }
434
+
347
435
  declare namespace OHLC {
348
436
  interface Params {
349
437
  /** Symbol to fetch bars for (e.g. "EURUSD"). */
@@ -369,6 +457,22 @@ declare namespace OHLC {
369
457
  }
370
458
  }
371
459
 
460
+ declare class PositionsDomain {
461
+ private _ctx;
462
+ constructor(_ctx: ClientContext);
463
+ /** Stream real-time position updates with P&L metrics. Requires connect(). Returns unsubscribe function. */
464
+ stream(callback: (positions: Position.Full[]) => void): () => void;
465
+ /** Get all open positions with P&L metrics merged. */
466
+ get(): Promise<Position.Full[]>;
467
+ /** Close all open positions with market orders. */
468
+ closeAll(): Promise<void>;
469
+ /** Close a position by its position code. Returns the position with P&L metrics. Optionally wait for close confirmation via `waitForClose: "stream" | "poll"`. */
470
+ close(positionCode: string, options?: Position.CloseOptions): Promise<Position.Full>;
471
+ private _waitForCloseStream;
472
+ private _waitForClosePoll;
473
+ private _sendCloseRequest;
474
+ }
475
+
372
476
  declare namespace Position {
373
477
  interface Get {
374
478
  uid: string;
@@ -389,13 +493,36 @@ declare namespace Position {
389
493
  stopLoss: number | null;
390
494
  }
391
495
  interface Metrics {
392
- positionCode: string;
393
- openPl: number;
394
- openPlPerLot: number;
395
- currentPrice: number;
396
- convertedOpenPl: number;
496
+ uid: string;
497
+ accountId: string;
498
+ margin: number;
499
+ plOpen: number;
500
+ plClosed: number;
501
+ totalCommissions: number;
502
+ totalFinancing: number;
503
+ plRate: number;
504
+ averagePrice: number;
505
+ marketValue: number;
397
506
  [key: string]: unknown;
398
507
  }
508
+ interface Full extends Get {
509
+ margin: number;
510
+ plOpen: number;
511
+ plClosed: number;
512
+ totalCommissions: number;
513
+ totalFinancing: number;
514
+ plRate: number;
515
+ averagePrice: number;
516
+ marketValue: number;
517
+ }
518
+ interface CloseOptions {
519
+ /** Wait for the position to disappear after closing. "stream" uses the persistent WebSocket (requires connect()), "poll" repeatedly calls getPositions(). */
520
+ waitForClose?: "stream" | "poll";
521
+ /** Timeout in ms for waitForClose (default: 30000). */
522
+ timeout?: number;
523
+ /** Poll interval in ms when using waitForClose: "poll" (default: 1000). */
524
+ pollInterval?: number;
525
+ }
399
526
  interface Close {
400
527
  legs: {
401
528
  instrumentId: number;
@@ -411,6 +538,17 @@ declare namespace Position {
411
538
  }
412
539
  }
413
540
 
541
+ declare class SymbolsDomain {
542
+ private _ctx;
543
+ constructor(_ctx: ClientContext);
544
+ /** Search for symbols matching the given text (e.g. "EURUSD", "BTC"). */
545
+ search(text: string): Promise<Symbol.Suggestion[]>;
546
+ /** Get detailed instrument info for a symbol, including volume limits and lot size. */
547
+ info(symbol: string): Promise<Symbol.Info>;
548
+ /** Get order size limits and stop/limit distances for all symbols. */
549
+ limits(timeout?: number): Promise<Symbol.Limits[]>;
550
+ }
551
+
414
552
  declare namespace Symbol {
415
553
  interface Suggestion {
416
554
  id: number;
@@ -438,94 +576,6 @@ declare namespace Symbol {
438
576
  }
439
577
  }
440
578
 
441
- declare class PositionsDomain {
442
- private _ctx;
443
- constructor(_ctx: ClientContext);
444
- /** Get all open positions via WebSocket. */
445
- get(): Promise<Position.Get[]>;
446
- /** Close a position. Supports partial closes by specifying a quantity smaller than the full position size. */
447
- close(params: Position.Close): Promise<void>;
448
- /** Close all open positions with market orders. */
449
- closeAll(): Promise<void>;
450
- /** Get position-level P&L metrics via WebSocket. */
451
- metrics(): Promise<Position.Metrics[]>;
452
- /** Stream real-time position updates. Requires connect(). Returns unsubscribe function. */
453
- stream(callback: (positions: Position.Get[]) => void): () => void;
454
- }
455
- declare class OrdersDomain {
456
- private _ctx;
457
- constructor(_ctx: ClientContext);
458
- /** Get all pending/open orders via WebSocket. */
459
- get(): Promise<Order.Get[]>;
460
- /**
461
- * Submit a trading order and wait for WebSocket confirmation.
462
- * Supports market, limit, and stop orders with optional stop loss and take profit.
463
- */
464
- submit(params: Order.SubmitParams): Promise<Order.Update>;
465
- /** Cancel a single pending order by its order chain ID. */
466
- cancel(orderChainId: number): Promise<void>;
467
- /** Cancel all pending orders. */
468
- cancelAll(): Promise<void>;
469
- }
470
- declare class AccountDomain {
471
- private _ctx;
472
- constructor(_ctx: ClientContext);
473
- /** Get account metrics including equity, balance, margin, and open P&L. */
474
- metrics(): Promise<Account.Metrics>;
475
- /**
476
- * Fetch trade journal entries for a date range.
477
- * @param params.from - Start timestamp (Unix ms)
478
- * @param params.to - End timestamp (Unix ms)
479
- */
480
- tradeJournal(params: {
481
- from: number;
482
- to: number;
483
- }): Promise<any>;
484
- /**
485
- * Fetch trade history for a date range.
486
- * @param params.from - Start timestamp (Unix ms)
487
- * @param params.to - End timestamp (Unix ms)
488
- */
489
- tradeHistory(params: {
490
- from: number;
491
- to: number;
492
- }): Promise<Account.TradeHistory[]>;
493
- }
494
- declare class SymbolsDomain {
495
- private _ctx;
496
- constructor(_ctx: ClientContext);
497
- /** Search for symbols matching the given text (e.g. "EURUSD", "BTC"). */
498
- search(text: string): Promise<Symbol.Suggestion[]>;
499
- /** Get detailed instrument info for a symbol, including volume limits and lot size. */
500
- info(symbol: string): Promise<Symbol.Info>;
501
- /** Get order size limits and stop/limit distances for all symbols. */
502
- limits(): Promise<Symbol.Limits[]>;
503
- }
504
- declare class InstrumentsDomain {
505
- private _ctx;
506
- constructor(_ctx: ClientContext);
507
- /** Get all available instruments, optionally filtered by partial match (e.g. `{ type: "FOREX" }`). */
508
- get(params?: Partial<Instrument.Info>): Promise<Instrument.Info[]>;
509
- }
510
- declare class OhlcDomain {
511
- private _ctx;
512
- constructor(_ctx: ClientContext);
513
- /**
514
- * Fetch OHLC price bars for a symbol.
515
- * @param params.symbol - Instrument symbol (e.g. "EURUSD")
516
- * @param params.resolution - Bar period in seconds (default: 60 = 1 min)
517
- * @param params.range - Lookback window in seconds (default: 432000 = 5 days)
518
- * @param params.maxBars - Maximum bars to return (default: 3500)
519
- * @param params.priceField - "bid" or "ask" (default: "bid")
520
- */
521
- get(params: OHLC.Params): Promise<OHLC.Bar[]>;
522
- }
523
- declare class AssessmentsDomain {
524
- private _ctx;
525
- constructor(_ctx: ClientContext);
526
- /** Fetch PnL assessments for an instrument within a date range. */
527
- get(params: Assessments.Params): Promise<Assessments.Response>;
528
- }
529
579
  /**
530
580
  * Client for interacting with the DXtrade trading API.
531
581
  *
@@ -544,6 +594,7 @@ declare class AssessmentsDomain {
544
594
  */
545
595
  declare class DxtradeClient {
546
596
  private _ctx;
597
+ private _session;
547
598
  /** Position operations: get, close, metrics, streaming. */
548
599
  readonly positions: PositionsDomain;
549
600
  /** Order operations: get, submit, cancel. */
@@ -554,7 +605,7 @@ declare class DxtradeClient {
554
605
  readonly symbols: SymbolsDomain;
555
606
  /** Instrument operations: get (with optional filtering). */
556
607
  readonly instruments: InstrumentsDomain;
557
- /** OHLC price bar operations: get. */
608
+ /** OHLC price bar operations: get, stream. */
558
609
  readonly ohlc: OhlcDomain;
559
610
  /** PnL assessment operations: get. */
560
611
  readonly assessments: AssessmentsDomain;
@@ -573,4 +624,4 @@ declare class DxtradeClient {
573
624
  disconnect(): void;
574
625
  }
575
626
 
576
- export { ACTION, BROKER, type DxtradeCallbacks, DxtradeClient, type DxtradeConfig, DxtradeError, ERROR, ORDER_TYPE, SIDE, TIF, WS_MESSAGE, type WsPayload, endpoints };
627
+ export { ACTION, BROKER, type DxtradeCallbacks, DxtradeClient, type DxtradeConfig, DxtradeError, ERROR, MESSAGE_CATEGORY, MESSAGE_TYPE, ORDER_STATUS, ORDER_TYPE, SIDE, TIF, WS_MESSAGE, type WsPayload, endpoints };