"use client"; /** * 公共配置(/settings)—— 全局唯一一份费率 / 滑点 / 最低佣金 / 复权口径 / 基准。 * * 为什么单独一页:这些是「常规配置」,所有回测组合共用,不该在每个策略里重复填 * (用户目标第 1 条)。改这里会影响**之后**的回测;已跑过的归档不受影响 * (归档的 config_snapshot 固化了当时的成本/复权,可复现)。 */ import { useEffect, useState } from "react"; import { apiGet, apiPut } from "@/lib/api"; import type { GlobalConfig } from "@/lib/types"; import { Banner, Btn, Card, Field, Loading, PageHeader, Pill } from "@/components/ui"; const DEFAULTS: GlobalConfig = { commission_rate: 0.0003, stamp_tax_rate: 0.0005, slippage_rate: 0.001, min_commission: 5, price_adjustment: "hfq", benchmark: "000300.SH", }; export default function SettingsPage() { const [cfg, setCfg] = useState(null); const [draft, setDraft] = useState(DEFAULTS); const [busy, setBusy] = useState(false); const [err, setErr] = useState(""); const [msg, setMsg] = useState(""); useEffect(() => { let alive = true; apiGet("/config") .then((c) => { if (!alive) return; setCfg(c); setDraft(c); }) .catch((e: Error) => alive && setErr(e.message)); return () => { alive = false; }; }, []); async function save() { setBusy(true); setErr(""); setMsg(""); try { const saved = await apiPut("/config", draft); setCfg(saved); setMsg("公共配置已保存(之后的回测组合将采用新值;已归档的结果不受影响)"); } catch (e) { setErr((e as Error).message); } finally { setBusy(false); } } // 只比较用户可编辑的字段:忽略 id / updated_at(后端回填,draft 里没有), // 否则刚载入就会因 updated_at:null vs undefined 被判为「有改动」而误亮保存按钮。 const editable = (c: GlobalConfig) => JSON.stringify([c.commission_rate, c.stamp_tax_rate, c.slippage_rate, c.min_commission, c.price_adjustment, c.benchmark]); const dirty = cfg ? editable(cfg) !== editable(draft) : false; return ( <> {err ? {err} : null} {msg ? {msg} : null} {!cfg ? ( ) : ( {dirty ? 有未保存的修改 : null} 保存配置 } >
setDraft({ ...draft, commission_rate: Number(e.target.value) })} /> setDraft({ ...draft, stamp_tax_rate: Number(e.target.value) })} /> setDraft({ ...draft, slippage_rate: Number(e.target.value) })} /> setDraft({ ...draft, min_commission: Number(e.target.value) })} /> setDraft({ ...draft, benchmark: e.target.value })} />
费率以**小数**填写(0.0003 = 万三,不是 0.03%)。这里的值是全局默认;每个回测组合运行时 会把当时的成本/复权**快照**进归档,所以事后改这里不会改变历史结果的数字。
)} ); }