Skip to content

Commit a9845bb

Browse files
committed
oracle: remove old aggregation logic
1 parent 4e0fd42 commit a9845bb

File tree

4 files changed

+13
-217
lines changed

4 files changed

+13
-217
lines changed

program/src/oracle/test_oracle.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,7 @@ Test( oracle, upd_aggregate ) {
656656
upd_aggregate( px, 1001, 2 );
657657
cr_assert( px->agg_.price_ == 145 );
658658
cr_assert( px->agg_.conf_ == 55 );
659-
cr_assert( px->twap_.val_ == 108 );
659+
cr_assert( px->twap_.val_ == 106 );
660660
cr_assert( px->twac_.val_ == 16 );
661661
cr_assert( px->num_qt_ == 2 );
662662
cr_assert( px->timestamp_ == 2 );
@@ -675,8 +675,8 @@ Test( oracle, upd_aggregate ) {
675675
upd_aggregate( px, 1001, 3 );
676676
cr_assert( px->agg_.price_ == 200 );
677677
cr_assert( px->agg_.conf_ == 90 );
678-
cr_assert( px->twap_.val_ == 116 );
679-
cr_assert( px->twac_.val_ == 22 );
678+
cr_assert( px->twap_.val_ == 114 );
679+
cr_assert( px->twac_.val_ == 23 );
680680
cr_assert( px->num_qt_ == 3 );
681681
cr_assert( px->timestamp_ == 3 );
682682
cr_assert( px->prev_slot_ == 1000 );
@@ -695,8 +695,8 @@ Test( oracle, upd_aggregate ) {
695695
upd_aggregate( px, 1001, 4 );
696696
cr_assert( px->agg_.price_ == 245 );
697697
cr_assert( px->agg_.conf_ == 85 );
698-
cr_assert( px->twap_.val_ == 124 );
699-
cr_assert( px->twac_.val_ == 27 );
698+
cr_assert( px->twap_.val_ == 125 );
699+
cr_assert( px->twac_.val_ == 28 );
700700
cr_assert( px->last_slot_ == 1001 );
701701
cr_assert( px->num_qt_ == 4 );
702702
cr_assert( px->timestamp_ == 4 );

program/src/oracle/upd_aggregate.h

Lines changed: 6 additions & 210 deletions
Original file line numberDiff line numberDiff line change
@@ -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
181145
static 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

pyth/tests/qset/36.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"exponent":-8,"price":0,"conf":0,"status":"unknown"}
1+
{"exponent":-8,"price":1002000000,"conf":48998000000,"status":"trading"}

pyth/tests/qset/39.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"exponent":-8,"price":0,"conf":0,"status":"unknown"}
1+
{"exponent":-8,"price":115000000,"conf":94900000,"status":"trading"}

0 commit comments

Comments
 (0)