import { FormEvent, useEffect, useState } from "react"; import { changeCredentials, getUsername, setSession, apiFetch, StrategySettings, } from "../api/client"; type Tab = "strategy" | "account"; export default function SettingsPage() { const [tab, setTab] = useState("strategy"); const [newUsername, setNewUsername] = useState(getUsername() || "admin"); const [currentPassword, setCurrentPassword] = useState(""); const [newPassword, setNewPassword] = useState(""); const [confirmPassword, setConfirmPassword] = useState(""); const [err, setErr] = useState(""); const [ok, setOk] = useState(""); const [loading, setLoading] = useState(false); const [fee, setFee] = useState(0.0005); const [exitPct, setExitPct] = useState(2); const [rest, setRest] = useState(300); const [leverage, setLeverage] = useState(3); const [minHours, setMinHours] = useState(12); const [minOptLev, setMinOptLev] = useState(100); const [closeDevPct, setCloseDevPct] = useState(30); const [perpQty, setPerpQty] = useState(1); const [optQty, setOptQty] = useState(2); const [stratOk, setStratOk] = useState(""); useEffect(() => { apiFetch("/api/settings/strategy") .then((s) => { setFee(s.fee_rate); setExitPct(s.exit_move_pct ?? 2); setRest(s.rest_seconds); setLeverage(s.leverage ?? 3); setMinHours(s.min_option_hours ?? 12); setMinOptLev(s.min_option_leverage ?? 100); setCloseDevPct(s.close_bid_mark_max_pct ?? 30); setPerpQty(s.perp_qty_eth ?? 1); setOptQty(s.option_qty_eth ?? 2); }) .catch(() => undefined); }, []); async function onSaveCreds(e: FormEvent) { e.preventDefault(); setErr(""); setOk(""); if (newPassword !== confirmPassword) { setErr("两次输入的新密码不一致"); return; } if (newPassword.length < 4) { setErr("新密码至少 4 位"); return; } setLoading(true); try { const res = await changeCredentials({ current_password: currentPassword, new_username: newUsername.trim(), new_password: newPassword, }); setSession(res.token, res.username); setCurrentPassword(""); setNewPassword(""); setConfirmPassword(""); setOk("用户名/密码已更新"); } catch (ex) { setErr(ex instanceof Error ? ex.message : String(ex)); } finally { setLoading(false); } } async function onSaveStrategy(e: FormEvent) { e.preventDefault(); setStratOk(""); setErr(""); try { await apiFetch("/api/settings/strategy", { method: "PUT", body: JSON.stringify({ fee_rate: fee, exit_move_pct: exitPct, rest_seconds: rest, leverage, min_option_hours: minHours, min_option_leverage: minOptLev, close_bid_mark_max_pct: closeDevPct, perp_qty_eth: perpQty, option_qty_eth: optQty, }), }); setStratOk("策略参数已保存"); } catch (ex) { setErr(ex instanceof Error ? ex.message : String(ex)); } } return (

系统设置

{tab === "strategy" ? (

无开仓时间窗;期权按剩余时长选到期 → 平值 → 校验杠杆;波动按百分比全平。

{stratOk ?
{stratOk}
: null} {err && tab === "strategy" ?
{err}
: null}

资金

setLeverage(Number(e.target.value))} />

策略

setMinHours(Number(e.target.value))} />
setMinOptLev(Number(e.target.value))} />
setExitPct(Number(e.target.value))} />
setCloseDevPct(Number(e.target.value))} />
setPerpQty(Number(e.target.value))} />
setOptQty(Number(e.target.value))} />
setRest(Number(e.target.value))} />
setFee(Number(e.target.value))} />
) : (
{err ?
{err}
: null} {ok ?
{ok}
: null}
setNewUsername(e.target.value)} required />
setCurrentPassword(e.target.value)} required />
setNewPassword(e.target.value)} required />
setConfirmPassword(e.target.value)} required />
)}
); }