From 9df109b1415893c6eb5e409e6ad7b5020a5903d7 Mon Sep 17 00:00:00 2001 From: microwavedcola1 Date: Fri, 8 Apr 2022 16:57:37 +0200 Subject: [PATCH] Fix price, & size computation while placing serum3 order Signed-off-by: microwavedcola1 --- ts/client.ts | 79 +++++++++++++++++++++++++++++++++++++++++---- ts/example1-user.ts | 68 +++++++++++++++++++++++++++++++++++--- 2 files changed, 136 insertions(+), 11 deletions(-) diff --git a/ts/client.ts b/ts/client.ts index bcdf50bde..e323e5627 100644 --- a/ts/client.ts +++ b/ts/client.ts @@ -1,5 +1,6 @@ import { BN, Program, Provider } from '@project-serum/anchor'; -import { Market } from '@project-serum/serum'; +import { getFeeRates, getFeeTier, Market } from '@project-serum/serum'; +import { Order } from '@project-serum/serum/lib/market'; import * as spl from '@solana/spl-token'; import { AccountMeta, @@ -383,9 +384,8 @@ export class MangoClient { serum3ProgramId: PublicKey, serum3MarketName: string, side: Serum3Side, - limitPrice: number, - maxBaseQty: number, - maxNativeQuoteQtyIncludingFees: number, + price: number, + size: number, selfTradeBehavior: Serum3SelfTradeBehavior, orderType: Serum3OrderType, clientOrderId: number, @@ -421,12 +421,25 @@ export class MangoClient { const healthRemainingAccounts: PublicKey[] = await this.buildHealthRemainingAccounts(group, mangoAccount); + const limitPrice = serum3MarketExternal.priceNumberToLots(price); + const maxBaseQuantity = serum3MarketExternal.baseSizeNumberToLots(size); + const feeTier = getFeeTier(0, 0 /** TODO: fix msrm/srm balance */); + const rates = getFeeRates(feeTier); + const maxQuoteQuantity = new BN( + serum3MarketExternal.decoded.quoteLotSize.toNumber() * + (1 + rates.taker) /** TODO: fix taker/maker */, + ).mul( + serum3MarketExternal + .baseSizeNumberToLots(size) + .mul(serum3MarketExternal.priceNumberToLots(price)), + ); + return await this.program.methods .serum3PlaceOrder( side, - new BN(limitPrice), - new BN(maxBaseQty), - new BN(maxNativeQuoteQtyIncludingFees), + limitPrice, + maxBaseQuantity, + maxQuoteQuantity, selfTradeBehavior, orderType, new BN(clientOrderId), @@ -463,6 +476,58 @@ export class MangoClient { .rpc(); } + async cancelSerumOrder( + group: Group, + mangoAccount: MangoAccount, + serum3ProgramId: PublicKey, + serum3MarketName: string, + side: Serum3Side, + orderId: BN, + ): Promise { + const serum3Market = group.serum3MarketsMap.get(serum3MarketName)!; + + const serum3MarketExternal = await Market.load( + this.program.provider.connection, + serum3Market.serumMarketExternal, + { commitment: this.program.provider.connection.commitment }, + serum3ProgramId, + ); + return await this.program.methods + .serum3CancelOrder(side, orderId) + .accounts({ + group: group.publicKey, + account: mangoAccount.publicKey, + openOrders: mangoAccount.findSerum3Account(serum3Market.marketIndex) + ?.openOrders, + serumMarket: serum3Market.publicKey, + serumProgram: serum3ProgramId, + serumMarketExternal: serum3Market.serumMarketExternal, + marketBids: serum3MarketExternal.bidsAddress, + marketAsks: serum3MarketExternal.asksAddress, + marketEventQueue: serum3MarketExternal.decoded.eventQueue, + }) + .rpc(); + } + + async getSerum3Orders( + group: Group, + serum3ProgramId: PublicKey, + serum3MarketName: string, + ): Promise { + const serum3Market = group.serum3MarketsMap.get(serum3MarketName)!; + + const serum3MarketExternal = await Market.load( + this.program.provider.connection, + serum3Market.serumMarketExternal, + { commitment: this.program.provider.connection.commitment }, + serum3ProgramId, + ); + return await serum3MarketExternal.loadOrdersForOwner( + this.program.provider.connection, + group.publicKey, + ); + } + /// static static async connect( diff --git a/ts/example1-user.ts b/ts/example1-user.ts index 9984b1ffe..f5294f864 100644 --- a/ts/example1-user.ts +++ b/ts/example1-user.ts @@ -48,22 +48,82 @@ async function main() { await client.withdraw(group, mangoAccount, 'USDC', 500000, false); // serum3 - console.log(`Placing serum3 order`); + console.log( + `Placing serum3 bid which would not be settled since its relatively low then midprice`, + ); await client.serum3PlaceOrder( group, mangoAccount, DEVNET_SERUM3_PROGRAM_ID, 'BTC/USDC', Serum3Side.bid, - 40000, - 1, - 1000000, + 20000, + 0.0001, + Serum3SelfTradeBehavior.decrementTake, + Serum3OrderType.limit, + Date.now(), + 10, + ); + console.log(`Placing serum3 bid way above midprice`); + await client.serum3PlaceOrder( + group, + mangoAccount, + DEVNET_SERUM3_PROGRAM_ID, + 'BTC/USDC', + Serum3Side.bid, + 90000, + 0.0001, + Serum3SelfTradeBehavior.decrementTake, + Serum3OrderType.limit, + Date.now(), + 10, + ); + console.log(`Placing serum3 ask way below midprice`); + await client.serum3PlaceOrder( + group, + mangoAccount, + DEVNET_SERUM3_PROGRAM_ID, + 'BTC/USDC', + Serum3Side.ask, + 30000, + 0.0001, Serum3SelfTradeBehavior.decrementTake, Serum3OrderType.limit, Date.now(), 10, ); + console.log(`Current own orders on OB...`); + let orders = await client.getSerum3Orders( + group, + DEVNET_SERUM3_PROGRAM_ID, + 'BTC/USDC', + ); + for (const order of orders) { + console.log( + `Order orderId ${order.orderId}, ${order.side}, ${order.price}, ${order.size}`, + ); + console.log(`Cancelling order with ${order.orderId}`); + await client.cancelSerumOrder( + group, + mangoAccount, + DEVNET_SERUM3_PROGRAM_ID, + 'BTC/USDC', + order.side === 'buy' ? Serum3Side.bid : Serum3Side.ask, + order.orderId, + ); + } + + console.log(`Current own orders on OB...`); + orders = await client.getSerum3Orders( + group, + DEVNET_SERUM3_PROGRAM_ID, + 'BTC/USDC', + ); + for (const order of orders) { + console.log(order); + } + process.exit(); }