chore(trading): update fee factor with discount calculation (#5138)
This commit is contained in:
parent
cc6629ad27
commit
c8e624eaba
@ -7,7 +7,7 @@ import {
|
|||||||
NetworkParams,
|
NetworkParams,
|
||||||
} from '@vegaprotocol/network-parameters';
|
} from '@vegaprotocol/network-parameters';
|
||||||
import { useMarketList } from '@vegaprotocol/markets';
|
import { useMarketList } from '@vegaprotocol/markets';
|
||||||
import { formatNumber } from '@vegaprotocol/utils';
|
import { formatNumber, formatNumberRounded } from '@vegaprotocol/utils';
|
||||||
import { useDiscountProgramsQuery, useFeesQuery } from './__generated__/Fees';
|
import { useDiscountProgramsQuery, useFeesQuery } from './__generated__/Fees';
|
||||||
import { FeeCard } from './fees-card';
|
import { FeeCard } from './fees-card';
|
||||||
import { MarketFees } from './market-fees';
|
import { MarketFees } from './market-fees';
|
||||||
@ -284,7 +284,7 @@ export const CurrentVolume = ({
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Stat
|
<Stat
|
||||||
value={formatNumber(windowLengthVolume)}
|
value={formatNumberRounded(new BigNumber(windowLengthVolume))}
|
||||||
text={t('Past %s epochs', epochs.toString())}
|
text={t('Past %s epochs', epochs.toString())}
|
||||||
/>
|
/>
|
||||||
{requiredForNextTier > 0 && (
|
{requiredForNextTier > 0 && (
|
||||||
|
74
apps/trading/components/fees-container/utils.spec.ts
Normal file
74
apps/trading/components/fees-container/utils.spec.ts
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import BigNumber from 'bignumber.js';
|
||||||
|
import { getAdjustedFee } from './utils';
|
||||||
|
|
||||||
|
describe('getAdjustedFee', () => {
|
||||||
|
it('simple', () => {
|
||||||
|
const volumeDiscount = 0.5;
|
||||||
|
const referralDiscount = 0.5;
|
||||||
|
|
||||||
|
const infraFee = 0.1;
|
||||||
|
const makerFee = 0.1;
|
||||||
|
const liqFee = 0.1;
|
||||||
|
|
||||||
|
const fees = [
|
||||||
|
new BigNumber(infraFee),
|
||||||
|
new BigNumber(makerFee),
|
||||||
|
new BigNumber(liqFee),
|
||||||
|
];
|
||||||
|
|
||||||
|
const discounts = [
|
||||||
|
new BigNumber(volumeDiscount),
|
||||||
|
new BigNumber(referralDiscount),
|
||||||
|
];
|
||||||
|
|
||||||
|
// 1 - 0.5 - 0.5
|
||||||
|
const v = new BigNumber(1).minus(new BigNumber(volumeDiscount));
|
||||||
|
|
||||||
|
// 1 - 0.5 = 0.5
|
||||||
|
const r = new BigNumber(1).minus(new BigNumber(referralDiscount));
|
||||||
|
|
||||||
|
// 0.5 * 0.5 = 0.25
|
||||||
|
// 1 - 0.25 = 0.75
|
||||||
|
const factor = new BigNumber(1).minus(v.times(r));
|
||||||
|
|
||||||
|
// 0.1 + 0.1 + 0.1 = 0.3
|
||||||
|
const totalFees = fees.reduce((sum, x) => sum.plus(x), new BigNumber(0));
|
||||||
|
|
||||||
|
// 0.3 * 0.75 = 0.225
|
||||||
|
const expected = new BigNumber(totalFees).times(factor).toNumber();
|
||||||
|
|
||||||
|
expect(getAdjustedFee(fees, discounts)).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('combines discount factors multiplicativly', () => {
|
||||||
|
const volumeDiscount = 0.4;
|
||||||
|
const referralDiscount = 0.1;
|
||||||
|
|
||||||
|
const infraFee = 0.0005;
|
||||||
|
const makerFee = 0.0002;
|
||||||
|
const liqFee = 0.01;
|
||||||
|
|
||||||
|
const fees = [
|
||||||
|
new BigNumber(infraFee),
|
||||||
|
new BigNumber(makerFee),
|
||||||
|
new BigNumber(liqFee),
|
||||||
|
];
|
||||||
|
|
||||||
|
const discounts = [
|
||||||
|
new BigNumber(volumeDiscount),
|
||||||
|
new BigNumber(referralDiscount),
|
||||||
|
];
|
||||||
|
|
||||||
|
// formula for calculating adjusted fees
|
||||||
|
const v = new BigNumber(1).minus(new BigNumber(volumeDiscount));
|
||||||
|
const r = new BigNumber(1).minus(new BigNumber(referralDiscount));
|
||||||
|
const factor = new BigNumber(1).minus(v.times(r));
|
||||||
|
|
||||||
|
// summed fees
|
||||||
|
const totalFees = fees.reduce((sum, x) => sum.plus(x), new BigNumber(0));
|
||||||
|
|
||||||
|
const expected = new BigNumber(totalFees).times(factor).toNumber();
|
||||||
|
|
||||||
|
expect(getAdjustedFee(fees, discounts)).toBe(expected);
|
||||||
|
});
|
||||||
|
});
|
@ -88,14 +88,18 @@ export const getReferralBenefitTier = (
|
|||||||
/**
|
/**
|
||||||
* Given a set of fees and a set of discounts return
|
* Given a set of fees and a set of discounts return
|
||||||
* the adjusted fee factor
|
* the adjusted fee factor
|
||||||
|
*
|
||||||
|
* Formula for calculating the adjusted fees
|
||||||
|
* total_discount_factor = 1 - (1 - volumeDiscount) * (1 - referralDiscount)
|
||||||
*/
|
*/
|
||||||
export const getAdjustedFee = (fees: BigNumber[], discounts: BigNumber[]) => {
|
export const getAdjustedFee = (fees: BigNumber[], discounts: BigNumber[]) => {
|
||||||
const totalFee = fees.reduce((sum, f) => sum.plus(f), new BigNumber(0));
|
const totalFee = fees.reduce((sum, f) => sum.plus(f), new BigNumber(0));
|
||||||
const totalDiscount = discounts.reduce(
|
|
||||||
(sum, d) => sum.plus(d),
|
const combinedFactors = discounts.reduce((acc, d) => {
|
||||||
new BigNumber(0)
|
return acc.times(new BigNumber(1).minus(d));
|
||||||
);
|
}, new BigNumber(1));
|
||||||
return totalFee
|
|
||||||
.times(BigNumber.max(0, new BigNumber(1).minus(totalDiscount)))
|
const totalFactor = new BigNumber(1).minus(combinedFactors);
|
||||||
.toNumber();
|
|
||||||
|
return totalFee.times(BigNumber.max(0, totalFactor)).toNumber();
|
||||||
};
|
};
|
||||||
|
@ -179,3 +179,33 @@ export const toNumberParts = (
|
|||||||
export const isNumeric = (
|
export const isNumeric = (
|
||||||
value?: string | number | BigNumber | bigint | null
|
value?: string | number | BigNumber | bigint | null
|
||||||
): value is NonNullable<number | string> => /^-?\d*\.?\d+$/.test(String(value));
|
): value is NonNullable<number | string> => /^-?\d*\.?\d+$/.test(String(value));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format a number greater than 1 million with m for million, b for billion
|
||||||
|
* and t for trillion
|
||||||
|
*/
|
||||||
|
export const formatNumberRounded = (num: BigNumber) => {
|
||||||
|
let value = '';
|
||||||
|
|
||||||
|
const format = (divisor: string) => {
|
||||||
|
const result = num.dividedBy(divisor);
|
||||||
|
return result.isInteger() ? result.toString() : result.toFixed(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (num.isGreaterThan(new BigNumber('1e14'))) {
|
||||||
|
value = '>100t';
|
||||||
|
} else if (num.isGreaterThanOrEqualTo(new BigNumber('1e12'))) {
|
||||||
|
// Trillion
|
||||||
|
value = `${format('1e12')}t`;
|
||||||
|
} else if (num.isGreaterThanOrEqualTo(new BigNumber('1e9'))) {
|
||||||
|
// Billion
|
||||||
|
value = `${format('1e9')}b`;
|
||||||
|
} else if (num.isGreaterThanOrEqualTo(new BigNumber('1e6'))) {
|
||||||
|
// Million
|
||||||
|
value = `${format('1e6')}m`;
|
||||||
|
} else {
|
||||||
|
value = formatNumber(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user