Now force canceling with up to 10 instructions in the partial liq transaction

This commit is contained in:
dd 2021-04-07 20:54:06 -04:00
parent fd1dc9d344
commit d92212723a
3 changed files with 74 additions and 39 deletions

View File

@ -2,7 +2,7 @@ import {
findLargestTokenAccountForOwner, findLargestTokenAccountForOwner,
getMultipleAccounts, getMultipleAccounts,
IDS, IDS,
MangoClient, nativeToUi, NUM_MARKETS, NUM_TOKENS, parseTokenAccountData, uiToNative, MangoClient, nativeToUi, NUM_MARKETS, NUM_TOKENS, parseTokenAccount, parseTokenAccountData, uiToNative,
} from '@blockworks-foundation/mango-client'; } from '@blockworks-foundation/mango-client';
import { Account, Connection, PublicKey, Transaction } from '@solana/web3.js'; import { Account, Connection, PublicKey, Transaction } from '@solana/web3.js';
import { homedir } from 'os'; import { homedir } from 'os';
@ -57,7 +57,8 @@ async function runPartialLiquidator() {
while (true) { while (true) {
try { try {
mangoGroup = await client.getMangoGroup(connection, mangoGroupPk) mangoGroup = await client.getMangoGroup(connection, mangoGroupPk)
const marginAccounts = await client.getAllMarginAccounts(connection, programId, mangoGroup) // const marginAccounts = await client.getAllMarginAccounts(connection, programId, mangoGroup)
const marginAccounts = [await client.getMarginAccount(connection, new PublicKey("85zCT5JsSmE5tgF42gPH6xxeVic5tXutAQDkSwfm9FN9"), mangoGroup.dexProgramId)]
let prices = await mangoGroup.getPrices(connection) // TODO put this on websocket as well let prices = await mangoGroup.getPrices(connection) // TODO put this on websocket as well
console.log(prices) console.log(prices)
@ -93,17 +94,20 @@ async function runPartialLiquidator() {
break break
} }
let collRatio = (assetsVal / liabsVal) if (!ma.beingLiquidated) {
if (collRatio + coll_bias >= mangoGroup.maintCollRatio) { let collRatio = (assetsVal / liabsVal)
break if (collRatio + coll_bias >= mangoGroup.maintCollRatio) {
break
}
const deficit = liabsVal * mangoGroup.initCollRatio - assetsVal
if (deficit < 0.1) { // too small of an account; number precision may cause errors
break
}
} }
const deficit = liabsVal * mangoGroup.initCollRatio - assetsVal
if (deficit < 0.1) { // too small of an account; number precision may cause errors
break
}
description = ma.toPrettyString(mangoGroup, prices) description = ma.toPrettyString(mangoGroup, prices)
console.log('liquidatable', deficit) console.log('liquidatable')
console.log(description) console.log(description)
// find the market with the most value in OpenOrdersAccount // find the market with the most value in OpenOrdersAccount
@ -120,11 +124,17 @@ async function runPartialLiquidator() {
maxMarketVal = marketVal maxMarketVal = marketVal
} }
} }
const transaction = new Transaction() const transaction = new Transaction()
if (maxMarketIndex !== -1) { if (maxMarketIndex !== -1) {
// force cancel orders on this particular market // force cancel orders on this particular market
const spotMarket = markets[maxMarketIndex] const spotMarket = markets[maxMarketIndex]
const [bids, asks] = await Promise.all([spotMarket.loadBids(connection), spotMarket.loadAsks(connection)])
const openOrdersAccount = ma.openOrdersAccounts[maxMarketIndex]
if (openOrdersAccount === undefined) {
console.log('error state')
continue
}
let numOrders = spotMarket.filterForOpenOrders(bids, asks, [openOrdersAccount]).length
const dexSigner = await PublicKey.createProgramAddress( const dexSigner = await PublicKey.createProgramAddress(
[ [
spotMarket.publicKey.toBuffer(), spotMarket.publicKey.toBuffer(),
@ -132,26 +142,34 @@ async function runPartialLiquidator() {
], ],
spotMarket.programId spotMarket.programId
) )
const instruction = makeForceCancelOrdersInstruction( let numInstrs = 0
programId, while (numInstrs < 10) {
mangoGroup.publicKey, const instruction = makeForceCancelOrdersInstruction(
payer.publicKey, programId,
ma.publicKey, mangoGroup.publicKey,
mangoGroup.vaults[maxMarketIndex], payer.publicKey,
mangoGroup.vaults[NUM_TOKENS-1], ma.publicKey,
spotMarket.publicKey, mangoGroup.vaults[maxMarketIndex],
spotMarket.bidsAddress, mangoGroup.vaults[NUM_TOKENS-1],
spotMarket.asksAddress, spotMarket.publicKey,
mangoGroup.signerKey, spotMarket.bidsAddress,
spotMarket['_decoded'].eventQueue, spotMarket.asksAddress,
spotMarket['_decoded'].baseVault, mangoGroup.signerKey,
spotMarket['_decoded'].quoteVault, spotMarket['_decoded'].eventQueue,
dexSigner, spotMarket['_decoded'].baseVault,
spotMarket.programId, spotMarket['_decoded'].quoteVault,
ma.openOrders, dexSigner,
mangoGroup.oracles spotMarket.programId,
) ma.openOrders,
transaction.add(instruction) mangoGroup.oracles
)
transaction.add(instruction)
numOrders -= 6
numInstrs += 1
if (numOrders <= 0) {
break
}
}
} }
// I'm assuming here that there is at least one asset greater than 0 and one less than // I'm assuming here that there is at least one asset greater than 0 and one less than
@ -175,11 +193,9 @@ async function runPartialLiquidator() {
// choose the max // choose the max
const liqorAccs = await getMultipleAccounts(connection, tokenWallets) const liqorAccs = await getMultipleAccounts(connection, tokenWallets)
const liqorTokenValues = liqorAccs.map( const liqorTokenValues = liqorAccs.map(
(a, i) => (a) => parseTokenAccount(a.accountInfo.data).amount
nativeToUi(parseTokenAccountData(a.accountInfo.data).amount, mangoGroup.mintDecimals[i])
) )
console.log(minNetIndex, maxNetIndex)
transaction.add(makePartialLiquidateInstruction( transaction.add(makePartialLiquidateInstruction(
programId, programId,
mangoGroup.publicKey, mangoGroup.publicKey,
@ -192,9 +208,14 @@ async function runPartialLiquidator() {
mangoGroup.signerKey, mangoGroup.signerKey,
ma.openOrders, ma.openOrders,
mangoGroup.oracles, mangoGroup.oracles,
uiToNative(0.001, mangoGroup.mintDecimals[minNetIndex]) liqorTokenValues[minNetIndex]
)) ))
// transaction.recentBlockhash = (await connection.getRecentBlockhash('singleGossip')).blockhash
// transaction.setSigners(payer.publicKey)
// transaction.sign(payer)
// const raw_tx = transaction.serialize()
// console.log('tx size', raw_tx.length)
await client.sendTransaction(connection, transaction, payer, []) await client.sendTransaction(connection, transaction, payer, [])
console.log('success liquidation') console.log('success liquidation')
liquidated = true liquidated = true

View File

@ -249,14 +249,14 @@ async function drainAccount(
async function testAll() { async function testAll() {
const client = new MangoClient() const client = new MangoClient()
const cluster = 'mainnet-beta' const cluster = 'devnet'
const clusterUrl = process.env.CLUSTER_URL || IDS.cluster_urls[cluster] const clusterUrl = process.env.CLUSTER_URL || IDS.cluster_urls[cluster]
const connection = new Connection(clusterUrl, 'singleGossip') const connection = new Connection(clusterUrl, 'singleGossip')
const programId = new PublicKey(IDS[cluster].mango_program_id) const programId = new PublicKey(IDS[cluster].mango_program_id)
const dexProgramId = new PublicKey(IDS[cluster].dex_program_id) const dexProgramId = new PublicKey(IDS[cluster].dex_program_id)
const mangoGroupPk = new PublicKey(IDS[cluster].mango_groups['BTC_ETH_USDT'].mango_group_pk) const mangoGroupPk = new PublicKey(IDS[cluster].mango_groups['BTC_ETH_USDT'].mango_group_pk)
const keyPairPath = process.env.KEYPAIR || homedir() + '/.config/solana/id.json' const keyPairPath = process.env.KEYPAIR || homedir() + '/.config/solana/id2.json'
const payer = new Account(JSON.parse(fs.readFileSync(keyPairPath, 'utf-8'))) const payer = new Account(JSON.parse(fs.readFileSync(keyPairPath, 'utf-8')))
const mangoGroup = await client.getMangoGroup(connection, mangoGroupPk) const mangoGroup = await client.getMangoGroup(connection, mangoGroupPk)
@ -340,7 +340,21 @@ async function testAll() {
console.log(mangoGroup.borrowLimits.map((b, i) => nativeToUi(b, mangoGroup.mintDecimals[i]))) console.log(mangoGroup.borrowLimits.map((b, i) => nativeToUi(b, mangoGroup.mintDecimals[i])))
} }
await testBorrowLimits() async function placeMultipleOrders() {
const marginAccountPk = new PublicKey("85zCT5JsSmE5tgF42gPH6xxeVic5tXutAQDkSwfm9FN9")
const marginAccount = await client.getMarginAccount(connection, marginAccountPk, dexProgramId)
const market = await Market.load(connection, mangoGroup.spotMarkets[1], { skipPreflight: true, commitment: 'singleGossip'}, mangoGroup.dexProgramId)
for (let i = 0; i < 12; i++) {
const price = 1010 + 10 * i
await client.placeAndSettle(connection, programId, mangoGroup, marginAccount, market, payer, "sell", price, 0.001)
await sleep(500)
}
}
placeMultipleOrders()
// await testBorrowLimits()
// await testGetOpenOrdersLatency() // await testGetOpenOrdersLatency()
// await testPlaceCancelOrder() // await testPlaceCancelOrder()
// await testDrainAccount() // await testDrainAccount()

View File

@ -316,7 +316,7 @@
"@blockworks-foundation/mango-client@https://github.com/blockworks-foundation/mango-client-ts#partial_liq": "@blockworks-foundation/mango-client@https://github.com/blockworks-foundation/mango-client-ts#partial_liq":
version "0.1.10" version "0.1.10"
resolved "https://github.com/blockworks-foundation/mango-client-ts#e581b5dfc7c79ec8c396ee132edaef6dfd355c8e" resolved "https://github.com/blockworks-foundation/mango-client-ts#e10fadd7bb9dee4f04994ad6cf293b4654c7edf1"
dependencies: dependencies:
"@project-serum/serum" "^0.13.20" "@project-serum/serum" "^0.13.20"
"@project-serum/sol-wallet-adapter" "^0.1.4" "@project-serum/sol-wallet-adapter" "^0.1.4"