Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
1 change: 1 addition & 0 deletions src/pages/portfolio/Portfolio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ const PortfolioPage = () => {
FillsTableColumnKey.Price,
FillsTableColumnKey.Total,
FillsTableColumnKey.Fee,
FillsTableColumnKey.ClosedPnl,
FillsTableColumnKey.Liquidity,
]
}
Expand Down
1 change: 1 addition & 0 deletions src/pages/trade/HorizontalPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ export const HorizontalPanel = ({ isOpen = true, setIsOpen, handleStartResize }:
FillsTableColumnKey.Price,
FillsTableColumnKey.Total,
FillsTableColumnKey.Fee,
FillsTableColumnKey.ClosedPnl,
FillsTableColumnKey.Liquidity,
].filter(isTruthy)
}
Expand Down
4 changes: 4 additions & 0 deletions src/types/indexer/indexerManual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
IndexerPerpetualMarketStatus,
IndexerPerpetualMarketType,
IndexerPerpetualPositionResponseObject,
IndexerPositionSide,
IndexerTradeResponseObject,
IndexerTransferResponseObject,
} from './indexerApiGen';
Expand Down Expand Up @@ -156,6 +157,9 @@ export interface IndexerCompositeFillObject {
clientMetadata?: string | null;
subaccountNumber?: number;
market?: string;
positionSideBefore?: IndexerPositionSide;
positionSizeBefore?: number;
entryPriceBefore?: number;
}

export interface IndexerWsParentSubaccountSubscribedResponse {
Expand Down
46 changes: 46 additions & 0 deletions src/views/tables/FillsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,48 @@ export enum FillsTableColumnKey {
AmountTag = 'Amount-Tag',
Total = 'Total',
Fee = 'Fee',
ClosedPnl = 'ClosedPnl',

// Tablet Only
TypeAmount = 'Type-Amount',
PriceFee = 'Price-Fee',
}

const calculateClosedPnl = (fill: FillTableRow) => {
const fee = parseFloat(fill.fee ?? '0');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of parseFloat, you can use maybeBigNumber

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

used MustNumber instead!


// No position before = opening trade, only fees realize
if (!fill.positionSizeBefore || fill.positionSizeBefore === 0) {
return -fee;
}

// Check if position is reducing (opposite side)
const isReducing =
(fill.positionSideBefore === 'LONG' && fill.side === 'SELL') ||
(fill.positionSideBefore === 'SHORT' && fill.side === 'BUY');

if (!isReducing) {
// Position increasing (same side), only fees realize
return -fee;
}

const size = parseFloat(fill.size ?? '0');
const price = parseFloat(fill.price ?? '0');

// Position reducing - cap closing amount to actual position size
const closingAmount = Math.min(size, fill.positionSizeBefore);

// Calculate P&L only on the closing portion
let closingPnl: number;
if (fill.positionSideBefore === 'LONG') {
closingPnl = (price - fill.entryPriceBefore!) * closingAmount;
} else {
closingPnl = (fill.entryPriceBefore! - price) * closingAmount;
}

return closingPnl - fee;
};

export type FillTableRow = {
marketSummary: Nullable<PerpetualMarketSummary>;
stepSizeDecimals: number;
Expand Down Expand Up @@ -215,6 +251,16 @@ const getFillsTableColumnDef = ({
</TableCell>
),
},
[FillsTableColumnKey.ClosedPnl]: {
columnKey: 'closedPnl',
getCellValue: (row) => calculateClosedPnl(row),
label: stringGetter({ key: STRING_KEYS.CLOSED_PNL }),
renderCell: (row) => (
<TableCell>
<Output type={OutputType.Fiat} value={calculateClosedPnl(row)} />
</TableCell>
),
},
[FillsTableColumnKey.Type]: {
columnKey: 'type',
getCellValue: (row) => row.type,
Expand Down
Loading