| | |
| | | import logging |
| | | import multiprocessing |
| | | import threading |
| | | import time |
| | | |
| | | import qcvalueaddproapi |
| | | from log_module.log import logger_system |
| | | from utils import tool |
| | | |
| | | global g_userid, g_passwd, g_address, g_port, g_seqnum |
| | | g_seqnum = 100000 |
| | | from datetime import datetime |
| | | |
| | | |
| | | def new_seqnum(): |
| | |
| | | def __create_request_id(self): |
| | | return new_seqnum() |
| | | |
| | | def queryTradeCalendar(self): |
| | | def __query_trade_calendar(self, start_date, end_date, page_locate=1, page_count=200): |
| | | """ |
| | | 查询交易日历 |
| | | @param start_date: 格式:20241201 |
| | | @param end_date: 格式:20241201 |
| | | @param page_locate: |
| | | @param page_count: |
| | | @return: 返回日期[顺序] |
| | | """ |
| | | try: |
| | | queryField = qcvalueaddproapi.CQCVDReqQryShareCalendarField() |
| | | # queryField.BegDate = "20240704" |
| | | queryField.EndDate = "20240904" |
| | | queryField.PageCount = 10 |
| | | queryField.PageLocate = 1 |
| | | if queryField.BegDate: |
| | | queryField.BegDate = start_date |
| | | queryField.EndDate = end_date |
| | | queryField.PageCount = page_count |
| | | queryField.PageLocate = page_locate |
| | | queryField.OrderType = qcvalueaddproapi.QCVD_ORDST_ASC |
| | | if queryField.EndDate: |
| | | queryField.OrderType = qcvalueaddproapi.QCVD_ORDST_DESC |
| | | |
| | | request_id = self.__create_request_id() |
| | | results = self.m_api.ReqReqQryShareCalendar(queryField, request_id) |
| | | for i in range(0, 1000): |
| | | if request_id in self.__result_cache: |
| | | return self.__result_cache |
| | | return self.__result_cache[request_id] |
| | | time.sleep(0.002) |
| | | print("ReqReqQryShareCalendar:", results) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | return [] |
| | | |
| | | def queryBars(self, code, begin_date, end_date): |
| | | def queryTradeCalendar(self, start_date, end_date): |
| | | """ |
| | | 查询交易日历 |
| | | @return: |
| | | """ |
| | | fresults = [] |
| | | try: |
| | | page_locate = 1 |
| | | for i in range(20): |
| | | results = self.__query_trade_calendar(start_date.replace("-", ""), end_date.replace("-", ""), |
| | | page_locate=page_locate) |
| | | if results: |
| | | fresults.extend(results) |
| | | if len(results) != 200: |
| | | break |
| | | page_locate += 1 |
| | | print("queryTradeCalendar:", len(fresults)) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | return fresults |
| | | |
| | | def __query_bars(self, code, begin_date, end_date, page_locate=1, page_count=200): |
| | | queryField = qcvalueaddproapi.CQCVDReqQryStockDayQuotationField() |
| | | |
| | | queryField.BegDate = begin_date.replace("-", "") |
| | | queryField.EndDate = end_date.replace("-", "") |
| | | if tool.is_sh_code(code): |
| | |
| | | else: |
| | | queryField.ExchangeID = qcvalueaddproapi.QCVD_EXD_SZSE |
| | | queryField.SecurityID = code |
| | | # queryField.PageCount = 10 |
| | | queryField.PageLocate = 1 |
| | | queryField.PageCount = page_count |
| | | queryField.PageLocate = page_locate |
| | | queryField.OrderType = qcvalueaddproapi.QCVD_ORDST_DESC |
| | | |
| | | request_id = self.__create_request_id() |
| | | results = self.m_api.ReqReqQryStockDayQuotation(queryField, request_id) |
| | | # 读取结果 |
| | | for i in range(0, 1000): |
| | | # 读取结果 |
| | | if request_id in self.__result_cache: |
| | | results = self.__result_cache[request_id] |
| | | return results |
| | | time.sleep(0.002) |
| | | return [] |
| | | |
| | | def queryBars(self, code, begin_date, end_date): |
| | | """ |
| | | 获取历史K线(包含起止日期) |
| | | @param code: |
| | | @param begin_date: 例如:2024-10-31 |
| | | @param end_date: 例如:2024-11-30 |
| | | @param page_locate: 第几页(从第一页开始) |
| | | @return: |
| | | """ |
| | | try: |
| | | |
| | | page_locate = 1 |
| | | final_results = [] |
| | | for i in range(20): |
| | | # 最多翻20页 |
| | | results = self.__query_bars(code, begin_date, end_date, page_locate) |
| | | if results: |
| | | final_results.extend(results) |
| | | if len(results) != 200: |
| | | break |
| | | else: |
| | | page_locate += 1 |
| | | |
| | | # 最新的复权因子 |
| | | start_adjust_factor = None |
| | | for i in range(0, len(results)): |
| | | d = results[i] |
| | | for i in range(0, len(final_results)): |
| | | d = final_results[i] |
| | | if not start_adjust_factor: |
| | | start_adjust_factor = d["AdjustFactor"] |
| | | # 复权价格 |
| | |
| | | d["LowPrice"] = round(d["AdjustFactor"] * d["LowPrice"] / start_adjust_factor, 4) |
| | | d["ClosePrice"] = round(d["AdjustFactor"] * d["ClosePrice"] / start_adjust_factor, 4) |
| | | fresults = [] |
| | | for r in results: |
| | | for r in final_results: |
| | | fresults.append({"sec_id": r["SecurityID"], |
| | | "open": r["TradingDay"], |
| | | "open": r["OpenPrice"], |
| | | "high": r["HighPrice"], |
| | | "low": r["LowPrice"], |
| | | "close": r["ClosePrice"], |
| | | "volume": r["Volume"], |
| | | "pre_close": r["PreClosePrice"], |
| | | "bob": f"{r['TradingDay'][:4]}-{r['TradingDay'][4:6]}-{r['TradingDay'][6:]} 00:00:00", |
| | | "bob": datetime.strptime(r['TradingDay'], '%Y%m%d'), |
| | | "amount": r["Turnover"] |
| | | }) |
| | | print("ReqReqQryStockDayQuotation:", len(fresults)) |
| | | return fresults |
| | | time.sleep(0.002) |
| | | print("ReqReqQryStockDayQuotation:", results) |
| | | |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | |
| | |
| | | nRequestID, |
| | | pRspInfo.ErrorID, |
| | | pRspInfo.ErrorMsg)) |
| | | if (pRspInfo.ErrorID == 0): |
| | | if pRspInfo.ErrorID == 0: |
| | | logger_system.info("华鑫增值服务API登录成功") |
| | | # 登录成功后直接查询 |
| | | # self.ReqInquiryHistoryDelivery() |
| | | # threading.Thread(target=lambda : print("交易日历:", self.queryTradeCalendar())).start() |
| | | threading.Thread(target=lambda: print("日K:", self.queryBars())).start() |
| | | # threading.Thread(target=lambda: print("交易日历:", self.queryTradeCalendar("2024-03-08", "2024-12-31"))).start() |
| | | # threading.Thread( |
| | | # target=lambda: print("日K:", self.queryBars("601298", "2024-12-15", "2024-12-31"))).start() |
| | | |
| | | def ReqQryGGTEODPrices(self): |
| | | QryField = qcvalueaddproapi.CQCVDQryGGTEODPricesField() |
| | |
| | | if nRequestID not in self.__temp_cache: |
| | | self.__temp_cache[nRequestID] = [] |
| | | |
| | | print("是否本页查询完毕:", bIsPageLast) |
| | | # print("是否本页查询完毕:", bIsPageLast) |
| | | |
| | | if not bIsPageLast: |
| | | self.__temp_cache[nRequestID].append({ |
| | |
| | | print("OnRspInquiryStockDayQuotation:", len(self.__result_cache[nRequestID])) |
| | | |
| | | |
| | | def main(): |
| | | # if (len(sys.argv)< 5): |
| | | # ######运行命令行: |
| | | # ###### ip地址 端口号 用户名 密码 |
| | | # print("usage: ipaddress port userid passwd") |
| | | # return |
| | | def __read_request(request_queue: multiprocessing.Queue, response_queue: multiprocessing.Queue): |
| | | |
| | | def __set_response_data(request_id, response_data): |
| | | response_queue.put_nowait({"request_id": request_id, "data": response_data}) |
| | | |
| | | while True: |
| | | try: |
| | | val = request_queue.get() |
| | | type_ = val['type'] |
| | | request_id = val['request_id'] |
| | | data = val.get('data') |
| | | if type_ == 'get_trade_calendar': |
| | | # 获取交易日历 |
| | | start_date = data['start_date'] |
| | | end_date = data['end_date'] |
| | | results = thespi.queryTradeCalendar(start_date, end_date) |
| | | __set_response_data(request_id, results) |
| | | elif type_ == 'get_history_k_bars': |
| | | # 获取历史K线 |
| | | start_date = data['start_date'] |
| | | end_date = data['end_date'] |
| | | code = data['code'] |
| | | results = thespi.queryBars(code, start_date, end_date) |
| | | __set_response_data(request_id, results) |
| | | except: |
| | | pass |
| | | |
| | | |
| | | def run(request_queue: multiprocessing.Queue, response_queue: multiprocessing.Queue): |
| | | """ |
| | | 运行 |
| | | @param request_queue: 请求队列 |
| | | @param response_queue: 响应队列 |
| | | @return: |
| | | """ |
| | | global g_userid, g_passwd, g_address, g_port |
| | | g_address = "101.230.90.99" |
| | | g_port = 25556 |
| | |
| | | # 用户可使用回测traderapi的RegisterFront函数来注册此地址去连接上回测服务器 |
| | | print("GetApiVersion():", qcvalueaddproapi.CQCValueAddProApi_GetApiVersion()) |
| | | theapi = qcvalueaddproapi.CQCValueAddProApi_CreateInfoQryApi() |
| | | global thespi |
| | | thespi = sampleSpi(theapi) |
| | | theapi.RegisterSpi(thespi) |
| | | theapi.RegisterFront(g_address, g_port) |
| | | threading.Thread(target=__read_request, args=(request_queue, response_queue, ), daemon=True).start() |
| | | theapi.Run() |
| | | return |
| | | |
| | | |
| | | def main(): |
| | | request_queue, response_queue = multiprocessing.Queue(), multiprocessing.Queue() |
| | | run(request_queue, response_queue) |
| | | |
| | | |
| | | if __name__ == '__main__': |