From a2956eccc9257a931926539a055843c341184095 Mon Sep 17 00:00:00 2001 From: Jarry Xiao <61092285+jarry-xiao@users.noreply.github.com> Date: Fri, 22 Dec 2023 06:33:28 -0600 Subject: [PATCH] Try catch around price calculation (#786) * Pull the data for lot and tick sizes * naming * more robust strategy * ts * add example code for each market * prettier * linter --- sdk/examples/phoenix.ts | 71 ++++++++++++++++++---------- sdk/src/phoenix/phoenixSubscriber.ts | 39 ++++++++------- 2 files changed, 64 insertions(+), 46 deletions(-) diff --git a/sdk/examples/phoenix.ts b/sdk/examples/phoenix.ts index b46e7435a..e879abadd 100644 --- a/sdk/examples/phoenix.ts +++ b/sdk/examples/phoenix.ts @@ -1,38 +1,57 @@ import { Connection, PublicKey } from '@solana/web3.js'; -import { BASE_PRECISION, PRICE_PRECISION, PhoenixSubscriber } from '../src'; +import { + BASE_PRECISION, + L2Level, + PRICE_PRECISION, + PhoenixSubscriber, +} from '../src'; import { PROGRAM_ID } from '@ellipsis-labs/phoenix-sdk'; export async function listenToBook(): Promise { const connection = new Connection('https://api.mainnet-beta.solana.com'); - const phoenixSubscriber = new PhoenixSubscriber({ - connection, - programId: PROGRAM_ID, - marketAddress: new PublicKey( - '4DoNfFBfF7UokCC2FQzriy7yHK6DY6NVdYpuekQ5pRgg' - ), - accountSubscription: { - type: 'websocket', - }, - }); - - await phoenixSubscriber.subscribe(); - - for (let i = 0; i < 10; i++) { - const bids = phoenixSubscriber.getL2Levels("bids"); - const asks = phoenixSubscriber.getL2Levels("asks"); - console.log("bids"); - for (const bid of bids) { - console.log(bid.price.toNumber() / PRICE_PRECISION.toNumber(), bid.size.toNumber() / BASE_PRECISION.toNumber()); + for (const market of [ + '4DoNfFBfF7UokCC2FQzriy7yHK6DY6NVdYpuekQ5pRgg', // SOL/USDC + 'Ew3vFDdtdGrknJAVVfraxCA37uNJtimXYPY4QjnfhFHH', // ETH/USDC + '2sTMN9A1D1qeZLF95XQgJCUPiKe5DiV52jLfZGqMP46m', // PYTH/USDC + 'BRLLmdtPGuuFn3BU6orYw4KHaohAEptBToi3dwRUnHQZ', // JTO/USDC + ]) { + const phoenixSubscriber = new PhoenixSubscriber({ + connection, + programId: PROGRAM_ID, + marketAddress: new PublicKey(market), + accountSubscription: { + type: 'websocket', + }, + }); + + await phoenixSubscriber.subscribe(); + + const bids = phoenixSubscriber.getL2Levels('bids'); + const asks = phoenixSubscriber.getL2Levels('asks'); + let bid: L2Level | null = null; + for (const b of bids) { + bid = b; + break; } - console.log("asks"); - for (const ask of asks) { - console.log(ask.price.toNumber() / PRICE_PRECISION.toNumber(), ask.size.toNumber() / BASE_PRECISION.toNumber()); + let ask: L2Level | null = null; + for (const a of asks) { + ask = a; + break; } - await new Promise((r) => setTimeout(r, 2000)); - } - await phoenixSubscriber.unsubscribe(); + console.log('market', market); + console.log( + (bid?.size.toNumber() || 0) / BASE_PRECISION.toNumber(), + (bid?.price.toNumber() || 0) / PRICE_PRECISION.toNumber(), + '@', + (ask?.price.toNumber() || (1 << 53) - 1) / PRICE_PRECISION.toNumber(), + (ask?.size.toNumber() || 0) / BASE_PRECISION.toNumber() + ); + console.log(); + + await phoenixSubscriber.unsubscribe(); + } } (async function () { diff --git a/sdk/src/phoenix/phoenixSubscriber.ts b/sdk/src/phoenix/phoenixSubscriber.ts index b35b3474f..65adb59d3 100644 --- a/sdk/src/phoenix/phoenixSubscriber.ts +++ b/sdk/src/phoenix/phoenixSubscriber.ts @@ -6,7 +6,6 @@ import { toNum, getMarketUiLadder, Market, - getMarketLadder, } from '@ellipsis-labs/phoenix-sdk'; import { PRICE_PRECISION } from '../constants/numericConstants'; import { BN } from '@coral-xyz/anchor'; @@ -164,18 +163,14 @@ export class PhoenixSubscriber implements L2OrderBookGenerator { } *getL2Levels(side: 'bids' | 'asks'): Generator { - const tickSize = this.market.data.header - .tickSizeInQuoteAtomsPerBaseUnit as BN; - const baseLotsToRawBaseUnits = this.market.baseLotsToRawBaseUnits(1); - - const basePrecision = new BN( - Math.pow(10, this.market.data.header.baseParams.decimals) * - baseLotsToRawBaseUnits + const basePrecision = Math.pow( + 10, + this.market.data.header.baseParams.decimals ); - const pricePrecision = PRICE_PRECISION.div(tickSize as BN); + const pricePrecision = PRICE_PRECISION.toNumber(); - const ladder = getMarketLadder( + const ladder = getMarketUiLadder( this.market, this.lastSlot, this.lastUnixTimestamp, @@ -183,18 +178,22 @@ export class PhoenixSubscriber implements L2OrderBookGenerator { ); for (let i = 0; i < ladder[side].length; i++) { - const { priceInTicks, sizeInBaseLots } = ladder[side][i]; - const size = sizeInBaseLots.mul(basePrecision); - yield { - price: priceInTicks.mul(new BN(pricePrecision)), - size, - sources: { - phoenix: size, - }, - }; + const { price, quantity } = ladder[side][i]; + try { + const size = new BN(quantity * basePrecision); + const updatedPrice = new BN(price * pricePrecision); + yield { + price: updatedPrice, + size, + sources: { + phoenix: size, + }, + }; + } catch { + continue; + } } } - public async unsubscribe(): Promise { if (!this.subscribed) { return;