feat(chart): 10m 실시간 / 일·주·월 토글 / 오늘 마커 / 예측 거래일 선택
- backend/app/api/chart.py: interval=10m|1d|1w|1mo. 10m 은 ohlcv_1m 을 time_bucket(10min) 으로 집계, stale(>10분) 이면 KIS 분봉 fetch 후 재조회. 1w/1mo 는 ohlcv_daily 를 date_trunc 로 집계. today 필드 추가. - backend/app/fetch/kis.py: fetch_minute_price() 추가 (tr_id FHKST03010200). KIS 응답 KST 시각을 tz-aware datetime 으로 변환, 오름차순 정렬. - web/lib/api.ts: ChartInterval 타입, getChart(interval), predict(horizons[]). - web/components/StockChart.tsx: 10m 이면 timeVisible. 일·주·월에서 오늘 화살표 마커 표시. ISO datetime 도 파싱. - web/components/PredictionPanel.tsx: 단기/중기/장기 프리셋 + 사용자 직접 지정 (예: 1,2,3,7). API 에 horizons 배열 전달. - web/app/[code]/page.tsx: interval 칩 (10분/일/주/월). 10m 일 때 60초마다 폴링. interval 별 기본 lookback (10m=1, 1d=180, 1w=730, 1mo=1825).
This commit is contained in:
@@ -42,6 +42,7 @@ export type SymbolSearch = {
|
||||
};
|
||||
|
||||
export type OhlcvPoint = {
|
||||
// 1d/1w/1mo: 'YYYY-MM-DD' / 10m: 'YYYY-MM-DDTHH:MM:SS' (KST naive ISO)
|
||||
date: string;
|
||||
open: number | null;
|
||||
high: number | null;
|
||||
@@ -50,6 +51,8 @@ export type OhlcvPoint = {
|
||||
volume: number | null;
|
||||
};
|
||||
|
||||
export type ChartInterval = "10m" | "1d" | "1w" | "1mo";
|
||||
|
||||
export type SentimentPoint = {
|
||||
date: string;
|
||||
n_articles: number;
|
||||
@@ -68,7 +71,10 @@ export type ChartPayload = {
|
||||
code: string;
|
||||
name: string;
|
||||
market: string;
|
||||
interval: ChartInterval;
|
||||
intraday_status: string | null;
|
||||
range: { from: string; to: string };
|
||||
today: string;
|
||||
ohlcv: OhlcvPoint[];
|
||||
sentiment: SentimentPoint[];
|
||||
trading_value: TradingValuePoint[];
|
||||
@@ -178,13 +184,17 @@ export const api = {
|
||||
`/api/symbols/search?q=${encodeURIComponent(q)}&limit=${limit}&seed_only=${seedOnly}`,
|
||||
),
|
||||
getSymbol: (code: string) => getJson<Symbol>(`/api/symbols/${encodeURIComponent(code)}`),
|
||||
getChart: (code: string, days = 180) =>
|
||||
getJson<ChartPayload>(`/api/chart/${encodeURIComponent(code)}?days=${days}`),
|
||||
predict: (code: string, horizons = "1,3,5") =>
|
||||
getJson<PredictResponse>(
|
||||
`/api/predict/${encodeURIComponent(code)}?horizons=${encodeURIComponent(horizons)}`,
|
||||
{ method: "POST" },
|
||||
getChart: (code: string, days = 180, interval: ChartInterval = "1d") =>
|
||||
getJson<ChartPayload>(
|
||||
`/api/chart/${encodeURIComponent(code)}?days=${days}&interval=${encodeURIComponent(interval)}`,
|
||||
),
|
||||
predict: (code: string, horizons: string | number[] = "1,3,5") => {
|
||||
const h = Array.isArray(horizons) ? horizons.join(",") : horizons;
|
||||
return getJson<PredictResponse>(
|
||||
`/api/predict/${encodeURIComponent(code)}?horizons=${encodeURIComponent(h)}`,
|
||||
{ method: "POST" },
|
||||
);
|
||||
},
|
||||
latestPrediction: (code: string) =>
|
||||
getJson<LatestPredictionResponse>(`/api/predict/${encodeURIComponent(code)}/latest`),
|
||||
metrics: (code: string, windowDays = 30) =>
|
||||
|
||||
Reference in New Issue
Block a user