2003년 ~ 2021년까지 PBR x DPS 와 시가총액, 거래대금, 월별로 가장 투자에 적합한 조건을 찾는 코드다.
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
|
# 경우의 수를 이용해서 최적조건 찾기
# (저PBR, 저DPS) x 12(개월) x 2(월초, 월말) x 30(시가총액 0이상~3천억이상 조건) x 100(거래금액 0이상부터 ~ 10억이상)
# col은 투자월, 투자일, CAGR, MDD, 손실횟수, 누적이익률, 손실평균
import pandas as pd
import sqlite3
con = sqlite3.connect('krx_data_new.db')
# 주식거래일을 구하는 함수
def near_business_day(b_start, b_month, b_day):
df_date = pd.read_sql("SELECT 일자 FROM fund WHERE 일자 LIKE " + "'" + b_start + "%'", con)
df_date.drop_duplicates(inplace=True)
li_df = df_date['일자'].tolist()
date = b_start + b_month + b_day
if date in li_df:
b_date = date
else:
if int(b_day) < 15: # 날짜가 15미만이면 1씩 더해서 영업일 구하기
while 10: # 10번 정도 더하기 반복해서 DB에 있는 날짜 구하기
b_day = int(b_day) + 1
b_day = str(b_day).zfill(2)
b_date = date[:6] + b_day
if b_date in li_df:
break
else: # 날짜가 15이상이면 1씩 빼면서 영업일 구하기
while 10:
b_day = int(b_day) - 1
b_day = str(b_day).zfill(2)
b_date = date[:6] + b_day
if b_date in li_df:
break
return b_date
li = [] #CAGR, MDD, 손실횟수, 누계이익률, 손실평균 등을 담을 list
i = 0
d = 1
for m in [4, 5, 6, 7, 8, 9, 10]:
for trans in range(0, 110000000, 10000000):
for cap in range(50000000000, 350000000000, 50000000000): #거래대금
li_result = []
for y in range(2003, 2022): #년
m = str(m).zfill(2)
d = str(d).zfill(2)
invest_day = near_business_day(str(y), m, d)
df = pd.read_sql("SELECT 일자, code, 종목명, 종가, 거래량, 거래대금, 상장주식수, 시가총액, "
"PBR, DPS FROM Fund WHERE 일자= " + invest_day, con)
# 거래량, PBR, DPS, 0이상인 종목만 가져오고, 거래대금은과 시가총액은 조건이상
df = df[(df['거래량'] > 0) & (df['PBR'] > 0) & (df['DPS'] > 0) & (df['거래대금'] >= trans) & (df['시가총액'] <= cap)]
df['PBR_rank'] = df['PBR'].rank()
df['DPS_rank'] = df['DPS'].rank()
df['PBR_DPS'] = df['PBR_rank'] + df['DPS_rank']
df['PBR_DPS_rank'] = df['PBR_DPS'].rank()
df.sort_values(by='PBR_DPS_rank', inplace=True)
df = df.iloc[:20]
#1년후의 날짜 구하기
sell_day = near_business_day(str(y + 1), m, d)
# 1년후의 날짜로 데이터 가져오기
df_later = pd.read_sql("SELECT 일자, code, 종가, 상장주식수 FROM fund WHERE 일자= " + sell_day, con)
df_later.columns = ['1년후의_일자', 'code', '1년후_종가', '1년후_상장주식수']
df = pd.merge(df, df_later, on='code')
df['수익률'] = (df['1년후_종가'] - df['종가']) / df['종가']
profit = df['수익률'].sum()/20
li_result.append([invest_day, profit])
if i == 0: # 첫번째 날짜는 만들어진 dataframe이 df_t로 저장되고, 나머지는 계속 concat로 붙여넣기
df_t = df
else:
df_t = pd.concat([df_t, df])
print(f'{m}월 {trans}거래대금 {cap}시가총액 {y}년도 작업중')
i += 1
df_result = pd.DataFrame(data=li_result, columns=['투자년도', '수익률']) # 투자년도와 수익률로 데이터프레임 만들기
li_acc = []
for n, p in enumerate(df_result['수익률']):
if n == 0:
li_acc.append(1 + p)
else:
li_acc.append(li_acc[n - 1] * (1 + p))
print(li_acc)
df_result['누적수익률'] = pd.DataFrame(data=li_acc, columns=['누적수익률'])
cagr = (df_result['누적수익률'].iloc[-1]) ** (1 / len(df_result)) - 1
MDD = df_result['수익률'].min()
return_acc = df_result['누적수익률'].iloc[-1]
df_lost = df_result[df_result['수익률'] < 0]
count_lost = df_lost['수익률'].count() #손실횟수
mean_lost = df_lost['수익률'].mean() #손실평균
li.append([m, d, cap, trans, cagr, MDD, return_acc, count_lost, mean_lost])
print(li)
df_find = pd.DataFrame(data=li, columns=['투자월', '투자일', '시가총액조건(이하)', '거래대금조건(이상)',
'CAGR', 'MDD', '누적수익률', '손실횟수', '손실평균'])
df_find.to_excel('최적조건찾기(2003-2021)4월-10월 거래대금0-1억이상 시가총액5백억-3천억이하 11-4월초.xlsx')
|
cs |
728x90
반응형
'돈을 벌기 위한 자료 > 투자정보' 카테고리의 다른 글
퀀트투자 계획 세우기 (1) | 2023.10.22 |
---|---|
파이썬으로 만든 퀀트투자 백테스트 툴 업데이트 (0) | 2023.10.15 |
투자종목 관리를 위한 스크래핑 코드(엑셀, 파이썬) (1) | 2023.09.04 |
효성ITX 094280 - 2 (3) | 2023.06.13 |
효성ITX 094280 (0) | 2023.06.09 |
댓글