@pipsend/sdk 0.3.0 โ 0.3.2
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 +246 -228
- package/dist/index.d.mts +28 -26
- package/dist/index.d.ts +28 -26
- 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
|
|
@@ -504,15 +508,21 @@ client.stream.disconnect();
|
|
|
504
508
|
|
|
505
509
|
See [WebSocket API Documentation](docs/WEBSOCKET_API.md) for complete guide.
|
|
506
510
|
|
|
507
|
-
##
|
|
511
|
+
## ๏ฟฝ Documentation
|
|
512
|
+
|
|
513
|
+
- **[Positions & Trading Guide](docs/POSITIONS_TRADING.md)** - Complete guide for opening, closing, and modifying positions (SL/TP)
|
|
514
|
+
- **[WebSocket API](docs/WEBSOCKET_API.md)** - Real-time updates and streaming data
|
|
515
|
+
- **[Authentication](AUTHENTICATION.md)** - Authentication system and token management
|
|
516
|
+
|
|
517
|
+
## ๏ฟฝ๐ง Configuration
|
|
508
518
|
|
|
509
519
|
### Basic Configuration
|
|
510
520
|
|
|
511
521
|
```typescript
|
|
512
522
|
const client = createClient({
|
|
513
|
-
server:
|
|
514
|
-
login:
|
|
515
|
-
password:
|
|
523
|
+
server: "http://localhost:8080", // Required: API server URL
|
|
524
|
+
login: "1000", // Required: Admin/API login
|
|
525
|
+
password: "YourPassword", // Required: Admin/API password
|
|
516
526
|
});
|
|
517
527
|
```
|
|
518
528
|
|
|
@@ -520,39 +530,40 @@ const client = createClient({
|
|
|
520
530
|
|
|
521
531
|
```typescript
|
|
522
532
|
const client = createClient({
|
|
523
|
-
server:
|
|
524
|
-
login:
|
|
525
|
-
password:
|
|
526
|
-
|
|
533
|
+
server: "http://localhost:8080",
|
|
534
|
+
login: "1000",
|
|
535
|
+
password: "YourPassword",
|
|
536
|
+
|
|
527
537
|
// WebSocket configuration (optional)
|
|
528
538
|
websocket: {
|
|
529
|
-
enabled: true,
|
|
530
|
-
autoConnect: false,
|
|
531
|
-
autoReconnect: true,
|
|
532
|
-
maxReconnectAttempts: 5,
|
|
533
|
-
heartbeatInterval: 30000
|
|
534
|
-
}
|
|
539
|
+
enabled: true, // Enable WebSocket support
|
|
540
|
+
autoConnect: false, // Auto-connect on client creation
|
|
541
|
+
autoReconnect: true, // Auto-reconnect on disconnect
|
|
542
|
+
maxReconnectAttempts: 5, // Max reconnection attempts
|
|
543
|
+
heartbeatInterval: 30000, // Heartbeat interval in ms
|
|
544
|
+
},
|
|
535
545
|
});
|
|
536
546
|
```
|
|
537
547
|
|
|
538
548
|
### Configuration Options
|
|
539
549
|
|
|
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`
|
|
550
|
+
| Option | Type | Required | Default | Description |
|
|
551
|
+
| -------------------------------- | ------- | -------- | ------- | ---------------------------------- |
|
|
552
|
+
| `server` | string | โ
Yes | - | Pipsend API server URL |
|
|
553
|
+
| `login` | string | โ
Yes | - | Admin/API login for authentication |
|
|
554
|
+
| `password` | string | โ
Yes | - | Admin/API password |
|
|
555
|
+
| `websocket.enabled` | boolean | No | `false` | Enable WebSocket support |
|
|
556
|
+
| `websocket.autoConnect` | boolean | No | `false` | Auto-connect on creation |
|
|
557
|
+
| `websocket.autoReconnect` | boolean | No | `true` | Auto-reconnect on disconnect |
|
|
558
|
+
| `websocket.maxReconnectAttempts` | number | No | `5` | Max reconnection attempts |
|
|
559
|
+
| `websocket.heartbeatInterval` | number | No | `30000` | Heartbeat interval (ms) |
|
|
550
560
|
|
|
551
561
|
## ๐ฆ API Response Structure
|
|
552
562
|
|
|
553
563
|
All API endpoints return a consistent response structure:
|
|
554
564
|
|
|
555
565
|
### Success Response (without pagination)
|
|
566
|
+
|
|
556
567
|
```typescript
|
|
557
568
|
{
|
|
558
569
|
status: "success",
|
|
@@ -562,6 +573,7 @@ All API endpoints return a consistent response structure:
|
|
|
562
573
|
```
|
|
563
574
|
|
|
564
575
|
### Success Response (with pagination)
|
|
576
|
+
|
|
565
577
|
```typescript
|
|
566
578
|
{
|
|
567
579
|
status: "success",
|
|
@@ -579,6 +591,7 @@ All API endpoints return a consistent response structure:
|
|
|
579
591
|
```
|
|
580
592
|
|
|
581
593
|
### Error Response
|
|
594
|
+
|
|
582
595
|
```typescript
|
|
583
596
|
{
|
|
584
597
|
status: "error",
|
|
@@ -596,10 +609,12 @@ All API endpoints return a consistent response structure:
|
|
|
596
609
|
### Common Status Codes
|
|
597
610
|
|
|
598
611
|
**Success:**
|
|
612
|
+
|
|
599
613
|
- `SUCCESS` - Operation successful
|
|
600
614
|
- `CREATED` - Resource created successfully
|
|
601
615
|
|
|
602
616
|
**Errors:**
|
|
617
|
+
|
|
603
618
|
- `VALIDATION_ERROR` (400) - Invalid parameters
|
|
604
619
|
- `BAD_REQUEST` (400) - Invalid request
|
|
605
620
|
- `UNAUTHORIZED` (401) - Authentication required
|
|
@@ -609,6 +624,7 @@ All API endpoints return a consistent response structure:
|
|
|
609
624
|
- `INTERNAL_ERROR` (500) - Server error
|
|
610
625
|
|
|
611
626
|
**Market Data Specific:**
|
|
627
|
+
|
|
612
628
|
- `SYMBOL_NOT_FOUND` (404) - Symbol not found
|
|
613
629
|
- `INVALID_TIMEFRAME` (400) - Invalid timeframe
|
|
614
630
|
- `TIME_RANGE_TOO_LARGE` (400) - Time range exceeds maximum
|
|
@@ -619,21 +635,23 @@ All API endpoints return a consistent response structure:
|
|
|
619
635
|
### Pagination
|
|
620
636
|
|
|
621
637
|
**Option 1: Get all results (no pagination)**
|
|
638
|
+
|
|
622
639
|
```typescript
|
|
623
640
|
// Returns all results in a single array
|
|
624
641
|
const accounts = await client.accounts.list({
|
|
625
|
-
state:
|
|
642
|
+
state: "active",
|
|
626
643
|
});
|
|
627
644
|
// Response: { status, status_code, data: [...] }
|
|
628
645
|
```
|
|
629
646
|
|
|
630
647
|
**Option 2: Paginated results**
|
|
648
|
+
|
|
631
649
|
```typescript
|
|
632
650
|
// Returns paginated results with metadata
|
|
633
651
|
const accounts = await client.accounts.list({
|
|
634
|
-
state:
|
|
652
|
+
state: "active",
|
|
635
653
|
page: 1,
|
|
636
|
-
per_page: 20
|
|
654
|
+
per_page: 20,
|
|
637
655
|
});
|
|
638
656
|
// Response: { status, status_code, data: [...], meta: {...} }
|
|
639
657
|
|
|
@@ -643,26 +661,27 @@ let hasMore = true;
|
|
|
643
661
|
|
|
644
662
|
while (hasMore) {
|
|
645
663
|
const response = await client.accounts.list({
|
|
646
|
-
state:
|
|
664
|
+
state: "active",
|
|
647
665
|
page,
|
|
648
|
-
per_page: 50
|
|
666
|
+
per_page: 50,
|
|
649
667
|
});
|
|
650
|
-
|
|
668
|
+
|
|
651
669
|
// Process response.data
|
|
652
670
|
console.log(`Page ${page}:`, response.data.length);
|
|
653
|
-
|
|
671
|
+
|
|
654
672
|
hasMore = response.meta.has_next;
|
|
655
673
|
page++;
|
|
656
674
|
}
|
|
657
675
|
```
|
|
658
676
|
|
|
659
677
|
**Option 3: Limit results (ignores pagination)**
|
|
678
|
+
|
|
660
679
|
```typescript
|
|
661
680
|
// Get specific number of results
|
|
662
681
|
const candles = await client.marketData.getCandles({
|
|
663
|
-
symbol:
|
|
664
|
-
timeframe:
|
|
665
|
-
limit: 100
|
|
682
|
+
symbol: "BTCUSD",
|
|
683
|
+
timeframe: "1h",
|
|
684
|
+
limit: 100, // Max: 10,000 for candles
|
|
666
685
|
});
|
|
667
686
|
```
|
|
668
687
|
|
|
@@ -673,17 +692,17 @@ Many filters accept comma-separated values:
|
|
|
673
692
|
```typescript
|
|
674
693
|
// Multiple symbols (OR logic)
|
|
675
694
|
const positions = await client.positions.list({
|
|
676
|
-
symbol:
|
|
695
|
+
symbol: "EURUSD,GBPUSD,USDJPY", // Positions in ANY of these symbols
|
|
677
696
|
});
|
|
678
697
|
|
|
679
698
|
// Multiple countries
|
|
680
699
|
const accounts = await client.accounts.list({
|
|
681
|
-
country:
|
|
700
|
+
country: "Mexico,United States,Canada",
|
|
682
701
|
});
|
|
683
702
|
|
|
684
703
|
// Multiple states
|
|
685
704
|
const orders = await client.orders.list({
|
|
686
|
-
status:
|
|
705
|
+
status: "new,partial", // Orders with status new OR partial
|
|
687
706
|
});
|
|
688
707
|
```
|
|
689
708
|
|
|
@@ -694,16 +713,16 @@ All date parameters must be in **ISO 8601 / RFC3339 format** (UTC):
|
|
|
694
713
|
```typescript
|
|
695
714
|
// Correct format
|
|
696
715
|
const positions = await client.positions.list({
|
|
697
|
-
opened_from:
|
|
698
|
-
opened_to:
|
|
716
|
+
opened_from: "2025-01-01T00:00:00Z",
|
|
717
|
+
opened_to: "2025-01-31T23:59:59Z",
|
|
699
718
|
});
|
|
700
719
|
|
|
701
720
|
// Also valid
|
|
702
721
|
const candles = await client.marketData.getCandles({
|
|
703
|
-
symbol:
|
|
704
|
-
timeframe:
|
|
705
|
-
from:
|
|
706
|
-
to:
|
|
722
|
+
symbol: "BTCUSD",
|
|
723
|
+
timeframe: "1h",
|
|
724
|
+
from: "2025-01-15T10:30:00Z",
|
|
725
|
+
to: "2025-01-15T18:30:00Z",
|
|
707
726
|
});
|
|
708
727
|
```
|
|
709
728
|
|
|
@@ -717,21 +736,21 @@ Use `min_*` and `max_*` for numeric ranges:
|
|
|
717
736
|
// Balance range
|
|
718
737
|
const accounts = await client.accounts.list({
|
|
719
738
|
min_balance: 1000,
|
|
720
|
-
max_balance: 50000
|
|
739
|
+
max_balance: 50000,
|
|
721
740
|
});
|
|
722
741
|
|
|
723
742
|
// Profit range
|
|
724
743
|
const positions = await client.positions.list({
|
|
725
744
|
profit_min: 100,
|
|
726
|
-
profit_max: 1000
|
|
745
|
+
profit_max: 1000,
|
|
727
746
|
});
|
|
728
747
|
|
|
729
748
|
// Volume range
|
|
730
749
|
const candles = await client.marketData.getCandles({
|
|
731
|
-
symbol:
|
|
732
|
-
timeframe:
|
|
750
|
+
symbol: "BTCUSD",
|
|
751
|
+
timeframe: "1h",
|
|
733
752
|
min_volume: 1000,
|
|
734
|
-
max_volume: 50000
|
|
753
|
+
max_volume: 50000,
|
|
735
754
|
});
|
|
736
755
|
```
|
|
737
756
|
|
|
@@ -741,16 +760,16 @@ Most list endpoints support sorting:
|
|
|
741
760
|
|
|
742
761
|
```typescript
|
|
743
762
|
const orders = await client.orders.list({
|
|
744
|
-
login:
|
|
745
|
-
sort_by:
|
|
746
|
-
sort_order:
|
|
763
|
+
login: "50001",
|
|
764
|
+
sort_by: "created_at", // Field to sort by
|
|
765
|
+
sort_order: "desc", // 'asc' or 'desc'
|
|
747
766
|
});
|
|
748
767
|
|
|
749
768
|
const candles = await client.marketData.getCandles({
|
|
750
|
-
symbol:
|
|
751
|
-
timeframe:
|
|
752
|
-
sort:
|
|
753
|
-
order:
|
|
769
|
+
symbol: "BTCUSD",
|
|
770
|
+
timeframe: "1h",
|
|
771
|
+
sort: "volume", // Some endpoints use 'sort'
|
|
772
|
+
order: "desc", // instead of 'sort_by'/'sort_order'
|
|
754
773
|
});
|
|
755
774
|
```
|
|
756
775
|
|
|
@@ -761,28 +780,27 @@ All errors thrown by the SDK are instances of `PipsendError` with detailed infor
|
|
|
761
780
|
### Basic Error Handling
|
|
762
781
|
|
|
763
782
|
```typescript
|
|
764
|
-
import { PipsendError } from
|
|
783
|
+
import { PipsendError } from "@pipsend/sdk";
|
|
765
784
|
|
|
766
785
|
try {
|
|
767
786
|
const trade = await client.trades.open({
|
|
768
787
|
login: 50001,
|
|
769
|
-
symbol:
|
|
770
|
-
action:
|
|
771
|
-
type:
|
|
772
|
-
volume: 1.0
|
|
788
|
+
symbol: "EURUSD",
|
|
789
|
+
action: "buy",
|
|
790
|
+
type: "market",
|
|
791
|
+
volume: 1.0,
|
|
773
792
|
});
|
|
774
|
-
|
|
775
|
-
console.log(
|
|
776
|
-
|
|
793
|
+
|
|
794
|
+
console.log("Trade opened:", trade.position_id);
|
|
777
795
|
} catch (error) {
|
|
778
796
|
if (error instanceof PipsendError) {
|
|
779
|
-
console.error(
|
|
780
|
-
console.error(
|
|
781
|
-
console.error(
|
|
782
|
-
|
|
797
|
+
console.error("Error code:", error.code);
|
|
798
|
+
console.error("Status code:", error.statusCode);
|
|
799
|
+
console.error("Message:", error.message);
|
|
800
|
+
|
|
783
801
|
// Check if it's a validation error
|
|
784
802
|
if (error.isValidationError()) {
|
|
785
|
-
console.error(
|
|
803
|
+
console.error("Validation errors:", error.errors);
|
|
786
804
|
// Get formatted message with all details
|
|
787
805
|
console.error(error.getDetailedMessage());
|
|
788
806
|
}
|
|
@@ -797,26 +815,26 @@ When the API returns validation errors, the SDK provides detailed field-level in
|
|
|
797
815
|
```typescript
|
|
798
816
|
try {
|
|
799
817
|
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:
|
|
818
|
+
trading_group: "InvalidGroup",
|
|
819
|
+
country: "XYZ",
|
|
820
|
+
master_password: "short",
|
|
821
|
+
investor_password: "short",
|
|
822
|
+
email: "invalid-email",
|
|
823
|
+
first_name: "John",
|
|
824
|
+
last_name: "Doe",
|
|
807
825
|
});
|
|
808
826
|
} catch (error) {
|
|
809
827
|
if (error instanceof PipsendError && error.isValidationError()) {
|
|
810
|
-
console.log(
|
|
811
|
-
|
|
828
|
+
console.log("Validation failed:");
|
|
829
|
+
|
|
812
830
|
// Access individual validation errors
|
|
813
|
-
error.errors?.forEach(err => {
|
|
831
|
+
error.errors?.forEach((err) => {
|
|
814
832
|
console.log(` - ${err.field}: ${err.message}`);
|
|
815
833
|
});
|
|
816
|
-
|
|
834
|
+
|
|
817
835
|
// Or get formatted message
|
|
818
836
|
console.log(error.getDetailedMessage());
|
|
819
|
-
|
|
837
|
+
|
|
820
838
|
// Output:
|
|
821
839
|
// The provided data is not valid.
|
|
822
840
|
// - trading_group: Trading group 'InvalidGroup' not found
|
|
@@ -831,20 +849,20 @@ try {
|
|
|
831
849
|
|
|
832
850
|
```typescript
|
|
833
851
|
interface PipsendError {
|
|
834
|
-
message: string;
|
|
835
|
-
code: string;
|
|
836
|
-
statusCode: number;
|
|
837
|
-
errors?: ValidationError[];
|
|
838
|
-
response?: any;
|
|
839
|
-
|
|
852
|
+
message: string; // Error message
|
|
853
|
+
code: string; // Error code (e.g., 'VALIDATION_ERROR', 'NOT_FOUND')
|
|
854
|
+
statusCode: number; // HTTP status code (e.g., 422, 404, 500)
|
|
855
|
+
errors?: ValidationError[]; // Validation errors (for 422 responses)
|
|
856
|
+
response?: any; // Full error response from server
|
|
857
|
+
|
|
840
858
|
// Helper methods
|
|
841
|
-
isValidationError(): boolean;
|
|
842
|
-
getDetailedMessage(): string;
|
|
859
|
+
isValidationError(): boolean; // Check if it's a validation error
|
|
860
|
+
getDetailedMessage(): string; // Get formatted message with details
|
|
843
861
|
}
|
|
844
862
|
|
|
845
863
|
interface ValidationError {
|
|
846
|
-
field: string;
|
|
847
|
-
message: string;
|
|
864
|
+
field: string; // Field name that failed validation
|
|
865
|
+
message: string; // Validation error message
|
|
848
866
|
}
|
|
849
867
|
```
|
|
850
868
|
|
|
@@ -912,8 +930,8 @@ import type {
|
|
|
912
930
|
Candle,
|
|
913
931
|
Symbol,
|
|
914
932
|
OpenTradeRequest,
|
|
915
|
-
OpenTradeResponse
|
|
916
|
-
} from
|
|
933
|
+
OpenTradeResponse,
|
|
934
|
+
} from "@pipsend/sdk";
|
|
917
935
|
```
|
|
918
936
|
|
|
919
937
|
## ๐งช Testing
|