배당수익률로 종목 선정하기 Update (With Python)
본문 바로가기
파이썬으로 만든 것들/배당투자를 위한 도구

배당수익률로 종목 선정하기 Update (With Python)

by Squat Lee 2022. 11. 11.

 

배당수익률로 종목을 선정하는 코드를 업데이트 했다.

 

DB에서 마지막 행의 날짜와 최근 영업일을 비교해서 DB에 최근 Data가 없으면 자동으로 업데이트 하도록 했다.

 

주식을 분석하는 툴에 이 기능을 추가할 예정이기에 자동화 시킬 수 있는 부분은 최대한 자동화 시키려고 노력했다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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(13)
            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[-1and 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')
 
 
 
cs

 

728x90
반응형

댓글