1
1
#pragma once
2
2
3
3
#include "oracle.h"
4
+ #include "model/model.h"
4
5
#include "pd.h"
5
- #include "sort.h"
6
6
7
7
#include <limits.h>
8
8
@@ -205,39 +205,76 @@ static inline void upd_aggregate( pc_price_t *ptr, uint64_t slot )
205
205
ptr -> valid_slot_ = ptr -> agg_ .pub_slot_ ;// valid slot-time of agg. price
206
206
ptr -> agg_ .pub_slot_ = slot ; // publish slot-time of agg. price
207
207
208
+ // identify valid quotes
209
+ // compute the aggregate prices and ranges
208
210
uint32_t numv = 0 ;
209
211
uint32_t vidx [ PC_COMP_SIZE ];
210
- // identify valid quotes and order them by price
211
- for ( uint32_t i = 0 ; i != ptr -> num_ ; ++ i ) {
212
- pc_price_comp_t * iptr = & ptr -> comp_ [i ];
213
- // copy contributing price to aggregate snapshot
214
- iptr -> agg_ = iptr -> latest_ ;
215
- // add quote to sorted permutation array if it is valid
216
- int64_t slot_diff = ( int64_t )slot - ( int64_t )( iptr -> agg_ .pub_slot_ );
217
- if ( iptr -> agg_ .status_ == PC_STATUS_TRADING &&
218
- iptr -> agg_ .conf_ != 0UL &&
219
- iptr -> agg_ .price_ > 0L &&
220
- slot_diff >= 0 && slot_diff <= PC_MAX_SEND_LATENCY ) {
221
- vidx [numv ++ ] = i ;
212
+ int64_t agg_price ;
213
+ int64_t agg_conf ;
214
+ {
215
+ uint32_t nprcs = (uint32_t )0 ;
216
+ int64_t prcs [ PC_COMP_SIZE * 3 ]; // ~0.75KiB for current PC_COMP_SIZE (FIXME: DOUBLE CHECK THIS FITS INTO STACK FRAME LIMIT)
217
+ for ( uint32_t i = 0 ; i != ptr -> num_ ; ++ i ) {
218
+ pc_price_comp_t * iptr = & ptr -> comp_ [i ];
219
+ // copy contributing price to aggregate snapshot
220
+ iptr -> agg_ = iptr -> latest_ ;
221
+ // add quote to sorted permutation array if it is valid
222
+ int64_t slot_diff = ( int64_t )slot - ( int64_t )( iptr -> agg_ .pub_slot_ );
223
+ int64_t price = iptr -> agg_ .price_ ;
224
+ int64_t conf = ( int64_t )( iptr -> agg_ .conf_ );
225
+ if ( iptr -> agg_ .status_ == PC_STATUS_TRADING &&
226
+ (int64_t )0 < conf && conf < price && conf <= (INT64_MAX - price ) && // No overflow for INT64_MAX-price as price>0
227
+ slot_diff >= 0 && slot_diff <= PC_MAX_SEND_LATENCY ) {
228
+ vidx [numv ++ ] = i ; // FIXME: GRAFT FOR OLD PRICE MODEL
229
+ prcs [ nprcs ++ ] = price - conf ; // No overflow as 0 < conf < price
230
+ prcs [ nprcs ++ ] = price ;
231
+ prcs [ nprcs ++ ] = price + conf ; // No overflow as 0 < conf <= INT64_MAX-price
232
+ }
233
+ }
234
+
235
+ // too few valid quotes
236
+ ptr -> num_qt_ = numv ; // FIXME: TEMPORARY GRAFT (ALL RETURN PATHS SET NUM_QT TO SOMETHING SENSIBLE)
237
+ if ( numv == 0 || numv < ptr -> min_pub_ ) {
238
+ ptr -> agg_ .status_ = PC_STATUS_UNKNOWN ;
239
+ return ;
222
240
}
223
- }
224
241
225
- uint32_t nprcs = 0 ;
226
- int64_t prcs [ PC_COMP_SIZE * 2 ];
227
- for ( uint32_t i = 0 ; i < numv ; ++ i ) {
228
- pc_price_comp_t const * iptr = & ptr -> comp_ [ vidx [ i ] ];
229
- int64_t const price = iptr -> agg_ .price_ ;
230
- int64_t const conf = ( int64_t )( iptr -> agg_ .conf_ );
231
- prcs [ nprcs ++ ] = price - conf ;
232
- prcs [ nprcs ++ ] = price + conf ;
242
+ // evaluate the model to get the p25/p50/p75 prices
243
+ // note: numv>0 and nprcs = 3*numv at this point
244
+ int64_t agg_p25 ;
245
+ int64_t agg_p75 ;
246
+ int64_t scratch [ PC_COMP_SIZE * 3 ]; // ~0.75KiB for current PC_COMP_SIZE (FIXME: DOUBLE CHECK THIS FITS INTO STACK FRAME LIMIT)
247
+ price_model_core ( (uint64_t )nprcs , prcs , & agg_p25 , & agg_price , & agg_p75 , scratch );
248
+
249
+ // get the left and right confidences
250
+ // note that as valid quotes have positive prices currently and
251
+ // agg_p25, agg_price, agg_p75 are ordered, this calculation can't
252
+ // overflow / underflow
253
+ int64_t agg_conf_left = agg_price - agg_p25 ;
254
+ int64_t agg_conf_right = agg_p75 - agg_price ;
255
+
256
+ // use the larger of the left and right confidences
257
+ agg_conf = agg_conf_right > agg_conf_left ? agg_conf_right : agg_conf_left ;
258
+
259
+ // if the confidences end up at zero, we abort
260
+ // this is paranoia as it is currently not possible when nprcs>2 and
261
+ // positive confidences given the current pricing model
262
+ if ( agg_conf <= (int64_t )0 ) {
263
+ ptr -> agg_ .status_ = PC_STATUS_UNKNOWN ;
264
+ return ;
265
+ }
233
266
}
234
- qsort_int64 ( prcs , nprcs );
267
+
268
+ // FIXME: MOST OF THE REST OF THE CODE HERE CAN PROBABLY BE REMOVED /
269
+ // CONDENSED AND/OR MADE MORE EFFICIENT. AND IT PROBABLY WILL
270
+ // REPLACED SOON BY THE VWAP MODEL UNDER DEVELOPMENT. IT IS KEPT HERE
271
+ // TO KEEP THE CURRENT VWAP CALCULATION AS CLOSE AS POSSIBLE TO WHAT
272
+ // HOW IT CURRENTLY WORKS.
235
273
236
274
uint32_t numa = 0 ;
237
275
uint32_t aidx [PC_COMP_SIZE ];
238
-
239
- if ( nprcs ) {
240
- int64_t const mprc = ( prcs [ numv - 1 ] + prcs [ numv ] ) / 2 ;
276
+ {
277
+ int64_t const mprc = agg_price ; // FIXME: GRAFT TO NEW CALC TO OLD CALC
241
278
int64_t const lb = mprc / 5 ;
242
279
int64_t const ub = ( mprc > LONG_MAX / 5 ) ? LONG_MAX : mprc * 5 ;
243
280
@@ -247,7 +284,7 @@ static inline void upd_aggregate( pc_price_t *ptr, uint64_t slot )
247
284
int64_t const prc = iptr -> agg_ .price_ ;
248
285
if ( prc >= lb && prc <= ub ) {
249
286
uint32_t j = numa ++ ;
250
- for ( ; j > 0 && ptr -> comp_ [ aidx [ j - 1 ] ].agg_ .price_ > prc ; -- j ) {
287
+ for ( ; j > 0 && ptr -> comp_ [ aidx [ j - 1 ] ].agg_ .price_ > prc ; -- j ) { // FIXME: O(N^2)
251
288
aidx [ j ] = aidx [ j - 1 ];
252
289
}
253
290
aidx [ j ] = idx ;
@@ -272,6 +309,8 @@ static inline void upd_aggregate( pc_price_t *ptr, uint64_t slot )
272
309
ptr -> agg_ .price_ = iptr -> agg_ .price_ ;
273
310
ptr -> agg_ .conf_ = iptr -> agg_ .conf_ ;
274
311
upd_twap ( ptr , agg_diff , qs );
312
+ ptr -> agg_ .price_ = agg_price ; // FIXME: OVERRIDE OLD PRICE MODEL
313
+ ptr -> agg_ .conf_ = (uint64_t )agg_conf ; // FIXME: OVERRIDE OLD PRICE MODEL
275
314
return ;
276
315
}
277
316
@@ -362,7 +401,7 @@ static inline void upd_aggregate( pc_price_t *ptr, uint64_t slot )
362
401
// sort upper prices and weights
363
402
for ( uint32_t i = 0 ; i < numa ; ++ i ) {
364
403
uint32_t j = i ;
365
- for ( ; j > 0 && pd_lt ( & qs -> uprice_ [ i ], & prices [ j - 1 ], qs -> fact_ ); -- j ) {
404
+ for ( ; j > 0 && pd_lt ( & qs -> uprice_ [ i ], & prices [ j - 1 ], qs -> fact_ ); -- j ) { // FIXME: O(N^2)
366
405
prices [ j ] = prices [ j - 1 ];
367
406
weights [ j ] = weights [ j - 1 ];
368
407
}
@@ -373,7 +412,7 @@ static inline void upd_aggregate( pc_price_t *ptr, uint64_t slot )
373
412
// sort lower prices and weights
374
413
for ( uint32_t i = 0 ; i < numa ; ++ i ) {
375
414
uint32_t j = i ;
376
- for ( ; j > 0 && pd_lt ( & qs -> lprice_ [ i ], & prices [ j - 1 ], qs -> fact_ ); -- j ) {
415
+ for ( ; j > 0 && pd_lt ( & qs -> lprice_ [ i ], & prices [ j - 1 ], qs -> fact_ ); -- j ) { // FIXME: O(N^2)
377
416
prices [ j ] = prices [ j - 1 ];
378
417
weights [ j ] = weights [ j - 1 ];
379
418
}
@@ -398,6 +437,8 @@ static inline void upd_aggregate( pc_price_t *ptr, uint64_t slot )
398
437
pd_adjust ( cptr , ptr -> expo_ , qs -> fact_ );
399
438
ptr -> agg_ .conf_ = ( uint64_t )( cptr -> v_ );
400
439
upd_twap ( ptr , agg_diff , qs );
440
+ ptr -> agg_ .price_ = agg_price ; // FIXME: OVERRIDE OLD PRICE MODEL
441
+ ptr -> agg_ .conf_ = (uint64_t )agg_conf ; // FIXME: OVERRIDE OLD PRICE MODEL
401
442
}
402
443
403
444
#ifdef __cplusplus
0 commit comments