사람이 손대지 않아도 도는 구조

평일 08:50에 깨어나 15:30에 일지를 쓰고 잠드는 봇이 서울 리전의 5달러짜리 서버에서 돕니다. 사람이 개입하는 지점은 두 곳뿐입니다. 슬랙과 실시간 페이지로 결과를 읽는 것, 그리고 주 1회 에이전트 팀이 올린 규칙 변경안을 승인하는 것.

구성 요소

맥 (개발·분석)코드 수정, 백테스트, 에이전트 리뷰. 무거운 작업은 전부 여기서
→
GitHub 비공개 저장소 + rsync.env는 git 제외, rsync로만 서버 전송. 배포는 장 마감 후에만
→
AWS Lightsail · 서울Ubuntu 24.04, nano(414MB, $5/월), systemd 서비스 stock-bot: 부팅 자동시작, 죽으면 30초 후 재시작, TZ=Asia/Seoul
⇄
한국투자증권 Open APIREST. 토큰·순위·일봉·현재가·체결강도·지수·주문·체결조회·잔고
→
출력슬랙 웹훅, reports/날짜.md, trades.jsonl, paper_trades.jsonl, 일자별 로그, live/status.json(10초)

상태 영속화 · 자가치유

보유 포지션과 대기 주문을 파일로 저장. 재시작하면 오늘 상태를 복원하고 잔고와 대조해 체결분을 재편입, 미체결 주문은 회수합니다.

서버 복구

맥의 AWS CLI로 reboot-instance 한 줄이면 1.5분 뒤 복귀, 봇은 systemd가 띄웁니다. 10/8 밤 서버에서 수집 작업을 돌리다 메모리 고갈로 멈춘 뒤 "서버에서 무거운 작업 금지"가 규칙이 됐습니다.

알려진 한계

봇은 공휴일을 모릅니다(평일만 판단). 휴장일엔 순위 API가 빈 응답을 주어 자연히 무매매라 무해합니다. 등락률 순위 API는 9/15 이후 계속 빈 응답이라 후보군은 거래량 순위 30개에서 ETF를 뺀 것뿐입니다.

하루 세션 (평일, KST)

시각단계하는 일
~08:49대기다음 평일 세션까지 sleep. 최대 1시간 단위로 쪼개서 깨어남(맥 시절 잠자기 중 타이머가 멈춰 세션을 놓친 사고 이후).
08:50세션 시작일자별 로그 파일 생성, 실계좌·가상 포트폴리오 복원, 토큰 갱신(09:00 만료 시).
09:00~지수 필터10분마다 코스피(0001)·코스닥(1001) 등락률 조회. 둘 중 하나라도 −1.0% 이하면 신규 매수와 스크리닝 중단, 보유분 관리만 계속. 해제되면 재개.
09:05첫 스크리닝거래량 순위 상위 → ETF 제외 → 후보 약 13종목 → 25일 일봉으로 4개 전략 판정 → 중복 제거 → 시그널 목록.
09:05~라우팅전략 모드가 PAPER이거나 서킷브레이커 발동 후면 가상 장부로. LIVE면 체결강도 조회 → 80 미만은 섀도우 기록, 이상이면 실매수.
매수지정가 + 체결 확인시장가는 상한가 기준 증거금 때문에 거절되므로 지정가 주문 → 주문번호로 체결조회(TTTC8001R) → 체결 수량만 포지션 등록. 진입 스냅샷(점수·순위·거래대금·체결강도·지수) 저장.
10초마다모니터링 · 상태 발행현재가 폴링 → 손절(−3%, IOC 최유리 2회 → 시장가) / 트레일링(+1.5% 활성, 고점 −1.5%) / 조건부 타임컷(15분·30분) 판정. 5/10/15/30/60분 MFE 버킷 갱신. 같은 주기로 status.json 기록.
30분마다재스크리닝빈 슬롯이 있고 지수 필터가 통과 상태면 반복. 포트폴리오 요약도 30분마다 로그.
청산 후 60분사후 추적청산 종목의 5/10/30/60분 뒤·최종 가격을 기록(컷 과잉 판정용). 트레일링 청산 후 +1% 회복 시 가상 재진입 섀도우.
15:00강제 청산신규 매수 금지, 보유분 전부 청산.
15:30장 종료매매일지 .md 생성(요약·성찰·"오늘의 이야기"), 슬랙 요약 전송, 가상 장부 집계, 상태 파일 초기화.

봇 위의 에이전트, 에이전트 위의 사람

매일

규칙 엔진 (봇)

판단하지 않습니다. 규칙을 집행하고 모든 것을 기록합니다. 기록의 목적은 "왜 졌는지"가 아니라 "이 규칙이 반복 가능한 엣지를 갖는지"를 나중에 판정할 수 있게 하는 것.

주 1회

멀티에이전트 퀀트팀

리서처 3(병렬) → 적대적 비판자 → 리스크 매니저(거부권·롤백 조건) → PM. 1회차는 Fable 5, 2회차는 Opus 5.5 서브에이전트로 돌았습니다. 입력은 trades.jsonl과 12지표 성적표. 섀도우 모드로 실탄 없이 가설을 검증합니다.

승인

사람

승인·기각·보류만 결정합니다. 전략 삭제는 "단일 주 EV 음수"로는 금지하고, 충분 표본·여러 국면·비용 포함·PAPER 결과를 종합해서만 허용합니다. 외부 AI 조언이 오면 시뮬레이션으로 숫자로 검증합니다.

왜 "완전자동화"인데 사람이 남아 있나 — 규칙을 바꾸면 통계의 시계가 리셋됩니다(0.5%p 차이를 구분하는 데 약 383건·8주, 기대 비용 약 −32만원). 바꿀지 말지는 비용을 치르는 쪽이 결정해야 하므로, 자동화의 경계를 "집행과 검증"까지로 두고 "규칙 변경"은 사람에게 남겼습니다.

실시간 페이지는 어떻게 서버와 이어지나

live_status.py (봇 안)루프마다 에이전트 상태·포지션·오늘 체결·지수 판독·로그 40줄을 JSON으로 조립, 10초에 한 번 기록
→
S3 PUT (SigV4 직접 서명)boto3 없이 requests만 사용. 버킷은 PutObject 권한만 가진 전용 IAM 키
→
정적 페이지10초 폴링, 90초 넘게 묵으면 stale 표시. 서버 포트는 열지 않음