행위

배당 수익률 상위 종목 검색

DB CAFE

thumb_up 추천메뉴 바로가기


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')