@@ -141,42 +141,6 @@ static inline void upd_twap(
141141 upd_ema ( & ptr -> twac_ , conf , conf , nslots , qs );
142142}
143143
144- // compute weighted percentile
145- static void wgt_ptile (
146- pd_t * const res
147- , const pd_t * const prices , const pd_t * const weights , const uint32_t num
148- , const pd_t * const ptile , pc_qset_t * qs )
149- {
150- pd_t cumwgt [ PC_COMP_SIZE ];
151-
152- pd_t cumwgta [ 1 ], half [ 1 ];
153- pd_new ( cumwgta , 0 , 0 );
154- pd_new ( half , 5 , -1 );
155- for ( uint32_t i = 0 ; i < num ; ++ i ) {
156- const pd_t * const wptr = & weights [ i ];
157- pd_t weight [ 1 ];
158- pd_mul ( weight , wptr , half );
159- pd_add ( & cumwgt [ i ], cumwgta , weight , qs -> fact_ );
160- pd_add ( cumwgta , cumwgta , wptr , qs -> fact_ );
161- }
162-
163- uint32_t i = 0 ;
164- for ( ; i != num && pd_lt ( & cumwgt [i ], ptile , qs -> fact_ ); ++ i );
165- if ( i == num ) {
166- pd_set ( res , & prices [num - 1 ] );
167- } else if ( i == 0 ) {
168- pd_set ( res , & prices [0 ] );
169- } else {
170- pd_t t1 [1 ], t2 [1 ];
171- pd_sub ( t1 , & prices [i ], & prices [i - 1 ], qs -> fact_ );
172- pd_sub ( t2 , ptile , & cumwgt [i - 1 ], qs -> fact_ );
173- pd_mul ( t1 , t1 , t2 );
174- pd_sub ( t2 , & cumwgt [i ], & cumwgt [i - 1 ], qs -> fact_ );
175- pd_div ( t1 , t1 , t2 );
176- pd_add ( res , & prices [i - 1 ], t1 , qs -> fact_ );
177- }
178- }
179-
180144// update aggregate price
181145static inline void upd_aggregate ( pc_price_t * ptr , uint64_t slot , int64_t timestamp )
182146{
@@ -204,11 +168,10 @@ static inline void upd_aggregate( pc_price_t *ptr, uint64_t slot, int64_t timest
204168
205169 // identify valid quotes
206170 // compute the aggregate prices and ranges
207- uint32_t numv = 0 ;
208- uint32_t vidx [ PC_COMP_SIZE ];
209171 int64_t agg_price ;
210172 int64_t agg_conf ;
211173 {
174+ uint32_t numv = 0 ;
212175 uint32_t nprcs = (uint32_t )0 ;
213176 int64_t prcs [ PC_COMP_SIZE * 3 ]; // ~0.75KiB for current PC_COMP_SIZE (FIXME: DOUBLE CHECK THIS FITS INTO STACK FRAME LIMIT)
214177 for ( uint32_t i = 0 ; i != ptr -> num_ ; ++ i ) {
@@ -222,15 +185,15 @@ static inline void upd_aggregate( pc_price_t *ptr, uint64_t slot, int64_t timest
222185 if ( iptr -> agg_ .status_ == PC_STATUS_TRADING &&
223186 (int64_t )0 < conf && conf < price && conf <= (INT64_MAX - price ) && // No overflow for INT64_MAX-price as price>0
224187 slot_diff >= 0 && slot_diff <= PC_MAX_SEND_LATENCY ) {
225- vidx [ numv ++ ] = i ; // FIXME: GRAFT FOR OLD PRICE MODEL
188+ numv += 1 ;
226189 prcs [ nprcs ++ ] = price - conf ; // No overflow as 0 < conf < price
227190 prcs [ nprcs ++ ] = price ;
228191 prcs [ nprcs ++ ] = price + conf ; // No overflow as 0 < conf <= INT64_MAX-price
229192 }
230193 }
231194
232195 // too few valid quotes
233- ptr -> num_qt_ = numv ; // FIXME: TEMPORARY GRAFT (ALL RETURN PATHS SET NUM_QT TO SOMETHING SENSIBLE)
196+ ptr -> num_qt_ = numv ;
234197 if ( numv == 0 || numv < ptr -> min_pub_ ) {
235198 ptr -> agg_ .status_ = PC_STATUS_UNKNOWN ;
236199 return ;
@@ -262,180 +225,13 @@ static inline void upd_aggregate( pc_price_t *ptr, uint64_t slot, int64_t timest
262225 }
263226 }
264227
265- // FIXME: MOST OF THE REST OF THE CODE HERE CAN PROBABLY BE REMOVED /
266- // CONDENSED AND/OR MADE MORE EFFICIENT. AND IT PROBABLY WILL
267- // REPLACED SOON BY THE VWAP MODEL UNDER DEVELOPMENT. IT IS KEPT HERE
268- // TO KEEP THE CURRENT VWAP CALCULATION AS CLOSE AS POSSIBLE TO WHAT
269- // HOW IT CURRENTLY WORKS.
270-
271- uint32_t numa = 0 ;
272- uint32_t aidx [PC_COMP_SIZE ];
273- {
274- int64_t const mprc = agg_price ; // FIXME: GRAFT TO NEW CALC TO OLD CALC
275- int64_t const lb = mprc / 5 ;
276- int64_t const ub = ( mprc > LONG_MAX / 5 ) ? LONG_MAX : mprc * 5 ;
277-
278- for ( uint32_t i = 0 ; i < numv ; ++ i ) {
279- uint32_t const idx = vidx [ i ];
280- pc_price_comp_t const * iptr = & ptr -> comp_ [ idx ];
281- int64_t const prc = iptr -> agg_ .price_ ;
282- if ( prc >= lb && prc <= ub ) {
283- uint32_t j = numa ++ ;
284- for ( ; j > 0 && ptr -> comp_ [ aidx [ j - 1 ] ].agg_ .price_ > prc ; -- j ) { // FIXME: O(N^2)
285- aidx [ j ] = aidx [ j - 1 ];
286- }
287- aidx [ j ] = idx ;
288- }
289- }
290- }
291-
292- // zero quoters
293- ptr -> num_qt_ = numa ;
294- if ( numa == 0 || numa < ptr -> min_pub_ || numa * 2 <= numv ) {
295- ptr -> agg_ .status_ = PC_STATUS_UNKNOWN ;
296- return ;
297- }
298-
299228 // update status and publish slot of last trading status price
300229 ptr -> agg_ .status_ = PC_STATUS_TRADING ;
301- ptr -> last_slot_ = slot ;
302-
303- // single quoter
304- if ( numa == 1 ) {
305- pc_price_comp_t * iptr = & ptr -> comp_ [aidx [0 ]];
306- ptr -> agg_ .price_ = iptr -> agg_ .price_ ;
307- ptr -> agg_ .conf_ = iptr -> agg_ .conf_ ;
308- upd_twap ( ptr , agg_diff , qs );
309- ptr -> agg_ .price_ = agg_price ; // FIXME: OVERRIDE OLD PRICE MODEL
310- ptr -> agg_ .conf_ = (uint64_t )agg_conf ; // FIXME: OVERRIDE OLD PRICE MODEL
311- return ;
312- }
313-
314- // assign quotes and compute weights
315- pc_price_comp_t * pptr = 0 ;
316- pd_t price [1 ], conf [1 ], weight [1 ], one [1 ], wsum [1 ];
317- pd_new ( one , 100000000L , -8 );
318- pd_new ( wsum , 0 , 0 );
319- int64_t ldiff = INT64_MAX ;
320- pd_t * wptr = qs -> weight_ ;
321- for ( uint32_t i = 0 ;i != numa ; ++ i ) {
322- pc_price_comp_t * iptr = & ptr -> comp_ [aidx [i ]];
323- // scale confidence interval by sqrt of slot age
324- int64_t slot_diff = ( int64_t )slot - ( int64_t )( iptr -> agg_ .pub_slot_ );
325- pd_t decay [1 ];
326- pd_new ( decay , qs -> decay_ [slot_diff ], PC_EXP_DECAY );
327- pd_new_scale ( conf , ( int64_t )( iptr -> agg_ .conf_ ), ptr -> expo_ );
328- pd_mul ( conf , conf , decay );
329-
330- // assign price and upper/lower bounds of price
331- pd_new_scale ( price , iptr -> agg_ .price_ , ptr -> expo_ );
332- pd_set ( & qs -> iprice_ [i ], price );
333- pd_add ( & qs -> uprice_ [i ], price , conf , qs -> fact_ );
334- pd_sub ( & qs -> lprice_ [i ], price , conf , qs -> fact_ );
335-
336- // compute weight (1/(conf+nearest_neighbor))
337- pd_set ( & qs -> weight_ [i ], conf );
338- if ( i ) {
339- int64_t idiff = iptr -> agg_ .price_ - pptr -> agg_ .price_ ;
340- pd_new_scale ( weight , idiff < ldiff ? idiff : ldiff , ptr -> expo_ );
341- pd_add ( wptr , wptr , weight , qs -> fact_ );
342- pd_div ( wptr , one , wptr );
343- pd_add ( wsum , wsum , wptr , qs -> fact_ );
344- ldiff = idiff ;
345- ++ wptr ;
346- }
347- pptr = iptr ;
348- }
349- // compute weight for last quote
350- pd_new_scale ( weight , ldiff , ptr -> expo_ );
351- pd_add ( wptr , wptr , weight , qs -> fact_ );
352- pd_div ( wptr , one , wptr );
353- pd_add ( wsum , wsum , wptr , qs -> fact_ );
354-
355- // bound weights at 1/sqrt(Nquotes) and redeistribute the remaining weight
356- // among the remaining quoters proportional to their weights
357- pd_t wmax [1 ], rnumer [1 ], rdenom [1 ];
358- pd_set ( rnumer , one );
359- pd_new ( rdenom , 0 , 0 );
360- // wmax = 1 / sqrt( numa )
361- pd_new ( wmax , numa , 0 );
362- pd_sqrt ( wmax , wmax , qs -> fact_ );
363- pd_div ( wmax , one , wmax );
364- for ( uint32_t i = 0 ;i != numa ; ++ i ) {
365- wptr = & qs -> weight_ [i ];
366- pd_div ( wptr , wptr , wsum );
367- if ( pd_gt ( wptr , wmax , qs -> fact_ ) ) {
368- pd_set ( wptr , wmax );
369- pd_sub ( rnumer , rnumer , wmax , qs -> fact_ );
370- aidx [i ] = 1 ;
371- } else {
372- pd_add ( rdenom , rdenom , wptr , qs -> fact_ );
373- aidx [i ] = 0 ;
374- }
375- }
376- if ( rdenom -> v_ ) {
377- pd_div ( rnumer , rnumer , rdenom );
378- }
379- for ( uint32_t i = 0 ; i != numa ; ++ i ) {
380- wptr = & qs -> weight_ [ i ];
381- if ( aidx [ i ] == 0 ) {
382- pd_mul ( wptr , wptr , rnumer );
383- }
384- }
385-
386- const pd_t half = { .e_ = -1 , .v_ = 5 };
387-
388- // compute aggregate price as weighted median
389- pd_t iprice [1 ], lprice [1 ], uprice [1 ], q3price [1 ], q1price [1 ], ptile [1 ];
390- pd_new ( ptile , 5 , -1 );
391- wgt_ptile ( iprice , qs -> iprice_ , qs -> weight_ , numa , ptile , qs );
392- pd_adjust ( iprice , ptr -> expo_ , qs -> fact_ );
393- ptr -> agg_ .price_ = iprice -> v_ ;
394-
395- // compute diff in weighted median between upper and lower price bounds
396- pd_t prices [ PC_COMP_SIZE ];
397- pd_t weights [ PC_COMP_SIZE ];
398- // sort upper prices and weights
399- for ( uint32_t i = 0 ; i < numa ; ++ i ) {
400- uint32_t j = i ;
401- for ( ; j > 0 && pd_lt ( & qs -> uprice_ [ i ], & prices [ j - 1 ], qs -> fact_ ); -- j ) { // FIXME: O(N^2)
402- prices [ j ] = prices [ j - 1 ];
403- weights [ j ] = weights [ j - 1 ];
404- }
405- prices [ j ] = qs -> uprice_ [ i ];
406- weights [ j ] = qs -> weight_ [ i ];
407- }
408- wgt_ptile ( uprice , prices , weights , numa , ptile , qs );
409- // sort lower prices and weights
410- for ( uint32_t i = 0 ; i < numa ; ++ i ) {
411- uint32_t j = i ;
412- for ( ; j > 0 && pd_lt ( & qs -> lprice_ [ i ], & prices [ j - 1 ], qs -> fact_ ); -- j ) { // FIXME: O(N^2)
413- prices [ j ] = prices [ j - 1 ];
414- weights [ j ] = weights [ j - 1 ];
415- }
416- prices [ j ] = qs -> lprice_ [ i ];
417- weights [ j ] = qs -> weight_ [ i ];
418- }
419- wgt_ptile ( lprice , prices , weights , numa , ptile , qs );
420-
421- pd_sub ( uprice , uprice , lprice , qs -> fact_ );
422- pd_mul ( uprice , uprice , & half );
423-
424- // compute weighted iqr of prices
425- pd_new ( ptile , 75 , -2 );
426- wgt_ptile ( q3price , qs -> iprice_ , qs -> weight_ , numa , ptile , qs );
427- pd_new ( ptile , 25 , -2 );
428- wgt_ptile ( q1price , qs -> iprice_ , qs -> weight_ , numa , ptile , qs );
429- pd_sub ( q3price , q3price , q1price , qs -> fact_ );
430- pd_mul ( q3price , q3price , & half );
230+ ptr -> last_slot_ = slot ;
231+ ptr -> agg_ .price_ = agg_price ;
232+ ptr -> agg_ .conf_ = (uint64_t )agg_conf ;
431233
432- // take confidence interval as larger
433- pd_t * cptr = pd_gt ( uprice , q3price , qs -> fact_ ) ? uprice : q3price ;
434- pd_adjust ( cptr , ptr -> expo_ , qs -> fact_ );
435- ptr -> agg_ .conf_ = ( uint64_t )( cptr -> v_ );
436234 upd_twap ( ptr , agg_diff , qs );
437- ptr -> agg_ .price_ = agg_price ; // FIXME: OVERRIDE OLD PRICE MODEL
438- ptr -> agg_ .conf_ = (uint64_t )agg_conf ; // FIXME: OVERRIDE OLD PRICE MODEL
439235}
440236
441237#ifdef __cplusplus
0 commit comments