[F4] /api/portfolio 응답의 summary.total_buy가 종목별 단가 × 수량의 합이 되도록 fix. 기존 인라인 코드가 purchase_price를 수량 미곱산으로 단순 누적해 명세(qty 100 · avg 72000 → 7,200,000)와 어긋났음. API_SPEC.md에 purchase_price 필드 의미 + total_buy 계산식 명시. test 3건 (단가 곱산, avg_price 폴백, 다종목 합산). [F6] insta-trends spec/plan 상단에 "google_trends → youtube_trending" 변경 이력 추가. Google Trends endpoint 폐기로 source 교체된 이력이 본문 검색 시 혼란 주는 문제 차단. 사유 cross-ref: feedback_external_data_sources.md
5.8 KiB
📈 Stock Lab API Specification
프론트엔드 연동을 위한 주식 서비스 API 명세서입니다.
Base URL: /api
1. 💰 계좌 잔고 조회
현재 연결된 한국투자증권 계좌의 잔고와 보유 종목을 조회합니다.
- URL:
/trade/balance - Method:
GET - Description: Windows AI Server를 통해 실시간 잔고를 가져옵니다.
Response Example
{
"holdings": [
{
"code": "005930",
"name": "삼성전자",
"qty": 10,
"buy_price": 72000.0,
"current_price": 74500.0,
"profit_rate": 3.47
}
],
"summary": {
"total_eval": 15400000,
"deposit": 5000000,
"note": "정상 조회됨"
}
}
2. 🤖 AI 자동 매매 (분석/주문)
AI에게 현재 잔고와 뉴스를 기반으로 매매 판단을 요청합니다.
- URL:
/trade/auto - Method:
POST - Description: 분석에는 수 초~수십 초가 소요될 수 있습니다. (타임아웃 주의)
Response Example (성공 - JSON 파싱 완료)
{
"status": "success",
"decision": {
"action": "BUY",
"ticker": "000660",
"quantity": 10,
"reason": "반도체 업황 개선 뉴스 다수 포착 및 현금 비중 과다"
},
"trade_result": {
"success": true,
"order_no": "1234567"
}
}
Response Example (실패 - AI가 JSON을 안 줬을 때)
AI가 말로 설명하느라 JSON 포맷을 어긴 경우입니다. raw_response를 화면에 그대로 보여주는 것을 권장합니다.
{
"status": "failed_parse",
"raw_response": "잔고 현황을 분석해 보겠습니다...\n결정:\n```\n{\n ... \n}\n```"
}
Frontend 처리 권장사항: status가 failed_parse라면 raw_response 텍스트를 pre 태그 등으로 그대로 노출하거나, 정규식으로 JSON 부분만 추출하여 보여주세요.
3. 📰 뉴스 조회
DB에 저장된 최신 뉴스를 조회합니다.
- URL:
/stock/news - Method:
GET - Params:
limit: 개수 (기본 20)category:domestic(국내) |overseas(해외)
Response Example
[
{
"id": 105,
"title": "삼성전자, 3분기 영업익 2.4조... 전년비 77% 감소",
"link": "https://n.news.naver.com/...",
"published_at": "2024-09-25T09:00:00",
"sentiment": "negative"
}
]
4. 📊 지수 조회
KOSPI, KOSDAQ 등 주요 지수를 조회합니다.
- URL:
/stock/indices - Method:
GET
Response Example
{
"KOSPI": {
"value": "2450.55",
"change": "-10.23",
"percent": "-0.42%"
},
"USD/KRW": {
"value": "1340.50",
"change": "5.00",
"percent": "0.37%"
}
}
5. 📂 포트폴리오 (수동 입력)
KB증권·삼성증권 등 Open API 미제공 증권사용. 보유 종목을 수동 등록하면 현재가는 네이버 금융에서 자동 조회 (3분 캐시)하여 손익을 계산해 반환합니다.
5-1. 전체 조회
- URL:
GET /portfolio - Description: 등록된 모든 종목의 현재가·평가금액·손익을 포함하여 반환합니다.
Response
{
"holdings": [
{
"id": 1,
"broker": "KB증권",
"ticker": "005930",
"name": "삼성전자",
"quantity": 100,
"avg_price": 72000,
"purchase_price": 72000,
"current_price": 74500,
"price_session": "NXT_AFTER",
"price_as_of": "2026-05-11T19:21:40+09:00",
"eval_amount": 7450000,
"profit_amount": 250000,
"profit_rate": 3.47
}
],
"summary": {
"total_buy": 7200000,
"total_eval": 7450000,
"total_profit": 250000,
"total_profit_rate": 3.47
}
}
purchase_price필드: 종목별 매입 단가(1주당). 사용자가 수동 등록한 매입가가 평균단가(avg_price)와 다를 때 표시용으로 분리한다. 미설정 시avg_price로 폴백.summary.total_buy = SUM(purchase_price × quantity)(CODE_REVIEW F4에서 명세 정합화).
주의: 현재가 조회에 실패한 종목은
current_price,eval_amount,profit_amount,profit_rate가null로 반환됩니다. 프론트에서null체크 후"조회 실패"등으로 표시해 주세요.
현재가 출처(
price_session): 정규장 마감 후 NXT 시간외 거래가 진행 중이면 NXT 가격으로 자동 전환됩니다.
REGULAR— KRX 정규장 진행중(09:00–15:30) 실시간 가격NXT_PRE— NXT 프리마켓(08:00–08:50) 거래가NXT_AFTER— NXT 애프터마켓(15:30–20:00) 거래가CLOSED— 모든 세션 마감, 정규장 종가 노출
price_as_of는 가격이 마지막으로 형성된 시각(ISO 8601, KST). HTML 폴백 경로에서는null일 수 있음.
5-2. 종목 추가
- URL:
POST /portfolio - Status:
201 Created
Request Body
{
"broker": "KB증권",
"ticker": "005930",
"name": "삼성전자",
"quantity": 100,
"avg_price": 72000
}
| 필드 | 타입 | 설명 |
|---|---|---|
broker |
string | 증권사명 (자유 입력) |
ticker |
string | 종목 코드 6자리 |
name |
string | 종목명 |
quantity |
integer | 보유 수량 |
avg_price |
integer | 평균 매입가 (원) |
Response
{ "id": 1, "ok": true }
5-3. 종목 수정
- URL:
PUT /portfolio/{id} - Description: 변경할 필드만 포함하면 됩니다 (부분 수정).
Request Body (모든 필드 Optional)
{ "quantity": 150 }
Response
{ "ok": true }
Error (존재하지 않는 id)
{ "error": "Item not found" } // HTTP 404
5-4. 종목 삭제
- URL:
DELETE /portfolio/{id}
Response
{ "ok": true }
Error (존재하지 않는 id)
{ "error": "Item not found" } // HTTP 404