Merge PR 'Replace weighted average to weighted median. #173' into main

This commit is contained in:
Reckless_Satoshi 2022-06-29 02:42:31 -07:00
commit 6952bedbf6
No known key found for this signature in database
GPG Key ID: 9C4585B561315571

View File

@ -143,16 +143,52 @@ def compute_premium_percentile(order):
return round(np.sum(rates < order_rate) / len(rates), 2) return round(np.sum(rates < order_rate) / len(rates), 2)
def weighted_median(values, sample_weight=None, quantiles= 0.5, values_sorted=False):
"""Very close to numpy.percentile, but it supports weights.
NOTE: quantiles should be in [0, 1]!
:param values: numpy.array with data
:param quantiles: array-like with many quantiles needed. For weighted median 0.5
:param sample_weight: array-like of the same length as `array`
:param values_sorted: bool, if True, then will avoid sorting of
initial array assuming array is already sorted
:return: numpy.array with computed quantiles.
"""
values = np.array(values)
quantiles = np.array(quantiles)
if sample_weight is None:
sample_weight = np.ones(len(values))
sample_weight = np.array(sample_weight)
assert np.all(quantiles >= 0) and np.all(quantiles <= 1), \
'quantiles should be in [0, 1]'
if not values_sorted:
sorter = np.argsort(values)
values = values[sorter]
sample_weight = sample_weight[sorter]
weighted_quantiles = np.cumsum(sample_weight) - 0.5 * sample_weight
weighted_quantiles -= weighted_quantiles[0]
weighted_quantiles /= weighted_quantiles[-1]
return np.interp(quantiles, weighted_quantiles, values)
def compute_avg_premium(queryset): def compute_avg_premium(queryset):
weighted_premiums = [] premiums = []
volumes = [] volumes = []
# We exclude BTC, as LN <-> BTC swap premiums should not be mixed with FIAT. # We exclude BTC, as LN <-> BTC swap premiums should not be mixed with FIAT.
for tick in queryset.exclude(currency=1000): for tick in queryset.exclude(currency=1000):
weighted_premiums.append(tick.premium * tick.volume) premiums.append(float(tick.premium))
volumes.append(tick.volume) volumes.append(float(tick.volume))
total_volume = sum(volumes) total_volume = sum(volumes)
# Avg_premium is the weighted average of the premiums by volume
avg_premium = sum(weighted_premiums) / total_volume # weighted_median_premium is the weighted median of the premiums by volume
return avg_premium, total_volume
weighted_median_premium = weighted_median(values=premiums,
sample_weight=volumes,
quantiles=0.5,
values_sorted=False)
return weighted_median_premium, total_volume