Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>
This commit is contained in:
microwavedcola1 2023-07-12 17:25:16 +02:00
parent 20a4fdebf9
commit 2ebffcdb05
1 changed files with 80 additions and 9 deletions

View File

@ -14,7 +14,7 @@ import { Bank, BankForHealth, TokenIndex } from './bank';
import { Group } from './group'; import { Group } from './group';
import { HealthType, MangoAccount, PerpPosition } from './mangoAccount'; import { HealthType, MangoAccount, PerpPosition } from './mangoAccount';
import { PerpMarket, PerpOrderSide } from './perp'; import { PerpMarket, PerpMarketIndex, PerpOrderSide } from './perp';
import { MarketIndex, Serum3Market, Serum3Side } from './serum3'; import { MarketIndex, Serum3Market, Serum3Side } from './serum3';
// ░░░░ // ░░░░
@ -235,6 +235,42 @@ export class HealthCache {
return tokenBalances; return tokenBalances;
} }
effectiveTokenBalancesInternalDisplay(
group: Group,
healthType: HealthType | undefined,
ignoreNegativePerp: boolean,
): TokenBalanceDisplay[] {
const tokenBalances = new Array(this.tokenInfos.length)
.fill(null)
.map((ignored) => new TokenBalanceDisplay(ZERO_I80F48(), 0, []));
for (const perpInfo of this.perpInfos) {
const settleTokenIndex = this.findTokenInfoIndex(
perpInfo.settleTokenIndex,
);
const perpSettleToken = tokenBalances[settleTokenIndex];
const healthUnsettled = perpInfo.healthUnsettledPnl(healthType);
perpSettleToken.perpMarketContributions.push({
market: group.getPerpMarketByMarketIndex(
perpInfo.perpMarketIndex as PerpMarketIndex,
).name,
contributionUi: toUiDecimalsForQuote(healthUnsettled),
});
if (!ignoreNegativePerp || healthUnsettled.gt(ZERO_I80F48())) {
perpSettleToken.spotAndPerp.iadd(healthUnsettled);
}
}
for (const index of this.tokenInfos.keys()) {
const tokenInfo = this.tokenInfos[index];
const tokenBalance = tokenBalances[index];
tokenBalance.spotAndPerp.iadd(tokenInfo.balanceSpot);
tokenBalance.spotUi += toUiDecimalsForQuote(tokenInfo.balanceSpot);
}
return tokenBalances;
}
healthSum(healthType: HealthType, tokenBalances: TokenBalance[]): I80F48 { healthSum(healthType: HealthType, tokenBalances: TokenBalance[]): I80F48 {
const health = ZERO_I80F48(); const health = ZERO_I80F48();
for (const index of this.tokenInfos.keys()) { for (const index of this.tokenInfos.keys()) {
@ -265,16 +301,35 @@ export class HealthCache {
healthContributionPerAssetUi( healthContributionPerAssetUi(
group: Group, group: Group,
healthType: HealthType, healthType: HealthType,
): { asset: string; contribution: number }[] { ): {
const tokenBalances = this.effectiveTokenBalancesInternal( asset: string;
healthType, contribution: number;
false, contributionDetails:
); | {
spotUi: number;
perpMarketContributions: { market: string; contributionUi: number }[];
}
| undefined;
}[] {
const tokenBalancesDisplay: TokenBalanceDisplay[] =
this.effectiveTokenBalancesInternalDisplay(group, healthType, false);
const ret = new Array<{ asset: string; contribution: number }>(); const ret = new Array<{
asset: string;
contribution: number;
contributionDetails:
| {
spotUi: number;
perpMarketContributions: {
market: string;
contributionUi: number;
}[];
}
| undefined;
}>();
for (const index of this.tokenInfos.keys()) { for (const index of this.tokenInfos.keys()) {
const tokenInfo = this.tokenInfos[index]; const tokenInfo = this.tokenInfos[index];
const tokenBalance = tokenBalances[index]; const tokenBalance = tokenBalancesDisplay[index];
const contrib = tokenInfo.healthContribution( const contrib = tokenInfo.healthContribution(
healthType, healthType,
tokenBalance.spotAndPerp, tokenBalance.spotAndPerp,
@ -282,6 +337,10 @@ export class HealthCache {
ret.push({ ret.push({
asset: group.getFirstBankByTokenIndex(tokenInfo.tokenIndex).name, asset: group.getFirstBankByTokenIndex(tokenInfo.tokenIndex).name,
contribution: toUiDecimalsForQuote(contrib), contribution: toUiDecimalsForQuote(contrib),
contributionDetails: {
spotUi: tokenBalance.spotUi,
perpMarketContributions: tokenBalance.perpMarketContributions,
},
}); });
} }
const res = this.computeSerum3Reservations(healthType); const res = this.computeSerum3Reservations(healthType);
@ -289,13 +348,14 @@ export class HealthCache {
const contrib = serum3Info.healthContribution( const contrib = serum3Info.healthContribution(
healthType, healthType,
this.tokenInfos, this.tokenInfos,
tokenBalances, tokenBalancesDisplay,
res.tokenMaxReserved, res.tokenMaxReserved,
res.serum3Reserved[index], res.serum3Reserved[index],
); );
ret.push({ ret.push({
asset: group.getSerum3MarketByMarketIndex(serum3Info.marketIndex).name, asset: group.getSerum3MarketByMarketIndex(serum3Info.marketIndex).name,
contribution: toUiDecimalsForQuote(contrib), contribution: toUiDecimalsForQuote(contrib),
contributionDetails: undefined,
}); });
} }
@ -1429,6 +1489,17 @@ class TokenBalance {
constructor(public spotAndPerp: I80F48) {} constructor(public spotAndPerp: I80F48) {}
} }
class TokenBalanceDisplay {
constructor(
public spotAndPerp: I80F48,
public spotUi: number,
public perpMarketContributions: {
market: string;
contributionUi: number;
}[],
) {}
}
class TokenMaxReserved { class TokenMaxReserved {
constructor(public maxSerumReserved: I80F48) {} constructor(public maxSerumReserved: I80F48) {}
} }