Overview
The SDK provides methods to track user financial activity:
getUserPnl - Get profit/loss summary with optional time-series
getUserHistory - Get unified transaction history (fills, settlements, deposits, withdrawals)
To avoid ambiguity, we denote the smallest possible multiple of USDC (0.000001 USDC) as one uusdc,
which stands for µUSDC (micro-USDC), and denote the smallest possible multiple of a contract (0.01 contract)
as one ccontract (centicontract). User-facing USDC balances are specified as fixed-point strings (e.g. "1.2625" for USDC). Contract quantities
in the API and SDK are specified as integer ccontracts strings (e.g. "1050" for 10.50 contracts at precision 2).
Getting PNL
getUserPnl
Get a comprehensive PNL summary for a user.
async getUserPnl (
userId : string ,
params ?: GetUserPnlParams
): Promise < GetUserPnlResponse >
Parameters
Optional filtering parameters
Filter to a specific market
Start timestamp (milliseconds)
End timestamp (milliseconds)
Time-series granularity: "hour", "day", or "all" (default, no time series)
Response
{
totalDeposits : string ; // Total deposits in µUSDC
totalWithdrawals : string ; // Total withdrawals in µUSDC
realizedPnl : string ; // Realized PNL in µUSDC
unrealizedPnl : string ; // Unrealized PNL in µUSDC
netPnl : string ; // Net PNL (realized + unrealized)
totalFeesPaid : string ; // Total fees paid in µUSDC
timeSeries ?: { // Only if granularity is hour/day
timestamp: number ;
cumulativePnl : string ;
}[];
}
Examples
Basic PNL summary:
import { createBisonClient , uusdcToUsdc } from '@bison-markets/sdk-ts' ;
const client = createBisonClient ({
baseUrl: 'https://api.bison.markets'
});
const pnl = await client . getUserPnl (
'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266'
);
// Display in dollars
console . log ( `Net P&L: $ ${ uusdcToUsdc ( pnl . netPnl ) } ` );
console . log ( `Realized: $ ${ uusdcToUsdc ( pnl . realizedPnl ) } ` );
console . log ( `Unrealized: $ ${ uusdcToUsdc ( pnl . unrealizedPnl ) } ` );
console . log ( `Fees Paid: $ ${ uusdcToUsdc ( pnl . totalFeesPaid ) } ` );
PNL with daily time series (for charts):
const pnl = await client . getUserPnl (
'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' ,
{ granularity: 'day' }
);
// Build chart data
const chartData = pnl . timeSeries ?. map ( point => ({
date: new Date ( point . timestamp ),
pnl: Number ( point . cumulativePnl ) / 1_000_000 // Convert to dollars
})) ?? [];
PNL for a specific market:
const marketPnl = await client . getUserPnl (
'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' ,
{ marketId: 'KXFEDDECISION-26JAN-T425' }
);
console . log ( `Market P&L: $ ${ uusdcToUsdc ( marketPnl . realizedPnl ) } ` );
PNL for a date range:
const oneWeekAgo = Date . now () - 7 * 24 * 60 * 60 * 1000 ;
const weeklyPnl = await client . getUserPnl (
'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' ,
{
startTime: oneWeekAgo ,
granularity: 'hour'
}
);
Getting Transaction History
getUserHistory
Get a chronological list of all financial transactions.
async getUserHistory (
userId : string ,
params ?: GetUserHistoryParams
): Promise < GetUserHistoryResponse >
Parameters
Optional filtering and pagination
Filter by type: "fill", "settlement", "deposit", or "withdraw"
Filter by market ID (only for fills and settlements)
Start timestamp (milliseconds)
End timestamp (milliseconds)
Max records per page (default: 50, max: 200)
Pagination cursor from previous response
Response
Returns an array of transaction records, each with a type discriminator:
{
records : ( FillRecord | SettlementRecord | DepositRecord | WithdrawRecord )[];
pagination : {
hasMore : boolean ;
nextCursor ?: string ;
};
}
Examples
Get all recent activity:
const { records } = await client . getUserHistory (
'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266'
);
records . forEach ( record => {
const date = new Date ( record . timestamp ). toLocaleDateString ();
switch ( record . type ) {
case 'fill' :
console . log (
` ${ date } : ${ record . action } ${ Number ( record . ccontracts ) / 100 } ${ record . side } @ $ ${ Number ( record . priceUusdc ) / 1_000_000 } `
);
break ;
case 'settlement' :
const won = record . payoutUusdc !== '0' ;
console . log ( ` ${ date } : Settlement ${ won ? 'WON' : 'LOST' } - $ ${ Number ( record . payoutUusdc ) / 1_000_000 } ` );
break ;
case 'deposit' :
console . log ( ` ${ date } : Deposited $ ${ Number ( record . amountUusdc ) / 1_000_000 } ` );
break ;
case 'withdraw' :
console . log ( ` ${ date } : Withdrew $ ${ Number ( record . amountUusdc ) / 1_000_000 } ( ${ record . status } )` );
break ;
}
});
Get only fills for a market:
const { records } = await client . getUserHistory (
'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' ,
{
type: 'fill' ,
marketId: 'KXFEDDECISION-26JAN-T425'
}
);
Paginate through all history:
let cursor : string | undefined ;
const allRecords = [];
do {
const result = await client . getUserHistory (
'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' ,
{ limit: 100 , cursor }
);
allRecords . push ( ... result . records );
cursor = result . pagination . nextCursor ;
} while ( cursor );
console . log ( `Total transactions: ${ allRecords . length } ` );
Error Handling
try {
const pnl = await client . getUserPnl ( '0x...' );
console . log ( 'Net PNL:' , pnl . netPnl );
} catch ( error ) {
if ( error instanceof Error ) {
console . error ( 'Failed to get PNL:' , error . message );
}
}
Important Notes
All monetary values are in µUSDC (1 USD = 1,000,000 µUSDC)
When filtering by marketId, deposits and withdrawals are excluded from PNL calculations
Transaction history is sorted newest-first by default
Unrealized PNL is estimated based on position cost basis
Time series data points represent cumulative PNL at each interval