btc-api-node 1.12.7

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.

Potentially problematic release.


This version of btc-api-node might be problematic. Click here for more details.

Files changed (97) hide show
  1. package/.istanbul.yml +53 -0
  2. package/.travis.yml +5 -0
  3. package/CHANGELOG +33 -0
  4. package/LICENSE.md +21 -0
  5. package/README.md +211 -0
  6. package/doc/order.md +160 -0
  7. package/doc/rest2.md +573 -0
  8. package/doc/ws2.md +925 -0
  9. package/examples/bfx.js +26 -0
  10. package/examples/rest2/order_history.js +29 -0
  11. package/examples/rest2/symbols.js +15 -0
  12. package/examples/rest2/tickers.js +24 -0
  13. package/examples/rest2/trade_history.js +28 -0
  14. package/examples/ws2/auth.js +31 -0
  15. package/examples/ws2/calc.js +33 -0
  16. package/examples/ws2/cancel_all.js +35 -0
  17. package/examples/ws2/cancel_all_buf.js +39 -0
  18. package/examples/ws2/candles.js +36 -0
  19. package/examples/ws2/info_events.js +40 -0
  20. package/examples/ws2/oc_multi.js +50 -0
  21. package/examples/ws2/order_books.js +37 -0
  22. package/examples/ws2/orders.js +67 -0
  23. package/examples/ws2/ox_multi.js +61 -0
  24. package/examples/ws2/sequencing.js +23 -0
  25. package/examples/ws2/ticker.js +20 -0
  26. package/examples/ws2/trades.js +27 -0
  27. package/index.js +24 -0
  28. package/lib/model.js +25 -0
  29. package/lib/models/alert.js +25 -0
  30. package/lib/models/balance_info.js +21 -0
  31. package/lib/models/candle.js +33 -0
  32. package/lib/models/funding_credit.js +61 -0
  33. package/lib/models/funding_info.js +16 -0
  34. package/lib/models/funding_loan.js +64 -0
  35. package/lib/models/funding_offer.js +60 -0
  36. package/lib/models/funding_trade.js +33 -0
  37. package/lib/models/index.js +23 -0
  38. package/lib/models/margin_info.js +29 -0
  39. package/lib/models/notification.js +31 -0
  40. package/lib/models/order.js +288 -0
  41. package/lib/models/order_book.js +214 -0
  42. package/lib/models/position.js +43 -0
  43. package/lib/models/tick.js +83 -0
  44. package/lib/models/trade.js +43 -0
  45. package/lib/models/trade_tick.js +29 -0
  46. package/lib/models/wallet.js +34 -0
  47. package/lib/transports/rest.js +391 -0
  48. package/lib/transports/rest2.js +597 -0
  49. package/lib/transports/ws.js +323 -0
  50. package/lib/transports/ws2.js +1729 -0
  51. package/lib/util/gen_auth_sig.js +23 -0
  52. package/lib/util/index.js +11 -0
  53. package/lib/util/is_snapshot.js +5 -0
  54. package/lib/util/nonce.js +5 -0
  55. package/package.json +39 -0
  56. package/test/fixtures/response-ticker-funding.json +1 -0
  57. package/test/fixtures/response-ticker-pairs.json +1 -0
  58. package/test/fixtures/response-trades-funding.json +1 -0
  59. package/test/fixtures/response-trades-pairs.json +1 -0
  60. package/test/fixtures/response-ws-1-orderbook-R0.json +51 -0
  61. package/test/fixtures/response-ws2-server-order-book-P0.json +1 -0
  62. package/test/fixtures/response-ws2-server-order-book-P1.json +1 -0
  63. package/test/fixtures/response-ws2-server-order-book-R0.json +1 -0
  64. package/test/fixtures/response-ws2-server-ticker-funding.json +1 -0
  65. package/test/fixtures/response-ws2-server-trades.json +1 -0
  66. package/test/helpers/test_model.js +71 -0
  67. package/test/index.js +131 -0
  68. package/test/lib/models/alert.js +12 -0
  69. package/test/lib/models/balance_info.js +12 -0
  70. package/test/lib/models/candle.js +12 -0
  71. package/test/lib/models/funding_credit.js +17 -0
  72. package/test/lib/models/funding_info.js +7 -0
  73. package/test/lib/models/funding_loan.js +17 -0
  74. package/test/lib/models/funding_offer.js +17 -0
  75. package/test/lib/models/funding_trade.js +15 -0
  76. package/test/lib/models/margin_info.js +15 -0
  77. package/test/lib/models/notification.js +14 -0
  78. package/test/lib/models/order.js +395 -0
  79. package/test/lib/models/order_book.js +188 -0
  80. package/test/lib/models/position.js +15 -0
  81. package/test/lib/models/tick.js +34 -0
  82. package/test/lib/models/trade.js +16 -0
  83. package/test/lib/models/trade_tick.js +14 -0
  84. package/test/lib/models/wallet.js +14 -0
  85. package/test/lib/transports/rest-1-integration.js +131 -0
  86. package/test/lib/transports/rest-2-integration.js +80 -0
  87. package/test/lib/transports/rest-2-issue-80-argument-length.js +61 -0
  88. package/test/lib/transports/rest-2-smoke-test.js +49 -0
  89. package/test/lib/transports/rest-2-unit.js +26 -0
  90. package/test/lib/transports/rest1.js +152 -0
  91. package/test/lib/transports/ws-1-handle-channel.js +83 -0
  92. package/test/lib/transports/ws-1-parsing.js +40 -0
  93. package/test/lib/transports/ws-1-test.js +275 -0
  94. package/test/lib/transports/ws2-integration.js +259 -0
  95. package/test/lib/transports/ws2-unit.js +1295 -0
  96. package/test/lib/util/is_snapshot.js +20 -0
  97. package/test/lib/util/nonce.js +20 -0
@@ -0,0 +1,395 @@
1
+ /* eslint-env mocha */
2
+ 'use strict'
3
+
4
+ const assert = require('assert')
5
+ const { Order } = require('../../../lib/models')
6
+ const WSv2 = require('../../../lib/transports/ws2')
7
+ const testModel = require('../../helpers/test_model')
8
+
9
+ describe('Order model', () => {
10
+ testModel({
11
+ model: Order,
12
+ boolFields: ['notify', 'hidden'],
13
+ orderedFields: [
14
+ 'id', 'gid', 'cid', 'symbol', 'mtsCreate', 'mtsUpdate', 'amount',
15
+ 'amountOrig', 'type', 'typePrev', null, null, 'flags', 'status', null,
16
+ null, 'price', 'priceAvg', 'priceTrailing', 'priceAuxLimit', null, null,
17
+ null, 'notify', 'hidden', 'placedId'
18
+ ]
19
+ })
20
+
21
+ it('registerListeners: sets up ws2 listeners for on/ou/oc messages', () => {
22
+ const ws = new WSv2()
23
+ assert.equal(Object.keys(ws._listeners).length, 0)
24
+
25
+ const o = new Order({}, ws)
26
+ o.registerListeners()
27
+
28
+ assert.equal(Object.keys(ws._listeners).length, 1)
29
+ assert(ws._listeners[o.cbGID()])
30
+ assert.equal(Object.keys(ws._listeners[o.cbGID()]).length, 3)
31
+ })
32
+
33
+ it('registerListeners: uses provided ws, or defaults to internal ws', () => {
34
+ const wsA = new WSv2()
35
+ const wsB = new WSv2()
36
+ assert.equal(Object.keys(wsA._listeners).length, 0)
37
+ assert.equal(Object.keys(wsB._listeners).length, 0)
38
+
39
+ const oInternal = new Order({}, wsA)
40
+ const oProvided = new Order({})
41
+
42
+ oInternal.registerListeners()
43
+ oProvided.registerListeners(wsB)
44
+
45
+ assert.equal(Object.keys(wsA._listeners).length, 1)
46
+ assert(wsA._listeners[oInternal.cbGID()])
47
+ assert.equal(Object.keys(wsA._listeners[oInternal.cbGID()]).length, 3)
48
+
49
+ assert.equal(Object.keys(wsB._listeners).length, 1)
50
+ assert(wsB._listeners[oProvided.cbGID()])
51
+ assert.equal(Object.keys(wsB._listeners[oProvided.cbGID()]).length, 3)
52
+ })
53
+
54
+ it('registerListeners: does nothing if no ws is available', () => {
55
+ const o = new Order()
56
+ assert.doesNotThrow(() => o.registerListeners())
57
+ })
58
+
59
+ it('removeListeners: removes all registered ws2 listeners', () => {
60
+ const o = new Order()
61
+ const ws = new WSv2()
62
+ assert.equal(Object.keys(ws._listeners).length, 0)
63
+ o.registerListeners(ws)
64
+ assert.equal(Object.keys(ws._listeners).length, 1)
65
+ o.removeListeners(ws)
66
+ assert.equal(Object.keys(ws._listeners).length, 0)
67
+ })
68
+
69
+ it('removeListeners: uses ws argument if provided', () => {
70
+ const wsA = new WSv2()
71
+ const wsB = new WSv2()
72
+ const o = new Order({}, wsB)
73
+
74
+ assert.equal(Object.keys(wsA._listeners).length, 0)
75
+ assert.equal(Object.keys(wsB._listeners).length, 0)
76
+
77
+ o.registerListeners(wsA)
78
+
79
+ assert.equal(Object.keys(wsA._listeners).length, 1)
80
+ assert.equal(Object.keys(wsB._listeners).length, 0)
81
+
82
+ o.removeListeners(wsA)
83
+
84
+ assert.equal(Object.keys(wsA._listeners).length, 0)
85
+ assert.equal(Object.keys(wsB._listeners).length, 0)
86
+ })
87
+
88
+ it('removeListeners: does nothing if no ws is available', () => {
89
+ const o = new Order()
90
+ assert.doesNotThrow(() => o.removeListeners())
91
+ })
92
+
93
+ it('submit: uses provided ws, or defaults to internal ws', (done) => {
94
+ const wsA = new WSv2()
95
+ const wsB = new WSv2()
96
+ const oA = new Order()
97
+ const oB = new Order({}, wsB)
98
+
99
+ let submitA = false
100
+ let submitB = false
101
+
102
+ wsA.submitOrder = () => {
103
+ submitA = true
104
+ return Promise.resolve([])
105
+ }
106
+
107
+ wsB.submitOrder = () => {
108
+ submitB = true
109
+ return Promise.resolve([])
110
+ }
111
+
112
+ oA.submit(wsA).then(() => {
113
+ assert(submitA)
114
+ return oB.submit()
115
+ }).then(() => {
116
+ assert(submitB)
117
+ done()
118
+ }).catch(done)
119
+ })
120
+
121
+ it('submit: rejects if no ws is available', (done) => {
122
+ const o = new Order()
123
+
124
+ o.submit().then(() => {
125
+ assert(false)
126
+ }).catch((e) => {
127
+ assert(e.message.indexOf('no ws') !== -1)
128
+ done()
129
+ })
130
+ })
131
+
132
+ it('submit: submits order via ws and saves any changes from the response', (done) => {
133
+ const ws = new WSv2()
134
+ const o = new Order({}, ws)
135
+
136
+ ws.submitOrder = () => {
137
+ return Promise.resolve(new Order({
138
+ id: 1,
139
+ gid: 2,
140
+ cid: 3,
141
+ type: 'EXCHANGE LIMIT',
142
+ symbol: 42
143
+ }).serialize())
144
+ }
145
+
146
+ o.submit().then(() => {
147
+ assert.equal(o.id, 1)
148
+ assert.equal(o.gid, 2)
149
+ assert.equal(o.cid, 3)
150
+ assert.equal(o.type, 'EXCHANGE LIMIT')
151
+ assert.equal(o.symbol, 42)
152
+ done()
153
+ })
154
+ })
155
+
156
+ it('cancel: uses provided ws, or defaults to internal ws', (done) => {
157
+ const wsA = new WSv2()
158
+ const wsB = new WSv2()
159
+ const oA = new Order({ id: 41 })
160
+ const oB = new Order({ id: 42 }, wsB)
161
+
162
+ let cancelA = false
163
+ let cancelB = false
164
+
165
+ wsA.cancelOrder = () => {
166
+ cancelA = true
167
+ return Promise.resolve([])
168
+ }
169
+
170
+ wsB.cancelOrder = () => {
171
+ cancelB = true
172
+ return Promise.resolve([])
173
+ }
174
+
175
+ oA.cancel(wsA).then(() => {
176
+ assert(cancelA)
177
+ return oB.cancel()
178
+ }).then(() => {
179
+ assert(cancelB)
180
+ done()
181
+ }).catch(done)
182
+ })
183
+
184
+ it('cancel: rejects if no ws is available', (done) => {
185
+ const o = new Order({ id: 42 })
186
+
187
+ o.cancel().then(() => {
188
+ assert(false)
189
+ }).catch((e) => {
190
+ assert(e.message.indexOf('no ws') !== -1)
191
+ done()
192
+ })
193
+ })
194
+
195
+ it('cancel: rejects if order has no ID', (done) => {
196
+ const ws = new WSv2()
197
+ const o = new Order({}, ws)
198
+
199
+ ws.cancelOrder = () => Promise.resolve()
200
+
201
+ o.cancel().then(() => {
202
+ assert(false)
203
+ }).catch((e) => {
204
+ assert(e.message.indexOf('no ID') !== -1)
205
+ done()
206
+ })
207
+ })
208
+
209
+ it('cancel: cancels the order by ID via the ws client', (done) => {
210
+ const ws = new WSv2()
211
+ const o = new Order({ id: 42 }, ws)
212
+ let canceled = false
213
+
214
+ ws.cancelOrder = (id) => {
215
+ assert.equal(id, 42)
216
+ canceled = true
217
+ return Promise.resolve()
218
+ }
219
+
220
+ o.cancel().then(() => {
221
+ assert(canceled)
222
+ done()
223
+ })
224
+ })
225
+
226
+ it.skip('recreate: uses provided ws, or defaults to internal ws')
227
+ it.skip('recreate: passes ws through to cancel & submit')
228
+
229
+ it('recreate: rejects if no ws is available', (done) => {
230
+ const o = new Order({ id: 42 })
231
+
232
+ o.recreate().then(() => {
233
+ assert(false)
234
+ }).catch((e) => {
235
+ assert(e.message.indexOf('no ws') !== -1)
236
+ done()
237
+ })
238
+ })
239
+
240
+ it('recreate: rejects if order has no ID', (done) => {
241
+ const ws = new WSv2()
242
+ const o = new Order({}, ws)
243
+
244
+ o.recreate().then(() => {
245
+ assert(false)
246
+ }).catch((e) => {
247
+ assert(e.message.indexOf('no ID') !== -1)
248
+ done()
249
+ })
250
+ })
251
+
252
+ it('recreate: cancels & submits the order as new w/ null ID', (done) => {
253
+ const ws = new WSv2()
254
+ const o = new Order({ id: 42 }, ws)
255
+
256
+ let canceled = false
257
+ let submitted = false
258
+
259
+ o.submit = () => {
260
+ assert.equal(o.id, null)
261
+ submitted = true
262
+ return Promise.resolve()
263
+ }
264
+
265
+ o.cancel = () => {
266
+ assert.equal(o.id, 42)
267
+ canceled = true
268
+ return Promise.resolve()
269
+ }
270
+
271
+ o.recreate().then(() => {
272
+ assert(canceled)
273
+ assert(submitted)
274
+ done()
275
+ }).catch(done)
276
+ })
277
+
278
+ it('recreate: saves new order data off of response', (done) => {
279
+ const ws = new WSv2()
280
+ const o = new Order({ id: 42 }, ws)
281
+
282
+ o.cancel = () => Promise.resolve()
283
+ ws.submitOrder = () => {
284
+ return Promise.resolve(new Order({
285
+ id: 128
286
+ }).serialize())
287
+ }
288
+
289
+ o.recreate().then(() => {
290
+ assert.equal(o.id, 128)
291
+ done()
292
+ }).catch(done)
293
+ })
294
+
295
+ it('getLastFillAmount: respects _lastAmount & amount', () => {
296
+ const o = new Order()
297
+ o.amount = 5
298
+ o._lastAmount = 7
299
+ assert.equal(o.getLastFillAmount(), 2)
300
+ o._lastAmount = 6
301
+ assert.equal(o.getLastFillAmount(), 1)
302
+ o._lastAmount = 3
303
+ o.amount = 1
304
+ assert.equal(o.getLastFillAmount(), 2)
305
+ })
306
+
307
+ const testHandlerFillUpdate = (handler) => {
308
+ const o = new Order({ id: 100, amount: 10 })
309
+ const oArr = [42]
310
+ oArr[6] = 8
311
+ o[handler](oArr)
312
+ oArr[6] = 6
313
+ o[handler](oArr)
314
+ assert.equal(o._lastAmount, 8)
315
+ }
316
+
317
+ it('_onWSOrderUpdate: updates last fill amount', () => {
318
+ testHandlerFillUpdate('_onWSOrderUpdate')
319
+ })
320
+
321
+ it('_onWSOrderUpdate: saves data off of request', () => {
322
+ const o = new Order({ id: 100 })
323
+ o._onWSOrderUpdate([42])
324
+ assert.equal(o.id, 42)
325
+ })
326
+
327
+ it('_onWSOrderUpdate: emits update event', (done) => {
328
+ const o = new Order({ id: 100 })
329
+ o.on('update', () => done())
330
+ o._onWSOrderUpdate([42])
331
+ })
332
+
333
+ it('_onWSOrderClose: updates last fill amount', () => {
334
+ testHandlerFillUpdate('_onWSOrderClose')
335
+ })
336
+
337
+ it('_onWSOrderClose: saves data off of request', () => {
338
+ const o = new Order({ id: 100 })
339
+ o._onWSOrderClose([42])
340
+ assert.equal(o.id, 42)
341
+ })
342
+
343
+ it('_onWSOrderClose: emits close event', (done) => {
344
+ const o = new Order({ id: 100 })
345
+ o.on('close', () => done())
346
+ o._onWSOrderClose([42])
347
+ })
348
+
349
+ it('_onWSOrderNew: updates last fill amount', () => {
350
+ testHandlerFillUpdate('_onWSOrderNew')
351
+ })
352
+
353
+ it('_onWSOrderNew: saves data off of request', () => {
354
+ const o = new Order({ id: 100 })
355
+ o._onWSOrderNew([42])
356
+ assert.equal(o.id, 42)
357
+ })
358
+
359
+ it('_onWSOrderNew: emits update event', (done) => {
360
+ const o = new Order({ id: 100 })
361
+ o.on('update', () => done())
362
+ o._onWSOrderNew([42])
363
+ })
364
+
365
+ it('toNewOrderPacket: uses correct values', () => {
366
+ const o = new Order({
367
+ id: 1,
368
+ gid: 2,
369
+ cid: 3,
370
+ symbol: 'tBTCUSD',
371
+ type: 'EXCHANGE LIMIT',
372
+ priceTrailing: 0.1,
373
+ priceAuxLimit: 0.2,
374
+ price: 0.3,
375
+ amount: 0.4,
376
+ hidden: true,
377
+ postonly: false
378
+ })
379
+
380
+ const p = o.toNewOrderPacket()
381
+
382
+ assert.equal(p.constructor.name, 'Object')
383
+ assert(!p.id)
384
+ assert.equal(p.gid, 2)
385
+ assert.equal(p.cid, 3)
386
+ assert.equal(p.symbol, 'tBTCUSD')
387
+ assert.equal(p.type, 'EXCHANGE LIMIT')
388
+ assert.equal(p.price_trailing, '0.1')
389
+ assert.equal(p.price_aux_limit, '0.2')
390
+ assert.equal(p.price, '0.3')
391
+ assert.equal(p.amount, '0.4')
392
+ assert.equal(p.hidden, 1)
393
+ assert.equal(p.postonly, 0)
394
+ })
395
+ })
@@ -0,0 +1,188 @@
1
+ /* eslint-env mocha */
2
+ 'use strict'
3
+
4
+ const assert = require('assert')
5
+ const { OrderBook } = require('../../../lib/models')
6
+
7
+ describe('OrderBook model', () => {
8
+ it('constructor: integrates snapshot', () => {
9
+ const entries = [
10
+ [100, 2, 10],
11
+ [200, 2, -10]
12
+ ]
13
+
14
+ const ob = new OrderBook(entries)
15
+
16
+ assert.deepEqual(ob.bids, [entries[0]])
17
+ assert.deepEqual(ob.asks, [entries[1]])
18
+ })
19
+
20
+ it('updateWith: emits an error if removing an unknown price level', (done) => {
21
+ const entries = [
22
+ [100, 2, 10],
23
+ [200, 2, -10]
24
+ ]
25
+
26
+ const ob = new OrderBook(entries)
27
+
28
+ ob.on('error', (err) => {
29
+ assert(err.message.indexOf('unknown price') !== -1)
30
+ done()
31
+ })
32
+
33
+ ob.updateWith([300, 0, 1])
34
+ })
35
+
36
+ it('updateWith: correctly applies update', () => {
37
+ const entries = [
38
+ [100, 2, 10],
39
+ [200, 2, -10]
40
+ ]
41
+
42
+ const ob = new OrderBook(entries)
43
+ ob.updateWith([100, 3, 15])
44
+
45
+ assert.deepEqual(ob.bids[0], [100, 3, 15])
46
+ assert.equal(ob.bids.length, 1)
47
+
48
+ ob.updateWith([100, 0, 1])
49
+ assert.equal(ob.bids.length, 0)
50
+ })
51
+
52
+ it('updateWith: maintains sort', () => {
53
+ const ob = new OrderBook([
54
+ [100, 2, 10],
55
+ [200, 2, -10]
56
+ ])
57
+
58
+ ob.updateWith([20, 5, 10])
59
+ ob.updateWith([150, 5, 10])
60
+ ob.updateWith([80, 5, 10])
61
+ ob.updateWith([300, 5, -10])
62
+ ob.updateWith([40, 5, 10])
63
+ ob.updateWith([130, 5, 10])
64
+ ob.updateWith([342, 5, -10])
65
+ ob.updateWith([457, 5, -10])
66
+
67
+ for (let i = 0; i < ob.bids.length - 2; i++) {
68
+ assert(ob.bids[i][0] > ob.bids[i + 1][0])
69
+ }
70
+
71
+ for (let i = 0; i < ob.asks.length - 2; i++) {
72
+ assert(ob.asks[i][0] < ob.asks[i + 1][0])
73
+ }
74
+ })
75
+
76
+ it('updateWith: emits an update event', (done) => {
77
+ const ob = new OrderBook([
78
+ [100, 2, 10],
79
+ [200, 2, -10]
80
+ ])
81
+
82
+ ob.on('update', () => {
83
+ done()
84
+ })
85
+
86
+ ob.updateWith([20, 5, 10])
87
+ })
88
+
89
+ it('midPrice: calculates mid price', () => {
90
+ const entries = [
91
+ [100, 2, 10],
92
+ [200, 2, -10]
93
+ ]
94
+
95
+ const ob = new OrderBook(entries)
96
+ assert.equal(ob.midPrice(), 150)
97
+ })
98
+
99
+ it('getEntry: returns null for unknown entries', () => {
100
+ const entries = [
101
+ [100, 2, 10],
102
+ [200, 2, -10]
103
+ ]
104
+
105
+ const ob = new OrderBook(entries)
106
+ const entry = ob.getEntry(300)
107
+
108
+ assert.equal(entry, null)
109
+ })
110
+
111
+ it('getEntry: returns entry even with only one OB side', () => {
112
+ const entriesA = [[100, 2, 10]]
113
+ const entriesB = [[200, 2, -10]]
114
+
115
+ const obA = new OrderBook(entriesA)
116
+ const obB = new OrderBook(entriesB)
117
+
118
+ assert.deepEqual(obA.getEntry(100), { price: 100, count: 2, amount: 10 })
119
+ assert.deepEqual(obB.getEntry(200), { price: 200, count: 2, amount: -10 })
120
+ })
121
+
122
+ it('getEntry: unserializes entry before returning', () => {
123
+ const entries = [
124
+ [100, 2, 10],
125
+ [200, 2, -10]
126
+ ]
127
+
128
+ const ob = new OrderBook(entries)
129
+ const entry = ob.getEntry(100)
130
+
131
+ assert.equal(entry.price, 100)
132
+ assert.equal(entry.count, 2)
133
+ assert.equal(entry.amount, 10)
134
+ })
135
+
136
+ it('updateArrayOBWith: returns false for unknown entry', () => {
137
+ const ob = [
138
+ [100, 2, 10],
139
+ [200, 2, -10]
140
+ ]
141
+
142
+ assert(!OrderBook.updateArrayOBWith(ob, [300, 0, -1]))
143
+ assert(!OrderBook.updateArrayOBWith(ob, [300, 0, 1]))
144
+ })
145
+
146
+ it('updateArrayOBWith: correctly applies update', () => {
147
+ const ob = [
148
+ [100, 2, 10],
149
+ [200, 2, -10]
150
+ ]
151
+
152
+ OrderBook.updateArrayOBWith(ob, [100, 0, 1])
153
+ OrderBook.updateArrayOBWith(ob, [150, 1, 16])
154
+ OrderBook.updateArrayOBWith(ob, [200, 7, -42])
155
+ OrderBook.updateArrayOBWith(ob, [121, 3, 14])
156
+ OrderBook.updateArrayOBWith(ob, [300, 1, -4])
157
+
158
+ assert.deepEqual(ob, [
159
+ [300, 1, -4],
160
+ [200, 7, -42],
161
+ [150, 1, 16],
162
+ [121, 3, 14]
163
+ ])
164
+ })
165
+
166
+ it('unserialize: returns bid/asks map for snapshots', () => {
167
+ const obData = [
168
+ [100, 2, 10],
169
+ [200, 2, -10]
170
+ ]
171
+
172
+ const ob = OrderBook.unserialize(obData)
173
+ assert.equal(typeof ob, 'object')
174
+ assert.equal(Object.keys(ob).length, 2)
175
+ assert.deepEqual(ob.bids, [{ price: 100, count: 2, amount: 10 }])
176
+ assert.deepEqual(ob.asks, [{ price: 200, count: 2, amount: -10 }])
177
+ })
178
+
179
+ it('unserialiez: returns map for entries', () => {
180
+ const entry = OrderBook.unserialize([150, 0, -1])
181
+
182
+ assert.deepEqual(entry, {
183
+ price: 150,
184
+ count: 0,
185
+ amount: -1
186
+ })
187
+ })
188
+ })
@@ -0,0 +1,15 @@
1
+ /* eslint-env mocha */
2
+ 'use strict'
3
+
4
+ const { Position } = require('../../../lib/models')
5
+ const testModel = require('../../helpers/test_model')
6
+
7
+ describe('Position model', () => {
8
+ testModel({
9
+ model: Position,
10
+ orderedFields: [
11
+ 'symbol', 'status', 'amount', 'basePrice', 'marginFunding',
12
+ 'marginFundingType', 'pl', 'plPerc', 'liquidationPrice', 'leverage'
13
+ ]
14
+ })
15
+ })
@@ -0,0 +1,34 @@
1
+ /* eslint-env mocha */
2
+ 'use strict'
3
+
4
+ const { Tick } = require('../../../lib/models')
5
+ const testModel = require('../../helpers/test_model')
6
+
7
+ describe('Trade Tick model', () => {
8
+ testModel({
9
+ model: Tick,
10
+ values: {
11
+ symbol: 'tBTCUSD'
12
+ },
13
+
14
+ orderedFields: [
15
+ 'symbol', 'bid', 'bidSize', 'ask', 'askSize', 'dailyChange',
16
+ 'dailyChangePerc', 'lastPrice', 'volume', 'high', 'low'
17
+ ]
18
+ })
19
+ })
20
+
21
+ describe('Funding Tick model', () => {
22
+ testModel({
23
+ model: Tick,
24
+ values: {
25
+ symbol: 'fUSD'
26
+ },
27
+
28
+ orderedFields: [
29
+ 'symbol', 'frr', 'bid', 'bidSize', 'bidPeriod', 'ask', 'askSize',
30
+ 'askPeriod', 'dailyChange', 'dailyChangePerc', 'lastPrice', 'volume',
31
+ 'high', 'low'
32
+ ]
33
+ })
34
+ })
@@ -0,0 +1,16 @@
1
+ /* eslint-env mocha */
2
+ 'use strict'
3
+
4
+ const { Trade } = require('../../../lib/models')
5
+ const testModel = require('../../helpers/test_model')
6
+
7
+ describe('Trade model', () => {
8
+ testModel({
9
+ model: Trade,
10
+ boolFields: ['maker'],
11
+ orderedFields: [
12
+ 'id', 'pair', 'mtsCreate', 'orderID', 'execAmount', 'execPrice',
13
+ 'orderType', 'orderPrice', 'maker', 'fee', 'feeCurrency'
14
+ ]
15
+ })
16
+ })
@@ -0,0 +1,14 @@
1
+ /* eslint-env mocha */
2
+ 'use strict'
3
+
4
+ const { TradeTick } = require('../../../lib/models')
5
+ const testModel = require('../../helpers/test_model')
6
+
7
+ describe('Trade Tick model', () => {
8
+ testModel({
9
+ model: TradeTick,
10
+ orderedFields: [
11
+ 'id', 'mts', 'amount', 'price'
12
+ ]
13
+ })
14
+ })
@@ -0,0 +1,14 @@
1
+ /* eslint-env mocha */
2
+ 'use strict'
3
+
4
+ const { Wallet } = require('../../../lib/models')
5
+ const testModel = require('../../helpers/test_model')
6
+
7
+ describe('Wallet model', () => {
8
+ testModel({
9
+ model: Wallet,
10
+ orderedFields: [
11
+ 'type', 'currency', 'balance', 'unsettledInterest', 'balanceAvailable'
12
+ ]
13
+ })
14
+ })