
시스템은 완성되었다, 이제는 '두뇌'를 장착할 시간
안녕하세요! 9편의 텔레그램 알림을 마지막으로 자동매매 봇의 물리적인 아키텍처는 모두 완성되었습니다. 하지만 우리 봇은 아직 "언제 사야 할지" 스스로 결정하지 못합니다. 단지 우리가 하드코딩해 둔 특정 가격이나 단순 비율에 의존할 뿐이죠.
진정한 자동매매, 즉 '퀀트(Quant)' 투자의 세계로 넘어가기 위해서는 차트의 흐름을 읽고 수학적 통계에 기반한 매매 알고리즘(전략)을 봇에게 심어주어야 합니다.
수많은 보조지표(RSI, MACD, 볼린저 밴드 등)가 있지만, 이번 심화편에서는 추세의 방향과 지지/저항을 한눈에 파악할 수 있어 강력한 팬덤을 가진 일목균형표(Ichimoku Cloud)를 활용한 매매 로직을 Node.js로 구현해 보겠습니다.
1단계: 차트의 과거 데이터(OHLCV) 가져오기
일목균형표의 전환선, 기준선, 선행스팬 등을 계산하려면 현재가 하나만으로는 부족합니다. 과거 일정 기간의 시가(Open), 고가(High), 저가(Low), 종가(Close), 거래량(Volume) 데이터가 필요합니다.
한국투자증권 API의 '국내주식 기간별 시세(일/주/월/년)' API (TR 코드: FHKST03010100)를 호출하여 이 데이터를 먼저 확보해야 합니다.
2단계: 기술적 지표 계산 라이브러리 설치 (설정 꿀팁 포함)
과거 데이터를 가져왔다면 직접 수식을 짜서 일목균형표를 계산할 수도 있지만, 이미 잘 만들어진 검증된 라이브러리를 사용하는 것이 정신 건강에 좋습니다. technicalindicators라는 강력한 패키지를 사용하겠습니다.
💡 Pro Tip: 패키지 관리자 및 네트워크 설정
프로젝트 규모가 커질 것을 대비해 속도가 빠른 pnpm 사용을 권장합니다. 만약 사내망 등 외부망 접근이 제한된 환경에서 봇을 개발 중이시라면, 사설 Nexus 저장소 등을 바라보도록 .npmrc 설정이 필요할 수 있습니다.
# 로컬 환경 또는 사설 레지스트리가 세팅된 환경에서 pnpm으로 설치
pnpm add technicalindicators

3단계: Node.js로 일목균형표 구름대 돌파 전략 구현하기
일목균형표의 대표적인 매수 시그널 중 하나는 "주가가 양운(구름대 상단)을 상향 돌파할 때"입니다. 추세가 완벽한 상승세로 전환되었음을 의미하죠.
과거 데이터를 배열로 만든 뒤, 지표를 계산하고 매수 신호를 포착하는 핵심 로직을 작성해 봅시다.
// (프로젝트 루트의 ichimoku_strategy.js)
const { IchimokuCloud } = require('technicalindicators');
/**
* 일목균형표 기반 매매 시그널 분석 함수
* @param {Array} highPrices - 과거 고가 배열 (오래된 순 -> 최신 순)
* @param {Array} lowPrices - 과거 저가 배열
* @param {Array} closePrices - 과거 종가 배열
* @returns {string} - 'BUY', 'SELL', 'HOLD'
*/
const analyzeIchimoku = (highPrices, lowPrices, closePrices) => {
// 일목균형표 기본 설정값 (9, 26, 52, 26)
const input = {
high: highPrices,
low: lowPrices,
close: closePrices,
conversionPeriod: 9, // 전환선
basePeriod: 26, // 기준선
spanPeriod: 52, // 선행스팬B
displacement: 26 // 후행스팬 (시프트)
};
const result = IchimokuCloud.calculate(input);
if (result.length === 0) return 'HOLD';
// 가장 최근(오늘)의 지표 값 가져오기
const latestInd = result[result.length - 1];
const currentPrice = closePrices[closePrices.length - 1];
console.log('☁️ [일목균형표 지표]');
console.log(`전환선: ${latestInd.conversion.toFixed(2)} | 기준선: ${latestInd.base.toFixed(2)}`);
console.log(`선행스팬A: ${latestInd.spanA.toFixed(2)} | 선행스팬B: ${latestInd.spanB.toFixed(2)}`);
// 구름대(Kumo) 상단과 하단 구하기
const cloudTop = Math.max(latestInd.spanA, latestInd.spanB);
const cloudBottom = Math.min(latestInd.spanA, latestInd.spanB);
// [전략 1] 주가가 구름대 상단을 돌파하며 상승 추세일 때 매수 (BUY)
if (currentPrice > cloudTop) {
console.log('📈 [매수 시그널] 주가가 구름대를 상향 돌파했습니다!');
return 'BUY';
}
// [전략 2] 주가가 구름대 하단을 이탈하며 하락 추세일 때 매도 (SELL)
else if (currentPrice < cloudBottom) {
console.log('📉 [매도 시그널] 주가가 구름대 하단을 이탈했습니다!');
return 'SELL';
}
// 구름대 안에 있거나 애매한 경우 관망
return 'HOLD';
};
// 테스트용 더미 데이터 (실제로는 KIS API에서 OHLCV 배열을 파싱해서 넣어야 합니다)
// const highs = [...]; const lows = [...]; const closes = [...];
// const signal = analyzeIchimoku(highs, lows, closes);
로직을 봇에 이식하기
이제 이 analyzeIchimoku 함수를 8편에서 만든 node-cron 스케줄러 안에 넣으면 됩니다. 매일 오전 9시 5분쯤 (시가가 어느 정도 형성된 후) API로 어제까지의 일봉 데이터를 불러와 분석하고, 결과가 'BUY'라면 6편의 매수 함수를, 'SELL'이라면 7편의 매도 함수를 실행하도록 연결하는 것이죠.
진정한 퀀트를 향한 끝없는 여정
이번 편에서는 일목균형표의 구름대 돌파라는 단일 지표를 사용했지만, 실제 시장에서는 휩소(가짜 신호)가 빈번하게 발생합니다. 승률을 높이기 위해서는 거래량의 변화를 함께 체크하거나, 볼린저 밴드 등 다른 성격의 보조지표를 결합하는 다중 조건식을 연구해야 합니다.
여러분의 봇이 어떤 데이터를 보고 판단하게 만들 것인가요? 코드는 도구일 뿐, 핵심은 여러분의 전략입니다. 성공적인 퀀트 투자를 향한 여러분의 항해를 언제나 응원합니다!
'🛠️ Dev & Tools (투자 도구 개발)' 카테고리의 다른 글
| [계좌 리팩토링] 12편(안정성). 대시보드 UI를 완벽하게 지키는 법: Playwright와 Storybook을 활용한 VRT 구축 (0) | 2026.05.25 |
|---|---|
| [계좌 리팩토링] 11편(심화). 내 봇의 상태를 한눈에! Nuxt로 실시간 트레이딩 대시보드 만들기 (0) | 2026.05.24 |
| [계좌 리팩토링] 9편(외전). 봇의 보고서를 내 폰으로! 텔레그램(Telegram) 실시간 알림 연동 (0) | 2026.05.23 |
| [계좌 리팩토링] 8편. 24시간 잠들지 않는 봇! PM2와 node-cron으로 무중단 자동화 완성하기 (0) | 2026.05.22 |
| [계좌 리팩토링] 7편. 수익의 완성! Node.js 주식 매도 주문 및 수익률 자동 계산 (0) | 2026.05.20 |