示例#1
0
    def get_multi_response(self, tr_code, tr_name, pre_next, output_format):
        list = []
        count = self.dynamicCall("GetRepeatCnt(QString, QString)", tr_code,
                                 tr_name)
        code = None
        log.instance().logger().debug("LIST COUNT: {0}".format(count))
        for i in range(0, count):
            data = {}

            for key, value in output_format["output_list"].items():
                kr = value["kr"]
                type = value["type"]
                value = self.kiwoom_GetCommData(tr_code, tr_name, i,
                                                kr).strip()
                data[key] = self.tr_util.parse_response(value, type)
            if i == 0:
                if 'code' in data.keys():
                    code = data["code"]
            else:
                if code:
                    data["code"] = code
            list.append(data)

        log.instance().logger().debug("TR: {0}\tDATA: {1}".format(
            tr_name, list))
        return list
示例#2
0
    def get(self):
        """
        get real time stock info
        :return:
        """
        table_name = "stock"
        list_temp = self.db.dist(table_name, "code")
        size = 100
        page = 1
        count = len(list_temp)

        def isNotEmpty(x):
            return len(x) > 0

        # self.hts.get_daily_stock_open_status()
        # time.sleep(2)
        for i in range(0, count, size):
            code_list = list_temp[i:  i + size if size + i <= count else count]
            log.instance().logger().debug("SET REAL RES: {0} {1}".format(page, code_list))
            self.hts.set_real_stocks(code_list)
            code_list = list(filter(isNotEmpty, code_list))
            if page == 1:
                self.hts.set_check_market_state("{0:05}".format(page), ";".join(code_list), "0")
            else:
                self.hts.set_check_market_state("{0:05}".format(page), ";".join(code_list), "1")
                # print("")
            time.sleep(2)
            page += 1
        self.hts.multiEvents["STOCK"] = QEventLoop()
        self.hts.multiEvents["STOCK"].exec_()
示例#3
0
    def get(self):
        """
            restore kospi code
        """
        log.instance().logger().debug("code handler")

        # query = self.get_argument('query', None)
        # if query is not None:
        """
            [시장구분값]
            0 : 장내
            10 : 코스닥
            3 : ELW
            8 : ETF
            50 : KONEX
            4 :  뮤추얼펀드
            5 : 신주인수권
            6 : 리츠
            9 : 하이얼펀드
            30 : K-OTC
        """
        self.time = datetime.datetime.now().strftime("%H")
        if self.time < "09":
            d = datetime.datetime.now().date()
            self.today = "{0}{1:02}{2:02}".format(datetime.datetime.now().year, datetime.datetime.now().month,
                                                  datetime.datetime.now().day - 1)
        else:
            self.today = datetime.datetime.now().strftime("%Y%m%d")

        # KOSPI
        ks = self.reload_kospi("0", self.today)

        index = 1
        size = len(ks)
        for i in ks:
            print("{0}/{1}: {3}-{2}".format(index, size, i["code"], i["market"]))
            index = index + 1
            try:
                self.loadYahooHistory(i["code"], i["market"])
            except:
                print("Oops!  That was no valid number.  Try again...")
        # KOSDAQ
        kq = self.reload_kospi("10", self.today)
        index = 1
        size = len(kq)
        for i in kq:
            print("{0}/{1}: {3}-{2}".format(index, size, i["code"], i["market"]))
            index = index + 1
            try:
                self.loadYahooHistory(i["code"], i["market"])
            except:
                print("Oops!  That was no valid number.  Try again...")
        self.store()

        return {
            "ks": ks,
            "kq": kq
        }
示例#4
0
 def check_market_open(self):
     fid = "215;20;214"
     res = self.dynamicCall(
         "SetRealReg(QString, QString, QString, QString)", "1000", "", fid,
         "0")
     log.instance().logger().debug("SetRealReg RES: {0}".format(res))
     if res < 0:
         log.instance().logger().debug("SetRealReg RES: {0}".format(
             errors(res)))
         self.event.exit()
示例#5
0
    def get_single_response(self, tr_code, tr_name, pre_next, output_format):
        data = {}
        for key, value in output_format["output"].items():
            kr = value["kr"]
            type = value["type"]
            value = self.kiwoom_GetCommData(tr_code, tr_name, 0, kr).strip()
            data[key] = self.tr_util.parse_response(value, type)

        log.instance().logger().debug("TR: {0}\tDATA: {1}".format(
            tr_name, data))
        # self.dict_callback[tr_name] = data
        return data
示例#6
0
 def kiwoom_CommRqData(self, sRQName, sTrCode, nPrevNext, sScreenNo):
     """
     :param sRQName:
     :param sTrCode:
     :param nPrevNext:
     :param sScreenNo:
     :return:
     """
     res = self.dynamicCall("CommRqData(QString, QString, int, QString)",
                            sRQName, sTrCode, nPrevNext, sScreenNo)
     log.instance().logger().debug("CommRqData RES: {0}".format(res))
     if res < 0:
         log.instance().logger().debug("CommRqData RES: {0}".format(
             errors(res)))
         self.event.exit()
     return res
示例#7
0
    def get(self):
        """
            restore kospi code
        """
        log.instance().logger().debug("stock daily handler")

        code = self.get_argument('code', None)
        today = self.get_argument('today', None)
        if today is None:
            today = datetime.datetime.now().strftime("%Y%m%d")

        result = None
        if code is not None:
            result = self.hts.get_daily_stock_info_detail(code, today)
            # self.hts.save_daily_stock_info(code, result)
        self.write(json.dumps(result))
示例#8
0
    def get(self):
        """
            restore kospi code
        """
        log.instance().logger().debug("code handler")

        code = self.get_argument('code', None)
        # query = self.get_argument('query', None)
        result = None
        # if query is not None:

        if code is None:
            result = self.reload_kospi()
        else:
            result = self.get_stock_info(code)

        self.write(json.dumps(result))
示例#9
0
        def func_wrapper(self, *args, **kwargs):
            # self.request_thread_worker.request_queue.append((func, args, kwargs))
            arg_names = inspect.getfullargspec(func).args
            if 'pre_next' in arg_names:
                index = arg_names.index('pre_next') - 1
            else:
                index = -1

            log.instance().logger().debug("요청 실행: %s %s %s" % (func.__name__, args, kwargs))
            res = func(self, *args, **kwargs)
            if index < 0 or len(args) <= index or args[index] != '2':
                log.instance().logger().debug("EVENT INIT")
                self.event = QEventLoop()
                self.params = {}
                self.result = {}

            self.event.exec_()
            self.result['res'] = res
            return self.result  # 콜백 결과 반환
示例#10
0
    def commKwRqData(self,
                     codes,
                     codeCount,
                     requestName,
                     screenNo,
                     inquiry=0,
                     typeFlag=0):
        """
        복수종목조회 메서드(관심종목조회 메서드라고도 함).
        이 메서드는 setInputValue() 메서드를 이용하여, 사전에 필요한 값을 지정하지 않는다.
        단지, 메서드의 매개변수에서 직접 종목코드를 지정하여 호출하며,
        데이터 수신은 receiveTrData() 이벤트에서 아래 명시한 항목들을 1회 수신하며,
        이후 receiveRealData() 이벤트를 통해 실시간 데이터를 얻을 수 있다.
        복수종목조회 TR 코드는 OPTKWFID 이며, 요청 성공시 아래 항목들의 정보를 얻을 수 있다.
        종목코드, 종목명, 현재가, 기준가, 전일대비, 전일대비기호, 등락율, 거래량, 거래대금,
        체결량, 체결강도, 전일거래량대비, 매도호가, 매수호가, 매도1~5차호가, 매수1~5차호가,
        상한가, 하한가, 시가, 고가, 저가, 종가, 체결시간, 예상체결가, 예상체결량, 자본금,
        액면가, 시가총액, 주식수, 호가시간, 일자, 우선매도잔량, 우선매수잔량,우선매도건수,
        우선매수건수, 총매도잔량, 총매수잔량, 총매도건수, 총매수건수, 패리티, 기어링, 손익분기,
        잔본지지, ELW행사가, 전환비율, ELW만기일, 미결제약정, 미결제전일대비, 이론가,
        내재변동성, 델타, 감마, 쎄타, 베가, 로
        :param codes: string - 한번에 100종목까지 조회가능하며 종목코드사이에 세미콜론(;)으로 구분.
        :param inquiry: int - api 문서는 bool 타입이지만, int로 처리(0: 조회, 1: 남은 데이터 이어서 조회)
        :param codeCount: int - codes에 지정한 종목의 갯수.
        :param requestName: string
        :param screenNo: string
        :param typeFlag: int - 주식과 선물옵션 구분(0: 주식, 3: 선물옵션), 주의: 매개변수의 위치를 맨 뒤로 이동함.
        :return: list - 중첩 리스트 [[종목코드, 종목명 ... 종목 정보], [종목코드, 종목명 ... 종목 정보]]
        """

        if not (isinstance(codes, str) and isinstance(inquiry, int) and
                isinstance(codeCount, int) and isinstance(requestName, str)
                and isinstance(screenNo, str) and isinstance(typeFlag, int)):
            raise ParameterTypeError()

        res = self.dynamicCall(
            "CommKwRqData(QString, QBoolean, int, int, QString, QString)",
            codes, inquiry, codeCount, typeFlag, requestName, screenNo)
        log.instance().logger().debug("CommKwRqData RES: {0}".format(res))
        if res < 0:
            log.instance().logger().debug("CommKwRqData RES: {0}".format(
                errors(res)))
            self.event.exit()
示例#11
0
    def get(self):
        """
        Request data must contain
        accno : account number the transaction will happen
        """

        accno = self.get_argument('accno', None)

        # data = tornado.escape.json_decode(self.request.body)
        log.instance().logger().debug("BalanceHandler: incoming")
        # log.instance().logger().debug(data)

        hts = self.hts
        hts.deposit = None
        result = hts.kiwoom_tr_account_balance(accno, "1000")
        while not hts.deposit:
            time.sleep(self.SLEEP_TIME)
        cash = hts.deposit

        result = {}
        result["cash"] = cash

        log.instance().logger().debug("Response to client:")
        log.instance().logger().debug(str(result))
        self.write(json.dumps(result))
示例#12
0
    def kiwoom_tr_recall(self, tr_name, tr_code, screen_no, pre_next):
        time.sleep(3.6)
        time.sleep(self.LONG_SLEEP_TIME)

        log.instance().logger().debug("연속조회")
        if tr_code.lower() == 'OPT10081'.lower():
            log.instance().logger().debug("OPT10081는 안 함")
            # self.kiwoom_tr_daily_stock_info(self.dict_callback_temp[0]["code"], self.dict_callback_temp[len(self.dict_callback_temp)-1]["date"], pre_next, '0')
        elif tr_code.lower() == 'OPT10086'.lower():
            param = self.dict_call_param[tr_code]
            if param:
                # {"종목코드": code, "조회일자": date, "수정주가구분": type, 'last_date': last_date}
                response = self.dict_callback_temp
                last_date = param['last_date']
                selected_list = list(
                    filter(lambda x: (x['date'] < last_date), response))
                if len(selected_list) == 0:
                    self.kiwoom_tr_daily_stock_info_detail(
                        param["종목코드"], param["조회일자"], param['last_date'],
                        pre_next, param["수정주가구분"])
                else:
                    pre_next = '0'

        return pre_next
示例#13
0
    def kiwoom_OnEventConnect(self, nErrCode, **kwargs):
        """로그인 결과 수신
        로그인 성공시 [조건목록 요청]GetConditionLoad() 실행
        :param nErrCode: 0: 로그인 성공, 100: 사용자 정보교환 실패, 101: 서버접속 실패, 102: 버전처리 실패
        :param kwargs:
        :return:
        """
        if nErrCode == 0:
            log.instance().logger().debug("로그인 성공")
        elif nErrCode == 100:
            log.instance().logger().debug("사용자 정보교환 실패")
        elif nErrCode == 101:
            log.instance().logger().debug("서버접속 실패")
        elif nErrCode == 102:
            log.instance().logger().debug("버전처리 실패")

        self.result['result'] = nErrCode
        if self.event is not None:
            self.event.exit()
示例#14
0
 def check_market_state(self, screenId, codes, addType="1"):
     # fid = "10;20;11;12;15;13;14;15;29;567;568;"
     fid = "10;20"
     res = self.dynamicCall(
         "SetRealReg(QString, QString, QString, QString)", screenId, codes,
         fid, addType)
     log.instance().logger().debug(
         "SetRealReg RES: {0} {1} {2} {3} {4}".format(
             res, screenId, codes, fid, addType))
     if res < 0:
         log.instance().logger().debug("SetRealReg RES ERROR: {0}".format(
             errors(res)))
         # self.event.exit()
     else:
         log.instance().logger().debug("SetRealReg RES SUCCESS: {0}".format(
             errors(res)))
         # self.multiEvents[screenId] = QEventLoop()
         # self.multiEvents[screenId].exec_()
         # self.event.exit()
     return res
示例#15
0
 def __init__(self):
     log.instance().logger().debug("Kiwoom_tr_parse_util init")
示例#16
0
    def get_kospi_list(self, today=None, market_type="0"):
        """
            KOSPI 정보만 불러옴
            나중에는 코스닥도 한번
        """
        table_name = 'stock'
        ret = self.dynamicCall("GetCodeListByMarket(QString)", [market_type])
        temp_kospi_code_list = ret.split(';')
        kospi_code_list = []
        kospi_list = []
        if today is None:
            today = datetime.datetime.now().strftime("%Y%m%d")

        for v in temp_kospi_code_list:
            if not v:
                continue
            if int(v[:2]) <= 12:
                kospi_code_list.append(v)

        print(temp_kospi_code_list)
        print(kospi_code_list)
        # return kospi_code_list
        pre = self.db.find(table_name, {'date': today})
        # pre = self.db.find('code', {'date': '20200529'})
        print(len(pre))
        pre_code_list = []
        # { "address": { "$regex": "^S" } }
        codes = []
        if pre is not None:
            for x in pre:
                if 'code' in x.keys():
                    pre_code_list.append(x['code'])

        for code in kospi_code_list:

            if code in pre_code_list:
                log.instance().logger().debug(
                    "IT WAS STORED: {0}".format(code))
                continue

            time.sleep(self.SLEEP_TIME)
            last_price = self.dynamicCall("GetMasterLastPrice(QString)",
                                          [code])
            if last_price == '':
                last_price = 0
            else:
                last_price = int(last_price)

            item = {
                "code":
                code,
                "date":
                today
                # , "name": self.dynamicCall("GetMasterCodeName(QString)", [code])
                # , "stock_count": int(self.dynamicCall("GetMasterListedStockCnt(QString)", [code]))
                # (정상, 투자주의, 투자경고, 투자위험, 투자주의환기종목)
                ,
                "company_state":
                self.dynamicCall("GetMasterConstruction(QString)", [code])
                # , "listing_date": self.dynamicCall("GetMasterListedStockDate(QString)", [code])
                # , "last_price": last_price
                # (정상, 투자주의, 투자경고, 투자위험, 투자주의환기종목)
                ,
                "stock_state":
                self.dynamicCall("GetMasterStockState(QString)", [code])
            }

            time.sleep(self.SLEEP_TIME * 16)
            print("종목 정보: ", item)

            # if '투자주의' in item["stock_state"] or '투자경고' in item["company_state"] or '투자위험' in item["company_state"] or '투자주의환기종목' in item["company_state"]:
            #     continue

            tr_code = self.kiwoom_tr_stock_info(code)['res']
            keys = self.dict_callback.keys()

            count = 0

            while tr_code not in keys and count < 20:
                time.sleep(self.SLEEP_TIME)
                count += 1
                # print("count ", count)

            if count >= 20:
                break

            detail = self.dict_callback.pop(tr_code, None)

            for key, value in detail.items():
                item[key] = value

            if market_type == "0":
                item["market"] = "KS"
            elif market_type == "10":
                item["market"] = "KQ"

            print("종목 상세 정보: ", item)
            kospi_list.append(item)

            self.db.add(table_name, item)

        # self.db.add('code', kospi_list)

        stored_list = self.db.find(table_name, {'date': today})
        # pre = self.db.find('code', {'date': '20200529'})
        # { "address": { "$regex": "^S" } }

        return stored_list
示例#17
0
 def func_wrapper(self, *args, **kwargs):
     log.instance().logger().debug("요청 콜백: %s %s %s" % (func.__name__, args, kwargs))
     func(self, *args, **kwargs)  # 콜백 함수 호출
示例#18
0
        ("/real", RealTimeHandler, dict(SLEEP_TIME=SLEEP_TIME, hts=hts,
                                        db=db)),
        ("/remove", RealTimeRemoveHandler,
         dict(SLEEP_TIME=SLEEP_TIME, hts=hts, db=db)),
        ("/code", StockCodeHandler, dict(SLEEP_TIME=SLEEP_TIME, hts=hts,
                                         db=db)),
        ("/store", FileStoreHandler, dict(db=db))
    ]
    # Autoreload seems troublesome.
    return Application(urls, debug=True, autoreload=False)


if __name__ == "__main__":
    # login
    if hts.kiwoom_GetConnectState() != 0:
        log.instance().logger().debug('Connection failed')
        sys.exit()

    log.instance().logger().debug('로그인 시도')
    res = hts.kiwoom_CommConnect()
    if res.get('result') != 0:
        log.instance().logger().debug('Login failed')
        sys.exit()

    # To see list of your accounts...
    if True:
        accounts = hts.kiwoom_GetAccList()
        log.instance().logger().debug("Your accounts:")
        for acc in accounts:
            log.instance().logger().debug(acc)
示例#19
0
    def kiwoom_OnReceiveTrData(self, screen_no, tr_name, tr_code, record_name,
                               pre_next, data_length, error_code, message,
                               sSPlmMsg, **kwargs):
        """TR 요청에 대한 결과 수신 데이터 얻어오기 위해 내부에서 GetCommData() 호출
          GetCommData(
          BSTR tr_code,   // TR 이름
          BSTR tr_name,   // 레코드이름
          long nIndex,      // TR반복부
          BSTR strItemName) // TR에서 얻어오려는 출력항목이름
        :param screen_no: 화면번호
        :param tr_name: 사용자 구분명
        :param tr_code: TR이름
        :param record_name: 레코드 이름
        :param pre_next: 연속조회 유무를 판단하는 값 0: 연속(추가조회)데이터 없음, 2:연속(추가조회) 데이터 있음
        :param data_length: 사용안함
        :param error_code: 사용안함
        :param message: 사용안함
        :param sSPlmMsg: 사용안함
        :param kwargs:
        :return:
        """
        log.instance().logger().debug("TR name : {0} | code : {1}".format(
            tr_name, tr_code))
        if tr_name == "예수금상세현황요청":
            self.deposit = int(
                self.kiwoom_GetCommData(tr_code, tr_name, 0, "주문가능금액"))
            log.instance().logger().debug("예수금상세현황요청: %s" % (self.deposit, ))
            if "예수금상세현황요청" in self.dict_callback:
                self.dict_callback["예수금상세현황요청"](self.deposit)

        response = None

        if self.code.in_code(tr_name):
            code_info = self.code.get_code_info(tr_name)
            if 'output' in code_info.keys():
                response = self.get_single_response(tr_code, tr_name, pre_next,
                                                    code_info)
            elif 'output_list' in code_info.keys():
                response = self.get_multi_response(tr_code, tr_name, pre_next,
                                                   code_info)

        # 임시 코드
        if tr_code.lower() == 'OPT10081'.lower():
            pre_next = '0'

        if isinstance(response, (dict)):
            self.dict_callback[tr_name] = response
            self.dict_callback_temp = None
        elif isinstance(response, (list)) and len(response) == 0:
            if self.dict_callback_temp is None:
                self.dict_callback[tr_name] = []
            else:
                self.dict_callback[tr_name] = self.dict_callback_temp.copy()
                self.dict_callback_temp = None
            pre_next = '0'
        elif pre_next == '0':
            if self.dict_callback_temp is None:
                self.dict_callback[tr_name] = response
            else:
                prev = self.dict_callback_temp.copy()
                self.dict_callback_temp = None
                prev.extend(response)
                self.dict_callback[tr_name] = prev
        elif pre_next == '':
            log.instance().logger().debug("다음이 없음")
        else:
            if self.dict_callback_temp is None:
                self.dict_callback_temp = response
            else:
                self.dict_callback_temp.extend(response)

            pre_next = self.kiwoom_tr_recall(tr_name, tr_code, screen_no,
                                             pre_next)

            if pre_next == '0':
                if self.dict_callback_temp:
                    temp = self.dict_callback_temp.copy()
                    self.dict_callback_temp = None
                    self.dict_callback[tr_name] = temp
                else:
                    self.dict_callback[tr_name] = []

        if self.event and pre_next != '2':
            self.event.exit()
示例#20
0
 def clear_market_state(self, screen=""):
     res = self.dynamicCall("DisconnectRealData(QString)", screen)
     res = 1
     log.instance().logger().debug(
         "DisconnectRealData RES: {0}".format(res))
示例#21
0
 def remove_real(self):
     res = self.dynamicCall("SetRealRemove(QString, QString)", "ALL", "ALL")
     log.instance().logger().debug("SetRealRemove RES: {0}".format(res))
示例#22
0
 def set_input(self, data):
     for key, value in data.items():
         log.instance().logger().debug("K : {0} | V : {1}".format(
             key, value))
         self.kiwoom_SetInputValue(key, value)