diff --git a/src/abacus-ts/calculators/funding.ts b/src/abacus-ts/calculators/funding.ts
new file mode 100644
index 000000000..d22cc175b
--- /dev/null
+++ b/src/abacus-ts/calculators/funding.ts
@@ -0,0 +1,21 @@
+import { IndexerHistoricalFundingResponseObject } from '@/types/indexer/indexerApiGen';
+
+import { FundingDirection } from '@/constants/markets';
+
+import { MustBigNumber } from '@/lib/numbers';
+
+export const getDirectionFromFundingRate = (fundingRate: string) => {
+ const fundingRateBN = MustBigNumber(fundingRate);
+
+ return fundingRateBN.isZero()
+ ? FundingDirection.None
+ : fundingRateBN.isPositive()
+ ? FundingDirection.ToShort
+ : FundingDirection.ToLong;
+};
+
+export const mapFundingChartObject = (funding: IndexerHistoricalFundingResponseObject) => ({
+ fundingRate: MustBigNumber(funding.rate).toNumber(),
+ time: new Date(funding.effectiveAt).getTime(),
+ direction: getDirectionFromFundingRate(funding.rate),
+});
diff --git a/src/abacus-ts/rest/funding.ts b/src/abacus-ts/rest/funding.ts
index dc1c4e874..fec23f419 100644
--- a/src/abacus-ts/rest/funding.ts
+++ b/src/abacus-ts/rest/funding.ts
@@ -1,3 +1,5 @@
+import { useMemo } from 'react';
+
import { IndexerHistoricalFundingResponse } from '@/types/indexer/indexerApiGen';
import { useQuery } from '@tanstack/react-query';
@@ -6,13 +8,20 @@ import { timeUnits } from '@/constants/time';
import { useAppSelector } from '@/state/appTypes';
import { getCurrentMarketIdIfTradeable } from '@/state/perpetualsSelectors';
+import { isTruthy } from '@/lib/isTruthy';
+import { MustBigNumber } from '@/lib/numbers';
+import { orEmptyObj } from '@/lib/typeUtils';
+
+import { getDirectionFromFundingRate, mapFundingChartObject } from '../calculators/funding';
+import { selectCurrentMarketInfo } from '../selectors/markets';
import { useIndexerClient } from './lib/useIndexer';
export const useCurrentMarketHistoricalFunding = () => {
const { indexerClient, key: indexerKey } = useIndexerClient();
const currentMarketId = useAppSelector(getCurrentMarketIdIfTradeable);
+ const { nextFundingRate } = orEmptyObj(useAppSelector(selectCurrentMarketInfo));
- return useQuery({
+ const historicalFundingQuery = useQuery({
enabled: Boolean(currentMarketId) && Boolean(indexerClient),
queryKey: ['historicalFunding', currentMarketId, indexerKey],
queryFn: async () => {
@@ -24,9 +33,26 @@ export const useCurrentMarketHistoricalFunding = () => {
const result: IndexerHistoricalFundingResponse =
await indexerClient.markets.getPerpetualMarketHistoricalFunding(currentMarketId);
- return result.historicalFunding;
+
+ return result.historicalFunding.reverse().map(mapFundingChartObject);
},
refetchInterval: timeUnits.hour,
staleTime: timeUnits.hour,
});
+
+ const data = useMemo(() => {
+ return [
+ ...(historicalFundingQuery.data ?? []),
+ nextFundingRate != null && {
+ fundingRate: MustBigNumber(nextFundingRate).toNumber(),
+ time: Date.now(),
+ direction: getDirectionFromFundingRate(nextFundingRate),
+ },
+ ].filter(isTruthy);
+ }, [historicalFundingQuery.data, nextFundingRate]);
+
+ return {
+ ...historicalFundingQuery,
+ data,
+ };
};
diff --git a/src/views/charts/FundingChart/index.tsx b/src/views/charts/FundingChart/index.tsx
index ff2104586..64de28a1a 100644
--- a/src/views/charts/FundingChart/index.tsx
+++ b/src/views/charts/FundingChart/index.tsx
@@ -1,8 +1,8 @@
import { useState } from 'react';
+import { BonsaiHooks } from '@/abacus-ts/ontology';
import { curveMonotoneX, curveStepAfter } from '@visx/curve';
import type { TooltipContextType } from '@visx/xychart';
-import { shallowEqual } from 'react-redux';
import styled, { css } from 'styled-components';
import { ButtonSize } from '@/constants/buttons';
@@ -22,9 +22,6 @@ import { ToggleGroup } from '@/components/ToggleGroup';
import { AxisLabelOutput } from '@/components/visx/AxisLabelOutput';
import { TimeSeriesChart } from '@/components/visx/TimeSeriesChart';
-import { useAppSelector } from '@/state/appTypes';
-import { calculateFundingRateHistory } from '@/state/perpetualsCalculators';
-
import { MustBigNumber } from '@/lib/numbers';
import { FundingChartTooltipContent } from './Tooltip';
@@ -49,7 +46,7 @@ export const FundingChart = ({ selectedLocale }: ElementProps) => {
const stringGetter = useStringGetter();
// Chart data
- const data = useAppSelector(calculateFundingRateHistory, shallowEqual);
+ const { data, isLoading, isError } = BonsaiHooks.useCurrentMarketHistoricalFunding();
const latestDatum = data[data.length - 1];
@@ -129,7 +126,17 @@ export const FundingChart = ({ selectedLocale }: ElementProps) => {
onTooltipContext={(ttContext) => setTooltipContext(ttContext)}
minZoomDomain={FUNDING_RATE_TIME_RESOLUTION * 4}
numGridLines={1}
- slotEmpty={