Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix position card avg entry preview calculation so it matches position chart #1670

Merged
merged 3 commits into from
Dec 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions hooks/useAverageEntryPrice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useMemo } from 'react';
import { useRecoilValue } from 'recoil';

import { PositionHistory, PositionSide } from 'queries/futures/types';
import { potentialTradeDetailsState } from 'store/futures';

// Used to calculate the new average entry price of a modified position
const useAverageEntryPrice = (positionHistory?: PositionHistory) => {
const { data: previewTrade } = useRecoilValue(potentialTradeDetailsState);

return useMemo(() => {
if (positionHistory && previewTrade) {
const { avgEntryPrice, side, size } = positionHistory;
const currentSize = side === PositionSide.SHORT ? size.neg() : size;

// If the trade switched sides (long -> short or short -> long), use oracle price
if (currentSize.mul(previewTrade.size).lt(0)) return previewTrade.price;

// If the trade reduced position size on the same side, average entry remains the same
if (previewTrade.size.abs().lt(size)) return avgEntryPrice;

// If the trade increased position size on the same side, calculate new average
const existingValue = avgEntryPrice.mul(size);
const newValue = previewTrade.price.mul(previewTrade.sizeDelta.abs());
const totalValue = existingValue.add(newValue);
return totalValue.div(previewTrade.size.abs());
}
return null;
}, [positionHistory, previewTrade]);
};

export default useAverageEntryPrice;
15 changes: 2 additions & 13 deletions sections/futures/PositionCard/PositionCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { DEFAULT_CRYPTO_DECIMALS } from 'constants/defaults';
import { NO_VALUE } from 'constants/placeholder';
import Connector from 'containers/Connector';
import { useFuturesContext } from 'contexts/FuturesContext';
import useAverageEntryPrice from 'hooks/useAverageEntryPrice';
import useFuturesMarketClosed from 'hooks/useFuturesMarketClosed';
import useSelectedPriceCurrency from 'hooks/useSelectedPriceCurrency';
import { PositionSide } from 'queries/futures/types';
Expand Down Expand Up @@ -73,7 +74,6 @@ const PositionCard: React.FC<PositionCardProps> = () => {
const positionDetails = position?.position ?? null;
const { isFuturesMarketClosed } = useFuturesMarketClosed(marketKey);

const potentialTrade = useRecoilValue(potentialTradeDetailsState);
const positionHistory = useRecoilValue(positionHistoryState);

const [showEditLeverage, setShowEditLeverage] = useState(false);
Expand All @@ -96,18 +96,7 @@ const PositionCard: React.FC<PositionCardProps> = () => {

const { data: previewTradeData } = useRecoilValue(potentialTradeDetailsState);

const modifiedAverage = useMemo(() => {
if (thisPositionHistory && previewTradeData && potentialTrade.data) {
const totalSize = thisPositionHistory.size.add(potentialTrade.data.size);

const existingValue = thisPositionHistory.avgEntryPrice.mul(thisPositionHistory.size);
const newValue = previewTradeData.price.mul(potentialTrade.data.size);
const totalValue = existingValue.add(newValue);

return totalSize.gt(0) ? totalValue.div(totalSize) : null;
}
return null;
}, [thisPositionHistory, previewTradeData, potentialTrade.data]);
const modifiedAverage = useAverageEntryPrice(thisPositionHistory);

const previewData: PositionPreviewData = React.useMemo(() => {
if (positionDetails === null || previewTradeData === null) {
Expand Down
16 changes: 2 additions & 14 deletions sections/futures/PositionChart/PositionChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { useRecoilValue } from 'recoil';
import styled from 'styled-components';

import TVChart from 'components/TVChart';
import useAverageEntryPrice from 'hooks/useAverageEntryPrice';
import { selectMarketAsset } from 'state/futures/selectors';
import { useAppSelector } from 'state/hooks';
import {
positionState,
potentialTradeDetailsState,
futuresTradeInputsState,
positionHistoryState,
futuresAccountTypeState,
openOrdersState,
Expand All @@ -30,19 +30,7 @@ export default function PositionChart() {
return positionHistory[futuresAccountType].find((p) => p.isOpen && p.asset === marketAsset);
}, [positionHistory, marketAsset, futuresAccountType]);

const { nativeSize } = useRecoilValue(futuresTradeInputsState);

const modifiedAverage = useMemo(() => {
if (subgraphPosition && previewTrade && !!nativeSize) {
const totalSize = subgraphPosition.size.add(nativeSize);

const existingValue = subgraphPosition.avgEntryPrice.mul(subgraphPosition.size);
const newValue = previewTrade.price.mul(nativeSize);
const totalValue = existingValue.add(newValue);
return totalValue.div(totalSize);
}
return null;
}, [subgraphPosition, previewTrade, nativeSize]);
const modifiedAverage = useAverageEntryPrice(subgraphPosition);

const activePosition = useMemo(() => {
if (!position?.position) {
Expand Down