ctrader-ts 0.1.10 → 1.0.0
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 +259 -91
- package/dist/bin/auth.js +8 -8
- package/dist/bin/auth.js.map +1 -1
- package/dist/cli/index.js +169 -26
- package/dist/cli/index.js.map +1 -1
- package/dist/src/{client.d.ts → core/client.d.ts} +57 -15
- package/dist/src/core/client.d.ts.map +1 -0
- package/dist/src/{client.js → core/client.js} +306 -49
- package/dist/src/core/client.js.map +1 -0
- package/dist/src/core/config.d.ts.map +1 -0
- package/dist/src/{config.js → core/config.js} +13 -13
- package/dist/src/core/config.js.map +1 -0
- package/dist/src/{connect.d.ts → core/connect.d.ts} +3 -3
- package/dist/src/core/connect.d.ts.map +1 -0
- package/dist/src/{connect.js → core/connect.js} +4 -6
- package/dist/src/core/connect.js.map +1 -0
- package/dist/src/{connection.d.ts → core/connection.d.ts} +53 -4
- package/dist/src/core/connection.d.ts.map +1 -0
- package/dist/src/{connection.js → core/connection.js} +152 -18
- package/dist/src/core/connection.js.map +1 -0
- package/dist/src/{errors.d.ts → core/errors.d.ts} +5 -0
- package/dist/src/core/errors.d.ts.map +1 -0
- package/dist/src/core/errors.js +85 -0
- package/dist/src/core/errors.js.map +1 -0
- package/dist/src/{helpers.d.ts → core/helpers.d.ts} +3 -3
- package/dist/src/core/helpers.d.ts.map +1 -0
- package/dist/src/{helpers.js → core/helpers.js} +9 -7
- package/dist/src/core/helpers.js.map +1 -0
- package/dist/src/{symbol-cache.d.ts → core/symbol-cache.d.ts} +2 -2
- package/dist/src/core/symbol-cache.d.ts.map +1 -0
- package/dist/src/core/symbol-cache.js.map +1 -0
- package/dist/src/index.d.ts +26 -11
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +24 -9
- package/dist/src/index.js.map +1 -1
- package/dist/src/modules/account.d.ts +68 -2
- package/dist/src/modules/account.d.ts.map +1 -1
- package/dist/src/modules/account.js +91 -34
- package/dist/src/modules/account.js.map +1 -1
- package/dist/src/modules/auth.d.ts +29 -2
- package/dist/src/modules/auth.d.ts.map +1 -1
- package/dist/src/modules/auth.js +42 -10
- package/dist/src/modules/auth.js.map +1 -1
- package/dist/src/modules/market.d.ts +51 -3
- package/dist/src/modules/market.d.ts.map +1 -1
- package/dist/src/modules/market.js +57 -16
- package/dist/src/modules/market.js.map +1 -1
- package/dist/src/modules/trading.d.ts +69 -3
- package/dist/src/modules/trading.d.ts.map +1 -1
- package/dist/src/modules/trading.js +74 -35
- package/dist/src/modules/trading.js.map +1 -1
- package/dist/src/protocol/codec.d.ts.map +1 -0
- package/dist/src/{codec.js → protocol/codec.js} +2 -2
- package/dist/src/protocol/codec.js.map +1 -0
- package/dist/src/{enums.d.ts → protocol/enums.d.ts} +177 -0
- package/dist/src/protocol/enums.d.ts.map +1 -0
- package/dist/src/{enums.js → protocol/enums.js} +177 -0
- package/dist/src/protocol/enums.js.map +1 -0
- package/dist/src/protocol/proto/messages.d.ts +7496 -0
- package/dist/src/protocol/proto/messages.js +21525 -0
- package/dist/src/protocol/proto/proto/messages.d.ts +7496 -0
- package/dist/src/protocol/proto/proto/messages.js +21525 -0
- package/dist/src/{types.d.ts → protocol/types.d.ts} +151 -3
- package/dist/src/protocol/types.d.ts.map +1 -0
- package/dist/src/{types.js.map → protocol/types.js.map} +1 -1
- package/llms.txt +280 -0
- package/package.json +89 -61
- package/dist/src/client.d.ts.map +0 -1
- package/dist/src/client.js.map +0 -1
- package/dist/src/codec.d.ts.map +0 -1
- package/dist/src/codec.js.map +0 -1
- package/dist/src/config.d.ts.map +0 -1
- package/dist/src/config.js.map +0 -1
- package/dist/src/connect.d.ts.map +0 -1
- package/dist/src/connect.js.map +0 -1
- package/dist/src/connection.d.ts.map +0 -1
- package/dist/src/connection.js.map +0 -1
- package/dist/src/enums.d.ts.map +0 -1
- package/dist/src/enums.js.map +0 -1
- package/dist/src/errors.d.ts.map +0 -1
- package/dist/src/errors.js +0 -47
- package/dist/src/errors.js.map +0 -1
- package/dist/src/helpers.d.ts.map +0 -1
- package/dist/src/helpers.js.map +0 -1
- package/dist/src/proto/messages.d.ts +0 -7076
- package/dist/src/proto/messages.js +0 -23289
- package/dist/src/proto/proto/messages.d.ts +0 -7076
- package/dist/src/proto/proto/messages.js +0 -23289
- package/dist/src/symbol-cache.d.ts.map +0 -1
- package/dist/src/symbol-cache.js.map +0 -1
- package/dist/src/types.d.ts.map +0 -1
- /package/dist/src/{config.d.ts → core/config.d.ts} +0 -0
- /package/dist/src/{symbol-cache.js → core/symbol-cache.js} +0 -0
- /package/dist/src/{codec.d.ts → protocol/codec.d.ts} +0 -0
- /package/dist/src/{types.js → protocol/types.js} +0 -0
|
@@ -9,20 +9,29 @@
|
|
|
9
9
|
* - When a heartbeat is received from the server, immediately echo one back
|
|
10
10
|
* - If no heartbeat received from server for HEARTBEAT_TIMEOUT_MS, close
|
|
11
11
|
*/
|
|
12
|
-
import type { ConnectionState } from "
|
|
12
|
+
import type { ConnectionState } from "../protocol/types.js";
|
|
13
13
|
type PayloadHandler = (payload: Record<string, unknown>) => void;
|
|
14
14
|
export type ConnectionEvent = "stateChange" | "error" | "message";
|
|
15
15
|
type ConnectionEventHandler = (data: unknown) => void;
|
|
16
16
|
export interface CTraderConnectionConfig {
|
|
17
|
-
/** Hostname, e.g
|
|
17
|
+
/** Hostname or IP address, e.g., "demo.ctraderapi.com" */
|
|
18
18
|
host: string;
|
|
19
|
-
/** Port — default 5035 */
|
|
19
|
+
/** Port number — default 5035 for cTrader Open API over TLS/TCP */
|
|
20
20
|
port?: number;
|
|
21
|
+
/** Maximum number of reconnection attempts (0 = unlimited) */
|
|
21
22
|
maxReconnectAttempts?: number;
|
|
23
|
+
/** Timeout in milliseconds for individual requests (default 15000ms) */
|
|
22
24
|
requestTimeoutMs?: number;
|
|
23
|
-
/** Called after TCP reconnects (not initial connect). Use for re-auth + subscription restore. */
|
|
25
|
+
/** Called after TLS/TCP reconnects (not initial connect). Use for re-auth + subscription restore. */
|
|
24
26
|
onReconnect?: () => Promise<void>;
|
|
25
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Low-level TLS/TCP connection to the cTrader Open API (port 5035).
|
|
30
|
+
* Handles connect/disconnect, heartbeat, automatic reconnection,
|
|
31
|
+
* request/response matching, and payload-based event dispatch.
|
|
32
|
+
*
|
|
33
|
+
* Most users should use {@link CTrader} (via `connect()`) instead of this class directly.
|
|
34
|
+
*/
|
|
26
35
|
export declare class CTraderConnection {
|
|
27
36
|
private socket;
|
|
28
37
|
private readonly host;
|
|
@@ -44,16 +53,56 @@ export declare class CTraderConnection {
|
|
|
44
53
|
private readonly pending;
|
|
45
54
|
private readonly payloadHandlers;
|
|
46
55
|
private readonly eventHandlers;
|
|
56
|
+
/** Request throttle queue */
|
|
57
|
+
private readonly requestQueue;
|
|
58
|
+
private inFlightRequests;
|
|
59
|
+
private lastRequestSentAt;
|
|
47
60
|
constructor(config: CTraderConnectionConfig);
|
|
61
|
+
/** Current connection lifecycle state. */
|
|
48
62
|
get state(): ConnectionState;
|
|
63
|
+
/** True when the TLS/TCP socket is established and ready for messages. */
|
|
49
64
|
get isConnected(): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Establish a TLS/TCP connection to the cTrader API.
|
|
67
|
+
* Resolves when the connection is established, rejects on failure.
|
|
68
|
+
*/
|
|
50
69
|
connect(): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Close the TLS/TCP connection and stop automatic reconnection.
|
|
72
|
+
* All pending requests are rejected.
|
|
73
|
+
*/
|
|
51
74
|
disconnect(): void;
|
|
75
|
+
/**
|
|
76
|
+
* Send a one-way message (fire-and-forget) over the TLS/TCP connection.
|
|
77
|
+
* Returns the generated clientMsgId for tracking.
|
|
78
|
+
*/
|
|
52
79
|
send(payloadType: number, payload?: Record<string, unknown>): string;
|
|
80
|
+
private static readonly MAX_RETRIES;
|
|
81
|
+
private static readonly INITIAL_RETRY_DELAY_MS;
|
|
82
|
+
/**
|
|
83
|
+
* Send a request and wait for the matching response.
|
|
84
|
+
* Automatically retries on rate-limit errors with exponential backoff.
|
|
85
|
+
* Rejects on timeout, non-retryable API error, or max retries exceeded.
|
|
86
|
+
*/
|
|
53
87
|
request(payloadType: number, payload: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
88
|
+
/**
|
|
89
|
+
* Internal: send a single request without retry.
|
|
90
|
+
*/
|
|
91
|
+
private requestOnce;
|
|
92
|
+
private drainQueue;
|
|
93
|
+
/**
|
|
94
|
+
* Subscribe to a specific payload type.
|
|
95
|
+
* Returns an unsubscribe function.
|
|
96
|
+
*/
|
|
54
97
|
on(payloadType: number, handler: PayloadHandler): () => void;
|
|
98
|
+
/** Remove a specific handler for a payload type. */
|
|
55
99
|
off(payloadType: number, handler: PayloadHandler): void;
|
|
100
|
+
/**
|
|
101
|
+
* Subscribe to connection lifecycle events (stateChange, error, message).
|
|
102
|
+
* Returns an unsubscribe function.
|
|
103
|
+
*/
|
|
56
104
|
onEvent(event: ConnectionEvent, handler: ConnectionEventHandler): () => void;
|
|
105
|
+
/** Remove a specific connection event handler. */
|
|
57
106
|
offEvent(event: ConnectionEvent, handler: ConnectionEventHandler): void;
|
|
58
107
|
private handleData;
|
|
59
108
|
private handleMessage;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../src/core/connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,15 +10,29 @@
|
|
|
10
10
|
* - If no heartbeat received from server for HEARTBEAT_TIMEOUT_MS, close
|
|
11
11
|
*/
|
|
12
12
|
import * as tls from "node:tls";
|
|
13
|
-
import {
|
|
14
|
-
import { PayloadType } from "
|
|
15
|
-
import {
|
|
13
|
+
import { decodeMessage, encodeHeartbeat, encodeMessage, } from "../protocol/codec.js";
|
|
14
|
+
import { PayloadType } from "../protocol/enums.js";
|
|
15
|
+
import { CTraderError, NotConnectedError, RequestTimeoutError } from "./errors.js";
|
|
16
16
|
const REQUEST_TIMEOUT_MS = 15_000;
|
|
17
17
|
const HEARTBEAT_CHECK_MS = 1_000;
|
|
18
18
|
const HEARTBEAT_IDLE_MS = 10_000;
|
|
19
19
|
const HEARTBEAT_TIMEOUT_MS = 60_000;
|
|
20
20
|
const INITIAL_RECONNECT_DELAY_MS = 2_000;
|
|
21
21
|
const MAX_RECONNECT_DELAY_MS = 60_000;
|
|
22
|
+
/**
|
|
23
|
+
* Throttle settings to avoid REQUEST_FREQUENCY_EXCEEDED errors.
|
|
24
|
+
* The cTrader Open API has an undocumented rate limit (~50 req/s).
|
|
25
|
+
* We limit concurrency and add a small gap between sends.
|
|
26
|
+
*/
|
|
27
|
+
const MAX_CONCURRENT_REQUESTS = 5;
|
|
28
|
+
const REQUEST_GAP_MS = 50;
|
|
29
|
+
/**
|
|
30
|
+
* Low-level TLS/TCP connection to the cTrader Open API (port 5035).
|
|
31
|
+
* Handles connect/disconnect, heartbeat, automatic reconnection,
|
|
32
|
+
* request/response matching, and payload-based event dispatch.
|
|
33
|
+
*
|
|
34
|
+
* Most users should use {@link CTrader} (via `connect()`) instead of this class directly.
|
|
35
|
+
*/
|
|
22
36
|
export class CTraderConnection {
|
|
23
37
|
socket = null;
|
|
24
38
|
host;
|
|
@@ -40,6 +54,10 @@ export class CTraderConnection {
|
|
|
40
54
|
pending = new Map();
|
|
41
55
|
payloadHandlers = new Map();
|
|
42
56
|
eventHandlers = new Map();
|
|
57
|
+
/** Request throttle queue */
|
|
58
|
+
requestQueue = [];
|
|
59
|
+
inFlightRequests = 0;
|
|
60
|
+
lastRequestSentAt = 0;
|
|
43
61
|
constructor(config) {
|
|
44
62
|
this.host = config.host;
|
|
45
63
|
this.port = config.port ?? 5035;
|
|
@@ -47,17 +65,22 @@ export class CTraderConnection {
|
|
|
47
65
|
this.requestTimeoutMs = config.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
48
66
|
this.onReconnect = config.onReconnect;
|
|
49
67
|
}
|
|
68
|
+
/** Current connection lifecycle state. */
|
|
50
69
|
get state() {
|
|
51
70
|
return this._state;
|
|
52
71
|
}
|
|
72
|
+
/** True when the TLS/TCP socket is established and ready for messages. */
|
|
53
73
|
get isConnected() {
|
|
54
74
|
return this._state.status === "connected" || this._state.status === "ready";
|
|
55
75
|
}
|
|
56
76
|
// ─── Connect ────────────────────────────────────────────────────────────
|
|
77
|
+
/**
|
|
78
|
+
* Establish a TLS/TCP connection to the cTrader API.
|
|
79
|
+
* Resolves when the connection is established, rejects on failure.
|
|
80
|
+
*/
|
|
57
81
|
connect() {
|
|
58
82
|
return new Promise((resolve, reject) => {
|
|
59
|
-
if (this._state.status === "connected" ||
|
|
60
|
-
this._state.status === "ready") {
|
|
83
|
+
if (this._state.status === "connected" || this._state.status === "ready") {
|
|
61
84
|
resolve();
|
|
62
85
|
return;
|
|
63
86
|
}
|
|
@@ -97,6 +120,10 @@ export class CTraderConnection {
|
|
|
97
120
|
});
|
|
98
121
|
});
|
|
99
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Close the TLS/TCP connection and stop automatic reconnection.
|
|
125
|
+
* All pending requests are rejected.
|
|
126
|
+
*/
|
|
100
127
|
disconnect() {
|
|
101
128
|
this.shouldReconnect = false;
|
|
102
129
|
if (this.reconnectTimer !== null) {
|
|
@@ -112,6 +139,10 @@ export class CTraderConnection {
|
|
|
112
139
|
this.setState({ status: "disconnected" });
|
|
113
140
|
}
|
|
114
141
|
// ─── Send ───────────────────────────────────────────────────────────────
|
|
142
|
+
/**
|
|
143
|
+
* Send a one-way message (fire-and-forget) over the TLS/TCP connection.
|
|
144
|
+
* Returns the generated clientMsgId for tracking.
|
|
145
|
+
*/
|
|
115
146
|
send(payloadType, payload) {
|
|
116
147
|
if (this.socket === null || this.socket.destroyed) {
|
|
117
148
|
throw new NotConnectedError();
|
|
@@ -122,17 +153,105 @@ export class CTraderConnection {
|
|
|
122
153
|
this.lastSendAt = Date.now();
|
|
123
154
|
return clientMsgId;
|
|
124
155
|
}
|
|
125
|
-
|
|
156
|
+
static MAX_RETRIES = 3;
|
|
157
|
+
static INITIAL_RETRY_DELAY_MS = 1_000;
|
|
158
|
+
/**
|
|
159
|
+
* Send a request and wait for the matching response.
|
|
160
|
+
* Automatically retries on rate-limit errors with exponential backoff.
|
|
161
|
+
* Rejects on timeout, non-retryable API error, or max retries exceeded.
|
|
162
|
+
*/
|
|
163
|
+
async request(payloadType, payload) {
|
|
164
|
+
let lastError;
|
|
165
|
+
for (let attempt = 0; attempt <= CTraderConnection.MAX_RETRIES; attempt++) {
|
|
166
|
+
try {
|
|
167
|
+
return await this.requestOnce(payloadType, payload);
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
if (err instanceof CTraderError &&
|
|
171
|
+
err.isRateLimit &&
|
|
172
|
+
attempt < CTraderConnection.MAX_RETRIES) {
|
|
173
|
+
lastError = err;
|
|
174
|
+
const delay = err.retryAfter ?? CTraderConnection.INITIAL_RETRY_DELAY_MS * 2 ** attempt;
|
|
175
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
throw err;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
throw lastError ?? new Error("Max retries exceeded");
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Internal: send a single request without retry.
|
|
185
|
+
*/
|
|
186
|
+
requestOnce(payloadType, payload) {
|
|
126
187
|
return new Promise((resolve, reject) => {
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
this.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
188
|
+
const execute = () => {
|
|
189
|
+
this.inFlightRequests++;
|
|
190
|
+
this.lastRequestSentAt = Date.now();
|
|
191
|
+
let clientMsgId;
|
|
192
|
+
try {
|
|
193
|
+
clientMsgId = this.send(payloadType, payload);
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
this.inFlightRequests--;
|
|
197
|
+
this.drainQueue();
|
|
198
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const onComplete = () => {
|
|
202
|
+
this.inFlightRequests--;
|
|
203
|
+
this.drainQueue();
|
|
204
|
+
};
|
|
205
|
+
const timeout = setTimeout(() => {
|
|
206
|
+
this.pending.delete(clientMsgId);
|
|
207
|
+
onComplete();
|
|
208
|
+
reject(new RequestTimeoutError(payloadType, clientMsgId, this.requestTimeoutMs));
|
|
209
|
+
}, this.requestTimeoutMs);
|
|
210
|
+
this.pending.set(clientMsgId, {
|
|
211
|
+
resolve: (result) => {
|
|
212
|
+
onComplete();
|
|
213
|
+
resolve(result);
|
|
214
|
+
},
|
|
215
|
+
reject: (err) => {
|
|
216
|
+
onComplete();
|
|
217
|
+
reject(err);
|
|
218
|
+
},
|
|
219
|
+
timeout,
|
|
220
|
+
});
|
|
221
|
+
};
|
|
222
|
+
// Queue if at concurrency limit or need gap between sends
|
|
223
|
+
if (this.inFlightRequests >= MAX_CONCURRENT_REQUESTS) {
|
|
224
|
+
this.requestQueue.push(execute);
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
const elapsed = Date.now() - this.lastRequestSentAt;
|
|
228
|
+
if (elapsed < REQUEST_GAP_MS) {
|
|
229
|
+
setTimeout(execute, REQUEST_GAP_MS - elapsed);
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
execute();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
133
235
|
});
|
|
134
236
|
}
|
|
237
|
+
drainQueue() {
|
|
238
|
+
if (this.requestQueue.length === 0 || this.inFlightRequests >= MAX_CONCURRENT_REQUESTS) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
const next = this.requestQueue.shift();
|
|
242
|
+
const elapsed = Date.now() - this.lastRequestSentAt;
|
|
243
|
+
if (elapsed < REQUEST_GAP_MS) {
|
|
244
|
+
setTimeout(next, REQUEST_GAP_MS - elapsed);
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
next();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
135
250
|
// ─── Event handlers ─────────────────────────────────────────────────────
|
|
251
|
+
/**
|
|
252
|
+
* Subscribe to a specific payload type.
|
|
253
|
+
* Returns an unsubscribe function.
|
|
254
|
+
*/
|
|
136
255
|
on(payloadType, handler) {
|
|
137
256
|
let handlers = this.payloadHandlers.get(payloadType);
|
|
138
257
|
if (handlers === undefined) {
|
|
@@ -142,9 +261,14 @@ export class CTraderConnection {
|
|
|
142
261
|
handlers.add(handler);
|
|
143
262
|
return () => this.off(payloadType, handler);
|
|
144
263
|
}
|
|
264
|
+
/** Remove a specific handler for a payload type. */
|
|
145
265
|
off(payloadType, handler) {
|
|
146
266
|
this.payloadHandlers.get(payloadType)?.delete(handler);
|
|
147
267
|
}
|
|
268
|
+
/**
|
|
269
|
+
* Subscribe to connection lifecycle events (stateChange, error, message).
|
|
270
|
+
* Returns an unsubscribe function.
|
|
271
|
+
*/
|
|
148
272
|
onEvent(event, handler) {
|
|
149
273
|
let handlers = this.eventHandlers.get(event);
|
|
150
274
|
if (handlers === undefined) {
|
|
@@ -154,6 +278,7 @@ export class CTraderConnection {
|
|
|
154
278
|
handlers.add(handler);
|
|
155
279
|
return () => this.offEvent(event, handler);
|
|
156
280
|
}
|
|
281
|
+
/** Remove a specific connection event handler. */
|
|
157
282
|
offEvent(event, handler) {
|
|
158
283
|
this.eventHandlers.get(event)?.delete(handler);
|
|
159
284
|
}
|
|
@@ -194,8 +319,7 @@ export class CTraderConnection {
|
|
|
194
319
|
const req = this.pending.get(clientMsgId);
|
|
195
320
|
this.pending.delete(clientMsgId);
|
|
196
321
|
clearTimeout(req.timeout);
|
|
197
|
-
if (payloadType === PayloadType.ERROR_RES ||
|
|
198
|
-
payloadType === PayloadType.OA_ERROR_RES) {
|
|
322
|
+
if (payloadType === PayloadType.ERROR_RES || payloadType === PayloadType.OA_ERROR_RES) {
|
|
199
323
|
req.reject(this.makeError(payload));
|
|
200
324
|
return;
|
|
201
325
|
}
|
|
@@ -203,8 +327,7 @@ export class CTraderConnection {
|
|
|
203
327
|
return;
|
|
204
328
|
}
|
|
205
329
|
// Unsolicited error
|
|
206
|
-
if (payloadType === PayloadType.ERROR_RES ||
|
|
207
|
-
payloadType === PayloadType.OA_ERROR_RES) {
|
|
330
|
+
if (payloadType === PayloadType.ERROR_RES || payloadType === PayloadType.OA_ERROR_RES) {
|
|
208
331
|
this.emit("error", this.makeError(payload));
|
|
209
332
|
return;
|
|
210
333
|
}
|
|
@@ -264,8 +387,7 @@ export class CTraderConnection {
|
|
|
264
387
|
if (!this.shouldReconnect)
|
|
265
388
|
return;
|
|
266
389
|
this.reconnectAttempt++;
|
|
267
|
-
if (this.maxReconnectAttempts > 0 &&
|
|
268
|
-
this.reconnectAttempt > this.maxReconnectAttempts) {
|
|
390
|
+
if (this.maxReconnectAttempts > 0 && this.reconnectAttempt > this.maxReconnectAttempts) {
|
|
269
391
|
this.setState({ status: "disconnected" });
|
|
270
392
|
return;
|
|
271
393
|
}
|
|
@@ -329,6 +451,18 @@ export class CTraderConnection {
|
|
|
329
451
|
req.reject(error);
|
|
330
452
|
}
|
|
331
453
|
this.pending.clear();
|
|
454
|
+
// Reset throttle state — all in-flight requests are now dead
|
|
455
|
+
this.inFlightRequests = 0;
|
|
456
|
+
// Reject queued requests too — they'll fail on a dead socket
|
|
457
|
+
const queued = this.requestQueue.splice(0);
|
|
458
|
+
for (const fn of queued) {
|
|
459
|
+
try {
|
|
460
|
+
fn();
|
|
461
|
+
}
|
|
462
|
+
catch {
|
|
463
|
+
// Will throw NotConnectedError — caught by caller
|
|
464
|
+
}
|
|
465
|
+
}
|
|
332
466
|
}
|
|
333
467
|
makeError(err) {
|
|
334
468
|
const opts = {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../../src/core/connection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,EAEN,aAAa,EACb,eAAe,EACf,aAAa,GACb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEnF,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,MAAM,kBAAkB,GAAG,KAAK,CAAC;AACjC,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACjC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AACpC,MAAM,0BAA0B,GAAG,KAAK,CAAC;AACzC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAEtC;;;;GAIG;AACH,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAClC,MAAM,cAAc,GAAG,EAAE,CAAC;AA0B1B;;;;;;GAMG;AACH,MAAM,OAAO,iBAAiB;IACrB,MAAM,GAAyB,IAAI,CAAC;IAC3B,IAAI,CAAS;IACb,IAAI,CAAS;IACb,oBAAoB,CAAS;IAC7B,gBAAgB,CAAS;IACzB,WAAW,CAAoC;IACxD,gBAAgB,GAAG,KAAK,CAAC;IAEzB,MAAM,GAAoB,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IACrD,eAAe,GAAG,KAAK,CAAC;IACxB,cAAc,GAAyC,IAAI,CAAC;IAC5D,gBAAgB,GAAG,CAAC,CAAC;IAErB,iBAAiB,GAA0C,IAAI,CAAC;IAChE,sBAAsB,GAA0C,IAAI,CAAC;IACrE,eAAe,GAAG,CAAC,CAAC;IACpB,UAAU,GAAG,CAAC,CAAC;IAEvB,qDAAqD;IAC7C,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEpB,OAAO,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC5C,eAAe,GAAG,IAAI,GAAG,EAA+B,CAAC;IACzD,aAAa,GAAG,IAAI,GAAG,EAAgD,CAAC;IAEzF,6BAA6B;IACZ,YAAY,GAAsB,EAAE,CAAC;IAC9C,gBAAgB,GAAG,CAAC,CAAC;IACrB,iBAAiB,GAAG,CAAC,CAAC;IAE9B,YAAY,MAA+B;QAC1C,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC;QAChC,IAAI,CAAC,oBAAoB,GAAG,MAAM,CAAC,oBAAoB,IAAI,CAAC,CAAC;QAC7D,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,IAAI,kBAAkB,CAAC;QACtE,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IACvC,CAAC;IAED,0CAA0C;IAC1C,IAAI,KAAK;QACR,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;IAED,0EAA0E;IAC1E,IAAI,WAAW;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,OAAO,CAAC;IAC7E,CAAC;IAED,2EAA2E;IAE3E;;;OAGG;IACH,OAAO;QACN,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;gBAC1E,OAAO,EAAE,CAAC;gBACV,OAAO;YACR,CAAC;YAED,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;YAC5B,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;YAC1B,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;YAEpD,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACjE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YAErB,MAAM,eAAe,GAAG,GAAG,EAAE;gBAC5B,OAAO,EAAE,CAAC;gBACV,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;gBAC1B,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBAC7B,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAClC,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBAC1D,IAAI,CAAC,cAAc,EAAE,CAAC;gBACtB,OAAO,EAAE,CAAC;YACX,CAAC,CAAC;YAEF,MAAM,OAAO,GAAG,CAAC,GAAU,EAAE,EAAE;gBAC9B,OAAO,EAAE,CAAC;gBACV,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBACxB,MAAM,CAAC,IAAI,KAAK,CAAC,0BAA0B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAC5D,CAAC,CAAC;YAEF,MAAM,OAAO,GAAG,GAAG,EAAE;gBACpB,MAAM,CAAC,cAAc,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;gBACxD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACzC,CAAC,CAAC;YAEF,MAAM,CAAC,EAAE,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;YAC5C,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAE5B,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;YAC7D,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACvB,IAAI,CAAC,aAAa,EAAE,CAAC;gBACrB,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;gBACnD,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;oBAC3C,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;gBAC3C,CAAC;gBACD,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC1B,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,UAAU;QACT,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAE7B,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YAClC,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAErD,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC1B,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACtB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACpB,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,2EAA2E;IAE3E;;;OAGG;IACH,IAAI,CAAC,WAAmB,EAAE,OAAiC;QAC1D,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACnD,MAAM,IAAI,iBAAiB,EAAE,CAAC;QAC/B,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,aAAa,CAAC,WAAW,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,OAAO,WAAW,CAAC;IACpB,CAAC;IAEO,MAAM,CAAU,WAAW,GAAG,CAAC,CAAC;IAChC,MAAM,CAAU,sBAAsB,GAAG,KAAK,CAAC;IAEvD;;;;OAIG;IACH,KAAK,CAAC,OAAO,CACZ,WAAmB,EACnB,OAAgC;QAEhC,IAAI,SAA4B,CAAC;QACjC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,iBAAiB,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;YAC3E,IAAI,CAAC;gBACJ,OAAO,MAAM,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACrD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,IACC,GAAG,YAAY,YAAY;oBAC3B,GAAG,CAAC,WAAW;oBACf,OAAO,GAAG,iBAAiB,CAAC,WAAW,EACtC,CAAC;oBACF,SAAS,GAAG,GAAG,CAAC;oBAChB,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,IAAI,iBAAiB,CAAC,sBAAsB,GAAG,CAAC,IAAI,OAAO,CAAC;oBACxF,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;oBACrD,SAAS;gBACV,CAAC;gBACD,MAAM,GAAG,CAAC;YACX,CAAC;QACF,CAAC;QACD,MAAM,SAAS,IAAI,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACtD,CAAC;IAED;;OAEG;IACK,WAAW,CAClB,WAAmB,EACnB,OAAgC;QAEhC,OAAO,IAAI,OAAO,CAA0B,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC/D,MAAM,OAAO,GAAG,GAAG,EAAE;gBACpB,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACxB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAEpC,IAAI,WAAmB,CAAC;gBACxB,IAAI,CAAC;oBACJ,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;gBAC/C,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACd,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACxB,IAAI,CAAC,UAAU,EAAE,CAAC;oBAClB,MAAM,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;oBAC5D,OAAO;gBACR,CAAC;gBAED,MAAM,UAAU,GAAG,GAAG,EAAE;oBACvB,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACxB,IAAI,CAAC,UAAU,EAAE,CAAC;gBACnB,CAAC,CAAC;gBAEF,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;oBAC/B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;oBACjC,UAAU,EAAE,CAAC;oBACb,MAAM,CAAC,IAAI,mBAAmB,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;gBAClF,CAAC,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;gBAE1B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE;oBAC7B,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE;wBACnB,UAAU,EAAE,CAAC;wBACb,OAAO,CAAC,MAAM,CAAC,CAAC;oBACjB,CAAC;oBACD,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE;wBACf,UAAU,EAAE,CAAC;wBACb,MAAM,CAAC,GAAG,CAAC,CAAC;oBACb,CAAC;oBACD,OAAO;iBACP,CAAC,CAAC;YACJ,CAAC,CAAC;YAEF,0DAA0D;YAC1D,IAAI,IAAI,CAAC,gBAAgB,IAAI,uBAAuB,EAAE,CAAC;gBACtD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACjC,CAAC;iBAAM,CAAC;gBACP,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC;gBACpD,IAAI,OAAO,GAAG,cAAc,EAAE,CAAC;oBAC9B,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC;gBAC/C,CAAC;qBAAM,CAAC;oBACP,OAAO,EAAE,CAAC;gBACX,CAAC;YACF,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IAEO,UAAU;QACjB,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,gBAAgB,IAAI,uBAAuB,EAAE,CAAC;YACxF,OAAO;QACR,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,EAAG,CAAC;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC;QACpD,IAAI,OAAO,GAAG,cAAc,EAAE,CAAC;YAC9B,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC;QAC5C,CAAC;aAAM,CAAC;YACP,IAAI,EAAE,CAAC;QACR,CAAC;IACF,CAAC;IAED,2EAA2E;IAE3E;;;OAGG;IACH,EAAE,CAAC,WAAmB,EAAE,OAAuB;QAC9C,IAAI,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACrD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,QAAQ,GAAG,IAAI,GAAG,EAAE,CAAC;YACrB,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QACjD,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED,oDAAoD;IACpD,GAAG,CAAC,WAAmB,EAAE,OAAuB;QAC/C,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACxD,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,KAAsB,EAAE,OAA+B;QAC9D,IAAI,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,QAAQ,GAAG,IAAI,GAAG,EAAE,CAAC;YACrB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACzC,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,kDAAkD;IAClD,QAAQ,CAAC,KAAsB,EAAE,OAA+B;QAC/D,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;IAED,2EAA2E;IAEnE,UAAU,CAAC,KAAa;QAC/B,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;QAE1D,iDAAiD;QACjD,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/C,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM;gBAAE,MAAM,CAAC,qBAAqB;YAErE,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC;YACzD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;YAEvD,IAAI,CAAC;gBACJ,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;gBACxC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YAC7B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACvB,CAAC;QACF,CAAC;IACF,CAAC;IAEO,aAAa,CAAC,GAAmB;QACxC,kEAAkE;QAClE,iEAAiE;QACjE,+DAA+D;QAC/D,+BAA+B;QAC/B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAElC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAE1B,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC;QAElD,kEAAkE;QAClE,IAAI,WAAW,KAAK,WAAW,CAAC,eAAe,EAAE,CAAC;YACjD,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,OAAO;QACR,CAAC;QAED,+BAA+B;QAC/B,IAAI,WAAW,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAChE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAE,CAAC;YAC3C,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YACjC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAE1B,IAAI,WAAW,KAAK,WAAW,CAAC,SAAS,IAAI,WAAW,KAAK,WAAW,CAAC,YAAY,EAAE,CAAC;gBACvF,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAgD,CAAC,CAAC,CAAC;gBAC7E,OAAO;YACR,CAAC;YAED,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACrB,OAAO;QACR,CAAC;QAED,oBAAoB;QACpB,IAAI,WAAW,KAAK,WAAW,CAAC,SAAS,IAAI,WAAW,KAAK,WAAW,CAAC,YAAY,EAAE,CAAC;YACvF,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAgD,CAAC,CAAC,CAAC;YACrF,OAAO;QACR,CAAC;QAED,kDAAkD;QAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACvD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAChC,IAAI,CAAC;oBACJ,OAAO,CAAC,OAAO,CAAC,CAAC;gBAClB,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACZ,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBACvB,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAED,2EAA2E;IAEnE,aAAa;QACpB,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YAC3C,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,CAAC;IACF,CAAC;IAEO,cAAc;QACrB,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,eAAe,GAAG,GAAG,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QAEtB,kEAAkE;QAClE,IAAI,CAAC,iBAAiB,GAAG,WAAW,CAAC,GAAG,EAAE;YACzC,IACC,IAAI,CAAC,MAAM;gBACX,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS;gBACtB,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,IAAI,iBAAiB,EAChD,CAAC;gBACF,IAAI,CAAC,aAAa,EAAE,CAAC;YACtB,CAAC;QACF,CAAC,EAAE,kBAAkB,CAAC,CAAC;QAEvB,4DAA4D;QAC5D,IAAI,CAAC,sBAAsB,GAAG,WAAW,CAAC,GAAG,EAAE;YAC9C,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,GAAG,oBAAoB,EAAE,CAAC;gBAC9D,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YACxB,CAAC;QACF,CAAC,EAAE,kBAAkB,CAAC,CAAC;IACxB,CAAC;IAEO,aAAa;QACpB,IAAI,IAAI,CAAC,iBAAiB,KAAK,IAAI,EAAE,CAAC;YACrC,aAAa,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACtC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC/B,CAAC;QACD,IAAI,IAAI,CAAC,sBAAsB,KAAK,IAAI,EAAE,CAAC;YAC1C,aAAa,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;YAC3C,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;QACpC,CAAC;IACF,CAAC;IAED,2EAA2E;IAEnE,iBAAiB;QACxB,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE,OAAO;QAElC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAExB,IAAI,IAAI,CAAC,oBAAoB,GAAG,CAAC,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACxF,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;YAC1C,OAAO;QACR,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACrB,0BAA0B,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC,EAC7D,sBAAsB,CACtB,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC;YACb,MAAM,EAAE,cAAc;YACtB,OAAO,EAAE,IAAI,CAAC,gBAAgB;YAC9B,WAAW,EAAE,KAAK;SAClB,CAAC,CAAC;QAEH,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;YACrC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,IAAI,CAAC,WAAW,EAAE,CAAC;QACpB,CAAC,EAAE,KAAK,CAAC,CAAC;IACX,CAAC;IAEO,WAAW;QAClB,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE,OAAO;QAElC,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAExE,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACjE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,MAAM,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;YACrC,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;YAC1B,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAClC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACzB,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;YAC9C,IAAI,CAAC,cAAc,EAAE,CAAC;YAEtB,IAAI,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC7D,IAAI,CAAC;oBACJ,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;oBACzB,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;wBACxC,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;oBAC3C,CAAC;gBACF,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACZ,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBACvB,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YAC3C,CAAC;QACF,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;QAE7D,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;YACjC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACvB,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;YACnD,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;YAC1C,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,2EAA2E;IAEnE,QAAQ,CAAC,KAAsB;QACtC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IAEO,aAAa,CAAC,KAAY;QACjC,KAAK,MAAM,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACpC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC1B,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnB,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,6DAA6D;QAC7D,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;QAC1B,6DAA6D;QAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC3C,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;YACzB,IAAI,CAAC;gBACJ,EAAE,EAAE,CAAC;YACN,CAAC;YAAC,MAAM,CAAC;gBACR,kDAAkD;YACnD,CAAC;QACF,CAAC;IACF,CAAC;IAEO,SAAS,CAAC,GAA+B;QAChD,MAAM,IAAI,GAKN;YACH,IAAI,EAAE,GAAG,EAAE,SAAS,IAAI,SAAS;YACjC,WAAW,EAAE,GAAG,EAAE,WAAW,IAAI,eAAe;SAChD,CAAC;QACF,IAAI,GAAG,EAAE,UAAU,KAAK,SAAS;YAAE,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC;QACpE,IAAI,GAAG,EAAE,uBAAuB,KAAK,SAAS;YAC7C,IAAI,CAAC,uBAAuB,GAAG,GAAG,CAAC,uBAAuB,CAAC;QAC5D,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAEO,IAAI,CAAC,KAAsB,EAAE,IAAa;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAChC,IAAI,CAAC;oBACJ,OAAO,CAAC,IAAI,CAAC,CAAC;gBACf,CAAC;gBAAC,MAAM,CAAC;oBACR,+CAA+C;gBAChD,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** Error returned by the cTrader Open API — includes a machine-readable code and human description. */
|
|
1
2
|
export declare class CTraderError extends Error {
|
|
2
3
|
readonly code: string;
|
|
3
4
|
readonly description: string;
|
|
@@ -9,15 +10,19 @@ export declare class CTraderError extends Error {
|
|
|
9
10
|
retryAfter?: number;
|
|
10
11
|
maintenanceEndTimestamp?: number;
|
|
11
12
|
});
|
|
13
|
+
/** Actionable recovery hint for this error, or undefined for unknown error codes */
|
|
14
|
+
get hint(): string | undefined;
|
|
12
15
|
get isAuthError(): boolean;
|
|
13
16
|
get isRateLimit(): boolean;
|
|
14
17
|
get isMaintenance(): boolean;
|
|
15
18
|
}
|
|
19
|
+
/** Thrown when a request does not receive a response within the configured timeout. */
|
|
16
20
|
export declare class RequestTimeoutError extends Error {
|
|
17
21
|
readonly payloadType: number;
|
|
18
22
|
readonly clientMsgId: string;
|
|
19
23
|
constructor(payloadType: number, clientMsgId: string, timeoutMs: number);
|
|
20
24
|
}
|
|
25
|
+
/** Thrown when an operation is attempted while the WebSocket is not connected. */
|
|
21
26
|
export declare class NotConnectedError extends Error {
|
|
22
27
|
constructor();
|
|
23
28
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/core/errors.ts"],"names":[],"mappings":"AA6CA,uGAAuG;AACvG,qBAAa,YAAa,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC;gBAE9B,IAAI,EAAE;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,uBAAuB,CAAC,EAAE,MAAM,CAAC;KACjC;IAcD,oFAAoF;IACpF,IAAI,IAAI,IAAI,MAAM,GAAG,SAAS,CAE7B;IAED,IAAI,WAAW,IAAI,OAAO,CASzB;IAED,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,IAAI,aAAa,IAAI,OAAO,CAE3B;CACD;AAED,uFAAuF;AACvF,qBAAa,mBAAoB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAEjB,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAQvE;AAED,kFAAkF;AAClF,qBAAa,iBAAkB,SAAQ,KAAK;;CAO3C"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/** Actionable hint map: maps error codes to user-friendly recovery instructions */
|
|
2
|
+
const ERROR_HINTS = {
|
|
3
|
+
// Auth errors
|
|
4
|
+
OA_AUTH_TOKEN_EXPIRED: "Your access token has expired. Run `ctrader-ts auth` to re-authenticate.",
|
|
5
|
+
ACCOUNT_NOT_AUTHORIZED: "This account isn't authorized. Run `ctrader-ts auth` and select the correct account.",
|
|
6
|
+
CH_CLIENT_AUTH_FAILURE: "Client authentication failed. Check your clientId and clientSecret in config.",
|
|
7
|
+
CH_CLIENT_NOT_AUTHENTICATED: "You must authenticate before making requests. Call connect() which handles this automatically.",
|
|
8
|
+
CH_ACCESS_TOKEN_INVALID: "Invalid access token. Run `ctrader-ts auth` to get a fresh token.",
|
|
9
|
+
OAUTH_TOKEN_INVALIDATED: "Token was invalidated (possibly revoked or used from another location). Run `ctrader-ts auth`.",
|
|
10
|
+
// Rate limiting
|
|
11
|
+
REQUEST_FREQUENCY_EXCEEDED: "Too many requests. Wait and retry — consider adding delays between rapid API calls.",
|
|
12
|
+
BLOCKED_PAYLOAD_TYPE: "This request type is temporarily blocked due to rate limiting. Wait before retrying.",
|
|
13
|
+
// Maintenance
|
|
14
|
+
SERVER_IS_UNDER_MAINTENANCE: "Server is under maintenance. Check maintenanceEndTimestamp for expected end time.",
|
|
15
|
+
// Trading errors
|
|
16
|
+
NOT_ENOUGH_MONEY: "Insufficient free margin. Reduce position size or close existing positions to free up margin.",
|
|
17
|
+
SYMBOL_NOT_FOUND: "Symbol not found. Check available symbols with getSymbols() or `ctrader-ts symbols`.",
|
|
18
|
+
INVALID_VOLUME: "Invalid volume. Ensure lots >= minVolume and is a multiple of stepVolume. Use getSymbolInfo() to check limits.",
|
|
19
|
+
MARKET_CLOSED: "Market is closed for this symbol. Check trading hours with getSymbolInfo().",
|
|
20
|
+
TRADING_BAD_VOLUME: "Volume out of range. Use getSymbolInfo() to check minVolume, maxVolume, and stepVolume.",
|
|
21
|
+
TRADING_BAD_STOPS: "Invalid SL/TP distance. Some brokers require minimum distances — use getSymbolInfo() to check slDistance/tpDistance.",
|
|
22
|
+
POSITION_NOT_FOUND: "Position not found. It may have been closed or the ID is incorrect.",
|
|
23
|
+
ORDER_NOT_FOUND: "Order not found. It may have been filled, expired, or cancelled.",
|
|
24
|
+
NO_MORE_ACCOUNTS_AVAILABLE: "No more accounts available. Check your cTrader ID has linked broker accounts.",
|
|
25
|
+
CONNECTIONS_LIMIT_EXCEEDED: "Too many connections from this app. Close other sessions or wait for them to expire.",
|
|
26
|
+
TRADING_DISABLED: "Trading is disabled on this account. Contact your broker.",
|
|
27
|
+
};
|
|
28
|
+
/** Error returned by the cTrader Open API — includes a machine-readable code and human description. */
|
|
29
|
+
export class CTraderError extends Error {
|
|
30
|
+
code;
|
|
31
|
+
description;
|
|
32
|
+
retryAfter;
|
|
33
|
+
maintenanceEndTimestamp;
|
|
34
|
+
constructor(opts) {
|
|
35
|
+
const hint = ERROR_HINTS[opts.code];
|
|
36
|
+
const message = hint
|
|
37
|
+
? `[${opts.code}] ${opts.description} — ${hint}`
|
|
38
|
+
: `[${opts.code}] ${opts.description}`;
|
|
39
|
+
super(message);
|
|
40
|
+
this.name = "CTraderError";
|
|
41
|
+
this.code = opts.code;
|
|
42
|
+
this.description = opts.description;
|
|
43
|
+
if (opts.retryAfter !== undefined)
|
|
44
|
+
this.retryAfter = opts.retryAfter;
|
|
45
|
+
if (opts.maintenanceEndTimestamp !== undefined)
|
|
46
|
+
this.maintenanceEndTimestamp = opts.maintenanceEndTimestamp;
|
|
47
|
+
}
|
|
48
|
+
/** Actionable recovery hint for this error, or undefined for unknown error codes */
|
|
49
|
+
get hint() {
|
|
50
|
+
return ERROR_HINTS[this.code];
|
|
51
|
+
}
|
|
52
|
+
get isAuthError() {
|
|
53
|
+
return (this.code === "OA_AUTH_TOKEN_EXPIRED" ||
|
|
54
|
+
this.code === "ACCOUNT_NOT_AUTHORIZED" ||
|
|
55
|
+
this.code === "CH_CLIENT_AUTH_FAILURE" ||
|
|
56
|
+
this.code === "CH_CLIENT_NOT_AUTHENTICATED" ||
|
|
57
|
+
this.code === "CH_ACCESS_TOKEN_INVALID" ||
|
|
58
|
+
this.code === "OAUTH_TOKEN_INVALIDATED");
|
|
59
|
+
}
|
|
60
|
+
get isRateLimit() {
|
|
61
|
+
return this.code === "REQUEST_FREQUENCY_EXCEEDED" || this.code === "BLOCKED_PAYLOAD_TYPE";
|
|
62
|
+
}
|
|
63
|
+
get isMaintenance() {
|
|
64
|
+
return this.code === "SERVER_IS_UNDER_MAINTENANCE";
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** Thrown when a request does not receive a response within the configured timeout. */
|
|
68
|
+
export class RequestTimeoutError extends Error {
|
|
69
|
+
payloadType;
|
|
70
|
+
clientMsgId;
|
|
71
|
+
constructor(payloadType, clientMsgId, timeoutMs) {
|
|
72
|
+
super(`Request timed out after ${timeoutMs}ms (payloadType: ${payloadType}, id: ${clientMsgId}). Check your network connection or try increasing requestTimeoutMs.`);
|
|
73
|
+
this.name = "RequestTimeoutError";
|
|
74
|
+
this.payloadType = payloadType;
|
|
75
|
+
this.clientMsgId = clientMsgId;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** Thrown when an operation is attempted while the WebSocket is not connected. */
|
|
79
|
+
export class NotConnectedError extends Error {
|
|
80
|
+
constructor() {
|
|
81
|
+
super("Not connected to cTrader API. Call connect() first, or check that the connection hasn't been dropped.");
|
|
82
|
+
this.name = "NotConnectedError";
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/core/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { CTraderAccount } from "
|
|
2
|
-
import type { CTraderMarket } from "
|
|
1
|
+
import type { CTraderAccount } from "../modules/account.js";
|
|
2
|
+
import type { CTraderMarket } from "../modules/market.js";
|
|
3
|
+
import type { SlTpSpec } from "../protocol/types.js";
|
|
3
4
|
import type { SymbolCache } from "./symbol-cache.js";
|
|
4
|
-
import type { SlTpSpec } from "./types.js";
|
|
5
5
|
export type { SlTpSpec };
|
|
6
6
|
interface SlTpContext {
|
|
7
7
|
account: CTraderAccount;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/core/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAc,QAAQ,EAAa,MAAM,sBAAsB,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,YAAY,EAAE,QAAQ,EAAE,CAAC;AAEzB,UAAU,WAAW;IACpB,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,YAAY;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,SAAI,GAAG,MAAM,CAEpE;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAChC,GAAG,EAAE,WAAW,EAChB,EAAE,EAAE,QAAQ,GAAG,SAAS,EACxB,EAAE,EAAE,QAAQ,GAAG,SAAS,GACtB,OAAO,CAAC,YAAY,CAAC,CAmBvB"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Formula: pips * 10^(5 - pipPosition)
|
|
4
4
|
*/
|
|
5
5
|
export function pipsToRelative(pips, pipPosition = 4) {
|
|
6
|
-
return Math.round(pips *
|
|
6
|
+
return Math.round(pips * 10 ** (5 - pipPosition));
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* Resolve human-friendly SlTpSpec (pips / dollars / equity) into protocol-level
|
|
@@ -31,7 +31,7 @@ async function specToPips(cache, spec, volumeInUnits) {
|
|
|
31
31
|
if ("pips" in spec)
|
|
32
32
|
return spec.pips;
|
|
33
33
|
const sym = await cache.getSymbolDetails();
|
|
34
|
-
const pipSize =
|
|
34
|
+
const pipSize = 10 ** -sym.pipPosition;
|
|
35
35
|
const lotSize = sym.lotSize ?? 100_000;
|
|
36
36
|
const lots = volumeInUnits / 100_000;
|
|
37
37
|
// pipValue = pipSize * lotSize * quoteToAccountRate (assumed 1:1 for USD accounts)
|
|
@@ -63,9 +63,7 @@ class RequestCache {
|
|
|
63
63
|
}
|
|
64
64
|
getSymbolDetails() {
|
|
65
65
|
if (this.symbolPromise === null) {
|
|
66
|
-
this.symbolPromise = this.ctx.market
|
|
67
|
-
.getSymbolsById([this.ctx.symbolId])
|
|
68
|
-
.then((symbols) => {
|
|
66
|
+
this.symbolPromise = this.ctx.market.getSymbolsById([this.ctx.symbolId]).then((symbols) => {
|
|
69
67
|
const sym = symbols[0];
|
|
70
68
|
if (sym === undefined) {
|
|
71
69
|
throw new Error(`Symbol details not found for id ${this.ctx.symbolId}`);
|
|
@@ -91,14 +89,18 @@ class RequestCache {
|
|
|
91
89
|
return new Promise((resolve, reject) => {
|
|
92
90
|
const timeout = setTimeout(() => {
|
|
93
91
|
unsub();
|
|
94
|
-
void this.ctx.market.unsubscribeSpots([this.ctx.symbolId]).catch(() => {
|
|
92
|
+
void this.ctx.market.unsubscribeSpots([this.ctx.symbolId]).catch(() => {
|
|
93
|
+
/* fire-and-forget cleanup */
|
|
94
|
+
});
|
|
95
95
|
reject(new Error(`Timed out waiting for spot price on symbol ${this.ctx.symbolId}`));
|
|
96
96
|
}, 10_000);
|
|
97
97
|
const unsub = this.ctx.market.onSpot((event) => {
|
|
98
98
|
if (event.symbolId === this.ctx.symbolId) {
|
|
99
99
|
clearTimeout(timeout);
|
|
100
100
|
unsub();
|
|
101
|
-
void this.ctx.market.unsubscribeSpots([this.ctx.symbolId]).catch(() => {
|
|
101
|
+
void this.ctx.market.unsubscribeSpots([this.ctx.symbolId]).catch(() => {
|
|
102
|
+
/* fire-and-forget cleanup */
|
|
103
|
+
});
|
|
102
104
|
resolve(event);
|
|
103
105
|
}
|
|
104
106
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/core/helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { CTraderMarket } from "
|
|
2
|
-
import type { LightSymbol } from "
|
|
1
|
+
import type { CTraderMarket } from "../modules/market.js";
|
|
2
|
+
import type { LightSymbol } from "../protocol/types.js";
|
|
3
3
|
export declare class SymbolCache {
|
|
4
4
|
private readonly market;
|
|
5
5
|
private nameToId;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"symbol-cache.d.ts","sourceRoot":"","sources":["../../../src/core/symbol-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,qBAAa,WAAW;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAoC;IACpD,OAAO,CAAC,UAAU,CAAyC;gBAE/C,MAAM,EAAE,aAAa;IAI3B,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAWvD,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAQ5D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAMhB,WAAW;YAKX,aAAa;CAI3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"symbol-cache.js","sourceRoot":"","sources":["../../../src/core/symbol-cache.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,WAAW;IACN,MAAM,CAAgB;IAC/B,QAAQ,GAA+B,IAAI,CAAC;IAC5C,UAAU,GAAoC,IAAI,CAAC;IAE3D,YAAY,MAAqB;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,UAA2B;QAC1C,IAAI,OAAO,UAAU,KAAK,QAAQ;YAAE,OAAO,UAAU,CAAC;QACtD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;QAC7C,IAAI,EAAE,KAAK,SAAS;YACnB,MAAM,IAAI,KAAK,CACd,sBAAsB,UAAU,sDAAsD,CACtF,CAAC;QACH,OAAO,EAAE,CAAC;IACX,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,UAA2B;QAC1C,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxB,IAAI,GAAG,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,aAAa,EAAE,sBAAsB,CAAC,CAAC;QAC9E,OAAO,GAAG,CAAC;IACZ,CAAC;IAED,KAAK,CAAC,OAAO;QACZ,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QACnD,IAAI,CAAC,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC7F,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC;IAEO,KAAK,CAAC,WAAW;QACxB,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI;YAAE,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACjD,OAAO,IAAI,CAAC,QAAS,CAAC;IACvB,CAAC;IAEO,KAAK,CAAC,aAAa;QAC1B,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI;YAAE,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACnD,OAAO,IAAI,CAAC,UAAW,CAAC;IACzB,CAAC;CACD"}
|