collector_api.py 12.5 KB
from Open_Api import *
from collections import OrderedDict
from pandas import DataFrame

from Daily_Info import *
from Stock_Info import *
import config

class Collector_Api():
    def __init__(self):
        self.open_api=Open_Api()
        self.engine_bot=self.open_api.engine_bot
        self.set_variable()

    # 변수 설정
    def set_variable(self):
        self.open_api.use="collector"
        self.stock_info=Stock_Info(config.real_bot_name,config.real_dailyInfo_name,config.real_stockInfo_name)
        self.daily_info=Daily_Info()

    def code_update_check(self):
        query="select code_update,balance_to_db,posses_stocks,today_profit,contract_check,db_to_daily_info," \
              "today_buy_list,stock_info,min_info,daily_info from setting_data"
        result=self.engine_bot.execute(query).fetchall()

        # 오늘 날짜에 종목리스트가 업데이트 되지 않았다면 업데이트를 실행
        if result[0][0]!=self.open_api.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:
            self.check_balance()
            self.open_api.set_per_invest()

        # 현재 보유종목 테이블 업데이트
        if result[0][2]!=self.open_api.today:
            self.open_api.get_posses_item()
            self.open_api.setting_data_posses_stock()

        if result[0][3]!=self.open_api.today:
            self.update_today_profit_list()

        if result[0][7]!=self.open_api.today:
            self.check_daily_info()



    # 코스피, 코스닥 리스트 확인 및 데이터베이스 업데이트
    def get_code_list(self):
        self.stock_info.get_item_kospi()
        self.stock_info.get_item_kosdaq()

        stock_data=OrderedDict(
            kospi=self.stock_info.kospi_list,
            kosdaq=self.stock_info.kosdaq_list
        )

        for s_type,data in stock_data.items():
            stock_data[s_type]=self.create_stock_table(data,s_type)

        stock_all=stock_data['kospi'].append(stock_data['kosdaq'],ignore_index=True)
        self.create_stock_table(stock_all,"all")
        query="update setting_data set code_update='%s'"
        self.engine_bot.execute(query%(self.open_api.today))

    # kospi, kosdaq 주식 종목을 저장하는 테이블 생성
    def create_stock_table(self,data,type):
        checking=['kospi','kosdaq']
        stock_df=DataFrame()
        stock_df['code']=data['code']
        stock_list=list()
        # 주식 code를 이용하여 실제 kiwoom 증권에서 사용하는 주식이름으로 변경
        for kind in data.itertuples():
            kiwoom_name=self.open_api.dynamicCall("GetMasterCodeName(QString)",kind.code).strip()
            stock_list.append(kiwoom_name)
        stock_df['code_name']=stock_list
        stock_df['check_item']=0

        if type in checking:
            stock_df=stock_df[stock_df['code_name'].map(len)>0]

        if type=="all":
            stock_df['check_stock']="0"
            stock_df['check_min']="0"

        # 데이터 타입을 설정
        # code, code_name 칼럼은 Text. check_item 칼럼은 Integer
        dtypes=dict(zip(list(stock_df.columns),[Text]*len(stock_df.columns)))
        dtypes['check_item']=Integer

        table_name='stock_'+str(type)
        stock_df.to_sql(table_name,self.open_api.engine_daily,if_exists='replace',dtype=dtypes)
        return stock_df

    def check_balance(self):
        self.open_api.reset_opw00018_output()
        # 예수금 상세현황 요청
        self.open_api.set_input_value("계좌번호",self.open_api.account_no)
        self.open_api.set_input_value("비밀번호입력매체구분",00)
        self.open_api.set_input_value("조회구분",1)
        self.open_api.comm_rq_data("opw00001_req","opw00001",0,"2000")
        # 계좌평가 잔고내역 요청
        self.open_api.set_input_value("계좌번호",self.open_api.account_no)
        self.open_api.comm_rq_data("opw00018_req","opw00018",0,"2000")
        while self.open_api.remained_data:
            self.open_api.set_input_value("계좌번호",self.open_api.account_no)
            self.open_api.comm_rq_data("opw00018_req","opw00018",2,"2000")
        # 일자별 실현손익 요청
        self.open_api.set_input_value("계좌번호",self.open_api.account_no)
        self.open_api.set_input_value("시작일자","20170101")
        self.open_api.set_input_value("종료일자",self.open_api.today)
        self.open_api.comm_rq_data("opt10074_req","opt10074",0,"0329")
        while self.open_api.remained_data:
            self.open_api.set_input_value("계좌번호", self.open_api.account_no)
            self.open_api.set_input_value("시작일자", "20170101")
            self.open_api.set_input_value("종료일자", self.open_api.today)
            self.open_api.set_input_value("구분","0")
            self.open_api.comm_rq_data("opt10074_req", "opt10074", 2, "0329")

        self.create_balance_table()

    # balance_data 테이블 생성
    def create_balance_table(self):
        self.total_invest=int(self.open_api.deposit)+int(self.open_api.total_purchase)
        balance_data={'id':[],'date':[],'total_asset':[],'today_profit':[],"total_profit":[],
                      'total_invest':[],'deposit':[],'total_purchase':[],'total_evaluation':[],'today_invest':[],
                      'today_rate':[],'estimated_asset':[]}

        balance_cols=['date','today_earning_rate','total_asset','deposit',
                      'today_profit','total_profit','today_invest','total_invest',
                      'total_purchase','today_evaluation','today_sell_count',
                      'today_rate','estimated_asset','sell_point','per_invest','limit_money',
                      'today_buy_count','today_sell_count','total_posses_count','today_buy_price','today_sell_price'
                      ]

        balance=DataFrame(balance_data,columns=balance_cols,index=balance_data['id'])

        balance.loc[0,'date']=self.open_api.today
        balance.loc[0,'today_profit']=self.open_api.today_profit
        balance.loc[0,'total_profit']=self.open_api.total_profit
        balance.loc[0,'total_invest']=self.open_api.total_invest
        balance.loc[0,'deposit']=self.open_api.deposit
        balance.loc[0,'total_purchase']=self.open_api.total_purchase
        balance.loc[0,'total_evaluation']=self.open_api.total_evaluated_price
        balance.loc[0,'today_invest']=self.open_api.total_valuation
        balance.loc[0,'today_rate']=float(self.open_api.earning_rate/self.open_api.mod_classify)
        balance.loc[0,'estimate_asset']=self.open_api.estimated_deposit
        balance.loc[0,'sell_point']=self.open_api.simul_api.sell_point
        balance.loc[0,'per_invest']=self.open_api.per_invest
        balance.loc[0,'limit_money']=self.open_api.simul_api.limit_money

        # balance_data 테이블 생성
        balance.to_sql('balance_data', self.engine_bot, if_exists='append')

        query = "select date from balance_data"
        rows = self.engine_bot.execute(query).fetchall()

        for i in range(len(rows)):
            # today_earning_rate
            query = "update balance_data " \
                    "set " \
                    "today_earning_rate =round(today_profit / total_invest  * '%s',2) WHERE date='%s'"
            self.engine_bot.execute(query % (100, rows[i][0]))
            # today_buy_count
            query = "UPDATE balance_data " \
                    "SET " \
                    "today_buy_count=" \
                    "(select count(*) " \
                    "from " \
                    "(select code from transaction_history where buy_date like '%s' group by code )) " \
                    "WHERE date='%s'"
            self.engine_bot.execute(query % (rows[i][0] + "%%", rows[i][0]))
            # today_sell_count
            query="UPDATE balance_data " \
                  "SET " \
                  "today_sell_count=" \
                  "(select count(*) " \
                  "from " \
                  "(select code from transaction_history" \
                  "where buy_date like '%s' and sell_date is not null group by code) temp) " \
                  "WHERE date='%s'"
            self.engine_bot.execute(query % (rows[i][0] + "%%", rows[i][0]))
            # today_sell_price
            query="UPDATE balance_data " \
                  "SET" \
                  "today_sell_price=" \
                  "(select sum(*) " \
                  "from " \
                  "(select sell_price from transaction_history " \
                  "where sell_date like '%s')" \
                  "where date='%s'"
            self.engine_bot.execute(query%(rows[i][0])+"%%",rows[i][0])
            # today_buy_price
            query="UPDATE balance_data " \
                  "SET" \
                  "today_sell_price=" \
                  "(select sum(*) " \
                  "from " \
                  "(select purchase_price from transaction_history " \
                  "where sell_date like '%s')" \
                  "where date='%s'"
            self.engine_bot.execute(query%(rows[i][0])+"%%",rows[i][0])
            # total_posses_count
            query="UPDATE balance_data " \
                  "SET" \
                  "total_posses_count=" \
                  "(select count(*) " \
                  "from" \
                  "transaction_history where sell_date is Null)" \
                  "where date='%s'"
            self.engine_bot.execute(query%(rows[i][0]))

        sql = "UPDATE setting_data SET balance_to_db='%s' limit 1"
        self.engine_bot.execute(sql % (self.open_api.today))

    def is_table_exist(self,db_name,table_name):
        query="select 1 from information_schema.tables where table_schema='{}' and table_name='{}'"
        result=self.open_api.engine_minute.execute(query.format(db_name,table_name)).fetchall()
        if len(result)==1:
            return True
        else:
            return False

    def update_today_profit_list(self):
        self.open_api.reset_opt10073_output()

        self.open_api.set_input_value("계좌번호",self.open_api.account_no)
        self.open_api.set_input_value("시작일자",self.open_api.today)
        self.open_api.set_input_value("종료일자",self.open_api.today)
        self.open_api.comm_rq_data("opt10073_req","opt10073",0,"0328")

        while self.open_api.remained_data:
            self.open_api.set_input_value("계좌번호",self.open_api.account_no)
            self.open_api.comm_rq_data("opt10073_req","opt10073",2,"0328")

        today_profit_item_temp = {'date': [], 'code': [], 'code_name': [], 'amount': [], 'today_profit': [],
                                  'earning_rate': []}

        today_profit_item = DataFrame(today_profit_item_temp,
                                      columns=['date', 'code', 'code_name', 'amount', 'today_profit',
                                               'earning_rate'])

        item_count = len(self.open_api.opt10073_output['multi'])
        for i in range(item_count):
            row = self.open_api.opt10073_output['multi'][i]
            today_profit_item.loc[i, 'date'] = row[0]
            today_profit_item.loc[i, 'code'] = row[1]
            today_profit_item.loc[i, 'code_name'] = row[2]
            today_profit_item.loc[i, 'amount'] = int(row[3])
            today_profit_item.loc[i, 'today_profit'] = float(row[4])
            today_profit_item.loc[i, 'earning_rate'] = float(row[5])

        if len(today_profit_item) > 0:
            today_profit_item.to_sql('today_profit_list', self.engine_bot, if_exists='append')
        query = "UPDATE setting_data SET today_profit='%s' limit 1"
        self.engine_bot.execute(query % (self.open_api.today))

    def check_daily_info(self):
        self.update_daily_info()
        query="update setting_data set daily_info='%s'"
        self.engine_bot.execute(query%(self.open_api.today))

    def update_daily_info(self):
        query="select code,code_name,check_stock from stock_all"
        code_list=self.open_api.engine_daily.execute(query).fetchall()
        num=len(code_list)
        query="update stock_all set check_stock='%s' where code='%s'"
        for i in range(num):
            if int(code_list[i][2] in (1,3)):
                continue

            code=code_list[i][0]
            code_name=code_list[i][1]

            check_item_sort=self.set_minute_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.


app=QApplication(sys.argv)
c=Collector_Api()
c.get_code_list()