mc/break even price ts client: account for unsettled funding (#617)

* v0.16.3

* ts: break even price, account for unsettled funding

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* script

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

---------

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>
This commit is contained in:
microwavedcola1 2023-06-23 14:32:04 +02:00 committed by GitHub
parent e8a5b543af
commit 66ccd962bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 5 deletions

View File

@ -0,0 +1,44 @@
import { PublicKey } from '@solana/web3.js';
import { MangoClient } from '../../src/client';
import { toUiDecimalsForQuote } from '../../src/utils';
async function main(): Promise<void> {
const client = MangoClient.connectDefault(process.env.MB_CLUSTER_URL!);
const group = await client.getGroup(
new PublicKey('78b8f4cGCwmZ9ysPFMWLaLTkkaYnUjwMJYStWe5RTSSX'),
);
const mangoAccounts = await client.getAllMangoAccounts(group, true);
const solPerp = group.getPerpMarketByName('SOL-PERP');
const solPPs = mangoAccounts
.filter(
(a) =>
a
.perpActive()
.filter(
(pp) =>
pp.marketIndex === solPerp.perpMarketIndex &&
pp.getNotionalValueUi(solPerp) > 1000,
).length > 0,
)
.map((a) => {
const pp = a
.perpActive()
.filter((pp) => pp.marketIndex === solPerp.perpMarketIndex)[0];
pp['mangoAccount'] = a.publicKey;
return pp;
});
solPPs.forEach((pp) => {
let out = ``;
out += `https://app.mango.markets/?address=${pp['mangoAccount']}, `;
out += `bep ${pp.getBreakEvenPriceUi(solPerp)}, `;
out += `aep ${pp.getAverageEntryPriceUi(solPerp)}, `;
out += `uFunding ${pp.getUnsettledFundingUi(solPerp)}, `;
out += `rPnl ${toUiDecimalsForQuote(pp.realizedPnlForPositionNative)}, `;
out += `qRn ${toUiDecimalsForQuote(pp.quoteRunningNative)}, `;
console.log(out);
});
}
main();

View File

@ -17,9 +17,9 @@ import { I80F48, ONE_I80F48 } from '../numbers/I80F48';
import { toNative, toNativeI80F48, toUiDecimals } from '../utils';
import { Bank, MintInfo, TokenIndex } from './bank';
import {
OracleProvider,
isPythOracle,
isSwitchboardOracle,
OracleProvider,
parseSwitchboardOracle,
} from './oracle';
import { BookSide, PerpMarket, PerpMarketIndex } from './perp';

View File

@ -1432,17 +1432,24 @@ export class PerpPosition {
);
}
public getBreakEvenPriceUi(perpMarket: PerpMarket): number {
public getBreakEvenPrice(perpMarket: PerpMarket): I80F48 {
if (perpMarket.perpMarketIndex !== this.marketIndex) {
throw new Error("PerpPosition doesn't belong to the given market!");
}
if (this.basePositionLots.eq(new BN(0))) {
return 0;
return ZERO_I80F48();
}
return I80F48.fromI64(this.quoteRunningNative)
.sub(this.getUnsettledFunding(perpMarket))
.neg()
.div(I80F48.fromI64(this.basePositionLots.mul(perpMarket.baseLotSize)));
}
public getBreakEvenPriceUi(perpMarket: PerpMarket): number {
return perpMarket.priceNativeToUi(
-this.quoteRunningNative.toNumber() /
this.basePositionLots.mul(perpMarket.baseLotSize).toNumber(),
this.getBreakEvenPrice(perpMarket).toNumber(),
);
}