
예전부터 주식 자동매매 봇을 하나 갖고 싶었습니다. 차트를 하루 종일 볼 자신은 없고, 그렇다고 감으로 사고팔기도 싫어서 규칙대로 알아서 움직이는 봇을 만들어 보기로 했습니다. 이름은 quant-pilot입니다. 이 시리즈는 그 봇을 만들면서 정한 것, 돌려 본 것, 그리고 틀렸던 것을 순서대로 적은 기록입니다.
투자 권유 글이 아닙니다. 시리즈에 나오는 수익률은 모두 과거 데이터로 돌린 백테스트 결과라 앞으로의 수익을 보장하지 않습니다. 실제 매매도 아직은 모의투자로만 하고 있습니다.
한눈에 보기
- 시장은 국내주식부터 시작합니다. 소액투자자는 매매차익에 세금이 없고 환전도 필요 없습니다.
- 증권사는 한국투자증권 KIS Open API, 언어는 Python으로 정했습니다. 모의투자 계좌가 무료라 마음 편히 시험할 수 있습니다.
- 대상은 시가총액 1조 원 이상 대형주입니다. ETF는 사지 않고 시장 분위기를 보는 신호로만 씁니다.
- 실전 계좌는 제가 직접 정한 금액으로만 돌리도록 처음부터 막아 뒀습니다.
있는 것부터 꺼내 보기
새로 돈을 쓰기보다 이미 쓰고 있는 것들로 해결하고 싶었습니다. 손에 있던 건 이 정도입니다.
- 오라클 클라우드 무료 서버
- Cloudflare Workers와 Pages
- GitHub 저장소
바라는 건 두 가지였습니다. 일단 수익이 나는 쪽으로 가되, 너무 작은 회사는 위험하니 빼고 싶다는 것입니다. 나머지는 하나씩 따져 보면서 정했습니다.
이렇게 정했습니다
| 항목 | 선택 | 이유 |
|---|---|---|
| 시장 | 국내주식 먼저 | 소액투자자는 매매차익 세금이 없고 환전할 필요도 없습니다. 미국주식은 연 250만 원을 넘는 수익에 양도세 22%가 붙습니다. |
| 증권사 | 한국투자증권 KIS Open API | REST 방식이라 리눅스 서버에서 돌리기 쉽고, 모의투자 계좌가 무료입니다. 같은 API로 미국주식도 됩니다. |
| 언어 | Python | 데이터 분석과 백테스트 라이브러리가 제일 많습니다. |
| 대상 종목 | 시가총액 1조 원 이상 | 관리종목, 우선주, 스팩은 뺍니다. |
| 알림 | 텔레그램 | 무료고, 봇 만들기가 쉽습니다. |
진행은 4단계로 잡았습니다.
- 뼈대 만들기, 모의투자 연결, 종목 필터
- 전략 백테스트
- 모의투자로 자동매매
- 결과가 괜찮으면 제가 정한 금액으로만 실전
마지막 단계를 굳이 따로 적어 둔 이유가 있습니다. 봇이 어느 날 알아서 실전 계좌로 넘어가는 일만큼은 절대 없어야 하니까요.
이름은 quant-pilot
처음에는 kstock-autotrader라는 이름을 생각했습니다. 그런데 나중에 미국주식까지 하게 되면 이름에 시장이 들어간 게 영 어색할 것 같아서 quant-pilot으로 바꿨습니다. 저장소는 비공개(private)로 만들었습니다.
ETF는 왜 안 사나
처음에는 ETF도 같이 사면 되지 않나 싶었는데, 따져 보니 빼는 게 맞았습니다.
- 상승률 순위를 매기면 레버리지 ETF가 늘 위쪽에 올라옵니다. 그런데 레버리지 ETF는 오래 들고 있으면 횡보장에서 가치가 조금씩 깎입니다.
- KODEX 200 같은 ETF는 이미 삼성전자와 SK하이닉스를 담고 있어서, 같이 사면 같은 종목에 두 번 거는 셈이 됩니다.
- 시가총액이나 관리종목 같은 필터는 회사를 거르는 기준이라 ETF에는 맞지 않습니다.
대신 KODEX 200은 시장 상태를 보는 신호로 쓰기로 했습니다. 시장 전체가 내리막이면 새로 사지 않는 식입니다.
첫 결과물: 종목 필터
1단계로 살 만한 종목을 거르는 필터부터 만들었습니다. 기준은 이렇습니다.
- 시가총액 1조 원 이상
- 전일 거래대금 50억 원 이상
- 상장 180일 이상 지난 보통주
- 관리종목, 투자경고, 우선주, 스팩, ETF 제외
한국투자증권 계좌는 윈도우 PC에서만 만들 수 있는 줄 알았는데, 휴대폰 앱으로도 비대면 개설이 됩니다. 저는 이때 계좌가 없어서 연결은 뒤로 미루고 백테스트부터 해 보기로 했습니다.
코드로 보면
저장소가 비공개라 링크 대신 주요 부분만 옮겨 둡니다. 거르는 기준은 설정 한 곳에 모아 두고, 종목마다 "뺄 이유"를 돌려주는 함수 하나로 처리했습니다. 이유가 없으면(None) 통과입니다. 나중에 "이 종목은 왜 빠졌지?"를 바로 알 수 있어서 편합니다.
@dataclass(frozen=True)
class UniverseRules:
min_market_cap: float = 1e12 # 시가총액 1조 원
min_trading_value: float = 5e9 # 전일 거래대금 50억 원
min_listed_days: int = 180 # 신규상장주 제외
markets: tuple[str, ...] = ("KOSPI", "KOSDAQ")
def exclusion_reason(stock, rules, today):
"""종목을 뺄 이유를 돌려준다. None 이면 대상에 포함."""
if stock.group != "ST":
return "보통 주식 아님(ETF/ETN/리츠 등)"
if stock.preferred:
return "우선주"
if stock.spac:
return "스팩"
if stock.admin_issue:
return "관리종목"
if stock.market_warning:
return "투자주의/경고/위험"
if stock.market_cap < rules.min_market_cap:
return "시가총액 미달"
if stock.prev_trading_value < rules.min_trading_value:
return "거래대금 미달"
if today - stock.listed_date < timedelta(days=rules.min_listed_days):
return "신규상장"
return None
종목 정보(시가총액, 관리종목 여부 등)는 한국투자증권이 매일 공개하는 종목 마스터 파일에서 읽습니다. 계좌가 없어도 받을 수 있는 파일이라 이 단계는 계좌 없이 끝낼 수 있었습니다.
다음 편에서는 모멘텀 전략을 10년치 데이터로 돌려 봅니다. 솔직히 당연히 잘 나올 줄 알았는데, 결과는 꽤 달랐습니다.
주식 자동매매 봇 만들기
'개발 > 주식 자동매매' 카테고리의 다른 글
| 주식 자동매매 봇 만들기 6편: 텔레그램 알림 봇 만들기와 한국투자증권 모의투자 연결 (0) | 2026.10.15 |
|---|---|
| 주식 자동매매 봇 만들기 5편: 공시와 뉴스로 악재 종목 거르기, 네이버 뉴스 검색 API 발급 (0) | 2026.10.15 |
| 주식 자동매매 봇 만들기 4편: 서버 없이 GitHub Actions로 매일 아침 9시 10분에 도는 봇 (0) | 2026.10.15 |
| 주식 자동매매 봇 만들기 3편: 8가지 전략 비교, 그리고 연 +32%가 가짜였던 이유 (0) | 2026.10.15 |
| 주식 자동매매 봇 만들기 2편: 모멘텀 전략 10년 백테스트, 결과는 지수도 못 이김 (0) | 2026.10.15 |