AlgoLab Blog · 한국투자증권 KIS API · 2026

KIS 실현손익 잔고조회 TTTC8494R — 함정 5가지

KIS API · 계좌 조회 2026-10-05 · 약 7분 읽기 · 알고랩 AlgoLab
한 줄 요약

TTTC8494R(주식잔고조회_실현손익)은 일반 잔고조회 TTTC8434R과 같은 output1·output2 구조에 rlzt_pfls(실현손익)·rlzt_erng_rt(실현수익율)·real_evlu_pfls(실평가손익)·real_evlu_pfls_erng_rt 4개가 붙은 API이고, 실전계좌 전용입니다. 엔드포인트는 GET /uapi/domestic-stock/v1/trading/inquire-balance-rlz-pl, 한국투자 HTS [0800] 국내 체결기준잔고 화면을 API로 옮긴 것입니다. 공식 저장소(koreainvestment/open-trading-api, 2026-10-05 확인)에서 모의투자 지원 칸이 비어 있고, 예제 함수에는 env_dv(실전/모의) 인자 자체가 없습니다. 조회구분 INQR_DVSN은 설명엔 "00:전체", 예제엔 "02"로 서로 다르게 적혀 있습니다. 기간 실현손익을 정산할 때는 이 값이 아니라 기간별매매손익 TTTC8715R로 맞춰야 합니다.

목차

  1. 세 가지 손익 API — 무엇을 언제 쓰나
  2. 요청 파라미터 12개
  3. 응답 — TTTC8434R과 무엇이 다른가
  4. 함정 5가지
  5. 동작하는 코드 — 연속조회 포함
  6. 자주 묻는 질문

1. 세 가지 손익 API — 무엇을 언제 쓰나

봇 대시보드에 "오늘 얼마 벌었나"를 띄우려고 KIS Developers 문서를 뒤지면 손익이 붙은 API가 여럿 나옵니다. 용도가 다릅니다.

APItr_id답하는 질문모의투자
주식잔고조회TTTC8434R지금 무엇을 몇 주, 평가손익 얼마⭕ (VTTC8434R)
주식잔고조회_실현손익TTTC8494R잔고 + 체결기준 실현손익을 한 번에공란(미제공)
기간별매매손익현황조회TTTC8715R기간 동안 종목별 확정 손익·수수료·세금공란
기간별손익일별합산조회TTTC8708R기간 동안 일별 손익 합계공란

모의투자 칸은 공식 저장소 legacy/README.md의 지원 표 기준입니다(legacy/postman/README.md에서는 실전 칸만 ⭕). TTTC8494R의 자리는 "잔고를 이미 매번 조회하는 봇이, 호출 하나로 실현손익까지 같이 받고 싶을 때"입니다. 정산·세금 계산용은 아닙니다(함정 ⑤).

2. 요청 파라미터 12개

공식 Postman 컬렉션 실전계좌_POSTMAN_샘플코드_v2.6.json의 요청 URL 원문입니다.

{{PROD}}/uapi/domestic-stock/v1/trading/inquire-balance-rlz-pl?CANO={{CANO_REAL}}&ACNT_PRDT_CD=01&AFHR_FLPR_YN=N&OFL_YN=&INQR_DVSN=02&UNPR_DVSN=01&FUND_STTL_ICLD_YN=N&FNCG_AMT_AUTO_RDPT_YN=N&PRCS_DVSN=01&COST_ICLD_YN=N&CTX_AREA_FK100=&CTX_AREA_NK100=
파라미터설명(공식)예제 값
CANO종합계좌번호, 8-2 체계의 앞 8자리계좌번호
ACNT_PRDT_CD계좌상품코드, 뒤 2자리01
AFHR_FLPR_YN시간외단일가여부 N:기본값 / Y:시간외단일가N
OFL_YN오프라인여부(공란)빈 값
INQR_DVSN조회구분(00 : 전체)02 ← 불일치
UNPR_DVSN단가구분(01 : 기본값)01
FUND_STTL_ICLD_YN펀드결제포함여부 N/YN
FNCG_AMT_AUTO_RDPT_YN융자금액자동상환여부 N:기본값N
PRCS_DVSN00:전일매매포함 / 01:전일매매미포함01
COST_ICLD_YN비용포함여부 N:포함하지 않음 / Y:포함N
CTX_AREA_FK100연속조회검색조건100, 최초 공란빈 값
CTX_AREA_NK100연속조회키100, 최초 공란빈 값

헤더는 다른 KIS 조회와 같습니다 — authorization(Bearer access_token), appkey, appsecret, tr_id=TTTC8494R, custtype=P. 토큰 발급은 KIS API 키 발급 30분 가이드를 보세요.

3. 응답 — TTTC8434R과 무엇이 다른가

두 API의 공식 예제 chk_*.py에 있는 COLUMN_MAPPING을 집합으로 비교하면 차이는 7개뿐입니다. 나머지(pdno, prdt_name, hldg_qty, ord_psbl_qty, pchs_avg_pric, evlu_pfls_amt, dnca_tot_amt, tot_evlu_amt, nass_amt 등)는 같습니다.

구분필드공식 한글명
TTTC8494R에만rlzt_pfls실현손익
rlzt_erng_rt실현수익율
real_evlu_pfls실평가손익
real_evlu_pfls_erng_rt실평가손익수익율
TTTC8434R에만item_mgna_rt_name종목증거금율명
grta_rt_name보증금율명
sbst_pric대용가격

즉 증거금율·대용가격이 필요한 신용·담보 로직이면 TTTC8434R을 그대로 써야 하고, 손익 표시가 목적이면 TTTC8494R 하나로 충분합니다.

4. 함정 5가지

함정 ① 모의투자에서 개발하다 막힌다

공식 예제의 함수 시그니처부터 다릅니다.

# examples_llm/domestic_stock/inquire_balance/inquire_balance.py  (TTTC8434R)
def inquire_balance(env_dv: str, cano: str, acnt_prdt_cd: str, ...)
    if env_dv == "real":   tr_id = "TTTC8434R"
    elif env_dv == "demo": tr_id = "VTTC8434R"

# examples_llm/domestic_stock/inquire_balance_rlz_pl/inquire_balance_rlz_pl.py  (TTTC8494R)
def inquire_balance_rlz_pl(cano: str, acnt_prdt_cd: str, ...)   # env_dv 인자 자체가 없음
    tr_id = "TTTC8494R"  # 주식잔고조회_실현손익

문제는 인증 모듈입니다. 공식 kis_auth.py의 _url_fetch()는 모의 모드에서 tr_id 첫 글자를 자동으로 바꿉니다.

    tr_id = ptr_id
    if ptr_id[0] in ("T", "J", "C"):  # 실전투자용 TR id 체크
        if isPaperTrading():  # 모의투자용 TR id 식별
            tr_id = "V" + ptr_id[1:]

모의 모드로 이 예제를 돌리면 요청 헤더에는 VTTC8494R이 들어가는데, 모의 서버 제공 목록에 이 API가 없습니다. 에러 문구를 보고 파라미터를 의심하기 쉽지만 원인은 환경입니다. 모의에서 개발한 봇을 실전으로 옮길 때 생기는 다른 차이는 모의→실전 전환 체크리스트에 모았습니다. 대응: 모의 단계에선 TTTC8434R로 잔고를 받고 실현손익 표시는 끄거나, 실전 소액 계좌에서만 이 API를 켭니다.

함정 ② INQR_DVSN — 문서는 00, 예제는 02

# 같은 저장소, 같은 API, 세 가지 값
docstring   : inqr_dvsn (str): [필수] 조회구분 (00:전체)
chk 예제    : inqr_dvsn="02"
Postman     : "INQR_DVSN" value "02"  /  description "조회구분(00 : 전체)"
legacy      : "INQR_DVSN": "00",       # 00 : 전체

일반 잔고 TTTC8434R은 INQR_DVSN이 01(대출일별) / 02(종목별)입니다. TTTC8494R 설명은 "00:전체" 하나만 적어 두고, 최신 예제와 Postman은 02를 보냅니다. 어느 쪽이 맞는지 공식 설명만으로는 확정할 수 없습니다. 대응: 실계좌에서 00과 02를 한 번씩 호출해 output1 행 수와 output2 합계가 같은지 비교한 뒤 한 값으로 고정하세요. 신용 보유분이 있는 계좌라면 차이가 날 가능성이 더 큽니다.

함정 ③ PRCS_DVSN — 전일 매매를 넣느냐 빼느냐

PRCS_DVSN은 00(전일매매포함) / 01(전일매매미포함)인데 최신 예제는 01, legacy/Sample01/kis_domstk.py는 00입니다. 응답에 bfdy_buy_qty(전일매수수량)·bfdy_sll_qty·bfdy_buy_amt·bfdy_sll_amt·bfdy_tlex_amt(전일제비용금액) 같은 전일 필드가 있으므로, 전일 청산분까지 화면에 보여야 하는 봇은 00을 써야 의미가 맞습니다. 오전 장 시작 직후 대시보드가 "어제 판 종목"을 놓친다면 이 값부터 보세요.

함정 ④ output1·output2를 헷갈린다

공식 chk_inquire_balance_rlz_pl.py는 output1(종목 행)과 output2(계좌 합계) 필드를 하나의 COLUMN_MAPPING에 섞어 두었고, rlzt_pfls 등은 nass_amt·asst_icdc_amt 같은 합계 필드 뒤에 나열돼 있습니다. legacy 예제는 더 헷갈립니다 — get_inquire_balance_rlz_pl_lst()는 주석에 "Output2"라고 써 놓고 실제로는 output1을 읽고, get_inquire_balance_rlz_pl_obj()는 그 반대입니다. 대응: 첫 실행에서 output1[0].keys()와 output2[0].keys()를 찍어 실제 위치를 확인한 뒤 코드를 고정하세요. 값은 전부 문자열이라 int()/float() 변환이 필요합니다.

함정 ⑤ rlzt_pfls를 정산 숫자로 쓴다

공식 설명은 rlzt_pfls를 "실현손익"이라고만 적고, 어느 기간의 실현인지(당일·누적), COST_ICLD_YN=Y일 때 무슨 비용이 빠지는지는 적지 않습니다. HTS [0800] 화면 기준이라는 안내가 전부입니다. 수수료·제세금이 항목별로 필요한 월간 성과 보고, 세금 계산에는 fee·tl_tax를 따로 주는 TTTC8715R을 쓰세요. TTTC8494R은 "지금 화면에 띄우는 근사치"로 두고, 하루 한 번 TTTC8715R 합계와 대조하는 구조가 안전합니다.

연속조회도 확인하세요. 예제는 응답 헤더 tr_cont가 M 또는 F면 ctx_area_fk100·ctx_area_nk100을 다음 요청에 넣고 tr_cont=N으로 재호출합니다. TTTC8434R 예제에는 "실전 1회 최대 50건"이 명시돼 있지만 TTTC8494R 예제에는 건수 문구가 없습니다. 보유 종목이 많다면 연속조회를 처음부터 넣어 두세요 — 구조는 잔고조회 연속조회 글과 같습니다.

5. 동작하는 코드 — 연속조회 포함

requests만 쓰는 단독 버전입니다. 키·계좌번호는 환경변수로 받습니다(코드에 직접 쓰지 마세요).

import os, time, requests

BASE = "https://openapi.koreainvestment.com:9443"   # 실전 전용 — 모의 도메인에선 쓰지 않는다
URL = BASE + "/uapi/domestic-stock/v1/trading/inquire-balance-rlz-pl"

def _headers(tr_cont=""):
    return {"content-type": "application/json; charset=utf-8",
            "authorization": f"Bearer {os.environ['KIS_ACCESS_TOKEN']}",
            "appkey": os.environ["KIS_APPKEY"], "appsecret": os.environ["KIS_APPSECRET"],
            "tr_id": "TTTC8494R", "tr_cont": tr_cont, "custtype": "P"}

def balance_rlz_pl(cano, acnt_prdt_cd="01", max_pages=10):
    params = {"CANO": cano, "ACNT_PRDT_CD": acnt_prdt_cd, "AFHR_FLPR_YN": "N", "OFL_YN": "",
              "INQR_DVSN": "02", "UNPR_DVSN": "01", "FUND_STTL_ICLD_YN": "N",
              "FNCG_AMT_AUTO_RDPT_YN": "N", "PRCS_DVSN": "01", "COST_ICLD_YN": "N",
              "CTX_AREA_FK100": "", "CTX_AREA_NK100": ""}
    rows, summary, tr_cont = [], None, ""
    for _ in range(max_pages):
        r = requests.get(URL, headers=_headers(tr_cont), params=params, timeout=10)
        body = r.json()
        if body.get("rt_cd") != "0":
            raise RuntimeError(f'{body.get("msg_cd")} {body.get("msg1")}')
        rows += body.get("output1") or []
        o2 = body.get("output2")
        if o2:
            summary = o2[0] if isinstance(o2, list) else o2
        if r.headers.get("tr_cont") not in ("F", "M"):     # 응답 "헤더"의 tr_cont
            break
        params["CTX_AREA_FK100"] = body["ctx_area_fk100"]
        params["CTX_AREA_NK100"] = body["ctx_area_nk100"]
        tr_cont = "N"                                      # 두 번째 호출부터 N
        time.sleep(0.1)
    return rows, summary

rows, s = balance_rlz_pl(os.environ["KIS_CANO"])
held = [x for x in rows if int(x["hldg_qty"]) > 0]        # 전부 문자열로 온다
print(sorted(s.keys()))                                   # 첫 실행 땐 키부터 확인
print("실현손익", float(s["rlzt_pfls"]), "실평가손익", float(s["real_evlu_pfls"]))

대시보드가 몇 초마다 이 API를 부르면 주문·시세 조회와 같은 한도를 나눠 씁니다. 몰리면 아래 응답이 오니 EGW00201 해결 글처럼 호출 간격을 둡니다. 다른 에러코드는 KIS API 에러코드 정리에 있습니다.

{"rt_cd": "1", "msg_cd": "EGW00201", "msg1": "초당 거래건수를 초과하였습니다."}

키움증권 REST API를 쓰는 경우 같은 역할은 ka10072 실현손익 조회가 맡습니다. 증권사마다 "실현손익"의 기간·비용 기준이 다르니 숫자를 섞어 쓰지 마세요.

이 글의 tr_id·파라미터·필드는 한국투자증권 공식 GitHub 저장소를 2026-10-05에 내려받아 대조한 것입니다. 스펙은 예고 없이 바뀔 수 있으니 KIS Developers 공식 문서를 함께 확인하세요.

6. 자주 묻는 질문

TTTC8494R은 모의투자에서 되나요?

공식 저장소 legacy/README.md의 지원 표에서 주식잔고조회_실현손익의 모의투자 칸은 비어 있고, 공식 예제 함수에도 실전/모의를 고르는 env_dv 인자가 없습니다. 공식 kis_auth.py는 모의 모드에서 tr_id를 VTTC8494R로 바꿔 보내므로 모의 서버에서는 동작하지 않는다고 보고 개발하는 편이 안전합니다.

TTTC8434R과 TTTC8494R 중 무엇을 써야 하나요?

손익 표시가 목적이면 TTTC8494R 하나로 잔고와 실현손익을 같이 받을 수 있습니다. 다만 실전 전용이고 증거금율·대용가격 필드(item_mgna_rt_name, grta_rt_name, sbst_pric)가 없으므로, 모의 개발 단계이거나 신용·담보 로직이 있으면 TTTC8434R을 씁니다.

INQR_DVSN에는 00과 02 중 무엇을 넣나요?

공식 설명은 00:전체, 최신 예제와 Postman 요청은 02, legacy 예제는 00으로 서로 다릅니다. 실계좌에서 두 값으로 한 번씩 호출해 output1 행 수와 output2 합계가 같은지 확인한 뒤 하나로 고정하는 것을 권합니다.

rlzt_pfls 값으로 월 수익을 계산해도 되나요?

권하지 않습니다. 공식 설명에 실현손익의 기간과 비용 포함 범위가 적혀 있지 않습니다. 수수료(fee)와 제세금(tl_tax)이 따로 필요한 정산에는 기간별매매손익현황조회 TTTC8715R을 쓰고, TTTC8494R은 화면 표시용 근사치로 두는 편이 안전합니다.

손익이 정확히 찍히는 대시보드까지 붙여 드립니다

사용 중인 증권사와 보고 싶은 숫자만 알려 주세요. 24시간 빠른 답변 가능합니다.

무료 상담 시작하기