@pipsend/sdk 0.1.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/LICENSE +21 -0
- package/README.md +774 -0
- package/dist/index.d.mts +1194 -0
- package/dist/index.d.ts +1194 -0
- package/dist/index.js +1030 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1005 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,774 @@
|
|
|
1
|
+
# @pipsend/sdk
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@pipsend/sdk)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
Official Pipsend SDK for Node.js and TypeScript. Complete MT5 trading platform integration with WebSocket support.
|
|
7
|
+
|
|
8
|
+
## ๐ Features
|
|
9
|
+
|
|
10
|
+
- โ
**6 Complete API Modules**: Accounts, Orders, Positions, Trades, Market Data, Trading Groups
|
|
11
|
+
- โ
**TypeScript Native** with 100+ complete types
|
|
12
|
+
- โ
**WebSocket Support** with auto-reconnect and heartbeat
|
|
13
|
+
- โ
**Advanced Filtering** (dates, ranges, multi-value, search)
|
|
14
|
+
- โ
**Dynamic Statistics** grouped by any field
|
|
15
|
+
- โ
**Pagination Support** for all list endpoints
|
|
16
|
+
- โ
**Dual Package** (ESM + CommonJS)
|
|
17
|
+
- โ
**56 Unit Tests** passing
|
|
18
|
+
- โ
**Compatible with Node.js โฅ16**
|
|
19
|
+
|
|
20
|
+
## ๐ฆ Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install @pipsend/sdk
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
yarn add @pipsend/sdk
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pnpm add @pipsend/sdk
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## ๐ง Quick Start
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { createClient } from '@pipsend/sdk';
|
|
38
|
+
|
|
39
|
+
const client = createClient({
|
|
40
|
+
server: 'http://localhost:8080'
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const login = 50001;
|
|
44
|
+
|
|
45
|
+
// List accounts with filters
|
|
46
|
+
const accounts = await client.accounts.list({
|
|
47
|
+
state: 'active',
|
|
48
|
+
country: 'Mexico',
|
|
49
|
+
min_balance: 1000
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Open a trade
|
|
53
|
+
const trade = await client.trades.open({
|
|
54
|
+
login,
|
|
55
|
+
symbol: 'EURUSD',
|
|
56
|
+
action: 'buy',
|
|
57
|
+
type: 'market',
|
|
58
|
+
volume: 1.0,
|
|
59
|
+
stop_loss: 1.0850,
|
|
60
|
+
take_profit: 1.0950
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Get market data
|
|
64
|
+
const candles = await client.marketData.getCandles({
|
|
65
|
+
symbol: 'BTCUSD',
|
|
66
|
+
timeframe: '1h',
|
|
67
|
+
limit: 100
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// WebSocket real-time updates
|
|
71
|
+
client.stream.onPriceUpdate((price) => {
|
|
72
|
+
console.log('Price update:', price);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
await client.stream.connect();
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## ๐ API Modules
|
|
79
|
+
|
|
80
|
+
### 1. Accounts API
|
|
81
|
+
|
|
82
|
+
Manage MT5 accounts with advanced filtering and statistics.
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
// List accounts with filters
|
|
86
|
+
const accounts = await client.accounts.list({
|
|
87
|
+
state: 'active',
|
|
88
|
+
country: 'Mexico,United States',
|
|
89
|
+
trading_group: 'Premium',
|
|
90
|
+
min_balance: 1000,
|
|
91
|
+
max_balance: 50000,
|
|
92
|
+
page: 1,
|
|
93
|
+
per_page: 20
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Get statistics with filters
|
|
97
|
+
const stats = await client.accounts.getStatistics({
|
|
98
|
+
country: 'Mexico',
|
|
99
|
+
state: 'active'
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Get all account logins
|
|
103
|
+
const logins = await client.accounts.getLogins();
|
|
104
|
+
|
|
105
|
+
// Change passwords
|
|
106
|
+
await client.accounts.changeMasterPassword(50001, {
|
|
107
|
+
new_password: 'NewPass123!'
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
await client.accounts.changeInvestorPassword(50001, {
|
|
111
|
+
new_password: 'InvestorPass123!'
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Archive/Unarchive
|
|
115
|
+
await client.accounts.archive(50001);
|
|
116
|
+
await client.accounts.unarchive(50001);
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### 2. Orders API
|
|
120
|
+
|
|
121
|
+
Manage pending orders with statistics and validation.
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
// List orders with advanced filters
|
|
125
|
+
const orders = await client.orders.list({
|
|
126
|
+
login: '50001',
|
|
127
|
+
symbol: 'EURUSD,GBPUSD',
|
|
128
|
+
order_type: 'limit',
|
|
129
|
+
status: 'new,partial',
|
|
130
|
+
created_from: '2025-01-01T00:00:00Z',
|
|
131
|
+
created_to: '2025-01-31T23:59:59Z',
|
|
132
|
+
price_min: 1.08,
|
|
133
|
+
price_max: 1.10,
|
|
134
|
+
sort_by: 'created_at',
|
|
135
|
+
sort_order: 'desc'
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// Get statistics grouped by symbol
|
|
139
|
+
const stats = await client.orders.getStats({
|
|
140
|
+
login: '50001',
|
|
141
|
+
group_by: 'symbol'
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// Get totals by order type
|
|
145
|
+
const totals = await client.orders.getTotals({
|
|
146
|
+
login: '50001',
|
|
147
|
+
group_by: 'order_type'
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// Update order
|
|
151
|
+
await client.orders.update(12345, {
|
|
152
|
+
login: 50001,
|
|
153
|
+
stop_loss: 1.0800,
|
|
154
|
+
take_profit: 1.0950
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// Delete order
|
|
158
|
+
await client.orders.delete(12345, { login: 50001 });
|
|
159
|
+
|
|
160
|
+
// Validate orders
|
|
161
|
+
const checkResult = await client.orders.check({
|
|
162
|
+
filters: {
|
|
163
|
+
logins: [50001],
|
|
164
|
+
statuses: ['new']
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### 3. Positions API
|
|
170
|
+
|
|
171
|
+
Manage open positions with recalculation support.
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
// List positions with filters
|
|
175
|
+
const positions = await client.positions.list({
|
|
176
|
+
login: '50001',
|
|
177
|
+
symbol: 'EURUSD',
|
|
178
|
+
state: 'open',
|
|
179
|
+
profit_min: 100,
|
|
180
|
+
profit_max: 1000
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// Get statistics grouped by type
|
|
184
|
+
const stats = await client.positions.getStats({
|
|
185
|
+
login: '50001',
|
|
186
|
+
state: 'open',
|
|
187
|
+
group_by: 'type'
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Get totals by symbol
|
|
191
|
+
const totals = await client.positions.getTotals({
|
|
192
|
+
login: '50001',
|
|
193
|
+
group_by: 'symbol'
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// Update position
|
|
197
|
+
await client.positions.update(1, {
|
|
198
|
+
login: 50001,
|
|
199
|
+
stop_loss: 1.0875,
|
|
200
|
+
take_profit: 1.0975
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// Delete position
|
|
204
|
+
await client.positions.delete(1, { login: 50001 });
|
|
205
|
+
|
|
206
|
+
// Recalculate positions
|
|
207
|
+
const checkResult = await client.positions.check({
|
|
208
|
+
filters: {
|
|
209
|
+
logins: [50001],
|
|
210
|
+
states: ['open']
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### 4. Trades API
|
|
216
|
+
|
|
217
|
+
Execute trading operations with margin checking.
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
// Check margin before trading
|
|
221
|
+
const marginCheck = await client.trades.checkMargin({
|
|
222
|
+
login: 50001,
|
|
223
|
+
symbol: 'EURUSD',
|
|
224
|
+
action: 'buy',
|
|
225
|
+
volume: 1.0
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
if (marginCheck.can_execute) {
|
|
229
|
+
// Open trade
|
|
230
|
+
const trade = await client.trades.open({
|
|
231
|
+
login: 50001,
|
|
232
|
+
symbol: 'EURUSD',
|
|
233
|
+
action: 'buy',
|
|
234
|
+
type: 'market',
|
|
235
|
+
volume: 1.0,
|
|
236
|
+
stop_loss: 1.0850,
|
|
237
|
+
take_profit: 1.0950,
|
|
238
|
+
comment: 'API Trade'
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// Modify trade
|
|
242
|
+
await client.trades.modify({
|
|
243
|
+
login: 50001,
|
|
244
|
+
position_id: trade.position_id,
|
|
245
|
+
stop_loss: 1.0875,
|
|
246
|
+
take_profit: 1.0975
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
// Calculate potential profit
|
|
250
|
+
const profitCalc = await client.trades.calculateProfit({
|
|
251
|
+
login: 50001,
|
|
252
|
+
symbol: 'EURUSD',
|
|
253
|
+
action: 'buy',
|
|
254
|
+
volume: 1.0,
|
|
255
|
+
open_price: 1.0900,
|
|
256
|
+
close_price: 1.0950
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// Close trade (partial or full)
|
|
260
|
+
await client.trades.close({
|
|
261
|
+
login: 50001,
|
|
262
|
+
position_id: trade.position_id,
|
|
263
|
+
volume: 0.5, // Partial close
|
|
264
|
+
comment: 'Taking profit'
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Force price (for historical data import)
|
|
269
|
+
const historicalTrade = await client.trades.open({
|
|
270
|
+
login: 50001,
|
|
271
|
+
symbol: 'EURUSD',
|
|
272
|
+
action: 'buy',
|
|
273
|
+
type: 'market',
|
|
274
|
+
volume: 1.0,
|
|
275
|
+
price: 1.0850,
|
|
276
|
+
force_price: true,
|
|
277
|
+
force_timestamp: '2025-01-15T10:30:00Z'
|
|
278
|
+
});
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### 5. Market Data API
|
|
282
|
+
|
|
283
|
+
Query historical market data (minimum 1 hour old).
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
// Get candles with filters
|
|
287
|
+
const candles = await client.marketData.getCandles({
|
|
288
|
+
symbol: 'BTCUSD,ETHUSD',
|
|
289
|
+
timeframe: '1h',
|
|
290
|
+
from: '2025-01-01T00:00:00Z',
|
|
291
|
+
to: '2025-01-02T00:00:00Z',
|
|
292
|
+
min_volume: 1000,
|
|
293
|
+
max_volume: 50000,
|
|
294
|
+
sort: 'volume',
|
|
295
|
+
order: 'desc',
|
|
296
|
+
limit: 100
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
// Get last 100 candles
|
|
300
|
+
const recentCandles = await client.marketData.getCandles({
|
|
301
|
+
symbol: 'BTCUSD',
|
|
302
|
+
timeframe: '1m',
|
|
303
|
+
limit: 100,
|
|
304
|
+
order: 'desc'
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
// Get symbols with filters
|
|
308
|
+
const symbols = await client.marketData.getSymbols({
|
|
309
|
+
group: 'CRYPTO_MAJOR',
|
|
310
|
+
has_data: true,
|
|
311
|
+
search: 'bitcoin'
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
// Get groups hierarchy
|
|
315
|
+
const groups = await client.marketData.getGroups({
|
|
316
|
+
root_only: true,
|
|
317
|
+
sort: 'symbol_count',
|
|
318
|
+
order: 'desc'
|
|
319
|
+
});
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**Timeframes**: `1m`, `5m`, `15m`, `1h`, `4h`, `1d`
|
|
323
|
+
|
|
324
|
+
**Note**: Data must be at least 1 hour old (no real-time data).
|
|
325
|
+
|
|
326
|
+
### 6. Trading Groups API
|
|
327
|
+
|
|
328
|
+
Manage trading groups and their statistics.
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
// List trading groups
|
|
332
|
+
const groups = await client.tradingGroups.list({
|
|
333
|
+
page: 1,
|
|
334
|
+
per_page: 20
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
// Get statistics
|
|
338
|
+
const stats = await client.tradingGroups.getStatistics();
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### 7. WebSocket API
|
|
342
|
+
|
|
343
|
+
Real-time updates for prices, orders, positions, and balance.
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
// Connect to WebSocket
|
|
347
|
+
await client.stream.connect();
|
|
348
|
+
|
|
349
|
+
// Subscribe to price updates
|
|
350
|
+
client.stream.onPriceUpdate((price) => {
|
|
351
|
+
console.log('Price:', price.symbol, price.bid, price.ask);
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
// Subscribe to order updates
|
|
355
|
+
client.stream.onOrderUpdate((order) => {
|
|
356
|
+
console.log('Order:', order.id, order.status);
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
// Subscribe to position updates
|
|
360
|
+
client.stream.onPositionUpdate((position) => {
|
|
361
|
+
console.log('Position:', position.id, position.profit);
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
// Subscribe to balance updates
|
|
365
|
+
client.stream.onBalanceUpdate((balance) => {
|
|
366
|
+
console.log('Balance:', balance.balance, balance.equity);
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
// Disconnect
|
|
370
|
+
await client.stream.disconnect();
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
**Features**:
|
|
374
|
+
- Auto-reconnect with exponential backoff
|
|
375
|
+
- Heartbeat/ping-pong mechanism
|
|
376
|
+
- Automatic subscription restoration
|
|
377
|
+
|
|
378
|
+
## ๐ง Configuration
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
const client = createClient({
|
|
382
|
+
server: 'http://localhost:8080', // Required
|
|
383
|
+
login: 'username', // Optional (for future auth)
|
|
384
|
+
password: 'password' // Optional (for future auth)
|
|
385
|
+
});
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
## ๐ฆ API Response Structure
|
|
389
|
+
|
|
390
|
+
All API endpoints return a consistent response structure:
|
|
391
|
+
|
|
392
|
+
### Success Response (without pagination)
|
|
393
|
+
```typescript
|
|
394
|
+
{
|
|
395
|
+
status: "success",
|
|
396
|
+
status_code: "SUCCESS",
|
|
397
|
+
data: [...] // Array of results or single object
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### Success Response (with pagination)
|
|
402
|
+
```typescript
|
|
403
|
+
{
|
|
404
|
+
status: "success",
|
|
405
|
+
status_code: "SUCCESS",
|
|
406
|
+
data: [...],
|
|
407
|
+
meta: {
|
|
408
|
+
total: 156,
|
|
409
|
+
page: 1,
|
|
410
|
+
per_page: 20,
|
|
411
|
+
total_pages: 8,
|
|
412
|
+
has_next: true,
|
|
413
|
+
has_prev: false
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Error Response
|
|
419
|
+
```typescript
|
|
420
|
+
{
|
|
421
|
+
status: "error",
|
|
422
|
+
status_code: "VALIDATION_ERROR",
|
|
423
|
+
message: "The provided data is not valid.",
|
|
424
|
+
errors?: [
|
|
425
|
+
{
|
|
426
|
+
field: "symbol",
|
|
427
|
+
message: "At least one symbol is required."
|
|
428
|
+
}
|
|
429
|
+
]
|
|
430
|
+
}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### Common Status Codes
|
|
434
|
+
|
|
435
|
+
**Success:**
|
|
436
|
+
- `SUCCESS` - Operation successful
|
|
437
|
+
- `CREATED` - Resource created successfully
|
|
438
|
+
|
|
439
|
+
**Errors:**
|
|
440
|
+
- `VALIDATION_ERROR` (400) - Invalid parameters
|
|
441
|
+
- `BAD_REQUEST` (400) - Invalid request
|
|
442
|
+
- `UNAUTHORIZED` (401) - Authentication required
|
|
443
|
+
- `FORBIDDEN` (403) - Insufficient permissions
|
|
444
|
+
- `NOT_FOUND` (404) - Resource not found
|
|
445
|
+
- `CONFLICT` (409) - Resource conflict (duplicate)
|
|
446
|
+
- `INTERNAL_ERROR` (500) - Server error
|
|
447
|
+
|
|
448
|
+
**Market Data Specific:**
|
|
449
|
+
- `SYMBOL_NOT_FOUND` (404) - Symbol not found
|
|
450
|
+
- `INVALID_TIMEFRAME` (400) - Invalid timeframe
|
|
451
|
+
- `TIME_RANGE_TOO_LARGE` (400) - Time range exceeds maximum
|
|
452
|
+
- `DATA_TOO_RECENT` (400) - Data must be at least 1 hour old
|
|
453
|
+
|
|
454
|
+
## ๐ฏ Common Patterns
|
|
455
|
+
|
|
456
|
+
### Pagination
|
|
457
|
+
|
|
458
|
+
**Option 1: Get all results (no pagination)**
|
|
459
|
+
```typescript
|
|
460
|
+
// Returns all results in a single array
|
|
461
|
+
const accounts = await client.accounts.list({
|
|
462
|
+
state: 'active'
|
|
463
|
+
});
|
|
464
|
+
// Response: { status, status_code, data: [...] }
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
**Option 2: Paginated results**
|
|
468
|
+
```typescript
|
|
469
|
+
// Returns paginated results with metadata
|
|
470
|
+
const accounts = await client.accounts.list({
|
|
471
|
+
state: 'active',
|
|
472
|
+
page: 1,
|
|
473
|
+
per_page: 20
|
|
474
|
+
});
|
|
475
|
+
// Response: { status, status_code, data: [...], meta: {...} }
|
|
476
|
+
|
|
477
|
+
// Iterate through pages
|
|
478
|
+
let page = 1;
|
|
479
|
+
let hasMore = true;
|
|
480
|
+
|
|
481
|
+
while (hasMore) {
|
|
482
|
+
const response = await client.accounts.list({
|
|
483
|
+
state: 'active',
|
|
484
|
+
page,
|
|
485
|
+
per_page: 50
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
// Process response.data
|
|
489
|
+
console.log(`Page ${page}:`, response.data.length);
|
|
490
|
+
|
|
491
|
+
hasMore = response.meta.has_next;
|
|
492
|
+
page++;
|
|
493
|
+
}
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
**Option 3: Limit results (ignores pagination)**
|
|
497
|
+
```typescript
|
|
498
|
+
// Get specific number of results
|
|
499
|
+
const candles = await client.marketData.getCandles({
|
|
500
|
+
symbol: 'BTCUSD',
|
|
501
|
+
timeframe: '1h',
|
|
502
|
+
limit: 100 // Max: 10,000 for candles
|
|
503
|
+
});
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
### Multi-value Filters
|
|
507
|
+
|
|
508
|
+
Many filters accept comma-separated values:
|
|
509
|
+
|
|
510
|
+
```typescript
|
|
511
|
+
// Multiple symbols (OR logic)
|
|
512
|
+
const positions = await client.positions.list({
|
|
513
|
+
symbol: 'EURUSD,GBPUSD,USDJPY' // Positions in ANY of these symbols
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
// Multiple countries
|
|
517
|
+
const accounts = await client.accounts.list({
|
|
518
|
+
country: 'Mexico,United States,Canada'
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
// Multiple states
|
|
522
|
+
const orders = await client.orders.list({
|
|
523
|
+
status: 'new,partial' // Orders with status new OR partial
|
|
524
|
+
});
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
### Date Filters
|
|
528
|
+
|
|
529
|
+
All date parameters must be in **ISO 8601 / RFC3339 format** (UTC):
|
|
530
|
+
|
|
531
|
+
```typescript
|
|
532
|
+
// Correct format
|
|
533
|
+
const positions = await client.positions.list({
|
|
534
|
+
opened_from: '2025-01-01T00:00:00Z',
|
|
535
|
+
opened_to: '2025-01-31T23:59:59Z'
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
// Also valid
|
|
539
|
+
const candles = await client.marketData.getCandles({
|
|
540
|
+
symbol: 'BTCUSD',
|
|
541
|
+
timeframe: '1h',
|
|
542
|
+
from: '2025-01-15T10:30:00Z',
|
|
543
|
+
to: '2025-01-15T18:30:00Z'
|
|
544
|
+
});
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
**Note**: Market data has a minimum age of 1 hour. The `to` parameter cannot be more recent than `now - 1 hour`.
|
|
548
|
+
|
|
549
|
+
### Range Filters
|
|
550
|
+
|
|
551
|
+
Use `min_*` and `max_*` for numeric ranges:
|
|
552
|
+
|
|
553
|
+
```typescript
|
|
554
|
+
// Balance range
|
|
555
|
+
const accounts = await client.accounts.list({
|
|
556
|
+
min_balance: 1000,
|
|
557
|
+
max_balance: 50000
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
// Profit range
|
|
561
|
+
const positions = await client.positions.list({
|
|
562
|
+
profit_min: 100,
|
|
563
|
+
profit_max: 1000
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
// Volume range
|
|
567
|
+
const candles = await client.marketData.getCandles({
|
|
568
|
+
symbol: 'BTCUSD',
|
|
569
|
+
timeframe: '1h',
|
|
570
|
+
min_volume: 1000,
|
|
571
|
+
max_volume: 50000
|
|
572
|
+
});
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
### Sorting
|
|
576
|
+
|
|
577
|
+
Most list endpoints support sorting:
|
|
578
|
+
|
|
579
|
+
```typescript
|
|
580
|
+
const orders = await client.orders.list({
|
|
581
|
+
login: '50001',
|
|
582
|
+
sort_by: 'created_at', // Field to sort by
|
|
583
|
+
sort_order: 'desc' // 'asc' or 'desc'
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
const candles = await client.marketData.getCandles({
|
|
587
|
+
symbol: 'BTCUSD',
|
|
588
|
+
timeframe: '1h',
|
|
589
|
+
sort: 'volume', // Some endpoints use 'sort'
|
|
590
|
+
order: 'desc' // instead of 'sort_by'/'sort_order'
|
|
591
|
+
});
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
## โ ๏ธ Error Handling
|
|
595
|
+
|
|
596
|
+
Always wrap API calls in try-catch blocks:
|
|
597
|
+
|
|
598
|
+
```typescript
|
|
599
|
+
try {
|
|
600
|
+
const trade = await client.trades.open({
|
|
601
|
+
login: 50001,
|
|
602
|
+
symbol: 'EURUSD',
|
|
603
|
+
action: 'buy',
|
|
604
|
+
type: 'market',
|
|
605
|
+
volume: 1.0
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
console.log('Trade opened:', trade.position_id);
|
|
609
|
+
|
|
610
|
+
} catch (error: any) {
|
|
611
|
+
// Check status code
|
|
612
|
+
if (error.status_code === 'INSUFFICIENT_MARGIN') {
|
|
613
|
+
console.error('Not enough margin to open trade');
|
|
614
|
+
} else if (error.status_code === 'SYMBOL_NOT_FOUND') {
|
|
615
|
+
console.error('Symbol does not exist');
|
|
616
|
+
} else if (error.status_code === 'VALIDATION_ERROR') {
|
|
617
|
+
console.error('Invalid parameters:', error.errors);
|
|
618
|
+
} else {
|
|
619
|
+
console.error('Unexpected error:', error.message);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
### Common Error Scenarios
|
|
625
|
+
|
|
626
|
+
```typescript
|
|
627
|
+
// 1. Insufficient margin
|
|
628
|
+
try {
|
|
629
|
+
await client.trades.open({...});
|
|
630
|
+
} catch (error: any) {
|
|
631
|
+
if (error.status_code === 'INSUFFICIENT_MARGIN') {
|
|
632
|
+
// Check margin first
|
|
633
|
+
const check = await client.trades.checkMargin({...});
|
|
634
|
+
console.log('Required margin:', check.margin_required);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// 2. Position not found
|
|
639
|
+
try {
|
|
640
|
+
await client.positions.update(999, {...});
|
|
641
|
+
} catch (error: any) {
|
|
642
|
+
if (error.status_code === 'NOT_FOUND') {
|
|
643
|
+
console.error('Position does not exist');
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// 3. Invalid time range
|
|
648
|
+
try {
|
|
649
|
+
await client.marketData.getCandles({
|
|
650
|
+
symbol: 'BTCUSD',
|
|
651
|
+
timeframe: '1m',
|
|
652
|
+
from: '2025-01-01T00:00:00Z',
|
|
653
|
+
to: '2025-02-01T00:00:00Z' // Too large for 1m
|
|
654
|
+
});
|
|
655
|
+
} catch (error: any) {
|
|
656
|
+
if (error.status_code === 'TIME_RANGE_TOO_LARGE') {
|
|
657
|
+
console.error('Time range exceeds maximum for this timeframe');
|
|
658
|
+
// Max ranges: 1m=7d, 5m=30d, 15m=60d, 1h=6mo, 4h=1y, 1d=5y
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// 4. Data too recent
|
|
663
|
+
try {
|
|
664
|
+
await client.marketData.getCandles({
|
|
665
|
+
symbol: 'BTCUSD',
|
|
666
|
+
timeframe: '1h',
|
|
667
|
+
to: new Date().toISOString() // Too recent!
|
|
668
|
+
});
|
|
669
|
+
} catch (error: any) {
|
|
670
|
+
if (error.status_code === 'DATA_TOO_RECENT') {
|
|
671
|
+
console.error('Market data must be at least 1 hour old');
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
## ๐ TypeScript Support
|
|
677
|
+
|
|
678
|
+
The SDK is written in TypeScript and provides complete type definitions:
|
|
679
|
+
|
|
680
|
+
```typescript
|
|
681
|
+
import type {
|
|
682
|
+
Account,
|
|
683
|
+
Order,
|
|
684
|
+
Position,
|
|
685
|
+
Candle,
|
|
686
|
+
Symbol,
|
|
687
|
+
OpenTradeRequest,
|
|
688
|
+
OpenTradeResponse
|
|
689
|
+
} from '@pipsend/sdk';
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
## ๐งช Testing
|
|
693
|
+
|
|
694
|
+
```bash
|
|
695
|
+
# Run tests
|
|
696
|
+
npm test
|
|
697
|
+
|
|
698
|
+
# Run tests in watch mode
|
|
699
|
+
npm run test:watch
|
|
700
|
+
|
|
701
|
+
# Type checking
|
|
702
|
+
npm run typecheck
|
|
703
|
+
|
|
704
|
+
# Linting
|
|
705
|
+
npm run lint
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
## ๐ ๏ธ Development
|
|
709
|
+
|
|
710
|
+
```bash
|
|
711
|
+
# Install dependencies
|
|
712
|
+
npm install
|
|
713
|
+
|
|
714
|
+
# Build
|
|
715
|
+
npm run build
|
|
716
|
+
|
|
717
|
+
# Watch mode
|
|
718
|
+
npm run dev
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
## ๐ Examples
|
|
722
|
+
|
|
723
|
+
Check the `examples/` directory for complete usage examples:
|
|
724
|
+
|
|
725
|
+
- `examples/api-usage.ts` - Comprehensive API usage
|
|
726
|
+
- `examples/quick-start.ts` - Quick start guide
|
|
727
|
+
|
|
728
|
+
## ๐ Links
|
|
729
|
+
|
|
730
|
+
- [Documentation](https://docs.pipsend.com)
|
|
731
|
+
- [NPM Package](https://www.npmjs.com/package/@pipsend/sdk)
|
|
732
|
+
- [GitHub Repository](https://github.com/pipsend/sdk)
|
|
733
|
+
- [Report Issues](https://github.com/pipsend/sdk/issues)
|
|
734
|
+
|
|
735
|
+
## ๐ License
|
|
736
|
+
|
|
737
|
+
MIT ยฉ 2025 Pipsend
|
|
738
|
+
|
|
739
|
+
## ๐ค Contributing
|
|
740
|
+
|
|
741
|
+
Contributions are welcome! Please:
|
|
742
|
+
|
|
743
|
+
1. Fork the repository
|
|
744
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
745
|
+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
746
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
747
|
+
5. Open a Pull Request
|
|
748
|
+
|
|
749
|
+
## โ ๏ธ Project Status
|
|
750
|
+
|
|
751
|
+
**Current Version: 0.1.0 (Beta)**
|
|
752
|
+
|
|
753
|
+
This SDK is in active development. The API may change between minor versions until version 1.0.0.
|
|
754
|
+
|
|
755
|
+
## ๐ Features Roadmap
|
|
756
|
+
|
|
757
|
+
- [ ] Authentication with JWT tokens
|
|
758
|
+
- [ ] Rate limiting handling
|
|
759
|
+
- [ ] Retry logic with exponential backoff
|
|
760
|
+
- [ ] Request/response interceptors
|
|
761
|
+
- [ ] Batch operations
|
|
762
|
+
- [ ] Streaming data export
|
|
763
|
+
- [ ] Advanced error handling
|
|
764
|
+
- [ ] Performance metrics
|
|
765
|
+
- [ ] Request caching
|
|
766
|
+
- [ ] GraphQL support (future)
|
|
767
|
+
|
|
768
|
+
## ๐ Stats
|
|
769
|
+
|
|
770
|
+
- **6 API Modules**: Accounts, Orders, Positions, Trades, Market Data, Trading Groups
|
|
771
|
+
- **100+ TypeScript Types**: Fully typed interfaces
|
|
772
|
+
- **56 Unit Tests**: Comprehensive test coverage
|
|
773
|
+
- **Bundle Size**: ~26 KB (minified)
|
|
774
|
+
- **Zero Dependencies**: Lightweight and fast
|