[verified] Remove tourism-only sections (01 surprise pulse, 02 provenance, 03 signal table, 04 research run); thesis across 3 themes; sources show fetch date
- Removed 'เชื่อถือข้อมูลได้ไหม' (02), 'ตารางสัญญาณ' dup (03), 'หลักฐานพอจะรองรับ study' (04), tourism surprise pulse — superseded by 3-theme panel + sources table - 05 บันทึกการวิเคราะห์ now lists thesis per theme (tourism/auto/energy) with surprise - Sources table shows fetched-at date (ข้อ 2) - All dashboard analysis is real (no mock); automation note: no cron yet (data fetched on-demand + daily cache) - Verified: build + browser 8 checks pass
This commit is contained in:
@@ -518,113 +518,14 @@ onMounted(loadDashboard)
|
||||
<td>{{ s['จาก'] }}</td>
|
||||
<td class="source-name">{{ s['แหล่ง'] }}</td>
|
||||
<td class="muted-cell">{{ s['ข้อมูล'] }}</td>
|
||||
<td class="muted-cell">{{ s['dึงมาเมื่อ'] }}</td>
|
||||
<td class="muted-cell">{{ s['dึงมาเมื่อ'] ? formatDate(s['dึงมาเมื่อ']) : '—' }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="hero-grid" id="factors">
|
||||
<article class="panel pulse-panel">
|
||||
<div class="panel-header">
|
||||
<div>
|
||||
<div class="section-kicker">01 / สิ่งที่เปลี่ยนไป</div>
|
||||
<h2>ความต่างจากปกติ</h2>
|
||||
</div>
|
||||
<span class="confidence-tag">{{ positiveObservations }}/{{ observationRows.length }} เป็นบวก</span>
|
||||
</div>
|
||||
<div class="pulse-lead">
|
||||
<span class="pulse-number">{{ formatNumber(summary.theme_surprise) }}σ</span>
|
||||
<span class="pulse-copy">ธีม tourism วิ่ง{{ summary.theme_surprise >= 0 ? 'สูงกว่า' : 'ต่ำกว่า' }}ค่าตามฤดูกาล — เป็น input ไม่ใช่คำสั่งซื้อขาย.</span>
|
||||
</div>
|
||||
<div class="observation-list">
|
||||
<div v-for="observation in observationRows" :key="observation.metric_key" class="observation-row">
|
||||
<div class="observation-name">{{ observation.metric_key.replaceAll('_', ' ') }}</div>
|
||||
<div class="observation-track"><div class="observation-bar" :class="Number(observation.surprise) >= 0 ? 'bar-positive' : 'bar-negative'" :style="{ width: `${Math.min(Math.abs(Number(observation.surprise)) / maxSurprise * 100, 100)}%` }"></div></div>
|
||||
<div class="observation-value" :class="Number(observation.surprise) >= 0 ? 'positive-text' : 'negative-text'">{{ Number(observation.surprise) >= 0 ? '+' : '' }}{{ formatNumber(observation.surprise) }}σ</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="panel lineage-panel" id="lineage">
|
||||
<div class="panel-header">
|
||||
<div>
|
||||
<div class="section-kicker">02 / ที่มาของข้อมูล</div>
|
||||
<h2>เชื่อถือข้อมูลได้ไหม?</h2>
|
||||
</div>
|
||||
<span class="status-tag" :class="summary.data_health.status === 'high' ? '' : 'warning-tag'">{{ displayLabel(summary.data_health.status) }}</span>
|
||||
</div>
|
||||
<div class="lineage-list">
|
||||
<div class="lineage-item"><span>แหล่งข้อมูล</span><strong>{{ summary.data_health.source_id }}</strong></div>
|
||||
<div class="lineage-item"><span>เผยแพร่</span><strong>{{ formatDate(summary.data_health.published_at) }}</strong></div>
|
||||
<div class="lineage-item"><span>ดึงข้อมูล</span><strong>{{ formatDate(summary.data_health.retrieved_at) }}</strong></div>
|
||||
<div class="lineage-item"><span>Vintage</span><strong>{{ summary.data_health.vintage_id }}</strong></div>
|
||||
<div class="lineage-item"><span>ประวัติ</span><strong>{{ summary.data_health.history_points || '—' }} points</strong></div>
|
||||
<div class="lineage-item"><span>Parser</span><strong>{{ summary.data_health.parser_version || '—' }}</strong></div>
|
||||
<div class="lineage-item"><span>Replay</span><strong>{{ summary.data_health.replayable ? 'มี' : 'ไม่มี' }}</strong></div>
|
||||
<div class="lineage-item"><span>Raw hash</span><strong>{{ summary.data_health.raw_payload_hash ? summary.data_health.raw_payload_hash.slice(0, 16) : '—' }}</strong></div>
|
||||
</div>
|
||||
<div class="lineage-note">ทุกสัญญาณพกที่มา, เวลาเผยแพร่ และ vintage ของมัน ข้อมูลที่ถูกแก้ภายหลังไม่เคยเขียนทับอดีตแบบเงียบ.</div>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="panel signal-panel" id="signals">
|
||||
<div class="panel-header signal-header">
|
||||
<div>
|
||||
<div class="section-kicker">03 / ผลลัพธ์เชิงกำหนด</div>
|
||||
<h2>ตารางสัญญาณ</h2>
|
||||
</div>
|
||||
<div class="strategy-meta">{{ signalData.strategy_version }} <span>·</span> target weights ไม่ใช่คำสั่งซื้อขาย</div>
|
||||
</div>
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead><tr><th>อันดับ</th><th>หุ้น</th><th>ทิศทาง</th><th>Score</th><th>Exposure</th><th>เหตุผล</th><th>Target</th><th></th></tr></thead>
|
||||
<tbody>
|
||||
<tr v-for="signal in signals" :key="signal.symbol">
|
||||
<td class="muted-cell">{{ String(signal.rank).padStart(2, '0') }}</td>
|
||||
<td><strong class="symbol-name">{{ signal.symbol }}</strong><span class="confidence-cell">{{ Math.round(signal.confidence * 100) }}% confidence</span></td>
|
||||
<td><span class="side-pill" :class="signal.side.toLowerCase()">{{ signal.side }}</span></td>
|
||||
<td class="score-cell" :class="signal.score >= 0 ? 'positive-text' : 'negative-text'">{{ signal.score >= 0 ? '+' : '' }}{{ formatNumber(signal.score) }}</td>
|
||||
<td>{{ signal.coefficient >= 0 ? '+' : '' }}{{ formatNumber(signal.coefficient) }}</td>
|
||||
<td><span class="reason-code" v-for="code in signal.reason_codes" :key="code">{{ code }}</span></td>
|
||||
<td class="target-cell">{{ signal.target_weight >= 0 ? '+' : '' }}{{ (signal.target_weight * 100).toFixed(1) }}%</td>
|
||||
<td><button class="row-action" @click="chooseSignal(signal)">Paper entry</button></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="panel research-panel" id="research-run">
|
||||
<div class="panel-header">
|
||||
<div>
|
||||
<div class="section-kicker">04 / Research run</div>
|
||||
<h2>หลักฐานพอจะรองรับ study เชิงพรรณนาไหม?</h2>
|
||||
</div>
|
||||
<button class="primary-button" :disabled="researchRunning" @click="runResearch">{{ researchRunning ? 'กำลังรัน…' : 'รัน exploratory study' }}</button>
|
||||
</div>
|
||||
<div v-if="researchRun" class="research-grid">
|
||||
<div>
|
||||
<div class="research-status" :class="researchRun.result_scope === 'non_pit_descriptive_only' ? 'status-descriptive' : researchRun.status === 'ready' ? 'status-ready' : 'status-blocked'">{{ researchRun.result_scope === 'non_pit_descriptive_only' ? 'descriptive only' : displayLabel(researchRun.status) }}</div>
|
||||
<div class="research-reason">{{ researchReason(researchRun) }}</div>
|
||||
<div class="research-meta">Run {{ researchRun.run_id }} · {{ formatDate(researchRun.generated_at) }} · {{ displayLabel(researchRun.result_scope) }}</div>
|
||||
</div>
|
||||
<div class="gate-list">
|
||||
<div class="gate-row"><span>Independent vintages</span><strong>{{ researchRun.gates.vintages.available_events }} / {{ researchRun.gates.vintages.required_events }} · {{ displayLabel(researchRun.gates.vintages.status) }}</strong></div>
|
||||
<div class="gate-row"><span>ราคา</span><strong>{{ displayLabel(researchRun.gates.prices.quality) || 'ไม่มี' }} · {{ displayLabel(researchRun.gates.prices.status) }}</strong></div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="researchRun?.result?.windows" class="research-results">
|
||||
<div v-for="(windowResult, windowKey) in researchRun.result.windows" :key="windowKey" class="research-result-row">
|
||||
<span>+{{ windowKey }} sessions</span>
|
||||
<strong :class="windowResult.net_return >= 0 ? 'positive-text' : 'negative-text'">{{ (windowResult.net_return * 100).toFixed(2) }}% net</strong>
|
||||
<span>{{ (windowResult.hit_rate * 100).toFixed(0) }}% hit · {{ windowResult.event_count }} events</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!researchRun" class="empty-research">ยังไม่มี frozen research run. รันการตรวจเพื่อเก็บ input กับ gate decision ปัจจุบัน.</div>
|
||||
</section>
|
||||
|
||||
<!-- Sections 01-04 (tourism-only surprise, provenance, signal table, frozen research) removed per user: superseded by the 3-theme panel + sources table above. -->
|
||||
<section class="panel sim-panel" id="simulation">
|
||||
<div class="panel-header signal-header">
|
||||
<div>
|
||||
@@ -697,9 +598,15 @@ onMounted(loadDashboard)
|
||||
<section class="bottom-grid">
|
||||
<article class="panel thesis-panel">
|
||||
<div class="section-kicker">05 / บันทึกการวิเคราะห์</div>
|
||||
<h2>อ่านสัญญาณเป็นสมมติฐาน.</h2>
|
||||
<p>ข้อมูล tourism {{ summary.theme_surprise >= 0 ? 'สูงกว่า' : 'ต่ำกว่า' }}ค่าที่คาด เป็นตัวกำหนดว่าหุ้นตัวไหนได้ score บวกหรือลบ ระบบหยุดก่อนสั่ง execution — ยังต้องมีคน review valuation, price-in, liquidity และ risk.</p>
|
||||
<div class="thesis-rule"><span></span>Surprise × Exposure × Confidence</div>
|
||||
<h2>อ่านสัญญาณเป็นสมมติฐาน (3 ธีม).</h2>
|
||||
<div class="thesis-list">
|
||||
<div v-for="t in dashboardThemes" :key="t.id" class="thesis-row">
|
||||
<strong class="thesis-theme">{{ t.label_th }}</strong>
|
||||
<span class="thesis-text">{{ t.thesis || '—' }}</span>
|
||||
<span class="thesis-surprise">{{ t.surprise != null ? formatNumber(t.surprise,2) + 'σ' : '—' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="thesis-rule"><span></span>ความต่าง (surprise) × การเข้าถึงธีม × ความเชื่อมั่น</div>
|
||||
</article>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@@ -144,6 +144,12 @@ tbody tr:hover { background: rgba(255,255,255,.025); }
|
||||
.source-name { color: var(--accent); }
|
||||
.combined-cell { color: var(--mint); font-weight: 600; font-family: 'DM Mono', monospace; }
|
||||
|
||||
.thesis-list { display: flex; flex-direction: column; gap: 10px; margin: 12px 0; }
|
||||
.thesis-row { display: flex; gap: 10px; align-items: baseline; padding-bottom: 8px; border-bottom: 1px solid var(--line-weak, rgba(255,255,255,.05)); }
|
||||
.thesis-theme { min-width: 130px; color: var(--accent); }
|
||||
.thesis-text { flex: 1; font-size: 12px; color: var(--text-2, #99a); }
|
||||
.thesis-surprise { font-family: 'DM Mono', monospace; color: var(--mint); }
|
||||
|
||||
/* ---- Simulation panel ---- */
|
||||
.sim-panel { margin-top: 18px; }
|
||||
.sim-controls { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; margin-bottom: 14px; }
|
||||
|
||||
Reference in New Issue
Block a user