Show open-capacity labels, enlarge funds, move rules; WeCom on short funds.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -233,6 +233,18 @@ export type PlanState = {
|
||||
atm_open_offset_enabled?: boolean;
|
||||
max_atm_open_offset?: number;
|
||||
can_open: boolean;
|
||||
open_capacity?: {
|
||||
leverage?: number;
|
||||
perp_can_open?: boolean | null;
|
||||
option_can_open?: boolean | null;
|
||||
perp_label?: string;
|
||||
option_label?: string;
|
||||
funds_ok?: boolean;
|
||||
perp_need_usdt?: number | null;
|
||||
option_need_usdc?: number | null;
|
||||
perp_have_usdt?: number | null;
|
||||
option_have_usdc?: number | null;
|
||||
};
|
||||
last_error: string | null;
|
||||
show_manual_trade_buttons?: boolean;
|
||||
position: {
|
||||
|
||||
@@ -31,7 +31,6 @@ function pnlClass(n: number | null | undefined) {
|
||||
|
||||
export default function FundsBar() {
|
||||
const [s, setS] = useState<FundsSummary | null>(null);
|
||||
const [rulesOpen, setRulesOpen] = useState(false);
|
||||
|
||||
const load = useCallback(() => {
|
||||
apiFetch<FundsSummary>("/api/funds/summary")
|
||||
@@ -49,10 +48,6 @@ export default function FundsBar() {
|
||||
|
||||
if (!s?.ok) return null;
|
||||
|
||||
const rulesText = `行情 ${s.exchange || "OKX"} · ${
|
||||
s.perp_inst_id || "ETH-USDT-SWAP"
|
||||
} · 目标平仓(双腿/远虚只平永续) · 未达标则到期结算`;
|
||||
|
||||
return (
|
||||
<div className="funds-bar-shell">
|
||||
<div className="funds-bar-inner">
|
||||
@@ -83,50 +78,33 @@ export default function FundsBar() {
|
||||
: "—"}
|
||||
</div>
|
||||
</div>
|
||||
<div className="funds-item">
|
||||
<div className="funds-item funds-item--money">
|
||||
<div className="funds-label">总资金</div>
|
||||
<div className="funds-value mono">{fmtU(s.total_funds)}</div>
|
||||
</div>
|
||||
<div className="funds-item">
|
||||
<div className="funds-item funds-item--money">
|
||||
<div className="funds-label">资金账户</div>
|
||||
<div className="funds-value mono">{fmtU(s.funding_usdt)}</div>
|
||||
</div>
|
||||
<div className="funds-item">
|
||||
<div className="funds-item funds-item--money">
|
||||
<div className="funds-label">交易账户</div>
|
||||
<div className="funds-value mono">{fmtU(s.trading_usdt)}</div>
|
||||
</div>
|
||||
<div className="funds-item">
|
||||
<div className="funds-item funds-item--money">
|
||||
<div className="funds-label">期权资金账户</div>
|
||||
<div className="funds-value mono">{s.options_funding_label}</div>
|
||||
</div>
|
||||
<div className="funds-item">
|
||||
<div className="funds-item funds-item--money">
|
||||
<div className="funds-label">期权交易账户</div>
|
||||
<div className="funds-value mono">{s.options_trading_label}</div>
|
||||
</div>
|
||||
<div className="funds-item funds-item--pnl">
|
||||
<div className="funds-item funds-item--pnl funds-item--money">
|
||||
<div className="funds-label">实时盈亏</div>
|
||||
<div className={`funds-value mono ${pnlClass(s.realtime_pnl)}`}>
|
||||
{s.realtime_pnl == null ? "—" : fmtU(s.realtime_pnl)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="funds-rules">
|
||||
<button
|
||||
type="button"
|
||||
className="funds-rules-toggle"
|
||||
aria-expanded={rulesOpen}
|
||||
onClick={() => setRulesOpen((v) => !v)}
|
||||
>
|
||||
<span>规则说明</span>
|
||||
<span className="funds-rules-chevron" aria-hidden>
|
||||
{rulesOpen ? "▾" : "▸"}
|
||||
</span>
|
||||
</button>
|
||||
{rulesOpen ? (
|
||||
<p className="funds-rules-body meta">{rulesText}</p>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -80,6 +80,7 @@ const PHASE_ZH: Record<string, string> = {
|
||||
outside_window: "窗外",
|
||||
liquidity_wait: "流动性等待",
|
||||
weekend_skip: "周末跳过",
|
||||
wait_funds: "资金不足",
|
||||
};
|
||||
|
||||
export default function PlanPage() {
|
||||
@@ -213,6 +214,16 @@ export default function PlanPage() {
|
||||
|
||||
{err ? <div className="err">{err}</div> : null}
|
||||
|
||||
<div className="plan-rules-fold">
|
||||
<details>
|
||||
<summary>规则说明</summary>
|
||||
<p className="meta plan-rules-body">
|
||||
行情 {String(plan?.exchange || "okx").toUpperCase()} · ETH-USDT-SWAP ·
|
||||
目标平仓(双腿/远虚只平永续) · 未达标则到期结算
|
||||
</p>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<div className="plan-actions">
|
||||
<button
|
||||
className={plan?.running ? "btn btn-running" : "btn"}
|
||||
@@ -318,9 +329,41 @@ export default function PlanPage() {
|
||||
</div>
|
||||
<div className="kv">
|
||||
<span>权益 / 杠杆</span>
|
||||
<span className="mono">
|
||||
{fmt(plan?.ledger?.equity)} / 可用 {fmt(plan?.ledger?.available)} ·{" "}
|
||||
{fmt(plan?.leverage, 0)}x
|
||||
<span className="open-cap-row">
|
||||
<span
|
||||
className={
|
||||
plan?.open_capacity?.perp_can_open === true
|
||||
? "open-cap-ok"
|
||||
: plan?.open_capacity?.perp_can_open === false
|
||||
? "open-cap-bad"
|
||||
: "mono"
|
||||
}
|
||||
title={
|
||||
plan?.open_capacity?.perp_need_usdt != null
|
||||
? `需≈${plan.open_capacity.perp_need_usdt}U / 有${plan.open_capacity.perp_have_usdt ?? "—"}U`
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
{plan?.open_capacity?.perp_label ||
|
||||
`永续${fmt(plan?.leverage, 0)}x —`}
|
||||
</span>
|
||||
<span className="open-cap-sep">·</span>
|
||||
<span
|
||||
className={
|
||||
plan?.open_capacity?.option_can_open === true
|
||||
? "open-cap-ok"
|
||||
: plan?.open_capacity?.option_can_open === false
|
||||
? "open-cap-bad"
|
||||
: "mono"
|
||||
}
|
||||
title={
|
||||
plan?.open_capacity?.option_need_usdc != null
|
||||
? `需≈${plan.open_capacity.option_need_usdc}U / 有${plan.open_capacity.option_have_usdc ?? "—"}U`
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
{plan?.open_capacity?.option_label || "期权 —"}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div className="kv">
|
||||
|
||||
@@ -232,6 +232,16 @@ input {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.funds-item--money .funds-value {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
.funds-item--money .funds-label {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.funds-item--pnl .funds-value {
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
@@ -271,6 +281,55 @@ input {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.plan-rules-fold {
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
.plan-rules-fold details {
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
background: var(--bg-panel);
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
.plan-rules-fold summary {
|
||||
cursor: pointer;
|
||||
color: var(--muted);
|
||||
font-size: 13px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.plan-rules-fold summary:hover {
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.plan-rules-body {
|
||||
margin: 8px 0 0;
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
.open-cap-row {
|
||||
display: inline-flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.open-cap-sep {
|
||||
color: var(--muted);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.open-cap-ok {
|
||||
color: #0ecb81;
|
||||
}
|
||||
|
||||
.open-cap-bad {
|
||||
color: #f6465d;
|
||||
}
|
||||
|
||||
.topnav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user