본문 바로가기

Quant

정치테마 업데이트 기능 & 화면 개발

최근 링크드인, 이력서, 포트폴리오를 업데이트하면서 했던 업무들을 정리해봤다.

돌이켜보니 잘하는 방법을 몰라서 열심히 하기만 했던 날들이었다.

 

작년에 실리콘 밸리 출장 전에 오픈소스 릴리즈 일정 맞추려고 근 4달 동안 야근 +76시간 찍으면서,

주말도 평일도 회사 숙직실에서 먹고 자고 했던 것도,

새벽 2시에 선배 허락받고 사무실에서 매일 소리 지른 것도,

파트원들이랑 번아웃 테스트한 것도 생각난다.

누가 삼성 꿀이라 했나...


25.4.7 분석을 살펴보니 디버깅 할 작업량이 꽤 있다.

 

1. 대장주 교체 타이밍 이슈 체크

주도 테마 교체

- 09:25(자동차 부품) -> 09:30(엔젤 산업)

2025-04-07 09:30:00 자동차부품 A065500
오리엔트정공
BUY 13970.0 7158 99997260.0 0.0 None
2025-04-07 10:00:00 자동차부품 A065500
오리엔트정공
SELL 14130.0 -7158 101142540.0 0.0 TOP_STOCK_OUT

09:30에 매수를 하지 않거나, 바로 매도를 했어야 하는데 구현되지 않았다.

대장주 트래킹 시간을 보면 09:25 ~ 09:55로 되어 있다.

 

학생 때는 개발자가 되면 멋진 디버깅 방법이 있을 줄 알았다..

 

 

체크를 해보니, 이전에 대장주 선정/대장주 테마 로직을 분리했었다. 함수에서 퉁쳐져셔 가독성이 구려서 다시 보니 못 봤다.

예상한 대로 동작하는게 맞다.

헬퍼 함수를 추가하고 리팩토링을 해준다.

 


2. 수동 테마 입력 필요

대신증권 API는 InfoStock API를 래핑하는 것으로 사료된다.

문제는 정치테마주를 대신증권 API에서 제공을 하지 않는 거 같다.

 

DB를 까보니, 코나아이가 저렇게 분류되어 있다.

코나아이는 현재 이재명 테마주인데 이걸 그렇게 증권사에서 제공하지는 않나보다. 그럴만하다.

필요하다면 직접 입력하는게 필요한데

1. DB 저장 : stock (db) -> info(collection) -> theme(Array): 필드 추가

2. Logic 추가 : 실시간 상위 거래대금 데이터 생성 시, 테마를 DB에서 조회하는데 여기서 수동으로 입력한 DB를 concat 한다.

 

간단하게 생각하면 이런 중요한 작업 2개가 필요하고.

이 작업을 더 자주해야하나 생각하면, 더 심플한 작업 방법이 있으면 좋을 거 같다. 5월 중순에 React 교육 듣고 오는데, 그거 듣고와서 바이브 코딩으로 어떻게 해보면 되지 않을까. 일단 간단하게 하고 고도화 한다.

 

0. 테마 데이터는 어디서 분류?

https://www.infostock.co.kr/Theme/DailyFeaturedTheme

 

인포스탁

증권정보 사이트, 증시뉴스, 스케줄, 상장사 기업IPR, 주식신문, 주식테마분류 등 제공

www.infostock.co.kr

국장 테마 분류/리포트 제공해주는 사이트가 있다.

여기서 소스를 얻는다.

 

1. 어떻게 입력?

- 하책: 매일마다 테마 분류 파악하고, 수동 입력하고 수동 삭제한다.

  +) 개발 난이도 X. 한땀한땀 입력하며 국장을 이해할 수 있다.

  - ) 반복되는 작업이 많아 공수가 많이 들 듯 하다. 내가 생각하는 자동화에서 한발짝 멀어진다. 휴먼에러 발생 가능성 큼

 

- 중책: 입출력을 간단하게 하는 사이트를 개발해서 관리한다.

  +) 언젠가 만들 대시보드에서 간단한 기능 추가하는 정도라 간단.  시각화가 가능하다면 편할거 같다. 휴먼 에러 방지 가능

  - ) 완전 자동화라 할 수 있나. 공수가 은근 있긴 있다.

 

- 상책: AI agent 활용해서 자동화 해본다.

   +) 완전 자동화 가능. 

   -) 개발 난이도 ↑필요한 것 1) 인포스탁 데이터 진입 -> 2) 데이터 기반 테마&종목 분류 및 정제 -> 3)입력값을 mongo handler(아마 script)에 전달

  -) 디버깅 과정을 보려면 로그를 남겨야함.

 

개발 중 커스터마이징이 많아질 것으로 사료되고, 자동화도 중요하지만 전략에 핵심이 되는 직관이 중요하므로 중책으로 간다.

 

2. 시작은 어떻게?

성능은 무관한 기능이다. 간단하게 개발이 가능해야한다. pymongo 연동이 가능해야한다.

요구사항을 정리해서 AI에 입력한다. 요즘 핫한 manus를 써보려했지만 승인 대기가 필요하다. grok으로 떼운다.

베타 테스트 중이라..

 

이런게 가능하다니...

 

32bit python 환경인 것을 감안해 litestar는 안되서 fast api로 짜달라하고

html만 있는 건 칙칙해서 bootstrap으로 간단하게 깔롱 좀 부려달라했다.

 

옛날에 대학교 때 웹 개발 할 때는 이렇게 간단한거도 삽질 좀 많이 했던 거 같은데 신기하다..

 

 

입력을 하면 DB에도 잘 저장된다.

 

3. 기존 코드와 병합은 어떻게?

이전 리팩토링에서 비즈니스 레이어를 잘 분리해놔서, public function 내부에 private function을 추가하면 심플하게 해결된다.

    @staticmethod
    def get_transaction_data(time: datetime):
        transaction_data = RealTimeDAO().get_transaction_data(time)
        df = create_dataframe(transaction_data)
        df = df[~df["code"].apply(is_etf)]
        df = df[df["DoD_ratio"] > 0]
        df = df.sort_values(by="trade_value", ascending=False)
        df = GetData._get_theme_from_stock_info(df)
        validate_transaction_df(df)
        return df
    
    @staticmethod
    def _get_theme_from_stock_info(df: pd.DataFrame) -> pd.DataFrame:
        """
        df : 'code' 컬럼과 기존 'theme'(list) 컬럼을 가진 DataFrame
        return : 기존 theme + StockInfo.theme 를 병합한 DataFrame
        """

        # ────────────────────────────────────────────────
        # 1) 종목 코드 → theme 리스트 추출
        # ────────────────────────────────────────────────
        def _extract_theme(code: str) -> List[str]:
            info = StockInfoDAO().get_data(code)      # StockInfo | None
            return info.theme if info and getattr(info, "theme", None) else []

        df["_add_theme"] = df["code"].apply(_extract_theme)

        # ────────────────────────────────────────────────
        # 2) 기존 theme + 추가 theme 병합(중복 제거·순서 보존)
        # ────────────────────────────────────────────────
        df["theme"] = df.apply(
            lambda r: list(
                dict.fromkeys((r["theme"] or []) + (r["_add_theme"] or []))
            ),
            axis=1,
        )

        # ────────────────────────────────────────────────
        # 3) 임시 컬럼 정리 후 반환
        # ────────────────────────────────────────────────
        return df.drop(columns="_add_theme")

이제 정치 테마가 잘 표시된다.

 

4. Try & Error

도메인이 바뀌다보니 해당 도메인 클래스를 다루는 비즈니스 로직에서 빵꾸가 난다.. Pycharm 유료 버전을 쓰면 편한데 거지라 참는다.

수동으로 입력한 정치테마주가 잘 분류된다.

 

멀쥐 완