메뉴 여닫기
개인 메뉴 토글
로그인하지 않음
만약 지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

파이썬 배당 수익률 상위 종목 검색

데브카페

파이썬 배당 수익률 상위 종목 검색


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

Comments