안녕하세요. 주식 투자 관련 프로그램을 공유하는 인천고래입니다.
금일은 일봉 차트가 아닌 분봉 차트 데이터를 키움 API를 이용해서 가져오는 소스 코드를 공유하고자 합니다.
퀀트 투자를 하기 위해서는 우선 데이터를 취합을 하는게 우선입니다.
일봉 데이터는 쉽게 구할 수 있는 반면 분봉 데이터는 분 단위로 데이터가 발생되기 때문에 취합하는데 많은 시간을 할애를 해야 합니다. 일봉 하루치가 1분 봉 하나와 동일한 데이터이니 하루(6시간 30분간)의 1분 봉 데이터를 계산하면... 일봉 1년 치보다 많은 것 같네요.
그리고 퀀트 투자를 하고는 싶어도 데이터가 저장이 되는 데이터베이스를 잘 모르는 사람들이 대부분인데 이를 쉽게 활용할 수 있도록 많은 사람들이 사용하는 엑셀 파일로 저장하여 언제든지 쉽게 접근가능하도록 소스 코드를 구성해 보았습니다.
이번 글에서는 Python을 이용해 주식 데이터를 수집하고, 이동평균선, 엔벨로프, ATR 등의 기술적 지표를 계산하는 코드가 존재하니. 이 소스를 통해 초보자도 쉽게 따라할 수 있도록 전체 코드를 넣어두었습니다.
키움 API로 분봉 데이터 가져오기 목차
- 주식 데이터 수집: get_API_minute_data()
키움 API를 통해 주식의 분봉 데이터를 수집합니다. - 이동평균선 계산: calculate_moving_averages(df, periods)
다양한 기간의 이동평균선을 계산합니다. - 엔벨로프 계산: calculate_envelopes(df, period=20, deviation=0.02)
특정 기간과 이격 비율을 기반으로 엔벨로프를 계산합니다. - ATR 계산: calculate_atr(df, period=14)
True Range와 ATR 백분율을 계산합니다. - 데이터 저장: 수집한 데이터를 엑셀 파일로 저장합니다.
※ get_API_minute_data()함수 및 분봉 데이터를 요청하는 block_request() 메서드를 설명하는 글은 아래에 링크 글에 있습니다.
키움 API를 통해 분봉 데이터 가져오기 - kiwoom.block_request
안녕하세요. 주식 투자 관련 지식을 공유하는 인천고래입니다.오늘은 분봉 데이터를 연속적으로 가져오기 위해 꼭 알아야만 하는 block_request() 메서드에 대해 작성하도록 하겠습니다. 키움증권
i-whale.com
그리고 위의 목차에 나와있지만 주식 데이터를 수집한 뒤 이동평균선, 엔벨로프, ATR 등을 어떻게 추가하는지 알려드리기 위해 넣어두었고요. 필요 없으시면 삭제하셔도 됩니다.
데이터에는 주가 데이터만 존재하고 불러서 사용할 때 필요한 보조지표를 계산해서 사용하는 것이 더 좋은 것 같더라고요.
아래는 전체 코드입니다.
사용하시다가 궁금한 점 있으시면 댓글 달아주세요. 성심성의껏 설명 드리겠습니다.
import time
from pykiwoom.kiwoom import Kiwoom
import pandas as pd
import numpy as np
def calculate_moving_averages(df, periods):
"""
여러 기간에 대한 이동평균선을 계산하는 함수
:param df: 입력 데이터프레임 (종가 데이터 포함)
:param periods: 이동평균선을 계산할 기간 리스트 (예: [5, 10, 20, 60, 120])
:return: 여러 기간의 이동평균선이 포함된 데이터프레임
"""
for period in periods:
df[f'MA_{period}'] = df['Close'].rolling(window=period).mean()
return df
def calculate_envelopes(df, period=20, deviation=0.02):
"""
엔벨로프를 계산하는 함수
:param df: 입력 데이터프레임 (종가 데이터 포함)
:param period: 이동평균선 기간 (기본값: 20일)
:param deviation: 이격 비율 (기본값: 2%)
:return: 엔벨로프가 포함된 데이터프레임
"""
df['MA'] = df['Close'].rolling(window=period).mean()
df['Upper Envelope'] = df['MA'] * (1 + deviation)
df['Lower Envelope'] = df['MA'] * (1 - deviation)
return df
def calculate_atr(df, period=14):
"""
ATR(Average True Range)과 True Range 백분율을 계산하는 함수
:param df: 입력 데이터프레임 (고가, 저가, 종가 데이터 포함)
:param period: ATR을 계산할 기간 (기본값: 14일)
:return: ATR과 True Range 백분율이 포함된 데이터프레임
"""
df['High-Low'] = df['High'] - df['Low']
df['High-PrevClose'] = np.abs(df['High'] - df['Close'].shift(1))
df['Low-PrevClose'] = np.abs(df['Low'] - df['Close'].shift(1))
df['True Range'] = df[['High-Low', 'High-PrevClose', 'Low-PrevClose']].max(axis=1)
# 현재가 대비 True Range 백분율 계산
df['True Range %'] = (df['True Range'] / df['Close'].shift(1)) * 100
# ATR 계산
df['ATR %'] = df['True Range %'].rolling(window=period).mean()
return df
def get_API_minute_data(stock_code, start_date, end_date, tick_range=1):
kiwoom = Kiwoom()
kiwoom.CommConnect(block=True)
tr = "opt10080"
code = stock_code
df_list = []
# First block request
df_firstblock = kiwoom.block_request(tr,
종목코드=code,
수정주가구분=1,
틱범위=tick_range,
output="주식분봉차트조회",
next=0)
df_list.append(df_firstblock)
# Continue requesting while there is more data
while kiwoom.tr_remained:
df_remainblock = kiwoom.block_request(tr,
종목코드=code,
수정주가구분=1,
틱범위=tick_range,
output="주식분봉차트조회",
next=2)
df_list.append(df_remainblock)
oldest_date_in_block = pd.to_datetime(df_remainblock['체결시간'].min(), format='%Y%m%d%H%M%S')
if oldest_date_in_block < pd.to_datetime(start_date):
break
time.sleep(1) # To avoid request limit error
# Concatenate all data
df = pd.concat(df_list)
df.reset_index(drop=True, inplace=True)
# 한글 컬럼 이름을 영어로 변경
df.rename(columns={
'현재가': 'Close',
'거래량': 'Volume',
'시가': 'Open',
'고가': 'High',
'저가': 'Low',
'체결시간': 'DateTime'
}, inplace=True)
# Clean and preprocess the data
# 방법 1: str.replace 사용, str.replace 변환 시간: 0.024933 초
# 방법 2: apply + lambda 사용, apply + lambda 변환 시간: 0.012962 초
# df['Close_replace'] = df['Close'].str.replace('-', '').astype('float')
df['Close'] = df['Close'].apply(lambda x: x.lstrip('-')).astype('float')
df['Open'] = df['Open'].apply(lambda x: x.lstrip('-')).astype('float')
df['High'] = df['High'].apply(lambda x: x.lstrip('-')).astype('float')
df['Low'] = df['Low'].apply(lambda x: x.lstrip('-')).astype('float')
df['DateTime'] = pd.to_datetime(df['DateTime'], format='%Y%m%d%H%M%S', errors='raise')
df_all = df.drop(['수정주가구분', '수정비율', '대업종구분', '소업종구분', '종목정보', '수정주가이벤트', '전일종가'], axis=1)
# Filter by date range
df_all = df_all[(df_all['DateTime'] >= pd.to_datetime(start_date + ' 09:00:00')) & (
df_all['DateTime'] <= pd.to_datetime(end_date + ' 15:30:00'))]
df_all = df_all.sort_values(by='DateTime')
return df_all
# Example execution
if __name__ == "__main__":
start_time = time.time()
stock_code = "051380" # Example stock code
start_date = "20240526"
end_date = "20240626"
periods = [5, 10, 20, 60, 120]
min_df = get_API_minute_data(stock_code, start_date, end_date, tick_range=1)
atr_df = calculate_atr(min_df)
env_df = calculate_envelopes(atr_df, 60, 7)
env_df = calculate_moving_averages(atr_df, periods)
min_df.to_excel(f'min_data/{stock_code}_분봉데이터.xlsx')
end_time = time.time()
elapsed_time = end_time - start_time
msg = f"데이터 수집 시간(분): {elapsed_time / 60:.1f}\n------------------------------"
print(msg)
print(min_df.info())
print(min_df.head())
print(min_df.tail())
자신만의 매매법을 자동매매 프로그램으로 만들거나
기법이 확률이 떨어진다면 백테스팅을 사용해서 확률을 높여야 합니다.
아래의 링크를 통해서 요청하시면 요청하신 이상(가격대비 성능의 최대치)의 결과물을 받아 보실 수 있습니다.
한 방에 주식 데이터 만들기 - 크몽
인천고래 전문가의 IT·프로그래밍 서비스를 만나보세요. <p>퀀트 매매, 수익률 높은 매매, 확률 높은 매매, 잃지 않는 매매 등<...
kmong.com
다른 보조지표에 대해서는 아래의 링크 글을 통해 자세히 알아 볼 수 있습니다.
보조지표 리스트 (추세, 모멘텀, 채널, 변동성, 거래량, 기타 지표)
안녕하세요. 주식을 통해 삶을 영위할 수 있는 방법을 찾으며 인생 후반을 준비하고 있는 인천고래입니다.이전부터 보조지표에 대해서 글을 작성해 왔지만 중요한 것 위주로 작성을 하다보니
i-whale.com
단기적인 스윙 및 세력 매집 분석에 용이한 기준봉에 대해서는 아래의 링크 글을 통해 자세히 알아 볼 수 있습니다.
'주식 기준봉' 카테고리의 글 목록
주식 투자에 필요한 교육 내용을 제공하고 시장 정보 및 통계 등 수록하고 기록함을 원칙으로 하되 데이터마이닝을 통해 객관적인 자료를 구축하여 보다 경제적 자유를 얻기 위하여 사이트를
i-whale.com
'Quant' 카테고리의 다른 글
키움 openAPI 한글 깨짐 문제 해결 (0) | 2024.06.27 |
---|---|
키움 API를 통해 분봉 데이터 가져오기 - kiwoom.block_request (0) | 2024.06.26 |
자동매매 프레임워크를 Flask서버에서 FastAPI로 변경할 예정입니다. (0) | 2024.06.16 |
텔레그램 봇 생성: Token 및 Chat ID 확인 방법 (0) | 2024.06.07 |
주식 목표 주가 알림(알람) 프로그램 - 소스 코드 공유 (3) | 2024.06.07 |
댓글