feat(stock): 포트폴리오 매입가/평균단가 분리 + 총 매입 금액 반영

- 기존 카드의 "매입가" → "평균단가" (avg_price) 로 라벨 변경
- 신규 "매입가" (purchase_price) 컬럼 추가. 추가/수정 폼에 입력 필드 노출
  (미입력 시 평균단가 값으로 자동 설정)
- 브로커별 총 매입 금액은 purchase_price × quantity 합계 기준
- 손익/수익률은 평균단가(avg_price) 기준 유지

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-15 01:58:10 +09:00
parent 104a34912f
commit 18d2cd5a51
3 changed files with 54 additions and 8 deletions

View File

@@ -70,14 +70,19 @@ export default function usePortfolio() {
}, [brokerGroups]);
const getBrokerSummary = (items) => {
let totalBuy = 0, totalEvalAmt = 0, hasNullPrice = false;
// totalBuy: 요약 표시용 (매입가 purchase_price 기준)
// totalCostBasis: 손익 계산용 (평균단가 avg_price 기준)
let totalBuy = 0, totalCostBasis = 0, totalEvalAmt = 0, hasNullPrice = false;
for (const item of items) {
totalBuy += (item.avg_price ?? 0) * (item.quantity ?? 0);
const qty = item.quantity ?? 0;
const purchase = item.purchase_price ?? item.avg_price ?? 0;
totalBuy += purchase * qty;
totalCostBasis += (item.avg_price ?? 0) * qty;
if (item.eval_amount != null) totalEvalAmt += item.eval_amount;
else hasNullPrice = true;
}
const totalProfit = totalEvalAmt - totalBuy;
const totalProfitRate = totalBuy > 0 ? (totalProfit / totalBuy) * 100 : 0;
const totalProfit = totalEvalAmt - totalCostBasis;
const totalProfitRate = totalCostBasis > 0 ? (totalProfit / totalCostBasis) * 100 : 0;
return { totalBuy, totalEval: totalEvalAmt, totalProfit, totalProfitRate, hasNullPrice };
};
@@ -108,6 +113,9 @@ export default function usePortfolio() {
name: addForm.name.trim(),
quantity: Number(addForm.quantity),
avg_price: Number(addForm.avg_price),
purchase_price: addForm.purchase_price === '' || addForm.purchase_price == null
? Number(addForm.avg_price)
: Number(addForm.purchase_price),
});
setAddForm({ ...emptyPortfolioForm });
setAddFormOpen(false);
@@ -121,7 +129,13 @@ export default function usePortfolio() {
const handleEditStart = (item) => {
setEditingId(item.id);
const data = { quantity: item.quantity, avg_price: item.avg_price, broker: item.broker, name: item.name };
const data = {
quantity: item.quantity,
avg_price: item.avg_price,
purchase_price: item.purchase_price ?? item.avg_price,
broker: item.broker,
name: item.name,
};
setEditForm(data);
editOrigRef.current = { ...data };
};