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