fetch perp trade history from db
This commit is contained in:
parent
a019c06b28
commit
b2f6eece1c
|
@ -9,6 +9,10 @@ import { LinkButton } from './Button'
|
|||
import { useSortableData } from '../hooks/useSortableData'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
|
||||
function getTradeTimestamp(trade) {
|
||||
return trade?.timestamp ? trade.timestamp.toNumber() : trade.loadTimestamp
|
||||
}
|
||||
|
||||
const TradeHistoryTable = () => {
|
||||
const { asPath } = useRouter()
|
||||
const tradeHistory = useTradeHistory()
|
||||
|
@ -42,7 +46,7 @@ const TradeHistoryTable = () => {
|
|||
<Tr className="text-th-fgd-3 text-xs">
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
className={`px-6 py-2 text-left font-normal`}
|
||||
>
|
||||
<LinkButton
|
||||
className="flex items-center no-underline"
|
||||
|
@ -60,7 +64,7 @@ const TradeHistoryTable = () => {
|
|||
/>
|
||||
</LinkButton>
|
||||
</Th>
|
||||
<Th scope="col" className="px-6 py-3 text-left font-normal">
|
||||
<Th scope="col" className="px-6 py-2 text-left font-normal">
|
||||
<LinkButton
|
||||
className="flex items-center no-underline"
|
||||
onClick={() => requestSort('side')}
|
||||
|
@ -77,7 +81,7 @@ const TradeHistoryTable = () => {
|
|||
/>
|
||||
</LinkButton>
|
||||
</Th>
|
||||
<Th scope="col" className="px-6 py-3 text-left font-normal">
|
||||
<Th scope="col" className="px-6 py-2 text-left font-normal">
|
||||
<LinkButton
|
||||
className="flex items-center no-underline"
|
||||
onClick={() => requestSort('size')}
|
||||
|
@ -94,7 +98,7 @@ const TradeHistoryTable = () => {
|
|||
/>
|
||||
</LinkButton>
|
||||
</Th>
|
||||
<Th scope="col" className="px-6 py-3 text-left font-normal">
|
||||
<Th scope="col" className="px-6 py-2 text-left font-normal">
|
||||
<LinkButton
|
||||
className="flex items-center no-underline"
|
||||
onClick={() => requestSort('price')}
|
||||
|
@ -111,7 +115,7 @@ const TradeHistoryTable = () => {
|
|||
/>
|
||||
</LinkButton>
|
||||
</Th>
|
||||
<Th scope="col" className="px-6 py-3 text-left font-normal">
|
||||
<Th scope="col" className="px-6 py-2 text-left font-normal">
|
||||
<LinkButton
|
||||
className="flex items-center no-underline"
|
||||
onClick={() => requestSort('value')}
|
||||
|
@ -128,7 +132,7 @@ const TradeHistoryTable = () => {
|
|||
/>
|
||||
</LinkButton>
|
||||
</Th>
|
||||
<Th scope="col" className="px-6 py-3 text-left font-normal">
|
||||
<Th scope="col" className="px-6 py-2 text-left font-normal">
|
||||
<LinkButton
|
||||
className="flex items-center no-underline"
|
||||
onClick={() => requestSort('liquidity')}
|
||||
|
@ -145,7 +149,7 @@ const TradeHistoryTable = () => {
|
|||
/>
|
||||
</LinkButton>
|
||||
</Th>
|
||||
<Th scope="col" className="px-6 py-3 text-left font-normal">
|
||||
<Th scope="col" className="px-6 py-2 text-left font-normal">
|
||||
<LinkButton
|
||||
className="flex items-center no-underline"
|
||||
onClick={() => requestSort('feeCost')}
|
||||
|
@ -162,7 +166,7 @@ const TradeHistoryTable = () => {
|
|||
/>
|
||||
</LinkButton>
|
||||
</Th>
|
||||
<Th scope="col" className="px-6 py-3 text-left font-normal">
|
||||
<Th scope="col" className="px-6 py-2 text-left font-normal">
|
||||
<LinkButton
|
||||
className="flex items-center no-underline"
|
||||
onClick={() => requestSort('loadTimestamp')}
|
||||
|
@ -184,12 +188,12 @@ const TradeHistoryTable = () => {
|
|||
<Tbody>
|
||||
{items.map((trade, index) => (
|
||||
<Tr
|
||||
key={`${trade.timestamp.toNumber()}`}
|
||||
key={`${getTradeTimestamp(trade)}`}
|
||||
className={`border-b border-th-bkg-3
|
||||
${index % 2 === 0 ? `bg-th-bkg-3` : `bg-th-bkg-2`}
|
||||
`}
|
||||
>
|
||||
<Td className="px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
<Td className="px-6 py-2 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
alt=""
|
||||
|
@ -203,25 +207,25 @@ const TradeHistoryTable = () => {
|
|||
<div>{trade.marketName}</div>
|
||||
</div>
|
||||
</Td>
|
||||
<Td className="px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
<Td className="px-6 py-2 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
<SideBadge side={trade.side} />
|
||||
</Td>
|
||||
<Td className="px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
<Td className="px-6 py-2 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
{trade.size}
|
||||
</Td>
|
||||
<Td className="px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
<Td className="px-6 py-2 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
{trade.price}
|
||||
</Td>
|
||||
<Td className="px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
<Td className="px-6 py-2 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
${trade.value.toFixed(2)}
|
||||
</Td>
|
||||
<Td className="px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
<Td className="px-6 py-2 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
{trade.liquidity}
|
||||
</Td>
|
||||
<Td className="px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
<Td className="px-6 py-2 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
${trade.feeCost}
|
||||
</Td>
|
||||
<Td className="px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
<Td className="px-6 py-2 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
{trade.loadTimestamp || trade.timestamp
|
||||
? renderTradeDateTime(
|
||||
trade.loadTimestamp || trade.timestamp
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {
|
||||
getMarketIndexBySymbol,
|
||||
getMarketByPublicKey,
|
||||
MangoGroup,
|
||||
} from '@blockworks-foundation/mango-client'
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
|
@ -7,30 +7,33 @@ import useMangoStore from '../stores/useMangoStore'
|
|||
|
||||
const byTimestamp = (a, b) => {
|
||||
return (
|
||||
new Date(b.loadTimestamp || b.timestamp.toNumber()).getTime() -
|
||||
new Date(a.loadTimestamp || a.timestamp.toNumber()).getTime()
|
||||
new Date(b.loadTimestamp || b.timestamp.toNumber() * 1000).getTime() -
|
||||
new Date(a.loadTimestamp || a.timestamp.toNumber() * 1000).getTime()
|
||||
)
|
||||
}
|
||||
|
||||
const reverseSide = (side) => (side === 'buy' ? 'sell' : 'buy')
|
||||
|
||||
function getPerpMarketName(event) {
|
||||
const mangoGroupConfig = useMangoStore.getState().selectedMangoGroup.config
|
||||
|
||||
let marketName
|
||||
if (!event.marketName) {
|
||||
const marketInfo = getMarketByPublicKey(mangoGroupConfig, event.address)
|
||||
marketName = marketInfo.name
|
||||
}
|
||||
return event.marketName || marketName
|
||||
}
|
||||
|
||||
const parsedPerpEvent = (
|
||||
mangoGroup: MangoGroup,
|
||||
mangoAccountPk: PublicKey,
|
||||
event
|
||||
) => {
|
||||
const mangoGroupConfig = useMangoStore.getState().selectedMangoGroup.config
|
||||
const marketIndex = getMarketIndexBySymbol(
|
||||
mangoGroupConfig,
|
||||
event.marketName.split(/-|\//)[0]
|
||||
)
|
||||
const perpMarketInfo = mangoGroup.perpMarkets[marketIndex]
|
||||
const maker = event.maker.equals(mangoAccountPk)
|
||||
const maker = event.maker.toString() === mangoAccountPk.toString()
|
||||
const orderId = maker ? event.makerOrderId : event.takerOrderId
|
||||
const value = event.quantity * event.price
|
||||
const feeRate = maker
|
||||
? perpMarketInfo.makerFee.toNumber()
|
||||
: perpMarketInfo.takerFee.toNumber()
|
||||
const feeRate = maker ? event.makerFee : event.takerFee
|
||||
const side = maker ? reverseSide(event.takerSide) : event.takerSide
|
||||
|
||||
return {
|
||||
|
@ -42,6 +45,7 @@ const parsedPerpEvent = (
|
|||
value,
|
||||
feeCost: (feeRate * value).toFixed(4),
|
||||
side,
|
||||
marketName: getPerpMarketName(event),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,7 +106,13 @@ export const useTradeHistory = () => {
|
|||
if (mangoAccountFills && mangoAccountFills.length > 0) {
|
||||
const newFills = mangoAccountFills.filter(
|
||||
(fill) =>
|
||||
!tradeHistory.flat().find((t) => t.orderId === fill.orderId.toString())
|
||||
!tradeHistory.flat().find((t) => {
|
||||
if (t.orderId) {
|
||||
return t.orderId === fill.orderId?.toString()
|
||||
} else {
|
||||
return t.seqNum === fill.seqNum.toString()
|
||||
}
|
||||
})
|
||||
)
|
||||
const newTradeHistory = [...newFills, ...tradeHistory]
|
||||
if (newFills.length > 0 && newTradeHistory.length !== allTrades.length) {
|
||||
|
|
|
@ -371,7 +371,6 @@ const useMangoStore = create<MangoStore>((set, get) => ({
|
|||
})
|
||||
},
|
||||
async fetchTradeHistory(mangoAccount = null) {
|
||||
// TODO fetch perps open orders account from trade history service
|
||||
const selectedMangoAccount =
|
||||
mangoAccount || get().selectedMangoAccount.current
|
||||
const set = get().set
|
||||
|
@ -384,7 +383,13 @@ const useMangoStore = create<MangoStore>((set, get) => ({
|
|||
const publicKeys = openOrdersAccounts.map((act) =>
|
||||
act.publicKey.toString()
|
||||
)
|
||||
const results = await Promise.all(
|
||||
const perpHistory = await fetch(
|
||||
`https://event-history-api.herokuapp.com/perp_trades/${selectedMangoAccount.publicKey.toString()}`
|
||||
)
|
||||
let parsedPerpHistory = await perpHistory.json()
|
||||
parsedPerpHistory = parsedPerpHistory?.data || []
|
||||
|
||||
const serumHistory = await Promise.all(
|
||||
publicKeys.map(async (pk) => {
|
||||
const response = await fetch(
|
||||
`https://stark-fjord-45757.herokuapp.com/trades/open_orders/${pk.toString()}`
|
||||
|
@ -394,7 +399,7 @@ const useMangoStore = create<MangoStore>((set, get) => ({
|
|||
})
|
||||
)
|
||||
set((state) => {
|
||||
state.tradeHistory = results
|
||||
state.tradeHistory = [...serumHistory, ...parsedPerpHistory]
|
||||
})
|
||||
},
|
||||
async updateOpenOrders() {
|
||||
|
|
Loading…
Reference in New Issue