Skip to content

feat: Trade history#2087

Merged
dwjanus merged 6 commits into
mainfrom
dwj/eng-1829-trade-history
Feb 25, 2026
Merged

feat: Trade history#2087
dwjanus merged 6 commits into
mainfrom
dwj/eng-1829-trade-history

Conversation

@dwjanus

@dwjanus dwjanus commented Feb 24, 2026

Copy link
Copy Markdown
Contributor

Changes

  • add hooks, calculator, and app state for tradeHistory api endpoint
  • refactor initial share pnl hook and position table usage
  • replace fills table from Trades tab in portfolio/history with new trade history data
  • configure share action to use trade history data

Issue

Eng-1839

Screenshots/Recordings (Optional)

Screenshot 2026-02-24 at 5 04 29 PM

@dwjanus dwjanus requested a review from a team as a code owner February 24, 2026 22:07
@linear

linear Bot commented Feb 24, 2026

Copy link
Copy Markdown

@vercel

vercel Bot commented Feb 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
v4-staging Ready Ready Preview, Comment Feb 25, 2026 10:18pm
v4-testnet Ready Ready Preview, Comment Feb 25, 2026 10:18pm

Request Review

@wiz-55df730c58

wiz-55df730c58 Bot commented Feb 24, 2026

Copy link
Copy Markdown

Wiz Scan Summary

⚠️ Many findings detected
Many findings were detected, but only a subset of the findings are displayed inline due to API constraints. To view all findings inline, please click here.
Scanner Findings
Vulnerability Finding Vulnerabilities 23 High 18 Medium 6 Low
Data Finding Sensitive Data -
Secret Finding Secrets -
IaC Misconfiguration IaC Misconfigurations -
SAST Finding SAST Findings -
Software Management Finding Software Management Findings -
Total 23 High 18 Medium 6 Low

View scan details in Wiz

To detect these findings earlier in the dev lifecycle, try using Wiz Code VS Code Extension.

@dwjanus dwjanus changed the title feat: Trade history (eng-1839) feat: Trade history Feb 24, 2026
@dwjanus dwjanus requested a review from dankim214 February 24, 2026 22:32

@dankim214 dankim214 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

looks good!

dont have the trade history to properly test this but going off the screenshot it looks like the we have TradeHistoryList and TradeHistoryTable now, which is being used in what? i dont see <TradeHistoryList /> being rendered

Comment thread src/bonsai/calculators/trades.ts Outdated
Comment thread src/bonsai/rest/tradeHistory.ts Outdated
Comment on lines +27 to +28
data.wallet!,
data.subaccount!,

@dankim214 dankim214 Feb 25, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

do we need this assertion? i wouldve thought the above typeguards do that for us

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

we do for data.wallet, the subaccount assertion is redundant but we do it that way in other areas like orders.ts so i figured id do the same

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

hmm totally fine to do in a separate PR (or even just going forward) but generally could we avoid asserting like this unless its an escape hatch situation?

think assertion in this case is only required because we did nested access for wallet. if we do something like

(indexerClient, { wallet, subaccount, isPerpsGeoRestricted}) => {
      if (wallet == null || data.subaccount == null || data.isPerpsGeoRestricted) {
        return null
      }
      // From this point on wallet and subaccount will be defined
}

and i dont think how much contextual value the variable data is providing

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

100% agree, imo might be worth doing in a separate pr and cleaning up all similar logic at that time

Comment thread src/bonsai/types/summaryTypes.ts
Comment thread src/constants/dialogs.ts Outdated
marketId?: string;
isLong: boolean;
isCross: boolean;
shareType?: 'open' | 'close' | 'liquidated' | 'partialClose' | 'extend' | undefined;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: can we pull this into an enum

Comment thread src/lib/tradeHistoryHelpers.ts
liquidationPrice: trade.liquidationPrice,
};

const openShareDialog = () => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: useCallback

Comment thread src/views/tables/TradeHistoryTable.tsx Outdated
getCellValue: (row) => row.createdAt,
label: stringGetter({ key: STRING_KEYS.TIME }),
renderCell: ({ createdAt }) => (
<Output

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

could we use the new DateAgeOutput component (so we could switch between time/date) similar to FillsTable

Comment thread src/views/tables/TradeHistoryTable.tsx
Comment thread src/views/tables/TradeHistoryTable.tsx Outdated
getCellValue: (row) => row.marketId,
label: stringGetter({ key: STRING_KEYS.MARKET }),
renderCell: ({ marketSummary }) => (
<TableCell

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

can use MarketSummaryTableCell

Comment thread src/views/tables/TradeHistoryTable.tsx Outdated
label: stringGetter({ key: STRING_KEYS.SIDE }),
renderCell: ({ side }) =>
side != null ? (
<$Side side={side}>{side === IndexerOrderSide.BUY ? 'Buy' : 'Sell'}</$Side>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

can use <OrderSideTag />

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We actually dont even show this column in the ui so im gonna delete it

dankim214
dankim214 previously approved these changes Feb 25, 2026

@dankim214 dankim214 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

looks good! just couple nits

Comment thread src/bonsai/calculators/trades.ts Outdated
liveTrades: IndexerCompositeTradeHistoryObject[] | undefined
): SubaccountTrade[] {
const getTradesById = (data: IndexerCompositeTradeHistoryObject[]) => {
const tradesWithIds = data.filter((trade) => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: (trade): trade is TradeType & { id: string }

can typeguard here so we don't have to assert below

Comment thread src/bonsai/rest/tradeHistory.ts Outdated
Comment on lines +27 to +28
data.wallet!,
data.subaccount!,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

hmm totally fine to do in a separate PR (or even just going forward) but generally could we avoid asserting like this unless its an escape hatch situation?

think assertion in this case is only required because we did nested access for wallet. if we do something like

(indexerClient, { wallet, subaccount, isPerpsGeoRestricted}) => {
      if (wallet == null || data.subaccount == null || data.isPerpsGeoRestricted) {
        return null
      }
      // From this point on wallet and subaccount will be defined
}

and i dont think how much contextual value the variable data is providing

? 'liquidated'
: undefined;

const prevSize = !!trade.prevSize && !!trade.price ? trade.prevSize * trade.price : undefined;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

gotcha- not to be pedantic, but could we call this something like prevSizeDollar or just something different than prevSize since this one is a dollar amount and not size amount

@dwjanus dwjanus merged commit 08aec1a into main Feb 25, 2026
14 checks passed
@dwjanus dwjanus deleted the dwj/eng-1829-trade-history branch February 25, 2026 22:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants