POST /login
승인된 계정만 사용 가능합니다. 성공 시 JSESSIONID 쿠키가 발급됩니다.
Content-Type: application/x-www-form-urlencoded
username=USER&password=PASS
REST JSON + SSE로 해외선물·국내선물 시세를 제공합니다.
외부 플랫폼은 고정 symbol(NQ, ES …)만 키로 쓰고,
contract(근월물)는 서버가 자동 전환합니다.
전체 마크다운: 프로젝트 docs/API.md
# 로그인
curl -c cookies.txt -X POST "http://localhost:8080/login" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=YOUR_ID&password=YOUR_PASSWORD"
# 고정 종목 카탈로그 (권장)
curl -b cookies.txt "http://localhost:8080/api/market/catalog"
# 스냅샷
curl -b cookies.txt "http://localhost:8080/api/market/live"
# 실시간 SSE
curl -N -b cookies.txt "http://localhost:8080/api/market/stream"
POST /login → 쿠키 유지GET /api/market/catalog → 초기 종목·가격GET /api/market/stream → 틱 구독승인된 계정만 사용 가능합니다. 성공 시 JSESSIONID 쿠키가 발급됩니다.
Content-Type: application/x-www-form-urlencoded
username=USER&password=PASS
이후 모든 API에 쿠키를 포함하세요.
fetch("/api/market/catalog", { credentials: "include" });
| 경로 | 권한 |
|---|---|
/api/market/catalog | 로그인 사용자 |
/api/market/live | 로그인 사용자 |
/api/market/stream | 로그인 사용자 |
/api/market/symbols, /status, /selection | ADMIN |
외부 연동은 catalog / live / stream만 쓰면 됩니다.
| 필드 | 의미 | 외부에서 |
|---|---|---|
symbol | 상품 고정 코드 (NQ) | 필수 키 |
market | OVERSEAS_FUTURE 등 | 구분용 |
contract | 실제 월물 (NQU26) | 표시·참고만 |
contractExpiry | yyyyMM | 참고 |
fixed | 고정 유통 여부 | true면 항상 제공 |
status | LIVE / PENDING | 시세 유무 |
월물 코드(NQU26)를 DB 키로 저장하지 마세요. 만기마다 끊깁니다.
해외선물 → WebSocket(주) + REST(PENDING 보완)
국내선물(KOSPI200) → REST만
SSE source: websocket | poll — 클라이언트는 price만 반영하면 됩니다.
서버에서 항상 활성화됩니다. 해제할 수 없습니다.
| symbol | market | name | 근월물 | 현재가 | 상태 |
|---|---|---|---|---|---|
| 불러오는 중... | |||||
복합 키 예: OVERSEAS_FUTURE:NQ, DOMESTIC_FUTURE:KOSPI200
고정 19종목 + 현재가. 외부 연동 기본 API.
{
"count": 19,
"note": "고정 유통 종목...",
"data": [
{
"market": "OVERSEAS_FUTURE",
"symbol": "NQ",
"name": "E-mini Nasdaq100",
"source": "alias",
"contract": "NQU26",
"contractExpiry": "202609",
"fixed": true,
"price": 2936700.0,
"updatedAt": "2026-08-25T19:50:00.123",
"status": "LIVE",
"selected": true
}
]
}
가격은 KIS 원본 스케일입니다. (예: Nasdaq 2936700 ≈ 표시 29367.00) 상품별 소수점 규칙은 클라이언트에서 적용하세요.
현재 수집 대상 스냅샷(고정 + 관리자 추가 선택 가능). 고정 19개만 필요하면 catalog를 쓰세요.
{
"page": 0,
"size": 1000,
"total": 19,
"liveCount": 15,
"selectedOnly": true,
"data": [ /* catalog data[] 와 동일 스키마 */ ]
}
text/event-stream. 끊기면 재연결하세요.
| event | 설명 |
|---|---|
connected | 연결 성공 {"status":"ok"} |
market | 시세 틱 |
heartbeat | 약 15초마다 (연결 유지 확인) |
event: market
data: {
"source": "websocket",
"market": "OVERSEAS_FUTURE",
"symbol": "NQ",
"contract": "NQU26",
"price": 2936725.0,
"updatedAt": "2026-08-25T19:51:02.456"
}
const prices = new Map();
function connect() {
const es = new EventSource("/api/market/stream");
es.addEventListener("market", (e) => {
const tick = JSON.parse(e.data);
// 반드시 symbol 로 매칭
prices.set(tick.symbol, {
price: tick.price,
contract: tick.contract,
updatedAt: tick.updatedAt,
});
});
es.onerror = () => {
es.close();
setTimeout(connect, 3000);
};
}
connect();
수집기 상태. wsConnected, wsFutureReady, lastError, liveCount 등.
Query: query, page, size, selectedOnly
fixedKeys, selectedKeys 반환.
{ "keys": ["OVERSEAS_FUTURE:NQ", "KOSPI:005930"] }
고정 alias는 요청에서 빠져도 서버가 다시 포함합니다.
async function bootstrap() {
const catalog = await fetch("/api/market/catalog", { credentials: "include" })
.then((r) => r.json());
const state = Object.fromEntries(
catalog.data.map((row) => [
row.symbol,
{ price: row.price, contract: row.contract, status: row.status },
])
);
const es = new EventSource("/api/market/stream");
es.addEventListener("market", (e) => {
const t = JSON.parse(e.data);
state[t.symbol] = {
price: t.price,
contract: t.contract ?? state[t.symbol]?.contract,
status: "LIVE",
};
render(state);
});
}
setInterval(async () => {
const { data } = await fetch("/api/market/catalog", { credentials: "include" })
.then((r) => r.json());
data.forEach((row) => updateUi(row.symbol, row.price, row.status));
}, 2000);
| HTTP | 의미 | 대응 |
|---|---|---|
| 200 | 성공 | — |
| 401 / 로그인 페이지 | 미인증 | 재로그인 |
| 403 | 권한 부족 | ADMIN API는 관리자만 |
| 500 | 서버 오류 | status.lastError 확인 |
PENDING + price: null → 휴장·틱 공백·월물 전환·KIS 권한 문제 가능onerror 재연결POST /login 성공/api/market/catalog에서 19개 symbol 확인symbol인지 확인 (contract 아님)/api/market/stream에서 market 이벤트 수신