From 9bce2bfb6e8d160ed4e821fe9a567cdad412c96e Mon Sep 17 00:00:00 2001 From: gahusb Date: Wed, 25 Mar 2026 04:42:11 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20buildAdvisorPrompt=20TDZ=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95=20=E2=80=94=20portfolioHoldings?= =?UTF-8?q?=20=EC=A0=95=EC=9D=98=20=EC=9D=B4=ED=9B=84=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- src/pages/stock/StockTrade.jsx | 161 +++++++++++++++++---------------- 1 file changed, 81 insertions(+), 80 deletions(-) diff --git a/src/pages/stock/StockTrade.jsx b/src/pages/stock/StockTrade.jsx index bf98b22..626b3e8 100644 --- a/src/pages/stock/StockTrade.jsx +++ b/src/pages/stock/StockTrade.jsx @@ -287,86 +287,6 @@ const StockTrade = () => { } }, []); - /* AI 어드바이저: 포트폴리오 기반 프롬프트 생성 */ - const buildAdvisorPrompt = useCallback(() => { - const today = new Date().toLocaleDateString('ko-KR', { year: 'numeric', month: 'long', day: 'numeric' }); - - const holdingsLines = portfolioHoldings.map((h) => { - const cp = h.current_price != null ? `${formatNumber(h.current_price)}원` : '시세 미조회'; - const rate = h.profit_rate != null ? formatPercent(h.profit_rate) : '미조회'; - const profit = h.profit_amount != null ? `(${h.profit_amount >= 0 ? '+' : ''}${formatNumber(h.profit_amount)}원)` : ''; - return `- **${h.name ?? h.ticker}** (${h.ticker ?? ''}) | 계좌: ${h.broker ?? '-'} - 수량 ${h.quantity}주 | 평균매입가 ${formatNumber(h.avg_price)}원 | 현재가 ${cp} | 손익 ${rate} ${profit}`; - }).join('\n'); - - const cashLines = cashList.map((c) => `- ${c.broker}: ${formatNumber(c.cash)}원`).join('\n') || '- 없음'; - - const marketLines = marketCtx - ? [ - `VIX: ${marketCtx.vix != null ? `${marketCtx.vix} (${getVixLabel(marketCtx.vix)})` : '데이터 없음'}`, - `공포탐욕지수: ${marketCtx.fg != null ? `${marketCtx.fg}점 (${getFgLabel(marketCtx.fg)})` : '데이터 없음'}`, - `미 10년물 국채: ${marketCtx.treasury != null ? `${marketCtx.treasury}%` : '데이터 없음'}`, - `WTI 유가: ${marketCtx.wti != null ? `$${marketCtx.wti}` : '데이터 없음'}`, - ].join('\n') - : '시장 데이터 미로드'; - - return `당신은 15년 이상 경력의 한국 주식시장 전문 애널리스트입니다. -오늘은 ${today}입니다. 아래 포트폴리오 정보와 시장 환경을 바탕으로 전문가 분석을 제공해주세요. - ---- - -## 📊 현재 시장 환경 - -${marketLines} - ---- - -## 💼 보유 포트폴리오 - -### 보유 종목 (${portfolioHoldings.length}개) - -${holdingsLines || '보유 종목 없음'} - -### 포트폴리오 요약 - -- 총 매입금액: ${formatNumber(portfolioSummary.total_buy)}원 -- 총 평가금액: ${formatNumber(portfolioSummary.total_eval)}원 -- 총 손익: ${formatNumber(portfolioSummary.total_profit)}원 (수익률: ${formatPercent(portfolioSummary.total_profit_rate)}) -- 예수금 합계: ${totalCash != null ? formatNumber(totalCash) + '원' : '미입력'} -- 총 자산: ${totalAssets != null ? formatNumber(totalAssets) + '원' : '미집계'} - -### 예수금 현황 - -${cashLines} - ---- - -## 🔍 분석 요청 - -다음 형식으로 명확하게 작성해주세요: - -### 📈 오늘의 시장 환경 -시장 환경 데이터를 바탕으로 오늘 한국 주식시장의 전반적인 분위기와 주요 이슈를 2-3문장으로 요약하세요. - -### 🔍 종목별 분석 및 행동 지침 -각 보유 종목에 대해 아래 형식으로 작성하세요: - -**[종목명 (티커)]** -- 현황: 현재 손익 상태와 포지션 평가 -- 분석: 업황·섹터 동향, 주요 리스크/기회 -- 🎯 행동 지침: **[매도 / 보유 / 추가매수 / 분할매도]** — 구체적 이유와 목표 참고 가격대 - -### 💼 포트폴리오 종합 의견 -전체 포트폴리오의 섹터 편중, 리밸런싱 필요 여부, 현금 비중 조언을 작성하세요. - -### ⚠️ 오늘 주의해야 할 리스크 -매크로·섹터·개별 종목 측면에서 오늘 특히 주의할 리스크를 2-3가지 나열하세요. - ---- -분석은 반드시 한국어로, 구체적인 수치와 근거를 들어 전문적으로 작성해주세요. -투자 결정은 최종적으로 투자자 본인이 판단함을 명시하세요.`; - }, [portfolioHoldings, portfolioSummary, cashList, totalCash, totalAssets, marketCtx]); - const loadBalance = useCallback(async () => { setBalanceLoading(true); setBalanceError(''); @@ -923,6 +843,87 @@ ${holdingsText}${marketText} const cashList = portfolio?.cash ?? []; const totalCash = portfolioSummary.total_cash ?? null; const totalAssets = portfolioSummary.total_assets ?? null; + + /* AI 어드바이저: 포트폴리오 기반 프롬프트 생성 */ + const buildAdvisorPrompt = useCallback(() => { + const today = new Date().toLocaleDateString('ko-KR', { year: 'numeric', month: 'long', day: 'numeric' }); + + const holdingsLines = portfolioHoldings.map((h) => { + const cp = h.current_price != null ? `${formatNumber(h.current_price)}원` : '시세 미조회'; + const rate = h.profit_rate != null ? formatPercent(h.profit_rate) : '미조회'; + const profit = h.profit_amount != null ? `(${h.profit_amount >= 0 ? '+' : ''}${formatNumber(h.profit_amount)}원)` : ''; + return `- **${h.name ?? h.ticker}** (${h.ticker ?? ''}) | 계좌: ${h.broker ?? '-'} + 수량 ${h.quantity}주 | 평균매입가 ${formatNumber(h.avg_price)}원 | 현재가 ${cp} | 손익 ${rate} ${profit}`; + }).join('\n'); + + const cashLines = cashList.map((c) => `- ${c.broker}: ${formatNumber(c.cash)}원`).join('\n') || '- 없음'; + + const marketLines = marketCtx + ? [ + `VIX: ${marketCtx.vix != null ? `${marketCtx.vix} (${getVixLabel(marketCtx.vix)})` : '데이터 없음'}`, + `공포탐욕지수: ${marketCtx.fg != null ? `${marketCtx.fg}점 (${getFgLabel(marketCtx.fg)})` : '데이터 없음'}`, + `미 10년물 국채: ${marketCtx.treasury != null ? `${marketCtx.treasury}%` : '데이터 없음'}`, + `WTI 유가: ${marketCtx.wti != null ? `$${marketCtx.wti}` : '데이터 없음'}`, + ].join('\n') + : '시장 데이터 미로드'; + + return `당신은 15년 이상 경력의 한국 주식시장 전문 애널리스트입니다. +오늘은 ${today}입니다. 아래 포트폴리오 정보와 시장 환경을 바탕으로 전문가 분석을 제공해주세요. + +--- + +## 📊 현재 시장 환경 + +${marketLines} + +--- + +## 💼 보유 포트폴리오 + +### 보유 종목 (${portfolioHoldings.length}개) + +${holdingsLines || '보유 종목 없음'} + +### 포트폴리오 요약 + +- 총 매입금액: ${formatNumber(portfolioSummary.total_buy)}원 +- 총 평가금액: ${formatNumber(portfolioSummary.total_eval)}원 +- 총 손익: ${formatNumber(portfolioSummary.total_profit)}원 (수익률: ${formatPercent(portfolioSummary.total_profit_rate)}) +- 예수금 합계: ${totalCash != null ? formatNumber(totalCash) + '원' : '미입력'} +- 총 자산: ${totalAssets != null ? formatNumber(totalAssets) + '원' : '미집계'} + +### 예수금 현황 + +${cashLines} + +--- + +## 🔍 분석 요청 + +다음 형식으로 명확하게 작성해주세요: + +### 📈 오늘의 시장 환경 +시장 환경 데이터를 바탕으로 오늘 한국 주식시장의 전반적인 분위기와 주요 이슈를 2-3문장으로 요약하세요. + +### 🔍 종목별 분석 및 행동 지침 +각 보유 종목에 대해 아래 형식으로 작성하세요: + +**[종목명 (티커)]** +- 현황: 현재 손익 상태와 포지션 평가 +- 분석: 업황·섹터 동향, 주요 리스크/기회 +- 🎯 행동 지침: **[매도 / 보유 / 추가매수 / 분할매도]** — 구체적 이유와 목표 참고 가격대 + +### 💼 포트폴리오 종합 의견 +전체 포트폴리오의 섹터 편중, 리밸런싱 필요 여부, 현금 비중 조언을 작성하세요. + +### ⚠️ 오늘 주의해야 할 리스크 +매크로·섹터·개별 종목 측면에서 오늘 특히 주의할 리스크를 2-3가지 나열하세요. + +--- +분석은 반드시 한국어로, 구체적인 수치와 근거를 들어 전문적으로 작성해주세요. +투자 결정은 최종적으로 투자자 본인이 판단함을 명시하세요.`; + }, [portfolioHoldings, portfolioSummary, cashList, totalCash, totalAssets, marketCtx]); + const brokerGroups = useMemo(() => { const map = {}; for (const item of portfolioHoldings) {