added targets

This commit is contained in:
dd 2021-04-09 17:37:10 -04:00
parent 68564b7fec
commit ce3e07a8d7
1 changed files with 10 additions and 92 deletions

View File

@ -24,88 +24,6 @@ import {
import BN = require('bn.js'); import BN = require('bn.js');
async function drainAccount(
client: MangoClient,
connection: Connection,
programId: PublicKey,
mangoGroup: MangoGroup,
ma: MarginAccount,
markets: Market[],
payer: Account,
prices: number[],
usdWallet: PublicKey
) {
// Cancel all open orders
const bidsPromises = markets.map((market) => market.loadBids(connection))
const asksPromises = markets.map((market) => market.loadAsks(connection))
const books = await Promise.all(bidsPromises.concat(asksPromises))
const bids = books.slice(0, books.length / 2)
const asks = books.slice(books.length / 2, books.length)
const cancelProms: Promise<TransactionSignature[]>[] = []
for (let i = 0; i < NUM_MARKETS; i++) {
cancelProms.push(ma.cancelAllOrdersByMarket(connection, client, programId, mangoGroup, markets[i], bids[i], asks[i], payer))
}
await Promise.all(cancelProms)
console.log('all orders cancelled')
ma = await client.getMarginAccount(connection, ma.publicKey, mangoGroup.dexProgramId)
await client.settleAll(connection, programId, mangoGroup, ma, markets, payer)
console.log('settleAll complete')
await sleep(2000)
ma = await client.getMarginAccount(connection, ma.publicKey, mangoGroup.dexProgramId)
// sort non-quote currency assets by value
const assets = ma.getAssets(mangoGroup)
const liabs = ma.getLiabs(mangoGroup)
const netValues: [number, number][] = []
for (let i = 0; i < NUM_TOKENS - 1; i++) {
netValues.push([i, (assets[i] - liabs[i]) * prices[i]])
}
// Sort by those with largest net deposits and sell those first before trying to buy back the borrowed
netValues.sort((a, b) => (b[1] - a[1]))
for (let i = 0; i < NUM_TOKENS - 1; i++) {
const marketIndex = netValues[i][0]
const market = markets[marketIndex]
const tokenDecimals = tokenToDecimals[marketIndex === 0 ? 'BTC' : 'ETH']
const tokenDecimalAdj = Math.pow(10, tokenDecimals)
if (netValues[i][1] > 0) { // sell to close
const price = prices[marketIndex] * 0.95
const size = Math.floor(assets[marketIndex] * tokenDecimalAdj) / tokenDecimalAdj // round down the size
if (size === 0) {
continue
}
console.log(`Sell to close ${marketIndex} ${size}`)
await client.placeOrder(connection, programId, mangoGroup, ma, market, payer, 'sell', price, size, 'limit')
} else if (netValues[i][1] < 0) { // buy to close
const price = prices[marketIndex] * 1.05 // buy at up to 5% higher than oracle price
const size = Math.ceil(liabs[marketIndex] * tokenDecimalAdj) / tokenDecimalAdj
console.log(`Buy to close ${marketIndex} ${size}`)
await client.placeOrder(connection, programId, mangoGroup, ma, market, payer, 'buy', price, size, 'limit')
}
}
await sleep(3000)
ma = await client.getMarginAccount(connection, ma.publicKey, mangoGroup.dexProgramId)
await client.settleAll(connection, programId, mangoGroup, ma, markets, payer)
console.log('settleAll complete')
ma = await client.getMarginAccount(connection, ma.publicKey, mangoGroup.dexProgramId)
console.log('Liquidation process complete\n', ma.toPrettyString(mangoGroup, prices))
console.log('Withdrawing USD')
await client.withdraw(connection, programId, mangoGroup, ma, payer, mangoGroup.tokens[NUM_TOKENS-1], usdWallet, ma.getUiDeposit(mangoGroup, NUM_TOKENS-1) * 0.999)
console.log('Successfully drained account', ma.publicKey.toString())
}
/* /*
After a liquidation, the amounts in each wallet become unbalanced After a liquidation, the amounts in each wallet become unbalanced
Make sure to sell or buy quantities different from the target on base currencies Make sure to sell or buy quantities different from the target on base currencies
@ -119,7 +37,8 @@ async function balanceWallets(
liqor: Account, liqor: Account,
liqorWallets: PublicKey[], liqorWallets: PublicKey[],
liqorValuesUi: number[], liqorValuesUi: number[],
liqorOpenOrdersKeys: PublicKey[] liqorOpenOrdersKeys: PublicKey[],
targets: number[]
) { ) {
const liqorOpenOrders = await Promise.all(liqorOpenOrdersKeys.map((pk) => OpenOrders.load(connection, pk, mangoGroup.dexProgramId))) const liqorOpenOrders = await Promise.all(liqorOpenOrdersKeys.map((pk) => OpenOrders.load(connection, pk, mangoGroup.dexProgramId)))
let updateWallets = false let updateWallets = false
@ -141,7 +60,6 @@ async function balanceWallets(
} }
// TODO cancel outstanding orders as well // TODO cancel outstanding orders as well
const targets = [0.1, 2]
const diffs: number[] = [] const diffs: number[] = []
const netValues: [number, number][] = [] const netValues: [number, number][] = []
// Go to each base currency and see if it's above or below target // Go to each base currency and see if it's above or below target
@ -180,7 +98,7 @@ async function balanceWallets(
feeDiscountPubkey: null feeDiscountPubkey: null
} }
) )
console.log("settling funds") console.log(`Place order successful: ${txid}; Settling funds`)
await market.settleFunds(connection, liqor, liqorOpenOrders[marketIndex], liqorWallets[marketIndex], liqorWallets[NUM_TOKENS-1]) await market.settleFunds(connection, liqor, liqorOpenOrders[marketIndex], liqorWallets[marketIndex], liqorWallets[NUM_TOKENS-1])
} else if (netValues[i][1] < 0) { // buy to close } else if (netValues[i][1] < 0) { // buy to close
@ -201,7 +119,7 @@ async function balanceWallets(
feeDiscountPubkey: null feeDiscountPubkey: null
} }
) )
console.log("settling funds") console.log(`Place order successful: ${txid}; Settling funds`)
await market.settleFunds(connection, liqor, liqorOpenOrders[marketIndex], liqorWallets[marketIndex], liqorWallets[NUM_TOKENS-1]) await market.settleFunds(connection, liqor, liqorOpenOrders[marketIndex], liqorWallets[marketIndex], liqorWallets[NUM_TOKENS-1])
} }
} }
@ -212,6 +130,8 @@ async function runPartialLiquidator() {
const cluster = process.env.CLUSTER || 'mainnet-beta' const cluster = process.env.CLUSTER || 'mainnet-beta'
const group_name = process.env.GROUP_NAME || 'BTC_ETH_USDT' const group_name = process.env.GROUP_NAME || 'BTC_ETH_USDT'
const clusterUrl = process.env.CLUSTER_URL || IDS.cluster_urls[cluster] const clusterUrl = process.env.CLUSTER_URL || IDS.cluster_urls[cluster]
const targetsStr = process.env.TARGETS || "0.1 2"
const targets = targetsStr.split(' ').map((s) => parseFloat(s))
const connection = new Connection(clusterUrl, 'singleGossip') const connection = new Connection(clusterUrl, 'singleGossip')
// The address of the Mango Program on the blockchain // The address of the Mango Program on the blockchain
@ -227,7 +147,7 @@ async function runPartialLiquidator() {
const keyPairPath = process.env.KEYPAIR || homedir() + '/.config/solana/id.json' const keyPairPath = process.env.KEYPAIR || homedir() + '/.config/solana/id.json'
const payer = new Account(JSON.parse(fs.readFileSync(keyPairPath, 'utf-8'))) const payer = new Account(JSON.parse(fs.readFileSync(keyPairPath, 'utf-8')))
notify(`liquidator launched cluster=${cluster} group=${group_name}`); notify(`partial liquidator launched cluster=${cluster} group=${group_name}`);
let mangoGroup = await client.getMangoGroup(connection, mangoGroupPk) let mangoGroup = await client.getMangoGroup(connection, mangoGroupPk)
@ -258,9 +178,6 @@ 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.getMarginAccount(connection, new PublicKey("85zCT5JsSmE5tgF42gPH6xxeVic5tXutAQDkSwfm9FN9"), mangoGroup.dexProgramId)]
// let prices = await mangoGroup.getPrices(connection) // TODO put this on websocket as well
let [marginAccounts, prices, vaultAccs, liqorAccs] = await Promise.all([ let [marginAccounts, prices, vaultAccs, liqorAccs] = await Promise.all([
client.getAllMarginAccounts(connection, programId, mangoGroup), client.getAllMarginAccounts(connection, programId, mangoGroup),
@ -420,7 +337,8 @@ async function runPartialLiquidator() {
)) ))
await client.sendTransaction(connection, transaction, payer, []) await client.sendTransaction(connection, transaction, payer, [])
console.log('success liquidation') console.log('Successful partial liquidation')
notify(``)
liquidated = true liquidated = true
break break
} catch (e) { } catch (e) {
@ -436,7 +354,7 @@ async function runPartialLiquidator() {
} }
console.log(`Max Borrow Account: ${maxBorrAcc} | Max Borrow Val: ${maxBorrVal}`) console.log(`Max Borrow Account: ${maxBorrAcc} | Max Borrow Val: ${maxBorrVal}`)
await balanceWallets(connection, mangoGroup, prices, markets, payer, tokenWallets, liqorTokenUi, liqorOpenOrdersKeys) await balanceWallets(connection, mangoGroup, prices, markets, payer, tokenWallets, liqorTokenUi, liqorOpenOrdersKeys, targets)
} catch (e) { } catch (e) {
notify(`unknown error: ${e}`); notify(`unknown error: ${e}`);