fix(ui): show theme weighted-average verification in per-source modal
After reviewer suggestion: per theme, display sum(contribution)/sum(|weight|) = theme surprise so the owner can confirm the source audit matches the real score.
This commit is contained in:
18
frontend/dist/assets/index-C6jTIiYC.js
vendored
18
frontend/dist/assets/index-C6jTIiYC.js
vendored
File diff suppressed because one or more lines are too long
18
frontend/dist/assets/index-DDvZwbpd.js
vendored
Normal file
18
frontend/dist/assets/index-DDvZwbpd.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
frontend/dist/index.html
vendored
2
frontend/dist/index.html
vendored
@@ -5,7 +5,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="theme-color" content="#0b1018" />
|
||||
<title>SET50 Signal Lab</title>
|
||||
<script type="module" crossorigin src="/assets/index-C6jTIiYC.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-DDvZwbpd.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-CUx7tUuk.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -154,6 +154,22 @@ function formatNumber(value, digits = 2) {
|
||||
return Number(value ?? 0).toFixed(digits)
|
||||
}
|
||||
|
||||
// Per-theme factor audit helpers: verify sum(contribution)/sum(|weight|) = surprise
|
||||
function themeContribSum(rows) {
|
||||
return (rows || []).reduce((s, r) => s + (r.contribution ?? 0), 0)
|
||||
}
|
||||
function themeWeightSum(rows) {
|
||||
return (rows || []).reduce((s, r) => s + Math.abs(r.weight ?? 0), 0)
|
||||
}
|
||||
function themeWeightedAvg(rows) {
|
||||
// only contributing (non-missing) factors count, matching compute_theme_surprises
|
||||
const used = (rows || []).filter((r) => !r.missing && r.normalized != null)
|
||||
const cs = themeContribSum(used)
|
||||
const ws = themeWeightSum(used)
|
||||
if (ws === 0) return null
|
||||
return Math.max(-1, Math.min(1, cs / ws))
|
||||
}
|
||||
|
||||
// map the backend's dividend_method to an honest Thai label/flag
|
||||
function dividendMethodLabel(method) {
|
||||
if (method === 'dated_ledger') return 'ปันผล (ตามวันจริง)'
|
||||
@@ -910,8 +926,13 @@ onMounted(async () => { await loadDashboard(); await Promise.all([loadBacktestRu
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- weighted-average verification: sum(contrib) / sum(|weight|) = theme surprise -->
|
||||
<div class="calc-z" style="margin-top:4px">
|
||||
<span v-if="themeWeightedAvg(rows) != null">Σcontrib {{ formatNumber(themeContribSum(rows), 4) }} ÷ Σ{{ '|w|' }} {{ formatNumber(themeWeightSum(rows), 2) }} = ธีม surprise <strong>{{ formatNumber(themeWeightedAvg(rows), 3) }}σ</strong></span>
|
||||
<span v-else class="muted-cell">ยังไม่มีข้อมูล factor</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-sub">normalized = ค่า raw ที่ปรับด้วย sign/center/span อยู่ในช่วง [-1,1]; contribution = weight × normalized. แหล่งที่ไม่มีข้อมูลจะไม่ถูกนับ (missed → drop source)</div>
|
||||
<div class="modal-sub">normalized = ค่า raw ที่ปรับด้วย sign/center/span อยู่ในช่วง [-1,1]; contribution = weight × normalized; theme surprise = Σcontribution ÷ Σ{{ '|weight|' }}. แหล่งที่ไม่มีข้อมูลจะไม่ถูกนับ (drop source)</div>
|
||||
</div>
|
||||
<div v-else class="muted-cell">ไม่มีข้อมูลแยกตามแหล่ง</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user