Split fee stats by leg and hide LIVE slip.
SIM shows perp/option fees and slip separately; LIVE keeps real exchange fees only with slip forced to zero. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3,10 +3,14 @@ import { apiFetch } from "../api/client";
|
||||
import { closeReasonZh } from "../labels";
|
||||
|
||||
type Summary = {
|
||||
mode?: "SIM" | "LIVE" | string;
|
||||
show_slip?: boolean;
|
||||
groups: number;
|
||||
wins: number;
|
||||
win_rate: number;
|
||||
total_pnl: number;
|
||||
fees_perp?: number;
|
||||
fees_option?: number;
|
||||
total_fees: number;
|
||||
total_slip: number;
|
||||
close_reasons: Record<string, number>;
|
||||
@@ -26,6 +30,7 @@ export default function StatsPage() {
|
||||
const reasonEntries = s
|
||||
? Object.entries(s.close_reasons).sort((a, b) => b[1] - a[1])
|
||||
: [];
|
||||
const showSlip = s?.show_slip ?? s?.mode !== "LIVE";
|
||||
|
||||
return (
|
||||
<div className="card">
|
||||
@@ -46,11 +51,27 @@ export default function StatsPage() {
|
||||
<span className="mono">{s.total_pnl.toFixed(2)}</span>
|
||||
</div>
|
||||
<div className="kv">
|
||||
<span>总手续费 / 滑点</span>
|
||||
<span>永续手续费</span>
|
||||
<span className="mono">
|
||||
{s.total_fees.toFixed(2)} / {s.total_slip.toFixed(2)}
|
||||
{(s.fees_perp ?? 0).toFixed(4)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="kv">
|
||||
<span>期权手续费</span>
|
||||
<span className="mono">
|
||||
{(s.fees_option ?? 0).toFixed(4)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="kv">
|
||||
<span>手续费合计</span>
|
||||
<span className="mono">{s.total_fees.toFixed(4)}</span>
|
||||
</div>
|
||||
{showSlip ? (
|
||||
<div className="kv">
|
||||
<span>滑点合计</span>
|
||||
<span className="mono">{s.total_slip.toFixed(4)}</span>
|
||||
</div>
|
||||
) : null}
|
||||
<div className="kv" style={{ alignItems: "flex-start" }}>
|
||||
<span>平仓原因</span>
|
||||
<span className="mono" style={{ textAlign: "right" }}>
|
||||
|
||||
@@ -10,7 +10,10 @@ import {
|
||||
type PnlSummary = {
|
||||
option_pnl: number | null;
|
||||
perp_pnl: number | null;
|
||||
fees_perp?: number;
|
||||
fees_option?: number;
|
||||
fees_total: number;
|
||||
slip_total?: number;
|
||||
gross_pnl: number | null;
|
||||
net_pnl: number | null;
|
||||
};
|
||||
@@ -41,6 +44,7 @@ type Group = {
|
||||
hold_basis?: string | null;
|
||||
strike?: number | null;
|
||||
settle_index_px?: number | null;
|
||||
exec_mode?: string | null;
|
||||
expiry_settle?: ExpirySettle | null;
|
||||
pnl_summary?: PnlSummary;
|
||||
};
|
||||
@@ -349,10 +353,31 @@ export default function TradesPage() {
|
||||
{fmt(summary.perp_pnl)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="kv">
|
||||
<span>永续手续费</span>
|
||||
<span className="mono">
|
||||
{fmt(summary.fees_perp ?? 0, 4)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="kv">
|
||||
<span>期权手续费</span>
|
||||
<span className="mono">
|
||||
{fmt(summary.fees_option ?? 0, 4)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="kv">
|
||||
<span>手续费合计</span>
|
||||
<span className="mono">{fmt(summary.fees_total, 4)}</span>
|
||||
</div>
|
||||
{String(selectedGroup.exec_mode || "").toUpperCase() !==
|
||||
"LIVE" ? (
|
||||
<div className="kv">
|
||||
<span>滑点</span>
|
||||
<span className="mono">
|
||||
{fmt(summary.slip_total ?? 0, 4)}
|
||||
</span>
|
||||
</div>
|
||||
) : null}
|
||||
<div className="kv">
|
||||
<span>
|
||||
<strong>净盈亏(扣费后)</strong>
|
||||
|
||||
Reference in New Issue
Block a user