이하영

simulator기능 구현

This diff is collapsed. Click to expand it.
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)
......
......@@ -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__":
......