코인 봇 프로젝트에 이어, 이제 국내 주식 시장으로!
코인 봇으로 아직 첫 거래가 이루어지진 않았지만 주식 자동화 프로그램도 개발해 볼까 하는 마음 첫 삽을 뜹니다. 해당 프로젝트는 단순 시세 조회 단계를 넘어 종목발굴, 실시간 데이터를 활용한 자동 매매 및 모니터링을 목표로 합니다. 자동화 구축은 클라우드 서버와 Docker 환경과 Sqlite를 사용하여 무료로 잘 굴러가도록 설계했습니다.
프로젝트 환경
- 서버: AWS EC2 위에서 Docker로 띄웠습니다. 환경 재현? 배포? Docker면 끝이죠. 안정성도 기본 장착입니다. (아마존 무료서버 구축하기)
- 언어: Python, Node.js (핫 리로딩 - 설정방법 보러가기)
- 데이터베이스: SQLite
- 메시지: Telegram - 설정방법 보러 가기
- 주요 라이브러리:
requests
,sqlite3
,pandas
,python-telegram-bot
,python-dotenv
. 필요한 건 다 때려 박았습니다. - 보안:
API Key
,Telegram Token
같은 민감한 정보는secrets.env
파일에 짱박아뒀습니다. 내 정보는 소중하니까요.
# main.py
import time
import pandas as pd
from datetime import datetime
import requests
from config import API_BASE, ACCESS_TOKEN, KIS_API_KEY, KIS_API_SECRET, c, conn, USE_SANDBOX
from telegram_client import send_telegram # Import from the new module
한국투자증권 Open API - 이제 직접 물어본다
- 모의투자/실전:
USE_SANDBOX
변수 하나로 모의랑 실전 모드 왔다 갔다 합니다. 일단 간은 봐야죠? - 고난의 토큰 발급: 처음엔 토큰 받다가 헤맸습니다.
POST /oauth2/tokenP
이거 하나 찾느라... 그래도 결국 해냈죠. - 핵심: 토큰 받고 나니 종목 시세를 분봉 단위로 촤르륵 가져옵니다. 실시간 시세, 제 손안에 있습니다.
def get_access_token(): url = f"{API_BASE}/oauth2/tokenP" # ... (쿨하게 토큰 가져오는 로직) return res.json()["access_token"]
서버연결
1. 서버 접속 (EC2 → SSH)
AWS EC2 인스턴스를 만들면 키 페어 (.pem 파일)을 받습니다. 이걸로 서버에 접속하면 됩니다.
윈도우 기준 키가 저장된 폴더에서 shell을 열고, 권한설정
chmod 400 <키_경로>
서버접속
ssh -i <키_경로> ubuntu@<서버_IP>
👉 ubuntu 대신 Amazon Linux는 ec2-user을 유저네임으로 씁니다.
2. Docker 설치
서버에서 봇을 컨테이너로 돌릴 수 있게 Docker를 설치합니다.
sudo apt update && sudo apt upgrade -y
sudo apt install -y docker.io docker-compose
sudo systemctl enable docker sudo usermod -aG docker $USER
👉 여기서 한 번 로그아웃/로그인해야 docker 권한이 적용됩니다.
3. 코드 배포
프로젝트 폴더를 서버에 올립니다. (/home/ubuntu/ 는 서버 생성 시 기본경로)
scp -i <키_경로> <파일경로> ubuntu@<서버주소>:/home/ubuntu/
4. Docker 빌드 & 실행
cd <프로젝트 폴더명>
docker-compose run
5. 실행 확인
docker ps
docker logs -f <이미지명>
데이터 저장 - 기억은 미화되지만, 데이터는 남는다
- 데이터베이스:
SQLite
에stocks.db
라는 이름으로 차곡차곡 저장합니다. - 스키마: 필요한 것만 딱. 가격, 거래량, 코드, 시간. 이게 전부입니다.
CREATE TABLE IF NOT EXISTS stock_data( code TEXT, -- 종목 코드 date TEXT, -- 시간은 곧 돈 open REAL, -- 시가 high REAL, -- 고가 low REAL, -- 저가 close REAL, -- 종가 (중요!) volume INTEGER -- 거래량 (더 중요!) )
- 활용: 이 데이터를 기반으로 나중에 백테스팅이고 뭐고 다 할 겁니다.
# 데이터 저장
def save_stock_data(data):
c.execute(
"""
INSERT INTO stock_data (code, date, open, high, low, close, volume)
VALUES (?, ?, ?, ?, ?, ?, ?)
""",
(
data["code"],
data["date"],
data["open"],
data["high"],
data["low"],
data["close"],
data["volume"],
),
)
conn.commit()
추가로, SQLite는 파일형식의 데이터베이스로 서버가 재가동되면 데이터도 사라지므로 데이터를 지속하려면 추가설정이 필요합니다. 여러 방법 중 저는 docker-compose.yml파일을 생성하여 볼륨설정 (프로젝트와 데이터를 따로 관리하도록 설정)
version: '3.8'
services:
stock_bot:
build: .
volumes:
- stock_data:/app/data
env_file:
- .env
volumes:
stock_data:
텔레그램 알림 - 귓속말이 아니라 실시간 속보
- 봇 출동: 모니터링 결과를 텔레그램으로 바로 쏴줍니다. 휴대폰만 봐도 시장 상황 파악 끝.
- 똑똑한 알림: "평균 종가 몇!", "거래량 폭발!" 등 조건 맞으면 즉시 핑 띄워줍니다. 비서가 따로 없습니다.
def send_telegram(msg): bot.send_message(chat_id=TELEGRAM_CHAT_ID, text=msg)
# telegram_client.py
from config import bot, TELEGRAM_CHAT_ID
def send_telegram(msg: str):
"""
Sends a text message to the specified Telegram chat.
Args:
msg: The string message to be sent.
"""
try:
bot.send_message(chat_id=TELEGRAM_CHAT_ID, text=msg)
print(f"Message sent to Telegram: {msg}")
except Exception as e:
print(f"Failed to send Telegram message: {e}")
핵심 로직 - 시작은 가볍게
STOCK_LIST = ["005930", "000660", "035420"]
while True:
prices = [get_stock_price(code) for code in STOCK_LIST]
avg_close = sum([p["close"] for p in prices if p]) / len(prices)
send_telegram(f"평균 종가: {avg_close:.2f}")
time.sleep(60 * 5)
- 현재: 일단 삼성전자, SK하이닉스, NAVER 3대 장만 주시 중입니다.
- 미래: 나중엔 지가 알아서 유망 종목 찾아내서 리스트에 추가하고 감시할 겁니다. 지금은 5분 간격으로 시세 긁어오고 평균 종가만 알리지만, 곧 봇이 직접 투자하는 그림을 그립니다.
배포 및 운영 - 봇은 오늘도 쉬지 않는다
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "han_invest_auto.py"]
- 컨테이너:
Dockerfile
로 포장해서 EC2 서버에서 돌립니다. 깔끔하죠. Dockerfile은 이미지 설계도로 서버가동을 자동화해 주는 등 운영을 편리하게 해 줌
다음 목표 - 어디까지 갈 수 있을까?
- 스마트 종목 발굴: 전 종목 스캔해서 내 기준에 맞는 녀석들만 쏙쏙 골라냅니다.
def discover_stocks():
all_codes = get_all_stock_codes()
candidates = []
for code in all_codes:
data = get_stock_price(code)
if data and data["volume"] > 1_000_000:
candidates.append(code)
return candidates
- 실제 매매: 매수/매도 API 연결해서 진짜 돈을 벌어볼 때입니다.
def buy_stock(code, qty):
url = f"{API_BASE}/uapi/domestic-stock/v1/trading/order-cash"
headers = {
"authorization": f"Bearer {ACCESS_TOKEN}",
"appkey": KIS_API_KEY,
"appsecret": KIS_API_SECRET,
"tr_id": "TTTC0802U" # 매수 주문
}
body = {
"CANO": "계좌번호앞8자리",
"ACNT_PRDT_CD": "01",
"PDNO": code,
"ORD_DVSN": "01", # 시장가
"ORD_QTY": str(qty),
"ORD_UNPR": "0" # 시장가일 때 0
}
res = requests.post(url, headers=headers, json=body)
return res.json()
- 전략 고도화: 백테스팅 돌려가며 전략 보강하고, 리스크 관리까지 완벽하게. 제 봇은 매일 진화합니다.
import backtrader as bt
class MovingAverageStrategy(bt.Strategy):
def __init__(self):
self.sma = bt.indicators.SimpleMovingAverage(period=20)
def next(self):
if self.data.close[0] > self.sma[0]:
self.buy(size=10)
elif self.data.close[0] < self.sma[0]:
self.sell(size=10)
그리고 효율적인 개발을 위해 로컬과 서버 동기화는 필수이죠 (설정방법 보러 가기)
마무리
지금까지 '한국투자증권 Open API 기반 주식 자동매매 프로그램 개발일지 #1'을 통해 대략적인 프로젝트 구조와 코드예지, 프로젝트의 시작부터 텔레그램 알림 봇 연동까지, 핵심적인 부분들을 함께 살펴보았습니다. 단순히 코드를 짜는 것을 넘어, 이렇게 스마트한 알림 시스템을 구축함으로써 또 하나의 비서가 생긴 느낌입니다.
다음 개발일지에서는 더 심화된 로직과 실제 매매 기능, 그리고 백테스팅 방법에 대해 다룰 예정이니 기대해 주세요! 여러분의 스마트한 투자 여정에 이 프로젝트가 큰 도움이 되기를 바랍니다. 다음 편에서 만나요!
'프로젝트' 카테고리의 다른 글
개발 생산성 향상을 위한 로컬-서버 자동 동기화 및 핫 리로딩 툴 (0) | 2025.09.24 |
---|---|
AWS EC2, '프리티어' 말고 '크레딧'으로 시작하기 (feat. 주식 자동화 프로젝트) (0) | 2025.09.23 |
스캘핑 봇 개발 일지 #5 빗썸 자동거래 봇 완성: 파이썬 핵심 구성 요소와 공격적 스캘핑 전략 가이드 (0) | 2025.09.20 |
스캘핑 봇 개발 일지 #4. 파이썬 트레이딩 봇: 파이어스토어로 수익 추적 및 데이터 관리 (0) | 2025.09.20 |
스캘핑 봇 개발 일지 #3. 속도 향상! Docker 컨테이너에서 Hot Reloading 환경 구축하기 (feat. Nodemon) (0) | 2025.09.16 |