한국투자증권 API for Rust
이 라이브러리는 한국투자증권 Open API를 Rust에서 사용하기 위한 비공식 클라이언트입니다.
주의: 이 라이브러리는 공식 라이브러리가 아닙니다. 사용 전 공식 API 포털에서 이용약관을 확인하세요.
지원 기능
| 카테고리 | 기능 | 지원 환경 |
|---|---|---|
| 인증 | OAuth 토큰 발급/관리 | 실전 · 모의 |
| 인증 | WebSocket 접속키(Approval Key) 발급 | 실전 · 모의 |
| 인증 | HashKey 생성 | 실전 · 모의 |
| 주문 | 현금 매수/매도 | 실전 · 모의 |
| 주문 | 신용 매수/매도 | 실전만 |
| 주문 | 정정/취소 | 실전 · 모의 |
| 주문 | 일별 주문체결 조회 | 실전 · 모의 |
| 주문 | 잔고 조회 | 실전 · 모의 |
| 주문 | 정정취소가능주문 조회 | 실전만 |
| 시세 | 주식 일자별 시세 | 실전 · 모의 |
| 시세 | 거래량 순위 | 실전만 |
| 시세 | 관심종목 그룹 조회 | 실전만 |
| 시세 | 관심종목 그룹별 종목 조회 | 실전만 |
| 시세 | 주식 기본 정보 조회 | 실전만 |
| 실시간 | 체결 스트림 (KRX/NXT/Union) | 실전 · 모의 |
| 실시간 | 호가 스트림 (KRX/NXT/Union) | 실전 · 모의 |
| 실시간 | 체결통보 스트림 | 실전 · 모의 |
엔트리 포인트
모든 API는 KoreaInvestmentApi 구조체를 통해 접근합니다.
#![allow(unused)] fn main() { use korea_investment_api::KoreaInvestmentApi; let api = KoreaInvestmentApi::new(/* ... */).await?; api.auth // 인증 api.order // 주문 api.quote // 시세 api.k_data // 실시간 데이터 }
설치
요구사항
- Rust 1.70 이상
- Tokio async runtime
Cargo.toml 추가
Cargo.toml의 [dependencies]에 아래를 추가합니다:
[dependencies]
korea_investment_api = "0.x" # crates.io 최신 버전 확인
tokio = { version = "1", features = ["full"] }
crates.io에 publish된 최신 버전은 crates.io/crates/korea_investment_api에서 확인하세요.
예제 바이너리 빌드
이 저장소를 직접 클론해서 예제 바이너리를 빌드할 수 있습니다:
git clone https://github.com/systeminit/korea-investment-api
cd korea-investment-api
# 예제 바이너리 빌드 (structopt feature 필요)
cargo build --features example --bin example
# 실행 (config.toml 경로를 인자로 전달)
cargo run --features example --bin example -- config.toml
설정 파일
예제 바이너리 및 export_config를 사용할 때 config.toml 파일 형식을 사용합니다.
config.toml 형식
hts_id = "your-hts-id"
cano = "12345678" # 계좌번호 앞 8자리
acnt_prdt_cd = "01" # 계좌번호 뒤 2자리
app_key = "your-app-key"
app_secret = "your-app-secret"
real_app_key = "your-real-app-key" # 실전투자 전용 API 이용 시
real_app_secret = "your-real-app-secret" # 실전투자 전용 API 이용 시
environment = "Virtual" # "Real" 또는 "Virtual"
# 아래 항목은 선택 사항 (캐싱 목적)
approval_key = "" # WebSocket 접속키 (캐시)
token = "" # OAuth 토큰 (캐시)
real_approval_key = "" # 실전투자 WebSocket 접속키 (캐시)
real_token = "" # 실전투자 OAuth 토큰 (캐시)
항목 설명
| 항목 | 필수 | 설명 |
|---|---|---|
hts_id | 필수 | HTS 로그인 ID (체결통보 구독에 사용) |
cano | 필수 | 계좌번호 앞 8자리 |
acnt_prdt_cd | 필수 | 계좌번호 뒤 2자리 |
app_key | 필수 | API 포털에서 발급한 App Key |
app_secret | 필수 | API 포털에서 발급한 App Secret |
real_app_key | 조건부 | 실전투자 전용 API 사용 시 필요 |
real_app_secret | 조건부 | 실전투자 전용 API 사용 시 필요 |
environment | 필수 | "Real" (실전) 또는 "Virtual" (모의) |
token | 선택 | 기존 OAuth 토큰 (캐시). 비어있으면 자동 발급 |
approval_key | 선택 | 기존 WebSocket 접속키 (캐시). 비어있으면 자동 발급 |
토큰 캐싱
KoreaInvestmentApi::export_config를 호출하면 현재 토큰과 접속키가 config.toml에 저장됩니다. 이후 실행 시 기존 토큰을 재사용하여 불필요한 API 호출을 줄입니다.
#![allow(unused)] fn main() { // 프로그램 종료 전 토큰 저장 api.export_config(&config)?; }
주의:
config.toml에는 민감한 인증 정보가 포함됩니다..gitignore에 추가하여 버전 관리에서 제외하세요.
환경변수
| 환경변수 | 기본값 | 설명 |
|---|---|---|
CHANNEL_SIZE | 16384 | WebSocket 데이터 스트림 내부 broadcast 채널 크기. 메시지 유실이 발생할 경우 더 높은 값으로 설정하세요. |
CHANNEL_SIZE=32768 cargo run
빠른 시작
API 인스턴스 생성
#![allow(unused)] fn main() { use korea_investment_api::{KoreaInvestmentApi, Error}; use korea_investment_api::types::{Environment, Account}; async fn create_api() -> Result<KoreaInvestmentApi, Error> { let account = Account { cano: "12345678".to_string(), // 계좌번호 앞 8자리 acnt_prdt_cd: "01".to_string(), // 계좌번호 뒤 2자리 }; KoreaInvestmentApi::new( Environment::Virtual, // 실전: Real, 모의: Virtual "your-app-key", "your-app-secret", account, "your-hts-id", None, // token: None이면 자동 발급 None, // approval_key: None이면 자동 발급 Some("your-real-app-key".to_string()), // 실전투자 전용 API용 Some("your-real-app-secret".to_string()), // 실전투자 전용 API용 None, // real_token None, // real_approval_key ).await } }
token과approval_key에Some(...)값을 전달하면 API 호출을 건너뜁니다. 캐싱된 값이 있을 때 활용하세요.
기본 사용 예시
일자별 시세 조회
use korea_investment_api::types::{MarketCode, PeriodCode}; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { let api = create_api().await?; // 삼성전자 30일 시세 let prices = api.quote.daily_price( MarketCode::Stock, "005930", // 종목 코드 PeriodCode::ThirtyDays, false, // 수정주가 여부 (true = 수정주가 반영) ).await?; println!("{:?}", prices); Ok(()) }
현금 매수 주문
#![allow(unused)] fn main() { use korea_investment_api::types::{Direction, OrderClass, Price, Quantity}; let result = api.order.order_cash( OrderClass::Limit, // 지정가 Direction::Bid, // 매수 "005930", // 삼성전자 Quantity::from(10u32), // 10주 Price::from(70000u32), // 70,000원 None, // 거래소 코드 (None = 기본값) ).await?; }
실시간 체결 구독
#![allow(unused)] fn main() { use korea_investment_api::types::TrId; // KRX 체결 스트림 구독 let (rx, response) = api.k_data.subscribe_market::<Exec, ExecRow>( "005930", TrId::RealtimeExecKrx, ).await?; if let Some(mut rx) = rx { while let Some(exec) = rx.recv().await { println!("체결: {:?}", exec); } } }
토큰 저장
#![allow(unused)] fn main() { // 프로그램 종료 전 토큰 캐싱 api.export_config(&config)?; }
인증 (Auth)
api.auth는 OAuth 토큰 관리, WebSocket 접속키 발급, HashKey 생성을 담당합니다.
구조체 필드
| 필드 | 타입 | 설명 |
|---|---|---|
auth | Auth | 기본(모의/실전) 환경 인증 |
real_auth | Auth | 실전투자 전용 API용 인증 |
토큰 관리
토큰은 KoreaInvestmentApi::new() 생성 시 자동으로 발급됩니다. token 파라미터에 기존 값을 전달하면 재사용합니다.
#![allow(unused)] fn main() { // 자동 발급 KoreaInvestmentApi::new(..., None, None, ...).await?; // 캐시된 토큰 재사용 KoreaInvestmentApi::new(..., Some(cached_token), Some(cached_key), ...).await?; }
토큰 조회
#![allow(unused)] fn main() { let token: Option<String> = api.auth.get_token(); let approval_key: Option<String> = api.auth.get_approval_key(); }
HashKey
POST 요청의 무결성 검증을 위해 HashKey가 사용됩니다. 주문 API에서 내부적으로 자동 처리됩니다.
#![allow(unused)] fn main() { let hash = api.auth.get_hash(json_body_string).await?; }
레이트 리밋
전역 LAST_CALL mutex로 호출 빈도를 제한합니다:
| 환경 | 최대 호출 빈도 |
|---|---|
| 실전 (Real) | 초당 20회 |
| 모의 (Virtual) | 초당 2회 |
각 API 호출 전에 자동으로 대기 처리됩니다.
환경 엔드포인트
| 환경 | REST | WebSocket |
|---|---|---|
| 실전 | openapi.koreainvestment.com:9443 | ops.koreainvestment.com:21000 |
| 모의 | openapivts.koreainvestment.com:29443 | ops.koreainvestment.com:31000 |
주문 (Order)
api.order는 국내 주식 주문 관련 API를 제공합니다. src/stock/order.rs에 구현되어 있습니다.
order_cash — 현금 주문 [v1_국내주식-001]
현금으로 주식을 매수 또는 매도합니다.
#![allow(unused)] fn main() { pub async fn order_cash( &self, order_division: OrderClass, order_direction: Direction, pdno: &str, qty: Quantity, price: Price, excg_id_dvsn_cd: Option<TargetExchange>, ) -> Result<response::stock::order::Body::Order, Error> }
파라미터
| 파라미터 | 타입 | 설명 |
|---|---|---|
order_division | OrderClass | 주문 유형 (지정가, 시장가 등) |
order_direction | Direction | Bid (매수) / Ask (매도) |
pdno | &str | 종목 코드 (6자리, 예: "005930") |
qty | Quantity | 주문 수량 |
price | Price | 주문 단가 (시장가일 경우 0) |
excg_id_dvsn_cd | Option<TargetExchange> | 거래소 코드 (None = 기본값) |
예시
#![allow(unused)] fn main() { use korea_investment_api::types::{Direction, OrderClass, Price, Quantity}; // 삼성전자 10주 지정가 매수 (70,000원) let result = api.order.order_cash( OrderClass::Limit, Direction::Bid, "005930", Quantity::from(10u32), Price::from(70000u32), None, ).await?; }
지원 환경
실전 · 모의 모두 지원합니다.
order_credit — 신용 주문 [v1_국내주식-002]
신용으로 주식을 매수 또는 매도합니다.
#![allow(unused)] fn main() { pub async fn order_credit( &self, order_division: OrderClass, order_direction: Direction, pdno: &str, qty: Quantity, price: Price, excg_id_dvsn_cd: Option<TargetExchange>, credit_type: CreditType, ) -> Result<response::stock::order::Body::Order, Error> }
주의: 실전투자 환경만 지원합니다. 모의투자에서 호출하면
Error::NotSupported가 반환됩니다.
correct — 정정/취소 [v1_국내주식-003]
미체결 주문을 정정하거나 취소합니다.
#![allow(unused)] fn main() { pub async fn correct( &self, order_division: OrderClass, krx_fwdg_ord_orgno: &str, orgn_odno: &str, rvse_cncl_dvsn_cd: CorrectionClass, qty_all_ord_yn: bool, qty: Quantity, price: Price, excg_id_dvsn_cd: Option<TargetExchange>, ) -> Result<response::stock::order::Body::Order, Error> }
파라미터
| 파라미터 | 타입 | 설명 |
|---|---|---|
krx_fwdg_ord_orgno | &str | KRX 전송 주문 기관 번호 |
orgn_odno | &str | 원주문번호 |
rvse_cncl_dvsn_cd | CorrectionClass | Correct (정정) / Cancel (취소) |
qty_all_ord_yn | bool | 전량 주문 여부 |
qty | Quantity | 정정/취소 수량 (전량이면 0) |
price | Price | 정정 단가 (취소 시 0) |
inquire_daily_ccld — 일별 주문체결 조회 [v1_국내주식-005]
기간별 주문 및 체결 내역을 조회합니다.
#![allow(unused)] fn main() { pub async fn inquire_daily_ccld( &self, inqr_strt_dt: &str, // 조회 시작일 "YYYYMMDD" inqr_end_dt: &str, // 조회 종료일 "YYYYMMDD" sll_buy_dvsn_cd: Option<String>, inqr_dvsn: Option<String>, pdno: Option<String>, ccld_dvsn: Option<String>, ord_gno_brno: Option<String>, odno: Option<String>, inqr_dvsn_3: Option<String>, inqr_dvsn_1: Option<String>, ctx_area_fk100: Option<String>, // 연속조회 키 ctx_area_nk100: Option<String>, // 연속조회 키 excg_id_dvsn_cd: Option<TargetExchange>, ) -> Result<response::stock::order::daily_ccld::InquireDailyCcld, Error> }
연속조회
한 번에 반환되는 건수가 최대치(실전 50건, 모의 20건)를 초과하면 응답의 ctx_area_fk100 / ctx_area_nk100 값을 다음 요청에 전달합니다.
TR ID 자동 선택
조회 시작일에 따라 TR ID가 자동으로 선택됩니다:
- 3개월 이내: Recent TR 사용
- 3개월 이전: Past TR 사용
inquire_balance — 잔고 조회 [v1_국내주식-006]
계좌 잔고를 조회합니다.
#![allow(unused)] fn main() { pub async fn inquire_balance( &self, afhr_flpr_yn: Option<String>, // 시간외 단일가 여부 inqr_dvsn: Option<String>, // 조회 구분 prcs_dvsn: Option<String>, // 처리 구분 ctx_area_fk100: Option<String>, // 연속조회 키 ctx_area_nk100: Option<String>, // 연속조회 키 ) -> Result<response::stock::order::balance::InquireBalance, Error> }
inquire_psbl_rvsecncl — 정정취소가능주문 조회 [v1_국내주식-004]
정정 또는 취소가 가능한 미체결 주문 목록을 조회합니다.
#![allow(unused)] fn main() { pub async fn inquire_psbl_rvsecncl( &self, ctx_area_fk100: Option<String>, ctx_area_nk100: Option<String>, inqr_dvsn_1: Option<String>, inqr_dvsn_2: Option<String>, ) -> Result<response::stock::order::Body::InquirePsblRvsecncl, Error> }
주의: 실전투자 전용 API입니다. 모의투자 환경에서도 실전투자 엔드포인트로 요청됩니다.
시세 (Quote)
api.quote는 국내 주식 시세 조회 API를 제공합니다. src/stock/quote.rs에 구현되어 있습니다.
주의: 거래량순위, 관심종목, 주식기본조회 API는 실전투자 엔드포인트만 지원합니다. 모의투자 환경에서도 실전투자 서버로 요청이 전송됩니다.
daily_price — 일자별 시세 [v1_국내주식-010]
종목의 일자별 / 주별 / 월별 시세를 조회합니다.
#![allow(unused)] fn main() { pub async fn daily_price( &self, market_code: MarketCode, shortcode: &str, period_code: PeriodCode, is_adjust_price: bool, ) -> Result<response::stock::quote::DailyPriceResponse, Error> }
파라미터
| 파라미터 | 타입 | 설명 |
|---|---|---|
market_code | MarketCode | Stock (주식) / Etf (ETF) |
shortcode | &str | 종목 코드 (6자리) |
period_code | PeriodCode | 기간 코드 (아래 표 참고) |
is_adjust_price | bool | true = 수정주가 반영 |
PeriodCode 값
| 값 | 설명 |
|---|---|
ThirtyDays | 최근 30일 (일별) |
ThirtyWeeks | 최근 30주 (주별) |
ThirtyMonths | 최근 30개월 (월별) |
예시
#![allow(unused)] fn main() { use korea_investment_api::types::{MarketCode, PeriodCode}; // 삼성전자 30일 일자별 시세 (수정주가 미반영) let prices = api.quote.daily_price( MarketCode::Stock, "005930", PeriodCode::ThirtyDays, false, ).await?; }
volume_rank — 거래량 순위 [v1_국내주식-047]
거래량 기준 종목 순위를 조회합니다. 실전투자 전용입니다.
#![allow(unused)] fn main() { pub async fn volume_rank( &self, params: request::stock::quote::VolumeRankParameter, ) -> Result<response::stock::quote::VolumeRankResponse, Error> }
예시
#![allow(unused)] fn main() { use korea_investment_api::types::request::stock::quote::VolumeRankParameter; let params = VolumeRankParameter::new(/* ... */); let ranks = api.quote.volume_rank(params).await?; }
group_item — 관심종목 그룹별 종목조회 [국내주식-203]
관심종목 그룹에 속한 종목 목록을 조회합니다. 실전투자 전용입니다.
#![allow(unused)] fn main() { pub async fn group_item( &self, params: request::stock::quote::GroupItemParameter, ) -> Result<response::stock::quote::GroupItemResponse, Error> }
group_list — 관심종목 그룹조회 [국내주식-204]
관심종목 그룹 목록을 조회합니다. 실전투자 전용입니다.
#![allow(unused)] fn main() { pub async fn group_list( &self, params: request::stock::quote::GroupListParameter, ) -> Result<response::stock::quote::GroupListResponse, Error> }
basic_stock_info — 주식 기본 정보 [v1_국내주식-067]
종목의 기본 정보를 조회합니다. 실전투자 전용입니다.
#![allow(unused)] fn main() { pub async fn basic_stock_info( &self, prdt_type_cd: ProductTypeCode, pdno: &str, ) -> Result<response::stock::quote::BasicStockInfoResponse, Error> }
파라미터
| 파라미터 | 타입 | 설명 |
|---|---|---|
prdt_type_cd | ProductTypeCode | 상품 유형 코드 |
pdno | &str | 종목 코드 |
예시
#![allow(unused)] fn main() { use korea_investment_api::types::ProductTypeCode; let info = api.quote.basic_stock_info( ProductTypeCode::Stock, "005930", ).await?; }
실시간 데이터 (Realtime)
api.k_data는 WebSocket 기반의 실시간 시세 데이터를 제공합니다. src/stock/data.rs에 구현되어 있습니다.
스트림 종류
| TrId | 설명 | 데이터 타입 |
|---|---|---|
RealtimeExecKrx | KRX 체결 | Exec |
RealtimeExecNxt | NXT 체결 | Exec |
RealtimeExecUnion | 통합 체결 | Exec |
RealtimeOrdbKrx | KRX 호가 | Ordb |
RealtimeOrdbNxt | NXT 호가 | Ordb |
RealtimeOrdbUnion | 통합 호가 | Ordb |
RealRealtimeMyExec / VirtualRealtimeMyExec | 내 체결통보 | MyExec |
subscribe_market — 시세 구독
종목 실시간 체결 또는 호가 데이터를 구독합니다.
#![allow(unused)] fn main() { pub async fn subscribe_market<T: StreamParser<R> + Send, R: Clone + Send>( &mut self, tr_key: &str, tr_id: TrId, ) -> Result<(Option<broadcast::Receiver<T>>, SubscribeResponse), Error> }
파라미터
| 파라미터 | 타입 | 설명 |
|---|---|---|
tr_key | &str | 종목 코드 (6자리) |
tr_id | TrId | 스트림 종류 (RealtimeExecKrx 등) |
반환값
Option<broadcast::Receiver<T>>: 새로 생성된 수신 채널. 이미 구독 중이면NoneSubscribeResponse: 구독 응답 (성공 여부, 메시지)
예시 — 체결 구독
#![allow(unused)] fn main() { use korea_investment_api::types::{TrId}; use korea_investment_api::types::stream::stock::{Exec, exec}; let (rx, response) = api.k_data.subscribe_market::<Exec, exec::Body>( "005930", TrId::RealtimeExecKrx, ).await?; assert!(response.is_success()); if let Some(mut rx) = rx { while let Some(exec) = rx.recv().await { println!("체결가: {:?}", exec); } } }
예시 — 호가 구독
#![allow(unused)] fn main() { use korea_investment_api::types::stream::stock::{Ordb, ordb}; let (rx, _) = api.k_data.subscribe_market::<Ordb, ordb::Body>( "005930", TrId::RealtimeOrdbKrx, ).await?; }
PINGPONG 처리
서버에서 PINGPONG 프레임이 오면 자동으로 에코 응답합니다. 사용자 코드에서 처리할 필요가 없습니다.
subscribe_my_exec — 체결통보 구독
내 계좌의 주문 체결 통보를 실시간으로 수신합니다.
#![allow(unused)] fn main() { pub async fn subscribe_my_exec( &mut self, ) -> Result<(UnboundedReceiver<MyExec>, SubscribeResponse), Error> }
보안
체결통보 스트림 데이터는 AES-256-CBC로 암호화되어 전송됩니다. 구독 응답에 포함된 iv와 key를 사용하여 내부적으로 자동 복호화합니다.
예시
#![allow(unused)] fn main() { use korea_investment_api::types::stream::stock::MyExec; let (mut rx, response) = api.k_data.subscribe_my_exec().await?; assert!(response.is_success()); while let Some(my_exec) = rx.recv().await { println!("체결통보: {:?}", my_exec); } }
unsubscribe_market — 시세 구독 해제
구독 중인 종목 시세 스트림을 해제합니다.
#![allow(unused)] fn main() { pub async fn unsubscribe_market( &mut self, tr_key: &str, tr_id: TrId, ) -> Result<SubscribeResponse, Error> }
예시
#![allow(unused)] fn main() { let response = api.k_data.unsubscribe_market( "005930", TrId::RealtimeExecKrx, ).await?; }
자동 구독 해제
KoreaStockData가 Drop될 때, 진행 중인 모든 구독이 자동으로 해제됩니다.
타입 레퍼런스
주요 타입들은 korea_investment_api::types 모듈에 있습니다.
Environment
API 환경을 지정합니다.
#![allow(unused)] fn main() { pub enum Environment { Real, // 실전투자 Virtual, // 모의투자 } }
Account
계좌 정보를 담는 구조체입니다.
#![allow(unused)] fn main() { pub struct Account { pub cano: String, // 계좌번호 앞 8자리 pub acnt_prdt_cd: String, // 계좌번호 뒤 2자리 } }
Direction
매수/매도 방향을 나타냅니다.
#![allow(unused)] fn main() { pub enum Direction { Bid, // 매수 Ask, // 매도 } }
OrderClass
주문 유형을 나타냅니다. 주요 값:
| 값 | 설명 |
|---|---|
Limit | 지정가 |
Market | 시장가 |
BestLimit | 최우선 지정가 |
| 기타 | API 포털 참고 |
CorrectionClass
정정/취소 구분입니다.
#![allow(unused)] fn main() { pub enum CorrectionClass { Correct, // 정정 Cancel, // 취소 } }
MarketCode
시장/상품 구분입니다.
#![allow(unused)] fn main() { pub enum MarketCode { Stock, // 주식 Etf, // ETF } }
PeriodCode
조회 기간 코드입니다.
#![allow(unused)] fn main() { pub enum PeriodCode { ThirtyDays, // 30일 (일별) ThirtyWeeks, // 30주 (주별) ThirtyMonths, // 30개월 (월별) } }
TrId
API 거래 ID입니다. 주요 값:
| 값 | 설명 |
|---|---|
RealStockCashBidOrder | 실전 현금 매수 주문 |
RealStockCashAskOrder | 실전 현금 매도 주문 |
VirtualStockCashBidOrder | 모의 현금 매수 주문 |
VirtualStockCashAskOrder | 모의 현금 매도 주문 |
DailyPrice | 일자별 시세 |
VolumeRank | 거래량 순위 |
RealtimeExecKrx | KRX 실시간 체결 |
RealtimeOrdbKrx | KRX 실시간 호가 |
RealtimeExecNxt | NXT 실시간 체결 |
RealtimeOrdbNxt | NXT 실시간 호가 |
RealtimeExecUnion | 통합 실시간 체결 |
RealtimeOrdbUnion | 통합 실시간 호가 |
RealRealtimeMyExec | 실전 체결통보 |
VirtualRealtimeMyExec | 모의 체결통보 |
Enum 직렬화 패턴
모든 Enum은 API 전송 코드 문자열로 직렬화됩니다. Display 구현이 wire format 코드를 반환하고, SerializeDisplay로 serde 직렬화됩니다.
#![allow(unused)] fn main() { let tr_id_str: String = TrId::DailyPrice.into(); // "FHKST01010400" }
스트림 타입
실시간 데이터 파싱 타입은 korea_investment_api::types::stream::stock에 있습니다:
| 타입 | 설명 |
|---|---|
Exec | 체결 데이터 (H0STCNT0) |
Ordb | 호가 데이터 (H0STASP0) |
MyExec | 체결통보 (H0STCNI0/9) |
에러 처리
모든 API 함수는 Result<T, Error>를 반환합니다. Error 열거형은 src/lib.rs에 정의되어 있습니다.
Error 열거형
#![allow(unused)] fn main() { pub enum Error { // 외부 라이브러리 에러 WebSocket(tokio_tungstenite::tungstenite::Error), ReqwestError(reqwest::Error), Utf8Error(std::str::Utf8Error), JsonError(json::JsonError), ChronoError(chrono::ParseError), ParseIntError(std::num::ParseIntError), ParseFloatError(std::num::ParseFloatError), Base64DecodeError(base64::DecodeError), UrlParseError(url::ParseError), TomlSerializeError(toml::ser::Error), IoError(std::io::Error), // 커스텀 에러 AuthInitFailed(&'static str), BrokenProtocol(&'static str, String), InvalidData, WrongTrId(TrId, &'static str), AesInvalidLength, AesDecryptError(String), NotSupported(&'static str), } }
주요 에러 설명
| 에러 | 발생 상황 |
|---|---|
AuthInitFailed | 토큰 또는 접속키가 초기화되지 않은 상태에서 API 호출 |
WrongTrId | subscribe_market에 잘못된 TrId 전달 |
NotSupported | 모의투자에서 신용주문 등 미지원 기능 호출 |
AesDecryptError | 체결통보 복호화 실패 |
BrokenProtocol | 서버 응답이 예상과 다를 때 |
에러 처리 예시
#![allow(unused)] fn main() { use korea_investment_api::Error; match api.order.order_cash(/* ... */).await { Ok(result) => println!("주문 완료: {:?}", result), Err(Error::AuthInitFailed(field)) => { eprintln!("인증 정보 없음: {}", field); } Err(Error::ReqwestError(e)) => { eprintln!("HTTP 에러: {}", e); } Err(e) => { eprintln!("기타 에러: {}", e); } } }
? 연산자 사용
Error는 thiserror로 구현되어 있어 ? 연산자와 함께 편리하게 사용할 수 있습니다.
#![allow(unused)] fn main() { async fn run() -> Result<(), korea_investment_api::Error> { let api = KoreaInvestmentApi::new(/* ... */).await?; let prices = api.quote.daily_price(/* ... */).await?; Ok(()) } }