mirror of
https://github.com/Zproger/Aurum.git
synced 2026-10-13 02:56:39 +07:00
fix: Best/Worst Performer compared personal ROI, not coins against each other
best/worst were picked by profit_loss_percent (return since the user's own purchase price), so a coin bought cheap long ago could show as "best" without actually being the strongest mover right now. Switched to price_change_24h — the same market-price move already shown in the table's 24h% column — so the comparison is coins against each other by how they're actually performing today, independent of when/at what price each was bought. 24h was the user's explicit choice over 1h/7d. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01855PiW5Wd8n4aRW4n9kByY
This commit is contained in:
@@ -28,9 +28,15 @@ function computeTotals(holdings: CryptoHolding[]): Totals {
|
|||||||
for (const holding of holdings) {
|
for (const holding of holdings) {
|
||||||
if (holding.value !== null) totalValue += Number(holding.value);
|
if (holding.value !== null) totalValue += Number(holding.value);
|
||||||
if (holding.cost_basis !== null) totalCostBasis += Number(holding.cost_basis);
|
if (holding.cost_basis !== null) totalCostBasis += Number(holding.cost_basis);
|
||||||
if (holding.profit_loss_percent === null) continue;
|
// Best/Worst Performer compare coins against *each other* by market
|
||||||
if (best === null || holding.profit_loss_percent > best.profit_loss_percent!) best = holding;
|
// price move (24h % change), not against what the user personally paid
|
||||||
if (worst === null || holding.profit_loss_percent < worst.profit_loss_percent!) worst = holding;
|
// — a coin someone bought yesterday at the top can still be "best
|
||||||
|
// performer" here if it's simply up the most of anything they hold
|
||||||
|
// today, independent of their own entry price/timing.
|
||||||
|
if (holding.price_change_24h === null) continue;
|
||||||
|
const change = Number(holding.price_change_24h);
|
||||||
|
if (best === null || change > Number(best.price_change_24h)) best = holding;
|
||||||
|
if (worst === null || change < Number(worst.price_change_24h)) worst = holding;
|
||||||
}
|
}
|
||||||
|
|
||||||
const totalProfitLoss = totalValue - totalCostBasis;
|
const totalProfitLoss = totalValue - totalCostBasis;
|
||||||
@@ -52,14 +58,14 @@ function StatTile({ label, children }: { label: string; children: ReactNode }) {
|
|||||||
|
|
||||||
function PerformerTile({ label, holding }: { label: string; holding: CryptoHolding | null }) {
|
function PerformerTile({ label, holding }: { label: string; holding: CryptoHolding | null }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
if (holding === null || holding.profit_loss_percent === null) {
|
if (holding === null || holding.price_change_24h === null) {
|
||||||
return (
|
return (
|
||||||
<StatTile label={label}>
|
<StatTile label={label}>
|
||||||
<p className="text-lg font-semibold text-text-muted">—</p>
|
<p className="text-lg font-semibold text-text-muted">—</p>
|
||||||
</StatTile>
|
</StatTile>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const percent = holding.profit_loss_percent;
|
const percent = Number(holding.price_change_24h);
|
||||||
const color = percent >= 0 ? "var(--success)" : "var(--danger)";
|
const color = percent >= 0 ? "var(--success)" : "var(--danger)";
|
||||||
return (
|
return (
|
||||||
<StatTile label={label}>
|
<StatTile label={label}>
|
||||||
@@ -75,7 +81,7 @@ function PerformerTile({ label, holding }: { label: string; holding: CryptoHoldi
|
|||||||
{percent >= 0 ? "+" : ""}
|
{percent >= 0 ? "+" : ""}
|
||||||
{percent.toFixed(2)}%
|
{percent.toFixed(2)}%
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-0.5 text-xs text-text-muted">{t("crypto.stats.since", { name: holding.name })}</p>
|
<p className="mt-0.5 text-xs text-text-muted">{t("crypto.stats.change24h")}</p>
|
||||||
</StatTile>
|
</StatTile>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ const ru = {
|
|||||||
"crypto.stats.costBasisHint": "сумма покупок по факту",
|
"crypto.stats.costBasisHint": "сумма покупок по факту",
|
||||||
"crypto.stats.bestPerformer": "Лучший рост",
|
"crypto.stats.bestPerformer": "Лучший рост",
|
||||||
"crypto.stats.worstPerformer": "Худшее падение",
|
"crypto.stats.worstPerformer": "Худшее падение",
|
||||||
"crypto.stats.since": "с момента покупки {{name}}",
|
"crypto.stats.change24h": "изменение цены за 24ч",
|
||||||
|
|
||||||
"roi.calculator.title": "Калькулятор ROI",
|
"roi.calculator.title": "Калькулятор ROI",
|
||||||
"roi.calculator.investmentLabel": "Сумма инвестиции",
|
"roi.calculator.investmentLabel": "Сумма инвестиции",
|
||||||
@@ -619,7 +619,7 @@ const en: Record<keyof typeof ru, string> = {
|
|||||||
"crypto.stats.costBasisHint": "actual amount spent buying",
|
"crypto.stats.costBasisHint": "actual amount spent buying",
|
||||||
"crypto.stats.bestPerformer": "Best Performer",
|
"crypto.stats.bestPerformer": "Best Performer",
|
||||||
"crypto.stats.worstPerformer": "Worst Performer",
|
"crypto.stats.worstPerformer": "Worst Performer",
|
||||||
"crypto.stats.since": "since buying {{name}}",
|
"crypto.stats.change24h": "24h price change",
|
||||||
|
|
||||||
"roi.calculator.title": "ROI Calculator",
|
"roi.calculator.title": "ROI Calculator",
|
||||||
"roi.calculator.investmentLabel": "Investment amount",
|
"roi.calculator.investmentLabel": "Investment amount",
|
||||||
|
|||||||
Reference in New Issue
Block a user