import { useEffect, useState } from "react"; import { Banner, Button, Descriptions, Empty, Spin, Table, Tag, Toast, } from "@douyinfe/semi-ui-19"; import { api, correlationLabels, formatNumber, formatTime, post } from "../api"; import type { CorrelationResult } from "../types"; export function SelfCorrelationPanel({ id, version, timezone, onTask, }: { id: string; version: string; timezone?: string; onTask: () => void; }) { const [result, setResult] = useState(null); const [loading, setLoading] = useState(true); const [busy, setBusy] = useState(false); const [error, setError] = useState(""); useEffect(() => { const controller = new AbortController(); setLoading(true); api<{ result: CorrelationResult | null }>( `/alphas/${id}/self-correlation`, { signal: controller.signal }, ) .then((value) => { if (!controller.signal.aborted) { setResult(value.result); setError(""); } }) .catch((e) => { if (!controller.signal.aborted) setError(e.message); }) .finally(() => { if (!controller.signal.aborted) setLoading(false); }); return () => controller.abort(); }, [id, version]); async function check() { setBusy(true); try { await post("/sync-jobs", { kind: "self_correlation", alpha_ids: [id] }); onTask(); } catch (e) { Toast.error((e as Error).message); } finally { setBusy(false); } } return (

本地自相关

与本地已同步的同地区已提交 Alpha 比较,排除自身。使用 PnL 缓存,缺失时自动获取;建议先全量同步已提交 Alpha。

近四年 PnL 日变化的 Pearson 相关系数,至少 30 个共同样本;本地告警线为 0.7,检测结果与平台检查分别记录。

{error && } {loading && !result ? ( ) : !result ? ( ) : ( <> {result.stale && ( )}
{correlationLabels[result.status]} 计算于 {formatTime(result.calculated_at, timezone)}
{result.reason &&

{result.reason}

} {result.status === "partial" && (

已有样本低于阈值,但部分基准无法比较,不能据此判断全部样本。

)} {result.matches.length > 0 && ( <>

相关系数最高的 Alpha(最多 10 条)

( {value} ), }, { title: "相关系数", dataIndex: "correlation", render: (value) => formatNumber(value, 4), }, { title: "共同样本", dataIndex: "sample_count" }, { title: "PnL 更新", dataIndex: "pnl_fetched_at", render: (value) => formatTime(value, timezone), }, ]} /> )} {result.skipped.length > 0 && (
跳过原因({result.skipped_count} 条,最多展示 100 条) {result.skipped.map((item) => (

{item.alpha_id}:{item.reason}

))}
)} )} ); }