@@ -50,15 +50,27 @@ class OrderBook extends EventEmitter {
5050 const ask = this . asks [ i ]
5151
5252 if ( bid ) {
53+ const price = raw ? bid [ 0 ] : Number ( preparePrice ( bid [ 0 ] ) )
54+
5355 data . push (
54- raw ? bid [ 0 ] : Number ( preparePrice ( bid [ 0 ] ) ) , // order ID or price
56+ raw
57+ ? price
58+ : / e / . test ( price + '' )
59+ ? price . toFixed ( Math . abs ( ( price + '' ) . split ( 'e' ) [ 1 ] ) + 1 ) // i.e. 1.7e-7 to fixed
60+ : price ,
5561 bid [ 2 ] // amount
5662 )
5763 }
5864
5965 if ( ask ) {
66+ const price = raw ? ask [ 0 ] : Number ( preparePrice ( ask [ 0 ] ) )
67+
6068 data . push (
61- raw ? ask [ 0 ] : Number ( preparePrice ( ask [ 0 ] ) ) , //
69+ raw
70+ ? price
71+ : / e / . test ( price + '' )
72+ ? price . toFixed ( Math . abs ( ( price + '' ) . split ( 'e' ) [ 1 ] ) + 1 ) // i.e. 1.7e-7 to fixed
73+ : price ,
6274 ask [ 2 ] //
6375 )
6476 }
@@ -101,16 +113,28 @@ class OrderBook extends EventEmitter {
101113 : arr [ topAskI + i ]
102114
103115 if ( bid ) {
116+ const price = raw ? bid [ 0 ] : Number ( preparePrice ( bid [ 0 ] ) )
117+
104118 data . push (
105- raw ? bid [ 0 ] : Number ( preparePrice ( bid [ 0 ] ) ) , // order ID or price
119+ raw
120+ ? bid [ 0 ]
121+ : / e / . test ( price + '' )
122+ ? price . toFixed ( Math . abs ( ( price + '' ) . split ( 'e' ) [ 1 ] ) + 1 ) // i.e. 1.7e-7 to fixed
123+ : price , // order ID or price
106124 bid [ 2 ] // amount
107125 )
108126 }
109127
110128 if ( ask ) {
129+ const price = raw ? ask [ 0 ] : Number ( preparePrice ( ask [ 0 ] ) )
130+
111131 data . push (
112- raw ? ask [ 0 ] : Number ( preparePrice ( ask [ 0 ] ) ) , //
113- ask [ 2 ] //
132+ raw
133+ ? ask [ 0 ]
134+ : / e / . test ( price + '' )
135+ ? price . toFixed ( Math . abs ( ( price + '' ) . split ( 'e' ) [ 1 ] ) + 1 ) // i.e. 1.7e-7 to fixed
136+ : price ,
137+ ask [ 2 ]
114138 )
115139 }
116140 }
@@ -151,9 +175,11 @@ class OrderBook extends EventEmitter {
151175 const price = entry [ priceI ]
152176 const oID = entry [ 0 ] // only for raw books
153177 const amount = entry [ 2 ]
178+ const dir = amount < 0 ? - 1 : 1
154179 const side = amount < 0 ? this . asks : this . bids
155180
156181 let insertIndex = - 1
182+ let pl
157183
158184 // apply insert directly if empty
159185 if ( side . length === 0 && ( raw || count > 0 ) ) {
@@ -162,24 +188,17 @@ class OrderBook extends EventEmitter {
162188 return true
163189 }
164190
191+ // Match by price level, or order ID for raw books
165192 for ( let i = 0 ; i < side . length ; i ++ ) {
166- if ( insertIndex === - 1 && (
167- ( amount > 0 && price > side [ i ] [ priceI ] ) ||
168- ( amount < 0 && price < side [ i ] [ priceI ] )
169- ) ) {
170- insertIndex = i // insert index to maintain sort
171- }
172-
173- // Match by price level, or order ID for raw books
174193 if ( ( ! raw && side [ i ] [ priceI ] === price ) || ( raw && side [ i ] [ 0 ] === oID ) ) {
175194 if ( ( ! raw && count === 0 ) || ( raw && price === 0 ) ) {
176195 side . splice ( i , 1 ) // remove
196+ this . emit ( 'update' , entry )
197+ return true
177198 } else if ( ! raw || ( raw && price > 0 ) ) {
178- side [ i ] = entry // update
199+ side . splice ( i , 1 ) // remove, add update as new entry below
200+ break
179201 }
180-
181- this . emit ( 'update' , entry )
182- return true
183202 }
184203 }
185204
@@ -188,6 +207,21 @@ class OrderBook extends EventEmitter {
188207 return false
189208 }
190209
210+ for ( let i = 0 ; i < side . length ; i ++ ) {
211+ pl = side [ i ]
212+
213+ if ( insertIndex === - 1 && (
214+ ( dir === - 1 && pl [ 2 ] < 0 && price < pl [ priceI ] ) || // by price
215+ ( dir === - 1 && pl [ 2 ] < 0 && price === pl [ priceI ] && ( raw && entry [ 0 ] < pl [ 0 ] ) ) || // by order ID
216+ ( dir === 1 && pl [ 2 ] > 0 && price > pl [ priceI ] ) ||
217+ ( dir === 1 && pl [ 2 ] > 0 && price === pl [ priceI ] && ( raw && entry [ 0 ] < pl [ 0 ] ) ) ||
218+ ( dir === 1 && pl [ 2 ] < 0 )
219+ ) ) {
220+ insertIndex = i // insert index to maintain sort
221+ break
222+ }
223+ }
224+
191225 // add
192226 if ( insertIndex === - 1 ) {
193227 side . push ( entry )
@@ -308,8 +342,7 @@ class OrderBook extends EventEmitter {
308342 }
309343
310344 /**
311- * Modifies an array-format OB in place with an update entry. Sort is not
312- * gauranteed!
345+ * Modifies an array-format OB in place with an update entry. Maintains sort
313346 *
314347 * @param {number[][] } ob
315348 * @param {number[] } entry
@@ -319,22 +352,26 @@ class OrderBook extends EventEmitter {
319352 static updateArrayOBWith ( ob , entry , raw = false ) {
320353 const priceI = raw ? 1 : 0
321354 const price = entry [ priceI ]
355+ const amount = entry [ 2 ]
356+ const dir = amount < 0 ? - 1 : 1
322357 const count = raw ? - 1 : entry [ 1 ]
323358 let insertIndex = - 1
359+ let pl // price level
324360
325361 for ( let i = 0 ; i < ob . length ; i ++ ) {
326- if ( price > ob [ i ] [ priceI ] && insertIndex === - 1 ) {
327- insertIndex = i
328- }
362+ pl = ob [ i ]
329363
330- if ( ( ! raw && ob [ i ] [ priceI ] === price ) || ( raw && ob [ i ] [ 0 ] === entry [ 0 ] ) ) {
364+ if (
365+ ( ! raw && pl [ priceI ] === price ) ||
366+ ( raw && pl [ 0 ] === entry [ 0 ] )
367+ ) {
331368 if ( ( ! raw && count === 0 ) || ( raw && price === 0 ) ) {
332369 ob . splice ( i , 1 ) // remove existing
370+ return true
333371 } else {
334- ob [ i ] = entry // update existing
372+ ob . splice ( i , 1 ) // update; remove & re-insert
373+ break
335374 }
336-
337- return true
338375 }
339376 }
340377
@@ -343,6 +380,23 @@ class OrderBook extends EventEmitter {
343380 return false
344381 }
345382
383+ for ( let i = 0 ; i < ob . length ; i ++ ) {
384+ pl = ob [ i ]
385+
386+ if ( insertIndex === - 1 ) {
387+ if (
388+ ( dir === - 1 && pl [ 2 ] < 0 && price < pl [ priceI ] ) || // by price
389+ ( dir === - 1 && pl [ 2 ] < 0 && price === pl [ priceI ] && ( raw && entry [ 0 ] < pl [ 0 ] ) ) || // by order ID
390+ ( dir === 1 && pl [ 2 ] > 0 && price > pl [ priceI ] ) ||
391+ ( dir === 1 && pl [ 2 ] > 0 && price === pl [ priceI ] && ( raw && entry [ 0 ] < pl [ 0 ] ) ) ||
392+ ( dir === 1 && pl [ 2 ] < 0 )
393+ ) {
394+ insertIndex = i
395+ break
396+ }
397+ }
398+ }
399+
346400 // add
347401 if ( insertIndex === - 1 ) {
348402 ob . push ( entry )
0 commit comments