Files
KisStock/services/kisService.ts

106 lines
3.3 KiB
TypeScript

import { ApiSettings, MarketType, OrderType, StockItem } from '../types';
import { API_BASE_URL, getHeaders } from './config';
/**
* Korea Investment & Securities (KIS) Open API Service
* Now connected to Real Backend
*/
export class KisService {
private settings: ApiSettings;
constructor(settings: ApiSettings) {
this.settings = settings;
}
async issueAccessToken() {
// Backend manages token automatically.
return "backend-managed-token";
}
async inquirePrice(code: string): Promise<number> {
// Default to Domestic for now, or infer from code length
const market = code.length === 6 ? "Domestic" : "Overseas";
try {
const res = await fetch(`${API_BASE_URL}/kis/price?market=${market}&code=${code}`);
if (!res.ok) return 0;
const data = await res.json();
return parseFloat(data.price) || 0;
} catch (e) {
return 0;
}
}
/**
* Fetch Market Data
*/
async fetchMasterStocks(market: MarketType): Promise<StockItem[]> {
try {
// Use Rankings as the default "List"
const marketParam = market === MarketType.DOMESTIC ? "Domestic" : "Overseas";
const res = await fetch(`${API_BASE_URL}/discovery/rankings?limit=50`);
if (!res.ok) return [];
const data = await res.json();
// Transform logic if needed. Ranking API returns StockItem which matches frontend type mostly.
return data.map((item: any) => ({
code: item.code,
name: item.name,
price: item.price,
change: item.change,
changePercent: item.changePercent,
market: market,
volume: 0, // Rankings might not return volume yet, or it does if enabled
aiScoreBuy: 50, // Placeholder as backend doesn't have AI score in StockItem yet
aiScoreSell: 50,
themes: []
}));
} catch (e) {
return [];
}
}
async orderCash(code: string, type: OrderType, quantity: number, price: number = 0) {
return this._placeOrder("Domestic", code, type, quantity, price);
}
async orderOverseas(code: string, type: OrderType, quantity: number, price: number) {
return this._placeOrder("Overseas", code, type, quantity, price);
}
private async _placeOrder(market: string, code: string, type: OrderType, quantity: number, price: number) {
const payload = {
market: market,
side: type === OrderType.BUY ? "buy" : "sell",
code: code,
quantity: quantity,
price: price
};
const res = await fetch(`${API_BASE_URL}/kis/order`, {
method: 'POST',
headers: getHeaders(),
body: JSON.stringify(payload)
});
if (!res.ok) {
const err = await res.json();
throw new Error(err.detail || "Order Failed");
}
return await res.json();
}
async inquireBalance() {
// Default Domestic
const res = await fetch(`${API_BASE_URL}/kis/balance?market=Domestic`);
if (!res.ok) return { output1: [], output2: {} };
return await res.json();
}
async inquireBalanceOverseas() {
const res = await fetch(`${API_BASE_URL}/kis/balance?market=Overseas`);
if (!res.ok) return { output1: [], output2: {} };
return await res.json();
}
}