一、 系統功能與核心業務流程
本模組的核心目標在於將用戶碎片化的交易紀錄與持股動態,轉化為直觀、可量化的資產績效指標。
1.1 系統核心功能
- 即時資產清算:整合帳戶剩餘現金與台股即時市場報價,計算總資產淨值(NAV)。
- 多維度損益計算:區分「未實現損益(帳面損益)」與「已實現損益(已平倉結算)」,並精準扣除交易成本。
- 資產配置動態分析:即時計算各標的佔比,防止單一股票權重過高。
- 社交化績效競賽:透過全站 ROI 排名與同儕標竿(Benchmarking),提升平台的互動性與遊戲化體驗。
1.2 系統業務流程圖
系統必須在確保即時股價更新的同時,兼顧資料庫的讀取效能。以下為資產結算與圖表產生的標準作業流程:
+-------------------+
| 使用者登入 |
+---------+---------+
|
v
+-------------------+
| 讀取帳戶現金餘額 |
+---------+---------+
|
v
+-------------------+
| 讀取歷史持股庫存 |
+---------+---------+
|
v
+-------------------+
| 呼叫 API 取得 |
| 台灣股市即時報價 |
+---------+---------+
|
v
+-------------------+ +-------------------+
| 計算股票當前市值 +------>+ 計算未實現/已實現 |
+---------+---------+ | 損益 |
| +-------------------+
v
+-------------------+
| 計算當前總資產 |
+---------+---------+
|
v
+-------------------+
| 計算投資報酬率ROI |
+---------+---------+
|
v
+-------------------+
| 寫入 Redis 快取 |
+---------+---------+
|
v
+-------------------+
| 產生前後端視覺化 |
| 儀表板與排行數據 |
+-------------------+

二、 核心計算公式與進階金融指標
為了讓虛擬交易平台更貼近真實市場,計算公式除了基礎的 ROI 外,必須引入摩擦成本(交易稅費)與風險調整後報酬。
2.1 基礎資產與損益公式

2.2 專業FinTech進階指標
若要將模組提升至專業券商或基金分析等級,系統需在每日收盤後(EOD)增算以下指標:

三、 高效能關聯式資料庫設計(MySQL)
考慮到高頻交易與大數據排行,資料表設計採用了嚴格的正規化,並針對外鍵(Foreign Key)與索引(Index)進行優化,以確保在高併發查詢下依然流暢。
SQL
-- 1. 使用者主表:記錄初始與當前資產金額
CREATE TABLE users (
user_id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
initial_cash DECIMAL(14,2) NOT NULL DEFAULT 1000000.00 COMMENT '初始虛擬資金',
cash_balance DECIMAL(14,2) NOT NULL DEFAULT 1000000.00 COMMENT '可用現金餘額',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_cash (cash_balance)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 2. 股票標的行情表:記錄真實台股商品資訊與即時報價
CREATE TABLE stocks (
stock_id INT AUTO_INCREMENT PRIMARY KEY,
stock_code VARCHAR(20) NOT NULL UNIQUE COMMENT '股票代號, 如 2330',
stock_name VARCHAR(50) NOT NULL COMMENT '股票名稱, 如 台積電',
current_price DECIMAL(10,2) NOT NULL COMMENT '當前市價',
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_code (stock_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 3. 使用者庫存持股表:採用平均成本法
CREATE TABLE holdings (
holding_id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
stock_id INT NOT NULL,
quantity INT NOT NULL DEFAULT 0 COMMENT '目前持股股數',
average_cost DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '平均加權買入成本',
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uq_user_stock (user_id, stock_id),
FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE,
FOREIGN KEY (stock_id) REFERENCES stocks(stock_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 4. 交易流水明細表:用於完整追溯與對帳
CREATE TABLE transactions (
transaction_id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
stock_id INT NOT NULL,
transaction_type ENUM('BUY', 'SELL') NOT NULL,
quantity INT NOT NULL,
price DECIMAL(10,2) NOT NULL COMMENT '成交價格',
fee DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '手續費',
tax DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '證券交易稅',
total_amount DECIMAL(14,2) NOT NULL COMMENT '淨交割金額(買入含稅費, 賣出扣稅費)',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(user_id),
FOREIGN KEY (stock_id) REFERENCES stocks(stock_id),
INDEX idx_user_tx (user_id, created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
四、 後端核心績效計算與真實台股行情改編(PHP)
以下程式碼導入了當前真實台股權值股行情作為數據基礎(假設初始投入 2,000,000 元台幣,配置於台積電與鴻海,並保留剩餘現金)。
PHP
<?php
declare(strict_types=1);
/**
* 計算用戶最新的投資組合績效與回報率
* * @param float $initialCash 初始原始資金
* @param float $cashBalance 當前可用現金
* @param array $holdings 包含即時市價的庫存陣列
* @return array 運算後的績效指標
*/
function calculateAdvancedPerformance(float $initialCash, float $cashBalance, array $holdings): array {
$stockTotalMarketValue = 0.0;
$totalCostValue = 0.0;
$unrealizedProfitDetails = [];
foreach ($holdings as $stock) {
// 市值 = 庫存股數 * 當前股價
$marketValue = $stock['quantity'] * $stock['current_price'];
// 成本 = 庫存股數 * 平均成本
$costValue = $stock['quantity'] * $stock['average_cost'];
// 考量真實交易摩擦成本(以台股賣出時預估:手續費0.1425% + 證交稅0.3% = 約 0.4425%)
$estimatedFriction = $marketValue * 0.004425;
$unrealizedProfit = $marketValue - $costValue - $estimatedFriction;
$stockTotalMarketValue += $marketValue;
$totalCostValue += $costValue;
$unrealizedProfitDetails[] = [
'stock_name' => $stock['stock_name'],
'market_value' => $marketValue,
'unrealized_profit' => $unrealizedProfit,
'roi_individual' => $costValue > 0 ? ($unrealizedProfit / $costValue) * 100 : 0.0
];
}
// 總資產 = 現金餘額 + 股票總市值
$totalAsset = $cashBalance + $stockTotalMarketValue;
// 總投資報酬率 (ROI)
$totalRoi = $initialCash > 0 ? (($totalAsset - $initialCash) / $initialCash) * 100 : 0.0;
// 淨未實現總損益
$netUnrealizedProfit = $stockTotalMarketValue - $totalCostValue;
return [
'stock_total_value' => $stockTotalMarketValue,
'total_asset' => $totalAsset,
'net_unrealized' => $netUnrealizedProfit,
'total_roi' => $totalRoi,
'details' => $unrealizedProfitDetails
];
}
// === 實務模擬:真實台股行情配置案例 ===
$initialCash = 2000000.00; // 初始資金兩百萬台幣
$cashBalance = 415000.00; // 剩餘可用現金
// 帶入真實股票市場情境數據
$holdings = [
[
'stock_code' => '2330',
'stock_name' => '台積電',
'quantity' => 1000, // 1張
'average_cost' => 820.00, // 過去買入波段低點成本
'current_price' => 1040.00 // 突破千元後的真實市價
],
[
'stock_code' => '2317',
'stock_name' => '鴻海',
'quantity' => 3000, // 3張
'average_cost' => 150.00, // 買入成本
'current_price' => 215.00 // 現階段真實波段高點
]
];
// 執行核心運算
$performanceResult = calculateAdvancedPerformance($initialCash, $cashBalance, $holdings);
// 輸出標準 JSON 格式提供前端呼叫 API
header('Content-Type: application/json; charset=utf-8');
echo json_encode($performanceResult, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>
五、 前端 UI 儀表板與 Chart.js 資料視覺化
前端採用響應式卡片設計(Responsive Grid),並透過 Chart.js 繪製符合現代金融美學的「長條圖(資產損益比較)」與「圓餅圖(資產配置比例)」。
5.1 HTML/CSS 儀表板面板
HTML
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<title>專業投資績效分析儀表板</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
:root {
--bg-profit: #ebfcf2;
--text-profit: #0fd25b;
--bg-loss: #fcebeb;
--text-loss: #e61919;
--navy-dark: #1a252f;
}
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; background-color: #f4f6f9; color: #333; margin: 0; padding: 20px; }
.dashboard-container { max-width: 1200px; margin: 0 auto; }
.header-title { text-align: left; color: var(--navy-dark); font-size: 28px; margin-bottom: 25px; border-left: 6px solid #3498db; padding-left: 15px; }
/* 核心指標卡片區 */
.metrics-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 20px; margin-bottom: 30px; }
.metric-card { background: #fff; border-radius: 8px; padding: 20px; box-shadow: 0 4px 6px rgba(0,0,0,0.05); border: 1px solid #e1e8ed; }
.metric-card h3 { margin: 0 0 10px 0; font-size: 14px; color: #7f8c8d; text-transform: uppercase; }
.metric-card p { margin: 0; font-size: 26px; font-weight: 700; color: var(--navy-dark); }
/* 損益顏色級別 */
.status-profit { background-color: var(--bg-profit) !important; color: var(--text-profit) !important; padding: 2px 8px; border-radius: 4px; }
.status-loss { background-color: var(--bg-loss) !important; color: var(--text-loss) !important; padding: 2px 8px; border-radius: 4px; }
.text-profit { color: var(--text-profit) !important; }
/* 圖表與看盤區佈局 */
.visual-section { display: grid; grid-template-columns: 2fr 1fr; gap: 20px; margin-bottom: 30px; }
@media (max-width: 868px) { .visual-section { grid-template-columns: 1fr; } }
.chart-box { background: #fff; border-radius: 8px; padding: 20px; box-shadow: 0 4px 6px rgba(0,0,0,0.05); min-height: 320px; }
.chart-box h3 { margin-top: 0; margin-bottom: 15px; font-size: 16px; color: var(--navy-dark); }
/* 資料表格樣式 */
.table-box { background: #fff; border-radius: 8px; padding: 20px; box-shadow: 0 4px 6px rgba(0,0,0,0.05); margin-bottom: 30px; overflow-x: auto; }
.premium-table { width: 100%; border-collapse: collapse; text-align: right; }
.premium-table th { background-color: var(--navy-dark); color: #fff; padding: 12px 15px; font-weight: 500; text-align: right; }
.premium-table th:first-child, .premium-table td:first-child { text-align: left; }
.premium-table td { padding: 14px 15px; border-bottom: 1px solid #edf2f7; font-size: 15px; }
.premium-table tr:hover { background-color: #f8fafc; }
</style>
</head>
<body>
<div class="dashboard-container">
<div class="header-title">投資績效智慧分析儀表板</div>
<div class="metrics-grid">
<div class="metric-card">
<h3>初始資本額 (TWD)</h3>
<p>2,000,000</p>
</div>
<div class="metric-card">
<h3>可用現金餘額</h3>
<p>415,000</p>
</div>
<div class="metric-card">
<h3>目前總資產淨值</h3>
<p>2,100,000</p>
</div>
<div class="metric-card">
<h3>帳戶總投資報酬率</h3>
<p class="text-profit">+5.00%</p>
</div>
</div>
<div class="visual-section">
<div class="chart-box">
<h3>持股標的損益對比(長條圖趨勢)</h3>
<canvas id="barProfitChart"></canvas>
</div>
<div class="chart-box">
<h3>資產權重配置(圓餅圖比例)</h3>
<canvas id="piePortfolioChart"></canvas>
</div>
</div>
<div class="table-box">
<h3 style="margin-top:0;">目前台股現股持股明細</h3>
<table class="premium-table">
<thead>
<tr>
<th>股票名稱(代號)</th>
<th>持股股數</th>
<th>平均買入成本</th>
<th>市場現價</th>
<th>當前股票市值</th>
<th>未實現損益(預估)</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>台積電 (2330)</strong></td>
<td>1,000</td>
<td>$820.00</td>
<td>$1,040.00</td>
<td>$1,040,000</td>
<td><span class="status-profit">+$220,000</span></td>
</tr>
<tr>
<td><strong>鴻海 (2317)</strong></td>
<td>3,000</td>
<td>$150.00</td>
<td>$215.00</td>
<td>$645,000</td>
<td><span class="status-profit">+$195,000</span></td>
</tr>
</tbody>
</table>
</div>
</div>
5.2 Chart.js 圖表建構邏輯代碼
將下方 JavaScript 腳本串接於上述 HTML 閉合標籤前,即可自動渲染出符合專業投行視覺標準的資料圖表。
HTML
<script>
// 1. 長條圖 (Bar Chart) - 標的投資金額與損益對比
const barCtx = document.getElementById('barProfitChart').getContext('2d');
new Chart(barCtx, {
type: 'bar',
data: {
labels: ['台積電 (2330)', '鴻海 (2317)'],
datasets: [
{
label: '原始投入成本',
data: [820000, 450000],
backgroundColor: 'rgba(52, 152, 219, 0.75)',
borderColor: 'rgba(52, 152, 219, 1)',
borderWidth: 1
},
{
label: '當前最新市值',
data: [1040000, 645000],
backgroundColor: 'rgba(46, 204, 113, 0.75)',
borderColor: 'rgba(46, 204, 113, 1)',
borderWidth: 1
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
ticks: { callback: function(value) { return '$' + value.toLocaleString(); } }
}
}
}
});
// 2. 圓餅圖 (Pie Chart) - 多元資產配置分散權重
const pieCtx = document.getElementById('piePortfolioChart').getContext('2d');
new Chart(pieCtx, {
type: 'pie',
data: {
labels: ['台積電市值', '鴻海市值', '帳戶可用現金'],
datasets: [{
data: [1040000, 645000, 415000],
backgroundColor: [
'#2c3e50', // 深藍 (核心權值股)
'#e67e22', // 橘色 (次要資產)
'#bdc3c7' // 灰色 (現金流)
],
borderWidth: 2
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { position: 'bottom' }
}
}
});
</script>
</body>
</html>


六、 社交化排行與資料庫查詢優化
在多用戶的大型交易平台中,即時計算全站排行極耗效能。在實務上,我們應在計算公式中建立快取欄位或採用中繼統計表(Materialized View/Summary Table),並利用高效率 SQL Window Function 產出即時排名。
SQL
-- 使用視窗函數(Window Function)進行全站交易績效排行查詢
SELECT
user_id,
username,
cash_balance + IFNULL(stock_market_value, 0) AS total_net_assets,
initial_cash,
-- 核心 ROI 計算公式
ROUND(((cash_balance + IFNULL(stock_market_value, 0) - initial_cash) / initial_cash) * 100, 2) AS roi_percentage,
-- 產生連續不跳躍的精確排名
DENSE_RANK() OVER (ORDER BY ((cash_balance + IFNULL(stock_market_value, 0) - initial_cash) / initial_cash) DESC) AS global_rank
FROM (
SELECT
u.user_id,
u.username,
u.initial_cash,
u.cash_balance,
SUM(h.quantity * s.current_price) AS stock_market_value
FROM users u
LEFT JOIN holdings h ON u.user_id = h.user_id
LEFT JOIN stocks s ON h.stock_id = s.stock_id
GROUP BY u.user_id
) AS account_summary
ORDER BY global_rank ASC
LIMIT 100;
七、 結論與 FinTech 進階發展規劃
本報告所規劃的「投資績效分析模組」,在功能面與技術架構上均具備了商業化虛擬交易系統的基礎雛形。透過自動化清算機制、真實摩擦成本模擬,以及直觀的 Chart.js 視覺化圖表,能有效幫助使用者客觀、科學地檢視個人交易策略。
未來升級發展規劃(Roadmap)
為了邁向更專業的數位資產管理(WealthTech)平台,本模組未來可循以下三個方向進行深化:
- 異步排程結算 (Batch Processing):當用戶數破萬時,全面改用後端 CRON Job 或監聽 MySQL Binlog,於非交易時段異步計算總體排行,並將靜態圖表封裝快取至 Redis。
- 導入基準指數對比 (Benchmark Comparison):於長條圖中加入「大盤指數(如台股加權指數、0050)」之同期 ROI 走勢,協助用戶判斷自身績效是否成功「打敗大盤」。
- AI 風險健檢與診斷:利用機器學習分析用戶的歷史交易流水線,偵測是否有週轉率過高、過度集中單一投機股等不良交易心理,並給予智慧自動化資產配置建議。