slowlp
← 블로그
교훈 2026.06.11 · 4분 읽기

다 만들고 나서 약관을 읽었다

주식 포트폴리오 앱 개발기 — KIS API 규제 삽질과 방향 전환

교훈

다 만들고 나서 약관을 읽었다

주식 포트폴리오 앱 개발기 — KIS API 규제 삽질과 방향 전환

slowloop 브랜드 이름을 고를 때, 후보 중에 For Loop도 있었다. for(;;) { ship(); } — 개발자라면 바로 웃는 이름이었는데, 일반 사용자한테는 그냥 영어 단어 두 개일 뿐이었다. 주식 관리 앱을 쓰는 사람들이 “for loop이 만든 앱”이라는 말을 들어도 아무 감흥이 없다 — 라고 쓴 적이 있다. 그 주식 관리 앱이 바로 이 이야기의 주인공이다.


처음 만들려 했던 건 단순했다. 주식에 관심은 있지만 종목 분석이 어려운 사람들을 위해, 포트폴리오 단위로 매매 계획을 세우고 실행할 수 있는 앱. 한국투자증권 API와 연동해서, 사용자가 포트폴리오를 만들고 비중을 설정하면 앱이 주문 계획을 계산해주는 구조였다.

AI 에이전트와 함께 만들었다. 백엔드는 FastAPI, 모바일은 Expo, 인증은 Clerk, DB는 PostgreSQL. 기능별로 브랜치를 따서 병렬로 작업하고, 통합 스크립트로 dev에 합치는 워크트리 파이프라인을 썼다. 매니저 에이전트, 워커 에이전트, 리뷰어 에이전트를 분리하는 멀티에이전트 실험도 해봤다. 그 과정에서 “에이전트 간 컨텍스트 전달과 피드 관리가 핵심”이라는 걸 직접 확인했다.

꽤 많이 만들었다. 포트폴리오 생성 마법사, KIS 실주문 실행, Celery 워커를 통한 주문 처리, 알림 시스템, 손익 계산. 70%쯤 됐을 때였다.


KIS API를 쓰면서 삽질도 많이 했다. 초당 호출 한도를 넘는 에러(EGW00201)는 12종목 일괄 매도를 짜다가 처음 맞닥뜨렸다. 모의투자 모드에서만 나오는 에러(40100000 — “모의투자 영업일이 아닙니다”)는 테스트 환경 세팅을 잘못 한 거라 한참 헤맸다. D+0 잔고와 D+2 결제잔고를 혼용했다가 숫자가 안 맞는 것도 겪었다. 테스트 환경에 AUTH_EMAIL_ALLOWLIST가 설정된 채로 pytest를 돌렸더니 전체 엔드포인트가 403이 나온 일도 있었다.

배포는 집 서버에 했다. GitHub Actions self-hosted runner를 집 서버에 깔고, dev-release 브랜치에 올리면 자동으로 Docker Compose가 돌아가는 구조였다. 이쪽에서도 삽질이 있었다.

처음엔 korat.iptime.org 도메인을 쓰려고 했는데, Let’s Encrypt 인증서 발급이 계속 실패했다. 포트포워딩부터 의심했고, 방화벽 설정도 뒤졌다. 이틀이 지나서야 원인을 찾았다 — iptime.org의 CAA 레코드에 0 issue ";" 가 박혀 있었다. 모든 공인 CA의 인증서 발급을 전면 차단하는 설정이었고, 상위 도메인 DNS를 내가 제어할 수 없으니 고칠 방법도 없었다. dig +short CAA iptime.org 한 줄이 이틀짜리 삽질을 끝냈다. 그 뒤로는 DuckDNS로 갈아탔다.

self-hosted runner가 배포 서버이기도 해서 포트 충돌도 났다. CI가 테스트 DB 컨테이너를 올릴 때 라이브 dev 스택이 같은 5432 포트를 이미 점유하고 있었다. Docker Compose의 ports 오버라이드에서 !reset []이라는 문법을 이때 처음 썼다 — base에 있는 포트 매핑을 완전히 지우는 방법인데, 그냥 빈 배열 []로는 안 지워진다.

수동 폴더에서 docker compose up을 한 번 잘못 돌렸다가 연쇄 장애도 겪었다. 낡은 체크아웃에는 프로젝트명 핀(name:)이 없어서 디렉터리명이 프로젝트명이 됐고, 라이브 스택과 컨테이너명이 충돌했다. 거기에 환경변수 누락이 겹쳐서 사이트가 내려갔다. 그날 이후로 수동 폴더는 아예 없앴다.


그리고 개발이 거의 마무리될 때쯤, KIS API 약관을 다시 읽었다.

핀테크 사업자가 타인의 계좌에 대해 API를 대행 호출하려면 금융위 인가 또는 법인 + 금융자문업 제휴가 필요했다. 개인이 다른 사람의 계좌에 붙어서 주문을 실행하는 건 안 된다는 얘기였다. 사실상 공개 런칭이 막혔다.

처음에는 꽤 허탈했다. 기능은 다 만들었는데. 그런데 잠깐 생각해보니 방향이 완전히 막힌 건 아니었다. 나 자신의 계좌에 쓰는 건 문제없다. 개인 서버에서 본인 전용으로 운영하면 된다. 만든 것이 낭비가 아니라 내 투자 도구로 자산화됐다.

지금은 그렇게 쓰고 있다. 포트폴리오를 만들고, 비중을 설정하고, 앱이 계산한 주문 계획을 확인한 뒤 실행하는 흐름으로.


이 경험에서 하나를 챙겨간다면 — 외부 API나 규제 제약은 설계 전에 먼저 확인해야 한다는 것이다. 70%를 만들고 나서 방향을 바꾸는 건 처음부터 제약을 알고 설계하는 것보다 훨씬 힘들다. 나는 다행히 본인 용도로 전환할 수 있었지만, 처음부터 그 제약을 알았다면 설계 자체가 달라졌을 수 있다.

새 도메인을 쓸 때 dig +short CAA <도메인>을 먼저 확인하는 습관도 챙겼다. 이틀짜리 삽질을 한 번 더 안 해도 되는 한 줄이다.


<- 이전 편: 브랜드 사이트 기획하다가 슬로우루프가 뭔지 알았다 다음 편 ->: AI 에이전트로 주식 포트폴리오 앱을 만들면서 겪은 것들 함께 보기: 집 서버에 주식 앱 배포하다 겪은 삽질 3가지 · 1인 개발자가 반복하는 실수 5가지

댓글