AI 자동 판단 시뮬레이션
세 번째 단계에서는 AI 자동 판단 기능을 실제 주문에 바로 연결하지 않고, 먼저 가상 매매에 붙여보았다.
이전 단계에서 단타 매수/매도 시뮬레이션은 성공했지만, 실제 주문에서는 체결 상태와 계좌 상태를 더 조심해서 봐야 한다는 결론이 나왔다. 그래서 AI도 같은 기준으로 접근했다. 모델이 매수라고 말한다고 바로 주문을 넣는 것이 아니라, AI 판단을 하나의 신호로 기록하고, 규칙 기반 risk engine과 함께 비교하는 방식이다.
AI 판단에는 관심 종목의 현재 상태, 최근 가격 변화, 1초봉, 거래량 흐름, 공시, 뉴스, 가상 포지션, 사용자가 지정한 운용금액 기준을 함께 넘기는 구조를 잡았다. 자동 판단 루프는 Ollama 로컬 모델을 기본으로 사용하고, OpenAI는 특정 종목 1회 판단 API로 남겨두었다.
이 단계에서 모델 기준도 한 번 바뀌었다. 처음에는 qwen2.5:7b로 빠르게 자동 판단 루프를 돌려보는 것이 목표였다. 그런데 판단 context가 커지면서 단순히 buy, sell, hold, watch만 받는 방식으로는 왜 그런 결론이 나왔는지 확인하기 어려웠다. 그래서 기본 권장 모델을 qwen2.5:14b로 올리고, 더 큰 qwen2.5:32b는 관심종목 수와 판단 주기를 줄여야 하는 무거운 실험 후보로 남겨두었다.
모델만 바꾼 것은 아니었다. 출력 형식도 바꾸었다. 결과는 단순히 “매수” 하나만 받지 않고, 다음처럼 나누어 기록하는 것이 더 낫다고 봤다.
buywatchsellhold- 판단 이유
- 위험 요소
- 점수 내역
- 부족한 판단 신호
- AI 참고 손절/익절
- AI 제안 진입 비중
이렇게 나누면 나중에 모델 판단이 맞았는지 틀렸는지만 보는 것이 아니라, 어떤 이유로 그런 판단을 했는지까지 복기할 수 있다.
점수형 판단으로 바꾼 이유
초기 AI 판단은 서술형 설명에 가까웠다. 모델이 “최근 흐름이 좋아 보인다” 또는 “거래량이 부족하다”는 식으로 말해주면 사람이 읽기에는 그럴듯했다. 하지만 매매 보조 시스템에서는 그럴듯한 문장만으로는 부족했다.
문제는 판단을 비교하기 어렵다는 점이었다.
같은 종목을 여러 번 판단했을 때 어떤 항목 때문에 watch가 됐는지, 어떤 조건이 채워져서 buy가 됐는지, 데이터가 부족하다면 정확히 무엇이 부족한지 기록으로 남아야 했다. 그래서 AI에게 scoring_policy를 함께 전달하고, 반드시 score_breakdown, total_score, decision_rule을 내도록 바꾸었다.
신규 진입은 대략 이런 식으로 점수를 보게 했다.
- 가격 모멘텀:
+2 - 거래량 증가:
+1 - 시장 흐름:
+1 - 변동성 과다:
-1 - 리스크 한도 초과:
-2
이렇게 바꾸면서 AI 판단은 “감상문”에서 “검토 가능한 기록”에 가까워졌다. total_score >= 3이면 매수 후보, 1~2면 관찰, 0 이하면 제외 또는 대기로 볼 수 있다. 물론 이 점수도 완전한 정답은 아니지만, 적어도 나중에 왜 매수 후보가 됐는지 다시 볼 수 있다.
보유 중인 포지션은 기준이 다르다. 이미 들어간 종목에서는 신규 매수보다 유지와 정리 판단이 중요하다.
- 수익권:
+1 - 거래량 유지:
+1 - 추세 유지:
+1 - 변동성 확대:
-1 - 손절선 근접:
-2 - 운용 종료 임박:
-1
이 구조를 넣은 이유는 매수와 매도를 같은 기준으로 보면 안 된다고 판단했기 때문이다. 신규 진입에서는 “들어가도 되는가”가 중요하고, 보유 중에는 “계속 들고 있어도 되는가”가 중요하다.
매수 기준 변경
매수 기준도 꽤 바뀌었다.
처음에는 AI가 buy를 내고 기본 리스크 조건을 통과하면 가용 예산 안에서 살 수 있는 수량을 계산하는 쪽에 가까웠다. 하지만 실제로 테스트해보면 이 방식은 너무 거칠었다. 종목 하나가 가용 예산을 과하게 가져갈 수 있고, 모델 확신도가 애매한 상황에서도 진입 금액이 커질 수 있었다.
그래서 매수 기준을 세 단계로 나누었다.
- AI가 점수형 판단으로
buy를 낸다. confidence가 고급 설정의ai_min_order_confidence이상인지 확인한다.- risk engine이 운용금액, 시장 세션, 정보 리스크, 킬 스위치, 주문 가능 상태를 다시 본다.
특히 confidence_below_minimum이면 주문 제안뿐 아니라 AI 가상 매수도 막도록 바꾼 점이 중요했다. 실제 주문만 막고 가상 매수는 허용하면 통계가 지나치게 낙관적으로 쌓일 수 있기 때문이다.
수량 계산도 바꿨다.
이전에는 남은 운용금액으로 살 수 있는 수량을 바로 계산하는 느낌이었다면, 지금은 AI가 제안한 position_size_rate를 먼저 본다. 이 값은 가용 예산 대비 진입 비중이고, 시스템에서는 0.05 ~ 0.35 범위로 제한한다. 값이 없으면 기본 0.15를 사용한다.
available_budget = daily_budget_amount - open_exposure_amount
position_size_rate = AI 제안값 또는 기본 0.15
target_budget = available_budget * position_size_rate
quantity = target_budget 안에서 살 수 있는 수량
이렇게 바꾼 결론은 명확했다. AI가 매수 후보를 골라도 한 번에 크게 들어가지 않는다. 단타 실험에서는 수익보다 먼저 진입 규모를 통제해야 했다.
매도 기준 변경
매도 기준도 같이 정리했다.
처음에는 손절/익절률을 개별 종목의 고정 청산 기준처럼 볼 수 있었다. 하지만 AI 자동 판단에서는 이 방식이 애매했다. 전체 운용금액 기준의 손절/익절과 개별 포지션의 참고 손절/익절이 섞이면, 시스템이 무엇을 기준으로 닫는지 헷갈릴 수 있었다.
그래서 기준을 분리했다.
- 운용금액 설정의 손절/익절은 전체 포트폴리오 guard 기준이다.
- AI가
buy와 함께 제안하는 손절/익절은 개별 포지션의 참고선이다. - 실제 가상 포지션 정리는 AI
sell판단, 운용 종료 시간, 전체 손익 guard를 따른다.
대시보드에도 이 표현을 맞췄다. 열린 포지션 표에는 AI 참고 손절 / 익절로 표시하고, 이 값이 자동 청산용 고정 기준이 아니라 다음 AI 판단에 참고하는 값이라고 명확히 보여주도록 했다.
이 결정은 작지만 중요했다. 손절가와 익절가라는 단어는 사용자가 보기에는 곧바로 자동 매도 조건처럼 느껴질 수 있다. 실제 시스템 의도와 화면 문구가 다르면 나중에 내가 봐도 헷갈린다. 그래서 “참고선”이라는 표현으로 정리했다.
실매수/매도와 연결할 때의 기준
AI 판단을 실매수/매도에 연결하는 부분은 보수적으로 정리했다.
현재 시스템에서는 AI가 단독으로 주문을 실행하지 않는 방향이 맞다고 봤다. 이유는 명확하다. 모델이 틀릴 수 있고, 데이터가 늦을 수 있고, API 응답이 실패할 수 있다. 무엇보다 최종 책임은 시스템이 아니라 사용자에게 있다.
그래서 실거래에서는 다음 원칙을 세웠다.
- AI 판단은 주문 조건 중 하나일 뿐 최종 결정이 아니다.
- 실제 매수는 투자 한도와 보유 상태를 다시 확인한 뒤에만 가능하다.
- 실제 매도는 API 기준 보유 수량을 다시 조회한 뒤 실행한다.
dry_run,kill_switch,live_trading_enabled,SEND_REAL_ORDER확인 문구를 모두 통과해야 한다.- AI 판단과 규칙 기반 판단이 충돌하면 기본값은 관망이다.
- 장중 자동 실행보다 점심시간 확인 가능한 요약 화면을 우선한다.
이 결론은 프로젝트의 현실적인 제약과도 맞았다. 개발은 집에서 하고, 테스트는 점심시간에 짧게 해야 한다. 그러니 시스템은 혼자 과감하게 움직이는 것보다, 짧은 시간 안에 확인 가능한 근거를 잘 보여주는 쪽이 더 유용하다.
관심목록 관리 확장
이번 단계에서 관심목록도 단순 종목 리스트에서 조금 확장했다.
처음에는 종목명과 현재가 정도만 있으면 충분할 것 같았다. 하지만 실제로 테스트해보니 “왜 이 종목을 관심목록에 넣었는지”가 중요했다. 시간이 지나면 내가 어떤 이유로 봤는지 잊어버리고, 그러면 매수 판단도 흔들린다.
그래서 관심목록에는 다음 정보를 함께 다루는 방향으로 정리했다.
- 관심 등록 이유
- 활성 여부
- 시장 분류 코드
- 메모
- 최근 현재가
- 최근 시세 로그
- AI 판단 결과
- 시뮬레이션 결과
이 확장은 작은 변화지만 프로젝트 성격을 바꿨다. 단순히 가격을 보는 화면이 아니라, 판단을 쌓아가는 화면이 됐다.
통계 페이지 추가
통계 페이지는 이번 단계에서 꼭 필요하다고 느꼈다.
단타 매수/매도 시뮬레이션을 반복하다 보면 개별 결과만 봐서는 감이 잘 오지 않는다. 한 번의 성공이나 실패보다 중요한 것은 전체적으로 어떤 기준이 잘 맞았는지, 어떤 조건에서 손실이 반복됐는지 보는 것이다.
통계 페이지에서는 다음 내용을 다루는 방향으로 잡았다.
- 월별 시뮬레이션 횟수
- 매수 후보로 판단된 횟수
- 익절/손절/관망 결과
- 평균 수익률
- 종목별 결과
- AI 미사용 단타와 AI 가상 운용 구분
- 시뮬레이션과 실제 주문 연동 run 구분
특히 AI 판단은 통계 없이 붙이면 위험하다고 봤다. 모델이 한두 번 맞았다고 신뢰할 수도 없고, 한두 번 틀렸다고 바로 버릴 수도 없다. 반복된 결과를 모아야 모델이 보조 도구로 쓸 만한지 판단할 수 있다.
실시간 확인 페이지 추가
실시간 확인 페이지는 점심시간 테스트 제약 때문에 더 필요해졌다.
하루 종일 화면을 보고 있을 수 없으니, 앱을 열었을 때 지금 중요한 상태가 바로 보여야 했다. 그래서 실시간 확인 페이지는 화려한 차트보다 현재 판단과 위험 상태를 빠르게 확인하는 쪽으로 정리했다.
주요 구성은 다음과 같다.
- 현재 관심 종목 상태
- 매수 후보로 바뀐 종목
- 보유 또는 가상 보유 포지션
- 전체 운용금액 기준 손익 상태
- 최근 AI 판단
- KIS API 잠금 상태
- Ollama 상태
- 공시 수집 상태
- 마지막 데이터 갱신 시각
이 화면의 목표는 단순했다. 점심시간 30분 안에 “지금 봐야 할 것”을 먼저 보여주는 것이다.
공시 조회 페이지 추가
이번 단계에서 새로 추가된 화면 중 하나가 /disclosures-page다.
처음에는 대시보드 안에서 공시와 뉴스 정보를 같이 다뤘다. 하지만 AI 판단 context에 공시가 들어가기 시작하자, 공시 수집 상태를 별도로 확인할 필요가 생겼다. 관심종목마다 DART corp_code 매핑이 되어 있는지, 최근 공시가 몇 건 저장됐는지, 위험 키워드가 있는지, 수집이 실패했는지 한 화면에서 봐야 했다.
그래서 공시 조회 페이지를 따로 분리했다.
이 페이지에서 확인하는 내용은 다음과 같다.
- 활성 관심종목 기준 종목 필터
- DART corp_code 종목코드 동기화
- 활성 관심종목 공시 일괄 수집
- 선택 종목 공시 수집
- 선택 종목 저장 공시 조회
- 전체 저장 공시 조회
- 종목별 저장 공시 수와 최신 공시
- 위험 키워드와 수집 성공/실패 결과
이 페이지를 따로 만든 이유는 단순히 화면이 많아져서가 아니다. AI가 공시를 판단 근거로 쓰려면, 그 공시 데이터가 정말 들어와 있는지 사람이 확인할 수 있어야 한다. 데이터가 없는데 AI가 “공시 리스크가 낮다”고 말하면 그건 안전한 판단이 아니라 근거 없는 판단일 수 있다.
뉴스는 아직 자동 수집기가 없고, 수동 저장된 항목만 AI 판단 context에 들어간다. 이 점도 화면과 문서에 남겨두었다. 자동화 프로젝트에서는 “되는 것”보다 “아직 안 되는 것”을 명확히 적어두는 게 더 중요할 때가 있다.
결과물 이미지 정리
세 번째 글에는 실제 결과물 이미지를 함께 남겼다. 화면 캡처를 같이 보면 프로젝트가 단순 API 서버에서 내부 운영 화면을 가진 매매 보조 도구로 확장되는 과정이 더 잘 보인다.
관심목록 화면은 AI가 아무 종목이나 판단하지 않게 하는 기준점이다. 활성 종목만 자동 판단 대상이 되고, 종목명, 시장 구분, 메모를 함께 관리한다. 이 화면을 따로 둔 이유는 매매 판단의 시작점이 모델이 아니라 사용자가 고른 관찰 대상이어야 한다고 봤기 때문이다.
실시간 확인 화면은 점심시간처럼 짧은 시간에 상태를 확인하기 위한 화면이다. 현재 관심종목 상태, AI 자동 판단 상태, 열린 가상 포지션, KIS 잠금 상태, Ollama 상태를 한 번에 봐야 했다. 개발하면서 가장 신경 쓴 부분은 “지금 위험한 상태인가”를 빠르게 알 수 있게 하는 것이었다.
통계 화면은 AI 판단이 실제로 도움이 되는지 확인하기 위해 추가했다. 단타 시뮬레이션과 AI 가상 운용을 분리하고, 시뮬레이션과 실제 주문 연동 run도 구분해서 볼 수 있게 했다. 한두 번 맞고 틀리는 것보다 반복된 결과를 봐야 모델과 규칙을 고칠 수 있다고 판단했다.
공시 조회 화면은 AI 판단의 근거 데이터를 사람이 확인하기 위한 페이지다. DART corp_code 동기화, 활성 관심종목 공시 수집, 저장 공시 조회, 위험 키워드 확인을 별도 화면으로 분리했다. AI가 공시 리스크를 판단하려면 먼저 공시 데이터가 제대로 들어와 있는지 확인할 수 있어야 했다.
이미지는 단순한 장식이 아니라, 어떤 기능을 실제로 만들었는지 보여주는 근거가 된다. 특히 QuantPilot처럼 판단 흐름이 중요한 프로젝트에서는 화면 안에 조건, 결과, 마지막 갱신 시간이 함께 보여야 한다.
현재 시스템의 문제점
현재 시스템은 실험용으로는 의미가 있지만, 아직 그대로 믿고 운영하기에는 부족한 부분이 많다.
가장 큰 문제는 데이터 신뢰성이다. 주식 데이터는 짧은 시간에도 바뀌고, KIS API 응답이 늦거나 실패할 수 있다. 데이터가 늦게 들어왔는데 최신 상태라고 믿으면 매수/매도 판단이 틀어질 수 있다. 그래서 자동 판단에서는 최근 가격 로그가 오래되면 판단을 건너뛰거나 watch 쪽으로 유도해야 한다.
두 번째는 자동화 기준이다. 규칙 기반 판단과 AI 판단을 함께 쓰면 좋아 보이지만, 두 판단이 충돌할 때 어떻게 할지가 중요하다. 현재 결론은 보수적으로 관망하는 것이다. 단타에서는 기회를 놓치는 것도 아쉽지만, 애매한 상태에서 들어가는 것이 더 위험하다고 봤다.
세 번째는 테스트 시간이다. 점심시간 30분 테스트는 현실적인 방식이지만, 다양한 장 상황을 충분히 보기에는 짧다. 상승장, 하락장, 횡보장, 거래량 급증, 급락 같은 상황을 모두 검증하려면 더 많은 데이터와 반복 테스트가 필요하다.
네 번째는 AI 판단의 검증이다. AI가 왜 그렇게 판단했는지 설명은 할 수 있지만, 그 설명이 실제 수익과 연결되는지는 별개의 문제다. 그래서 AI 판단은 계속 통계로 검증해야 한다. 특히 이번에 점수형 판단을 넣으면서, 단순 승패뿐 아니라 어떤 점수 항목이 실제 결과와 맞았는지도 봐야 한다.
다섯 번째는 화면과 용어의 일관성이다. 손절/익절이라는 단어를 그대로 쓰면 사용자는 자동 청산 조건으로 이해할 수 있다. 하지만 현재 AI가 제안하는 값은 개별 포지션 참고선이고, 실제 정리는 AI sell, 운용 종료, 전체 손익 guard가 맡는다. 그래서 화면에는 AI 참고 손절 / 익절로 표시하도록 바꾸었다.
개선 방향
다음 단계로 이어간다면 개선 방향은 분명하다.
- 시뮬레이션 결과를 더 오래 쌓는다.
- 실제 주문은 수동 지정가와 강한 안전장치 중심으로 유지한다.
- AI 판단은 자동 주문보다 결과 분석과 후보 필터링에 먼저 사용한다.
score_breakdown과 실제 결과를 연결해서 어떤 판단 항목이 유효했는지 검증한다.- KIS API 실패, 지연, 체결 불일치 상황을 더 명확하게 기록한다.
- 공시와 뉴스 데이터의 수집 여부를 AI 판단 화면에서 더 잘 드러낸다.
- 관심목록과 통계 페이지를 연결해서 판단 근거를 복기하기 쉽게 만든다.
- 손익보다 리스크 관리 기준과 킬 스위치 상태를 먼저 강화한다.
QuantPilot은 결국 돈을 불려주는 마법 같은 시스템이 아니라, 투자 판단을 구조화해보는 프로젝트다. 이 관점을 유지해야 프로젝트가 안전하게 이어질 수 있다.
마무리
이번 단계까지 오면서 QuantPilot의 방향은 더 분명해졌다.
처음에는 주식 자동매매라는 말이 먼저 떠올랐지만, 실제로 만들어보니 중요한 것은 자동화 자체가 아니었다. 관심 종목을 왜 골랐는지, 어떤 기준으로 매수/매도를 생각했는지, 그 결과가 어땠는지, AI 판단은 얼마나 도움이 됐는지를 계속 기록하는 일이 더 중요했다.
현재 결론은 이렇다.
- AI 자동 판단은 시뮬레이션에서 먼저 검증한다.
- 실매수/매도는 보수적으로 연결하고, 최종 확인 흐름을 유지한다.
- 모델은 빠른 실험용
qwen2.5:7b보다 판단 품질 확인용qwen2.5:14b를 기본 기준으로 본다. - AI 판단은 점수형 evidence와 부족한 신호를 함께 남긴다.
- 관심목록은 판단 근거를 남기는 방향으로 확장한다.
- 통계 페이지, 실시간 확인 페이지, 공시 조회 페이지는 프로젝트의 핵심 화면으로 둔다.
- 현재 시스템의 가장 큰 과제는 데이터 신뢰성, 자동화 기준, AI 판단 검증이다.
“QuantPilot의 목적은 시장을 이기는 척하는 것이 아니라, 내가 왜 그런 판단을 했는지 남기는 것이었다.”
시리즈
- QuantPilot 프로젝트를 시작하며
- 단타 매수/매도 시뮬레이션과 AI 모델 검토
- AI 자동 판단 테스트와 현재 시스템 정리 (현재 글)