바이브 코딩, 주식 거래 관리 앱 개발 ① — 엑셀 기반 자동화

지난번 「바이브 코딩으로 웹앱 만들기」에서 아이의 학습 습관을 기록하는 웹앱 My Lesson Log를 만든 이야기를 했습니다. 다행히 아이가 지금도 잘 쓰고 있습니다. 이번에는 저와 아내가 쓸 프로그램을 만들었습니다. 우리 가족의 주식 계좌 거래내역을 한곳에서 관리하는 TradeLog입니다.

기존에 수동으로 하던 작업을 엑셀 기반 자동화 스크립트로 만들고, 이를 데스크톱 앱 형태로 개선하고, 이후 웹서비스까지, 수차례 버전을 올리며 발전시켰습니다. 개발을 진행하면서 경험한 내용들을 총 세 편의 글로 정리하고자 합니다. 이번 글에서는 엑셀로 자동화하던 첫 단계(V1~V3)를 다룹니다.

그리고 이 과정에서 다시 확인한 한 가지, 완벽한 설계보다, 정확히 동작하는 버전을 확보하는 것이 가장 중요한 일이라는 점을 함께 짚어보겠습니다.

앞서 「바이브 코딩, 제대로 하는 법 — 10가지 원칙」에서 AI와 협업하는 개발 원칙을 정리한 적이 있습니다. 설계, 점진적 확장, 테스트, 검증, 기록 같은 것들입니다. 그 원칙들이 실제 프로젝트에서 어떻게 작동하는지도 이 글을 따라가며 확인할 수 있습니다.


목 차


기존 정리 방식

저와 아내를 포함한 저희 가족은 각자 여러 개의 주식 계좌를 가지고 있습니다. 어쩌다 보니 증권사도 다르고 국내·해외 주식거래, ISA·IRP·연금저축처럼 계좌 종류도 제각각입니다. 저는 이 모든 계좌의 거래내역을 한 화면에서 보고 싶었습니다. 종목별 매매와 배당은 얼마였는지, 지금 무엇을 얼마나 보유하고 있는지를 한눈에 파악하는 것이 목표였습니다.

그동안은 전 과정이 수작업이었습니다.

  1. 증권사 사이트에 로그인해 계좌별로 거래내역 파일을 내려받고
  2. 제각각인 양식을 표준 엑셀 형식으로 옮기고
  3. 피벗 테이블로 종목별 요약을 만든다

이 과정 곳곳에서 실수와 누락이 발생했습니다. 어떤 계좌는 다운로드를 빠뜨리고, 옮기는 과정에서 행이 누락되고, 증권사마다 컬럼 이름이 달라 잘못 매핑되기도 했습니다. 게다가 “계좌별이 아니라 사람별로 보고 싶다”처럼 관점을 바꾸려면 피벗을 처음부터 다시 짜야 했습니다. 보는 방식 하나 바꾸는 데 적지 않은 시간이 들었습니다. 실수를 하지 않기 위해 집중해야 했고, 많은 시간을 쏟아부어야 했습니다.

더 심각한 문제는 틀려도 틀린 줄 모른다는 것이었습니다. 손으로 옮긴 숫자가 맞는지 확인할 방법이 없었으니까요. 실제로 이번 자동화 과정에서, 그동안 수작업으로 관리하던 데이터에서 누락된 거래를 발견하기도 했습니다. 수작업은 틀려도 조용히 틀립니다. 자동화를 해야 하는 중요한 이유 중 하나입니다.


V1. 기존 방식 대체

새로운 프로젝트를 시작할 때는 작게 시작하는 것이 좋습니다. 처음부터 방대한 기능을 가진 웹서비스를 목표로 할 수도 있지만, 작은 서비스를 만들고 점진적으로 확장해 나가는 것이 개발에서 발생하는 불확실성을 단계적으로 제거할 수 있기 때문에 보다 더 안전하고, 결과적으로 개발 시간도 단축할 수 있습니다. 사실 이것은 AI시대의 바이브코딩과는 무관한 원칙입니다.

특히, AI와 작업을 해야 하는 상황에서, 제가 생각한 가장 중요한 첫 번째 목표는 사람이 손으로 하던 일을 코드로 똑같이 재현하는 것이었습니다. 새 기능을 더하기 전에 기존 방식을 빠짐없이 대체하는 것이 중요합니다.

그래서 첫 번째 버전은 엑셀 파일 하나를 이용하는 방식으로 정리했습니다. 계좌별 거래내역 RAW 데이터를 별도의 시트로 붙여넣으면, 스크립트가 이를 읽어 계좌별 표준화된 종목별 거래 및 통계 시트를 만들고 전체 요약 시트를 갱신합니다. 사람이 “다운로드 → 변환 → 피벗”으로 하던 일을 시트 간 변환으로 옮긴 것입니다.

이 단계에서는 새 기능은 고려하지 않았습니다. 더 똑똑하지도 않았습니다. 사람이 하던 일을 똑같이 재현했을 뿐입니다. 그리고 바로 그 점이 중요했습니다.

완벽한 대체가 곧 정답지가 된다

첫 번째 버전의 출력은 그동안 사람이 손으로 만들던 결과물과 정확히 일치해야 합니다. 기존 방식을 완벽히 대체했다는 건 같은 입력에 같은 결과를 낸다는 뜻이기 때문입니다. 그리고, 그 조건을 만족하는 순간, 이 버전은 단순한 첫 번째 버전이 아니라 오라클(oracle), 즉 정답지가 됩니다.

이후로는 리팩토링을 하든, 입력 방식을 바꾸든, 도구를 교체하든 결과가 이 오라클이 만들어내는 결과와 일치하는가라는 질문 하나로 검증할 수 있습니다. 동작하는 첫 버전을 빠르게 확보하는 것이 중요한 이유가 여기 있습니다. 정답지가 없으면 이후의 어떤 변경도 맞는지 틀린지 검증할 기준이 없습니다.

동작 다음은 확장가능한 구조 확보

일단 동작하게 만든 뒤 곧바로 코드를 정리했습니다. 처음 작성한 코드를 살펴보니 main() 함수 하나에 파일 입출력, 파라미터 파싱, 처리 로직이 뒤엉켜 있어 테스트가 불가능한 구조였습니다.

가장 먼저 처리 로직을 별도 함수로 분리했습니다. 파일 입출력과 핵심 로직을 떼어내자, 실제 엑셀 파일 없이 메모리상의 워크북만으로 테스트할 수 있게 됐습니다.

그 위에 테스트를 쌓았습니다. 날짜·금액 파싱 같은 순수 함수 테스트, 증권사별 컬럼 해석 테스트, 통계 수식 재구성 테스트, 전체 파이프라인 통합 테스트까지, 무엇을 테스트할지는 제가 정하고, 실제 테스트 코드 작성은 AI가 맡았습니다.

여기서 오라클이 아주 중요한 역할을 합니다. 회귀 테스트(regression test)입니다.

# 리팩토링 전, 최초 버전이 만든 출력물
cp data/TradeLog_Summary.xlsx _test_before.xlsx
./run.sh v1 _test_before.xlsx --reset

# 리팩토링 후, 같은 입력으로 다시 만든 출력물
cp data/TradeLog_Summary.xlsx _test_after.xlsx
./run.sh v1 _test_after.xlsx --reset

# 두 파일의 모든 시트, 모든 셀을 비교한다

리팩토링 전후의 엑셀파일을 모든 시트, 모든 셀 단위로 비교합니다. 차이가 있으면 시트명과 셀 주소, 전후 값을 그대로 출력합니다. 기능은 그대로 두고 구조만 개선했다는 사실을 자동으로 검증하는 방식입니다.

이 안전망 위에서 리팩토링을 세 단계로 나눠 진행했습니다. 중복 상수 정리, 거래종류 분기 단순화, 반복되는 서식 복사 로직 추출. 단계마다 단위 테스트 70개와 회귀 테스트 29개, 총 99개를 돌려 통과를 확인했습니다.

한 가지 강조하고 싶은 점은, 이 리팩토링의 목적이 사람이 읽기 좋게가 아니라 다음에 이 코드를 이어받을 AI가 더 정확히 작업하게 만드는 것이었습니다. 구조가 깔끔할수록 AI가 맥락을 정확히 파악하고, 엉뚱한 곳을 건드릴 여지가 줄어듭니다. 이 관점은 이후 버전에서 더 분명해집니다.


V2. 입력 확장성 확보

V1은 기존 방식을 완벽히 대체했지만, 입력 단계가 여전히 사람 손에 묶여 있었습니다. 증권사에서 받은 파일을 워크북 안에 RAW 시트로 일일이 붙여넣어야 했기 때문입니다. 새 증권사나 계좌가 늘 때마다 손이 더 갔습니다.

V2의 목표는 입력 단계의 수고를 줄이고 확장성을 확보하는 것이었습니다. 어떤 증권사 파일이든 내려받은 그대로 넣으면 처리되도록 만드는 것입니다. 정답지(오라클)는 그대로 둔 채, 앞단의 확장성만 키우는 작업이었습니다. 이 부분은 나중에 웹서비스로 확장할 때, 업로드한 파일을 처리하는 로직으로 활용될 예정입니다.

폴더 기반으로 전환

파일별로 계좌 소유자, 증권사, 계좌종류 등 정보가 필요했기 때문에, 가장 손쉬운 방법으로 폴더구조를 선택했습니다.
사용자 / 증권사 / 계좌 / 폴더를 두고, 증권사에서 다운로드 받은 파일을 해당 위치에 넣어두기만 하면 됩니다.

data/
└── {사용자}/{증권사}/{계좌}/filename.xlsx

이 규칙만 지키면 스크립트가 폴더를 훑으며 아직 처리하지 않은 파일을 찾아 처리합니다. 이때 동일한 파일을 중복으로 처리하는 상황을 막기 위해 처리 완료된 파일은 경로와 fingerprint(파일 크기·수정 시각)를 별도의 JSON에 기록해 두고, 같은 파일을 다시 만나면 건너뛰게 하였습니다.

증권사 거래내역 RAW 데이터의 현실

증권사가 내보내는 파일은 예상보다 훨씬 제각각이었습니다. 이 부분이 까다롭더군요.

  • 위장된 .xls 파일 — 확장자만 .xls이고 실제 내용은 HTML 테이블이거나 CSV 텍스트인 경우가 있었습니다. 결국 .xls로 열어 실패하면 HTML로, 다시 실패하면 CSV로 재시도하는 다단계 fallback을 넣었습니다.
  • 다중행 포맷 — 거래 한 건이 3행에 걸쳐 기록되는 경우도 있었습니다. 헤더도 3행, 데이터도 3행씩 묶여 있습니다. 이를 표준 1행 구조로 펼치는 변환 로직을 별도로 작성했습니다.
  • 다중 시트 — 어떤 경우는 매매 시트와 배당 시트가 분리돼 있고, 매매는 거래 1건이 2행, 배당은 1행 구조였습니다.
  • 표기 변형 — 거래를 구분하는 명칭도 증권사마다 제각각입니다. 같은 배당이라도 배당금외화입금배당금(외화)입금처럼 괄호 하나로 표기가 갈렸습니다. 인식하지 못한 거래종류는 누락시키지 않고 경고 로그에 쌓이도록 하여, 확인 후 줄여나갔습니다.

사실 이렇게 다양한 형태의 데이터를 사람이 직접 다루면 실수하기 쉽습니다. 하지만 AI는 이럴 때 놓치지 않고 모든 경우를 처리합니다. AI는 지치지 않기 때문이죠.

또, V1에서 만들어 둔 기준 덕분에 입력 방식을 통째로 바꾸고 파서를 아무리 늘려도 바로 확인이 가능했습니다. 같은 데이터를 넣으면 V1과 같은 결과가 나오는가라는 질문을 유지하면서 과감하게 손볼 수 있었습니다. 어긋나면 회귀 테스트가 잡아주기 때문입니다.

결과적으로 새 증권사나 새 포맷이 등장해도 파서를 한 겹 더 얹으면 되는 구조가 됐습니다. 정답지는 그대로 둔 채 받아들일 수 있는 입력의 폭만 넓힌 것입니다.

이 단계에서 배포 관련 문제도 하나 겪었습니다. 가상환경 밖에서 스크립트를 실행하자 파이썬 실행과 관련된 모듈을 찾지 못하는 에러가 났습니다. 파이썬 파일만 전달하면 된다는 생각이 틀렸던 것입니다. 의존성 설치와 실행을 묶은 setup/run 스크립트로 정리했습니다.


V3. 사용성 개선 — GUI

V2까지 데이터 처리는 탄탄해졌지만, 사용 방식은 여전히 터미널에서 명령어를 입력하는 것이었습니다. 저에게는 익숙해도 가족이 함께 쓰기엔 문턱이 높았습니다. V3의 초점은 기능이 아니라 사용성이었습니다. 누구나 클릭 몇 번으로 쓸 수 있도록 GUI 앱으로 묶었습니다.

핵심은 새 기능 개발이 아니라, 기존 로직을 GUI와 CLI 양쪽에서 쓸 수 있게 공통 core로 분리하는 일이었습니다. 동기화 로직을 별도 패키지로 떼어내고, 그 위에 CLI 진입점과 데스크톱 GUI를 각각 얹었습니다. 화면은 PySide6로 만들고 Windows 실행 패키지로 빌드했습니다.

이 과정에서도 환경 문제를 여럿 만났습니다. Windows 콘솔에서 한글이 깨지는 인코딩 문제, PowerShell 실행 정책에 막혀 스크립트가 동작하지 않는 문제 등입니다. OS마다 동작이 달라 이 부분도 신경을 써야 했습니다.

화면에 보이는 방식도 손봤습니다. 사소해 보이지만 데이터를 여러 관점으로 보고 싶다는 원래 목표에 한 걸음 다가간 사용성 개선이었습니다.

파이썬 스크립트와 달리 GUI 앱은 빌드/배포의 과정을 거쳐야 합니다. 문제는 사용자마다 OS가 다르기도 하고, Windows용, macOS용 실행 파일을 매번 직접 빌드해 올리는 일은 무척 귀찮고 번거롭습니다. 그래서 빌드와 배포를 GitHub Actions를 통해 자동화했습니다. 버전 태그를 push하면 자동으로 Windows와 macOS 실행 파일을 병렬로 빌드하고, 그 결과물을 GitHub Releases에 초안(draft) 형태로 올립니다. 저는 결과를 확인하고 공개 버튼을 누르면 됩니다. 사용성은 단순히 사용자만의 문제가 아니라, 개발자의 문제이기도 합니다.

이 단계에서도 코드를 직접 들여다보며 확인하지는 않았습니다. 앱을 실제로 실행해 나온 결과물과 회귀 테스트가 보증하는 출력으로 판단했습니다. 공통 core 분리도 단순한 정리가 아니라 다음 도약, 즉 웹서비스(V4)를 위한 포석이었습니다. 로직이 화면에서 독립돼 있어야 화면을 통째로 웹으로 바꿔도 핵심을 그대로 재사용할 수 있기 때문입니다.


AI와의 협업 방식

이 과정을 진행하면서 AI와 어떻게 협력을 했는지 정리했습니다.

의사결정. 예를 들어 GUI를 만들 때, 가장 쉬운 건 기존 CLI 명령을 그대로 실행시키는 방식이었지만 AI와 장단점을 따져 보니 이 방식은 패키징, 로그 전달, 오류 처리, OS별 차이에서 복잡해진다는 점이 드러났습니다. 그래서 CLI와 GUI가 같은 core를 직접 호출하는 구조로 정했습니다. 또, V2의 배포 방식을 결정할 때, AI에게 선택지를 달라고 했습니다. 소스와 설치 스크립트를 함께 배포하는 방식, 가상환경을 통째로 포함하는 방식, PyInstaller로 단일 실행 파일을 만드는 방식. 각각의 장단점을 표로 정리받고, 몇 차례 질문/답변을 한 후, 소스와 설치 스크립트를 배포하는 방식으로 선택했습니다. 선택지는 AI가 넓히고, 제가 결정을 하는 방식이었습니다.

구현과 검증. 제가 무엇을 테스트할지 정하면, 실제 테스트 코드는 AI가 작성했습니다. 그 중 가장 중요했던 검증 기준은 V1에서 만든 오라클이었습니다. V1의 결과는 제가 직접 눈으로 확인을 했고, 이후 V1의 결과를 기준점으로 하는 회귀 테스트가 통과하는 한, AI가 만든 코드를 한 줄씩 읽지 않아도 결과를 신뢰할 수 있었습니다.

빌드와 배포. GitHub Actions를 통한 빌드/배포의 경우 사실 제가 직접 적용해 본 적은 없었습니다. AI가 그 방식을 제안해 주었고, 예전에 같이 일하던 분들과 간접적으로 경험한 적이 있어서 바로 이해할 수 있었습니다. 관련 워크플로우도 AI와 함께 작성했고, 자동 빌드를 처음 돌렸을 때 여러 문제점들이 드러났는데, 로그를 함께 읽으며 원인을 좁혀 나갔습니다.

이력 기록. 제가 생각할 때 바이브코딩을 할 때 가장 중요한 부분입니다. AI와의 작업은 세션이 끊기면 맥락도 함께 사라집니다. 그래서 작업 방식과 의사결정 사항들을 문서로 기록했습니다.

  • AGENTS.md — 협업 규칙과 이 프로젝트만의 용어들, 헷갈리면 안 되는 각종 규칙을 정리했습니다.
  • DEVELOPMENT.md — 개발과 테스트의 하네스로서 브랜치 운영, 어떤 변경에 어떤 테스트를 돌릴지, 큰 기능을 단계별로 나눠 단계마다 검증하고 커밋하는 순서까지 적어 두었습니다. AI가 큰 작업을 한 번에 밀어붙이지 않고 안전하게 진행하도록 만든 일종의 가드레일입니다.
  • RETROSPECT.md — 왜 그렇게 결정했는지를 이유와 함께 남긴 회고로서 나중에 같은 고민을 반복하지 않게 해줍니다.
  • HANDOFF.md — 인수인계서. 현재 브랜치, 최근 커밋, 배포 상태, 테스트 결과, 아직 적용하지 않은 변경, 다음 작업 후보를 적습니다. 새 세션의 AI는 이 문서부터 읽고 시작합니다.

이 문서들은 결국 다음 세션 AI의 온보딩 자료입니다. 기록이 곧 AI의 메모리인 셈입니다.

사실 V3까지는, 물론 시간이 좀 걸리겠지만, 제가 직접 해도 되는 일들이었습니다. AI가 빠르게 처리해 줬을 뿐, 필요하면 제 손으로 따라갈 수 있는 범위였습니다. 하지만 다음 단계인 웹서비스는 다릅니다. 백엔드, 데이터베이스, 인증, 배포 운영까지 제가 실무로서 많이 경험해 보지 않았던 영역으로 들어섭니다. 이때는 더더욱 AI에게 얼마나 정확한 맥락을 주느냐가 결과의 품질을 좌우하게 됩니다. 그 이야기는 다음 편에서 다룹니다.


맺음말

V1부터 3까지 구현하는 과정에서, 완벽한 설계를 먼저 끝내고 시작한 적은 없습니다. 먼저 기존 방식을 그대로 대체하는 동작하는 첫 버전을 만들어 정답지로 삼고(V1), 그 위에서 입력의 확장성을 넓히고(V2), 사용성을 끌어올렸습니다(V3). 매 단계 테스트와 회귀 검증, 버전 관리로 안전망을 유지하며 점진적으로 키웠습니다.

이 글에서 다룬 범위까지는 모두 엑셀 기반입니다. 사람이 하던 일을, 사람이 하던 방식 그대로 자동화한 단계였습니다. 하지만 가족이 함께, 여러 기기에서 동시에 쓰려고 하면 엑셀을 중심으로 하는 사용 시나리오는 한계가 드러났습니다. 파일을 누가 들고 있느냐, 누가 무엇을 올렸느냐, 같은 결과를 어떻게 공유하느냐 같은 문제들이죠.

다음 편에서는 이를 극복하기 위해 웹서비스로 전환하고, 원본을 엑셀에서 데이터베이스로 옮긴 과정을 다룰 예정입니다.

동작하는 첫 버전은 단순한 시작점이 아닙니다. 이후의 모든 변화가 옳은지 알려주는 정답지입니다.

ChulJoo Kim (김철주)

ckarch.kr © 2026 is licensed under CC BY-NC-SA 4.0 CC BY NC SA

댓글 남기기