wire up trade history

This commit is contained in:
Tyler Shipe 2021-04-13 00:40:26 -04:00
parent 9e67c147bf
commit 56c0372a7f
8 changed files with 116 additions and 112 deletions

View File

@ -65,37 +65,37 @@ const BalancesTable = () => {
<tr>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-4 tracking-wider`}
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
>
Coin
</th>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-4 tracking-wider`}
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
>
Deposits
</th>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-4 tracking-wider`}
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
>
Borrows
</th>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-4 tracking-wider`}
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
>
In Orders
</th>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-4 tracking-wider`}
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
>
Unsettled
</th>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-4 tracking-wider`}
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
>
Net
</th>
@ -110,32 +110,32 @@ const BalancesTable = () => {
`}
>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-4 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
>
{balance.coin}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-4 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
>
{balance.marginDeposits}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-4 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
>
{balance.borrows}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-4 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
>
{balance.orders}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-4 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
>
{balance.unsettled}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-4 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
>
{balance.net}
</td>
@ -146,7 +146,7 @@ const BalancesTable = () => {
</div>
) : (
<div
className={`w-full text-center py-6 text-base bg-th-bkg-1 font-light text-th-fgd-4 rounded-md`}
className={`w-full text-center py-6 text-base bg-th-bkg-1 font-light text-th-fgd-2 rounded-md`}
>
No balances
</div>

View File

@ -49,11 +49,11 @@ const FeeDiscountsTable = () => {
</div>
<div className="mt-6">
{connected ? (
<div className="bg-th-bkg-2 p-6">
<div className="text-th-fgd-4 text-center">
<div className="bg-th-bkg-2 p-6 rounded">
<div className="text-th-fgd-4 text-center text-lg">
Your contributed SRM: {contributedSrm}
</div>
<div className="flex space-x-4 mt-8">
<div className="flex space-x-4 mt-4">
<Button onClick={() => setShowDeposit(true)}>Deposit</Button>
<Button onClick={() => setShowWithdraw(true)}>Withdraw</Button>
</div>

View File

@ -61,25 +61,25 @@ const OpenOrdersTable = () => {
<tr>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-4 tracking-wider`}
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
>
Market
</th>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-4 tracking-wider`}
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
>
Side
</th>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-4 tracking-wider`}
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
>
Size
</th>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-4 tracking-wider`}
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
>
Price
</th>
@ -97,12 +97,12 @@ const OpenOrdersTable = () => {
`}
>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-4 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
>
{order.marketName}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-4 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
>
<div
className={`rounded inline-block bg-mango-green px-2 py-1 text-mango-dark font-bold`}
@ -111,12 +111,12 @@ const OpenOrdersTable = () => {
</div>
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-4 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
>
{order.size}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-4 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
>
{order.price}
</td>
@ -142,7 +142,7 @@ const OpenOrdersTable = () => {
</div>
) : (
<div
className={`w-full text-center py-6 text-base bg-th-bkg-1 font-light text-th-fgd-4 rounded-md`}
className={`w-full text-center py-6 text-base bg-th-bkg-1 font-light text-th-fgd-2 rounded-md`}
>
No open orders
</div>

View File

@ -1,113 +1,103 @@
import { useOpenOrders } from '../hooks/useOpenOrders'
import useTradeHistory from '../hooks/useTradeHistory'
const TradeHistoryTable = () => {
const openOrders = useOpenOrders()
const { tradeHistory } = useTradeHistory()
return (
<div className={`flex flex-col py-6`}>
<div className={`-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8`}>
<div className={`align-middle inline-block min-w-full sm:px-6 lg:px-8`}>
{openOrders ? (
{tradeHistory ? (
<div
className={`shadow overflow-hidden border-b border-mango-dark-light sm:rounded-md`}
className={`shadow overflow-hidden border-b border-th-bkg-2 sm:rounded-md`}
>
<table className={`min-w-full divide-y divide-mango-dark-light`}>
<table className={`min-w-full divide-y divide-th-bkg-2`}>
<thead>
<tr>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-gray-300 tracking-wider`}
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
>
Coin
Market
</th>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-gray-300 tracking-wider`}
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
>
Wallet Balance
Side
</th>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-gray-300 tracking-wider`}
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
>
Deposits
Size
</th>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-gray-300 tracking-wider`}
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
>
Borrows
Price
</th>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-gray-300 tracking-wider`}
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
>
In Orders
Liquidity
</th>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-gray-300 tracking-wider`}
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
>
Unsettled
</th>
<th
scope="col"
className={`px-6 py-3 text-left text-base font-medium text-gray-300 tracking-wider`}
>
Net
Fees
</th>
</tr>
</thead>
<tbody>
{openOrders.map((order, index) => (
{tradeHistory.map((trade, index) => (
<tr
key={`${order.orderId}${order.side}`}
key={`${trade.orderId}${trade.side}`}
className={`
${
index % 2 === 0
? `bg-mango-dark-light`
: `bg-mango-dark-lighter`
}
${index % 2 === 0 ? `bg-th-bkg-2` : `bg-th-bkg-3`}
`}
>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-gray-300 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
>
{order.marketName}
{trade.marketName}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-gray-300 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
>
<div
className={`rounded inline-block bg-mango-green px-2 py-1 text-mango-dark font-bold`}
className={`rounded inline-block ${
trade.side === 'buy'
? 'bg-th-green text-th-bkg-1'
: 'bg-th-red text-white'
}
px-2 py-1 font-bold`}
>
{order.side.toUpperCase()}
{trade.side.toUpperCase()}
</div>
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-gray-300 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
>
{order.size}
{trade.size}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-gray-300 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
>
{order.price}
{trade.price}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-gray-300 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
>
{order.price}
{trade.liquidity}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-gray-300 font-light`}
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
>
{order.price}
</td>
<td
className={`px-6 py-4 whitespace-nowrap text-sm text-gray-300 font-light`}
>
{order.price}
{trade.feeCost}
</td>
</tr>
))}

View File

@ -3,14 +3,19 @@ import { Market } from '@project-serum/serum'
import { PublicKey, AccountInfo } from '@solana/web3.js'
import useConnection from './useConnection'
import useMangoStore from '../stores/useMangoStore'
import useSerumStore from '../stores/useSerumStore'
import useMarketList from './useMarketList'
import { notify } from '../utils/notifications'
import useInterval from './useInterval'
const _SLOW_REFRESH_INTERVAL = 5 * 1000
const marketAddressSelector = (s) => s.selectedMarket.address
const mangoGroupMarketsSelector = (s) => s.selectedMangoGroup.markets
const useHydrateStore = () => {
const setMangoStore = useMangoStore((s) => s.set)
const setSerumStore = useSerumStore((s) => s.set)
const selectedMarketAddress = useMangoStore(marketAddressSelector)
const marketsForSelectedMangoGroup = useMangoStore(mangoGroupMarketsSelector)
const { connection, dexProgramId } = useConnection()
@ -128,6 +133,22 @@ const useHydrateStore = () => {
}
}
}, [marketsForSelectedMangoGroup])
useInterval(() => {
async function fetchFills() {
const market = useMangoStore.getState().market.current
if (!market || !connection) {
return null
}
const loadedFills = await market.loadFills(connection, 10000)
setSerumStore((state) => {
state.fills = loadedFills
})
}
fetchFills()
}, _SLOW_REFRESH_INTERVAL)
}
export default useHydrateStore

View File

@ -1,36 +1,7 @@
import { useEffect } from 'react'
import useMangoStore from '../stores/useMangoStore'
import useInterval from './useInterval'
import useSerumStore from '../stores/useSerumStore'
import useOrderbook from './useOrderbook'
import useConnection from './useConnection'
// const _FAST_REFRESH_INTERVAL = 1000;
const _SLOW_REFRESH_INTERVAL = 5 * 1000
// const _VERY_SLOW_REFRESH_INTERVAL = 5000 * 1000;
export function _useUnfilteredTrades(limit = 10000) {
console.log('fetching unfiltered trades')
const market = useMangoStore((state) => state.market.current)
const { connection } = useConnection()
const setSerumStore = useSerumStore((state) => state.set)
useInterval(() => {
async function fetchFills() {
if (!market || !connection) {
return null
}
const loadedFills = await market.loadFills(connection, limit)
setSerumStore((state) => {
state.fills = loadedFills
})
}
fetchFills()
}, _SLOW_REFRESH_INTERVAL)
}
export function useTrades() {
const trades = useSerumStore((state) => state.fills)
@ -64,10 +35,11 @@ export default function useMarkPrice() {
? [bb, ba, last].sort((a, b) => a - b)[1]
: (bb + ba) / 2
: null
setMangoStore((state) => {
state.market.markPrice = newMarkPrice
})
if (newMarkPrice !== markPrice) {
setMangoStore((state) => {
state.market.markPrice = newMarkPrice
})
}
}, [orderbook, trades])
return markPrice

View File

@ -2,6 +2,8 @@ import { useCallback, useState, useEffect, useRef } from 'react'
import { isDefined } from '../utils'
import useMangoStore from '../stores/useMangoStore'
import useSerumStore from '../stores/useSerumStore'
import useMarket from './useMarket'
import useInterval from './useInterval'
const byTimestamp = (a, b) => {
return (
@ -35,13 +37,30 @@ export const usePrevious = (value) => {
return ref.current
}
const useFills = () => {
const fills = useSerumStore((s) => s.fills)
const { market, marketName } = useMarket()
const marginAccount = useMangoStore((s) => s.selectedMarginAccount.current)
const selectedMangoGroup = useMangoStore((s) => s.selectedMangoGroup.current)
if (!marginAccount || !selectedMangoGroup) return null
const marketIndex = selectedMangoGroup.getMarketIndex(market)
const openOrdersAccount = marginAccount.openOrdersAccounts[marketIndex]
return fills
.filter((fill) => fill.openOrders.equals(openOrdersAccount.publicKey))
.map((fill) => ({ ...fill, marketName }))
}
export const useTradeHistory = () => {
const eventQueueFills = useSerumStore((s) => s.fills)
const eventQueueFills = useFills()
const [tradeHistory, setTradeHistory] = useState<any[]>([])
const [allTrades, setAllTrades] = useState<any[]>([])
const marginAccount = useMangoStore((s) => s.selectedMarginAccount.current)
const fetchTradeHistory = useCallback(async () => {
console.log('fetching history')
if (!marginAccount) return
if (marginAccount.openOrdersAccounts.length === 0) return
@ -59,16 +78,18 @@ export const useTradeHistory = () => {
return parsedResponse?.data ? parsedResponse.data : []
})
)
console.log('results', results)
setTradeHistory(formatTradeHistory(results))
setAllTrades(formatTradeHistory(results))
}, [marginAccount, eventQueueFills])
}, [marginAccount])
useEffect(() => {
useInterval(() => {
console.log('interval', allTrades, tradeHistory)
if (marginAccount && tradeHistory.length === 0) {
fetchTradeHistory()
}
}, [marginAccount])
}, 10000)
useEffect(() => {
if (eventQueueFills && eventQueueFills.length > 0) {

View File

@ -1,6 +1,6 @@
import { useEffect, useState } from 'react'
import styled from '@emotion/styled'
import { Button, Select } from 'antd'
import { Select } from 'antd'
import { LineChart, Line, ReferenceLine, XAxis, YAxis, Tooltip } from 'recharts'
import useDimensions from 'react-cool-dimensions'
import { IDS, MangoClient } from '@blockworks-foundation/mango-client'
@ -197,7 +197,7 @@ export default function StatsPage() {
return (
<Wrapper>
<TopBar />
<div className="px-48">
<div className="w-2/3 mx-auto">
<FloatingElement>
<>
<div className="text-center">