-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathuseSpreadModel.ts
97 lines (83 loc) · 3.24 KB
/
useSpreadModel.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import { useMemo } from 'react';
import WAD from '@exactly/lib/esm/fixed-point-math/WAD';
import baseRate from '@exactly/lib/esm/interest-rate-model/baseRate';
import fixedRate from '@exactly/lib/esm/interest-rate-model/fixedRate';
import fixedUtilization from '@exactly/lib/esm/interest-rate-model/fixedUtilization';
import floatingRate from '@exactly/lib/esm/interest-rate-model/floatingRate';
import floatingUtilization from '@exactly/lib/esm/interest-rate-model/floatingUtilization';
import globalUtilization from '@exactly/lib/esm/interest-rate-model/globalUtilization';
import useAccountData from './useAccountData';
import useIRM from './useIRM';
export const MAX = 1;
export const INTERVAL = 0.005;
const levels = 8;
export default function useSpreadModel(symbol: string) {
const { marketAccount } = useAccountData(symbol);
const irm = useIRM(symbol);
const data = useMemo(() => {
if (!marketAccount || !irm) {
return [];
}
const {
maxFuturePools,
fixedPools,
totalFloatingBorrowAssets,
totalFloatingDepositAssets,
floatingBackupBorrowed,
} = marketAccount;
const uFloating = floatingUtilization(totalFloatingDepositAssets, totalFloatingBorrowAssets);
const uGlobal = globalUtilization(totalFloatingDepositAssets, totalFloatingBorrowAssets, floatingBackupBorrowed);
const pools = Object.fromEntries(fixedPools.map((pool) => [String(pool.maturity), pool]));
const maturities = fixedPools.map(({ maturity }) => Number(maturity));
const end = Math.max(...maturities);
const now = Math.floor(Date.now() / 1000);
const steps = MAX / INTERVAL;
const points: Record<string, number | number[]>[] = [];
const base = baseRate(uFloating, uGlobal, irm);
for (const date of [
...maturities,
...Array.from({ length: Number(steps) }).map((_, i) => Math.floor(now + i * ((end - now) / steps))),
].sort()) {
const extend: Record<string, number | number[]> = {};
if (pools[date]) {
extend.rate =
Number(
fixedRate(
date,
maxFuturePools,
fixedUtilization(pools[date].supplied, pools[date].borrowed, totalFloatingDepositAssets),
uFloating,
uGlobal,
irm,
now,
base,
),
) / 1e18;
extend.highlight = 1;
} else if (date === now) {
extend.rate = Number(floatingRate(uFloating, uGlobal, irm)) / 1e18;
extend.highlight = 1;
}
points.push({
date: date,
...Object.fromEntries(
[...Array(levels)].map((_, i, { length }) => {
const z = WAD - (BigInt(i) * WAD) / BigInt(length);
return [
`area${i}`,
date <= now
? [Number(base) / 1e18, Number(base) / 1e18]
: [
Number(fixedRate(date, maxFuturePools, 0n, uFloating, uGlobal, irm, now, base, -z)) / 1e18,
Number(fixedRate(date, maxFuturePools, 0n, uFloating, uGlobal, irm, now, base, z)) / 1e18,
],
];
}),
),
...extend,
});
}
return points;
}, [irm, marketAccount]);
return { data, levels, loading: data.length === 0 };
}