2021-07-24 11:12:52 -07:00
|
|
|
import {
|
|
|
|
getMarketIndexBySymbol,
|
|
|
|
MangoGroup,
|
|
|
|
} from '@blockworks-foundation/mango-client'
|
|
|
|
import { PublicKey } from '@solana/web3.js'
|
2021-04-05 07:32:11 -07:00
|
|
|
import useMangoStore from '../stores/useMangoStore'
|
|
|
|
|
|
|
|
const byTimestamp = (a, b) => {
|
|
|
|
return (
|
2021-08-04 09:46:14 -07:00
|
|
|
new Date(b.loadTimestamp || b.timestamp.toNumber()).getTime() -
|
|
|
|
new Date(a.loadTimestamp || a.timestamp.toNumber()).getTime()
|
2021-04-05 07:32:11 -07:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-08-04 10:15:28 -07:00
|
|
|
const reverseSide = (side) => (side === 'buy' ? 'sell' : 'buy')
|
|
|
|
|
2021-07-24 11:12:52 -07:00
|
|
|
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 orderId = maker ? event.makerOrderId : event.takerOrderId
|
|
|
|
const value = event.quantity * event.price
|
|
|
|
const feeRate = maker
|
|
|
|
? perpMarketInfo.makerFee.toNumber()
|
|
|
|
: perpMarketInfo.takerFee.toNumber()
|
2021-08-04 10:15:28 -07:00
|
|
|
const side = maker ? reverseSide(event.takerSide) : event.takerSide
|
2021-07-24 11:12:52 -07:00
|
|
|
|
2021-06-24 09:30:45 -07:00
|
|
|
return {
|
2021-06-24 13:57:11 -07:00
|
|
|
...event,
|
2021-07-24 11:12:52 -07:00
|
|
|
key: orderId.toString(),
|
|
|
|
liquidity: maker ? 'Maker' : 'Taker',
|
|
|
|
size: event.quantity,
|
|
|
|
price: event.price,
|
|
|
|
value,
|
|
|
|
feeCost: (feeRate * value).toFixed(4),
|
2021-08-04 10:15:28 -07:00
|
|
|
side,
|
2021-06-24 09:30:45 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-24 13:57:11 -07:00
|
|
|
const parsedSerumEvent = (event) => {
|
2021-06-24 09:30:45 -07:00
|
|
|
return {
|
2021-06-24 13:57:11 -07:00
|
|
|
...event,
|
|
|
|
key: `${event.maker}-${event.price}`,
|
|
|
|
liquidity: event?.eventFlags?.maker ? 'Maker' : 'Taker',
|
|
|
|
value: event.price * event.size,
|
|
|
|
side: event.side,
|
2021-06-24 09:30:45 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-24 11:12:52 -07:00
|
|
|
const formatTradeHistory = (
|
|
|
|
selectedMangoGroup,
|
|
|
|
mangoAccountPk: PublicKey,
|
|
|
|
newTradeHistory
|
|
|
|
) => {
|
2021-04-05 07:32:11 -07:00
|
|
|
return newTradeHistory
|
|
|
|
.flat()
|
|
|
|
.map((trade) => {
|
2021-06-24 09:30:45 -07:00
|
|
|
if (trade.eventFlags) {
|
|
|
|
return parsedSerumEvent(trade)
|
|
|
|
} else {
|
2021-07-24 11:12:52 -07:00
|
|
|
return parsedPerpEvent(selectedMangoGroup, mangoAccountPk, trade)
|
2021-04-05 07:32:11 -07:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.sort(byTimestamp)
|
|
|
|
}
|
|
|
|
|
2021-06-24 09:30:45 -07:00
|
|
|
export const useTradeHistory = () => {
|
2021-06-21 12:02:12 -07:00
|
|
|
const marketConfig = useMangoStore((s) => s.selectedMarket.config)
|
|
|
|
const fills = useMangoStore((s) => s.selectedMarket.fills)
|
2021-06-23 08:32:33 -07:00
|
|
|
const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current)
|
2021-04-12 21:40:26 -07:00
|
|
|
const selectedMangoGroup = useMangoStore((s) => s.selectedMangoGroup.current)
|
2021-06-24 09:30:45 -07:00
|
|
|
const tradeHistory = useMangoStore((s) => s.tradeHistory)
|
2021-04-12 21:40:26 -07:00
|
|
|
|
2021-06-23 08:32:33 -07:00
|
|
|
if (!mangoAccount || !selectedMangoGroup) return null
|
2021-06-20 11:08:14 -07:00
|
|
|
const openOrdersAccount =
|
2021-06-23 08:32:33 -07:00
|
|
|
mangoAccount.spotOpenOrdersAccounts[marketConfig.marketIndex]
|
2021-06-20 11:08:14 -07:00
|
|
|
|
2021-06-24 09:30:45 -07:00
|
|
|
const mangoAccountFills = fills
|
|
|
|
.filter((fill) => {
|
2021-06-24 13:57:11 -07:00
|
|
|
if (fill.openOrders) {
|
2021-08-09 07:55:48 -07:00
|
|
|
return openOrdersAccount?.publicKey
|
|
|
|
? fill.openOrders.equals(openOrdersAccount?.publicKey)
|
|
|
|
: false
|
2021-06-24 09:30:45 -07:00
|
|
|
} else {
|
2021-07-07 14:18:54 -07:00
|
|
|
return (
|
|
|
|
fill.taker.equals(mangoAccount.publicKey) ||
|
|
|
|
fill.maker.equals(mangoAccount.publicKey)
|
|
|
|
)
|
2021-06-24 09:30:45 -07:00
|
|
|
}
|
|
|
|
})
|
2021-06-20 11:08:14 -07:00
|
|
|
.map((fill) => ({ ...fill, marketName: marketConfig.name }))
|
2021-04-05 07:32:11 -07:00
|
|
|
|
2021-04-14 23:16:36 -07:00
|
|
|
const allTrades = []
|
2021-06-24 09:30:45 -07:00
|
|
|
if (mangoAccountFills && mangoAccountFills.length > 0) {
|
|
|
|
const newFills = mangoAccountFills.filter(
|
2021-04-14 23:16:36 -07:00
|
|
|
(fill) =>
|
|
|
|
!tradeHistory.flat().find((t) => t.orderId === fill.orderId.toString())
|
|
|
|
)
|
|
|
|
const newTradeHistory = [...newFills, ...tradeHistory]
|
|
|
|
if (newFills.length > 0 && newTradeHistory.length !== allTrades.length) {
|
2021-07-24 11:12:52 -07:00
|
|
|
return formatTradeHistory(
|
|
|
|
selectedMangoGroup,
|
|
|
|
mangoAccount.publicKey,
|
|
|
|
newTradeHistory
|
|
|
|
)
|
2021-04-05 07:32:11 -07:00
|
|
|
}
|
2021-04-14 23:16:36 -07:00
|
|
|
}
|
2021-04-05 07:32:11 -07:00
|
|
|
|
2021-07-24 11:12:52 -07:00
|
|
|
return formatTradeHistory(
|
|
|
|
selectedMangoGroup,
|
|
|
|
mangoAccount.publicKey,
|
|
|
|
tradeHistory
|
|
|
|
)
|
2021-04-05 07:32:11 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
export default useTradeHistory
|