개발 과정에 고민했던 이슈들
https://stockman.fly.dev 를 개발하면서 고민했던 이슈들과 대응 방법들을 소개합니다.
데이터
PostgreSQL 연결
DB 로 PostgreSQL 을 사용하는데, 연결에 무엇을 사용할 것인가?
데이터 전처리
모델 개발을 위한 데이터 전처리는 pandas 가 국룰(?) 인 것 같았다. 그러나 엔지니어 입장에서 pandas API 는 불편해서 pyspark (local 모드) 를 사용해 전처리를 해 봤다. 개인적으로 pyspark window function SQL 로 결측치 처리(fillna), 이동평균(rolling) 계산하는게 pandas 보다 더 쉽고 익숙했다. 그러나 pyspark local 모드 실행에 시간이 걸리는 것이 답답해 결국 pandas 로 돌아왔다. 다음에는 duckdb 도 검토해 봐도 좋을 것 같다.
모델링
미래 며칠의 주가를 예측할 것인가?
- 개발 초기 야심차게 중장기 예측을 시도했지만, 결과가 좋지 않았다.
- 단기 예측(2~4일) 으로 방향을 바꿨다.
개별 종목마다 모델을 만들 것인지, 아니면 일반화된 모델 하나를 만들지?
TCN/GBM 경우는 개별 종목마다 모델을 만들고, TFT 는 일반화된 모델 하나를 만들었다. 학습 데이터가 적은 상황에서는 여러 종목의 데이터를 모아 일반화된 모델 하나를 만드는게 유리한 것 같다.
주가의 급락/급등 데이터는 학습에 방해되지 않나?
- 갑작스런 이벤트로 주가가 급락/급등하는 경우가 있는데, 이런 데이터는 학습에 방해 되지 않을까?
- 그래서
주가 대신에 3일 이동평균 수익률(혹은 주가)을 target 으로 학습했다.
예측할 target 을 무엇으로 할 것인가?
- 초기에는
주가 를 target 으로 설정해 학습했다.
- AI 와 대화를 통해
수익률 을 target 으로 설정하는 방법도 알게되었다. 주가 보다는 수익률 이 더 안정적으로 학습되고 예측 결과도 좋아 보인다.
TFT 개별 종목마다 모델 성능 측정을 어떻게 할 것인가?
- TFT 는 여러 종목의 데이터로 하나의 모델을 만든 후 단일 모델로 각 종목의 주가를 예측한다.
- 특정 종목에서는 잘 맞추지만, 다른 종목에서는 잘 맞추지 못할 수 있다.
- 종목마다 최근 20 일치를 맞추는 테스트를 매일 수행해 대시보드에 노출될 수 있도록 했다.
모델 방향 정확도 (directional accuracy) 를 어떻게 측정할 것인가?
- 오늘(D day) 주가와 3일뒤(D+3 day) 주가를 비교하는데
- 실제(정답) 의 상승/하락 과 예측한 상승/하락 일치를 측정한다.
- 이때 미세한 상승/하락 때문에 방향 정확도가 페널티를 받으면 안될 것 같다. 예를 들어 실제로는 0.1% 상승했는데, 0.1% 하락할 것이라 예측한다면 방향 정확도가 떨어진다고 지표가 계산될 것이다. 이런 경우를 보완하기 위해 1% 이상 주가 변경이 있는 경우만을 대상으로 방향 정확도를 측정했다.
TCN, GBM 처럼 종목마다 모델을 만든다면, 각각의 종목마다 다른 설정으로 종목에 최적화된 모델을 만들수 있지 않을까?
- TCN, GBM 은 종목마다 모델을 만들기 때문에
- 모델의 성능 지표(R2 score, directional accuracy) 를 보고, 성능이 좋지 않은 종목만 대상으로
- 학습 파라미터를 변경해 성능 지표가 좋아질 때 까지 모델 생성을 반복할 수 있다.
- 학습 파라미터도 DB 에 저장해, 종목마다 추론(inference) 때 사용될 수 있도록 했다.
모델 개발해 본 적이 없는데 어떡하지?
ChatGPT 에 TFT 모델을 최소한의 코드로 작성 부탁하면, 몇 줄 안되기 때문에 대충 분석할 수 있다. (주석도 친절하게 추가해 주니..) 이해 안되는 부분은 다시 질문하면 되고~
대시보드
개인용(비공개) 와 서비스용(공개) 대시보드를 어떻게 구분해 배포할 것인가?
대시보드를 외부에 공개하려니, 투자 히스토리 의 내 개인 정보 노출이 염려되었다. 해결 방법으로는
- 방법1) 서비스 하나만 유지하고, 코드에 로그인 기능 추가
- 방법2) 개인용, 서비스용 2개 배포
코드 추가 개발보다는 배포 구축이 쉬워보여 방법2) 로 진행했다.
방법2) 의 추가 장점은 개발(개인용)과 서비스를 분리해, 외부에 안정적인 서비스를 제공할 수 있다는 것이다.
엄청 큰 프로젝트가 아니면 저도 orm 쓰기가 귀찮아서 sql문으로 처리하게 되는 것 같네요 ㅎㅎ
https://stockman.fly.dev/prediction 가보니 네이버는 중립 60, 매도 40이군요 ㅋㅋㅋ 좀 더 들고있어 보겠습니다