ข้อมูล tourism {{ summary.theme_surprise >= 0 ? 'สูงกว่า' : 'ต่ำกว่า' }}ค่าที่คาด เป็นตัวกำหนดว่าหุ้นตัวไหนได้ score บวกหรือลบ ระบบหยุดก่อนสั่ง execution — ยังต้องมีคน review valuation, price-in, liquidity และ risk.
diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 2897d3b..9ce6051 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -6,6 +6,10 @@ const observations = ref(null) const signalData = ref(null) const factorData = ref(null) const themeData = ref(null) +const simCapital = ref(1000000) +const simMode = ref('backtest') +const simLoading = ref(false) +const simResult = ref(null) const dividendOnly = ref(false) const sortKey = ref('signal_score') const sortDirection = ref('desc') @@ -189,6 +193,27 @@ async function runResearch() { } } +const simOrders = computed(() => simResult.value?.orders ?? []) +const simInvested = computed(() => simResult.value?.invested ?? 0) +const simUnallocated = computed(() => simResult.value?.unallocated_cash ?? 0) +const bucketOrders = (n) => simOrders.value.filter((o) => o.bucket === n) + +async function runSimulation() { + simLoading.value = true + simResult.value = null + try { + simResult.value = await fetchJson('/api/v1/simulation', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ capital: Number(simCapital.value), mode: simMode.value }), + }) + } catch (caught) { + notice.value = caught.message + } finally { + simLoading.value = false + } +} + async function loadDashboard() { loading.value = true error.value = '' @@ -312,6 +337,7 @@ onMounted(loadDashboard) ปัจจัย ที่มาข้อมูล งานวิจัย + จำลอง