@pipsend/sdk 0.3.0 โ 0.3.1
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 +239 -227
- package/dist/index.d.mts +17 -20
- package/dist/index.d.ts +17 -20
- package/dist/index.js +22 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +22 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,12 +36,12 @@ pnpm add @pipsend/sdk
|
|
|
36
36
|
The SDK uses JWT-based authentication with automatic token refresh.
|
|
37
37
|
|
|
38
38
|
```typescript
|
|
39
|
-
import { createClient } from
|
|
39
|
+
import { createClient } from "@pipsend/sdk";
|
|
40
40
|
|
|
41
41
|
const client = createClient({
|
|
42
|
-
server:
|
|
43
|
-
login:
|
|
44
|
-
password:
|
|
42
|
+
server: "http://localhost:8080",
|
|
43
|
+
login: "1000", // Your admin/API login
|
|
44
|
+
password: "YourPassword", // Your admin/API password
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
// The SDK automatically:
|
|
@@ -69,7 +69,7 @@ await client.logout();
|
|
|
69
69
|
|
|
70
70
|
// Get current token info
|
|
71
71
|
const tokenInfo = client.getTokenInfo();
|
|
72
|
-
console.log(
|
|
72
|
+
console.log("Token expires at:", tokenInfo?.expiresAt);
|
|
73
73
|
```
|
|
74
74
|
|
|
75
75
|
---
|
|
@@ -77,45 +77,45 @@ console.log('Token expires at:', tokenInfo?.expiresAt);
|
|
|
77
77
|
## ๐ง Quick Start
|
|
78
78
|
|
|
79
79
|
```typescript
|
|
80
|
-
import { createClient } from
|
|
80
|
+
import { createClient } from "@pipsend/sdk";
|
|
81
81
|
|
|
82
82
|
// Create authenticated client
|
|
83
83
|
const client = createClient({
|
|
84
|
-
server:
|
|
85
|
-
login:
|
|
86
|
-
password:
|
|
84
|
+
server: "http://localhost:8080",
|
|
85
|
+
login: "1000",
|
|
86
|
+
password: "DemoMaster",
|
|
87
87
|
});
|
|
88
88
|
|
|
89
89
|
const login = 50001;
|
|
90
90
|
|
|
91
91
|
// List accounts with filters
|
|
92
92
|
const accounts = await client.accounts.list({
|
|
93
|
-
state:
|
|
94
|
-
country:
|
|
95
|
-
min_balance: 1000
|
|
93
|
+
state: "active",
|
|
94
|
+
country: "Mexico",
|
|
95
|
+
min_balance: 1000,
|
|
96
96
|
});
|
|
97
97
|
|
|
98
98
|
// Open a trade
|
|
99
99
|
const trade = await client.trades.open({
|
|
100
100
|
login,
|
|
101
|
-
symbol:
|
|
102
|
-
action:
|
|
103
|
-
type:
|
|
101
|
+
symbol: "EURUSD",
|
|
102
|
+
action: "buy",
|
|
103
|
+
type: "market",
|
|
104
104
|
volume: 1.0,
|
|
105
|
-
stop_loss: 1.
|
|
106
|
-
take_profit: 1.
|
|
105
|
+
stop_loss: 1.085,
|
|
106
|
+
take_profit: 1.095,
|
|
107
107
|
});
|
|
108
108
|
|
|
109
109
|
// Get market data
|
|
110
110
|
const candles = await client.marketData.getCandles({
|
|
111
|
-
symbol:
|
|
112
|
-
timeframe:
|
|
113
|
-
limit: 100
|
|
111
|
+
symbol: "BTCUSD",
|
|
112
|
+
timeframe: "1h",
|
|
113
|
+
limit: 100,
|
|
114
114
|
});
|
|
115
115
|
|
|
116
116
|
// WebSocket real-time updates
|
|
117
117
|
client.stream.onPriceUpdate((price) => {
|
|
118
|
-
console.log(
|
|
118
|
+
console.log("Price update:", price);
|
|
119
119
|
});
|
|
120
120
|
|
|
121
121
|
await client.stream.connect();
|
|
@@ -130,32 +130,32 @@ Manage accounts with advanced filtering and statistics.
|
|
|
130
130
|
```typescript
|
|
131
131
|
// Create a new trading account
|
|
132
132
|
const newAccount = await client.accounts.create({
|
|
133
|
-
trading_group:
|
|
134
|
-
country:
|
|
135
|
-
master_password:
|
|
136
|
-
investor_password:
|
|
137
|
-
email:
|
|
138
|
-
first_name:
|
|
139
|
-
last_name:
|
|
133
|
+
trading_group: "Premium",
|
|
134
|
+
country: "MX",
|
|
135
|
+
master_password: "SecurePass123!",
|
|
136
|
+
investor_password: "InvestorPass123!",
|
|
137
|
+
email: "trader@example.com",
|
|
138
|
+
first_name: "John",
|
|
139
|
+
last_name: "Doe",
|
|
140
140
|
leverage: 100,
|
|
141
|
-
state:
|
|
141
|
+
state: "active",
|
|
142
142
|
});
|
|
143
143
|
|
|
144
144
|
// List accounts with filters
|
|
145
145
|
const accounts = await client.accounts.list({
|
|
146
|
-
state:
|
|
147
|
-
country:
|
|
148
|
-
trading_group:
|
|
146
|
+
state: "active",
|
|
147
|
+
country: "Mexico,United States",
|
|
148
|
+
trading_group: "Premium",
|
|
149
149
|
min_balance: 1000,
|
|
150
150
|
max_balance: 50000,
|
|
151
151
|
page: 1,
|
|
152
|
-
per_page: 20
|
|
152
|
+
per_page: 20,
|
|
153
153
|
});
|
|
154
154
|
|
|
155
155
|
// Get statistics with filters
|
|
156
156
|
const stats = await client.accounts.getStatistics({
|
|
157
|
-
country:
|
|
158
|
-
state:
|
|
157
|
+
country: "Mexico",
|
|
158
|
+
state: "active",
|
|
159
159
|
});
|
|
160
160
|
|
|
161
161
|
// Get all account logins
|
|
@@ -163,18 +163,15 @@ const logins = await client.accounts.getLogins();
|
|
|
163
163
|
|
|
164
164
|
// Get account status/metrics (balance, equity, credit, margin)
|
|
165
165
|
const status = await client.accounts.getStatus(50001);
|
|
166
|
-
console.log(
|
|
167
|
-
console.log(
|
|
168
|
-
console.log(
|
|
169
|
-
console.log(
|
|
166
|
+
console.log("Balance:", status.data.balance);
|
|
167
|
+
console.log("Equity:", status.data.equity);
|
|
168
|
+
console.log("Credit:", status.data.credit);
|
|
169
|
+
console.log("Margin:", status.data.margin);
|
|
170
170
|
|
|
171
|
-
// Change passwords
|
|
172
|
-
await client.accounts.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
await client.accounts.changeInvestorPassword(50001, {
|
|
177
|
-
new_password: 'InvestorPass123!'
|
|
171
|
+
// Change passwords (master and/or investor)
|
|
172
|
+
await client.accounts.changePassword(50001, {
|
|
173
|
+
master: "NewMasterPass123!",
|
|
174
|
+
investor: "NewInvestorPass123!",
|
|
178
175
|
});
|
|
179
176
|
|
|
180
177
|
// Archive/Unarchive
|
|
@@ -183,30 +180,30 @@ await client.accounts.unarchive(50001);
|
|
|
183
180
|
|
|
184
181
|
// Update account information (partial update)
|
|
185
182
|
await client.accounts.update(50001, {
|
|
186
|
-
email:
|
|
183
|
+
email: "newemail@example.com",
|
|
187
184
|
leverage: 200,
|
|
188
|
-
city:
|
|
189
|
-
trading_group:
|
|
185
|
+
city: "Los Angeles",
|
|
186
|
+
trading_group: "Premium",
|
|
190
187
|
});
|
|
191
188
|
|
|
192
189
|
// Adjust balance or credit
|
|
193
190
|
await client.accounts.balance(50001, {
|
|
194
|
-
type:
|
|
195
|
-
amount: 500.
|
|
196
|
-
comment:
|
|
191
|
+
type: "balance",
|
|
192
|
+
amount: 500.0,
|
|
193
|
+
comment: "Client deposit",
|
|
197
194
|
});
|
|
198
195
|
|
|
199
196
|
await client.accounts.balance(50001, {
|
|
200
|
-
type:
|
|
201
|
-
amount: 1000.
|
|
202
|
-
comment:
|
|
197
|
+
type: "credit",
|
|
198
|
+
amount: 1000.0,
|
|
199
|
+
comment: "Credit line increase",
|
|
203
200
|
});
|
|
204
201
|
|
|
205
202
|
// Subtract balance
|
|
206
203
|
await client.accounts.balance(50001, {
|
|
207
|
-
type:
|
|
208
|
-
amount: -200.
|
|
209
|
-
comment:
|
|
204
|
+
type: "balance",
|
|
205
|
+
amount: -200.0,
|
|
206
|
+
comment: "Withdrawal request",
|
|
210
207
|
});
|
|
211
208
|
```
|
|
212
209
|
|
|
@@ -217,35 +214,35 @@ Manage pending orders with statistics and validation.
|
|
|
217
214
|
```typescript
|
|
218
215
|
// List orders with advanced filters
|
|
219
216
|
const orders = await client.orders.list({
|
|
220
|
-
login:
|
|
221
|
-
symbol:
|
|
222
|
-
order_type:
|
|
223
|
-
status:
|
|
224
|
-
created_from:
|
|
225
|
-
created_to:
|
|
217
|
+
login: "50001",
|
|
218
|
+
symbol: "EURUSD,GBPUSD",
|
|
219
|
+
order_type: "limit",
|
|
220
|
+
status: "new,partial",
|
|
221
|
+
created_from: "2025-01-01T00:00:00Z",
|
|
222
|
+
created_to: "2025-01-31T23:59:59Z",
|
|
226
223
|
price_min: 1.08,
|
|
227
|
-
price_max: 1.
|
|
228
|
-
sort_by:
|
|
229
|
-
sort_order:
|
|
224
|
+
price_max: 1.1,
|
|
225
|
+
sort_by: "created_at",
|
|
226
|
+
sort_order: "desc",
|
|
230
227
|
});
|
|
231
228
|
|
|
232
229
|
// Get statistics grouped by symbol
|
|
233
230
|
const stats = await client.orders.getStats({
|
|
234
|
-
login:
|
|
235
|
-
group_by:
|
|
231
|
+
login: "50001",
|
|
232
|
+
group_by: "symbol",
|
|
236
233
|
});
|
|
237
234
|
|
|
238
235
|
// Get totals by order type
|
|
239
236
|
const totals = await client.orders.getTotals({
|
|
240
|
-
login:
|
|
241
|
-
group_by:
|
|
237
|
+
login: "50001",
|
|
238
|
+
group_by: "order_type",
|
|
242
239
|
});
|
|
243
240
|
|
|
244
241
|
// Update order
|
|
245
242
|
await client.orders.update(12345, {
|
|
246
243
|
login: 50001,
|
|
247
|
-
stop_loss: 1.
|
|
248
|
-
take_profit: 1.
|
|
244
|
+
stop_loss: 1.08,
|
|
245
|
+
take_profit: 1.095,
|
|
249
246
|
});
|
|
250
247
|
|
|
251
248
|
// Delete order
|
|
@@ -255,8 +252,8 @@ await client.orders.delete(12345, { login: 50001 });
|
|
|
255
252
|
const checkResult = await client.orders.check({
|
|
256
253
|
filters: {
|
|
257
254
|
logins: [50001],
|
|
258
|
-
statuses: [
|
|
259
|
-
}
|
|
255
|
+
statuses: ["new"],
|
|
256
|
+
},
|
|
260
257
|
});
|
|
261
258
|
```
|
|
262
259
|
|
|
@@ -267,31 +264,31 @@ Manage open positions with recalculation support.
|
|
|
267
264
|
```typescript
|
|
268
265
|
// List positions with filters
|
|
269
266
|
const positions = await client.positions.list({
|
|
270
|
-
login:
|
|
271
|
-
symbol:
|
|
272
|
-
state:
|
|
267
|
+
login: "50001",
|
|
268
|
+
symbol: "EURUSD",
|
|
269
|
+
state: "open",
|
|
273
270
|
profit_min: 100,
|
|
274
|
-
profit_max: 1000
|
|
271
|
+
profit_max: 1000,
|
|
275
272
|
});
|
|
276
273
|
|
|
277
274
|
// Get statistics grouped by type
|
|
278
275
|
const stats = await client.positions.getStats({
|
|
279
|
-
login:
|
|
280
|
-
state:
|
|
281
|
-
group_by:
|
|
276
|
+
login: "50001",
|
|
277
|
+
state: "open",
|
|
278
|
+
group_by: "type",
|
|
282
279
|
});
|
|
283
280
|
|
|
284
281
|
// Get totals by symbol
|
|
285
282
|
const totals = await client.positions.getTotals({
|
|
286
|
-
login:
|
|
287
|
-
group_by:
|
|
283
|
+
login: "50001",
|
|
284
|
+
group_by: "symbol",
|
|
288
285
|
});
|
|
289
286
|
|
|
290
287
|
// Update position
|
|
291
288
|
await client.positions.update(1, {
|
|
292
289
|
login: 50001,
|
|
293
290
|
stop_loss: 1.0875,
|
|
294
|
-
take_profit: 1.0975
|
|
291
|
+
take_profit: 1.0975,
|
|
295
292
|
});
|
|
296
293
|
|
|
297
294
|
// Delete position
|
|
@@ -301,8 +298,8 @@ await client.positions.delete(1, { login: 50001 });
|
|
|
301
298
|
const checkResult = await client.positions.check({
|
|
302
299
|
filters: {
|
|
303
300
|
logins: [50001],
|
|
304
|
-
states: [
|
|
305
|
-
}
|
|
301
|
+
states: ["open"],
|
|
302
|
+
},
|
|
306
303
|
});
|
|
307
304
|
```
|
|
308
305
|
|
|
@@ -314,22 +311,22 @@ Execute trading operations with margin checking.
|
|
|
314
311
|
// Check margin before trading
|
|
315
312
|
const marginCheck = await client.trades.checkMargin({
|
|
316
313
|
login: 50001,
|
|
317
|
-
symbol:
|
|
318
|
-
action:
|
|
319
|
-
volume: 1.0
|
|
314
|
+
symbol: "EURUSD",
|
|
315
|
+
action: "buy",
|
|
316
|
+
volume: 1.0,
|
|
320
317
|
});
|
|
321
318
|
|
|
322
319
|
if (marginCheck.can_execute) {
|
|
323
320
|
// Open trade
|
|
324
321
|
const trade = await client.trades.open({
|
|
325
322
|
login: 50001,
|
|
326
|
-
symbol:
|
|
327
|
-
action:
|
|
328
|
-
type:
|
|
323
|
+
symbol: "EURUSD",
|
|
324
|
+
action: "buy",
|
|
325
|
+
type: "market",
|
|
329
326
|
volume: 1.0,
|
|
330
|
-
stop_loss: 1.
|
|
331
|
-
take_profit: 1.
|
|
332
|
-
comment:
|
|
327
|
+
stop_loss: 1.085,
|
|
328
|
+
take_profit: 1.095,
|
|
329
|
+
comment: "API Trade",
|
|
333
330
|
});
|
|
334
331
|
|
|
335
332
|
// Modify trade
|
|
@@ -337,17 +334,17 @@ if (marginCheck.can_execute) {
|
|
|
337
334
|
login: 50001,
|
|
338
335
|
position_id: trade.position_id,
|
|
339
336
|
stop_loss: 1.0875,
|
|
340
|
-
take_profit: 1.0975
|
|
337
|
+
take_profit: 1.0975,
|
|
341
338
|
});
|
|
342
339
|
|
|
343
340
|
// Calculate potential profit
|
|
344
341
|
const profitCalc = await client.trades.calculateProfit({
|
|
345
342
|
login: 50001,
|
|
346
|
-
symbol:
|
|
347
|
-
action:
|
|
343
|
+
symbol: "EURUSD",
|
|
344
|
+
action: "buy",
|
|
348
345
|
volume: 1.0,
|
|
349
|
-
open_price: 1.
|
|
350
|
-
close_price: 1.
|
|
346
|
+
open_price: 1.09,
|
|
347
|
+
close_price: 1.095,
|
|
351
348
|
});
|
|
352
349
|
|
|
353
350
|
// Close trade (partial or full)
|
|
@@ -355,20 +352,20 @@ if (marginCheck.can_execute) {
|
|
|
355
352
|
login: 50001,
|
|
356
353
|
position_id: trade.position_id,
|
|
357
354
|
volume: 0.5, // Partial close
|
|
358
|
-
comment:
|
|
355
|
+
comment: "Taking profit",
|
|
359
356
|
});
|
|
360
357
|
}
|
|
361
358
|
|
|
362
359
|
// Force price (for historical data import)
|
|
363
360
|
const historicalTrade = await client.trades.open({
|
|
364
361
|
login: 50001,
|
|
365
|
-
symbol:
|
|
366
|
-
action:
|
|
367
|
-
type:
|
|
362
|
+
symbol: "EURUSD",
|
|
363
|
+
action: "buy",
|
|
364
|
+
type: "market",
|
|
368
365
|
volume: 1.0,
|
|
369
|
-
price: 1.
|
|
366
|
+
price: 1.085,
|
|
370
367
|
force_price: true,
|
|
371
|
-
force_timestamp:
|
|
368
|
+
force_timestamp: "2025-01-15T10:30:00Z",
|
|
372
369
|
});
|
|
373
370
|
```
|
|
374
371
|
|
|
@@ -379,37 +376,37 @@ Query historical market data (minimum 1 hour old).
|
|
|
379
376
|
```typescript
|
|
380
377
|
// Get candles with filters
|
|
381
378
|
const candles = await client.marketData.getCandles({
|
|
382
|
-
symbol:
|
|
383
|
-
timeframe:
|
|
384
|
-
from:
|
|
385
|
-
to:
|
|
379
|
+
symbol: "BTCUSD,ETHUSD",
|
|
380
|
+
timeframe: "1h",
|
|
381
|
+
from: "2025-01-01T00:00:00Z",
|
|
382
|
+
to: "2025-01-02T00:00:00Z",
|
|
386
383
|
min_volume: 1000,
|
|
387
384
|
max_volume: 50000,
|
|
388
|
-
sort:
|
|
389
|
-
order:
|
|
390
|
-
limit: 100
|
|
385
|
+
sort: "volume",
|
|
386
|
+
order: "desc",
|
|
387
|
+
limit: 100,
|
|
391
388
|
});
|
|
392
389
|
|
|
393
390
|
// Get last 100 candles
|
|
394
391
|
const recentCandles = await client.marketData.getCandles({
|
|
395
|
-
symbol:
|
|
396
|
-
timeframe:
|
|
392
|
+
symbol: "BTCUSD",
|
|
393
|
+
timeframe: "1m",
|
|
397
394
|
limit: 100,
|
|
398
|
-
order:
|
|
395
|
+
order: "desc",
|
|
399
396
|
});
|
|
400
397
|
|
|
401
398
|
// Get symbols with filters
|
|
402
399
|
const symbols = await client.marketData.getSymbols({
|
|
403
|
-
group:
|
|
400
|
+
group: "CRYPTO_MAJOR",
|
|
404
401
|
has_data: true,
|
|
405
|
-
search:
|
|
402
|
+
search: "bitcoin",
|
|
406
403
|
});
|
|
407
404
|
|
|
408
405
|
// Get groups hierarchy
|
|
409
406
|
const groups = await client.marketData.getGroups({
|
|
410
407
|
root_only: true,
|
|
411
|
-
sort:
|
|
412
|
-
order:
|
|
408
|
+
sort: "symbol_count",
|
|
409
|
+
order: "desc",
|
|
413
410
|
});
|
|
414
411
|
```
|
|
415
412
|
|
|
@@ -425,7 +422,7 @@ Manage trading groups and their statistics.
|
|
|
425
422
|
// List trading groups
|
|
426
423
|
const groups = await client.tradingGroups.list({
|
|
427
424
|
page: 1,
|
|
428
|
-
per_page: 20
|
|
425
|
+
per_page: 20,
|
|
429
426
|
});
|
|
430
427
|
|
|
431
428
|
// Get statistics
|
|
@@ -439,13 +436,13 @@ Real-time updates for positions and balance with manual channel subscription.
|
|
|
439
436
|
```typescript
|
|
440
437
|
// Enable WebSocket in config
|
|
441
438
|
const client = createClient({
|
|
442
|
-
server:
|
|
443
|
-
login:
|
|
444
|
-
password:
|
|
439
|
+
server: "http://localhost:8080",
|
|
440
|
+
login: "1000",
|
|
441
|
+
password: "DemoMaster",
|
|
445
442
|
websocket: {
|
|
446
443
|
enabled: true,
|
|
447
|
-
autoConnect: false
|
|
448
|
-
}
|
|
444
|
+
autoConnect: false,
|
|
445
|
+
},
|
|
449
446
|
});
|
|
450
447
|
|
|
451
448
|
// Connect to WebSocket
|
|
@@ -453,49 +450,56 @@ await client.stream.connect();
|
|
|
453
450
|
|
|
454
451
|
// Subscribe to channels
|
|
455
452
|
client.stream.subscribe([
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
453
|
+
"positions:new", // New positions opened
|
|
454
|
+
"positions:closed", // Positions closed (total and partial)
|
|
455
|
+
"positions:updated", // Position PnL updates (throttled to 1 per 2s)
|
|
456
|
+
"accounts:balance", // Balance updates
|
|
460
457
|
]);
|
|
461
458
|
|
|
462
459
|
// Listen to position opened events
|
|
463
460
|
client.stream.onPositionOpened((event) => {
|
|
464
461
|
const pos = event.position;
|
|
465
|
-
console.log(
|
|
462
|
+
console.log(
|
|
463
|
+
"Position opened:",
|
|
464
|
+
pos.symbol,
|
|
465
|
+
pos.side === 1 ? "LONG" : "SHORT",
|
|
466
|
+
pos.qty,
|
|
467
|
+
);
|
|
466
468
|
});
|
|
467
469
|
|
|
468
470
|
// Listen to position closed events
|
|
469
471
|
client.stream.onPositionClosed((event) => {
|
|
470
472
|
const pos = event.position;
|
|
471
|
-
console.log(
|
|
473
|
+
console.log("Position closed:", pos.symbol, "PnL:", pos.net_pnl);
|
|
472
474
|
});
|
|
473
475
|
|
|
474
476
|
// Listen to position updated events (throttled)
|
|
475
477
|
client.stream.onPositionUpdated((event) => {
|
|
476
478
|
const pos = event.position;
|
|
477
|
-
console.log(
|
|
479
|
+
console.log("Position update:", pos.position_id, "PnL:", pos.unrealized_pnl);
|
|
478
480
|
});
|
|
479
481
|
|
|
480
482
|
// Listen to balance updates
|
|
481
483
|
client.stream.onBalanceUpdated((event) => {
|
|
482
|
-
console.log(
|
|
484
|
+
console.log("Balance:", event.balance, "Equity:", event.equity);
|
|
483
485
|
});
|
|
484
486
|
|
|
485
487
|
// Unsubscribe from channels
|
|
486
|
-
client.stream.unsubscribe([
|
|
488
|
+
client.stream.unsubscribe(["positions:updated"]);
|
|
487
489
|
|
|
488
490
|
// Disconnect
|
|
489
491
|
client.stream.disconnect();
|
|
490
492
|
```
|
|
491
493
|
|
|
492
494
|
**Available Channels**:
|
|
495
|
+
|
|
493
496
|
- `positions:new` - New position opened
|
|
494
497
|
- `positions:closed` - Position closed (total or partial)
|
|
495
498
|
- `positions:updated` - PnL updates (throttled to max 1 per 2 seconds)
|
|
496
499
|
- `accounts:balance` - Balance changes
|
|
497
500
|
|
|
498
501
|
**Features**:
|
|
502
|
+
|
|
499
503
|
- Manual subscription to specific channels
|
|
500
504
|
- Auto-reconnect with exponential backoff
|
|
501
505
|
- Heartbeat/ping-pong mechanism
|
|
@@ -510,9 +514,9 @@ See [WebSocket API Documentation](docs/WEBSOCKET_API.md) for complete guide.
|
|
|
510
514
|
|
|
511
515
|
```typescript
|
|
512
516
|
const client = createClient({
|
|
513
|
-
server:
|
|
514
|
-
login:
|
|
515
|
-
password:
|
|
517
|
+
server: "http://localhost:8080", // Required: API server URL
|
|
518
|
+
login: "1000", // Required: Admin/API login
|
|
519
|
+
password: "YourPassword", // Required: Admin/API password
|
|
516
520
|
});
|
|
517
521
|
```
|
|
518
522
|
|
|
@@ -520,39 +524,40 @@ const client = createClient({
|
|
|
520
524
|
|
|
521
525
|
```typescript
|
|
522
526
|
const client = createClient({
|
|
523
|
-
server:
|
|
524
|
-
login:
|
|
525
|
-
password:
|
|
526
|
-
|
|
527
|
+
server: "http://localhost:8080",
|
|
528
|
+
login: "1000",
|
|
529
|
+
password: "YourPassword",
|
|
530
|
+
|
|
527
531
|
// WebSocket configuration (optional)
|
|
528
532
|
websocket: {
|
|
529
|
-
enabled: true,
|
|
530
|
-
autoConnect: false,
|
|
531
|
-
autoReconnect: true,
|
|
532
|
-
maxReconnectAttempts: 5,
|
|
533
|
-
heartbeatInterval: 30000
|
|
534
|
-
}
|
|
533
|
+
enabled: true, // Enable WebSocket support
|
|
534
|
+
autoConnect: false, // Auto-connect on client creation
|
|
535
|
+
autoReconnect: true, // Auto-reconnect on disconnect
|
|
536
|
+
maxReconnectAttempts: 5, // Max reconnection attempts
|
|
537
|
+
heartbeatInterval: 30000, // Heartbeat interval in ms
|
|
538
|
+
},
|
|
535
539
|
});
|
|
536
540
|
```
|
|
537
541
|
|
|
538
542
|
### Configuration Options
|
|
539
543
|
|
|
540
|
-
| Option
|
|
541
|
-
|
|
542
|
-
| `server`
|
|
543
|
-
| `login`
|
|
544
|
-
| `password`
|
|
545
|
-
| `websocket.enabled`
|
|
546
|
-
| `websocket.autoConnect`
|
|
547
|
-
| `websocket.autoReconnect`
|
|
548
|
-
| `websocket.maxReconnectAttempts` | number
|
|
549
|
-
| `websocket.heartbeatInterval`
|
|
544
|
+
| Option | Type | Required | Default | Description |
|
|
545
|
+
| -------------------------------- | ------- | -------- | ------- | ---------------------------------- |
|
|
546
|
+
| `server` | string | โ
Yes | - | Pipsend API server URL |
|
|
547
|
+
| `login` | string | โ
Yes | - | Admin/API login for authentication |
|
|
548
|
+
| `password` | string | โ
Yes | - | Admin/API password |
|
|
549
|
+
| `websocket.enabled` | boolean | No | `false` | Enable WebSocket support |
|
|
550
|
+
| `websocket.autoConnect` | boolean | No | `false` | Auto-connect on creation |
|
|
551
|
+
| `websocket.autoReconnect` | boolean | No | `true` | Auto-reconnect on disconnect |
|
|
552
|
+
| `websocket.maxReconnectAttempts` | number | No | `5` | Max reconnection attempts |
|
|
553
|
+
| `websocket.heartbeatInterval` | number | No | `30000` | Heartbeat interval (ms) |
|
|
550
554
|
|
|
551
555
|
## ๐ฆ API Response Structure
|
|
552
556
|
|
|
553
557
|
All API endpoints return a consistent response structure:
|
|
554
558
|
|
|
555
559
|
### Success Response (without pagination)
|
|
560
|
+
|
|
556
561
|
```typescript
|
|
557
562
|
{
|
|
558
563
|
status: "success",
|
|
@@ -562,6 +567,7 @@ All API endpoints return a consistent response structure:
|
|
|
562
567
|
```
|
|
563
568
|
|
|
564
569
|
### Success Response (with pagination)
|
|
570
|
+
|
|
565
571
|
```typescript
|
|
566
572
|
{
|
|
567
573
|
status: "success",
|
|
@@ -579,6 +585,7 @@ All API endpoints return a consistent response structure:
|
|
|
579
585
|
```
|
|
580
586
|
|
|
581
587
|
### Error Response
|
|
588
|
+
|
|
582
589
|
```typescript
|
|
583
590
|
{
|
|
584
591
|
status: "error",
|
|
@@ -596,10 +603,12 @@ All API endpoints return a consistent response structure:
|
|
|
596
603
|
### Common Status Codes
|
|
597
604
|
|
|
598
605
|
**Success:**
|
|
606
|
+
|
|
599
607
|
- `SUCCESS` - Operation successful
|
|
600
608
|
- `CREATED` - Resource created successfully
|
|
601
609
|
|
|
602
610
|
**Errors:**
|
|
611
|
+
|
|
603
612
|
- `VALIDATION_ERROR` (400) - Invalid parameters
|
|
604
613
|
- `BAD_REQUEST` (400) - Invalid request
|
|
605
614
|
- `UNAUTHORIZED` (401) - Authentication required
|
|
@@ -609,6 +618,7 @@ All API endpoints return a consistent response structure:
|
|
|
609
618
|
- `INTERNAL_ERROR` (500) - Server error
|
|
610
619
|
|
|
611
620
|
**Market Data Specific:**
|
|
621
|
+
|
|
612
622
|
- `SYMBOL_NOT_FOUND` (404) - Symbol not found
|
|
613
623
|
- `INVALID_TIMEFRAME` (400) - Invalid timeframe
|
|
614
624
|
- `TIME_RANGE_TOO_LARGE` (400) - Time range exceeds maximum
|
|
@@ -619,21 +629,23 @@ All API endpoints return a consistent response structure:
|
|
|
619
629
|
### Pagination
|
|
620
630
|
|
|
621
631
|
**Option 1: Get all results (no pagination)**
|
|
632
|
+
|
|
622
633
|
```typescript
|
|
623
634
|
// Returns all results in a single array
|
|
624
635
|
const accounts = await client.accounts.list({
|
|
625
|
-
state:
|
|
636
|
+
state: "active",
|
|
626
637
|
});
|
|
627
638
|
// Response: { status, status_code, data: [...] }
|
|
628
639
|
```
|
|
629
640
|
|
|
630
641
|
**Option 2: Paginated results**
|
|
642
|
+
|
|
631
643
|
```typescript
|
|
632
644
|
// Returns paginated results with metadata
|
|
633
645
|
const accounts = await client.accounts.list({
|
|
634
|
-
state:
|
|
646
|
+
state: "active",
|
|
635
647
|
page: 1,
|
|
636
|
-
per_page: 20
|
|
648
|
+
per_page: 20,
|
|
637
649
|
});
|
|
638
650
|
// Response: { status, status_code, data: [...], meta: {...} }
|
|
639
651
|
|
|
@@ -643,26 +655,27 @@ let hasMore = true;
|
|
|
643
655
|
|
|
644
656
|
while (hasMore) {
|
|
645
657
|
const response = await client.accounts.list({
|
|
646
|
-
state:
|
|
658
|
+
state: "active",
|
|
647
659
|
page,
|
|
648
|
-
per_page: 50
|
|
660
|
+
per_page: 50,
|
|
649
661
|
});
|
|
650
|
-
|
|
662
|
+
|
|
651
663
|
// Process response.data
|
|
652
664
|
console.log(`Page ${page}:`, response.data.length);
|
|
653
|
-
|
|
665
|
+
|
|
654
666
|
hasMore = response.meta.has_next;
|
|
655
667
|
page++;
|
|
656
668
|
}
|
|
657
669
|
```
|
|
658
670
|
|
|
659
671
|
**Option 3: Limit results (ignores pagination)**
|
|
672
|
+
|
|
660
673
|
```typescript
|
|
661
674
|
// Get specific number of results
|
|
662
675
|
const candles = await client.marketData.getCandles({
|
|
663
|
-
symbol:
|
|
664
|
-
timeframe:
|
|
665
|
-
limit: 100
|
|
676
|
+
symbol: "BTCUSD",
|
|
677
|
+
timeframe: "1h",
|
|
678
|
+
limit: 100, // Max: 10,000 for candles
|
|
666
679
|
});
|
|
667
680
|
```
|
|
668
681
|
|
|
@@ -673,17 +686,17 @@ Many filters accept comma-separated values:
|
|
|
673
686
|
```typescript
|
|
674
687
|
// Multiple symbols (OR logic)
|
|
675
688
|
const positions = await client.positions.list({
|
|
676
|
-
symbol:
|
|
689
|
+
symbol: "EURUSD,GBPUSD,USDJPY", // Positions in ANY of these symbols
|
|
677
690
|
});
|
|
678
691
|
|
|
679
692
|
// Multiple countries
|
|
680
693
|
const accounts = await client.accounts.list({
|
|
681
|
-
country:
|
|
694
|
+
country: "Mexico,United States,Canada",
|
|
682
695
|
});
|
|
683
696
|
|
|
684
697
|
// Multiple states
|
|
685
698
|
const orders = await client.orders.list({
|
|
686
|
-
status:
|
|
699
|
+
status: "new,partial", // Orders with status new OR partial
|
|
687
700
|
});
|
|
688
701
|
```
|
|
689
702
|
|
|
@@ -694,16 +707,16 @@ All date parameters must be in **ISO 8601 / RFC3339 format** (UTC):
|
|
|
694
707
|
```typescript
|
|
695
708
|
// Correct format
|
|
696
709
|
const positions = await client.positions.list({
|
|
697
|
-
opened_from:
|
|
698
|
-
opened_to:
|
|
710
|
+
opened_from: "2025-01-01T00:00:00Z",
|
|
711
|
+
opened_to: "2025-01-31T23:59:59Z",
|
|
699
712
|
});
|
|
700
713
|
|
|
701
714
|
// Also valid
|
|
702
715
|
const candles = await client.marketData.getCandles({
|
|
703
|
-
symbol:
|
|
704
|
-
timeframe:
|
|
705
|
-
from:
|
|
706
|
-
to:
|
|
716
|
+
symbol: "BTCUSD",
|
|
717
|
+
timeframe: "1h",
|
|
718
|
+
from: "2025-01-15T10:30:00Z",
|
|
719
|
+
to: "2025-01-15T18:30:00Z",
|
|
707
720
|
});
|
|
708
721
|
```
|
|
709
722
|
|
|
@@ -717,21 +730,21 @@ Use `min_*` and `max_*` for numeric ranges:
|
|
|
717
730
|
// Balance range
|
|
718
731
|
const accounts = await client.accounts.list({
|
|
719
732
|
min_balance: 1000,
|
|
720
|
-
max_balance: 50000
|
|
733
|
+
max_balance: 50000,
|
|
721
734
|
});
|
|
722
735
|
|
|
723
736
|
// Profit range
|
|
724
737
|
const positions = await client.positions.list({
|
|
725
738
|
profit_min: 100,
|
|
726
|
-
profit_max: 1000
|
|
739
|
+
profit_max: 1000,
|
|
727
740
|
});
|
|
728
741
|
|
|
729
742
|
// Volume range
|
|
730
743
|
const candles = await client.marketData.getCandles({
|
|
731
|
-
symbol:
|
|
732
|
-
timeframe:
|
|
744
|
+
symbol: "BTCUSD",
|
|
745
|
+
timeframe: "1h",
|
|
733
746
|
min_volume: 1000,
|
|
734
|
-
max_volume: 50000
|
|
747
|
+
max_volume: 50000,
|
|
735
748
|
});
|
|
736
749
|
```
|
|
737
750
|
|
|
@@ -741,16 +754,16 @@ Most list endpoints support sorting:
|
|
|
741
754
|
|
|
742
755
|
```typescript
|
|
743
756
|
const orders = await client.orders.list({
|
|
744
|
-
login:
|
|
745
|
-
sort_by:
|
|
746
|
-
sort_order:
|
|
757
|
+
login: "50001",
|
|
758
|
+
sort_by: "created_at", // Field to sort by
|
|
759
|
+
sort_order: "desc", // 'asc' or 'desc'
|
|
747
760
|
});
|
|
748
761
|
|
|
749
762
|
const candles = await client.marketData.getCandles({
|
|
750
|
-
symbol:
|
|
751
|
-
timeframe:
|
|
752
|
-
sort:
|
|
753
|
-
order:
|
|
763
|
+
symbol: "BTCUSD",
|
|
764
|
+
timeframe: "1h",
|
|
765
|
+
sort: "volume", // Some endpoints use 'sort'
|
|
766
|
+
order: "desc", // instead of 'sort_by'/'sort_order'
|
|
754
767
|
});
|
|
755
768
|
```
|
|
756
769
|
|
|
@@ -761,28 +774,27 @@ All errors thrown by the SDK are instances of `PipsendError` with detailed infor
|
|
|
761
774
|
### Basic Error Handling
|
|
762
775
|
|
|
763
776
|
```typescript
|
|
764
|
-
import { PipsendError } from
|
|
777
|
+
import { PipsendError } from "@pipsend/sdk";
|
|
765
778
|
|
|
766
779
|
try {
|
|
767
780
|
const trade = await client.trades.open({
|
|
768
781
|
login: 50001,
|
|
769
|
-
symbol:
|
|
770
|
-
action:
|
|
771
|
-
type:
|
|
772
|
-
volume: 1.0
|
|
782
|
+
symbol: "EURUSD",
|
|
783
|
+
action: "buy",
|
|
784
|
+
type: "market",
|
|
785
|
+
volume: 1.0,
|
|
773
786
|
});
|
|
774
|
-
|
|
775
|
-
console.log(
|
|
776
|
-
|
|
787
|
+
|
|
788
|
+
console.log("Trade opened:", trade.position_id);
|
|
777
789
|
} catch (error) {
|
|
778
790
|
if (error instanceof PipsendError) {
|
|
779
|
-
console.error(
|
|
780
|
-
console.error(
|
|
781
|
-
console.error(
|
|
782
|
-
|
|
791
|
+
console.error("Error code:", error.code);
|
|
792
|
+
console.error("Status code:", error.statusCode);
|
|
793
|
+
console.error("Message:", error.message);
|
|
794
|
+
|
|
783
795
|
// Check if it's a validation error
|
|
784
796
|
if (error.isValidationError()) {
|
|
785
|
-
console.error(
|
|
797
|
+
console.error("Validation errors:", error.errors);
|
|
786
798
|
// Get formatted message with all details
|
|
787
799
|
console.error(error.getDetailedMessage());
|
|
788
800
|
}
|
|
@@ -797,26 +809,26 @@ When the API returns validation errors, the SDK provides detailed field-level in
|
|
|
797
809
|
```typescript
|
|
798
810
|
try {
|
|
799
811
|
const account = await client.accounts.create({
|
|
800
|
-
trading_group:
|
|
801
|
-
country:
|
|
802
|
-
master_password:
|
|
803
|
-
investor_password:
|
|
804
|
-
email:
|
|
805
|
-
first_name:
|
|
806
|
-
last_name:
|
|
812
|
+
trading_group: "InvalidGroup",
|
|
813
|
+
country: "XYZ",
|
|
814
|
+
master_password: "short",
|
|
815
|
+
investor_password: "short",
|
|
816
|
+
email: "invalid-email",
|
|
817
|
+
first_name: "John",
|
|
818
|
+
last_name: "Doe",
|
|
807
819
|
});
|
|
808
820
|
} catch (error) {
|
|
809
821
|
if (error instanceof PipsendError && error.isValidationError()) {
|
|
810
|
-
console.log(
|
|
811
|
-
|
|
822
|
+
console.log("Validation failed:");
|
|
823
|
+
|
|
812
824
|
// Access individual validation errors
|
|
813
|
-
error.errors?.forEach(err => {
|
|
825
|
+
error.errors?.forEach((err) => {
|
|
814
826
|
console.log(` - ${err.field}: ${err.message}`);
|
|
815
827
|
});
|
|
816
|
-
|
|
828
|
+
|
|
817
829
|
// Or get formatted message
|
|
818
830
|
console.log(error.getDetailedMessage());
|
|
819
|
-
|
|
831
|
+
|
|
820
832
|
// Output:
|
|
821
833
|
// The provided data is not valid.
|
|
822
834
|
// - trading_group: Trading group 'InvalidGroup' not found
|
|
@@ -831,20 +843,20 @@ try {
|
|
|
831
843
|
|
|
832
844
|
```typescript
|
|
833
845
|
interface PipsendError {
|
|
834
|
-
message: string;
|
|
835
|
-
code: string;
|
|
836
|
-
statusCode: number;
|
|
837
|
-
errors?: ValidationError[];
|
|
838
|
-
response?: any;
|
|
839
|
-
|
|
846
|
+
message: string; // Error message
|
|
847
|
+
code: string; // Error code (e.g., 'VALIDATION_ERROR', 'NOT_FOUND')
|
|
848
|
+
statusCode: number; // HTTP status code (e.g., 422, 404, 500)
|
|
849
|
+
errors?: ValidationError[]; // Validation errors (for 422 responses)
|
|
850
|
+
response?: any; // Full error response from server
|
|
851
|
+
|
|
840
852
|
// Helper methods
|
|
841
|
-
isValidationError(): boolean;
|
|
842
|
-
getDetailedMessage(): string;
|
|
853
|
+
isValidationError(): boolean; // Check if it's a validation error
|
|
854
|
+
getDetailedMessage(): string; // Get formatted message with details
|
|
843
855
|
}
|
|
844
856
|
|
|
845
857
|
interface ValidationError {
|
|
846
|
-
field: string;
|
|
847
|
-
message: string;
|
|
858
|
+
field: string; // Field name that failed validation
|
|
859
|
+
message: string; // Validation error message
|
|
848
860
|
}
|
|
849
861
|
```
|
|
850
862
|
|
|
@@ -912,8 +924,8 @@ import type {
|
|
|
912
924
|
Candle,
|
|
913
925
|
Symbol,
|
|
914
926
|
OpenTradeRequest,
|
|
915
|
-
OpenTradeResponse
|
|
916
|
-
} from
|
|
927
|
+
OpenTradeResponse,
|
|
928
|
+
} from "@pipsend/sdk";
|
|
917
929
|
```
|
|
918
930
|
|
|
919
931
|
## ๐งช Testing
|