한국투자증권 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_SIZE16384WebSocket 데이터 스트림 내부 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
}
}

tokenapproval_keySome(...) 값을 전달하면 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 생성을 담당합니다.

구조체 필드

필드타입설명
authAuth기본(모의/실전) 환경 인증
real_authAuth실전투자 전용 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 호출 전에 자동으로 대기 처리됩니다.

환경 엔드포인트

환경RESTWebSocket
실전openapi.koreainvestment.com:9443ops.koreainvestment.com:21000
모의openapivts.koreainvestment.com:29443ops.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_divisionOrderClass주문 유형 (지정가, 시장가 등)
order_directionDirectionBid (매수) / Ask (매도)
pdno&str종목 코드 (6자리, 예: "005930")
qtyQuantity주문 수량
pricePrice주문 단가 (시장가일 경우 0)
excg_id_dvsn_cdOption<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&strKRX 전송 주문 기관 번호
orgn_odno&str원주문번호
rvse_cncl_dvsn_cdCorrectionClassCorrect (정정) / Cancel (취소)
qty_all_ord_ynbool전량 주문 여부
qtyQuantity정정/취소 수량 (전량이면 0)
pricePrice정정 단가 (취소 시 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_codeMarketCodeStock (주식) / Etf (ETF)
shortcode&str종목 코드 (6자리)
period_codePeriodCode기간 코드 (아래 표 참고)
is_adjust_pricebooltrue = 수정주가 반영

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_cdProductTypeCode상품 유형 코드
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설명데이터 타입
RealtimeExecKrxKRX 체결Exec
RealtimeExecNxtNXT 체결Exec
RealtimeExecUnion통합 체결Exec
RealtimeOrdbKrxKRX 호가Ordb
RealtimeOrdbNxtNXT 호가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_idTrId스트림 종류 (RealtimeExecKrx 등)

반환값

  • Option<broadcast::Receiver<T>>: 새로 생성된 수신 채널. 이미 구독 중이면 None
  • SubscribeResponse: 구독 응답 (성공 여부, 메시지)

예시 — 체결 구독

#![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로 암호화되어 전송됩니다. 구독 응답에 포함된 ivkey를 사용하여 내부적으로 자동 복호화합니다.

예시

#![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거래량 순위
RealtimeExecKrxKRX 실시간 체결
RealtimeOrdbKrxKRX 실시간 호가
RealtimeExecNxtNXT 실시간 체결
RealtimeOrdbNxtNXT 실시간 호가
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 호출
WrongTrIdsubscribe_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);
    }
}
}

? 연산자 사용

Errorthiserror로 구현되어 있어 ? 연산자와 함께 편리하게 사용할 수 있습니다.

#![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(())
}
}