from pykrx import stock
from datetime import datetime, timedelta
import pandas as pd
import time
import numpy as np
import sqlite3
import random
con = sqlite3.connect('krx_data.db')
# 오늘날짜 기준으로 아직 받지않은 Data를 DB에 다운로드 받기
# 영업일을 List로 가져오기
def make_date_list(start, end):
start = datetime.strptime(start, '%Y%m%d')
end = datetime.strptime(end, '%Y%m%d')
dates = [(start + timedelta(days=i)).strftime('%Y%m%d') for i in range((end-start).days+1)]
b_dates = []
for d in dates:
b_day = stock.get_nearest_business_day_in_a_week(d)
if not b_day in b_dates:
b_dates.append(b_day)
s = random.randint(1, 3)
time.sleep(s)
return b_dates
# Data를 다운로드 받기
def data_download(date):
codes = stock.get_market_ticker_list(date, market='ALL') # code list 만들기
corp = [] #Code와 Name을 저장할 List
for code in codes:
name = stock.get_market_ticker_name(code) #종목 이름 가져오기
corp.append([code, name]) #Code와 이름으로 리스트를 만들기
df1 = pd.DataFrame(data=corp, columns=['code', '종목명'])#code와 종목명을 데이터프레임으로 만들기
df1.index = df1['code'] #index를 코드로 만들기
df_f = stock.get_market_fundamental_by_ticker(date=date, market='ALL')#BPS, PER, PBR, EPS, DIV, DPS 가져와서 데이터 프레임 만들기
df_c = stock.get_market_cap_by_ticker(date=date, market='ALL')#종가, 시가총액, 거래량, 거래대금, 상장주식수 가져오기
time.sleep(1)
df = pd.merge(df1, df_c, left_index=True, right_index=True) #종목명, 종가, 시가총액, 거래량, 거래대금, 상장주식수
df = pd.merge(df, df_f, left_index=True, right_index=True) #위에 df + PER, PBR...
#column은 '종목명', '종가', '시가총액', '거래량', '거래대금', '상장주식수', 'BPS', 'PER', 'PBR', 'EPS', 'DIV', 'DPS'
df['일자'] = np.array([date]*len(df))
df = df.set_index('일자')
return df
#DB에서 마지막 행 구하기
db_last_df = pd.read_sql("SELECT 일자, code, 종목명, DIV, DPS FROM fundamental ORDER BY ROWID DESC LIMIT 1", con)
db_last_date = db_last_df['일자'].iloc[0] #마지막 행에서 날짜 구하기
db_last_date = datetime.strptime(db_last_date, '%Y%m%d')
start_date = (db_last_date + timedelta(days=1)).strftime('%Y%m%d')
#오늘날짜 구하기
today = datetime.today().strftime('%Y%m%d')
end_date = stock.get_nearest_business_day_in_a_week(today, prev=True)
# 데이터 받아서 데이터프레임으로 합치고, DB에 저장
if start_date < end_date:
try:
dates = make_date_list(start_date, end_date)
print(dates)
for n, date in enumerate(dates):
print(date)
if n == 0:
t_df = data_download(date)
else:
t_df = pd.concat([t_df, data_download(date)])
time.sleep(1) #혹시나 차단될 수 있으니깐
print(t_df)
con = sqlite3.connect("krx_data.db")
t_df.to_sql('fundamental', con, if_exists='append')
except:
pass
# 과거 5년간의 Dataframe 구하기
def filter_by_period(today, ticker):
start = str(int(today[:4]) - 5) + today[-4:]
end = str(today)
df = pd.read_sql("SELECT 일자, code, 종목명, DIV, DPS FROM fundamental WHERE code = '" + ticker + "'" +
" AND 일자 >= " + start + " AND 일자 < " + end, con)
return df
div = 8
today_df = pd.read_sql("SELECT 일자 FROM fundamental ORDER BY ROWID DESC LIMIT 1", con)
#DB에서 마지막 행 구하기
today = today_df['일자'].iloc[0] #마지막 행에서 날짜 구하기
today_df = pd.read_sql("SELECT 일자, code, 종목명, DIV, DPS, EPS FROM fundamental WHERE 일자 = "
+ today + " AND EPS > 0" + " AND DPS > 0 AND DIV > " +
str(div), con)
# 오늘 날짜 기준으로 Data를 분석하기
to_see_codes = []
count = 0
for code in today_df['code']:
try:
print(len(today_df['code']) - count)
t_df = today_df[today_df['code'] == code]
name = t_df['종목명'].iloc[0]
t_div = t_df['DIV'].iloc[0] # 기준일자의 DIV
df = filter_by_period(today, code)
m = int(len(df['DPS']) / 2)
if df['DPS'].iloc[0] <= df['DPS'].iloc[-1] and df['DPS'].iloc[0] != 0 and \
df['DPS'].iloc[m] <= df['DPS'].iloc[-1]:
if df['DIV'].max() * 0.9 < t_div:
to_see_codes.append([today, code, name, t_div])
except:
pass
count += 1
total_df = pd.DataFrame(data=to_see_codes, columns=['기준일', 'Code', '종목명', '배당률'])
print(total_df)
total_df.to_excel('배당률로 선별한 종목 DIV '+ str(div) + '이상' + today +'.xlsx')