AlgoLab Blog · 한국투자증권 시세분석 · 2026

KIS API 조건검색 — psearch 함정 5가지

한국투자증권 · 조건검색 2026-09-05 · 약 7분 읽기 · 알고랩 AlgoLab
한 줄 요약

조건검색은 키움 전용이 아닙니다. 한국투자증권 KIS API 에도 있습니다 — 목록은 GET /uapi/domestic-stock/v1/quotations/psearch-title(tr_id: HHKST03900300), 결과는 .../psearch-result(HHKST03900400)이고, 앞의 응답에서 받은 seq 를 뒤의 입력으로 넘깁니다. 다만 다섯 군데가 걸립니다. ⑴ 조건식을 API 로 만들 수 없습니다 — HTS eFriend Plus [0110] 에서 만든 것을 불러 씁니다. ⑵ ‘사용자조건 서버저장’ 을 안 누르면 목록이 비어 있거나 “조회가 계속 됩니다” 오류가 납니다. ⑶ 결과가 0건이면 rt_cd:"1", MCA05918 종목코드 오류입니다 로 옵니다 — 정상인데 오류 모양입니다. ⑷ 조건당 100건에서 잘립니다. ⑸ 종목 배열은 output1 이 아니라 output2 에 들어옵니다.

이 글은 한국투자증권 KIS API 자동매매 허브에서 조건검색 한 갈래만 떼어 낸 글입니다. 앱키 발급과 토큰부터라면 KIS API 키 발급 30분 가이드를 먼저 보십시오.

구조 — 두 번 부른다

KIS 의 조건검색은 조건을 만드는 API 가 아닙니다. HTS 에서 만들어 둔 나의 조건을 불러다 실행하는 API 입니다. 그래서 호출이 두 단계로 나뉩니다.

단계엔드포인트tr_id입력얻는 것
① 조건 목록GET /uapi/domestic-stock/v1/quotations/psearch-titleHHKST03900300user_idseq·condition_nm
② 조건 실행GET /uapi/domestic-stock/v1/quotations/psearch-resultHHKST03900400user_id·seq종목 배열

user_id 는 앱키가 아니라 HTS ID 입니다. 앱키·시크릿과 별개의 값이라, 설정 파일에 항목을 하나 더 두어야 합니다.

HTS eFriend Plus [0110] 조건검색 사용자조건 서버저장 필수 psearch-title HHKST03900300 output2[].seq seq psearch-result HHKST03900400 output2[] · 최대 100건 0건이면 rt_cd "1" / MCA05918 "종목코드 오류입니다" — 정상 상태다 실시간 편입·이탈 통보 없음 → 다시 호출해 차집합 계산
KIS 조건검색 — HTS에서 만들고, API는 실행만 한다

함정 1 · 조건은 API 로 못 만든다

이 API 로 할 수 있는 것은 실행뿐입니다. “거래대금 상위 + 20일선 돌파 + 시가총액 3,000억 이상” 같은 조건식 자체는 HTS(eFriend Plus)의 [0110] 조건검색 화면에서 만들어야 합니다.

자동매매 관점에서 이게 뜻하는 바는 분명합니다. 조건을 바꾸려면 사람이 HTS 를 켜야 합니다. 조건 자체를 코드로 관리하고 싶다면 조건검색 API 가 아니라 거래량·등락률 순위 API 로 스크리너를 직접 짜는 쪽이 맞습니다. 반대로 이미 손으로 다듬어 둔 조건이 있고 그걸 그대로 자동화하고 싶다면 이 API 가 지름길입니다.

함정 2 · ‘사용자조건 서버저장’ 을 안 누르면 아무것도 안 나온다

가장 많이 막히는 자리입니다. HTS 화면에 조건이 보인다고 서버에 있는 것이 아닙니다. 한국투자증권 공식 샘플 코드에는 이렇게 적혀 있습니다.

“조회가 계속 됩니다. (다음을 누르십시오.)” 오류 발생 시
→ HTS(eFriend Plus) [0110] 조건검색 화면에서 조건을 등록하신 후, 왼쪽 하단의 ‘사용자조건 서버저장’ 을 클릭하셔서 등록한 조건들을 서버로 보낸 후 다시 API 호출 시도 부탁드립니다.

증상은 두 가지로 나옵니다. psearch-title 의 목록이 비어 있다, ㈏ 위 문구의 오류가 뜬다. 둘 다 원인은 같습니다. 조건을 새로 추가하거나 수정할 때마다 서버저장을 다시 눌러야 한다는 점도 함께 기억해 두십시오.

한 가지 더. 공식 안내에 [0110] 화면의 ‘대상변경’ 설정은 HTS 화면에만 적용된다고 못박혀 있습니다. 화면에서 대상 범위를 좁혀 두고 API 결과가 같기를 기대하면 어긋납니다.

함정 3 · 0건인데 “종목코드 오류입니다”

이 글에서 가장 실무적인 함정입니다. 조건을 만족하는 종목이 하나도 없을 때, KIS 는 빈 배열을 주지 않고 오류 모양의 응답을 줍니다. 공식 샘플 코드가 직접 명시하는 내용입니다.

{"rt_cd":"1","msg_cd":"MCA05918","msg1":"종목코드 오류입니다."}

정상 상태입니다. 그런데 KIS 응답 처리의 표준 관례는 rt_cd == "0" 을 성공으로 보는 것이라(KIS API 에러코드 정리 참고) 대부분의 코드가 여기서 예외를 던집니다.

이 조합이 만드는 사고. 장중 조용한 구간에 조건이 0건을 반환합니다 → 봇이 예외를 던집니다 → 재시도 로직이 즉시 다시 호출합니다 → 여전히 0건입니다 → 이 루프가 호출 한도를 태웁니다. 결국 정작 필요한 시세·주문 호출이 EGW00201 로 막힙니다(EGW00201 초당 호출 제한 해결). 원인은 조건검색인데 증상은 주문 쪽에서 터져 진단이 오래 걸립니다.

처리는 간단합니다. msg_cdMCA05918 이면 빈 리스트로 바꿔 주면 됩니다.

import requests

BASE = "https://openapi.koreainvestment.com:9443"
EMPTY = "MCA05918"          # 조건 결과 0건일 때 오는 msg_cd

def _headers(token, tr_id, appkey, appsecret):
    return {
        "content-type": "application/json; charset=utf-8",
        "authorization": f"Bearer {token}",
        "appkey": appkey, "appsecret": appsecret,
        "tr_id": tr_id,
        "custtype": "P",     # 개인·법인 "P" / 제휴사 "B"
    }

def psearch_result(token, appkey, appsecret, hts_id, seq):
    r = requests.get(
        BASE + "/uapi/domestic-stock/v1/quotations/psearch-result",
        headers=_headers(token, "HHKST03900400", appkey, appsecret),
        params={"user_id": hts_id, "seq": seq},   # GET · 쿼리스트링
        timeout=10,
    )
    d = r.json()

    if d.get("msg_cd") == EMPTY:      # 0건 = 정상. 예외 아님
        return []
    if d.get("rt_cd") != "0":
        raise RuntimeError(f'{d.get("msg_cd")} {d.get("msg1")}')

    return d.get("output2") or []      # output1 아님

함정 4 · 조건당 100건에서 잘린다

공식 샘플 코드에 “시스템 안정성을 위해 API 로 제공되는 조건검색 결과의 경우 조건당 100건으로 제한” 이라고 적혀 있습니다.

HTS 화면에서 300종목이 잡히는 조건이라도 API 로는 100건에서 끊깁니다. 여기서 진짜 문제는 잘린다는 사실이 아니라 어떤 100건인지 보장되지 않는다는 점입니다. 그래서 이런 설계는 위험합니다.

대응은 조건 자체를 좁혀 100건 미만이 나오게 만드는 것입니다. HTS 조건에서 시가총액·거래대금 하한을 올리거나 조건을 두세 개로 쪼개 각각 부르십시오.

함정 5 · output2 이고, 실시간 통보가 없다

두 TR 모두 종목·조건 배열이 output1 이 아니라 output2 에 들어옵니다. 공식 샘플도 res.getBody().output2 로 읽습니다. KIS 의 다른 조회 API 를 쓰던 감각으로 output1 을 먼저 열어 보면 비어 있어 “결과가 없다” 고 오해하기 쉽습니다.

psearch-titleoutput2 는 조건 하나가 한 원소입니다.

필드
user_idHTS ID
seq조건키값 — 이 값을 psearch-result 로 넘긴다
grp_nm그룹명
condition_nm조건명 — HTS 에서 붙인 이름

psearch-resultoutput2 는 종목 하나가 한 원소이고, 시세가 함께 실려 옵니다. code(종목코드)·name(종목명)·price(현재가)·chgrate(등락율)·acml_vol(거래량)·trade_amt(거래대금)·cttr(체결강도)·open·high·low·high52·low52·expprice(예상체결가)·uplmtprice(상한가)·dnlmtprice(하한가)·stotprice(시가총액) 등입니다. 종목 리스트를 받고 다시 현재가 API 를 도는 코드는 대개 필요 없습니다 — 호출을 절반으로 줄일 수 있습니다.

키움과 갈리는 지점. 키움 REST API 의 조건검색은 WebSocket 으로 실시간 편입·이탈을 밀어 주는 방식이 있습니다. KIS 의 psearch-title·psearch-result둘 다 REST 조회입니다. 그래서 편입·이탈을 알려면 주기적으로 다시 호출해 직전 종목 집합과의 차집합을 직접 계산해야 합니다. 조건검색으로 자동매매를 굴리는 전체 그림은 조건검색 자동매매에 정리해 두었습니다. 실시간 지원 여부는 KIS Developers 공식 문서에서 확인하십시오.

prev = set()

def poll(token, appkey, appsecret, hts_id, seq):
    """편입·이탈을 차집합으로 계산한다."""
    global prev
    now = {row["code"] for row in
           psearch_result(token, appkey, appsecret, hts_id, seq)}
    entered, left = now - prev, prev - now
    prev = now
    return entered, left        # 편입 / 이탈

폴링 간격을 정할 때는 조건검색만 도는 것이 아니라는 점을 기억하십시오. 시세·주문·잔고가 같은 계정 한도를 나눠 씁니다. 조건 3개를 5초마다 돌리면 그것만으로 분당 36회입니다.

모의투자 참고. 한국투자증권 공식 샘플 코드의 모의투자 TR 치환 규칙은 tr_id 첫 글자가 T·J·C 인 경우에만 V 로 바꿉니다. 조건검색의 HHKST03900300·HHKST03900400그 규칙의 대상이 아닙니다. 모의투자 계정에서 쓸 수 있는지는 KIS Developers 공식 문서에서 반드시 확인하십시오. 실전·모의 전환 전반은 KIS 모의투자에서 실전 전환에 정리해 두었습니다.

붙이기 전 체크리스트

KIS 조건검색을 봇에 붙이기 전에

고지. 이 글은 기술 자료이며 특정 종목·전략을 권유하지 않습니다. 본문의 엔드포인트·tr_id·응답 필드·제한 사항은 한국투자증권 공식 open-trading-api 샘플 코드의 기재를 대조해 정리했지만, 증권사 API 스펙은 예고 없이 바뀌므로 실제 필드명과 제한값은 반드시 KIS Developers 공식 문서에서 다시 확인하십시오. 알고랩(퀀트웍스)은 투자자문업·투자일임업을 영위하지 않으며, 고객이 지정한 규칙을 프로그램으로 구현해 드리는 도구 제공자입니다.

손으로 다듬은 조건, 자동으로 돌리시겠어요?

조건 편입 감지부터 주문·리스크 한도까지 사람이 안 봐도 도는 상태로 만들어 드립니다. 24시간 빠른 답변 가능합니다.

상담 문의하기