import { useEffect, useState } from "react"; import { Toast } from "@douyinfe/semi-ui-19"; import { api, formatNumber, formatTime, stateLabels } from "../api"; import { PnlChart } from "../components/PnlChart"; import type { Alpha, Pnl, Research } from "../types"; import type { ToolCardProps } from "./types"; export function AlphaToolCard({ call, onAction, timezone }: ToolCardProps) { const result = call.result ?? {}; const items = Array.isArray(result.items) ? result.items : []; const isSearch = call.name === "search_alphas"; const alphas = ( isSearch ? items : call.name === "get_alpha" && result.id ? [result] : [] ) as Alpha[]; const openAlpha = (id: string) => onAction({ type: "open_alpha", alpha_id: id, nonce: Date.now() }); return ( <> {call.preview.targets?.map((target) => (
{target.alpha_id} 的修改 {(["note", "tags", "favorite", "state"] as const) .filter( (key) => JSON.stringify(target.before[key]) !== JSON.stringify(target.after[key]), ) .map((key) => (
{ { note: "备注", tags: "标签", favorite: "收藏", state: "研究状态", }[key] } 修改前 {researchValue(key, target.before[key])} 修改后 {researchValue(key, target.after[key])}
))}
))} {alphas.length > 0 && (
{alphas.map((alpha) => (
{alpha.id} · {alpha.region ?? "地区未提供"}
Sharpe Fitness Turnover
{formatNumber(alpha.sharpe)} {formatNumber(alpha.fitness)} {alpha.turnover == null ? "未提供" : `${formatNumber(alpha.turnover * 100)}%`}
本地快照 · {formatTime(alpha.synced_at, timezone)}
))}
)} {isSearch && (

共 {String(result.total ?? 0)} 条,当前返回 {items.length} 条。 {!!result.filters && ( )}

)} {call.name === "get_alpha_facets" && call.status === "completed" && (

已同步 {String(result.total ?? 0)} 条 Alpha · 收藏{" "} {String(result.favorites ?? 0)} 条
地区: {Array.isArray(result.region) ? result.region.join("、") : "未提供"}

)} {call.name === "get_alpha_pnl" && call.status === "completed" && ( )} {result.ok === true && (

操作已保存。 {typeof result.alpha_id === "string" && ( )}

)} {typeof result.updated === "number" && (

已更新 {result.updated} 条研究记录。

)} ); } function researchValue(key: keyof Research, value: unknown) { if (key === "favorite") return value ? "已收藏" : "未收藏"; if (key === "state") return ( stateLabels[String(value) as keyof typeof stateLabels] ?? String(value) ); if (Array.isArray(value)) return value.join("、") || "无"; return String(value || "空"); } function ChatPnl({ result, timezone, }: { result: Record; timezone?: string; }) { const [pnl, setPnl] = useState(null); useEffect(() => { let active = true; if (result.cached && typeof result.alpha_id === "string") api(`/alphas/${encodeURIComponent(result.alpha_id)}/pnl`) .then((value) => { if (active) setPnl(value); }) .catch((error) => { if (active) Toast.error(error.message); }); return () => { active = false; }; }, [result.alpha_id, result.fetched_at, result.cached]); return result.cached ? (
{pnl && } {String(result.count)} 条记录 · 缓存于{" "} {formatTime(result.fetched_at as string, timezone)}
) : (

尚无 PnL 缓存,可以请求创建 PnL 刷新任务。

); }