Toggle navigation
Toggle navigation
This project
Loading...
Sign in
2020-2-capstone-design2
/
2015104491
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
이하영
2020-11-25 03:50:12 +0900
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
f1ae6cc2bcb113825f7744dd1a4c9f3254ff046a
f1ae6cc2
1 parent
e329ca69
simulator기능 구현
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
223 additions
and
14 deletions
proj/library/Simulator_Api.py
proj/library/config.py → proj/library/cf.py
proj/library/collector_api.py
proj/library/open_api.py
proj/library/Simulator_Api.py
View file @
f1ae6cc
This diff is collapsed. Click to expand it.
proj/library/c
onfig
.py
→
proj/library/c
f
.py
View file @
f1ae6cc
File moved
proj/library/collector_api.py
View file @
f1ae6cc
from
Open_Api
import
*
from
collections
import
OrderedDict
from
pandas
import
DataFrame
import
time
from
Daily_Info
import
*
from
Stock_Info
import
*
...
...
@@ -23,27 +24,40 @@ class Collector_Api():
"today_buy_list,stock_info,min_info,daily_info from setting_data"
result
=
self
.
engine_bot
.
execute
(
query
)
.
fetchall
()
today
=
self
.
open_api
.
today
# 오늘 날짜에 종목리스트가 업데이트 되지 않았다면 업데이트를 실행
if
result
[
0
][
0
]
!=
self
.
open_api
.
today
:
if
result
[
0
][
0
]
!=
today
:
self
.
open_api
.
get_balance
()
self
.
get_code_list
()
# 계좌정보 업데이트
if
result
[
0
][
1
]
!=
self
.
open_api
.
today
or
result
[
0
][
2
]
!=
self
.
open_api
.
today
:
if
result
[
0
][
1
]
!=
today
or
result
[
0
][
2
]
!=
today
:
self
.
check_balance
()
self
.
open_api
.
set_per_invest
()
# 현재 보유종목 테이블 업데이트
if
result
[
0
][
2
]
!=
self
.
open_api
.
today
:
if
result
[
0
][
2
]
!=
today
:
self
.
open_api
.
get_posses_item
()
self
.
open_api
.
setting_data_posses_stock
()
if
result
[
0
][
3
]
!=
self
.
open_api
.
today
:
# 수익률 테이블 업데이트
if
result
[
0
][
3
]
!=
today
:
self
.
update_today_profit_list
()
if
result
[
0
][
7
]
!=
self
.
open_api
.
today
:
# stock_info 테이블 업데이트
if
result
[
0
][
7
]
!=
today
:
self
.
check_stock_info
()
if
result
[
0
][
9
]
!=
today
:
self
.
check_daily_info
()
if
result
[
0
][
4
]
!=
today
:
self
.
open_api
.
check_contract
()
self
.
open_api
.
final_check_contract
()
if
result
[
0
][
6
]
!=
today
:
self
.
realtime_daily_info_check
()
# 코스피, 코스닥 리스트 확인 및 데이터베이스 업데이트
...
...
@@ -256,7 +270,7 @@ class Collector_Api():
query
=
"UPDATE setting_data SET today_profit='
%
s' limit 1"
self
.
engine_bot
.
execute
(
query
%
(
self
.
open_api
.
today
))
def
check_
daily
_info
(
self
):
def
check_
stock
_info
(
self
):
self
.
update_daily_info
()
query
=
"update setting_data set daily_info='
%
s'"
self
.
engine_bot
.
execute
(
query
%
(
self
.
open_api
.
today
))
...
...
@@ -273,12 +287,102 @@ class Collector_Api():
code
=
code_list
[
i
][
0
]
code_name
=
code_list
[
i
][
1
]
check_item_sort
=
self
.
set_
minute
_info_table
(
code
,
code_name
)
check_item_sort
=
self
.
set_
stock
_info_table
(
code
,
code_name
)
self
.
open_api
.
engine_daily
.
execute
(
query
%
(
check_item_sort
,
code
))
def
set_minute_info_table
(
self
,
code
,
code_name
):
df
=
self
.
open_api
.
# stock_info 데이터베이스에 테이블 생성 및 추가
def
set_stock_info_table
(
self
,
code
,
code_name
):
df
=
self
.
open_api
.
get_date_data
(
code
,
code_name
,
self
.
open_api
.
today
)
df
=
DataFrame
(
df
,
columns
=
[
'date'
,
'check_item'
,
'code'
,
'code_name'
,
'd1_diff_rate'
,
'close'
,
'open'
,
'high'
,
'low'
,
'volume'
,
'clo5'
,
'clo10'
,
'clo20'
,
'clo60'
,
'clo120'
,
'pre_clo5'
,
'pre_clo10'
,
'pre_clo20'
,
'pre_clo60'
,
'pre_clo120'
,
'vol5'
,
'vol10'
,
'vol20'
,
'vol60'
,
'vol120'
])
df
=
df
.
sort_values
(
by
=
[
'date'
],
ascending
=
True
)
df
[
'code'
]
=
code
df
[
'code_name'
]
=
code_name
df
[
'd1_diff_rate'
]
=
float
((
df
[
'close'
]
-
df
[
'close'
]
.
shift
(
1
))
/
df
[
'close'
]
.
shift
(
1
)
*
100
)
df
[
'clo5'
]
=
df
[
'close'
]
.
rolling
(
window
=
5
)
.
mean
()
df
[
'clo10'
]
=
df
[
'close'
]
.
rolling
(
window
=
10
)
.
mean
()
df
[
'clo20'
]
=
df
[
'close'
]
.
rolling
(
window
=
20
)
.
mean
()
df
[
'clo60'
]
=
df
[
'close'
]
.
rolling
(
window
=
60
)
.
mean
()
df
[
'clo120'
]
=
df
[
'close'
]
.
rolling
(
window
=
120
)
.
mean
()
df
[
'pre_col5'
]
=
df
[
'clo5'
]
.
shift
(
1
)
df
[
'pre_col10'
]
=
df
[
'clo10'
]
.
shift
(
1
)
df
[
'pre_col20'
]
=
df
[
'clo20'
]
.
shift
(
1
)
df
[
'pre_col60'
]
=
df
[
'clo60'
]
.
shift
(
1
)
df
[
'pre_col120'
]
=
df
[
'clo120'
]
.
shift
(
1
)
df
[
'vlo5'
]
=
df
[
'volume'
]
.
rolling
(
window
=
5
)
.
mean
()
df
[
'vlo10'
]
=
df
[
'volume'
]
.
rolling
(
window
=
10
)
.
mean
()
df
[
'vlo20'
]
=
df
[
'volume'
]
.
rolling
(
window
=
20
)
.
mean
()
df
[
'vlo60'
]
=
df
[
'volume'
]
.
rolling
(
window
=
60
)
.
mean
()
df
[
'vlo120'
]
=
df
[
'volume'
]
.
rolling
(
window
=
120
)
.
mean
()
# 이미 테이블이 존재한다면 저장된 가장 최신의 날짜 이후의 데이터만 저장
if
self
.
engine_bot
.
dialect
.
has_table
(
self
.
open_api
.
engine_stock
,
code_name
):
df
=
df
[
df
.
date
>
self
.
open_api
.
get_latest_date_from_stock_info
(
code_name
)]
df
[[
'date'
,
'check_item'
,
'code'
,
'code_name'
,
'd1_diff_rate'
,
'close'
,
'open'
,
'high'
,
'low'
,
'volume'
,
'clo5'
,
'clo10'
,
'clo20'
,
'clo60'
,
'clo120'
,
'pre_clo5'
,
'pre_clo10'
,
'pre_clo20'
,
'pre_clo60'
,
'yes_clo120'
,
'vol5'
,
'vol10'
,
'vol20'
,
'vol60'
,
'vol120'
]]
=
\
df
[[
'date'
,
'check_item'
,
'code'
,
'code_name'
,
'd1_diff_rate'
,
'close'
,
'open'
,
'high'
,
'low'
,
'volume'
,
'clo5'
,
'clo10'
,
'clo20'
,
'clo60'
,
'clo120'
,
'pre_clo5'
,
'pre_clo10'
,
'pre_clo20'
,
'pre_clo60'
,
'yes_clo120'
,
'vol5'
,
'vol10'
,
'vol20'
,
'vol60'
,
'vol120'
]]
.
fillna
(
0
)
.
astype
(
int
)
df
.
to_sql
(
name
=
code_name
,
con
=
self
.
open_api
.
engine_stock
,
if_exists
=
'append'
)
check_item_sort
=
1
return
check_item_sort
def
check_daily_info
(
self
):
self
.
daily_info
.
create_daily_table
()
query
=
"update setting_data set daily_info='
%
s'"
self
.
engine_bot
.
execute
(
query
%
(
self
.
open_api
.
today
))
def
realtime_daily_info_check
(
self
):
if
self
.
open_api
.
simul_api
.
is_date_exist
(
self
.
open_api
.
today
):
self
.
open_api
.
simul_api
.
get_date_for_simul
()
self
.
open_api
.
simul_api
.
choose_to_buy_list
(
self
.
open_api
.
today
,
self
.
open_api
.
today
,
len
(
self
.
open_api
.
simul_api
.
date_rows
))
if
self
.
open_api
.
sf
.
is_date_exist
(
self
.
open_api
.
today
):
logger
.
debug
(
"daily_buy_list DB에 {} 테이블이 있습니다. jackbot DB에 realtime_daily_buy_list 테이블을 생성합니다"
.
format
(
self
.
open_api
.
today
))
self
.
open_api
.
sf
.
get_date_for_simul
()
# 첫 번째 파라미터는 여기서는 의미가 없다.
# 두 번째 파라미터에 오늘 일자를 넣는 이유는 매수를 하는 시점인 내일 기준으로 date_rows_yesterday가 오늘 이기 때문
self
.
open_api
.
sf
.
db_to_realtime_daily_buy_list
(
self
.
open_api
.
today
,
self
.
open_api
.
today
,
len
(
self
.
open_api
.
sf
.
date_rows
))
# all_item_db에서 open, clo5~120, volume 등을 오늘 일자 데이터로 업데이트 한다.
self
.
open_api
.
sf
.
update_all_db_by_date
(
self
.
open_api
.
today
)
self
.
open_api
.
rate_check
()
# realtime_daily_buy_list(매수 리스트) 테이블 세팅을 완료 했으면 아래 쿼리를 통해 setting_data의 today_buy_list에 오늘 날짜를 찍는다.
sql
=
"UPDATE setting_data SET today_buy_list='
%
s' limit 1"
self
.
engine_JB
.
execute
(
sql
%
(
self
.
open_api
.
today
))
else
:
logger
.
debug
(
"""daily_buy_list DB에 {} 테이블이 없습니다. jackbot DB에 realtime_daily_buy_list 테이블을 생성 할 수 없습니다.
realtime_daily_buy_list는 daily_buy_list DB 안에 오늘 날짜 테이블이 만들어져야 생성이 됩니다.
realtime_daily_buy_list 테이블을 생성할 수 없는 이유는 아래와 같습니다.
1. 장이 열리지 않은 날 혹은 15시 30분 ~ 23시 59분 사이에 콜렉터를 돌리지 않은 경우
2. 콜렉터를 오늘 날짜 까지 돌리지 않아 daily_buy_list의 오늘 날짜 테이블이 없는 경우
"""
.
format
(
self
.
open_api
.
today
))
app
=
QApplication
(
sys
.
argv
)
...
...
proj/library/open_api.py
View file @
f1ae6cc
...
...
@@ -329,13 +329,13 @@ class Open_Api(QAxWidget):
def
create_setting_data
(
self
):
df_data
=
{
"limit_money"
:[],
"per_invest"
:[],
"max_per_invest"
:[],
"min_per_invest"
:[],
"set_per_invest"
:[],
"code_update"
:[],
"today_finish"
:[],
"balance_to_db"
:[],
"posses_stocks"
:[],
"today_profit"
:[],
"contract_check"
:[],
"
db_to_daily_info"
:[],
"today_buy_list"
:[],
"stock_info"
:[],
"min_info
"
:[],
"daily_info"
:[]}
"contract_check"
:[],
"
final_contract_check"
:[],
"db_to_daily_info"
:[],
"today_buy_list
"
:[],
"
stock_info"
:[],
"min_info"
:[],
"
daily_info"
:[]}
df_setting_data
=
DataFrame
(
df_data
,
columns
=
[
'limit_money'
,
'per_invest'
,
'max_per_invest'
,
'min_per_invest'
,
'set_per_invest'
,
'code_update'
,
'today_finish'
,
'balance_to_db'
,
'posses_stocks'
,
'today_profit'
,
'contract_check'
,
'
db_to_daily_info'
,
'today_buy_list'
,
'stock_info'
,
'min_info
'
,
'daily_info'
])
'contract_check'
,
'
final_contract_check'
,
'db_to_daily_info'
,
'today_buy_list
'
,
'
stock_info'
,
'min_info'
,
'
daily_info'
])
df_setting_data
.
loc
[
0
,
'limit_money'
]
=
int
(
0
)
df_setting_data
.
loc
[
0
,
'per_invest'
]
=
int
(
0
)
...
...
@@ -350,11 +350,12 @@ class Open_Api(QAxWidget):
df_setting_data
.
loc
[
0
,
'today_profit'
]
=
float
(
0
)
df_setting_data
.
loc
[
0
,
'contract_check'
]
=
str
(
0
)
df_setting_data
.
loc
[
0
,
'final_contract_check'
]
=
str
(
0
)
df_setting_data
.
loc
[
0
,
'db_to_daily_info'
]
=
str
(
0
)
df_setting_data
.
loc
[
0
,
'today_buy_list'
]
=
str
(
0
)
df_setting_data
.
loc
[
0
,
'stock_info'
]
=
str
(
0
)
df_setting_data
.
loc
[
0
,
'min_info'
]
=
str
(
0
)
df_setting_data
.
loc
[
0
,
'min_info'
]
=
str
(
0
)
df_setting_data
.
loc
[
0
,
'daily_info'
]
=
str
(
0
)
df_setting_data
.
to_sql
(
"setting_data"
,
self
.
engine_bot
,
if_exists
=
"replace"
)
...
...
@@ -588,9 +589,113 @@ class Open_Api(QAxWidget):
self
.
opt10073_output
[
'multi'
]
.
append
([
date
,
code
,
code_name
,
amount
,
today_profit
,
earning_rate
])
# 특정 종목의 일자별 거래 데이터 조회 함수
def
get_date_data
(
self
,
code
,
code_name
,
date
):
self
.
ohlcv
=
defaultdict
(
list
)
self
.
set_input_value
(
"종목코드"
,
code
)
self
.
set_input_value
(
"기준일자"
,
date
)
self
.
set_input_value
(
"수정주가구분"
,
1
)
# 한번에 600일치의 데이터를 가져온다
self
.
comm_rq_data
(
"opt10081_req"
,
"opt10081"
,
0
,
"0101"
)
# stock_info 테이블이 존재하지 않는다면 600일치 이상의 전체 데이터를 가져와야 하므로 다음 페이지가 존재하지 않을 때까지 조회
if
not
self
.
is_stock_table_exist
(
code_name
):
while
self
.
remained_data
==
True
:
self
.
set_input_value
(
"종목코드"
,
code
)
self
.
set_input_value
(
"기준일자"
,
date
)
self
.
set_input_value
(
"수정주가구분"
,
1
)
self
.
comm_rq_data
(
"opt10081_req"
,
"opt10081"
,
2
,
"0101"
)
if
len
(
self
.
ohlcv
)
==
0
:
return
[]
if
self
.
ohlcv
[
'date'
]
==
''
:
return
[]
df
=
DataFrame
(
self
.
ohlcv
,
columns
=
[
'date'
,
'open'
,
'high'
,
'low'
,
'close'
,
'volume'
])
return
df
# stock_info 데이터베이스가 존재하는지 확인하는 함수
def
is_stock_table_exist
(
self
,
code_name
):
query
=
"select 1 from information_schema.tables where table_schema ='stock_info' and table_name = '{}'"
result
=
self
.
engine_stock
.
execute
(
query
.
format
(
code_name
))
.
fetchall
()
if
result
:
return
True
else
:
return
False
# 주식 일봉차트 조회 요청
# 주식의 날짜별 데이터를 저장하는 함수
def
collector_opt10081
(
self
,
sRQName
,
sTrCode
):
ohlcv_cnt
=
self
.
_get_repeat_cnt
(
sTrCode
,
sRQName
)
for
i
in
range
(
ohlcv_cnt
):
date
=
self
.
_get_comm_data
(
sTrCode
,
sRQName
,
i
,
"일자"
)
open
=
self
.
_get_comm_data
(
sTrCode
,
sRQName
,
i
,
"시가"
)
high
=
self
.
_get_comm_data
(
sTrCode
,
sRQName
,
i
,
"고가"
)
low
=
self
.
_get_comm_data
(
sTrCode
,
sRQName
,
i
,
"저가"
)
close
=
self
.
_get_comm_data
(
sTrCode
,
sRQName
,
i
,
"현재가"
)
volume
=
self
.
_get_comm_data
(
sTrCode
,
sRQName
,
i
,
"거래량"
)
self
.
ohlcv
[
'date'
]
.
append
(
date
)
self
.
ohlcv
[
'open'
]
.
append
(
int
(
open
))
self
.
ohlcv
[
'high'
]
.
append
(
int
(
high
))
self
.
ohlcv
[
'low'
]
.
append
(
int
(
low
))
self
.
ohlcv
[
'close'
]
.
append
(
int
(
close
))
self
.
ohlcv
[
'volume'
]
.
append
(
int
(
volume
))
# stock_info의 특정 종목 테이블에서 마지막으로 저장된 날짜를 가져오는 함수
# 저장된 데이터가 없다면 '0'문자를 반환
def
get_latest_date_from_stock_info
(
self
,
code_name
):
query
=
"select date from {} order by date desc limit 1"
result
=
self
.
engine_stock
.
execute
(
query
.
format
(
code_name
))
.
fetchall
()
if
len
(
result
):
return
result
[
0
][
0
]
else
:
return
str
(
0
)
def
check_contract
(
self
):
query
=
"select code from transaction_history where contract_check='1' and (sell date='0' or sell_date='')"
rows
=
self
.
engine_bot
.
execute
(
query
)
.
fetchall
()
for
r
in
rows
:
self
.
set_input_value
(
"종목코드"
,
r
.
code
)
self
.
set_input_value
(
"조회구분"
,
1
)
self
.
set_input_value
(
"계좌번호"
,
self
.
account_no
)
self
.
comm_rq_data
(
"opt10076_req"
,
"opt10076"
,
0
,
"0350"
)
query
=
"update transaction_history set contract_check='0' where code='{}' and sell_date='0'"
# 거래가 완료된 항목은 주문번호가 존재하지 않음
# 거래가 완료된 항목에 대해서 contract_check항목을 '0'으로 업데이트
if
not
self
.
not_contract
[
'주문번호'
]:
self
.
engine_bot
.
execute
(
query
.
format
(
r
.
code
))
# 미체결 수량이 없을 경우 contract_check항목을 '0'으로 업데이트
elif
self
.
not_contract
[
'미체결수량'
]
==
0
:
logger
.
debug
(
"미체결 항목이 없습니다"
)
self
.
engine_bot
.
execute
(
query
.
format
(
r
.
code
))
else
:
logger
.
debug
(
"미체결 종목이 존재합니다"
)
# posses_item테이블에는 존재하지만 transaction_history테이블에 존재하지 않는 항목에 대해 업데이트
def
final_check_contract
(
self
):
query
=
"select code from transaction_history"
\
"where"
\
"sell_date='
%
s' or sell_date='
%
s' and code not in (select code from posses_item) and contract_check!='
%
s'"
result
=
self
.
engine_bot
.
execute
(
query
%
(
0
,
""
,
1
))
.
fetchall
()
num
=
len
(
result
)
for
i
in
range
(
num
):
self
.
sell_check
(
result
[
i
][
0
])
query
=
"update setting_data set final_contract_check='
%
s'"
self
.
engine_bot
.
execute
(
query
%
(
self
.
today
))
# 가지고 있던 종목을 판매하여 posses_item테이블에 내역이 존재하지 않지만 transaction_history에 매도처리가 되지 않은 항목 업데이트
def
sell_check
(
self
,
code
):
query
=
"update transaction_history"
\
"set"
\
"contract_check='
%
s', sell_date='
%
s'"
\
"where code='
%
s' and sell_date='
%
s'"
self
.
engine_bot
.
execute
(
query
%
(
0
,
self
.
today_time
,
code
,
0
))
if
__name__
==
"__main__"
:
...
...
Please
register
or
login
to post a comment