이틀 만에 자리표시자였던 코드가 매일 자동으로 도는 공개 사이트가 됐다

이틀 만에 자리표시자였던 코드가 매일 자동으로 도는 공개 사이트가 됐다

2주차 1~2일차, 10종목 AI 매매 로직부터 매일 자동 실행·대시보드 3종까지 만들어서 로드맵 2주차 목표를 완성한 기록.

한 줄 요약: 1주차 끝엔 “AAPL 1종목, AI 판단 한 번 성공”이 전부였는데, 이틀(2주차 1~2일차) 만에 10종목 전체가 매일 밤 자동으로 판단·기록되고, 그 결과를 그래프·히스토리로 보여주는 공개 사이트까지 완성했다.

이런 분께 도움돼요: 계획은 잘게 쪼갰는데 “그래서 하루에 얼마나 진도가 나가야 정상인지” 감이 안 잡히는 분, GitHub Actions 자동화를 처음 실전에 연결해보는 분, 차트 라이브러리 없이 그래프를 그려야 하는 분.

Before

세부계획엔 9단계가 있었고, 1주차 끝엔 1~3단계(API 키, 데이터 하나, AI 판단 하나)만 끝난 상태였다. scripts/trade.js는 “자동 실행 확인”이라는 문구만 매일 찍는 자리표시자였고, 대시보드 페이지는 아예 없었다.

어떻게 했나

1일차 — 자리표시자를 진짜 로직으로 (4단계)

만들기 전에 먼저 오픈소스로 이미 있는 게 있는지 조사부터 했다. TradingAgents·AI Hedge Fund 같은 멀티에이전트 프레임워크가 나왔지만, PRD에서 이미 “간단하게, 백테스트 없이”로 범위를 좁혀둔 것과 안 맞아서 직접 만들기로 판단했다. 큰 도구를 그냥 가져다 쓰는 게 항상 정답은 아니라는 걸 배운 지점이다.

그다음 4단계를 작은 단계 5개로 쪼갰다 — 공용 함수 → 10종목 반복 → 자산 계산 → JSON 저장 → 로컬 테스트. 한 단계 끝날 때마다 바로 실행해서 확인하고 다음으로 넘어갔다.

// 판단 결과를 종목의 현금·보유수량에 반영 (종목당 독립된 $1,000 예산)
function 자산_반영(portfolioEntry, 판단, 현재가) {
  if (판단 === '매수' && portfolioEntry.상태 === '현금') {
    const 수량 = Math.floor(portfolioEntry.현금 / 현재가);
    if (수량 > 0) {
      portfolioEntry.현금 -= 수량 * 현재가;
      portfolioEntry.보유수량 = 수량;
      portfolioEntry.상태 = '보유';
    }
  } else if (판단 === '매도' && portfolioEntry.상태 === '보유') {
    portfolioEntry.현금 += portfolioEntry.보유수량 * 현재가;
    portfolioEntry.보유수량 = 0;
    portfolioEntry.상태 = '현금';
  }
}
복사

2일차 — 자동화 실전 연결 (5단계), 그리고 첫 실패

워크플로에 GitHub Secrets를 연결하고 수동 실행 버튼을 눌렀는데, 바로 실패했다.

Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@anthropic-ai/sdk'
복사

로그를 읽어보니 Secrets는 정상적으로 잘 들어갔는데(FINNHUB_API_KEY: ***로 잘 나옴), 워크플로에 npm install 하는 단계 자체가 아예 빠져 있었다. GitHub Actions 서버는 매번 깨끗한 상태로 시작해서 node_modules가 없다는 걸 놓쳤던 것. 한 줄 추가하고 다시 실행하니 성공했다.

- uses: actions/setup-node@v4
  with:
    node-version: 20
- run: npm ci        # ← 이 한 줄이 빠져서 실패했었다
- run: node scripts/trade.js
  env:
    FINNHUB_API_KEY: ${{ secrets.FINNHUB_API_KEY }}
    ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
복사

대시보드 3종 (6~8단계)

PRD에서 정한 화면 구성 3가지를 각각 작은 단계로 쪼개서 만들었다.

  1. 종목별 상태 표 — 10종목의 현금/보유 상태를 표로

  2. 수익률 그래프 — 라이브러리를 새로 설치하지 않고, SVG를 직접 계산해서 꺾은선을 그렸다. 점 하나짜리 선 하나 그리자고 차트 라이브러리를 설치하는 건 오히려 과했다.

const x = (i) => PAD.left + (i / (series.length - 1)) * (W - PAD.left - PAD.right);
const y = (v) => H - PAD.bottom - ((v - domainMin) / (domainMax - domainMin)) * (H - PAD.top - PAD.bottom);
복사
  1. 매매 히스토리 — “언제·어떤 종목·왜”를 리스트로, 매수는 초록·매도는 빨강 배지로 구분

통합 테스트 (9단계) — 그리고 또 한 번 막힘

배포된 사이트를 직접 열어 확인하던 중, 로컬 커밋을 푸시하려는데 거부당했다. 원인은 그사이 GitHub Actions 야간 자동 실행이 원격에 새 커밋을 이미 만들어둔 것 — 내가 로컬에서 작업하는 동안 자동화가 조용히 지 할 일을 하고 있었던 거다. git fetch + merge로 충돌 없이 합쳐졌다.

After

  • data/trades.json이 매일 밤 실제 10종목 AI 판단으로 자동 갱신됨

  • /dashboard에서 상태 표·수익률 그래프·매매 히스토리를 실시간으로 볼 수 있음

  • https://kevin-one-murex.vercel.app/dashboard — 로그인 없이 누구나 바로 볼 수 있는 공개 주소

  • 로드맵 2주차 목표(“작동하는 매매 판단 로직 + 대시보드 초안”)가 완성됨

배운 점 / 재사용 자산

  • 작은 단계마다 바로 실행해서 확인 — 5단계씩 쪼개고 매번 실행해보니, 문제가 생겨도 어디서 생겼는지 바로 알 수 있었다.

  • 자동화 로그는 에러 메시지를 그대로 읽으면 원인이 나온다npm ci 빠진 것도 로그 한 줄로 바로 잡았다.

  • 작업 중 원격이 먼저 바뀌어 있을 수 있다 — 자동화가 돌고 있는 프로젝트라면, 푸시 전에 항상 git fetch로 먼저 확인하는 습관이 필요하다.

  • 사이트 분리 : 지금은 학습보드와 같은 사이트 안의 대시보드를 사용중이고 조금 더 구체화된다면 사이트를 분리할 예정이다.

  • SVG 직접 그리기 패턴: 점 개수가 적고 단순한 꺾은선이면, 차트 라이브러리 없이 좌표 계산 몇 줄로 충분하다. 새 의존성을 늘리기 전에 “정말 라이브러리가 필요한가”부터 물어볼 것.

2
2개의 답글
밀어주고 끌어주는

온·오프라인 AI 스터디

AI로 어디까지 할 수 있는지
직접 확인하실 분만 신청하세요.