Files
auto-trade/features/trade/apis/kis-stock.api.ts

204 lines
5.5 KiB
TypeScript

import type { KisRuntimeCredentials } from "@/features/settings/store/use-kis-runtime-store";
import {
buildKisRequestHeaders,
resolveKisApiErrorMessage,
type KisApiErrorPayload,
} from "@/features/settings/apis/kis-api-utils";
import type {
DashboardChartTimeframe,
DashboardStockCashOrderRequest,
DashboardStockCashOrderResponse,
DashboardStockOrderableCashRequest,
DashboardStockOrderableCashResponse,
DashboardStockChartResponse,
DashboardStockOrderBookResponse,
DashboardStockOverviewResponse,
DashboardStockSearchResponse,
} from "@/features/trade/types/trade.types";
/**
* 종목 검색 API 호출
* @param keyword 검색어
*/
export async function fetchStockSearch(
keyword: string,
signal?: AbortSignal,
): Promise<DashboardStockSearchResponse> {
const response = await fetch(
`/api/kis/domestic/search?q=${encodeURIComponent(keyword)}`,
{
cache: "no-store",
signal,
},
);
const payload = (await response.json()) as
| DashboardStockSearchResponse
| KisApiErrorPayload;
if (!response.ok) {
throw new Error(resolveKisApiErrorMessage(payload, "종목 검색 중 오류가 발생했습니다."));
}
return payload as DashboardStockSearchResponse;
}
/**
* 종목 상세 개요 조회 API 호출
* @param symbol 종목코드
* @param credentials KIS 인증 정보
*/
export async function fetchStockOverview(
symbol: string,
credentials: KisRuntimeCredentials,
): Promise<DashboardStockOverviewResponse> {
const response = await fetch(
`/api/kis/domestic/overview?symbol=${encodeURIComponent(symbol)}`,
{
method: "GET",
headers: buildKisRequestHeaders(credentials, {
includeSessionOverride: true,
}),
cache: "no-store",
},
);
const payload = (await response.json()) as
| DashboardStockOverviewResponse
| KisApiErrorPayload;
if (!response.ok) {
throw new Error(resolveKisApiErrorMessage(payload, "종목 조회 중 오류가 발생했습니다."));
}
return payload as DashboardStockOverviewResponse;
}
/**
* 종목 호가 조회 API 호출
* @param symbol 종목코드
* @param credentials KIS 인증 정보
*/
export async function fetchStockOrderBook(
symbol: string,
credentials: KisRuntimeCredentials,
signal?: AbortSignal,
): Promise<DashboardStockOrderBookResponse> {
const response = await fetch(
`/api/kis/domestic/orderbook?symbol=${encodeURIComponent(symbol)}`,
{
method: "GET",
headers: buildKisRequestHeaders(credentials, {
includeSessionOverride: true,
}),
cache: "no-store",
signal,
},
);
const payload = (await response.json()) as
| DashboardStockOrderBookResponse
| KisApiErrorPayload;
if (!response.ok) {
throw new Error(resolveKisApiErrorMessage(payload, "호가 조회 중 오류가 발생했습니다."));
}
return payload as DashboardStockOrderBookResponse;
}
/**
* 종목 차트(분봉/일봉/주봉) 조회 API 호출
*/
export async function fetchStockChart(
symbol: string,
timeframe: DashboardChartTimeframe,
credentials: KisRuntimeCredentials,
cursor?: string,
): Promise<DashboardStockChartResponse> {
const query = new URLSearchParams({
symbol,
timeframe,
});
if (cursor) query.set("cursor", cursor);
const response = await fetch(`/api/kis/domestic/chart?${query.toString()}`, {
method: "GET",
headers: buildKisRequestHeaders(credentials, {
includeSessionOverride: true,
}),
cache: "no-store",
});
const payload = (await response.json()) as
| DashboardStockChartResponse
| KisApiErrorPayload;
if (!response.ok) {
throw new Error(resolveKisApiErrorMessage(payload, "차트 조회 중 오류가 발생했습니다."));
}
return payload as DashboardStockChartResponse;
}
/**
* 주식 현금 주문 API 호출
* @param request 주문 요청 데이터
* @param credentials KIS 인증 정보
*/
export async function fetchOrderCash(
request: DashboardStockCashOrderRequest,
credentials: KisRuntimeCredentials,
): Promise<DashboardStockCashOrderResponse> {
const response = await fetch("/api/kis/domestic/order-cash", {
method: "POST",
headers: buildKisRequestHeaders(credentials, {
jsonContentType: true,
includeSessionOverride: true,
}),
body: JSON.stringify(request),
cache: "no-store",
});
const payload = (await response.json()) as
| DashboardStockCashOrderResponse
| KisApiErrorPayload;
if (!response.ok) {
throw new Error(resolveKisApiErrorMessage(payload, "주문 전송 중 오류가 발생했습니다."));
}
return payload as DashboardStockCashOrderResponse;
}
/**
* 매수가능금액(주문가능현금) 조회 API 호출
* @param request 종목/가격 기준 조회 요청
* @param credentials KIS 인증 정보
*/
export async function fetchOrderableCashEstimate(
request: DashboardStockOrderableCashRequest,
credentials: KisRuntimeCredentials,
): Promise<DashboardStockOrderableCashResponse> {
const response = await fetch("/api/kis/domestic/orderable-cash", {
method: "POST",
headers: buildKisRequestHeaders(credentials, {
jsonContentType: true,
includeAccountNo: true,
includeSessionOverride: true,
}),
body: JSON.stringify(request),
cache: "no-store",
});
const payload = (await response.json()) as
| DashboardStockOrderableCashResponse
| KisApiErrorPayload;
if (!response.ok) {
throw new Error(resolveKisApiErrorMessage(payload, "매수가능금액 조회 중 오류가 발생했습니다."));
}
return payload as DashboardStockOrderableCashResponse;
}