From 6df8d9ac75a041377c01c80e6e970e5c75ce7662 Mon Sep 17 00:00:00 2001 From: Administrator <admin@example.com> Date: 星期五, 06 六月 2025 17:33:41 +0800 Subject: [PATCH] 初始化导入 --- trade/huaxin/huaxin_trade_order_processor.py | 186 + strategy/test.py | 33 strategy/data_analyzer.py | 122 huaxin_client/command_manager.py | 4 api/outside_api_command_manager.py | 273 ++ trade/huaxin/huaxin_trade_api.py | 733 +++++ strategy/data_downloader.py | 18 strategy/低吸脚本_辨识度.py | 25 server/data_server.py | 1048 ------- strategy/低吸脚本_辨识度_v6.py | 157 + strategy/今日量是否足够.py | 43 strategy/low_suction_strategy.py | 16 main.py | 59 third_data/hx_qc_value_util.py | 1 strategy/低吸脚本_辨识度_v2.py | 96 strategy/低吸脚本_辨识度_v4.py | 101 strategy/env_info.py | 48 trade/huaxin/huaxin_trade_data_update.py | 138 + code_attribute/zyltgb_util.py | 1 third_data/kpl_data_constant.py | 3 strategy/time_series_backtest.py | 623 +++ third_data/kpl_api.py | 38 strategy/strategy_variable_factory.py | 412 +++ third_data/third_blocks_manager.py | 124 /dev/null | 686 ----- huaxin_client/l2_market_client.py | 133 trade/trade_manager.py | 168 + huaxin_client/trade_client.py | 24 trade/trade_constant.py | 56 strategy/strategy_variable.py | 37 trade/trade_data_manager.py | 489 +++ strategy/strategy_params_settings.py | 75 strategy/低吸脚本_辨识度_v3.py | 122 lev2mdapi.py | 1166 ++++++++ log_module/log.py | 6 strategy/低吸脚本_辨识度_v5.py | 83 trade/huaxin/huaxin_trade_record_manager.py | 488 +++ 37 files changed, 5,830 insertions(+), 2,005 deletions(-) diff --git a/api/outside_api_command_manager.py b/api/outside_api_command_manager.py new file mode 100644 index 0000000..ba16e7a --- /dev/null +++ b/api/outside_api_command_manager.py @@ -0,0 +1,273 @@ +""" +澶栭儴鎺ュ彛绠$悊 +""" +import json +import logging +import random +import socket +import threading +import time + +# 蹇冭烦淇℃伅 +from huaxin_client import socket_util +from huaxin_client.client_network import SendResponseSkManager +from log_module.log import logger_system, logger_request_api +from utils import middle_api_protocol, tool + +MSG_TYPE_HEART = "heart" +# 鍛戒护淇℃伅 +MSG_TYPE_CMD = "cmd" + +CLIENT_TYPE_TRADE = "trade_low_suction" + +# 蹇冭烦鏃堕棿闂撮殧 +HEART_SPACE_TIME = 3 + +TRADE_DIRECTION_BUY = 1 +TRADE_DIRECTION_SELL = 2 + +TRADE_TYPE_ORDER = 1 +TRADE_TYPE_CANCEL_ORDER = 2 + +# 鏁版嵁鎿嶄綔 +OPERRATE_SET = 1 # 璁剧疆 +OPERRATE_DELETE = 2 # 鍒犻櫎 +OPERRATE_GET = 3 # 鑾峰彇 +OPERRATE_ADD = 4 # 鏂板 + +# 浠g爜鍚嶅崟绫诲瀷 +CODE_LIST_WHITE = "white" +CODE_LIST_BLACK = "black" +CODE_LIST_WANT = "want" +CODE_LIST_PAUSE_BUY = "pause_buy" +CODE_LIST_MUST_BUY = "must_buy" +CODE_LIST_GREEN = "green" + +# 绫诲瀷 +API_TYPE_TRADE = "trade" # 浜ゆ槗 +API_TYPE_TRADE_STATE = "trade_state" # 浜ゆ槗鐘舵�� +API_TYPE_TRADE_MODE = "trade_mode" # 浜ゆ槗妯″紡 +API_TYPE_SELL_RULE = "sell_rule" # 鍗栧嚭瑙勫垯 +API_TYPE_CODE_LIST = "code_list" # 浠g爜鍚嶅崟 +API_TYPE_EXPORT_L2 = "export_l2" # 瀵煎嚭L2鏁版嵁 +API_TYPE_INIT = "init" # 鍒濆鍖� +API_TYPE_REFRESH_TRADE_DATA = "refresh_trade_data" # 浜ゆ槗鏁版嵁鍒锋柊 +API_TYPE_CODE_ATRRIBUTE = "code_attribute" # 浠g爜灞炴�� +API_TYPE_CODE_TRADE_STATE = "code_trade_state" # 浠g爜浜ゆ槗鐘舵�� +API_TYPE_GET_ENV = "get_env" # 鑾峰彇鐜淇℃伅 +API_TYPE_SYNC_L1_TARGET_CODES = "sync_l1_subscript_codes" # 鍚屾L1闇�瑕佽闃呯殑浠g爜 +API_TYPE_SYSTEM_LOG = "system_log" # 绯荤粺鏃ュ織 +API_TYPE_GET_FROM_DATA_SERVER = "get_from_data_server" # 浠庢暟鎹湇鍔″櫒鎷夊彇鏁版嵁 +API_TYPE_CODE_TRADE_INFO = "code_trade_info" # 浠g爜浜ゆ槗淇℃伅 +API_TYPE_CODE_L2_LISTEN_ACTIVE_COUNT = "l2_listen_active_count" # L2鏈夋晥鐩戝惉鏁伴噺 +API_TYPE_SAVE_RUNNING_DATA = "save_running_data" # 淇濆瓨杩愯鏃舵暟鎹� +API_TYPE_GET_CODE_POSITION_INFO = "get_code_position_info" # 鑾峰彇浠g爜鎸佷粨淇℃伅 +API_TYPE_COMMON_REQUEST = "common_request" # 閫氱敤璇锋眰 + + +class ActionCallback(object): + # 浜ゆ槗 + def OnTrade(self, client_id, request_id, data): + pass + + # 浜ゆ槗鐘舵�� + def OnTradeState(self, client_id, request_id, data): + pass + + # 浜ゆ槗妯″紡 + def OnTradeMode(self, client_id, request_id, data): + pass + + # 鍗栧嚭瑙勫垯 + def OnSellRule(self, client_id, request_id, data): + pass + + # 浠g爜鍚嶅崟 + def OnCodeList(self, client_id, request_id, data): + pass + + def OnExportL2(self, client_id, request_id, data): + pass + + def OnEveryDayInit(self, client_id, request_id, data): + pass + + def OnRefreshTradeData(self, client_id, request_id, data): + pass + + def OnGetCodeAttribute(self, client_id, request_id, data): + pass + + def OnGetCodeTradeState(self, client_id, request_id, data): + pass + + def OnGetEnvInfo(self, client_id, request_id, data): + pass + + def OnSyncL2SubscriptCodes(self, client_id, request_id): + pass + + def OnGetFromDataServer(self, client_id, request_id, data): + pass + + # 浠g爜鐨勪氦鏄撲俊鎭� + def OnGetCodeTradeInfo(self, client_id, request_id, data): + pass + + def OnGetActiveListenCount(self, client_id, request_id): + pass + + def OnSaveRunningData(self, client_id, request_id): + pass + + def OnGetCodePositionInfo(self, client_id, request_id, data): + pass + + def OnCommonRequest(self, client_id, request_id, data): + pass + + +# 浜ゆ槗鎸囦护绠$悊 +# 浜ゆ槗鎸囦护绠$悊 +@tool.singleton +class ApiCommandManager: + trade_ls_client_dict = {} + trade_ls_client_count = 0 + + def __init__(self, addr, port, trade_action_callback, trade_ls_client_count=20): + self.trade_ls_client_dict.clear() + self.trade_ls_client_count = trade_ls_client_count + self.action_callback = trade_action_callback + self.ip_port = (addr, port) + + for i in range(trade_ls_client_count): + result = self.__create_and_run_client(CLIENT_TYPE_TRADE, i) + self.trade_ls_client_dict[result[0]] = result[1] + + def __create_client(self, client_type, rid): + client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 鐢熸垚socket锛岃繛鎺erver + # client.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, True) + # client.ioctl(socket.SIO_KEEPALIVE_VALS, (1, 60 * 1000, 30 * 1000)) + client.connect(self.ip_port) + client.send(SendResponseSkManager.format_response( + json.dumps({"type": "register", "data": {"client_type": client_type}, "rid": rid}).encode("utf-8"))) + client.recv(1024) + return client + + def __create_and_run_client(self, type, index=None): + key = f"{type}_{round(time.time() * 1000)}_{random.randint(0, 1000)}" + if index is not None: + key += f"_{index}" + sk = self.__create_client(type, key) + # 鍙戦�佸績璺� + self.__heartbeats_thread(type, key, sk) + self.__listen_command_thread(type, key, sk) + # print("create_and_run_client success", type, key) + logger_request_api.info(f"鍒涘缓鏈湴socket璇锋眰瀹㈡埛绔細{type}") + return key, sk + + # 鍚彇鎸囦护 + def __listen_command(self, _type, client_id, sk): + while True: + try: + result = socket_util.recv_data(sk)[0] + if result: + start_time = time.time() + try: + print("鎺ユ敹鏁版嵁", _type, result) + result_json = json.loads(result) + if result_json["type"] == MSG_TYPE_HEART: + # 杩斿洖鍐呭 + sk.send(json.dumps({"type": "heart", "client_id": client_id}).encode('utf-8')) + continue + + data = result_json["data"] + content_type = data["type"] + # print("鎺ユ敹鍐呭", data) + request_id = result_json.get('request_id') + if not socket_util.is_client_params_sign_right(result_json): + # print("绛惧悕閿欒") + # 绛惧悕鍑洪敊 + SendResponseSkManager.send_error_response(_type, request_id, client_id, + {"code": -1, "msg": "绛惧悕閿欒"}) + continue + if content_type == API_TYPE_COMMON_REQUEST: + self.action_callback.OnCommonRequest(client_id, request_id, data) + except Exception as e: + logging.exception(e) + finally: + use_time = int(time.time() - start_time) + if use_time > 5: + result_json = json.loads(result) + logger_request_api.info(f"瓒呮椂5s浠ヤ笂锛歿result_json['data']['type']}") + # 鍙戦�佸搷搴� + sk.send(json.dumps({"type": "cmd_recieve"}).encode('utf-8')) + else: + raise Exception("鎺ユ敹鐨勫唴瀹逛负绌�") + + except Exception as e: + logging.exception(e) + if _type == CLIENT_TYPE_TRADE: + if client_id in self.trade_ls_client_dict: + self.trade_ls_client_dict.pop(client_id) + try: + sk.close() + except: + pass + # 缁撴潫褰撳墠鐨勬秷鎭惊鐜� + break + + def __heart_beats(self, _type, client_id, sk): + while True: + try: + sk.send(socket_util.load_header(json.dumps({"type": "heart", "client_id": client_id}).encode('utf-8'))) + # print("蹇冭烦淇℃伅鍙戦�佹垚鍔�", client_id) + except Exception as e: + if _type == CLIENT_TYPE_TRADE: + if client_id in self.trade_ls_client_dict: + self.trade_ls_client_dict.pop(client_id) + try: + sk.close() + except: + pass + # 缁撴潫褰撳墠鐨勬秷鎭惊鐜� + break + time.sleep(HEART_SPACE_TIME) + + def __listen_command_thread(self, _type, rid, sk): + t1 = threading.Thread(target=lambda: self.__listen_command(_type, rid, sk)) + t1.setDaemon(True) + t1.start() + + def __heartbeats_thread(self, _type, rid, sk): + t1 = threading.Thread(target=lambda: self.__heart_beats(_type, rid, sk)) + t1.setDaemon(True) + t1.start() + + def __maintain_client(self): + logger_system.info(f"outside_api __maintain_client 绾跨▼ID:{tool.get_thread_id()}") + while True: + try: + if len(self.trade_ls_client_dict) < self.trade_ls_client_count: + for i in range(self.trade_ls_client_count - len(self.trade_ls_client_dict)): + result = self.__create_and_run_client(CLIENT_TYPE_TRADE) + self.trade_ls_client_dict[result[0]] = result[1] + except: + pass + time.sleep(1) + + # 缁存姢杩炴帴鏁扮殑绋冲畾 + def run(self, blocking=True): + # 缁存姢client + if blocking: + self.__maintain_client() + else: + t1 = threading.Thread(target=lambda: self.__maintain_client()) + t1.setDaemon(True) + t1.start() + + +if __name__ == "__main__": + manager = ApiCommandManager(middle_api_protocol.SERVER_HOST, middle_api_protocol.SERVER_PORT, ActionCallback()) + manager.run() + input() diff --git a/code_attribute/zyltgb_util.py b/code_attribute/zyltgb_util.py index ae076b9..b2ffdc9 100644 --- a/code_attribute/zyltgb_util.py +++ b/code_attribute/zyltgb_util.py @@ -1,6 +1,5 @@ import threading -from huaxin_client import l1_subscript_codes_manager from third_data import history_k_data_util, kpl_api from db import redis_manager_delegate as redis_manager from db.mysql_data_delegate import Mysqldb diff --git a/huaxin_client/command_manager.py b/huaxin_client/command_manager.py index 3996510..f9ff2ba 100644 --- a/huaxin_client/command_manager.py +++ b/huaxin_client/command_manager.py @@ -11,8 +11,6 @@ import zmq -from huaxin_client import socket_util -from huaxin_client.client_network import SendResponseSkManager from log_module import async_log_util from log_module.log import logger_local_huaxin_trade_debug, logger_trade, logger_local_huaxin_contact_debug @@ -69,7 +67,7 @@ class TradeCommandManager: trade_client_dict = {} _instance = None - process_command_thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=30) + process_command_thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=20) def __new__(cls, *args, **kwargs): if not cls._instance: diff --git a/huaxin_client/l1_client.py b/huaxin_client/l1_client.py deleted file mode 100644 index 54082e1..0000000 --- a/huaxin_client/l1_client.py +++ /dev/null @@ -1,329 +0,0 @@ -# -*- coding: utf-8 -*- -import json -import logging -import multiprocessing -import os -import threading -import time - -from huaxin_client import socket_util, l1_subscript_codes_manager -import xmdapi -from huaxin_client import tool, constant -from log_module.log import logger_system, logger_local_huaxin_l1, logger_l2_codes_subscript, logger_debug -from third_data import custom_block_in_money_manager -from utils import tool as out_tool - -################B绫�################## -ADDRESS = "udp://224.224.1.19:7880" - -################A绫�################## -if constant.IS_A: - ADDRESS = "udp://224.224.1.9:7880" - -level1_data_dict = { - -} - - -def __send_response(sk, msg): - msg = socket_util.load_header(msg) - sk.sendall(msg) - result, header_str = socket_util.recv_data(sk) - if result: - result_json = json.loads(result) - if result_json.get("code") == 0: - return True - return False - - -class MdSpi(xmdapi.CTORATstpXMdSpi): - def __init__(self, api, codes_sh, codes_sz): - for i in range(3): - try: - self.codes_sh, self.codes_sz = codes_sh, codes_sz - break - except: - time.sleep(2) - xmdapi.CTORATstpXMdSpi.__init__(self) - self.__api = api - - def OnFrontConnected(self): - print("OnFrontConnected") - - # 璇锋眰鐧诲綍锛岀洰鍓嶆湭鏍¢獙鐧诲綍鐢ㄦ埛锛岃姹傚煙缃┖鍗冲彲 - login_req = xmdapi.CTORATstpReqUserLoginField() - self.__api.ReqUserLogin(login_req, 1) - - def subscribe_codes(self, codes_sh, codes_sz): - # 閲嶆柊璁㈤槄浠g爜 - if codes_sh: - ret = self.__api.SubscribeMarketData(codes_sh, xmdapi.TORA_TSTP_EXD_SSE) - if ret != 0: - # print('SubscribeMarketData fail, ret[%d]' % ret) - pass - else: - # print('SubscribeMarketData success, ret[%d]' % ret) - pass - - if codes_sz: - ret = self.__api.SubscribeMarketData(codes_sz, xmdapi.TORA_TSTP_EXD_SZSE) - if ret != 0: - # print('SubscribeMarketData fail, ret[%d]' % ret) - pass - else: - # print('SubscribeMarketData success, ret[%d]' % ret) - pass - - def OnRspUserLogin(self, pRspUserLoginField, pRspInfoField, nRequestID): - if pRspInfoField.ErrorID == 0: - # print('Login success! [%d]' % nRequestID) - - ''' - 璁㈤槄琛屾儏 - 褰搒ub_arr涓彧鏈変竴涓�"00000000"鐨勫悎绾︿笖ExchangeID濉玊ORA_TSTP_EXD_SSE鎴朤ORA_TSTP_EXD_SZSE鏃讹紝璁㈤槄鍗曞競鍦烘墍鏈夊悎绾﹁鎯� - 褰搒ub_arr涓彧鏈変竴涓�"00000000"鐨勫悎绾︿笖ExchangeID濉玊ORA_TSTP_EXD_COMM鏃讹紝璁㈤槄鍏ㄥ競鍦烘墍鏈夊悎绾﹁鎯� - 鍏跺畠鎯呭喌锛岃闃卻ub_arr闆嗗悎涓殑鍚堢害琛屾儏 - ''' - - self.subscribe_codes(self.codes_sh, self.codes_sz) - # sub_arr = [b'600004'] - # ret = self.__api.UnSubscribeMarketData(sub_arr, xmdapi.TORA_TSTP_EXD_SSE) - # if ret != 0: - # print('UnSubscribeMarketData fail, ret[%d]' % ret) - # else: - # print('SubscribeMarketData success, ret[%d]' % ret) - - - else: - pass - # print('Login fail!!! [%d] [%d] [%s]' - # % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg)) - - def OnRspSubMarketData(self, pSpecificSecurityField, pRspInfoField): - if pRspInfoField.ErrorID == 0: - # print('OnRspSubMarketData: OK!') - pass - else: - # print('OnRspSubMarketData: Error! [%d] [%s]' - # % (pRspInfoField.ErrorID, pRspInfoField.ErrorMsg)) - pass - - def OnRspUnSubMarketData(self, pSpecificSecurityField, pRspInfoField): - if pRspInfoField.ErrorID == 0: - # print('OnRspUnSubMarketData: OK!') - pass - else: - pass - # print('OnRspUnSubMarketData: Error! [%d] [%s]' - # % (pRspInfoField.ErrorID, pRspInfoField.ErrorMsg)) - - def OnRtnMarketData(self, pMarketDataField): - if pMarketDataField.SecurityName.find("S") == 0: - return - if pMarketDataField.SecurityName.find("ST") >= 0: - return - close_price = pMarketDataField.PreClosePrice - lastPrice = pMarketDataField.LastPrice - if pMarketDataField.BidPrice1: - lastPrice = pMarketDataField.BidPrice1 - rate = round((lastPrice - close_price) * 100 / close_price, 2) - if out_tool.get_limit_up_rate(pMarketDataField.SecurityID) > 1.1001: - # 娑ㄥ仠鏉�20%浠ヤ笂鐨勬墦鎶� - rate = rate / 2 - # (浠g爜, 鐜颁环, 娑ㄥ箙, 閲�, 褰撳墠鏃堕棿, 涔�1浠�, 涔�1閲�, 涔�2浠�, 涔�2閲�, 鏇存柊鏃堕棿) - level1_data_dict[pMarketDataField.SecurityID] = ( - pMarketDataField.SecurityID, pMarketDataField.LastPrice, rate, pMarketDataField.Volume, time.time(), - pMarketDataField.BidPrice1, pMarketDataField.BidVolume1, pMarketDataField.BidPrice2, - pMarketDataField.BidVolume2, pMarketDataField.UpdateTime) - - -__latest_subscript_codes = set() - - -def __upload_codes_info(queue_l1_w_strategy_r: multiprocessing.Queue, datas): - if not tool.is_trade_time() and not tool.is_pre_trade_time(): - return - # 涓婁紶鏁版嵁 - type_ = "set_target_codes" - request_id = f"sb_{int(time.time() * 1000)}" - fdata = json.dumps( - {"type": type_, "data": {"data": datas}, "request_id": request_id, "time": round(time.time() * 1000, 0)}) - if queue_l1_w_strategy_r is not None: - queue_l1_w_strategy_r.put_nowait(fdata) - # 璁板綍鏂板鍔犵殑浠g爜 - codes = set([x[0] for x in datas]) - add_codes = codes - __latest_subscript_codes - __latest_subscript_codes.clear() - for c in codes: - __latest_subscript_codes.add(c) - if add_codes: - logger_local_huaxin_l1.info(f"({request_id})鏂板鍔犺闃呯殑浠g爜锛歿add_codes}") - - -# 閲嶆柊璁㈤槄浠g爜 -def re_subscript(spi: MdSpi): - try: - codes_sh, codes_sz = l1_subscript_codes_manager.request_l1_subscript_target_codes() - if len(codes_sh) > 100 and len(codes_sz) > 100: - logger_local_huaxin_l1.info(f"閲嶆柊璁㈤槄 sh-{len(codes_sh)} sz-{len(codes_sz)}") - spi.subscribe_codes(codes_sh, codes_sz) - except: - pass - - -__position_codes = set() - - -def __read_from_strategy(queue_l1_r_strategy_w: multiprocessing.Queue): - while True: - try: - data = queue_l1_r_strategy_w.get() - if type(data) == str: - data = json.loads(data) - if data["type"] == "set_position_codes": - codes = set(data["data"]) - global __position_codes - __position_codes = codes - logger_local_huaxin_l1.info(f"鏀跺埌绛栫暐娑堟伅锛歿data}", ) - except: - pass - finally: - time.sleep(1) - - -def __run_subscript_task(spi): - """ - 杩愯璁㈤槄浠诲姟锛屽湪9:19鍒�9:29涔嬮棿寮�濮嬭闃� - @return: - """ - is_re_subscript = False - while True: - try: - # 鍒ゆ柇鏄惁闇�瑕侀噸鏂拌闃� - if tool.is_pre_trade_time(): - re_subscript(spi) - is_re_subscript = True - if is_re_subscript: - break - except: - pass - finally: - time.sleep(3) - - -def run(queue_l1_w_strategy_r, queue_l1_r_strategy_w, fixed_codes=None): - """ - 杩愯l1璁㈤槄浠诲姟 - - @param queue_l1_w_strategy_r: L1鏂瑰啓锛岀瓥鐣ユ柟璇� - @param queue_l1_r_strategy_w: L1鏂硅锛岀瓥鐣ユ柟鍐� - @param fixed_codes: 鍥哄畾瑕佽繑鍥炴暟鎹殑浠g爜 - @return: - """ - if fixed_codes is None: - fixed_codes = set() - logger_local_huaxin_l1.info(f"杩愯l1璁㈤槄鏈嶅姟锛屽浐瀹氫唬鐮侊細{fixed_codes}") - codes_sh = [] - codes_sz = [] - for i in range(15): - try: - logger_local_huaxin_l1.info("寮�濮嬭幏鍙栫洰鏍囦唬鐮�") - codes_sh, codes_sz = l1_subscript_codes_manager.get_codes() - logger_local_huaxin_l1.info(f"鑾峰彇涓婅瘉锛屾繁璇佷唬鐮佹暟閲忥細sh-{len(codes_sh)} sz-{len(codes_sz)}") - break - except Exception as e: - logger_local_huaxin_l1.exception(e) - time.sleep(4) - logger_system.info(f"鑾峰彇L1璁㈤槄鐩爣绁ㄦ暟閲忥細sh-{len(codes_sh)} sz-{len(codes_sz)}") - # 鎵撳嵃鎺ュ彛鐗堟湰鍙� - print(xmdapi.CTORATstpXMdApi_GetApiVersion()) - - # 鍒涘缓鎺ュ彛瀵硅薄 - api = xmdapi.CTORATstpXMdApi_CreateTstpXMdApi(xmdapi.TORA_TSTP_MST_MCAST) - - # 鍒涘缓鍥炶皟瀵硅薄 - spi = MdSpi(api, codes_sh, codes_sz) - - # 娉ㄥ唽鍥炶皟鎺ュ彛 - api.RegisterSpi(spi) - - # 娉ㄥ唽鍗曚釜琛屾儏鍓嶇疆鏈嶅姟鍦板潃 - # api.RegisterFront("tcp://210.14.72.16:9402") - # 娉ㄥ唽澶氫釜琛屾儏鍓嶇疆鏈嶅姟鍦板潃锛岀敤閫楀彿闅斿紑 - # api.RegisterFront("tcp://10.0.1.101:6402,tcp://10.0.1.101:16402") - # 娉ㄥ唽鍚嶅瓧鏈嶅姟鍣ㄥ湴鍧�锛屾敮鎸佸鏈嶅姟鍦板潃閫楀彿闅斿紑 - # api.RegisterNameServer('tcp://224.224.3.19:7888') - # api.RegisterNameServer('tcp://10.0.1.101:52370,tcp://10.0.1.101:62370') - - # -------------------------姝e紡鍦板潃B绫�------------------------------- - api.RegisterMulticast(ADDRESS, None, "") - - # -------------------------姝e紡鍦板潃A绫�------------------------------- - # api.RegisterMulticast("udp://224.224.1.9:7880", None, "") - - # 鍚姩鎺ュ彛 - api.Init() - - logger_system.info("L1璁㈤槄鏈嶅姟鍚姩鎴愬姛") - # 娴嬭瘯閾捐矾 - # level1_data_dict["000969"] = ( - # "000969", 9.46, 9.11, 771000*100, time.time()) - # level1_data_dict["002292"] = ( - # "002292", 8.06, 9.96, 969500 * 100, time.time()) - - threading.Thread(target=__read_from_strategy, args=(queue_l1_r_strategy_w,), daemon=True).start() - - threading.Thread(target=__run_subscript_task, args=(spi,), daemon=True).start() - - # 绛夊緟绋嬪簭缁撴潫 - while True: - # print("鏁伴噺", len(level1_data_dict)) - try: - if len(level1_data_dict) < 1: - continue - # 鏍规嵁娑ㄥ箙鎺掑簭 - - # (浠g爜,鐜颁环,娑ㄥ箙,閲�,鏃堕棿) - list_ = [level1_data_dict[k] for k in level1_data_dict] - flist = [] - now_time_int = int(tool.get_now_time_str().replace(":", "")) - threshold_rate = constant.L1_MIN_RATE - for d in list_: - if d[2] >= threshold_rate or d[0] in fixed_codes: - # 娑ㄥ箙灏忎簬3%鐨勯渶瑕佸垹闄� - flist.append(d) - flist.sort(key=lambda x: x[2], reverse=True) - # 灏嗗浐瀹氫唬鐮佺殑鎺掑湪鏈�鍓� - for code in fixed_codes: - if code in level1_data_dict: - flist.insert(0, level1_data_dict[code]) - # 姝e紡浜ゆ槗涔嬪墠鍏堝鐞嗘瘮杈冨皯鐨勬暟鎹紝涓嶇劧澶勭悊鏃堕棿涔呴�犳垚鏁版嵁鎷ュ牭 - MAX_COUNT = 500 - if now_time_int < int("092600"): - MAX_COUNT = 200 - elif now_time_int < int("092800"): - MAX_COUNT = 300 - elif now_time_int < int("092900"): - MAX_COUNT = 400 - datas = flist[:MAX_COUNT] - if len(datas) > 0: - logger_l2_codes_subscript.info("寮�濮�#鍗庨懌L1涓婁紶浠g爜锛氭暟閲�-{}", len(datas)) - __upload_codes_info(queue_l1_w_strategy_r, datas) - except Exception as e: - logging.exception(e) - logger_debug.exception(e) - finally: - time.sleep(3) - - # 閲婃斁鎺ュ彛瀵硅薄 - api.Release() - - -def run_async(pipe_l2): - logger_system.info("L1杩涚▼ID锛歿}", os.getpid()) - t1 = threading.Thread(target=lambda: run(pipe_l2), daemon=True) - t1.start() - - -if __name__ == "__main__": - pass diff --git a/huaxin_client/l2_client.py b/huaxin_client/l2_client.py deleted file mode 100644 index 5876188..0000000 --- a/huaxin_client/l2_client.py +++ /dev/null @@ -1,740 +0,0 @@ -# -*- coding: utf-8 -*- -import json -import logging -import multiprocessing -import os -import queue -import threading -import time -import concurrent.futures - -from huaxin_client import command_manager -from huaxin_client import constant -from huaxin_client import l2_data_manager -import lev2mdapi -from huaxin_client.code_queue_distribute_manager import CodeDataCallbackDistributeManager -from huaxin_client.command_manager import L2ActionCallback -from huaxin_client.l2_data_manager import L2DataUploadManager -from log_module import log, async_log_util -from log_module.async_log_util import huaxin_l2_log -from log_module.log import logger_local_huaxin_l2_subscript, logger_system, logger_l2_codes_subscript, logger_debug -from utils import tool - -###B绫�### -Front_Address = "tcp://10.0.1.101:6900" -Multicast_Address = "udp://224.224.2.19:7889" -Multicast_Address2 = "udp://224.224.224.234:7890" -Local_Interface_Address = constant.LOCAL_IP - -###A绫�### -if constant.IS_A: - Front_Address = "tcp://10.0.1.101:6900" - Multicast_Address = "udp://224.224.22.3:8889" - Multicast_Address2 = "udp://224.224.224.231:4889" - Local_Interface_Address = "172.16.22.111" - -g_SubMarketData = False -g_SubTransaction = False -g_SubOrderDetail = False -g_SubXTSTick = False -g_SubXTSMarketData = False -g_SubNGTSTick = False -g_SubBondMarketData = False -g_SubBondTransaction = False -g_SubBondOrderDetail = False - -SH_Securities = [b"603000", b"600225", b"600469", b"600616", b"600059", b"002849", b"605188", b"603630", b"600105", - b"603773", b"603915", b"603569", b"603322", b"603798", b"605198", b"603079", b"600415", b"600601"] -SH_XTS_Securities = [b"018003", b"113565"] - -SZ_Securities = [b"002456", b"002849", b"002281", b"002336", b"000936", b"000920", b"000757", b"002896", b"002725", - b"000952", b"000526", b"000753", b"000681", b"002088", b"002436"] -SZ_Bond_Securities = [b"100303", b"109559", b"112617"] -set_codes_data_queue = queue.Queue(maxsize=1000) - -ENABLE_NGST = True - - -class Lev2MdSpi(lev2mdapi.CTORATstpLev2MdSpi): - latest_codes_set = set() - - special_code_volume_for_order_dict = {} - # 宸茬粡璁㈤槄鐨勪唬鐮� - subscripted_codes = set() - # 浠g爜鐨勪笂娆℃垚浜ょ殑璁㈠崟鍞竴绱㈠紩 - __last_transaction_keys_dict = {} - - # 涔板叆鐨勫ぇ鍗曡鍗曞彿 - - def __init__(self, api, l2_data_upload_manager: L2DataUploadManager): - lev2mdapi.CTORATstpLev2MdSpi.__init__(self) - self.__api = api - self.is_login = False - self.l2_data_upload_manager = l2_data_upload_manager - self.codes_volume_and_price_dict = {} - - def __split_codes(self, codes): - szse_codes = [] - sse_codes = [] - for code in codes: - market_type = tool.get_market_type(code) - if market_type == tool.MARKET_TYPE_SZSE: - szse_codes.append(code.encode()) - elif market_type == tool.MARKET_TYPE_SSE: - sse_codes.append(code.encode()) - return sse_codes, szse_codes - - # 鏂板璁㈤槄 - - # 鍙栨秷璁㈤槄 - def __unsubscribe(self, _codes): - sh, sz = self.__split_codes(_codes) - logger_local_huaxin_l2_subscript.info(f"鍙栨秷璁㈤槄涓婅瘉锛歿sh}") - logger_local_huaxin_l2_subscript.info(f"鍙栨秷璁㈤槄娣辫瘉锛歿sz}") - if sh: - if ENABLE_NGST: - result = self.__api.UnSubscribeNGTSTick(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - logger_local_huaxin_l2_subscript.info(f"閫愮瑪NGTS璁㈤槄缁撴灉sh锛歿result}") - else: - # 鍙栨秷璁㈤槄閫愮瑪濮旀墭 - self.__api.UnSubscribeOrderDetail(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - # 鍙栨秷璁㈤槄閫愮瑪鎴愪氦 - self.__api.UnSubscribeTransaction(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - self.__api.UnSubscribeMarketData(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - if sz: - self.__api.UnSubscribeOrderDetail(sz, lev2mdapi.TORA_TSTP_EXD_SZSE) - self.__api.UnSubscribeTransaction(sz, lev2mdapi.TORA_TSTP_EXD_SZSE) - self.__api.UnSubscribeMarketData(sz, lev2mdapi.TORA_TSTP_EXD_SZSE) - - def subscribe_codes(self, _codes): - self.__subscribe(_codes) - - def __subscribe(self, _codes): - sh, sz = self.__split_codes(_codes) - logger_local_huaxin_l2_subscript.info(f"璁㈤槄涓婅瘉锛歿sh}") - logger_local_huaxin_l2_subscript.info(f"璁㈤槄娣辫瘉锛歿sz}") - if sh: - if ENABLE_NGST: - result = self.__api.SubscribeNGTSTick(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - logger_local_huaxin_l2_subscript.info(f"閫愮瑪NGTS璁㈤槄缁撴灉sh锛歿result}") - else: - # 璁㈤槄閫愮瑪濮旀墭 - result = self.__api.SubscribeOrderDetail(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - logger_local_huaxin_l2_subscript.info(f"閫愮瑪濮旀墭璁㈤槄缁撴灉sh锛歿result}") - # 璁㈤槄閫愮瑪鎴愪氦 - result = self.__api.SubscribeTransaction(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - logger_local_huaxin_l2_subscript.info(f"閫愮瑪鎴愪氦璁㈤槄缁撴灉sh锛歿result}") - - result = self.__api.SubscribeMarketData(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - logger_local_huaxin_l2_subscript.info(f"甯傚満璁㈤槄缁撴灉sh锛歿result}") - if sz: - result = self.__api.SubscribeOrderDetail(sz, lev2mdapi.TORA_TSTP_EXD_SZSE) - logger_local_huaxin_l2_subscript.info(f"閫愮瑪濮旀墭璁㈤槄缁撴灉sz锛歿result}") - result = self.__api.SubscribeTransaction(sz, lev2mdapi.TORA_TSTP_EXD_SZSE) - logger_local_huaxin_l2_subscript.info(f"閫愮瑪鎴愪氦璁㈤槄缁撴灉sz锛歿result}") - result = self.__api.SubscribeMarketData(sz, lev2mdapi.TORA_TSTP_EXD_SZSE) - logger_local_huaxin_l2_subscript.info(f"甯傚満璁㈤槄缁撴灉sz锛歿result}") - - def __process_codes_data(self, codes_data, from_cache=False, delay=0.0): - - if from_cache and self.codes_volume_and_price_dict: - return - - if not self.is_login and not constant.TEST: - raise Exception("L2灏氭湭鐧诲綍") - if delay > 0: - time.sleep(delay) - codes = set() - for d in codes_data: - code = d[0] - codes.add(code) - self.codes_volume_and_price_dict[code] = (d[1], d[2], d[3], d[4], d[5]) - self.l2_data_upload_manager.set_order_fileter_condition(code, d[1], round(float(d[2]), 2), d[3], d[4], d[5]) - logger_l2_codes_subscript.info("鍗庨懌L2璁㈤槄鎬绘暟锛歿}", len(codes)) - add_codes = codes - self.subscripted_codes - del_codes = self.subscripted_codes - codes - print("add del codes", add_codes, del_codes) - try: - for c in del_codes: - self.l2_data_upload_manager.release_distributed_upload_queue(c) - l2_data_manager.del_target_code(c) - for c in codes: - self.l2_data_upload_manager.distribute_upload_queue(c, codes) - l2_data_manager.add_target_code(c) - except Exception as e: # TODO 娓呴櫎鍘熸潵杩樻病閲婃斁鎺夌殑鏁版嵁 - logger_system.error(f"L2浠g爜鍒嗛厤涓婁紶闃熷垪鍑洪敊:{str(e)}") - logger_system.exception(e) - self.__subscribe(add_codes) - self.__unsubscribe(del_codes) - - if add_codes: - logger_system.info(f"鏂板L2璁㈤槄浠g爜鏁伴噺({'缂撳瓨' if from_cache else ''}):{len(add_codes)}") - for c in add_codes: - logger_l2_codes_subscript.info(f"l2濮旀墭鏁版嵁杩囨护鏉′欢锛歿c} - {self.codes_volume_and_price_dict.get(c)}") - - logger_l2_codes_subscript.info("鍗庨懌L2璁㈤槄缁撴潫锛宎dd-{} del-{}", len(add_codes), len(del_codes)) - - # 璁剧疆鏈�杩戠殑浠g爜鍒楄〃 - self.latest_codes_set = codes - - # 璁㈤槄浠g爜,[(浠g爜,鏈�浣庢墜鏁�,娑ㄥ仠浠�)] - def set_codes_data(self, codes_data): - try: - self.__process_codes_data(codes_data) - except Exception as e: - logger_l2_codes_subscript.exception(e) - finally: - # 淇濆瓨涓�浠芥渶鏂扮殑鏁版嵁 - self.__set_latest_datas(codes_data) - - @classmethod - def __set_latest_datas(cls, codes_data): - data_str = json.dumps([tool.get_now_date_str(), codes_data]) - with open(constant.L2_CODES_INFO_PATH, mode='w') as f: - f.write(data_str) - - @classmethod - def __get_latest_datas(cls): - if os.path.exists(constant.L2_CODES_INFO_PATH): - with open(constant.L2_CODES_INFO_PATH, mode='r') as f: - str_ = f.readline() - data_json = json.loads(str_) - if data_json[0] == tool.get_now_date_str(): - return data_json[1] - return [] - - def OnFrontConnected(self): - print("OnFrontConnected") - logger_system.info(f"l2_client OnFrontConnected 绾跨▼ID:{tool.get_thread_id()}") - logout_req = lev2mdapi.CTORATstpUserLogoutField() - self.__api.ReqUserLogout(logout_req, 1) - time.sleep(1) - # 璇锋眰鐧诲綍 - login_req = lev2mdapi.CTORATstpReqUserLoginField() - self.__api.ReqUserLogin(login_req, 2) - - def OnRspUserLogin(self, pRspUserLogin, pRspInfo, nRequestID, bIsLast): - print("OnRspUserLogin: ErrorID[%d] ErrorMsg[%s] RequestID[%d] IsLast[%d]" % ( - pRspInfo['ErrorID'], pRspInfo['ErrorMsg'], nRequestID, bIsLast)) - if pRspInfo['ErrorID'] == 0: - print("----L2琛屾儏鐧诲綍鎴愬姛----") - self.is_login = True - logger_system.info(f"L2琛屾儏鐧诲綍鎴愬姛") - # 鍒濆璁剧疆鍊� - if tool.trade_time_sub(tool.get_now_time_str(), "09:20:00") > 0: - threading.Thread( - target=lambda: self.__process_codes_data(self.__get_latest_datas(), from_cache=True, delay=60), - daemon=True).start() - - def OnRspSubMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubMarketData") - - def OnRspSubIndex(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubIndex") - - def OnRspSubTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubTransaction") - - def OnRspSubOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubOrderDetail", pRspInfo) - # try: - print("璁㈤槄缁撴灉锛�", pSpecificSecurity["ExchangeID"], pSpecificSecurity["SecurityID"], pRspInfo["ErrorID"], - pRspInfo["ErrorMsg"]) - async_log_util.info(logger_local_huaxin_l2_subscript, - f"璁㈤槄缁撴灉锛歿pSpecificSecurity['SecurityID']} {pRspInfo['ErrorID']} {pRspInfo['ErrorMsg']}") - if pRspInfo["ErrorID"] == 0: - print("璁㈤槄鎴愬姛") - self.subscripted_codes.add(pSpecificSecurity['SecurityID']) - # 鍒濆鍖� - SubscriptDefend.set_l2_market_update(pSpecificSecurity['SecurityID']) - if bIsLast == 1: - print("璁㈤槄鍝嶅簲缁撴潫", self.subscripted_codes) - l2_data_manager.add_subscript_codes(self.subscripted_codes) - - def OnRspUnSubOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspUnSubOrderDetail", bIsLast) - try: - code = pSpecificSecurity['SecurityID'] - self.subscripted_codes.discard(code) - if bIsLast == 1: - print("鍙栨秷璁㈤槄鍝嶅簲缁撴潫", self.subscripted_codes) - l2_data_manager.add_subscript_codes(self.subscripted_codes) - except Exception as e: - logging.exception(e) - - def OnRspSubNGTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - async_log_util.info(logger_local_huaxin_l2_subscript, - f"NGTS璁㈤槄缁撴灉锛歿pSpecificSecurity['SecurityID']} {pRspInfo['ErrorID']} {pRspInfo['ErrorMsg']}") - if pRspInfo["ErrorID"] == 0: - print("璁㈤槄鎴愬姛") - self.subscripted_codes.add(pSpecificSecurity['SecurityID']) - # 鍒濆鍖� - SubscriptDefend.set_l2_market_update(pSpecificSecurity['SecurityID']) - if bIsLast == 1: - print("璁㈤槄鍝嶅簲缁撴潫", self.subscripted_codes) - l2_data_manager.add_subscript_codes(self.subscripted_codes) - - def OnRspUnSubNGTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - try: - code = pSpecificSecurity['SecurityID'] - logger_local_huaxin_l2_subscript.info(f"NGTS鍙栨秷璁㈤槄锛歿code}") - self.subscripted_codes.discard(code) - if bIsLast == 1: - print("鍙栨秷璁㈤槄鍝嶅簲缁撴潫", self.subscripted_codes) - l2_data_manager.add_subscript_codes(self.subscripted_codes) - except Exception as e: - logging.exception(e) - - def OnRspSubBondMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubBondMarketData") - - def OnRspSubBondTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubBondTransaction") - - def OnRspSubBondOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubBondOrderDetail") - - def OnRspSubXTSMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubXTSMarketData") - - def OnRspSubXTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubXTSTick") - - def OnRtnMarketData(self, pDepthMarketData, FirstLevelBuyNum, FirstLevelBuyOrderVolumes, FirstLevelSellNum, - FirstLevelSellOrderVolumes): - # 浼犲叆锛氭椂闂达紝鐜颁环,鎴愪氦鎬婚噺,涔�1锛屼拱2锛屼拱3,涔�4,涔�5,鍗�1,鍗�2,鍗�3,鍗�4,鍗�5 - try: - buys = [(pDepthMarketData['BidPrice1'], pDepthMarketData['BidVolume1']), - (pDepthMarketData['BidPrice2'], pDepthMarketData['BidVolume2']), - (pDepthMarketData['BidPrice3'], pDepthMarketData['BidVolume3']), - (pDepthMarketData['BidPrice4'], pDepthMarketData['BidVolume4']), - (pDepthMarketData['BidPrice5'], pDepthMarketData['BidVolume5'])] - for i in range(6, 11): - if not pDepthMarketData[f"BidVolume{i}"]: - break - buys.append((pDepthMarketData[f'BidPrice{i}'], pDepthMarketData[f'BidVolume{i}'])) - - sells = [ - (pDepthMarketData['AskPrice1'], pDepthMarketData['AskVolume1']), - (pDepthMarketData['AskPrice2'], pDepthMarketData['AskVolume2']), - (pDepthMarketData['AskPrice3'], pDepthMarketData['AskVolume3']), - (pDepthMarketData['AskPrice4'], pDepthMarketData['AskVolume4']), - (pDepthMarketData['AskPrice5'], pDepthMarketData['AskVolume5']) - ] - for i in range(6, 11): - if not pDepthMarketData[f"AskVolume{i}"]: - break - sells.append((pDepthMarketData[f'AskPrice{i}'], pDepthMarketData[f'AskVolume{i}'])) - - d = {"dataTimeStamp": pDepthMarketData['DataTimeStamp'], "securityID": pDepthMarketData['SecurityID'], - "lastPrice": pDepthMarketData['LastPrice'], - "totalVolumeTrade": pDepthMarketData['TotalVolumeTrade'], - "totalValueTrade": pDepthMarketData['TotalValueTrade'], - "totalAskVolume": pDepthMarketData['TotalAskVolume'], - "avgAskPrice": pDepthMarketData["AvgAskPrice"], - "buy": buys, - "sell": sells} - self.l2_data_upload_manager.add_market_data(d) - SubscriptDefend.set_l2_market_update(pDepthMarketData['SecurityID']) - except: - pass - - def OnRtnIndex(self, pIndex): - # 杈撳嚭鎸囨暟琛屾儏鏁版嵁 - print( - "OnRtnIndex SecurityID[%s] LastIndex[%.2f] LowIndex[%.2f] HighIndex[%.2f] TotalVolumeTraded[%d] Turnover[%.2f]" % ( - pIndex['SecurityID'], - pIndex['LastIndex'], - pIndex['LowIndex'], - pIndex['HighIndex'], - pIndex['TotalVolumeTraded'], - pIndex['Turnover'])) - - def OnRtnTransaction(self, pTransaction): - code = str(pTransaction['SecurityID']) - # min_volume, limit_up_price = self.codes_volume_and_price_dict.get(code) - # 杈撳嚭閫愮瑪鎴愪氦鏁版嵁 - if pTransaction['ExecType'] == b"2": - # 鎾ゅ崟 - item = {"SecurityID": pTransaction['SecurityID'], "Price": pTransaction['TradePrice'], - "Volume": pTransaction['TradeVolume'], - "OrderType": "2", - "OrderTime": pTransaction['TradeTime'], "MainSeq": pTransaction['MainSeq'], - "SubSeq": pTransaction['SubSeq'], - "OrderStatus": "D"} - buyNo = pTransaction['BuyNo'] - sellNo = pTransaction['SellNo'] - if buyNo > 0: - # 涔� - item["OrderNO"] = buyNo - item["Side"] = "1" - elif sellNo > 0: - # 鍗� - item["OrderNO"] = sellNo - item["Side"] = "2" - self.l2_data_upload_manager.add_l2_order_detail(item, 0, True) - else: - # if abs(pTransaction['TradePrice'] - limit_up_price) < 0.201: - # 娑ㄥ仠浠� - # 鎴愪氦 - item = {"SecurityID": pTransaction['SecurityID'], "TradePrice": pTransaction['TradePrice'], - "TradeVolume": pTransaction['TradeVolume'], - "OrderTime": pTransaction['TradeTime'], "MainSeq": pTransaction['MainSeq'], - "SubSeq": pTransaction['SubSeq'], "BuyNo": pTransaction['BuyNo'], - "SellNo": pTransaction['SellNo'], - "ExecType": pTransaction['ExecType'].decode()} - # 鏆傛椂娉ㄩ噴鎺夊悓1鍗曞彿鑷冲涓婁紶1娆� - # key = f"{item['SecurityID']}_{item['TradePrice']}_{item['BuyNo']}" - # if self.__last_transaction_keys_dict.get(code) == key: - # return - # self.__last_transaction_keys_dict[code] = key - # print("閫愮瑪鎴愪氦", item) - self.l2_data_upload_manager.add_transaction_detail(item) - - def OnRtnOrderDetail(self, pOrderDetail): - # 涓婅瘉OrderStatus=b"D"琛ㄧず鎾ゅ崟 - item = {"SecurityID": pOrderDetail['SecurityID'], "Price": pOrderDetail['Price'], - "Volume": pOrderDetail['Volume'], - "Side": pOrderDetail['Side'].decode(), "OrderType": pOrderDetail['OrderType'].decode(), - "OrderTime": pOrderDetail['OrderTime'], "MainSeq": pOrderDetail['MainSeq'], - "SubSeq": pOrderDetail['SubSeq'], "OrderNO": pOrderDetail['OrderNO'], - "OrderStatus": pOrderDetail['OrderStatus'].decode()} - self.l2_data_upload_manager.add_l2_order_detail(item, 0) - - def OnRtnNGTSTick(self, pTick): - """ - 涓婅瘉鑲$エ鐨勯�愮瑪濮旀墭涓庢垚浜� - @param pTick: - @return: - """ - try: - if pTick['TickType'] == b'T': - # 鎴愪氦 - item = {"SecurityID": pTick['SecurityID'], "TradePrice": pTick['Price'], - "TradeVolume": pTick['Volume'], - "OrderTime": pTick['TickTime'], "MainSeq": pTick['MainSeq'], - "SubSeq": pTick['SubSeq'], "BuyNo": pTick['BuyNo'], - "SellNo": pTick['SellNo'], - "ExecType": '1'} - self.l2_data_upload_manager.add_transaction_detail(item) - elif pTick['TickType'] == b'A' or pTick['TickType'] == b'D': - # 鎾ゅ崟 - item = {"SecurityID": pTick['SecurityID'], "Price": pTick['Price'], - "Volume": pTick['Volume'], - "Side": pTick['Side'].decode(), "OrderType": pTick['TickType'].decode(), - "OrderTime": pTick['TickTime'], "MainSeq": pTick['MainSeq'], - "SubSeq": pTick['SubSeq'], "OrderNO": '', - "OrderStatus": pTick['TickType'].decode()} - if pTick['Side'] == b'1': - item['OrderNO'] = pTick['BuyNo'] - elif pTick['Side'] == b'2': - item['OrderNO'] = pTick['SellNo'] - self.l2_data_upload_manager.add_l2_order_detail(item, 0) - except Exception as e: - logger_local_huaxin_l2_subscript.exception(e) - - def OnRtnBondMarketData(self, pDepthMarketData, FirstLevelBuyNum, FirstLevelBuyOrderVolumes, FirstLevelSellNum, - FirstLevelSellOrderVolumes): - # 杈撳嚭琛屾儏蹇収鏁版嵁 - print( - "OnRtnBondMarketData SecurityID[%s] LastPrice[%.2f] TotalVolumeTrade[%d] TotalValueTrade[%.2f] BidPrice1[%.2f] BidVolume1[%d] AskPrice1[%.2f] AskVolume1[%d]" % ( - pDepthMarketData['SecurityID'], - pDepthMarketData['LastPrice'], - pDepthMarketData['TotalValueTrade'], - pDepthMarketData['TotalValueTrade'], - pDepthMarketData['BidPrice1'], - pDepthMarketData['BidVolume1'], - pDepthMarketData['AskPrice1'], - pDepthMarketData['AskVolume1'])) - - # 杈撳嚭涓�妗d环浣嶄拱闃熷垪鍓�50绗斿鎵樻暟閲� - for buy_index in range(0, FirstLevelBuyNum): - print("first level buy [%d] : [%d]" % (buy_index, FirstLevelBuyOrderVolumes[buy_index])) - - # 杈撳嚭涓�妗d环浣嶅崠闃熷垪鍓�50绗斿鎵樻暟閲� - for sell_index in range(0, FirstLevelSellNum): - print("first level sell [%d] : [%d]" % (sell_index, FirstLevelSellOrderVolumes[sell_index])) - - def OnRtnBondTransaction(self, pTransaction): - # 杈撳嚭閫愮瑪鎴愪氦鏁版嵁 - print( - "OnRtnBondTransaction SecurityID[%s] TradePrice[%.2f] TradeVolume[%d] TradeTime[%d] MainSeq[%d] SubSeq[%d] BuyNo[%d] SellNo[%d] ExecType[%d]" % ( - pTransaction['SecurityID'], - pTransaction['TradePrice'], - pTransaction['TradeVolume'], - pTransaction['TradeTime'], - pTransaction['MainSeq'], - pTransaction['SubSeq'], - pTransaction['BuyNo'], - pTransaction['SellNo'], - pTransaction['ExecType'], - )) - - def OnRtnBondOrderDetail(self, pOrderDetail): - # 杈撳嚭閫愮瑪濮旀墭鏁版嵁 - print( - "OnRtnBondOrderDetail SecurityID[%s] Price[%.2f] Volume[%d] Side[%s] OrderType[%s] OrderTime[%d] MainSeq[%d] SubSeq[%d]" % ( - pOrderDetail['SecurityID'], - pOrderDetail['Price'], - pOrderDetail['Volume'], - pOrderDetail['Side'], - pOrderDetail['OrderType'], - pOrderDetail['OrderTime'], - pOrderDetail['MainSeq'], - pOrderDetail['SubSeq'])) - - def OnRtnXTSMarketData(self, pDepthMarketData, FirstLevelBuyNum, FirstLevelBuyOrderVolumes, FirstLevelSellNum, - FirstLevelSellOrderVolumes): - # 杈撳嚭琛屾儏蹇収鏁版嵁 - print( - "OnRtnXTSMarketData SecurityID[%s] LastPrice[%.2f] TotalVolumeTrade[%d] TotalValueTrade[%.2f] BidPrice1[%.2f] BidVolume1[%d] AskPrice1[%.2f] AskVolume1[%d]" % ( - pDepthMarketData['SecurityID'], - pDepthMarketData['LastPrice'], - pDepthMarketData['TotalValueTrade'], - pDepthMarketData['TotalValueTrade'], - pDepthMarketData['BidPrice1'], - pDepthMarketData['BidVolume1'], - pDepthMarketData['AskPrice1'], - pDepthMarketData['AskVolume1'])) - - # 杈撳嚭涓�妗d环浣嶄拱闃熷垪鍓�50绗斿鎵樻暟閲� - for buy_index in range(0, FirstLevelBuyNum): - print("first level buy [%d] : [%d]" % (buy_index, FirstLevelBuyOrderVolumes[buy_index])) - - # 杈撳嚭涓�妗d环浣嶅崠闃熷垪鍓�50绗斿鎵樻暟閲� - for sell_index in range(0, FirstLevelSellNum): - print("first level sell [%d] : [%d]" % (sell_index, FirstLevelSellOrderVolumes[sell_index])) - - -class SubscriptDefend: - """ - 璁㈤槄瀹堟姢 - 瀹氫箟锛氬綋璁㈤槄鐨勪唬鐮佽秴杩囦竴瀹氭椂闂存病鏈夊洖璋冩暟鎹椂閲嶆柊璁㈤槄 - """ - __l2_market_update_time = {} - - @classmethod - def set_l2_market_update(cls, code): - cls.__l2_market_update_time[code] = time.time() - - @classmethod - def run(cls): - while True: - try: - now_time = tool.get_now_time_as_int() - if now_time < int("093015"): - continue - if int("112945") < now_time < int("130015"): - continue - if int("145645") < now_time: - continue - if spi.subscripted_codes: - codes = [] - for code in spi.subscripted_codes: - # 鑾峰彇涓婃鏇存柊鏃堕棿 - update_time = cls.__l2_market_update_time.get(code) - if update_time and time.time() - update_time > 15: - # 闇�瑕侀噸鏂拌闃� - codes.append(code) - if codes: - logger_debug.info(f"閲嶆柊璁㈤槄锛歿codes}") - spi.subscribe_codes(codes) - except: - pass - finally: - time.sleep(15) - - -class MyL2ActionCallback(L2ActionCallback): - - def OnSetL2Position(self, codes_data): - huaxin_l2_log.info(logger_l2_codes_subscript, "鍗庨懌L2浠g爜澶勭悊闃熷垪鑾峰彇鍒版暟鎹細鏁伴噺-{}", len(codes_data)) - try: - spi.set_codes_data(codes_data) - except Exception as e: - logging.exception(e) - - -def __init_l2(l2_data_upload_manager): - print(lev2mdapi.CTORATstpLev2MdApi_GetApiVersion()) - # case 1: Tcp鏂瑰紡 - # g_SubMode=lev2mdapi.TORA_TSTP_MST_TCP - # case 2: 缁勬挱鏂瑰紡 - g_SubMode = lev2mdapi.TORA_TSTP_MST_MCAST - - # case 1缂撳瓨妯″紡 - api = lev2mdapi.CTORATstpLev2MdApi_CreateTstpLev2MdApi(g_SubMode, True) - # case 2闈炵紦瀛樻ā寮� - # api = lev2mdapi.CTORATstpLev2MdApi_CreateTstpLev2MdApi(g_SubMode, False) - global spi - spi = Lev2MdSpi(api, l2_data_upload_manager) - api.RegisterSpi(spi) - # -------------------姝e紡妯″紡------------------------------------- - if g_SubMode != lev2mdapi.TORA_TSTP_MST_MCAST: - api.RegisterFront(Front_Address) - else: - # case 1 浠庝竴涓粍鎾湴鍧�鏀跺彇琛屾儏 - api.RegisterMulticast(Multicast_Address, Local_Interface_Address, "") - # api.RegisterMulticast(Multicast_Address2, Local_Interface_Address, "") - - # case 2:娉ㄥ唽澶氫釜缁勬挱鍦板潃鍚屾椂鏀惰鎯� - # api.RegisterMulticast(Multicast_Address, Local_Interface_Address, ""); - # api.RegisterMulticast(Multicast_Address2, Local_Interface_Address, ""); - - # case 3:efvi妯″紡鏀惰鎯� - # api.RegisterMulticast(Multicast_Address, Local_Interface_Address, "", "enp101s0f0",4096, True); - - # case 1 涓嶇粦鏍歌繍琛� - api.Init() - - -__l2_cmd_thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=3) - - -def __receive_from_queue_trade(queue_trade_w_l2_r: multiprocessing.Queue): - logger_system.info(f"l2_client __receive_from_pipe_trade 绾跨▼ID:{tool.get_thread_id()}") - while True: - try: - value = queue_trade_w_l2_r.get() - if value: - if type(value) == bytes: - value = value.decode("utf-8") - data = json.loads(value) - _type = data["type"] - if _type == "l2_cmd": - __start_time = time.time() - # 绾跨▼姹� - __l2_cmd_thread_pool.submit( - lambda: l2CommandManager.process_command(command_manager.CLIENT_TYPE_CMD_L2, None, data)) - use_time = time.time() - __start_time - if use_time > 0.005: - huaxin_l2_log.info(logger_local_huaxin_l2_subscript, f"l2_cmd鑰楁椂锛歿use_time}s") - - except Exception as e: - logging.exception(e) - - -pipe_strategy = None - - -def test_add_codes(queue_r): - time.sleep(10) - # if value: - # if type(value) == bytes: - # value = value.decode("utf-8") - # data = json.loads(value) - # _type = data["type"] - # if _type == "listen_volume": - # volume = data["data"]["volume"] - # code = data["data"]["code"] - # spi.set_code_special_watch_volume(code, volume) - # elif _type == "l2_cmd": - # l2CommandManager.process_command(command_manager.CLIENT_TYPE_CMD_L2, None, data) - - demo_datas = [("603002", int(50 * 10000 / 6.35), 6.35, 6.00, 200), - ("002654", int(50 * 10000 / 15.59), 15.59, 15.3, 200), - ("603701", int(50 * 10000 / 14.28), 14.28, 14.00, 200), - ("002908", int(50 * 10000 / 12.78), 12.78, 12.00, 200)] - - queue_r.put_nowait(json.dumps({"type": "l2_cmd", "data": [demo_datas[0]]})) - time.sleep(10) - while True: - try: - spi.l2_data_upload_manager.add_l2_order_detail( - {'SecurityID': '603002', 'Price': 6.35, 'Volume': 275000, 'Side': "1", 'OrderType': '0', - 'OrderTime': '13000015', - 'MainSeq': 2, 'SubSeq': 6739147, 'OrderNO': 5512466, 'OrderStatus': 'D'}, 0) - spi.l2_data_upload_manager.add_l2_order_detail( - {'SecurityID': '603002', 'Price': 6.35, 'Volume': 200, 'Side': "1", 'OrderType': '0', - 'OrderTime': '13000015', - 'MainSeq': 2, 'SubSeq': 6739148, 'OrderNO': 5512467, 'OrderStatus': 'D'}, 0) - # queue_r.put_nowait(json.dumps({"type": "listen_volume", "data": {"code": "603002", "volume": 100}})) - time.sleep(0.1) - spi.l2_data_upload_manager.add_l2_order_detail( - {'SecurityID': '603002', 'Price': 6.35, 'Volume': 100, 'Side': "1", 'OrderType': '0', - 'OrderTime': '13000015', - 'MainSeq': 2, 'SubSeq': 6739148, 'OrderNO': 5512467, 'OrderStatus': 'D'}, 0) - except Exception as e: - logging.exception(e) - finally: - time.sleep(10) - - -def run(queue_r: multiprocessing.Queue, data_callbacks: list) -> None: - logger_system.info("L2杩涚▼ID锛歿}", os.getpid()) - logger_system.info(f"l2_client 绾跨▼ID:{tool.get_thread_id()}") - try: - log.close_print() - if queue_r is not None: - t1 = threading.Thread(target=lambda: __receive_from_queue_trade(queue_r), daemon=True) - t1.start() - # 璁㈤槄瀹堟姢 - threading.Thread(target=SubscriptDefend.run, daemon=True).start() - # 鍒濆鍖� - data_callback_distribute_manager = CodeDataCallbackDistributeManager(data_callbacks) - l2_data_upload_manager = L2DataUploadManager(data_callback_distribute_manager) - __init_l2(l2_data_upload_manager) - l2_data_manager.run_upload_common() - l2_data_manager.run_log() - # TODO 娴嬭瘯 - # threading.Thread(target=lambda: test_add_codes(queue_r), daemon=True).start() - global l2CommandManager - l2CommandManager = command_manager.L2CommandManager() - l2CommandManager.init(MyL2ActionCallback()) - logger_system.info("L2璁㈤槄鏈嶅姟鍚姩鎴愬姛") - except Exception as e: - logger_system.exception(e) - while True: - time.sleep(2) - - -def test(): - def test_add_codes(): - time.sleep(5) - # if value: - # if type(value) == bytes: - # value = value.decode("utf-8") - # data = json.loads(value) - # _type = data["type"] - # if _type == "listen_volume": - # volume = data["data"]["volume"] - # code = data["data"]["code"] - # spi.set_code_special_watch_volume(code, volume) - # elif _type == "l2_cmd": - # l2CommandManager.process_command(command_manager.CLIENT_TYPE_CMD_L2, None, data) - - demo_datas = [("603002", int(50 * 10000 / 6.35), 6.35), ("002654", int(50 * 10000 / 15.59), 15.59), - ("603701", int(50 * 10000 / 14.28), 14.28), ("002908", int(50 * 10000 / 12.78), 12.78)] - - queue_r.put_nowait(json.dumps({"type": "l2_cmd", "data": [demo_datas[0]]})) - time.sleep(1) - - spi.l2_data_upload_manager.add_l2_order_detail( - {'SecurityID': '603002', 'Price': 6.35, 'Volume': 275000, 'Side': "1", 'OrderType': '0', - 'OrderTime': '13000015', - 'MainSeq': 2, 'SubSeq': 6739147, 'OrderNO': 5512466, 'OrderStatus': 'D'}, 0) - spi.l2_data_upload_manager.add_l2_order_detail( - {'SecurityID': '603002', 'Price': 6.35, 'Volume': 200, 'Side': "1", 'OrderType': '0', - 'OrderTime': '13000015', - 'MainSeq': 2, 'SubSeq': 6739148, 'OrderNO': 5512467, 'OrderStatus': 'D'}, 0) - queue_r.put_nowait(json.dumps({"type": "listen_volume", "data": {"code": "603002", "volume": 100}})) - time.sleep(0.1) - spi.l2_data_upload_manager.add_l2_order_detail( - {'SecurityID': '603002', 'Price': 6.35, 'Volume': 100, 'Side': "1", 'OrderType': '0', - 'OrderTime': '13000015', - 'MainSeq': 2, 'SubSeq': 6739148, 'OrderNO': 5512467, 'OrderStatus': 'D'}, 0) - - queue_r = multiprocessing.Queue(maxsize=1024) - order_queues = [] - transaction_queues = [] - market_queue = multiprocessing.Queue(maxsize=1024) - for i in range(20): - order_queues.append(multiprocessing.Queue(maxsize=1024)) - transaction_queues.append(multiprocessing.Queue(maxsize=1024)) - threading.Thread(target=test_add_codes).start() - - run(queue_r, order_queues, transaction_queues, market_queue) - - -if __name__ == "__main__": - input() diff --git a/huaxin_client/l2_client_test.py b/huaxin_client/l2_client_test.py deleted file mode 100644 index 445715a..0000000 --- a/huaxin_client/l2_client_test.py +++ /dev/null @@ -1,322 +0,0 @@ -# -*- coding: utf-8 -*- -import logging -import multiprocessing -import queue -import time -import lev2mdapi -from log_module import log -from log_module.log import logger_local_huaxin_l2_subscript, logger_system -from utils import tool - -IS_TEST = False - -###B绫�### -Front_Address = "tcp://10.0.1.101:6900" -Multicast_Address = "udp://224.224.2.19:7889" -Multicast_Address2 = "udp://224.224.224.234:7890" -Local_Interface_Address = "192.168.84.126" - -###娴嬭瘯鍦板潃### -if IS_TEST: - Front_Address = "tcp://210.14.72.17:16900" - Multicast_Address = "udp://224.224.2.19:7889" - Multicast_Address2 = "udp://224.224.224.234:7890" - Local_Interface_Address = "192.168.84.126" - -g_SubMarketData = False -g_SubTransaction = False -g_SubOrderDetail = False -g_SubXTSTick = False -g_SubXTSMarketData = False -g_SubNGTSTick = False -g_SubBondMarketData = False -g_SubBondTransaction = False -g_SubBondOrderDetail = False -set_codes_data_queue = queue.Queue(maxsize=10240) -market_code_dict = {} - -ENABLE_NGST = True - - -class L2TransactionDataManager: - def __init__(self, code): - self.code = code - self.__latest_buy_order = None - self.__big_buy_orders = [] - self.__latest_sell_order = None - self.__big_sell_orders = [] - self.big_buy_order_queue = queue.Queue(maxsize=10240) - self.big_sell_order_queue = queue.Queue(maxsize=10240) - - def get_big_buy_orders(self): - return self.__big_buy_orders - - def get_big_sell_orders(self): - return self.__big_sell_orders - - def add_transaction_data(self, data): - item = (data["BuyNo"], data["SellNo"], data["TradePrice"], data["TradeVolume"]) - # item = {"SecurityID": pTransaction['SecurityID'], "TradePrice": pTransaction['TradePrice'], - # "TradeVolume": pTransaction['TradeVolume'], - # "OrderTime": pTransaction['TradeTime'], "MainSeq": pTransaction['MainSeq'], - # "SubSeq": pTransaction['SubSeq'], "BuyNo": pTransaction['BuyNo'], - # "SellNo": pTransaction['SellNo'], - # "ExecType": pTransaction['ExecType'].decode()} - money = round(item[2] * item[3]) - volume = item[3] - price = item[2] - order_time = data["OrderTime"] - if not self.__latest_buy_order: - # (涔板崟鍙�, 閲�, 閲戦, 鏃堕棿, 鏈�鏂版垚浜や环鏍�) - self.__latest_buy_order = [item[0], 0, 0, order_time, price] - if self.__latest_buy_order[0] == item[0]: - self.__latest_buy_order[1] += volume - self.__latest_buy_order[2] += money - self.__latest_buy_order[3] = order_time - self.__latest_buy_order[4] = price - else: - if self.__latest_buy_order[2] > 1e6: - d = (self.__latest_buy_order[0], self.__latest_buy_order[1], self.__latest_buy_order[2], self.__latest_buy_order[3], self.__latest_buy_order[4]) - self.__big_buy_orders.append(d) - self.big_buy_order_queue.put_nowait(d) - - self.__latest_buy_order = [item[0], volume, money, order_time, price] - - if not self.__latest_sell_order: - self.__latest_sell_order = [item[1], 0, 0, order_time, price] - if self.__latest_sell_order[0] == item[1]: - self.__latest_sell_order[1] += volume - self.__latest_sell_order[2] += money - self.__latest_sell_order[3] = order_time - self.__latest_sell_order[4] = price - else: - if self.__latest_sell_order[2] > 1e6: - d = (self.__latest_sell_order[0], self.__latest_sell_order[1], self.__latest_sell_order[2], self.__latest_sell_order[3], self.__latest_sell_order[4]) - self.__big_sell_orders.append(d) - self.big_sell_order_queue.put_nowait(d) - self.__latest_sell_order = [item[1], volume, money, order_time, price] - - -# 涔板叆鐨勫ぇ鍗曡鍗曞彿 -l2_transaction_data_dict = {} - - -class Lev2MdSpi(lev2mdapi.CTORATstpLev2MdSpi): - latest_codes_set = set() - - special_code_volume_for_order_dict = {} - # 宸茬粡璁㈤槄鐨勪唬鐮� - subscripted_codes = set() - # 浠g爜鐨勪笂娆℃垚浜ょ殑璁㈠崟鍞竴绱㈠紩 - __last_transaction_keys_dict = {} - - def __init__(self, api, codes): - lev2mdapi.CTORATstpLev2MdSpi.__init__(self) - self.__api = api - self.is_login = False - self.codes = codes - self.codes_volume_and_price_dict = {} - - def __split_codes(self, codes): - szse_codes = [] - sse_codes = [] - for code in codes: - market_type = tool.get_market_type(code) - if market_type == tool.MARKET_TYPE_SZSE: - szse_codes.append(code.encode()) - elif market_type == tool.MARKET_TYPE_SSE: - sse_codes.append(code.encode()) - return sse_codes, szse_codes - - # 鏂板璁㈤槄 - - # 鍙栨秷璁㈤槄 - def __unsubscribe(self, _codes): - sh, sz = self.__split_codes(_codes) - logger_local_huaxin_l2_subscript.info(f"鍙栨秷璁㈤槄涓婅瘉锛歿sh}") - logger_local_huaxin_l2_subscript.info(f"鍙栨秷璁㈤槄娣辫瘉锛歿sz}") - if sh: - if ENABLE_NGST: - result = self.__api.UnSubscribeNGTSTick(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - logger_local_huaxin_l2_subscript.info(f"閫愮瑪NGTS璁㈤槄缁撴灉sh锛歿result}") - else: - # 鍙栨秷璁㈤槄閫愮瑪鎴愪氦 - self.__api.UnSubscribeTransaction(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - if sz: - self.__api.UnSubscribeTransaction(sz, lev2mdapi.TORA_TSTP_EXD_SZSE) - - def __subscribe(self, _codes): - sh, sz = self.__split_codes(_codes) - logger_local_huaxin_l2_subscript.info(f"璁㈤槄涓婅瘉锛歿sh}") - logger_local_huaxin_l2_subscript.info(f"璁㈤槄娣辫瘉锛歿sz}") - if sh: - if ENABLE_NGST: - result = self.__api.SubscribeNGTSTick(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - logger_local_huaxin_l2_subscript.info(f"閫愮瑪NGTS璁㈤槄缁撴灉sh锛歿result}") - else: - # 璁㈤槄閫愮瑪鎴愪氦 - result = self.__api.SubscribeTransaction(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - logger_local_huaxin_l2_subscript.info(f"閫愮瑪鎴愪氦璁㈤槄缁撴灉sh锛歿result}") - - if sz: - result = self.__api.SubscribeTransaction(sz, lev2mdapi.TORA_TSTP_EXD_SZSE) - logger_local_huaxin_l2_subscript.info(f"閫愮瑪鎴愪氦璁㈤槄缁撴灉sz锛歿result}") - - def OnFrontConnected(self): - print("OnFrontConnected") - logger_system.info(f"l2_client OnFrontConnected 绾跨▼ID:{tool.get_thread_id()}") - logout_req = lev2mdapi.CTORATstpUserLogoutField() - self.__api.ReqUserLogout(logout_req, 1) - time.sleep(1) - # 璇锋眰鐧诲綍 - login_req = lev2mdapi.CTORATstpReqUserLoginField() - self.__api.ReqUserLogin(login_req, 2) - - def OnRspUserLogin(self, pRspUserLogin, pRspInfo, nRequestID, bIsLast): - print("OnRspUserLogin: ErrorID[%d] ErrorMsg[%s] RequestID[%d] IsLast[%d]" % ( - pRspInfo['ErrorID'], pRspInfo['ErrorMsg'], nRequestID, bIsLast)) - if pRspInfo['ErrorID'] == 0: - print("----L2琛屾儏鐧诲綍鎴愬姛----") - self.is_login = True - logger_system.info(f"L2琛屾儏鐧诲綍鎴愬姛") - self.__subscribe(self.codes) - - def OnRspSubMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubMarketData") - - def OnRspSubIndex(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubIndex") - - def OnRspSubTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubTransaction") - if pRspInfo["ErrorID"] == 0: - print("璁㈤槄鎴愬姛") - self.subscripted_codes.add(pSpecificSecurity['SecurityID']) - if bIsLast == 1: - print("璁㈤槄鍝嶅簲缁撴潫", self.subscripted_codes) - - def OnRspSubNGTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - if pRspInfo["ErrorID"] == 0: - print("璁㈤槄鎴愬姛") - self.subscripted_codes.add(pSpecificSecurity['SecurityID']) - if bIsLast == 1: - print("璁㈤槄鍝嶅簲缁撴潫", self.subscripted_codes) - - def OnRspUnSubNGTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - try: - code = pSpecificSecurity['SecurityID'] - logger_local_huaxin_l2_subscript.info(f"NGTS鍙栨秷璁㈤槄锛歿code}") - self.subscripted_codes.discard(code) - if bIsLast == 1: - print("鍙栨秷璁㈤槄鍝嶅簲缁撴潫", self.subscripted_codes) - except Exception as e: - logging.exception(e) - - def OnRtnTransaction(self, pTransaction): - code = str(pTransaction['SecurityID']) - # min_volume, limit_up_price = self.codes_volume_and_price_dict.get(code) - # 杈撳嚭閫愮瑪鎴愪氦鏁版嵁 - if pTransaction['ExecType'] == b"2": - pass - else: - item = {"SecurityID": pTransaction['SecurityID'], "TradePrice": pTransaction['TradePrice'], - "TradeVolume": pTransaction['TradeVolume'], - "OrderTime": pTransaction['TradeTime'], "MainSeq": pTransaction['MainSeq'], - "SubSeq": pTransaction['SubSeq'], "BuyNo": pTransaction['BuyNo'], - "SellNo": pTransaction['SellNo'], - "ExecType": pTransaction['ExecType'].decode()} - if item["SecurityID"] not in l2_transaction_data_dict: - l2_transaction_data_dict[item["SecurityID"]] = L2TransactionDataManager(item["SecurityID"]) - l2_transaction_data_dict[item["SecurityID"]].add_transaction_data(item) - - def OnRtnNGTSTick(self, pTick): - """ - 涓婅瘉鑲$エ鐨勯�愮瑪濮旀墭涓庢垚浜� - @param pTick: - @return: - """ - try: - if pTick['TickType'] == b'T': - # 鎴愪氦 - item = {"SecurityID": pTick['SecurityID'], "TradePrice": pTick['Price'], - "TradeVolume": pTick['Volume'], - "OrderTime": pTick['TickTime'], "MainSeq": pTick['MainSeq'], - "SubSeq": pTick['SubSeq'], "BuyNo": pTick['BuyNo'], - "SellNo": pTick['SellNo'], - "ExecType": '1'} - if item["SecurityID"] not in l2_transaction_data_dict: - l2_transaction_data_dict[item["SecurityID"]] = L2TransactionDataManager(item["SecurityID"]) - l2_transaction_data_dict[item["SecurityID"]].add_transaction_data(item) - except Exception as e: - logger_local_huaxin_l2_subscript.exception(e) - - -def __init_l2(codes): - print(lev2mdapi.CTORATstpLev2MdApi_GetApiVersion()) - # case 1: Tcp鏂瑰紡 - # g_SubMode=lev2mdapi.TORA_TSTP_MST_TCP - # case 2: 缁勬挱鏂瑰紡 - g_SubMode = lev2mdapi.TORA_TSTP_MST_MCAST - if IS_TEST: - g_SubMode = lev2mdapi.TORA_TSTP_MST_TCP - # case 1缂撳瓨妯″紡 - api = lev2mdapi.CTORATstpLev2MdApi_CreateTstpLev2MdApi(g_SubMode, True) - # case 2闈炵紦瀛樻ā寮� - # api = lev2mdapi.CTORATstpLev2MdApi_CreateTstpLev2MdApi(g_SubMode, False) - global spi - spi = Lev2MdSpi(api, codes) - api.RegisterSpi(spi) - # -------------------姝e紡妯″紡------------------------------------- - if g_SubMode != lev2mdapi.TORA_TSTP_MST_MCAST: - api.RegisterFront(Front_Address) - else: - # case 1 浠庝竴涓粍鎾湴鍧�鏀跺彇琛屾儏 - api.RegisterMulticast(Multicast_Address, Local_Interface_Address, "") - # api.RegisterMulticast(Multicast_Address2, Local_Interface_Address, "") - - # case 2:娉ㄥ唽澶氫釜缁勬挱鍦板潃鍚屾椂鏀惰鎯� - # api.RegisterMulticast(Multicast_Address, Local_Interface_Address, ""); - # api.RegisterMulticast(Multicast_Address2, Local_Interface_Address, ""); - - # case 3:efvi妯″紡鏀惰鎯� - # api.RegisterMulticast(Multicast_Address, Local_Interface_Address, "", "enp101s0f0",4096, True); - - # case 1 涓嶇粦鏍歌繍琛� - api.Init() - - -def run(codes, _queue: multiprocessing.Queue) -> None: - try: - log.close_print() - - __init_l2(codes) - logger_system.info(f"L2璁㈤槄鏈嶅姟鍚姩鎴愬姛:") - except Exception as e: - logger_system.exception(e) - while True: - try: - for code in l2_transaction_data_dict: - l2_transaction_data_manager: L2TransactionDataManager = l2_transaction_data_dict[code] - try: - while True: - result = l2_transaction_data_manager.big_buy_order_queue.get(block=False) - if result: - _queue.put_nowait((code, 0, result)) - else: - break - except: - pass - try: - while True: - result = l2_transaction_data_manager.big_sell_order_queue.get(block=False) - if result: - _queue.put_nowait((code, 1, result)) - else: - break - except: - pass - except: - pass - finally: - time.sleep(1) - diff --git a/huaxin_client/l2_client_v2.py b/huaxin_client/l2_client_v2.py deleted file mode 100644 index 2fc263b..0000000 --- a/huaxin_client/l2_client_v2.py +++ /dev/null @@ -1,727 +0,0 @@ -# -*- coding: utf-8 -*- -import json -import logging -import multiprocessing -import os -import queue -import threading -import time -import concurrent.futures - -from huaxin_client import command_manager -from huaxin_client import constant -from huaxin_client import l2_data_manager_v2 -import lev2mdapi -from huaxin_client.code_queue_distribute_manager import CodeDataCallbackDistributeManager, \ - CodeDataChannelDistributeManager -from huaxin_client.command_manager import L2ActionCallback -from huaxin_client.l2_data_manager_v2 import L2DataUploadManager -from log_module import log, async_log_util -from log_module.async_log_util import huaxin_l2_log -from log_module.log import logger_local_huaxin_l2_subscript, logger_system, logger_l2_codes_subscript, logger_debug -from utils import tool - -###B绫�### -Front_Address = "tcp://10.0.1.101:6900" -Multicast_Address = "udp://224.224.2.19:7889" -Multicast_Address2 = "udp://224.224.224.234:7890" -Local_Interface_Address = constant.LOCAL_IP - -###A绫�### -if constant.IS_A: - Front_Address = "tcp://10.0.1.101:6900" - Multicast_Address = "udp://224.224.22.3:8889" - Multicast_Address2 = "udp://224.224.224.231:4889" - Local_Interface_Address = "172.16.22.111" - -ENABLE_NGST = True - - -class Lev2MdSpi(lev2mdapi.CTORATstpLev2MdSpi): - latest_codes_set = set() - - special_code_volume_for_order_dict = {} - # 宸茬粡璁㈤槄鐨勪唬鐮� - subscripted_codes = set() - - # 涔板叆鐨勫ぇ鍗曡鍗曞彿 - - def __init__(self, api, l2_data_upload_manager: L2DataUploadManager, processor_index): - lev2mdapi.CTORATstpLev2MdSpi.__init__(self) - self.__api = api - self.is_login = False - self.l2_data_upload_manager = l2_data_upload_manager - self.codes_volume_and_price_dict = {} - self.processor_index = processor_index - - def __split_codes(self, codes): - szse_codes = [] - sse_codes = [] - for code in codes: - market_type = tool.get_market_type(code) - if market_type == tool.MARKET_TYPE_SZSE: - szse_codes.append(code.encode()) - elif market_type == tool.MARKET_TYPE_SSE: - sse_codes.append(code.encode()) - return sse_codes, szse_codes - - # 鏂板璁㈤槄 - - # 鍙栨秷璁㈤槄 - def __unsubscribe(self, _codes): - sh, sz = self.__split_codes(_codes) - logger_local_huaxin_l2_subscript.info(f"鍙栨秷璁㈤槄涓婅瘉锛歿sh}") - logger_local_huaxin_l2_subscript.info(f"鍙栨秷璁㈤槄娣辫瘉锛歿sz}") - if sh: - if ENABLE_NGST: - result = self.__api.UnSubscribeNGTSTick(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - logger_local_huaxin_l2_subscript.info(f"閫愮瑪NGTS璁㈤槄缁撴灉sh锛歿result}") - else: - # 鍙栨秷璁㈤槄閫愮瑪濮旀墭 - self.__api.UnSubscribeOrderDetail(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - # 鍙栨秷璁㈤槄閫愮瑪鎴愪氦 - self.__api.UnSubscribeTransaction(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - self.__api.UnSubscribeMarketData(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - if sz: - self.__api.UnSubscribeOrderDetail(sz, lev2mdapi.TORA_TSTP_EXD_SZSE) - self.__api.UnSubscribeTransaction(sz, lev2mdapi.TORA_TSTP_EXD_SZSE) - self.__api.UnSubscribeMarketData(sz, lev2mdapi.TORA_TSTP_EXD_SZSE) - - def subscribe_codes(self, _codes): - self.__subscribe(_codes) - - def __subscribe(self, _codes): - sh, sz = self.__split_codes(_codes) - logger_local_huaxin_l2_subscript.info(f"璁㈤槄涓婅瘉({self.processor_index})锛歿sh}") - logger_local_huaxin_l2_subscript.info(f"璁㈤槄娣辫瘉({self.processor_index})锛歿sz}") - if sh: - if ENABLE_NGST: - result = self.__api.SubscribeNGTSTick(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - logger_local_huaxin_l2_subscript.info(f"閫愮瑪NGTS璁㈤槄缁撴灉sh({self.processor_index})锛歿result}") - else: - # 璁㈤槄閫愮瑪濮旀墭 - result = self.__api.SubscribeOrderDetail(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - logger_local_huaxin_l2_subscript.info(f"閫愮瑪濮旀墭璁㈤槄缁撴灉sh({self.processor_index})锛歿result}") - # 璁㈤槄閫愮瑪鎴愪氦 - result = self.__api.SubscribeTransaction(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - logger_local_huaxin_l2_subscript.info(f"閫愮瑪鎴愪氦璁㈤槄缁撴灉sh({self.processor_index})锛歿result}") - - result = self.__api.SubscribeMarketData(sh, lev2mdapi.TORA_TSTP_EXD_SSE) - logger_local_huaxin_l2_subscript.info(f"甯傚満璁㈤槄缁撴灉sh({self.processor_index})锛歿result}") - if sz: - result = self.__api.SubscribeOrderDetail(sz, lev2mdapi.TORA_TSTP_EXD_SZSE) - logger_local_huaxin_l2_subscript.info(f"閫愮瑪濮旀墭璁㈤槄缁撴灉sz({self.processor_index})锛歿result}") - result = self.__api.SubscribeTransaction(sz, lev2mdapi.TORA_TSTP_EXD_SZSE) - logger_local_huaxin_l2_subscript.info(f"閫愮瑪鎴愪氦璁㈤槄缁撴灉sz({self.processor_index})锛歿result}") - result = self.__api.SubscribeMarketData(sz, lev2mdapi.TORA_TSTP_EXD_SZSE) - logger_local_huaxin_l2_subscript.info(f"甯傚満璁㈤槄缁撴灉sz({self.processor_index})锛歿result}") - - def __process_codes_data(self, codes_data, from_cache=False, delay=0.0): - - if from_cache and self.codes_volume_and_price_dict: - return - - if not self.is_login and not constant.TEST: - raise Exception("L2灏氭湭鐧诲綍") - if delay > 0: - time.sleep(delay) - codes = set() - for d in codes_data: - code = d[0] - codes.add(code) - self.codes_volume_and_price_dict[code] = (d[1], d[2], d[3], d[4], d[5]) - self.l2_data_upload_manager.set_order_fileter_condition(code, d[1], round(float(d[2]), 2), d[3], d[4], d[5]) - logger_l2_codes_subscript.info("鍗庨懌L2璁㈤槄鎬绘暟({})锛歿}", self.processor_index, len(codes)) - add_codes = codes - self.subscripted_codes - del_codes = self.subscripted_codes - codes - print("add del codes", add_codes, del_codes) - try: - for c in del_codes: - self.l2_data_upload_manager.release_distributed_upload_queue(c) - l2_data_manager_v2.del_target_code(c) - for c in codes: - self.l2_data_upload_manager.distribute_upload_queue(c, codes) - l2_data_manager_v2.add_target_code(c) - except Exception as e: # TODO 娓呴櫎鍘熸潵杩樻病閲婃斁鎺夌殑鏁版嵁 - logger_system.error(f"L2浠g爜鍒嗛厤涓婁紶闃熷垪鍑洪敊:{str(e)}") - logger_system.exception(e) - self.__subscribe(add_codes) - self.__unsubscribe(del_codes) - - if add_codes: - logger_system.info(f"鏂板L2璁㈤槄浠g爜鏁伴噺({self.processor_index}) ({'缂撳瓨' if from_cache else ''}):{len(add_codes)}") - for c in add_codes: - logger_l2_codes_subscript.info( - f"l2濮旀墭鏁版嵁杩囨护鏉′欢({self.processor_index})锛歿c} - {self.codes_volume_and_price_dict.get(c)}") - - logger_l2_codes_subscript.info("鍗庨懌L2璁㈤槄缁撴潫({})锛宎dd-{} del-{}", self.processor_index, len(add_codes), - len(del_codes)) - - # 璁剧疆鏈�杩戠殑浠g爜鍒楄〃 - self.latest_codes_set = codes - - # 璁㈤槄浠g爜,[(浠g爜,鏈�浣庢墜鏁�,娑ㄥ仠浠�)] - def set_codes_data(self, codes_data): - try: - self.__process_codes_data(codes_data) - except Exception as e: - logger_l2_codes_subscript.exception(e) - finally: - # 淇濆瓨涓�浠芥渶鏂扮殑鏁版嵁 - self.__set_latest_datas(codes_data) - - def __set_latest_datas(self, codes_data): - path_str = f"{constant.L2_CODES_INFO_PATH}_{self.processor_index}" - data_str = json.dumps([tool.get_now_date_str(), codes_data]) - with open(path_str, mode='w') as f: - f.write(data_str) - - def __get_latest_datas(self): - path_str = f"{constant.L2_CODES_INFO_PATH}_{self.processor_index}" - if os.path.exists(path_str): - with open(path_str, mode='r') as f: - str_ = f.readline() - data_json = json.loads(str_) - if data_json[0] == tool.get_now_date_str(): - return data_json[1] - return [] - - def OnFrontConnected(self): - print("OnFrontConnected") - logger_system.info(f"l2_client OnFrontConnected 绾跨▼ID:{tool.get_thread_id()}") - logout_req = lev2mdapi.CTORATstpUserLogoutField() - self.__api.ReqUserLogout(logout_req, 1) - time.sleep(1) - # 璇锋眰鐧诲綍 - login_req = lev2mdapi.CTORATstpReqUserLoginField() - self.__api.ReqUserLogin(login_req, 2) - - def OnRspUserLogin(self, pRspUserLogin, pRspInfo, nRequestID, bIsLast): - print("OnRspUserLogin: ErrorID[%d] ErrorMsg[%s] RequestID[%d] IsLast[%d]" % ( - pRspInfo['ErrorID'], pRspInfo['ErrorMsg'], nRequestID, bIsLast)) - if pRspInfo['ErrorID'] == 0: - print("----L2琛屾儏鐧诲綍鎴愬姛----") - self.is_login = True - logger_system.info(f"L2琛屾儏鐧诲綍鎴愬姛({self.processor_index})") - # 鍒濆璁剧疆鍊� - if tool.trade_time_sub(tool.get_now_time_str(), "09:20:00") > 0: - threading.Thread( - target=lambda: self.__process_codes_data(self.__get_latest_datas(), from_cache=True, delay=60), - daemon=True).start() - - def OnRspSubMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubMarketData") - - def OnRspSubIndex(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubIndex") - - def OnRspSubTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubTransaction") - - def OnRspSubOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubOrderDetail", pRspInfo) - # try: - print(f"璁㈤槄缁撴灉({self.processor_index})锛�", pSpecificSecurity["ExchangeID"], pSpecificSecurity["SecurityID"], - pRspInfo["ErrorID"], - pRspInfo["ErrorMsg"]) - async_log_util.info(logger_local_huaxin_l2_subscript, - f"璁㈤槄缁撴灉({self.processor_index})锛歿pSpecificSecurity['SecurityID']} {pRspInfo['ErrorID']} {pRspInfo['ErrorMsg']}") - if pRspInfo["ErrorID"] == 0: - print("璁㈤槄鎴愬姛") - self.subscripted_codes.add(pSpecificSecurity['SecurityID']) - # 鍒濆鍖� - SubscriptDefend.set_l2_market_update(pSpecificSecurity['SecurityID']) - if bIsLast == 1: - print("璁㈤槄鍝嶅簲缁撴潫", self.subscripted_codes) - l2_data_manager_v2.add_subscript_codes(self.subscripted_codes) - - def OnRspUnSubOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspUnSubOrderDetail", bIsLast) - try: - code = pSpecificSecurity['SecurityID'] - self.subscripted_codes.discard(code) - if bIsLast == 1: - print("鍙栨秷璁㈤槄鍝嶅簲缁撴潫", self.subscripted_codes) - l2_data_manager_v2.add_subscript_codes(self.subscripted_codes) - except Exception as e: - logging.exception(e) - - def OnRspSubNGTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - async_log_util.info(logger_local_huaxin_l2_subscript, - f"NGTS璁㈤槄缁撴灉({self.processor_index})锛歿pSpecificSecurity['SecurityID']} {pRspInfo['ErrorID']} {pRspInfo['ErrorMsg']}") - if pRspInfo["ErrorID"] == 0: - print("璁㈤槄鎴愬姛") - self.subscripted_codes.add(pSpecificSecurity['SecurityID']) - # 鍒濆鍖� - SubscriptDefend.set_l2_market_update(pSpecificSecurity['SecurityID']) - if bIsLast == 1: - print("璁㈤槄鍝嶅簲缁撴潫", self.subscripted_codes) - l2_data_manager_v2.add_subscript_codes(self.subscripted_codes) - - def OnRspUnSubNGTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - try: - code = pSpecificSecurity['SecurityID'] - logger_local_huaxin_l2_subscript.info(f"NGTS鍙栨秷璁㈤槄({self.processor_index})锛歿code}") - self.subscripted_codes.discard(code) - if bIsLast == 1: - print("鍙栨秷璁㈤槄鍝嶅簲缁撴潫", self.subscripted_codes) - l2_data_manager_v2.add_subscript_codes(self.subscripted_codes) - except Exception as e: - logging.exception(e) - - def OnRspSubBondMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubBondMarketData") - - def OnRspSubBondTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubBondTransaction") - - def OnRspSubBondOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubBondOrderDetail") - - def OnRspSubXTSMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubXTSMarketData") - - def OnRspSubXTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): - print("OnRspSubXTSTick") - - def OnRtnMarketData(self, pDepthMarketData, FirstLevelBuyNum, FirstLevelBuyOrderVolumes, FirstLevelSellNum, - FirstLevelSellOrderVolumes): - # 浼犲叆锛氭椂闂达紝鐜颁环,鎴愪氦鎬婚噺,涔�1锛屼拱2锛屼拱3,涔�4,涔�5,鍗�1,鍗�2,鍗�3,鍗�4,鍗�5 - try: - buys = [(pDepthMarketData['BidPrice1'], pDepthMarketData['BidVolume1']), - (pDepthMarketData['BidPrice2'], pDepthMarketData['BidVolume2']), - (pDepthMarketData['BidPrice3'], pDepthMarketData['BidVolume3']), - (pDepthMarketData['BidPrice4'], pDepthMarketData['BidVolume4']), - (pDepthMarketData['BidPrice5'], pDepthMarketData['BidVolume5'])] - for i in range(6, 11): - if not pDepthMarketData[f"BidVolume{i}"]: - break - buys.append((pDepthMarketData[f'BidPrice{i}'], pDepthMarketData[f'BidVolume{i}'])) - - sells = [ - (pDepthMarketData['AskPrice1'], pDepthMarketData['AskVolume1']), - (pDepthMarketData['AskPrice2'], pDepthMarketData['AskVolume2']), - (pDepthMarketData['AskPrice3'], pDepthMarketData['AskVolume3']), - (pDepthMarketData['AskPrice4'], pDepthMarketData['AskVolume4']), - (pDepthMarketData['AskPrice5'], pDepthMarketData['AskVolume5']) - ] - for i in range(6, 11): - if not pDepthMarketData[f"AskVolume{i}"]: - break - sells.append((pDepthMarketData[f'AskPrice{i}'], pDepthMarketData[f'AskVolume{i}'])) - - d = {"dataTimeStamp": pDepthMarketData['DataTimeStamp'], "securityID": pDepthMarketData['SecurityID'], - "lastPrice": pDepthMarketData['LastPrice'], - "totalVolumeTrade": pDepthMarketData['TotalVolumeTrade'], - "totalValueTrade": pDepthMarketData['TotalValueTrade'], - "totalAskVolume": pDepthMarketData['TotalAskVolume'], - "avgAskPrice": pDepthMarketData["AvgAskPrice"], - "buy": buys, - "sell": sells} - self.l2_data_upload_manager.add_market_data(d) - SubscriptDefend.set_l2_market_update(pDepthMarketData['SecurityID']) - except: - pass - - def OnRtnIndex(self, pIndex): - # 杈撳嚭鎸囨暟琛屾儏鏁版嵁 - print( - "OnRtnIndex SecurityID[%s] LastIndex[%.2f] LowIndex[%.2f] HighIndex[%.2f] TotalVolumeTraded[%d] Turnover[%.2f]" % ( - pIndex['SecurityID'], - pIndex['LastIndex'], - pIndex['LowIndex'], - pIndex['HighIndex'], - pIndex['TotalVolumeTraded'], - pIndex['Turnover'])) - - def OnRtnTransaction(self, pTransaction): - code = str(pTransaction['SecurityID']) - # min_volume, limit_up_price = self.codes_volume_and_price_dict.get(code) - # 杈撳嚭閫愮瑪鎴愪氦鏁版嵁 - if pTransaction['ExecType'] == b"2": - # 鎾ゅ崟 - item = {"SecurityID": pTransaction['SecurityID'], "Price": pTransaction['TradePrice'], - "Volume": pTransaction['TradeVolume'], - "OrderType": "2", - "OrderTime": pTransaction['TradeTime'], "MainSeq": pTransaction['MainSeq'], - "SubSeq": pTransaction['SubSeq'], - "OrderStatus": "D"} - buyNo = pTransaction['BuyNo'] - sellNo = pTransaction['SellNo'] - if buyNo > 0: - # 涔� - item["OrderNO"] = buyNo - item["Side"] = "1" - elif sellNo > 0: - # 鍗� - item["OrderNO"] = sellNo - item["Side"] = "2" - self.l2_data_upload_manager.add_l2_order_detail(item, 0, True) - else: - # if abs(pTransaction['TradePrice'] - limit_up_price) < 0.201: - # 娑ㄥ仠浠� - # 鎴愪氦 - item = {"SecurityID": pTransaction['SecurityID'], "TradePrice": pTransaction['TradePrice'], - "TradeVolume": pTransaction['TradeVolume'], - "OrderTime": pTransaction['TradeTime'], "MainSeq": pTransaction['MainSeq'], - "SubSeq": pTransaction['SubSeq'], "BuyNo": pTransaction['BuyNo'], - "SellNo": pTransaction['SellNo'], - "ExecType": pTransaction['ExecType'].decode()} - self.l2_data_upload_manager.add_transaction_detail(item) - - def OnRtnOrderDetail(self, pOrderDetail): - # 涓婅瘉OrderStatus=b"D"琛ㄧず鎾ゅ崟 - item = {"SecurityID": pOrderDetail['SecurityID'], "Price": pOrderDetail['Price'], - "Volume": pOrderDetail['Volume'], - "Side": pOrderDetail['Side'].decode(), "OrderType": pOrderDetail['OrderType'].decode(), - "OrderTime": pOrderDetail['OrderTime'], "MainSeq": pOrderDetail['MainSeq'], - "SubSeq": pOrderDetail['SubSeq'], "OrderNO": pOrderDetail['OrderNO'], - "OrderStatus": pOrderDetail['OrderStatus'].decode()} - self.l2_data_upload_manager.add_l2_order_detail(item, 0) - - def OnRtnNGTSTick(self, pTick): - """ - 涓婅瘉鑲$エ鐨勯�愮瑪濮旀墭涓庢垚浜� - @param pTick: - @return: - """ - try: - if pTick['TickType'] == b'T': - # 鎴愪氦 - item = {"SecurityID": pTick['SecurityID'], "TradePrice": pTick['Price'], - "TradeVolume": pTick['Volume'], - "OrderTime": pTick['TickTime'], "MainSeq": pTick['MainSeq'], - "SubSeq": pTick['SubSeq'], "BuyNo": pTick['BuyNo'], - "SellNo": pTick['SellNo'], - "ExecType": '1'} - self.l2_data_upload_manager.add_transaction_detail(item) - elif pTick['TickType'] == b'A' or pTick['TickType'] == b'D': - # 鎾ゅ崟 - item = {"SecurityID": pTick['SecurityID'], "Price": pTick['Price'], - "Volume": pTick['Volume'], - "Side": pTick['Side'].decode(), "OrderType": pTick['TickType'].decode(), - "OrderTime": pTick['TickTime'], "MainSeq": pTick['MainSeq'], - "SubSeq": pTick['SubSeq'], "OrderNO": '', - "OrderStatus": pTick['TickType'].decode()} - if pTick['Side'] == b'1': - item['OrderNO'] = pTick['BuyNo'] - elif pTick['Side'] == b'2': - item['OrderNO'] = pTick['SellNo'] - self.l2_data_upload_manager.add_l2_order_detail(item, 0) - except Exception as e: - logger_local_huaxin_l2_subscript.exception(e) - - def OnRtnBondMarketData(self, pDepthMarketData, FirstLevelBuyNum, FirstLevelBuyOrderVolumes, FirstLevelSellNum, - FirstLevelSellOrderVolumes): - # 杈撳嚭琛屾儏蹇収鏁版嵁 - print( - "OnRtnBondMarketData SecurityID[%s] LastPrice[%.2f] TotalVolumeTrade[%d] TotalValueTrade[%.2f] BidPrice1[%.2f] BidVolume1[%d] AskPrice1[%.2f] AskVolume1[%d]" % ( - pDepthMarketData['SecurityID'], - pDepthMarketData['LastPrice'], - pDepthMarketData['TotalValueTrade'], - pDepthMarketData['TotalValueTrade'], - pDepthMarketData['BidPrice1'], - pDepthMarketData['BidVolume1'], - pDepthMarketData['AskPrice1'], - pDepthMarketData['AskVolume1'])) - - # 杈撳嚭涓�妗d环浣嶄拱闃熷垪鍓�50绗斿鎵樻暟閲� - for buy_index in range(0, FirstLevelBuyNum): - print("first level buy [%d] : [%d]" % (buy_index, FirstLevelBuyOrderVolumes[buy_index])) - - # 杈撳嚭涓�妗d环浣嶅崠闃熷垪鍓�50绗斿鎵樻暟閲� - for sell_index in range(0, FirstLevelSellNum): - print("first level sell [%d] : [%d]" % (sell_index, FirstLevelSellOrderVolumes[sell_index])) - - def OnRtnBondTransaction(self, pTransaction): - # 杈撳嚭閫愮瑪鎴愪氦鏁版嵁 - print( - "OnRtnBondTransaction SecurityID[%s] TradePrice[%.2f] TradeVolume[%d] TradeTime[%d] MainSeq[%d] SubSeq[%d] BuyNo[%d] SellNo[%d] ExecType[%d]" % ( - pTransaction['SecurityID'], - pTransaction['TradePrice'], - pTransaction['TradeVolume'], - pTransaction['TradeTime'], - pTransaction['MainSeq'], - pTransaction['SubSeq'], - pTransaction['BuyNo'], - pTransaction['SellNo'], - pTransaction['ExecType'], - )) - - def OnRtnBondOrderDetail(self, pOrderDetail): - # 杈撳嚭閫愮瑪濮旀墭鏁版嵁 - print( - "OnRtnBondOrderDetail SecurityID[%s] Price[%.2f] Volume[%d] Side[%s] OrderType[%s] OrderTime[%d] MainSeq[%d] SubSeq[%d]" % ( - pOrderDetail['SecurityID'], - pOrderDetail['Price'], - pOrderDetail['Volume'], - pOrderDetail['Side'], - pOrderDetail['OrderType'], - pOrderDetail['OrderTime'], - pOrderDetail['MainSeq'], - pOrderDetail['SubSeq'])) - - def OnRtnXTSMarketData(self, pDepthMarketData, FirstLevelBuyNum, FirstLevelBuyOrderVolumes, FirstLevelSellNum, - FirstLevelSellOrderVolumes): - # 杈撳嚭琛屾儏蹇収鏁版嵁 - print( - "OnRtnXTSMarketData SecurityID[%s] LastPrice[%.2f] TotalVolumeTrade[%d] TotalValueTrade[%.2f] BidPrice1[%.2f] BidVolume1[%d] AskPrice1[%.2f] AskVolume1[%d]" % ( - pDepthMarketData['SecurityID'], - pDepthMarketData['LastPrice'], - pDepthMarketData['TotalValueTrade'], - pDepthMarketData['TotalValueTrade'], - pDepthMarketData['BidPrice1'], - pDepthMarketData['BidVolume1'], - pDepthMarketData['AskPrice1'], - pDepthMarketData['AskVolume1'])) - - # 杈撳嚭涓�妗d环浣嶄拱闃熷垪鍓�50绗斿鎵樻暟閲� - for buy_index in range(0, FirstLevelBuyNum): - print("first level buy [%d] : [%d]" % (buy_index, FirstLevelBuyOrderVolumes[buy_index])) - - # 杈撳嚭涓�妗d环浣嶅崠闃熷垪鍓�50绗斿鎵樻暟閲� - for sell_index in range(0, FirstLevelSellNum): - print("first level sell [%d] : [%d]" % (sell_index, FirstLevelSellOrderVolumes[sell_index])) - - -class SubscriptDefend: - """ - 璁㈤槄瀹堟姢 - 瀹氫箟锛氬綋璁㈤槄鐨勪唬鐮佽秴杩囦竴瀹氭椂闂存病鏈夊洖璋冩暟鎹椂閲嶆柊璁㈤槄 - """ - __l2_market_update_time = {} - - @classmethod - def set_l2_market_update(cls, code): - cls.__l2_market_update_time[code] = time.time() - - @classmethod - def run(cls): - while True: - try: - now_time = tool.get_now_time_as_int() - if now_time < int("093015"): - continue - if int("112945") < now_time < int("130015"): - continue - if int("145645") < now_time: - continue - if spi.subscripted_codes: - codes = [] - for code in spi.subscripted_codes: - # 鑾峰彇涓婃鏇存柊鏃堕棿 - update_time = cls.__l2_market_update_time.get(code) - if update_time and time.time() - update_time > 15: - # 闇�瑕侀噸鏂拌闃� - codes.append(code) - if codes: - logger_debug.info(f"閲嶆柊璁㈤槄锛歿codes}") - spi.subscribe_codes(codes) - except: - pass - finally: - time.sleep(15) - - -class MyL2ActionCallback(L2ActionCallback): - - def OnSetL2Position(self, codes_data): - huaxin_l2_log.info(logger_l2_codes_subscript, "鍗庨懌L2浠g爜澶勭悊闃熷垪鑾峰彇鍒版暟鎹細鏁伴噺-{}", len(codes_data)) - try: - spi.set_codes_data(codes_data) - except Exception as e: - logging.exception(e) - - -def __init_l2(l2_data_upload_manager, processor_index): - print(lev2mdapi.CTORATstpLev2MdApi_GetApiVersion()) - # case 1: Tcp鏂瑰紡 - # g_SubMode=lev2mdapi.TORA_TSTP_MST_TCP - # case 2: 缁勬挱鏂瑰紡 - g_SubMode = lev2mdapi.TORA_TSTP_MST_MCAST - - # case 1缂撳瓨妯″紡 - api = lev2mdapi.CTORATstpLev2MdApi_CreateTstpLev2MdApi(g_SubMode, True) - # case 2闈炵紦瀛樻ā寮� - # api = lev2mdapi.CTORATstpLev2MdApi_CreateTstpLev2MdApi(g_SubMode, False) - global spi - spi = Lev2MdSpi(api, l2_data_upload_manager, processor_index) - api.RegisterSpi(spi) - # -------------------姝e紡妯″紡------------------------------------- - if g_SubMode != lev2mdapi.TORA_TSTP_MST_MCAST: - api.RegisterFront(Front_Address) - else: - # case 1 浠庝竴涓粍鎾湴鍧�鏀跺彇琛屾儏 - api.RegisterMulticast(Multicast_Address, Local_Interface_Address, "") - # api.RegisterMulticast(Multicast_Address2, Local_Interface_Address, "") - - # case 2:娉ㄥ唽澶氫釜缁勬挱鍦板潃鍚屾椂鏀惰鎯� - # api.RegisterMulticast(Multicast_Address, Local_Interface_Address, ""); - # api.RegisterMulticast(Multicast_Address2, Local_Interface_Address, ""); - - # case 3:efvi妯″紡鏀惰鎯� - # api.RegisterMulticast(Multicast_Address, Local_Interface_Address, "", "enp101s0f0",4096, True); - - # case 1 涓嶇粦鏍歌繍琛� - api.Init() - - -__l2_cmd_thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=3) - - -def __receive_from_queue_trade(queue_trade_w_l2_r: multiprocessing.Queue): - logger_system.info(f"l2_client __receive_from_pipe_trade 绾跨▼ID:{tool.get_thread_id()}") - while True: - try: - value = queue_trade_w_l2_r.get() - if value: - if type(value) == bytes: - value = value.decode("utf-8") - data = json.loads(value) - _type = data["type"] - if _type == "l2_cmd": - __start_time = time.time() - # 绾跨▼姹� - __l2_cmd_thread_pool.submit( - lambda: l2CommandManager.process_command(command_manager.CLIENT_TYPE_CMD_L2, None, data)) - use_time = time.time() - __start_time - if use_time > 0.005: - huaxin_l2_log.info(logger_local_huaxin_l2_subscript, f"l2_cmd鑰楁椂锛歿use_time}s") - - except Exception as e: - logging.exception(e) - - -pipe_strategy = None - - -def test_add_codes(queue_r): - time.sleep(10) - # if value: - # if type(value) == bytes: - # value = value.decode("utf-8") - # data = json.loads(value) - # _type = data["type"] - # if _type == "listen_volume": - # volume = data["data"]["volume"] - # code = data["data"]["code"] - # spi.set_code_special_watch_volume(code, volume) - # elif _type == "l2_cmd": - # l2CommandManager.process_command(command_manager.CLIENT_TYPE_CMD_L2, None, data) - - demo_datas = [("603002", int(50 * 10000 / 6.35), 6.35, 6.00, 200), - ("002654", int(50 * 10000 / 15.59), 15.59, 15.3, 200), - ("603701", int(50 * 10000 / 14.28), 14.28, 14.00, 200), - ("002908", int(50 * 10000 / 12.78), 12.78, 12.00, 200)] - - queue_r.put_nowait(json.dumps({"type": "l2_cmd", "data": [demo_datas[0]]})) - time.sleep(10) - while True: - try: - spi.l2_data_upload_manager.add_l2_order_detail( - {'SecurityID': '603002', 'Price': 6.35, 'Volume': 275000, 'Side': "1", 'OrderType': '0', - 'OrderTime': '13000015', - 'MainSeq': 2, 'SubSeq': 6739147, 'OrderNO': 5512466, 'OrderStatus': 'D'}, 0) - spi.l2_data_upload_manager.add_l2_order_detail( - {'SecurityID': '603002', 'Price': 6.35, 'Volume': 200, 'Side': "1", 'OrderType': '0', - 'OrderTime': '13000015', - 'MainSeq': 2, 'SubSeq': 6739148, 'OrderNO': 5512467, 'OrderStatus': 'D'}, 0) - # queue_r.put_nowait(json.dumps({"type": "listen_volume", "data": {"code": "603002", "volume": 100}})) - time.sleep(0.1) - spi.l2_data_upload_manager.add_l2_order_detail( - {'SecurityID': '603002', 'Price': 6.35, 'Volume': 100, 'Side': "1", 'OrderType': '0', - 'OrderTime': '13000015', - 'MainSeq': 2, 'SubSeq': 6739148, 'OrderNO': 5512467, 'OrderStatus': 'D'}, 0) - except Exception as e: - logging.exception(e) - finally: - time.sleep(10) - - -def run(queue_r: multiprocessing.Queue, queue_data_callback: multiprocessing.Queue, channel_list: list, - processor_index) -> None: - """ - 杩愯 - @param queue_r: - @param queue_data_callback锛� 浣庨鏁版嵁鍥炶皟闃熷垪 - @param channel_list: [((缂栧彿,multiprocessing.Array, zmq_address),(缂栧彿, multiprocessing.Array, zmq_address))] - @param processor_index锛氬鐞嗗櫒绱㈠紩 - @return: - """ - logger_system.info("L2杩涚▼ID锛歿}", os.getpid()) - logger_system.info(f"l2_client 绾跨▼ID:{tool.get_thread_id()}") - try: - log.close_print() - if queue_r is not None: - t1 = threading.Thread(target=lambda: __receive_from_queue_trade(queue_r), daemon=True) - t1.start() - # 璁㈤槄瀹堟姢 - threading.Thread(target=SubscriptDefend.run, daemon=True).start() - # 鍒濆鍖� - data_channel_distribute_manager = CodeDataChannelDistributeManager(channel_list) - l2_data_upload_manager = L2DataUploadManager(data_channel_distribute_manager, queue_data_callback) - __init_l2(l2_data_upload_manager, processor_index) - l2_data_manager_v2.run_upload_common() - l2_data_manager_v2.run_log() - # TODO 娴嬭瘯 - # threading.Thread(target=lambda: test_add_codes(queue_r), daemon=True).start() - global l2CommandManager - l2CommandManager = command_manager.L2CommandManager() - l2CommandManager.init(MyL2ActionCallback()) - logger_system.info("L2璁㈤槄鏈嶅姟鍚姩鎴愬姛") - except Exception as e: - logger_system.exception(e) - while True: - time.sleep(2) - - -def test(): - def test_add_codes(): - time.sleep(5) - # if value: - # if type(value) == bytes: - # value = value.decode("utf-8") - # data = json.loads(value) - # _type = data["type"] - # if _type == "listen_volume": - # volume = data["data"]["volume"] - # code = data["data"]["code"] - # spi.set_code_special_watch_volume(code, volume) - # elif _type == "l2_cmd": - # l2CommandManager.process_command(command_manager.CLIENT_TYPE_CMD_L2, None, data) - - demo_datas = [("603002", int(50 * 10000 / 6.35), 6.35), ("002654", int(50 * 10000 / 15.59), 15.59), - ("603701", int(50 * 10000 / 14.28), 14.28), ("002908", int(50 * 10000 / 12.78), 12.78)] - - queue_r.put_nowait(json.dumps({"type": "l2_cmd", "data": [demo_datas[0]]})) - time.sleep(1) - - spi.l2_data_upload_manager.add_l2_order_detail( - {'SecurityID': '603002', 'Price': 6.35, 'Volume': 275000, 'Side': "1", 'OrderType': '0', - 'OrderTime': '13000015', - 'MainSeq': 2, 'SubSeq': 6739147, 'OrderNO': 5512466, 'OrderStatus': 'D'}, 0) - spi.l2_data_upload_manager.add_l2_order_detail( - {'SecurityID': '603002', 'Price': 6.35, 'Volume': 200, 'Side': "1", 'OrderType': '0', - 'OrderTime': '13000015', - 'MainSeq': 2, 'SubSeq': 6739148, 'OrderNO': 5512467, 'OrderStatus': 'D'}, 0) - queue_r.put_nowait(json.dumps({"type": "listen_volume", "data": {"code": "603002", "volume": 100}})) - time.sleep(0.1) - spi.l2_data_upload_manager.add_l2_order_detail( - {'SecurityID': '603002', 'Price': 6.35, 'Volume': 100, 'Side': "1", 'OrderType': '0', - 'OrderTime': '13000015', - 'MainSeq': 2, 'SubSeq': 6739148, 'OrderNO': 5512467, 'OrderStatus': 'D'}, 0) - - queue_r = multiprocessing.Queue(maxsize=1024) - order_queues = [] - transaction_queues = [] - market_queue = multiprocessing.Queue(maxsize=1024) - for i in range(20): - order_queues.append(multiprocessing.Queue(maxsize=1024)) - transaction_queues.append(multiprocessing.Queue(maxsize=1024)) - threading.Thread(target=test_add_codes).start() - - run(queue_r, order_queues, transaction_queues, market_queue) - - -if __name__ == "__main__": - input() diff --git a/huaxin_client/l2_data_manager.py b/huaxin_client/l2_data_manager.py deleted file mode 100644 index f47415a..0000000 --- a/huaxin_client/l2_data_manager.py +++ /dev/null @@ -1,452 +0,0 @@ -# -*- coding: utf-8 -*- -import json -import logging -import marshal -import queue -import threading -import time - -import constant -from huaxin_client import socket_util - -from huaxin_client.client_network import SendResponseSkManager - -# 娲诲姩鏃堕棿 -from huaxin_client.code_queue_distribute_manager import CodeDataCallbackDistributeManager -from log_module import async_log_util -from log_module.async_log_util import huaxin_l2_log -from log_module.log import logger_local_huaxin_l2_error, logger_system, logger_local_huaxin_l2_subscript, \ - logger_local_huaxin_l2_special_volume, logger_debug, logger_local_huaxin_l2_orderdetail -from utils import tool -import collections -import zmq - -order_detail_upload_active_time_dict = {} -transaction_upload_active_time_dict = {} -# 涓存椂鏁版嵁 -tmep_order_detail_queue_dict = {} -tmep_transaction_queue_dict = {} -target_codes = set() -target_codes_add_time = {} -common_queue = queue.Queue(maxsize=1000) - - -# L2涓婁紶鏁版嵁绠$悊鍣� -class L2DataUploadManager: - def __init__(self, data_callback_distribute_manager: CodeDataCallbackDistributeManager): - self.data_callback_distribute_manager = data_callback_distribute_manager - # 浠g爜鍒嗛厤鐨勫璞� - self.temp_order_queue_dict = {} - self.temp_transaction_queue_dict = {} - self.temp_log_queue_dict = {} - - self.filter_order_condition_dict = {} - self.upload_l2_data_task_dict = {} - self.l2_order_codes = set() - self.l2_transaction_codes = set() - - # 璁剧疆璁㈠崟杩囨护鏉′欢 - # special_price:杩囨护鐨�1鎵嬬殑浠锋牸 - def set_order_fileter_condition(self, code, min_volume, limit_up_price, shadow_price, buy_volume, special_volumes): - if not special_volumes: - special_volumes = set() - # if code not in self.filter_order_condition_dict: - try: - # (鏈�灏忕殑閲�, 娑ㄥ仠浠锋牸, 褰卞瓙鍗曚环鏍�, 涔扮殑閲�, 搴熷純浣跨敤, 鐗规畩鐨勯噺闆嗗悎) - self.filter_order_condition_dict[code] = [(min_volume, limit_up_price, shadow_price, buy_volume, - int(min_volume) // 50, set(special_volumes))] - # huaxin_l2_log.info(logger_local_huaxin_l2_subscript, - # f"({code})甯歌杩囨护鏉′欢璁剧疆锛歿self.filter_order_condition_dict[code]}") - except Exception as e: - logger_debug.error(f"{str(e)} - min_volume-{min_volume}") - - # 杩囨护璁㈠崟 - def __filter_order(self, item): - filter_condition = self.filter_order_condition_dict.get(item[0]) - if filter_condition: - # item[2]涓洪噺 - if item[2] >= filter_condition[0][0]: - return item - # 1鎵嬬殑涔板崟婊¤冻浠锋牸 - # if item[2] == 100 and abs(filter_condition[0][2] - item[1]) < 0.001: - # return item - # 涔伴噺 - if item[2] == filter_condition[0][3]: - return item - - # 鎵�鏈夌殑娑ㄥ仠鍗� - if item[3] != '1': - # 鍗栦笌鍗栨挙 - if abs(item[1] - filter_condition[0][1]) < 0.001: - # 娑ㄥ仠浠� - return item - else: - if item[2] in filter_condition[0][5]: - # 鐗规畩鎵嬫暟 - return item - return None - return item - # 杩囨护璁㈠崟 - - def __filter_transaction(self, item): - filter_condition = self.filter_order_condition_dict.get(item[0]) - if filter_condition: - # item[2]涓洪噺 - if abs(item[1] - filter_condition[0][1]) < 0.201: - return item - return None - return item - - # 娣诲姞濮旀墭璇︽儏 - def add_l2_order_detail(self, data, start_time=0, istransaction=False): - code = data["SecurityID"] - # 涓嶇洿鎺ュ姞鍏� - # queue_info = self.order_queue_distribute_manager.get_distributed_queue(code) - # if not queue_info: - # return - # queue_info[1].put_nowait( - # (data['SecurityID'], data['Price'], data['Volume'], data['Side'], data['OrderType'], data['OrderTime'], - # data['MainSeq'], data['SubSeq'], data['OrderNO'], data['OrderStatus'], time.time(), start_time)) - # if data['Volume'] == 100: - # log_queue = self.temp_log_queue_dict.get(code) - # if log_queue: - # log_queue.put_nowait(data) - - q: collections.deque = self.temp_order_queue_dict.get(code) - if q is not None: - q.append( - (data['SecurityID'], data['Price'], data['Volume'], data['Side'], data['OrderType'], data['OrderTime'], - data['MainSeq'], data['SubSeq'], data['OrderNO'], data['OrderStatus'], time.time(), start_time)) - - # 娣诲姞閫愮瑪鎴愪氦 - def add_transaction_detail(self, data): - code = data["SecurityID"] - # 涓嶇洿鎺ュ姞鍏� - # queue_info = self.transaction_queue_distribute_manager.get_distributed_queue(code) - # if not queue_info: - # return - # # 鍒ゆ柇鏄惁涓哄ぇ鍗曟垚浜� - # queue_info[1].put_nowait((data['SecurityID'], data['TradePrice'], data['TradeVolume'], - # data['OrderTime'], data['MainSeq'], data['SubSeq'], data['BuyNo'], - # data['SellNo'], data['ExecType'])) - - q: collections.deque = self.temp_transaction_queue_dict.get(code) - if q is not None: - q.append((data['SecurityID'], data['TradePrice'], data['TradeVolume'], - data['OrderTime'], data['MainSeq'], data['SubSeq'], data['BuyNo'], - data['SellNo'], data['ExecType'], time.time())) - - def add_market_data(self, data): - # 鍔犲叆涓婁紶闃熷垪 - # self.market_data_queue.put_nowait(data) - code = data['securityID'] - callback = self.data_callback_distribute_manager.get_distributed_callback(code) - if callback: - callback.OnMarketData(code, data) - - # 鍒嗛厤涓婁紶闃熷垪 - def distribute_upload_queue(self, code, _target_codes=None): - """ - 鍒嗛厤涓婁紶闃熷垪 - @param code: 浠g爜 - @param _target_codes: 鎵�鏈夌殑鐩爣浠g爜 - @return: - """ - if not self.data_callback_distribute_manager.get_distributed_callback(code): - self.data_callback_distribute_manager.distribute_callback(code, _target_codes) - - if code not in self.temp_order_queue_dict: - self.temp_order_queue_dict[code] = collections.deque() - if code not in self.temp_transaction_queue_dict: - self.temp_transaction_queue_dict[code] = collections.deque() - if code not in self.temp_log_queue_dict: - self.temp_log_queue_dict[code] = queue.Queue(maxsize=1000) - if code not in self.upload_l2_data_task_dict: - t1 = threading.Thread(target=lambda: self.__run_upload_order_task(code), daemon=True) - t1.start() - t2 = threading.Thread(target=lambda: self.__run_upload_transaction_task(code), daemon=True) - t2.start() - # t3 = threading.Thread(target=lambda: self.__run_log_task(code), daemon=True) - # t3.start() - self.upload_l2_data_task_dict[code] = (t1, t2) - # 閲婃斁宸茬粡鍒嗛厤鐨勯槦鍒� - - def release_distributed_upload_queue(self, code): - self.data_callback_distribute_manager.release_distribute_callback(code) - if code in self.temp_order_queue_dict: - self.temp_order_queue_dict[code].clear() - self.temp_order_queue_dict.pop(code) - if code in self.temp_transaction_queue_dict: - self.temp_transaction_queue_dict[code].clear() - self.temp_transaction_queue_dict.pop(code) - if code in self.temp_log_queue_dict: - self.temp_log_queue_dict.pop(code) - - if code in self.upload_l2_data_task_dict: - self.upload_l2_data_task_dict.pop(code) - - def __upload_l2_data(self, code, _queue, datas): - _queue.put_nowait(marshal.dumps([code, datas, time.time()])) - - # 澶勭悊璁㈠崟鏁版嵁骞朵笂浼� - def __run_upload_order_task(self, code): - q: collections.deque = self.temp_order_queue_dict.get(code) - temp_list = [] - filter_condition = self.filter_order_condition_dict.get(code) - while True: - try: - while len(q) > 0: - data = q.popleft() - # 鍓嶇疆鏁版嵁澶勭悊锛岃繃婊ゆ帀鏃犵敤鐨勬暟鎹� - data = self.__filter_order(data) - if data: - temp_list.append(data) - - if temp_list: - # 涓婁紶鏁版嵁 - # self.__upload_l2_data(code, upload_queue, temp_list) - # self.__upload_l2_order_data(code, temp_list) - __start_time = time.time() - last_data = temp_list[-1] - self.data_callback_distribute_manager.get_distributed_callback(code).OnL2Order(code, temp_list, - time.time()) - use_time = time.time() - __start_time - if use_time > 0.01: - # 璁板綍10ms浠ヤ笂鐨勬暟鎹� - huaxin_l2_log.info(logger_local_huaxin_l2_error, f"鑰楁椂:{use_time}s 缁撴潫鏁版嵁锛歿last_data}") - - # 璁板綍鎵�鏈夌殑璁㈠崟鍙� - if filter_condition: - huaxin_l2_log.info(logger_local_huaxin_l2_orderdetail, - f"{[(x[0], x[1], x[2], x[4], x[8]) for x in temp_list if x[2] >= filter_condition[0][0]]}") - temp_list.clear() - else: - if code not in self.temp_order_queue_dict: - self.l2_order_codes.discard(code) - break - self.l2_order_codes.add(code) - time.sleep(0.001) - - except Exception as e: - logging.exception(e) - finally: - temp_list.clear() - - # 澶勭悊鎴愪氦鏁版嵁骞朵笂浼� - def __run_upload_transaction_task(self, code): - q: collections.deque = self.temp_transaction_queue_dict.get(code) - temp_list = [] - while True: - try: - while len(q) > 0: - data = q.popleft() - data = self.__filter_transaction(data) - if data: - temp_list.append(data) - if temp_list: - # 涓婁紶鏁版嵁 - # self.__upload_l2_data(code, upload_queue, temp_list) - self.data_callback_distribute_manager.get_distributed_callback(code).OnL2Transaction(code, - temp_list) - temp_list = [] - else: - if code not in self.temp_transaction_queue_dict: - self.l2_transaction_codes.discard(code) - break - self.l2_transaction_codes.add(code) - time.sleep(0.001) - except: - pass - finally: - temp_list.clear() - - def __run_log_task(self, code): - q: queue.Queue = self.temp_log_queue_dict.get(code) - while True: - try: - temp = q.get(timeout=10) - huaxin_l2_log.info(logger_local_huaxin_l2_special_volume, - f"{temp}") - except: - time.sleep(0.02) - finally: - if code not in self.temp_log_queue_dict: - break - - -class L2DataUploadProtocolManager: - - # ipchosts IPC鍗忚 - def __init__(self, ipchosts): - self.ipchosts = ipchosts - # 鎵�鏈夌殑client - self.socket_client_dict = {} - # 淇濆瓨浠g爜鍒嗛厤鐨刢lient 鏍煎紡锛歿code:(host, socket)} - self.code_socket_client_dict = {} - self.rlock = threading.RLock() - context = zmq.Context() - if constant.is_windows(): - return - for host in self.ipchosts: - socket = context.socket(zmq.REQ) - socket.connect(host) - self.socket_client_dict[host] = socket - - # 鑾峰彇 - def __get_available_ipchost(self): - if len(self.code_socket_client_dict) >= len(self.socket_client_dict): - raise Exception("鏃犲彲鐢╤ost") - used_hosts = set([self.code_socket_client_dict[k][0] for k in self.code_socket_client_dict]) - for host in self.socket_client_dict: - if host not in used_hosts: - return host, self.socket_client_dict[host] - raise Exception("鏃犲彲鐢╤ost") - - # 鍒嗛厤HOST - def distribute_upload_host(self, code): - if code in self.code_socket_client_dict: - return - self.rlock.acquire() - try: - host_info = self.__get_available_ipchost() - if host_info: - self.code_socket_client_dict[code] = host_info - finally: - self.rlock.release() - - def release_distributed_upload_host(self, code): - if code not in self.code_socket_client_dict: - return - self.rlock.acquire() - try: - if code in self.code_socket_client_dict: - self.code_socket_client_dict.pop(code) - finally: - self.rlock.release() - - def upload_data_as_json(self, code, data): - if code not in self.code_socket_client_dict: - raise Exception("灏氭湭鍒嗛厤host") - host, socket = self.code_socket_client_dict[code] - socket.send(marshal.dumps(data)) - socket.recv_string() - - -def add_target_code(code): - target_codes.add(code) - # 璁板綍浠g爜鍔犲叆鏃堕棿 - target_codes_add_time[code] = time.time() - - -def del_target_code(code): - target_codes.discard(code) - if code in target_codes_add_time: - target_codes_add_time.pop(code) - - -def add_subscript_codes(codes): - # print("add_subscript_codes", codes) - # 鍔犲叆涓婁紶闃熷垪 - common_queue.put(('', "l2_subscript_codes", list(codes))) - - -def __send_response(sk, msg): - msg = socket_util.load_header(msg) - sk.sendall(msg) - result, header_str = socket_util.recv_data(sk) - if result: - result_json = json.loads(result) - if result_json.get("code") == 0: - return True - return False - - -# 鍙戦�佹秷鎭� -def send_response(type, msg): - try: - sk = SendResponseSkManager.get_send_response_sk(type) - if __send_response(sk, msg): - return True - else: - # 鍐嶆鍙戦�� - # print("鍐嶆鍙戦��") - return __send_response(sk, msg) - except ConnectionResetError as e: - SendResponseSkManager.del_send_response_sk(type) - sk = SendResponseSkManager.get_send_response_sk(type) - return __send_response(sk, msg) - except BrokenPipeError as e: - SendResponseSkManager.del_send_response_sk(type) - sk = SendResponseSkManager.get_send_response_sk(type) - return __send_response(sk, msg) - - -# 涓婁紶鏁版嵁 -def upload_data(code, _type, datas, new_sk=False): - key = f"{_type}_{code}" - fdata = json.dumps( - {"type": _type, "data": {"code": code, "data": datas, "time": round(time.time() * 1000)}}) - result = None - try: - if new_sk: - sk = SendResponseSkManager.create_send_response_sk() - result = __send_response(sk, fdata.encode('utf-8')) - else: - result = send_response(key, fdata.encode('utf-8')) - except Exception as e: - logging.exception(e) - finally: - pass - - -def __run_upload_common(): - # print("__run_upload_common") - logger_system.info(f"l2_client __run_upload_common 绾跨▼ID:{tool.get_thread_id()}") - while True: - try: - while not common_queue.empty(): - temp = common_queue.get() - upload_data(temp[0], temp[1], temp[2]) - - except Exception as e: - logger_local_huaxin_l2_error.exception(e) - logger_local_huaxin_l2_error.error(f"涓婁紶鏅�氭暟鎹嚭閿欙細{str(e)}") - finally: - time.sleep(0.01) - - -def __run_log(): - # print("__run_log") - logger_system.info(f"l2_client __run_log 绾跨▼ID:{tool.get_thread_id()}") - async_log_util.huaxin_l2_log.run_sync() - - -# 閲囩敤socket浼犺緭鏁版嵁 -def run_upload_common(): - t = threading.Thread(target=lambda: __run_upload_common(), daemon=True) - t.start() - - -def run_log(): - t = threading.Thread(target=lambda: __run_log(), daemon=True) - t.start() - - -def __test(): - # 鍒嗛厤鏁版嵁 - pass - - -def run_test(): - t = threading.Thread(target=lambda: __test(), daemon=True) - t.start() - - -def test(): - ipclist = [] - for i in range(0, 70): - ipclist.append(f"ipc://l2order{i}.ipc") - manager = L2DataUploadProtocolManager(ipclist) - code = "000333" - manager.distribute_upload_host(code) - manager.upload_data_as_json(code, {"test": "test"}) diff --git a/huaxin_client/l2_market_client.py b/huaxin_client/l2_market_client.py index ed65ab1..f1ab991 100644 --- a/huaxin_client/l2_market_client.py +++ b/huaxin_client/l2_market_client.py @@ -11,10 +11,7 @@ from huaxin_client import l1_subscript_codes_manager from huaxin_client import constant import lev2mdapi -from huaxin_client.l2_data_manager import L2DataUploadManager -from log_module.async_log_util import huaxin_l2_log -from log_module.log import logger_local_huaxin_l2_subscript, logger_system, logger_l2_codes_subscript, \ - hx_logger_l2_market_data_before_open, hx_logger_l2_debug +from log_module.log import logger_local_huaxin_l2_subscript, logger_system, logger_local_huaxin_contact_debug from utils import tool ###B绫�### @@ -34,16 +31,10 @@ # 宸茬粡璁㈤槄鐨勪唬鐮� subscripted_codes = set() - # 娑ㄥ仠浠g爜 - __limit_up_codes = set() - - # 涔板叆鐨勫ぇ鍗曡鍗曞彿 - - def __init__(self, api, l2_data_upload_manager: L2DataUploadManager): + def __init__(self, api): lev2mdapi.CTORATstpLev2MdSpi.__init__(self) self.__api = api self.is_login = False - self.l2_data_upload_manager = l2_data_upload_manager def __split_codes(self, codes): szse_codes = [] @@ -95,7 +86,7 @@ self.__process_codes_data(codes) except Exception as e: logging.exception(e) - logger_l2_codes_subscript.exception(e) + logger_local_huaxin_l2_subscript.exception(e) finally: # 淇濆瓨涓�浠芥渶鏂扮殑鏁版嵁 pass @@ -144,56 +135,33 @@ def OnRtnMarketData(self, pDepthMarketData, FirstLevelBuyNum, FirstLevelBuyOrderVolumes, FirstLevelSellNum, FirstLevelSellOrderVolumes): - # 浼犲叆锛氭椂闂达紝鐜颁环,鎴愪氦鎬婚噺,涔�1锛屼拱2锛屼拱3,涔�4,涔�5,鍗�1,鍗�2,鍗�3,鍗�4,鍗�5 - try: - d = {"dataTimeStamp": pDepthMarketData['DataTimeStamp'], "securityID": pDepthMarketData['SecurityID'], - "preClosePrice": pDepthMarketData['PreClosePrice'], - "lastPrice": pDepthMarketData['LastPrice'], - "totalBidVolume": pDepthMarketData['TotalBidVolume'], - "avgBidPrice": pDepthMarketData['AvgBidPrice'], - "totalAskVolume": pDepthMarketData['TotalAskVolume'], - "avgAskPrice": pDepthMarketData["AvgAskPrice"] - # "buy": [(pDepthMarketData['BidPrice1'], pDepthMarketData['BidVolume1']), - # (pDepthMarketData['BidPrice2'], pDepthMarketData['BidVolume2']), - # (pDepthMarketData['BidPrice3'], pDepthMarketData['BidVolume3']), - # (pDepthMarketData['BidPrice4'], pDepthMarketData['BidVolume4']), - # (pDepthMarketData['BidPrice5'], pDepthMarketData['BidVolume5'])], - # "sell": [ - # (pDepthMarketData['AskPrice1'], pDepthMarketData['AskVolume1']), - # (pDepthMarketData['AskPrice2'], pDepthMarketData['AskVolume2']), - # (pDepthMarketData['AskPrice3'], pDepthMarketData['AskVolume3']), - # (pDepthMarketData['AskPrice4'], pDepthMarketData['AskVolume4']), - # (pDepthMarketData['AskPrice5'], pDepthMarketData['AskVolume5']) - # ] - } - limit_up_count = len(self.__limit_up_codes) - # 鑾峰彇鏄惁娑ㄥ仠浠� - limit_up_price = float( - tool.to_price(decimal.Decimal(str(pDepthMarketData['PreClosePrice'])) * decimal.Decimal( - tool.get_limit_up_rate(pDepthMarketData['SecurityID'])))) - if abs(limit_up_price - pDepthMarketData['LastPrice']) < 0.001 or abs( - limit_up_price - pDepthMarketData['BidPrice1']) < 0.001: - huaxin_l2_log.info(hx_logger_l2_market_data_before_open, f"{d}") - self.__limit_up_codes.add(pDepthMarketData['SecurityID']) - else: - self.__limit_up_codes.discard(pDepthMarketData['SecurityID']) - if pDepthMarketData.SecurityID in self.__limit_up_codes: - market_code_dict[pDepthMarketData.SecurityID] = ( - pDepthMarketData.SecurityID, pDepthMarketData.BidPrice1, 0.1, pDepthMarketData.TotalBidVolume, - time.time(), - pDepthMarketData.BidPrice1, pDepthMarketData.BidVolume1, pDepthMarketData.BidPrice2, - pDepthMarketData.BidVolume2, pDepthMarketData.UpdateTime, pDepthMarketData.PreClosePrice) - else: - if pDepthMarketData.SecurityID in market_code_dict: - market_code_dict.pop(pDepthMarketData.SecurityID) - - if limit_up_count != len(self.__limit_up_codes): - huaxin_l2_log.info(hx_logger_l2_market_data_before_open, f"娑ㄥ仠浠g爜锛歿self.__limit_up_codes}") - except: - pass + d = {"dataTimeStamp": pDepthMarketData['DataTimeStamp'], "securityID": pDepthMarketData['SecurityID'], + "lastPrice": pDepthMarketData['LastPrice'], + "totalVolumeTrade": pDepthMarketData['TotalVolumeTrade'], + "totalValueTrade": pDepthMarketData['TotalValueTrade'], + "totalAskVolume": pDepthMarketData['TotalAskVolume'], + "avgAskPrice": pDepthMarketData["AvgAskPrice"], + "buy": [(pDepthMarketData['BidPrice1'], pDepthMarketData['BidVolume1']), + (pDepthMarketData['BidPrice2'], pDepthMarketData['BidVolume2']), + (pDepthMarketData['BidPrice3'], pDepthMarketData['BidVolume3']), + (pDepthMarketData['BidPrice4'], pDepthMarketData['BidVolume4']), + (pDepthMarketData['BidPrice5'], pDepthMarketData['BidVolume5'])], + "sell": [ + (pDepthMarketData['AskPrice1'], pDepthMarketData['AskVolume1']), + (pDepthMarketData['AskPrice2'], pDepthMarketData['AskVolume2']), + (pDepthMarketData['AskPrice3'], pDepthMarketData['AskVolume3']), + (pDepthMarketData['AskPrice4'], pDepthMarketData['AskVolume4']), + (pDepthMarketData['AskPrice5'], pDepthMarketData['AskVolume5']) + ] + } + # (浠g爜, 鏃堕棿鎴�, 浠锋牸, 鎬讳氦鏄撻噺, 鎬讳氦鏄撻, 涔�5, 鍗�5) + data = ( + d["securityID"], d["dataTimeStamp"], d["lastPrice"], d["totalVolumeTrade"], d["totalValueTrade"], d["buy"], + d["sell"]) + market_code_dict[pDepthMarketData.SecurityID] = data -def __init_l2(l2_data_upload_manager): +def __init_l2(): # print(lev2mdapi.CTORATstpLev2MdApi_GetApiVersion()) # case 1: Tcp鏂瑰紡 # g_SubMode=lev2mdapi.TORA_TSTP_MST_TCP @@ -205,7 +173,7 @@ # case 2闈炵紦瀛樻ā寮� # api = lev2mdapi.CTORATstpLev2MdApi_CreateTstpLev2MdApi(g_SubMode, False) global spi - spi = Lev2MdSpi(api, l2_data_upload_manager) + spi = Lev2MdSpi(api) api.RegisterSpi(spi) # -------------------姝e紡妯″紡------------------------------------- if g_SubMode != lev2mdapi.TORA_TSTP_MST_MCAST: @@ -244,13 +212,13 @@ if queue_l1_w_strategy_r is not None: queue_l1_w_strategy_r.put_nowait(fdata) # 璁板綍鏂板鍔犵殑浠g爜 - codes = set([x[0] for x in datas]) - add_codes = codes - __latest_subscript_codes - __latest_subscript_codes.clear() - for c in codes: - __latest_subscript_codes.add(c) - if add_codes: - hx_logger_l2_market_data_before_open.info(f"({request_id})鏂板鍔犺闃呯殑浠g爜锛歿add_codes}") + # codes = set([x[0] for x in datas]) + # add_codes = codes - __latest_subscript_codes + # __latest_subscript_codes.clear() + # for c in codes: + # __latest_subscript_codes.add(c) + # if add_codes: + # hx_logger_l2_market_data_before_open.info(f"({request_id})鏂板鍔犺闃呯殑浠g爜锛歿add_codes}") def run(queue_l1_w_strategy_r) -> None: @@ -258,39 +226,18 @@ logger_system.info(f"l2_client 绾跨▼ID:{tool.get_thread_id()}") try: # log.close_print() - # 鍒濆鍖� - # data_callback_distribute_manager = CodeDataCallbackDistributeManager(data_callbacks) - # l2_data_upload_manager = L2DataUploadManager(data_callback_distribute_manager) - __init_l2(None) + __init_l2() except Exception as e: logger_system.exception(e) while True: - if tool.trade_time_sub(tool.get_now_time_str(), "09:25:00") >= 0: - # 鍙绔炰环鏁版嵁 - break - # 鍙9:20-9:25鐨勬暟鎹� - if tool.trade_time_sub(tool.get_now_time_str(), "09:20:00") < 0: + # 鍙9:30涔嬪悗鐨勬暟鎹� + if tool.get_now_time_str() < '09:24:59': continue try: # (浠g爜,鐜颁环,娑ㄥ箙,閲�,鏃堕棿) list_ = [market_code_dict[k] for k in market_code_dict] - flist = [] - plist = [] - for d in list_: - if d[2] >= constant.L1_MIN_RATE: - # 娑ㄥ箙灏忎簬5%鐨勯渶瑕佸垹闄� - flist.append(d) - flist.sort(key=lambda x: x[2], reverse=True) - datas = flist[:1000] - hx_logger_l2_debug.info(f"闆嗗悎绔炰环娑ㄥ仠锛歿datas}") - # 灏嗘寔浠撹偂鍔犲叆杩涘幓 - datas.extend(plist) - __upload_codes_info(queue_l1_w_strategy_r, datas) + __upload_codes_info(queue_l1_w_strategy_r, list_) except Exception as e: pass finally: time.sleep(2) - - -if __name__ == "__main__": - run(None) diff --git a/huaxin_client/trade_client.py b/huaxin_client/trade_client.py index a244d7a..b7a9620 100644 --- a/huaxin_client/trade_client.py +++ b/huaxin_client/trade_client.py @@ -2,12 +2,9 @@ import concurrent.futures import json import logging -import multiprocessing import os import threading import time - -import zmq from huaxin_client import command_manager from huaxin_client import constant @@ -17,7 +14,6 @@ from huaxin_client.log import logger # 姝e紡璐﹀彿 -from huaxin_client.trade_transform_protocol import TradeRequest, TradeResponse from log_module import async_log_util from log_module.log import logger_local_huaxin_trade_debug, logger_system, logger_trade from utils import tool @@ -40,26 +36,6 @@ LOCAL_IP = constant.LOCAL_IP FRONT_ADDRESS = "tcp://192.168.84.31:6500" FRONT_ADDRESS1 = "tcp://192.168.84.32:26500" - -########A绫�######## -if constant.IS_A: - UserID = '388000013942' - # 鐧婚檰瀵嗙爜 - Password = '110808' - # 鎶曡祫鑰呰处鎴� - InvestorID = '388000013942' - # 缁忔祹鍏徃閮ㄩ棬浠g爜 - DepartmentID = '0003' - # 璧勯噾璐︽埛 - AccountID = '388000013942' - # 娌競鑲′笢璐﹀彿 - SSE_ShareHolderID = 'A856881552' - # 娣卞競鑲′笢璐﹀彿 - SZSE_ShareHolderID = '0363800008' - - LOCAL_IP = "192.168.10.111" - FRONT_ADDRESS = "tcp://10.224.123.143:6500" - FRONT_ADDRESS1 = "tcp://10.224.123.147:26500" # # 浠跨湡 # from mylog import logger_trade_debug diff --git a/lev2mdapi.py b/lev2mdapi.py new file mode 100644 index 0000000..2758f16 --- /dev/null +++ b/lev2mdapi.py @@ -0,0 +1,1166 @@ +# This file was automatically generated by SWIG (http://www.swig.org). +# Version 4.0.2 +# +# Do not make changes to this file unless you know what you are doing--modify +# the SWIG interface file instead. + +from sys import version_info as _swig_python_version_info +if _swig_python_version_info < (2, 7, 0): + raise RuntimeError("Python 2.7 or later required") + +# Import the low-level C/C++ module +if __package__ or "." in __name__: + from . import _lev2mdapi +else: + import _lev2mdapi + +try: + import builtins as __builtin__ +except ImportError: + import __builtin__ + +def _swig_repr(self): + try: + strthis = "proxy of " + self.this.__repr__() + except __builtin__.Exception: + strthis = "" + return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) + + +def _swig_setattr_nondynamic_instance_variable(set): + def set_instance_attr(self, name, value): + if name == "thisown": + self.this.own(value) + elif name == "this": + set(self, name, value) + elif hasattr(self, name) and isinstance(getattr(type(self), name), property): + set(self, name, value) + else: + raise AttributeError("You cannot add instance attributes to %s" % self) + return set_instance_attr + + +def _swig_setattr_nondynamic_class_variable(set): + def set_class_attr(cls, name, value): + if hasattr(cls, name) and not isinstance(getattr(cls, name), property): + set(cls, name, value) + else: + raise AttributeError("You cannot add class attributes to %s" % cls) + return set_class_attr + + +def _swig_add_metaclass(metaclass): + """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass""" + def wrapper(cls): + return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy()) + return wrapper + + +class _SwigNonDynamicMeta(type): + """Meta class to enforce nondynamic attributes (no new attributes) for a class""" + __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__) + + +import weakref + + +def set_null(*args): + return _lev2mdapi.set_null(*args) + +def is_null(*args): + return _lev2mdapi.is_null(*args) +class CTORATstpFensUserInfoField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + LogInAccount = property(_lev2mdapi.CTORATstpFensUserInfoField_LogInAccount_get, _lev2mdapi.CTORATstpFensUserInfoField_LogInAccount_set) + LogInAccountType = property(_lev2mdapi.CTORATstpFensUserInfoField_LogInAccountType_get, _lev2mdapi.CTORATstpFensUserInfoField_LogInAccountType_set) + + def __init__(self): + _lev2mdapi.CTORATstpFensUserInfoField_swiginit(self, _lev2mdapi.new_CTORATstpFensUserInfoField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpFensUserInfoField + +# Register CTORATstpFensUserInfoField in _lev2mdapi: +_lev2mdapi.CTORATstpFensUserInfoField_swigregister(CTORATstpFensUserInfoField) +cvar = _lev2mdapi.cvar +INT_NULL_VAL = cvar.INT_NULL_VAL +FLOAT_NULL_VAL = cvar.FLOAT_NULL_VAL +CHAR_NULL_VAL = cvar.CHAR_NULL_VAL +WORD_NULL_VAL = cvar.WORD_NULL_VAL +LONG_NULL_VAL = cvar.LONG_NULL_VAL +TORA_TSTP_EXD_COMM = cvar.TORA_TSTP_EXD_COMM +TORA_TSTP_EXD_SSE = cvar.TORA_TSTP_EXD_SSE +TORA_TSTP_EXD_SZSE = cvar.TORA_TSTP_EXD_SZSE +TORA_TSTP_EXD_HK = cvar.TORA_TSTP_EXD_HK +TORA_TSTP_AM_Password = cvar.TORA_TSTP_AM_Password +TORA_TSTP_AM_FingerPrint = cvar.TORA_TSTP_AM_FingerPrint +TORA_TSTP_AM_CertInfo = cvar.TORA_TSTP_AM_CertInfo +TORA_TSTP_MST_TCP = cvar.TORA_TSTP_MST_TCP +TORA_TSTP_MST_UDP = cvar.TORA_TSTP_MST_UDP +TORA_TSTP_MST_MCAST = cvar.TORA_TSTP_MST_MCAST +TORA_TSTP_MST_DMA = cvar.TORA_TSTP_MST_DMA +TORA_TSTP_MST_PROXY = cvar.TORA_TSTP_MST_PROXY +TORA_TSTP_UTYPE_BrokerUser = cvar.TORA_TSTP_UTYPE_BrokerUser +TORA_TSTP_UTYPE_SuperUser = cvar.TORA_TSTP_UTYPE_SuperUser +TORA_TSTP_UTYPE_Investor = cvar.TORA_TSTP_UTYPE_Investor +TORA_TSTP_LACT_UserID = cvar.TORA_TSTP_LACT_UserID +TORA_TSTP_LACT_AccountID = cvar.TORA_TSTP_LACT_AccountID +TORA_TSTP_LACT_SHAStock = cvar.TORA_TSTP_LACT_SHAStock +TORA_TSTP_LACT_SZAStock = cvar.TORA_TSTP_LACT_SZAStock +TORA_TSTP_LACT_SHBStock = cvar.TORA_TSTP_LACT_SHBStock +TORA_TSTP_LACT_SZBStock = cvar.TORA_TSTP_LACT_SZBStock +TORA_TSTP_LACT_ThreeNewBoardA = cvar.TORA_TSTP_LACT_ThreeNewBoardA +TORA_TSTP_LACT_ThreeNewBoardB = cvar.TORA_TSTP_LACT_ThreeNewBoardB +TORA_TSTP_LACT_HKStock = cvar.TORA_TSTP_LACT_HKStock +TORA_TSTP_LACT_UnifiedUserID = cvar.TORA_TSTP_LACT_UnifiedUserID +TORA_TSTP_MKST_MarketData = cvar.TORA_TSTP_MKST_MarketData +TORA_TSTP_MKST_Index = cvar.TORA_TSTP_MKST_Index +TORA_TSTP_MKST_Transaction = cvar.TORA_TSTP_MKST_Transaction +TORA_TSTP_MKST_OrderDetail = cvar.TORA_TSTP_MKST_OrderDetail +TORA_TSTP_MKST_PHMarketData = cvar.TORA_TSTP_MKST_PHMarketData +TORA_TSTP_MKST_PHTransaction = cvar.TORA_TSTP_MKST_PHTransaction +TORA_TSTP_MKST_ResendTransaction = cvar.TORA_TSTP_MKST_ResendTransaction +TORA_TSTP_MKST_ResendOrderDetail = cvar.TORA_TSTP_MKST_ResendOrderDetail +TORA_TSTP_MKST_XTSMarketData = cvar.TORA_TSTP_MKST_XTSMarketData +TORA_TSTP_MKST_XTSTick = cvar.TORA_TSTP_MKST_XTSTick +TORA_TSTP_MKST_BondMarketData = cvar.TORA_TSTP_MKST_BondMarketData +TORA_TSTP_MKST_BondTransaction = cvar.TORA_TSTP_MKST_BondTransaction +TORA_TSTP_MKST_BondOrderDetail = cvar.TORA_TSTP_MKST_BondOrderDetail +TORA_TSTP_MKST_NGTSTick = cvar.TORA_TSTP_MKST_NGTSTick +TORA_TSTP_LOT_Market = cvar.TORA_TSTP_LOT_Market +TORA_TSTP_LOT_Limit = cvar.TORA_TSTP_LOT_Limit +TORA_TSTP_LOT_HomeBest = cvar.TORA_TSTP_LOT_HomeBest +TORA_TSTP_LSD_Buy = cvar.TORA_TSTP_LSD_Buy +TORA_TSTP_LSD_Sell = cvar.TORA_TSTP_LSD_Sell +TORA_TSTP_LSD_Borrow = cvar.TORA_TSTP_LSD_Borrow +TORA_TSTP_LSD_Lend = cvar.TORA_TSTP_LSD_Lend +TORA_TSTP_ECT_Fill = cvar.TORA_TSTP_ECT_Fill +TORA_TSTP_ECT_Cancel = cvar.TORA_TSTP_ECT_Cancel +TORA_TSTP_ECT_Unknown = cvar.TORA_TSTP_ECT_Unknown +TORA_TSTP_LOS_Add = cvar.TORA_TSTP_LOS_Add +TORA_TSTP_LOS_Delete = cvar.TORA_TSTP_LOS_Delete +TORA_TSTP_MSST_PreOpen = cvar.TORA_TSTP_MSST_PreOpen +TORA_TSTP_MSST_CallAuction = cvar.TORA_TSTP_MSST_CallAuction +TORA_TSTP_MSST_Continous = cvar.TORA_TSTP_MSST_Continous +TORA_TSTP_MSST_Pause = cvar.TORA_TSTP_MSST_Pause +TORA_TSTP_MSST_Suspend = cvar.TORA_TSTP_MSST_Suspend +TORA_TSTP_MSST_LongSuspend = cvar.TORA_TSTP_MSST_LongSuspend +TORA_TSTP_MSST_UndulationInt = cvar.TORA_TSTP_MSST_UndulationInt +TORA_TSTP_MSST_CircuitBreak = cvar.TORA_TSTP_MSST_CircuitBreak +TORA_TSTP_MSST_CircuitBreakU = cvar.TORA_TSTP_MSST_CircuitBreakU +TORA_TSTP_MSST_Close = cvar.TORA_TSTP_MSST_Close +TORA_TSTP_MSST_Other = cvar.TORA_TSTP_MSST_Other +TORA_TSTP_MSST_CloseCallAuction = cvar.TORA_TSTP_MSST_CloseCallAuction +TORA_TSTP_MSST_CallMatch = cvar.TORA_TSTP_MSST_CallMatch +TORA_TSTP_MSST_PostContinous = cvar.TORA_TSTP_MSST_PostContinous +TORA_TSTP_MSST_PostClose = cvar.TORA_TSTP_MSST_PostClose +TORA_TSTP_MSST_PrePostOpen = cvar.TORA_TSTP_MSST_PrePostOpen +TORA_TSTP_MSST_Unlisted = cvar.TORA_TSTP_MSST_Unlisted +TORA_TSTP_TBSF_Buy = cvar.TORA_TSTP_TBSF_Buy +TORA_TSTP_TBSF_Sell = cvar.TORA_TSTP_TBSF_Sell +TORA_TSTP_TBSF_Unknown = cvar.TORA_TSTP_TBSF_Unknown +TORA_TSTP_LTT_Add = cvar.TORA_TSTP_LTT_Add +TORA_TSTP_LTT_Delete = cvar.TORA_TSTP_LTT_Delete +TORA_TSTP_LTT_Status = cvar.TORA_TSTP_LTT_Status +TORA_TSTP_LTT_Trade = cvar.TORA_TSTP_LTT_Trade + +class CTORATstpReqUserLoginField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + LogInAccount = property(_lev2mdapi.CTORATstpReqUserLoginField_LogInAccount_get, _lev2mdapi.CTORATstpReqUserLoginField_LogInAccount_set) + LogInAccountType = property(_lev2mdapi.CTORATstpReqUserLoginField_LogInAccountType_get, _lev2mdapi.CTORATstpReqUserLoginField_LogInAccountType_set) + Password = property(_lev2mdapi.CTORATstpReqUserLoginField_Password_get, _lev2mdapi.CTORATstpReqUserLoginField_Password_set) + UserProductInfo = property(_lev2mdapi.CTORATstpReqUserLoginField_UserProductInfo_get, _lev2mdapi.CTORATstpReqUserLoginField_UserProductInfo_set) + InterfaceProductInfo = property(_lev2mdapi.CTORATstpReqUserLoginField_InterfaceProductInfo_get, _lev2mdapi.CTORATstpReqUserLoginField_InterfaceProductInfo_set) + ProtocolInfo = property(_lev2mdapi.CTORATstpReqUserLoginField_ProtocolInfo_get, _lev2mdapi.CTORATstpReqUserLoginField_ProtocolInfo_set) + MacAddress = property(_lev2mdapi.CTORATstpReqUserLoginField_MacAddress_get, _lev2mdapi.CTORATstpReqUserLoginField_MacAddress_set) + Mobile = property(_lev2mdapi.CTORATstpReqUserLoginField_Mobile_get, _lev2mdapi.CTORATstpReqUserLoginField_Mobile_set) + InnerIPAddress = property(_lev2mdapi.CTORATstpReqUserLoginField_InnerIPAddress_get, _lev2mdapi.CTORATstpReqUserLoginField_InnerIPAddress_set) + Lang = property(_lev2mdapi.CTORATstpReqUserLoginField_Lang_get, _lev2mdapi.CTORATstpReqUserLoginField_Lang_set) + TerminalInfo = property(_lev2mdapi.CTORATstpReqUserLoginField_TerminalInfo_get, _lev2mdapi.CTORATstpReqUserLoginField_TerminalInfo_set) + GWMacAddress = property(_lev2mdapi.CTORATstpReqUserLoginField_GWMacAddress_get, _lev2mdapi.CTORATstpReqUserLoginField_GWMacAddress_set) + GWInnerIPAddress = property(_lev2mdapi.CTORATstpReqUserLoginField_GWInnerIPAddress_get, _lev2mdapi.CTORATstpReqUserLoginField_GWInnerIPAddress_set) + GWOuterIPAddress = property(_lev2mdapi.CTORATstpReqUserLoginField_GWOuterIPAddress_get, _lev2mdapi.CTORATstpReqUserLoginField_GWOuterIPAddress_set) + DepartmentID = property(_lev2mdapi.CTORATstpReqUserLoginField_DepartmentID_get, _lev2mdapi.CTORATstpReqUserLoginField_DepartmentID_set) + HDSerial = property(_lev2mdapi.CTORATstpReqUserLoginField_HDSerial_get, _lev2mdapi.CTORATstpReqUserLoginField_HDSerial_set) + AuthMode = property(_lev2mdapi.CTORATstpReqUserLoginField_AuthMode_get, _lev2mdapi.CTORATstpReqUserLoginField_AuthMode_set) + DeviceID = property(_lev2mdapi.CTORATstpReqUserLoginField_DeviceID_get, _lev2mdapi.CTORATstpReqUserLoginField_DeviceID_set) + CertSerial = property(_lev2mdapi.CTORATstpReqUserLoginField_CertSerial_get, _lev2mdapi.CTORATstpReqUserLoginField_CertSerial_set) + OuterIPAddress = property(_lev2mdapi.CTORATstpReqUserLoginField_OuterIPAddress_get, _lev2mdapi.CTORATstpReqUserLoginField_OuterIPAddress_set) + DynamicPassword = property(_lev2mdapi.CTORATstpReqUserLoginField_DynamicPassword_get, _lev2mdapi.CTORATstpReqUserLoginField_DynamicPassword_set) + OuterPort = property(_lev2mdapi.CTORATstpReqUserLoginField_OuterPort_get, _lev2mdapi.CTORATstpReqUserLoginField_OuterPort_set) + + def __init__(self): + _lev2mdapi.CTORATstpReqUserLoginField_swiginit(self, _lev2mdapi.new_CTORATstpReqUserLoginField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpReqUserLoginField + +# Register CTORATstpReqUserLoginField in _lev2mdapi: +_lev2mdapi.CTORATstpReqUserLoginField_swigregister(CTORATstpReqUserLoginField) + +class CTORATstpRspUserLoginField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + LoginTime = property(_lev2mdapi.CTORATstpRspUserLoginField_LoginTime_get, _lev2mdapi.CTORATstpRspUserLoginField_LoginTime_set) + LogInAccount = property(_lev2mdapi.CTORATstpRspUserLoginField_LogInAccount_get, _lev2mdapi.CTORATstpRspUserLoginField_LogInAccount_set) + LogInAccountType = property(_lev2mdapi.CTORATstpRspUserLoginField_LogInAccountType_get, _lev2mdapi.CTORATstpRspUserLoginField_LogInAccountType_set) + SystemName = property(_lev2mdapi.CTORATstpRspUserLoginField_SystemName_get, _lev2mdapi.CTORATstpRspUserLoginField_SystemName_set) + FrontID = property(_lev2mdapi.CTORATstpRspUserLoginField_FrontID_get, _lev2mdapi.CTORATstpRspUserLoginField_FrontID_set) + SessionID = property(_lev2mdapi.CTORATstpRspUserLoginField_SessionID_get, _lev2mdapi.CTORATstpRspUserLoginField_SessionID_set) + MaxOrderRef = property(_lev2mdapi.CTORATstpRspUserLoginField_MaxOrderRef_get, _lev2mdapi.CTORATstpRspUserLoginField_MaxOrderRef_set) + PrivateFlowCount = property(_lev2mdapi.CTORATstpRspUserLoginField_PrivateFlowCount_get, _lev2mdapi.CTORATstpRspUserLoginField_PrivateFlowCount_set) + PublicFlowCount = property(_lev2mdapi.CTORATstpRspUserLoginField_PublicFlowCount_get, _lev2mdapi.CTORATstpRspUserLoginField_PublicFlowCount_set) + TradingDay = property(_lev2mdapi.CTORATstpRspUserLoginField_TradingDay_get, _lev2mdapi.CTORATstpRspUserLoginField_TradingDay_set) + UserID = property(_lev2mdapi.CTORATstpRspUserLoginField_UserID_get, _lev2mdapi.CTORATstpRspUserLoginField_UserID_set) + UserName = property(_lev2mdapi.CTORATstpRspUserLoginField_UserName_get, _lev2mdapi.CTORATstpRspUserLoginField_UserName_set) + UserType = property(_lev2mdapi.CTORATstpRspUserLoginField_UserType_get, _lev2mdapi.CTORATstpRspUserLoginField_UserType_set) + DepartmentID = property(_lev2mdapi.CTORATstpRspUserLoginField_DepartmentID_get, _lev2mdapi.CTORATstpRspUserLoginField_DepartmentID_set) + InnerIPAddress = property(_lev2mdapi.CTORATstpRspUserLoginField_InnerIPAddress_get, _lev2mdapi.CTORATstpRspUserLoginField_InnerIPAddress_set) + MacAddress = property(_lev2mdapi.CTORATstpRspUserLoginField_MacAddress_get, _lev2mdapi.CTORATstpRspUserLoginField_MacAddress_set) + HDSerial = property(_lev2mdapi.CTORATstpRspUserLoginField_HDSerial_get, _lev2mdapi.CTORATstpRspUserLoginField_HDSerial_set) + OrderInsertCommFlux = property(_lev2mdapi.CTORATstpRspUserLoginField_OrderInsertCommFlux_get, _lev2mdapi.CTORATstpRspUserLoginField_OrderInsertCommFlux_set) + PasswordUpdatePeriod = property(_lev2mdapi.CTORATstpRspUserLoginField_PasswordUpdatePeriod_get, _lev2mdapi.CTORATstpRspUserLoginField_PasswordUpdatePeriod_set) + PasswordRemainDays = property(_lev2mdapi.CTORATstpRspUserLoginField_PasswordRemainDays_get, _lev2mdapi.CTORATstpRspUserLoginField_PasswordRemainDays_set) + NeedUpdatePassword = property(_lev2mdapi.CTORATstpRspUserLoginField_NeedUpdatePassword_get, _lev2mdapi.CTORATstpRspUserLoginField_NeedUpdatePassword_set) + OrderActionCommFlux = property(_lev2mdapi.CTORATstpRspUserLoginField_OrderActionCommFlux_get, _lev2mdapi.CTORATstpRspUserLoginField_OrderActionCommFlux_set) + Mobile = property(_lev2mdapi.CTORATstpRspUserLoginField_Mobile_get, _lev2mdapi.CTORATstpRspUserLoginField_Mobile_set) + OuterIPAddress = property(_lev2mdapi.CTORATstpRspUserLoginField_OuterIPAddress_get, _lev2mdapi.CTORATstpRspUserLoginField_OuterIPAddress_set) + CertSerial = property(_lev2mdapi.CTORATstpRspUserLoginField_CertSerial_get, _lev2mdapi.CTORATstpRspUserLoginField_CertSerial_set) + OuterPort = property(_lev2mdapi.CTORATstpRspUserLoginField_OuterPort_get, _lev2mdapi.CTORATstpRspUserLoginField_OuterPort_set) + + def __init__(self): + _lev2mdapi.CTORATstpRspUserLoginField_swiginit(self, _lev2mdapi.new_CTORATstpRspUserLoginField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpRspUserLoginField + +# Register CTORATstpRspUserLoginField in _lev2mdapi: +_lev2mdapi.CTORATstpRspUserLoginField_swigregister(CTORATstpRspUserLoginField) + +class CTORATstpRspInfoField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + ErrorID = property(_lev2mdapi.CTORATstpRspInfoField_ErrorID_get, _lev2mdapi.CTORATstpRspInfoField_ErrorID_set) + ErrorMsg = property(_lev2mdapi.CTORATstpRspInfoField_ErrorMsg_get, _lev2mdapi.CTORATstpRspInfoField_ErrorMsg_set) + + def __init__(self): + _lev2mdapi.CTORATstpRspInfoField_swiginit(self, _lev2mdapi.new_CTORATstpRspInfoField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpRspInfoField + +# Register CTORATstpRspInfoField in _lev2mdapi: +_lev2mdapi.CTORATstpRspInfoField_swigregister(CTORATstpRspInfoField) + +class CTORATstpUserLogoutField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + UserID = property(_lev2mdapi.CTORATstpUserLogoutField_UserID_get, _lev2mdapi.CTORATstpUserLogoutField_UserID_set) + + def __init__(self): + _lev2mdapi.CTORATstpUserLogoutField_swiginit(self, _lev2mdapi.new_CTORATstpUserLogoutField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpUserLogoutField + +# Register CTORATstpUserLogoutField in _lev2mdapi: +_lev2mdapi.CTORATstpUserLogoutField_swigregister(CTORATstpUserLogoutField) + +class CTORATstpSpecificSecurityField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + ExchangeID = property(_lev2mdapi.CTORATstpSpecificSecurityField_ExchangeID_get, _lev2mdapi.CTORATstpSpecificSecurityField_ExchangeID_set) + SecurityID = property(_lev2mdapi.CTORATstpSpecificSecurityField_SecurityID_get, _lev2mdapi.CTORATstpSpecificSecurityField_SecurityID_set) + + def __init__(self): + _lev2mdapi.CTORATstpSpecificSecurityField_swiginit(self, _lev2mdapi.new_CTORATstpSpecificSecurityField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpSpecificSecurityField + +# Register CTORATstpSpecificSecurityField in _lev2mdapi: +_lev2mdapi.CTORATstpSpecificSecurityField_swigregister(CTORATstpSpecificSecurityField) + +class CTORATstpLev2MarketDataField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + SecurityID = property(_lev2mdapi.CTORATstpLev2MarketDataField_SecurityID_get, _lev2mdapi.CTORATstpLev2MarketDataField_SecurityID_set) + ExchangeID = property(_lev2mdapi.CTORATstpLev2MarketDataField_ExchangeID_get, _lev2mdapi.CTORATstpLev2MarketDataField_ExchangeID_set) + DataTimeStamp = property(_lev2mdapi.CTORATstpLev2MarketDataField_DataTimeStamp_get, _lev2mdapi.CTORATstpLev2MarketDataField_DataTimeStamp_set) + PreClosePrice = property(_lev2mdapi.CTORATstpLev2MarketDataField_PreClosePrice_get, _lev2mdapi.CTORATstpLev2MarketDataField_PreClosePrice_set) + OpenPrice = property(_lev2mdapi.CTORATstpLev2MarketDataField_OpenPrice_get, _lev2mdapi.CTORATstpLev2MarketDataField_OpenPrice_set) + NumTrades = property(_lev2mdapi.CTORATstpLev2MarketDataField_NumTrades_get, _lev2mdapi.CTORATstpLev2MarketDataField_NumTrades_set) + TotalVolumeTrade = property(_lev2mdapi.CTORATstpLev2MarketDataField_TotalVolumeTrade_get, _lev2mdapi.CTORATstpLev2MarketDataField_TotalVolumeTrade_set) + TotalValueTrade = property(_lev2mdapi.CTORATstpLev2MarketDataField_TotalValueTrade_get, _lev2mdapi.CTORATstpLev2MarketDataField_TotalValueTrade_set) + TotalBidVolume = property(_lev2mdapi.CTORATstpLev2MarketDataField_TotalBidVolume_get, _lev2mdapi.CTORATstpLev2MarketDataField_TotalBidVolume_set) + AvgBidPrice = property(_lev2mdapi.CTORATstpLev2MarketDataField_AvgBidPrice_get, _lev2mdapi.CTORATstpLev2MarketDataField_AvgBidPrice_set) + TotalAskVolume = property(_lev2mdapi.CTORATstpLev2MarketDataField_TotalAskVolume_get, _lev2mdapi.CTORATstpLev2MarketDataField_TotalAskVolume_set) + AvgAskPrice = property(_lev2mdapi.CTORATstpLev2MarketDataField_AvgAskPrice_get, _lev2mdapi.CTORATstpLev2MarketDataField_AvgAskPrice_set) + HighestPrice = property(_lev2mdapi.CTORATstpLev2MarketDataField_HighestPrice_get, _lev2mdapi.CTORATstpLev2MarketDataField_HighestPrice_set) + LowestPrice = property(_lev2mdapi.CTORATstpLev2MarketDataField_LowestPrice_get, _lev2mdapi.CTORATstpLev2MarketDataField_LowestPrice_set) + LastPrice = property(_lev2mdapi.CTORATstpLev2MarketDataField_LastPrice_get, _lev2mdapi.CTORATstpLev2MarketDataField_LastPrice_set) + BidPrice1 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidPrice1_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidPrice1_set) + BidVolume1 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidVolume1_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidVolume1_set) + AskPrice1 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskPrice1_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskPrice1_set) + AskVolume1 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskVolume1_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskVolume1_set) + AskPrice2 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskPrice2_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskPrice2_set) + AskVolume2 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskVolume2_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskVolume2_set) + AskPrice3 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskPrice3_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskPrice3_set) + AskVolume3 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskVolume3_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskVolume3_set) + BidPrice2 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidPrice2_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidPrice2_set) + BidVolume2 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidVolume2_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidVolume2_set) + BidPrice3 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidPrice3_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidPrice3_set) + BidVolume3 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidVolume3_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidVolume3_set) + AskPrice4 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskPrice4_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskPrice4_set) + AskVolume4 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskVolume4_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskVolume4_set) + AskPrice5 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskPrice5_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskPrice5_set) + AskVolume5 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskVolume5_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskVolume5_set) + BidPrice4 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidPrice4_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidPrice4_set) + BidVolume4 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidVolume4_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidVolume4_set) + BidPrice5 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidPrice5_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidPrice5_set) + BidVolume5 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidVolume5_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidVolume5_set) + AskPrice6 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskPrice6_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskPrice6_set) + AskVolume6 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskVolume6_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskVolume6_set) + AskPrice7 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskPrice7_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskPrice7_set) + AskVolume7 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskVolume7_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskVolume7_set) + BidPrice6 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidPrice6_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidPrice6_set) + BidVolume6 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidVolume6_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidVolume6_set) + BidPrice7 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidPrice7_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidPrice7_set) + BidVolume7 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidVolume7_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidVolume7_set) + AskPrice8 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskPrice8_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskPrice8_set) + AskVolume8 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskVolume8_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskVolume8_set) + AskPrice9 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskPrice9_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskPrice9_set) + AskVolume9 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskVolume9_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskVolume9_set) + BidPrice8 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidPrice8_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidPrice8_set) + BidVolume8 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidVolume8_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidVolume8_set) + BidPrice9 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidPrice9_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidPrice9_set) + BidVolume9 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidVolume9_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidVolume9_set) + BidPrice10 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidPrice10_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidPrice10_set) + BidVolume10 = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidVolume10_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidVolume10_set) + AskPrice10 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskPrice10_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskPrice10_set) + AskVolume10 = property(_lev2mdapi.CTORATstpLev2MarketDataField_AskVolume10_get, _lev2mdapi.CTORATstpLev2MarketDataField_AskVolume10_set) + Info1 = property(_lev2mdapi.CTORATstpLev2MarketDataField_Info1_get, _lev2mdapi.CTORATstpLev2MarketDataField_Info1_set) + Info2 = property(_lev2mdapi.CTORATstpLev2MarketDataField_Info2_get, _lev2mdapi.CTORATstpLev2MarketDataField_Info2_set) + Info3 = property(_lev2mdapi.CTORATstpLev2MarketDataField_Info3_get, _lev2mdapi.CTORATstpLev2MarketDataField_Info3_set) + UpperLimitPrice = property(_lev2mdapi.CTORATstpLev2MarketDataField_UpperLimitPrice_get, _lev2mdapi.CTORATstpLev2MarketDataField_UpperLimitPrice_set) + LowerLimitPrice = property(_lev2mdapi.CTORATstpLev2MarketDataField_LowerLimitPrice_get, _lev2mdapi.CTORATstpLev2MarketDataField_LowerLimitPrice_set) + ClosePrice = property(_lev2mdapi.CTORATstpLev2MarketDataField_ClosePrice_get, _lev2mdapi.CTORATstpLev2MarketDataField_ClosePrice_set) + MDSecurityStat = property(_lev2mdapi.CTORATstpLev2MarketDataField_MDSecurityStat_get, _lev2mdapi.CTORATstpLev2MarketDataField_MDSecurityStat_set) + TotalBidNumber = property(_lev2mdapi.CTORATstpLev2MarketDataField_TotalBidNumber_get, _lev2mdapi.CTORATstpLev2MarketDataField_TotalBidNumber_set) + TotalOfferNumber = property(_lev2mdapi.CTORATstpLev2MarketDataField_TotalOfferNumber_get, _lev2mdapi.CTORATstpLev2MarketDataField_TotalOfferNumber_set) + BidTradeMaxDuration = property(_lev2mdapi.CTORATstpLev2MarketDataField_BidTradeMaxDuration_get, _lev2mdapi.CTORATstpLev2MarketDataField_BidTradeMaxDuration_set) + OfferTradeMaxDuration = property(_lev2mdapi.CTORATstpLev2MarketDataField_OfferTradeMaxDuration_get, _lev2mdapi.CTORATstpLev2MarketDataField_OfferTradeMaxDuration_set) + IOPV = property(_lev2mdapi.CTORATstpLev2MarketDataField_IOPV_get, _lev2mdapi.CTORATstpLev2MarketDataField_IOPV_set) + Ask1NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Ask1NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Ask1NumOrders_set) + Bid1NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Bid1NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Bid1NumOrders_set) + Ask2NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Ask2NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Ask2NumOrders_set) + Bid2NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Bid2NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Bid2NumOrders_set) + Ask3NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Ask3NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Ask3NumOrders_set) + Bid3NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Bid3NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Bid3NumOrders_set) + Ask4NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Ask4NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Ask4NumOrders_set) + Bid4NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Bid4NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Bid4NumOrders_set) + Ask5NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Ask5NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Ask5NumOrders_set) + Bid5NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Bid5NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Bid5NumOrders_set) + Ask6NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Ask6NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Ask6NumOrders_set) + Bid6NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Bid6NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Bid6NumOrders_set) + Ask7NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Ask7NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Ask7NumOrders_set) + Bid7NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Bid7NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Bid7NumOrders_set) + Ask8NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Ask8NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Ask8NumOrders_set) + Bid8NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Bid8NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Bid8NumOrders_set) + Ask9NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Ask9NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Ask9NumOrders_set) + Bid9NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Bid9NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Bid9NumOrders_set) + Ask10NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Ask10NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Ask10NumOrders_set) + Bid10NumOrders = property(_lev2mdapi.CTORATstpLev2MarketDataField_Bid10NumOrders_get, _lev2mdapi.CTORATstpLev2MarketDataField_Bid10NumOrders_set) + WithdrawBuyNumber = property(_lev2mdapi.CTORATstpLev2MarketDataField_WithdrawBuyNumber_get, _lev2mdapi.CTORATstpLev2MarketDataField_WithdrawBuyNumber_set) + WithdrawBuyAmount = property(_lev2mdapi.CTORATstpLev2MarketDataField_WithdrawBuyAmount_get, _lev2mdapi.CTORATstpLev2MarketDataField_WithdrawBuyAmount_set) + WithdrawBuyMoney = property(_lev2mdapi.CTORATstpLev2MarketDataField_WithdrawBuyMoney_get, _lev2mdapi.CTORATstpLev2MarketDataField_WithdrawBuyMoney_set) + WithdrawSellNumber = property(_lev2mdapi.CTORATstpLev2MarketDataField_WithdrawSellNumber_get, _lev2mdapi.CTORATstpLev2MarketDataField_WithdrawSellNumber_set) + WithdrawSellAmount = property(_lev2mdapi.CTORATstpLev2MarketDataField_WithdrawSellAmount_get, _lev2mdapi.CTORATstpLev2MarketDataField_WithdrawSellAmount_set) + WithdrawSellMoney = property(_lev2mdapi.CTORATstpLev2MarketDataField_WithdrawSellMoney_get, _lev2mdapi.CTORATstpLev2MarketDataField_WithdrawSellMoney_set) + + def __init__(self): + _lev2mdapi.CTORATstpLev2MarketDataField_swiginit(self, _lev2mdapi.new_CTORATstpLev2MarketDataField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpLev2MarketDataField + +# Register CTORATstpLev2MarketDataField in _lev2mdapi: +_lev2mdapi.CTORATstpLev2MarketDataField_swigregister(CTORATstpLev2MarketDataField) + +class CTORATstpLev2IndexField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + ExchangeID = property(_lev2mdapi.CTORATstpLev2IndexField_ExchangeID_get, _lev2mdapi.CTORATstpLev2IndexField_ExchangeID_set) + SecurityID = property(_lev2mdapi.CTORATstpLev2IndexField_SecurityID_get, _lev2mdapi.CTORATstpLev2IndexField_SecurityID_set) + DataTimeStamp = property(_lev2mdapi.CTORATstpLev2IndexField_DataTimeStamp_get, _lev2mdapi.CTORATstpLev2IndexField_DataTimeStamp_set) + PreCloseIndex = property(_lev2mdapi.CTORATstpLev2IndexField_PreCloseIndex_get, _lev2mdapi.CTORATstpLev2IndexField_PreCloseIndex_set) + OpenIndex = property(_lev2mdapi.CTORATstpLev2IndexField_OpenIndex_get, _lev2mdapi.CTORATstpLev2IndexField_OpenIndex_set) + HighIndex = property(_lev2mdapi.CTORATstpLev2IndexField_HighIndex_get, _lev2mdapi.CTORATstpLev2IndexField_HighIndex_set) + LowIndex = property(_lev2mdapi.CTORATstpLev2IndexField_LowIndex_get, _lev2mdapi.CTORATstpLev2IndexField_LowIndex_set) + LastIndex = property(_lev2mdapi.CTORATstpLev2IndexField_LastIndex_get, _lev2mdapi.CTORATstpLev2IndexField_LastIndex_set) + Turnover = property(_lev2mdapi.CTORATstpLev2IndexField_Turnover_get, _lev2mdapi.CTORATstpLev2IndexField_Turnover_set) + TotalVolumeTraded = property(_lev2mdapi.CTORATstpLev2IndexField_TotalVolumeTraded_get, _lev2mdapi.CTORATstpLev2IndexField_TotalVolumeTraded_set) + Info1 = property(_lev2mdapi.CTORATstpLev2IndexField_Info1_get, _lev2mdapi.CTORATstpLev2IndexField_Info1_set) + Info2 = property(_lev2mdapi.CTORATstpLev2IndexField_Info2_get, _lev2mdapi.CTORATstpLev2IndexField_Info2_set) + Info3 = property(_lev2mdapi.CTORATstpLev2IndexField_Info3_get, _lev2mdapi.CTORATstpLev2IndexField_Info3_set) + CloseIndex = property(_lev2mdapi.CTORATstpLev2IndexField_CloseIndex_get, _lev2mdapi.CTORATstpLev2IndexField_CloseIndex_set) + + def __init__(self): + _lev2mdapi.CTORATstpLev2IndexField_swiginit(self, _lev2mdapi.new_CTORATstpLev2IndexField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpLev2IndexField + +# Register CTORATstpLev2IndexField in _lev2mdapi: +_lev2mdapi.CTORATstpLev2IndexField_swigregister(CTORATstpLev2IndexField) + +class CTORATstpLev2TransactionField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + ExchangeID = property(_lev2mdapi.CTORATstpLev2TransactionField_ExchangeID_get, _lev2mdapi.CTORATstpLev2TransactionField_ExchangeID_set) + SecurityID = property(_lev2mdapi.CTORATstpLev2TransactionField_SecurityID_get, _lev2mdapi.CTORATstpLev2TransactionField_SecurityID_set) + TradeTime = property(_lev2mdapi.CTORATstpLev2TransactionField_TradeTime_get, _lev2mdapi.CTORATstpLev2TransactionField_TradeTime_set) + TradePrice = property(_lev2mdapi.CTORATstpLev2TransactionField_TradePrice_get, _lev2mdapi.CTORATstpLev2TransactionField_TradePrice_set) + TradeVolume = property(_lev2mdapi.CTORATstpLev2TransactionField_TradeVolume_get, _lev2mdapi.CTORATstpLev2TransactionField_TradeVolume_set) + ExecType = property(_lev2mdapi.CTORATstpLev2TransactionField_ExecType_get, _lev2mdapi.CTORATstpLev2TransactionField_ExecType_set) + MainSeq = property(_lev2mdapi.CTORATstpLev2TransactionField_MainSeq_get, _lev2mdapi.CTORATstpLev2TransactionField_MainSeq_set) + SubSeq = property(_lev2mdapi.CTORATstpLev2TransactionField_SubSeq_get, _lev2mdapi.CTORATstpLev2TransactionField_SubSeq_set) + BuyNo = property(_lev2mdapi.CTORATstpLev2TransactionField_BuyNo_get, _lev2mdapi.CTORATstpLev2TransactionField_BuyNo_set) + SellNo = property(_lev2mdapi.CTORATstpLev2TransactionField_SellNo_get, _lev2mdapi.CTORATstpLev2TransactionField_SellNo_set) + Info1 = property(_lev2mdapi.CTORATstpLev2TransactionField_Info1_get, _lev2mdapi.CTORATstpLev2TransactionField_Info1_set) + Info2 = property(_lev2mdapi.CTORATstpLev2TransactionField_Info2_get, _lev2mdapi.CTORATstpLev2TransactionField_Info2_set) + Info3 = property(_lev2mdapi.CTORATstpLev2TransactionField_Info3_get, _lev2mdapi.CTORATstpLev2TransactionField_Info3_set) + TradeBSFlag = property(_lev2mdapi.CTORATstpLev2TransactionField_TradeBSFlag_get, _lev2mdapi.CTORATstpLev2TransactionField_TradeBSFlag_set) + BizIndex = property(_lev2mdapi.CTORATstpLev2TransactionField_BizIndex_get, _lev2mdapi.CTORATstpLev2TransactionField_BizIndex_set) + + def __init__(self): + _lev2mdapi.CTORATstpLev2TransactionField_swiginit(self, _lev2mdapi.new_CTORATstpLev2TransactionField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpLev2TransactionField + +# Register CTORATstpLev2TransactionField in _lev2mdapi: +_lev2mdapi.CTORATstpLev2TransactionField_swigregister(CTORATstpLev2TransactionField) + +class CTORATstpLev2OrderDetailField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + ExchangeID = property(_lev2mdapi.CTORATstpLev2OrderDetailField_ExchangeID_get, _lev2mdapi.CTORATstpLev2OrderDetailField_ExchangeID_set) + SecurityID = property(_lev2mdapi.CTORATstpLev2OrderDetailField_SecurityID_get, _lev2mdapi.CTORATstpLev2OrderDetailField_SecurityID_set) + OrderTime = property(_lev2mdapi.CTORATstpLev2OrderDetailField_OrderTime_get, _lev2mdapi.CTORATstpLev2OrderDetailField_OrderTime_set) + Price = property(_lev2mdapi.CTORATstpLev2OrderDetailField_Price_get, _lev2mdapi.CTORATstpLev2OrderDetailField_Price_set) + Volume = property(_lev2mdapi.CTORATstpLev2OrderDetailField_Volume_get, _lev2mdapi.CTORATstpLev2OrderDetailField_Volume_set) + Side = property(_lev2mdapi.CTORATstpLev2OrderDetailField_Side_get, _lev2mdapi.CTORATstpLev2OrderDetailField_Side_set) + OrderType = property(_lev2mdapi.CTORATstpLev2OrderDetailField_OrderType_get, _lev2mdapi.CTORATstpLev2OrderDetailField_OrderType_set) + MainSeq = property(_lev2mdapi.CTORATstpLev2OrderDetailField_MainSeq_get, _lev2mdapi.CTORATstpLev2OrderDetailField_MainSeq_set) + SubSeq = property(_lev2mdapi.CTORATstpLev2OrderDetailField_SubSeq_get, _lev2mdapi.CTORATstpLev2OrderDetailField_SubSeq_set) + Info1 = property(_lev2mdapi.CTORATstpLev2OrderDetailField_Info1_get, _lev2mdapi.CTORATstpLev2OrderDetailField_Info1_set) + Info2 = property(_lev2mdapi.CTORATstpLev2OrderDetailField_Info2_get, _lev2mdapi.CTORATstpLev2OrderDetailField_Info2_set) + Info3 = property(_lev2mdapi.CTORATstpLev2OrderDetailField_Info3_get, _lev2mdapi.CTORATstpLev2OrderDetailField_Info3_set) + OrderNO = property(_lev2mdapi.CTORATstpLev2OrderDetailField_OrderNO_get, _lev2mdapi.CTORATstpLev2OrderDetailField_OrderNO_set) + OrderStatus = property(_lev2mdapi.CTORATstpLev2OrderDetailField_OrderStatus_get, _lev2mdapi.CTORATstpLev2OrderDetailField_OrderStatus_set) + BizIndex = property(_lev2mdapi.CTORATstpLev2OrderDetailField_BizIndex_get, _lev2mdapi.CTORATstpLev2OrderDetailField_BizIndex_set) + + def __init__(self): + _lev2mdapi.CTORATstpLev2OrderDetailField_swiginit(self, _lev2mdapi.new_CTORATstpLev2OrderDetailField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpLev2OrderDetailField + +# Register CTORATstpLev2OrderDetailField in _lev2mdapi: +_lev2mdapi.CTORATstpLev2OrderDetailField_swigregister(CTORATstpLev2OrderDetailField) + +class CTORATstpLev2PHMarketDataField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + SecurityID = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_SecurityID_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_SecurityID_set) + ExchangeID = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_ExchangeID_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_ExchangeID_set) + DataTimeStamp = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_DataTimeStamp_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_DataTimeStamp_set) + ClosePrice = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_ClosePrice_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_ClosePrice_set) + MDSecurityStat = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_MDSecurityStat_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_MDSecurityStat_set) + NumTrades = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_NumTrades_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_NumTrades_set) + TotalVolumeTrade = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_TotalVolumeTrade_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_TotalVolumeTrade_set) + TotalValueTrade = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_TotalValueTrade_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_TotalValueTrade_set) + TotalBidVolume = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_TotalBidVolume_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_TotalBidVolume_set) + TotalAskVolume = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_TotalAskVolume_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_TotalAskVolume_set) + WithdrawBuyNumber = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_WithdrawBuyNumber_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_WithdrawBuyNumber_set) + WithdrawBuyAmount = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_WithdrawBuyAmount_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_WithdrawBuyAmount_set) + WithdrawSellNumber = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_WithdrawSellNumber_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_WithdrawSellNumber_set) + WithdrawSellAmount = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_WithdrawSellAmount_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_WithdrawSellAmount_set) + BidOrderQty = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_BidOrderQty_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_BidOrderQty_set) + BidNumOrders = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_BidNumOrders_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_BidNumOrders_set) + AskOrderQty = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_AskOrderQty_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_AskOrderQty_set) + AskNumOrders = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_AskNumOrders_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_AskNumOrders_set) + Info1 = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_Info1_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_Info1_set) + Info2 = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_Info2_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_Info2_set) + Info3 = property(_lev2mdapi.CTORATstpLev2PHMarketDataField_Info3_get, _lev2mdapi.CTORATstpLev2PHMarketDataField_Info3_set) + + def __init__(self): + _lev2mdapi.CTORATstpLev2PHMarketDataField_swiginit(self, _lev2mdapi.new_CTORATstpLev2PHMarketDataField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpLev2PHMarketDataField + +# Register CTORATstpLev2PHMarketDataField in _lev2mdapi: +_lev2mdapi.CTORATstpLev2PHMarketDataField_swigregister(CTORATstpLev2PHMarketDataField) + +class CTORATstpLev2PHTransactionField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + ExchangeID = property(_lev2mdapi.CTORATstpLev2PHTransactionField_ExchangeID_get, _lev2mdapi.CTORATstpLev2PHTransactionField_ExchangeID_set) + SecurityID = property(_lev2mdapi.CTORATstpLev2PHTransactionField_SecurityID_get, _lev2mdapi.CTORATstpLev2PHTransactionField_SecurityID_set) + TradeTime = property(_lev2mdapi.CTORATstpLev2PHTransactionField_TradeTime_get, _lev2mdapi.CTORATstpLev2PHTransactionField_TradeTime_set) + TradePrice = property(_lev2mdapi.CTORATstpLev2PHTransactionField_TradePrice_get, _lev2mdapi.CTORATstpLev2PHTransactionField_TradePrice_set) + TradeVolume = property(_lev2mdapi.CTORATstpLev2PHTransactionField_TradeVolume_get, _lev2mdapi.CTORATstpLev2PHTransactionField_TradeVolume_set) + TradeMoney = property(_lev2mdapi.CTORATstpLev2PHTransactionField_TradeMoney_get, _lev2mdapi.CTORATstpLev2PHTransactionField_TradeMoney_set) + ExecType = property(_lev2mdapi.CTORATstpLev2PHTransactionField_ExecType_get, _lev2mdapi.CTORATstpLev2PHTransactionField_ExecType_set) + MainSeq = property(_lev2mdapi.CTORATstpLev2PHTransactionField_MainSeq_get, _lev2mdapi.CTORATstpLev2PHTransactionField_MainSeq_set) + SubSeq = property(_lev2mdapi.CTORATstpLev2PHTransactionField_SubSeq_get, _lev2mdapi.CTORATstpLev2PHTransactionField_SubSeq_set) + BuyNo = property(_lev2mdapi.CTORATstpLev2PHTransactionField_BuyNo_get, _lev2mdapi.CTORATstpLev2PHTransactionField_BuyNo_set) + SellNo = property(_lev2mdapi.CTORATstpLev2PHTransactionField_SellNo_get, _lev2mdapi.CTORATstpLev2PHTransactionField_SellNo_set) + Info1 = property(_lev2mdapi.CTORATstpLev2PHTransactionField_Info1_get, _lev2mdapi.CTORATstpLev2PHTransactionField_Info1_set) + Info2 = property(_lev2mdapi.CTORATstpLev2PHTransactionField_Info2_get, _lev2mdapi.CTORATstpLev2PHTransactionField_Info2_set) + Info3 = property(_lev2mdapi.CTORATstpLev2PHTransactionField_Info3_get, _lev2mdapi.CTORATstpLev2PHTransactionField_Info3_set) + TradeBSFlag = property(_lev2mdapi.CTORATstpLev2PHTransactionField_TradeBSFlag_get, _lev2mdapi.CTORATstpLev2PHTransactionField_TradeBSFlag_set) + + def __init__(self): + _lev2mdapi.CTORATstpLev2PHTransactionField_swiginit(self, _lev2mdapi.new_CTORATstpLev2PHTransactionField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpLev2PHTransactionField + +# Register CTORATstpLev2PHTransactionField in _lev2mdapi: +_lev2mdapi.CTORATstpLev2PHTransactionField_swigregister(CTORATstpLev2PHTransactionField) + +class CTORATstpLev2ResendTransactionField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + ExchangeID = property(_lev2mdapi.CTORATstpLev2ResendTransactionField_ExchangeID_get, _lev2mdapi.CTORATstpLev2ResendTransactionField_ExchangeID_set) + SecurityID = property(_lev2mdapi.CTORATstpLev2ResendTransactionField_SecurityID_get, _lev2mdapi.CTORATstpLev2ResendTransactionField_SecurityID_set) + TradeTime = property(_lev2mdapi.CTORATstpLev2ResendTransactionField_TradeTime_get, _lev2mdapi.CTORATstpLev2ResendTransactionField_TradeTime_set) + TradePrice = property(_lev2mdapi.CTORATstpLev2ResendTransactionField_TradePrice_get, _lev2mdapi.CTORATstpLev2ResendTransactionField_TradePrice_set) + TradeVolume = property(_lev2mdapi.CTORATstpLev2ResendTransactionField_TradeVolume_get, _lev2mdapi.CTORATstpLev2ResendTransactionField_TradeVolume_set) + ExecType = property(_lev2mdapi.CTORATstpLev2ResendTransactionField_ExecType_get, _lev2mdapi.CTORATstpLev2ResendTransactionField_ExecType_set) + MainSeq = property(_lev2mdapi.CTORATstpLev2ResendTransactionField_MainSeq_get, _lev2mdapi.CTORATstpLev2ResendTransactionField_MainSeq_set) + SubSeq = property(_lev2mdapi.CTORATstpLev2ResendTransactionField_SubSeq_get, _lev2mdapi.CTORATstpLev2ResendTransactionField_SubSeq_set) + BuyNo = property(_lev2mdapi.CTORATstpLev2ResendTransactionField_BuyNo_get, _lev2mdapi.CTORATstpLev2ResendTransactionField_BuyNo_set) + SellNo = property(_lev2mdapi.CTORATstpLev2ResendTransactionField_SellNo_get, _lev2mdapi.CTORATstpLev2ResendTransactionField_SellNo_set) + Info1 = property(_lev2mdapi.CTORATstpLev2ResendTransactionField_Info1_get, _lev2mdapi.CTORATstpLev2ResendTransactionField_Info1_set) + Info2 = property(_lev2mdapi.CTORATstpLev2ResendTransactionField_Info2_get, _lev2mdapi.CTORATstpLev2ResendTransactionField_Info2_set) + Info3 = property(_lev2mdapi.CTORATstpLev2ResendTransactionField_Info3_get, _lev2mdapi.CTORATstpLev2ResendTransactionField_Info3_set) + TradeBSFlag = property(_lev2mdapi.CTORATstpLev2ResendTransactionField_TradeBSFlag_get, _lev2mdapi.CTORATstpLev2ResendTransactionField_TradeBSFlag_set) + BizIndex = property(_lev2mdapi.CTORATstpLev2ResendTransactionField_BizIndex_get, _lev2mdapi.CTORATstpLev2ResendTransactionField_BizIndex_set) + + def __init__(self): + _lev2mdapi.CTORATstpLev2ResendTransactionField_swiginit(self, _lev2mdapi.new_CTORATstpLev2ResendTransactionField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpLev2ResendTransactionField + +# Register CTORATstpLev2ResendTransactionField in _lev2mdapi: +_lev2mdapi.CTORATstpLev2ResendTransactionField_swigregister(CTORATstpLev2ResendTransactionField) + +class CTORATstpLev2ResendOrderDetailField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + ExchangeID = property(_lev2mdapi.CTORATstpLev2ResendOrderDetailField_ExchangeID_get, _lev2mdapi.CTORATstpLev2ResendOrderDetailField_ExchangeID_set) + SecurityID = property(_lev2mdapi.CTORATstpLev2ResendOrderDetailField_SecurityID_get, _lev2mdapi.CTORATstpLev2ResendOrderDetailField_SecurityID_set) + OrderTime = property(_lev2mdapi.CTORATstpLev2ResendOrderDetailField_OrderTime_get, _lev2mdapi.CTORATstpLev2ResendOrderDetailField_OrderTime_set) + Price = property(_lev2mdapi.CTORATstpLev2ResendOrderDetailField_Price_get, _lev2mdapi.CTORATstpLev2ResendOrderDetailField_Price_set) + Volume = property(_lev2mdapi.CTORATstpLev2ResendOrderDetailField_Volume_get, _lev2mdapi.CTORATstpLev2ResendOrderDetailField_Volume_set) + Side = property(_lev2mdapi.CTORATstpLev2ResendOrderDetailField_Side_get, _lev2mdapi.CTORATstpLev2ResendOrderDetailField_Side_set) + OrderType = property(_lev2mdapi.CTORATstpLev2ResendOrderDetailField_OrderType_get, _lev2mdapi.CTORATstpLev2ResendOrderDetailField_OrderType_set) + MainSeq = property(_lev2mdapi.CTORATstpLev2ResendOrderDetailField_MainSeq_get, _lev2mdapi.CTORATstpLev2ResendOrderDetailField_MainSeq_set) + SubSeq = property(_lev2mdapi.CTORATstpLev2ResendOrderDetailField_SubSeq_get, _lev2mdapi.CTORATstpLev2ResendOrderDetailField_SubSeq_set) + Info1 = property(_lev2mdapi.CTORATstpLev2ResendOrderDetailField_Info1_get, _lev2mdapi.CTORATstpLev2ResendOrderDetailField_Info1_set) + Info2 = property(_lev2mdapi.CTORATstpLev2ResendOrderDetailField_Info2_get, _lev2mdapi.CTORATstpLev2ResendOrderDetailField_Info2_set) + Info3 = property(_lev2mdapi.CTORATstpLev2ResendOrderDetailField_Info3_get, _lev2mdapi.CTORATstpLev2ResendOrderDetailField_Info3_set) + OrderNO = property(_lev2mdapi.CTORATstpLev2ResendOrderDetailField_OrderNO_get, _lev2mdapi.CTORATstpLev2ResendOrderDetailField_OrderNO_set) + OrderStatus = property(_lev2mdapi.CTORATstpLev2ResendOrderDetailField_OrderStatus_get, _lev2mdapi.CTORATstpLev2ResendOrderDetailField_OrderStatus_set) + BizIndex = property(_lev2mdapi.CTORATstpLev2ResendOrderDetailField_BizIndex_get, _lev2mdapi.CTORATstpLev2ResendOrderDetailField_BizIndex_set) + + def __init__(self): + _lev2mdapi.CTORATstpLev2ResendOrderDetailField_swiginit(self, _lev2mdapi.new_CTORATstpLev2ResendOrderDetailField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpLev2ResendOrderDetailField + +# Register CTORATstpLev2ResendOrderDetailField in _lev2mdapi: +_lev2mdapi.CTORATstpLev2ResendOrderDetailField_swigregister(CTORATstpLev2ResendOrderDetailField) + +class CTORATstpLev2XTSMarketDataField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + SecurityID = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_SecurityID_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_SecurityID_set) + ExchangeID = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_ExchangeID_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_ExchangeID_set) + DataTimeStamp = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_DataTimeStamp_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_DataTimeStamp_set) + PreClosePrice = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_PreClosePrice_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_PreClosePrice_set) + OpenPrice = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_OpenPrice_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_OpenPrice_set) + NumTrades = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_NumTrades_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_NumTrades_set) + TotalVolumeTrade = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_TotalVolumeTrade_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_TotalVolumeTrade_set) + TotalValueTrade = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_TotalValueTrade_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_TotalValueTrade_set) + TotalBidVolume = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_TotalBidVolume_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_TotalBidVolume_set) + AvgBidPrice = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AvgBidPrice_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AvgBidPrice_set) + TotalAskVolume = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_TotalAskVolume_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_TotalAskVolume_set) + AvgAskPrice = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AvgAskPrice_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AvgAskPrice_set) + HighestPrice = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_HighestPrice_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_HighestPrice_set) + LowestPrice = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_LowestPrice_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_LowestPrice_set) + LastPrice = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_LastPrice_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_LastPrice_set) + BidPrice1 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice1_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice1_set) + BidVolume1 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume1_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume1_set) + Bid1NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid1NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid1NumOrders_set) + AskPrice1 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice1_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice1_set) + AskVolume1 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume1_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume1_set) + Ask1NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask1NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask1NumOrders_set) + AskPrice2 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice2_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice2_set) + AskVolume2 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume2_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume2_set) + Ask2NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask2NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask2NumOrders_set) + AskPrice3 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice3_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice3_set) + AskVolume3 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume3_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume3_set) + Ask3NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask3NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask3NumOrders_set) + BidPrice2 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice2_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice2_set) + BidVolume2 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume2_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume2_set) + Bid2NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid2NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid2NumOrders_set) + BidPrice3 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice3_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice3_set) + BidVolume3 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume3_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume3_set) + Bid3NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid3NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid3NumOrders_set) + AskPrice4 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice4_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice4_set) + AskVolume4 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume4_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume4_set) + Ask4NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask4NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask4NumOrders_set) + AskPrice5 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice5_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice5_set) + AskVolume5 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume5_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume5_set) + Ask5NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask5NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask5NumOrders_set) + BidPrice4 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice4_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice4_set) + BidVolume4 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume4_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume4_set) + Bid4NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid4NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid4NumOrders_set) + BidPrice5 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice5_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice5_set) + BidVolume5 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume5_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume5_set) + Bid5NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid5NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid5NumOrders_set) + AskPrice6 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice6_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice6_set) + AskVolume6 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume6_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume6_set) + Ask6NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask6NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask6NumOrders_set) + AskPrice7 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice7_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice7_set) + AskVolume7 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume7_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume7_set) + Ask7NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask7NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask7NumOrders_set) + BidPrice6 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice6_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice6_set) + BidVolume6 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume6_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume6_set) + Bid6NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid6NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid6NumOrders_set) + BidPrice7 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice7_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice7_set) + BidVolume7 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume7_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume7_set) + Bid7NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid7NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid7NumOrders_set) + AskPrice8 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice8_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice8_set) + AskVolume8 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume8_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume8_set) + Ask8NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask8NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask8NumOrders_set) + AskPrice9 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice9_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice9_set) + AskVolume9 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume9_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume9_set) + Ask9NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask9NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask9NumOrders_set) + BidPrice8 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice8_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice8_set) + BidVolume8 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume8_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume8_set) + Bid8NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid8NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid8NumOrders_set) + BidPrice9 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice9_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice9_set) + BidVolume9 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume9_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume9_set) + Bid9NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid9NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid9NumOrders_set) + BidPrice10 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice10_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidPrice10_set) + BidVolume10 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume10_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidVolume10_set) + Bid10NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid10NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Bid10NumOrders_set) + AskPrice10 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice10_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskPrice10_set) + AskVolume10 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume10_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_AskVolume10_set) + Ask10NumOrders = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask10NumOrders_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Ask10NumOrders_set) + ClosePrice = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_ClosePrice_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_ClosePrice_set) + MDSecurityStat = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_MDSecurityStat_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_MDSecurityStat_set) + TotalBidNumber = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_TotalBidNumber_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_TotalBidNumber_set) + TotalOfferNumber = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_TotalOfferNumber_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_TotalOfferNumber_set) + BidTradeMaxDuration = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_BidTradeMaxDuration_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_BidTradeMaxDuration_set) + OfferTradeMaxDuration = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_OfferTradeMaxDuration_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_OfferTradeMaxDuration_set) + WithdrawBuyNumber = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_WithdrawBuyNumber_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_WithdrawBuyNumber_set) + WithdrawBuyAmount = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_WithdrawBuyAmount_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_WithdrawBuyAmount_set) + WithdrawBuyMoney = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_WithdrawBuyMoney_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_WithdrawBuyMoney_set) + WithdrawSellNumber = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_WithdrawSellNumber_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_WithdrawSellNumber_set) + WithdrawSellAmount = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_WithdrawSellAmount_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_WithdrawSellAmount_set) + WithdrawSellMoney = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_WithdrawSellMoney_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_WithdrawSellMoney_set) + Info1 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Info1_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Info1_set) + Info2 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Info2_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Info2_set) + Info3 = property(_lev2mdapi.CTORATstpLev2XTSMarketDataField_Info3_get, _lev2mdapi.CTORATstpLev2XTSMarketDataField_Info3_set) + + def __init__(self): + _lev2mdapi.CTORATstpLev2XTSMarketDataField_swiginit(self, _lev2mdapi.new_CTORATstpLev2XTSMarketDataField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpLev2XTSMarketDataField + +# Register CTORATstpLev2XTSMarketDataField in _lev2mdapi: +_lev2mdapi.CTORATstpLev2XTSMarketDataField_swigregister(CTORATstpLev2XTSMarketDataField) + +class CTORATstpLev2XTSTickField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + ExchangeID = property(_lev2mdapi.CTORATstpLev2XTSTickField_ExchangeID_get, _lev2mdapi.CTORATstpLev2XTSTickField_ExchangeID_set) + SecurityID = property(_lev2mdapi.CTORATstpLev2XTSTickField_SecurityID_get, _lev2mdapi.CTORATstpLev2XTSTickField_SecurityID_set) + MainSeq = property(_lev2mdapi.CTORATstpLev2XTSTickField_MainSeq_get, _lev2mdapi.CTORATstpLev2XTSTickField_MainSeq_set) + SubSeq = property(_lev2mdapi.CTORATstpLev2XTSTickField_SubSeq_get, _lev2mdapi.CTORATstpLev2XTSTickField_SubSeq_set) + TickTime = property(_lev2mdapi.CTORATstpLev2XTSTickField_TickTime_get, _lev2mdapi.CTORATstpLev2XTSTickField_TickTime_set) + TickType = property(_lev2mdapi.CTORATstpLev2XTSTickField_TickType_get, _lev2mdapi.CTORATstpLev2XTSTickField_TickType_set) + BuyNo = property(_lev2mdapi.CTORATstpLev2XTSTickField_BuyNo_get, _lev2mdapi.CTORATstpLev2XTSTickField_BuyNo_set) + SellNo = property(_lev2mdapi.CTORATstpLev2XTSTickField_SellNo_get, _lev2mdapi.CTORATstpLev2XTSTickField_SellNo_set) + Price = property(_lev2mdapi.CTORATstpLev2XTSTickField_Price_get, _lev2mdapi.CTORATstpLev2XTSTickField_Price_set) + Volume = property(_lev2mdapi.CTORATstpLev2XTSTickField_Volume_get, _lev2mdapi.CTORATstpLev2XTSTickField_Volume_set) + TradeMoney = property(_lev2mdapi.CTORATstpLev2XTSTickField_TradeMoney_get, _lev2mdapi.CTORATstpLev2XTSTickField_TradeMoney_set) + Side = property(_lev2mdapi.CTORATstpLev2XTSTickField_Side_get, _lev2mdapi.CTORATstpLev2XTSTickField_Side_set) + TradeBSFlag = property(_lev2mdapi.CTORATstpLev2XTSTickField_TradeBSFlag_get, _lev2mdapi.CTORATstpLev2XTSTickField_TradeBSFlag_set) + MDSecurityStat = property(_lev2mdapi.CTORATstpLev2XTSTickField_MDSecurityStat_get, _lev2mdapi.CTORATstpLev2XTSTickField_MDSecurityStat_set) + Info1 = property(_lev2mdapi.CTORATstpLev2XTSTickField_Info1_get, _lev2mdapi.CTORATstpLev2XTSTickField_Info1_set) + Info2 = property(_lev2mdapi.CTORATstpLev2XTSTickField_Info2_get, _lev2mdapi.CTORATstpLev2XTSTickField_Info2_set) + Info3 = property(_lev2mdapi.CTORATstpLev2XTSTickField_Info3_get, _lev2mdapi.CTORATstpLev2XTSTickField_Info3_set) + + def __init__(self): + _lev2mdapi.CTORATstpLev2XTSTickField_swiginit(self, _lev2mdapi.new_CTORATstpLev2XTSTickField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpLev2XTSTickField + +# Register CTORATstpLev2XTSTickField in _lev2mdapi: +_lev2mdapi.CTORATstpLev2XTSTickField_swigregister(CTORATstpLev2XTSTickField) + +class CTORATstpLev2NGTSTickField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + ExchangeID = property(_lev2mdapi.CTORATstpLev2NGTSTickField_ExchangeID_get, _lev2mdapi.CTORATstpLev2NGTSTickField_ExchangeID_set) + SecurityID = property(_lev2mdapi.CTORATstpLev2NGTSTickField_SecurityID_get, _lev2mdapi.CTORATstpLev2NGTSTickField_SecurityID_set) + MainSeq = property(_lev2mdapi.CTORATstpLev2NGTSTickField_MainSeq_get, _lev2mdapi.CTORATstpLev2NGTSTickField_MainSeq_set) + SubSeq = property(_lev2mdapi.CTORATstpLev2NGTSTickField_SubSeq_get, _lev2mdapi.CTORATstpLev2NGTSTickField_SubSeq_set) + TickTime = property(_lev2mdapi.CTORATstpLev2NGTSTickField_TickTime_get, _lev2mdapi.CTORATstpLev2NGTSTickField_TickTime_set) + TickType = property(_lev2mdapi.CTORATstpLev2NGTSTickField_TickType_get, _lev2mdapi.CTORATstpLev2NGTSTickField_TickType_set) + BuyNo = property(_lev2mdapi.CTORATstpLev2NGTSTickField_BuyNo_get, _lev2mdapi.CTORATstpLev2NGTSTickField_BuyNo_set) + SellNo = property(_lev2mdapi.CTORATstpLev2NGTSTickField_SellNo_get, _lev2mdapi.CTORATstpLev2NGTSTickField_SellNo_set) + Price = property(_lev2mdapi.CTORATstpLev2NGTSTickField_Price_get, _lev2mdapi.CTORATstpLev2NGTSTickField_Price_set) + Volume = property(_lev2mdapi.CTORATstpLev2NGTSTickField_Volume_get, _lev2mdapi.CTORATstpLev2NGTSTickField_Volume_set) + TradeMoney = property(_lev2mdapi.CTORATstpLev2NGTSTickField_TradeMoney_get, _lev2mdapi.CTORATstpLev2NGTSTickField_TradeMoney_set) + Side = property(_lev2mdapi.CTORATstpLev2NGTSTickField_Side_get, _lev2mdapi.CTORATstpLev2NGTSTickField_Side_set) + TradeBSFlag = property(_lev2mdapi.CTORATstpLev2NGTSTickField_TradeBSFlag_get, _lev2mdapi.CTORATstpLev2NGTSTickField_TradeBSFlag_set) + MDSecurityStat = property(_lev2mdapi.CTORATstpLev2NGTSTickField_MDSecurityStat_get, _lev2mdapi.CTORATstpLev2NGTSTickField_MDSecurityStat_set) + Info1 = property(_lev2mdapi.CTORATstpLev2NGTSTickField_Info1_get, _lev2mdapi.CTORATstpLev2NGTSTickField_Info1_set) + Info2 = property(_lev2mdapi.CTORATstpLev2NGTSTickField_Info2_get, _lev2mdapi.CTORATstpLev2NGTSTickField_Info2_set) + Info3 = property(_lev2mdapi.CTORATstpLev2NGTSTickField_Info3_get, _lev2mdapi.CTORATstpLev2NGTSTickField_Info3_set) + + def __init__(self): + _lev2mdapi.CTORATstpLev2NGTSTickField_swiginit(self, _lev2mdapi.new_CTORATstpLev2NGTSTickField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpLev2NGTSTickField + +# Register CTORATstpLev2NGTSTickField in _lev2mdapi: +_lev2mdapi.CTORATstpLev2NGTSTickField_swigregister(CTORATstpLev2NGTSTickField) + +class CTORATstpLev2BondMarketDataField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + SecurityID = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_SecurityID_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_SecurityID_set) + ExchangeID = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_ExchangeID_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_ExchangeID_set) + DataTimeStamp = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_DataTimeStamp_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_DataTimeStamp_set) + PreClosePrice = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_PreClosePrice_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_PreClosePrice_set) + OpenPrice = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_OpenPrice_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_OpenPrice_set) + AvgPreClosePrice = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AvgPreClosePrice_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AvgPreClosePrice_set) + NumTrades = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_NumTrades_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_NumTrades_set) + TotalVolumeTrade = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_TotalVolumeTrade_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_TotalVolumeTrade_set) + TotalValueTrade = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_TotalValueTrade_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_TotalValueTrade_set) + AuctionVolumeTrade = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AuctionVolumeTrade_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AuctionVolumeTrade_set) + AuctionValueTrade = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AuctionValueTrade_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AuctionValueTrade_set) + TotalBidVolume = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_TotalBidVolume_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_TotalBidVolume_set) + AvgBidPrice = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AvgBidPrice_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AvgBidPrice_set) + TotalAskVolume = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_TotalAskVolume_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_TotalAskVolume_set) + AvgAskPrice = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AvgAskPrice_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AvgAskPrice_set) + HighestPrice = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_HighestPrice_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_HighestPrice_set) + LowestPrice = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_LowestPrice_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_LowestPrice_set) + LastPrice = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_LastPrice_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_LastPrice_set) + AuctionLastPrice = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AuctionLastPrice_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AuctionLastPrice_set) + AvgPrice = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AvgPrice_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AvgPrice_set) + PriceUpDown1 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_PriceUpDown1_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_PriceUpDown1_set) + PriceUpDown2 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_PriceUpDown2_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_PriceUpDown2_set) + ClosePrice = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_ClosePrice_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_ClosePrice_set) + MDSecurityStat = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_MDSecurityStat_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_MDSecurityStat_set) + BidPrice1 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice1_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice1_set) + BidVolume1 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume1_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume1_set) + Bid1NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Bid1NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Bid1NumOrders_set) + AskPrice1 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice1_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice1_set) + AskVolume1 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume1_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume1_set) + Ask1NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Ask1NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Ask1NumOrders_set) + AskPrice2 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice2_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice2_set) + AskVolume2 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume2_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume2_set) + Ask2NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Ask2NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Ask2NumOrders_set) + AskPrice3 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice3_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice3_set) + AskVolume3 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume3_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume3_set) + Ask3NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Ask3NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Ask3NumOrders_set) + BidPrice2 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice2_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice2_set) + BidVolume2 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume2_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume2_set) + Bid2NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Bid2NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Bid2NumOrders_set) + BidPrice3 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice3_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice3_set) + BidVolume3 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume3_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume3_set) + Bid3NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Bid3NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Bid3NumOrders_set) + AskPrice4 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice4_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice4_set) + AskVolume4 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume4_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume4_set) + Ask4NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Ask4NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Ask4NumOrders_set) + AskPrice5 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice5_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice5_set) + AskVolume5 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume5_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume5_set) + Ask5NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Ask5NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Ask5NumOrders_set) + BidPrice4 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice4_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice4_set) + BidVolume4 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume4_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume4_set) + Bid4NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Bid4NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Bid4NumOrders_set) + BidPrice5 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice5_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice5_set) + BidVolume5 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume5_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume5_set) + Bid5NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Bid5NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Bid5NumOrders_set) + AskPrice6 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice6_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice6_set) + AskVolume6 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume6_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume6_set) + Ask6NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Ask6NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Ask6NumOrders_set) + AskPrice7 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice7_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice7_set) + AskVolume7 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume7_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume7_set) + Ask7NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Ask7NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Ask7NumOrders_set) + BidPrice6 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice6_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice6_set) + BidVolume6 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume6_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume6_set) + Bid6NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Bid6NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Bid6NumOrders_set) + BidPrice7 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice7_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice7_set) + BidVolume7 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume7_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume7_set) + Bid7NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Bid7NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Bid7NumOrders_set) + AskPrice8 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice8_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice8_set) + AskVolume8 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume8_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume8_set) + Ask8NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Ask8NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Ask8NumOrders_set) + AskPrice9 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice9_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice9_set) + AskVolume9 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume9_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume9_set) + Ask9NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Ask9NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Ask9NumOrders_set) + BidPrice8 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice8_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice8_set) + BidVolume8 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume8_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume8_set) + Bid8NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Bid8NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Bid8NumOrders_set) + BidPrice9 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice9_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice9_set) + BidVolume9 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume9_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume9_set) + Bid9NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Bid9NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Bid9NumOrders_set) + BidPrice10 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice10_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidPrice10_set) + BidVolume10 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume10_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_BidVolume10_set) + Bid10NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Bid10NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Bid10NumOrders_set) + AskPrice10 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice10_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskPrice10_set) + AskVolume10 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume10_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_AskVolume10_set) + Ask10NumOrders = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Ask10NumOrders_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Ask10NumOrders_set) + Info1 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Info1_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Info1_set) + Info2 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Info2_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Info2_set) + Info3 = property(_lev2mdapi.CTORATstpLev2BondMarketDataField_Info3_get, _lev2mdapi.CTORATstpLev2BondMarketDataField_Info3_set) + + def __init__(self): + _lev2mdapi.CTORATstpLev2BondMarketDataField_swiginit(self, _lev2mdapi.new_CTORATstpLev2BondMarketDataField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpLev2BondMarketDataField + +# Register CTORATstpLev2BondMarketDataField in _lev2mdapi: +_lev2mdapi.CTORATstpLev2BondMarketDataField_swigregister(CTORATstpLev2BondMarketDataField) + +class CTORATstpLev2BondOrderDetailField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + ExchangeID = property(_lev2mdapi.CTORATstpLev2BondOrderDetailField_ExchangeID_get, _lev2mdapi.CTORATstpLev2BondOrderDetailField_ExchangeID_set) + SecurityID = property(_lev2mdapi.CTORATstpLev2BondOrderDetailField_SecurityID_get, _lev2mdapi.CTORATstpLev2BondOrderDetailField_SecurityID_set) + OrderTime = property(_lev2mdapi.CTORATstpLev2BondOrderDetailField_OrderTime_get, _lev2mdapi.CTORATstpLev2BondOrderDetailField_OrderTime_set) + Price = property(_lev2mdapi.CTORATstpLev2BondOrderDetailField_Price_get, _lev2mdapi.CTORATstpLev2BondOrderDetailField_Price_set) + Volume = property(_lev2mdapi.CTORATstpLev2BondOrderDetailField_Volume_get, _lev2mdapi.CTORATstpLev2BondOrderDetailField_Volume_set) + Side = property(_lev2mdapi.CTORATstpLev2BondOrderDetailField_Side_get, _lev2mdapi.CTORATstpLev2BondOrderDetailField_Side_set) + OrderType = property(_lev2mdapi.CTORATstpLev2BondOrderDetailField_OrderType_get, _lev2mdapi.CTORATstpLev2BondOrderDetailField_OrderType_set) + MainSeq = property(_lev2mdapi.CTORATstpLev2BondOrderDetailField_MainSeq_get, _lev2mdapi.CTORATstpLev2BondOrderDetailField_MainSeq_set) + SubSeq = property(_lev2mdapi.CTORATstpLev2BondOrderDetailField_SubSeq_get, _lev2mdapi.CTORATstpLev2BondOrderDetailField_SubSeq_set) + Info1 = property(_lev2mdapi.CTORATstpLev2BondOrderDetailField_Info1_get, _lev2mdapi.CTORATstpLev2BondOrderDetailField_Info1_set) + Info2 = property(_lev2mdapi.CTORATstpLev2BondOrderDetailField_Info2_get, _lev2mdapi.CTORATstpLev2BondOrderDetailField_Info2_set) + Info3 = property(_lev2mdapi.CTORATstpLev2BondOrderDetailField_Info3_get, _lev2mdapi.CTORATstpLev2BondOrderDetailField_Info3_set) + + def __init__(self): + _lev2mdapi.CTORATstpLev2BondOrderDetailField_swiginit(self, _lev2mdapi.new_CTORATstpLev2BondOrderDetailField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpLev2BondOrderDetailField + +# Register CTORATstpLev2BondOrderDetailField in _lev2mdapi: +_lev2mdapi.CTORATstpLev2BondOrderDetailField_swigregister(CTORATstpLev2BondOrderDetailField) + +class CTORATstpLev2BondTransactionField(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + ExchangeID = property(_lev2mdapi.CTORATstpLev2BondTransactionField_ExchangeID_get, _lev2mdapi.CTORATstpLev2BondTransactionField_ExchangeID_set) + SecurityID = property(_lev2mdapi.CTORATstpLev2BondTransactionField_SecurityID_get, _lev2mdapi.CTORATstpLev2BondTransactionField_SecurityID_set) + TradeTime = property(_lev2mdapi.CTORATstpLev2BondTransactionField_TradeTime_get, _lev2mdapi.CTORATstpLev2BondTransactionField_TradeTime_set) + TradePrice = property(_lev2mdapi.CTORATstpLev2BondTransactionField_TradePrice_get, _lev2mdapi.CTORATstpLev2BondTransactionField_TradePrice_set) + TradeVolume = property(_lev2mdapi.CTORATstpLev2BondTransactionField_TradeVolume_get, _lev2mdapi.CTORATstpLev2BondTransactionField_TradeVolume_set) + ExecType = property(_lev2mdapi.CTORATstpLev2BondTransactionField_ExecType_get, _lev2mdapi.CTORATstpLev2BondTransactionField_ExecType_set) + MainSeq = property(_lev2mdapi.CTORATstpLev2BondTransactionField_MainSeq_get, _lev2mdapi.CTORATstpLev2BondTransactionField_MainSeq_set) + SubSeq = property(_lev2mdapi.CTORATstpLev2BondTransactionField_SubSeq_get, _lev2mdapi.CTORATstpLev2BondTransactionField_SubSeq_set) + BuyNo = property(_lev2mdapi.CTORATstpLev2BondTransactionField_BuyNo_get, _lev2mdapi.CTORATstpLev2BondTransactionField_BuyNo_set) + SellNo = property(_lev2mdapi.CTORATstpLev2BondTransactionField_SellNo_get, _lev2mdapi.CTORATstpLev2BondTransactionField_SellNo_set) + Info1 = property(_lev2mdapi.CTORATstpLev2BondTransactionField_Info1_get, _lev2mdapi.CTORATstpLev2BondTransactionField_Info1_set) + Info2 = property(_lev2mdapi.CTORATstpLev2BondTransactionField_Info2_get, _lev2mdapi.CTORATstpLev2BondTransactionField_Info2_set) + Info3 = property(_lev2mdapi.CTORATstpLev2BondTransactionField_Info3_get, _lev2mdapi.CTORATstpLev2BondTransactionField_Info3_set) + + def __init__(self): + _lev2mdapi.CTORATstpLev2BondTransactionField_swiginit(self, _lev2mdapi.new_CTORATstpLev2BondTransactionField()) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpLev2BondTransactionField + +# Register CTORATstpLev2BondTransactionField in _lev2mdapi: +_lev2mdapi.CTORATstpLev2BondTransactionField_swigregister(CTORATstpLev2BondTransactionField) + +class CTORATstpLev2MdSpi(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + __repr__ = _swig_repr + + def OnFrontConnected(self): + return _lev2mdapi.CTORATstpLev2MdSpi_OnFrontConnected(self) + + def OnFrontDisconnected(self, nReason): + return _lev2mdapi.CTORATstpLev2MdSpi_OnFrontDisconnected(self, nReason) + + def OnRspError(self, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspError(self, pRspInfo, nRequestID, bIsLast) + + def OnRspUserLogin(self, pRspUserLogin, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspUserLogin(self, pRspUserLogin, pRspInfo, nRequestID, bIsLast) + + def OnRspUserLogout(self, pUserLogout, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspUserLogout(self, pUserLogout, pRspInfo, nRequestID, bIsLast) + + def OnRspSubMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspSubMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspUnSubMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspUnSubMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspSubIndex(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspSubIndex(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspUnSubIndex(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspUnSubIndex(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspSubTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspSubTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspUnSubTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspUnSubTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspSubOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspSubOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspUnSubOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspUnSubOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspSubPHMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspSubPHMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspUnSubPHMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspUnSubPHMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspSubPHTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspSubPHTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspUnSubPHTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspUnSubPHTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspSubResendTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspSubResendTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspUnSubResendTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspUnSubResendTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspSubResendOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspSubResendOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspUnSubResendOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspUnSubResendOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspSubXTSMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspSubXTSMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspUnSubXTSMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspUnSubXTSMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspSubXTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspSubXTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspUnSubXTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspUnSubXTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspSubNGTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspSubNGTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspUnSubNGTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspUnSubNGTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspSubBondMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspSubBondMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspUnSubBondMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspUnSubBondMarketData(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspSubBondTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspSubBondTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspUnSubBondTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspUnSubBondTransaction(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspSubBondOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspSubBondOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRspUnSubBondOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRspUnSubBondOrderDetail(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast) + + def OnRtnMarketData(self, pMarketData, FirstLevelBuyNum, FirstLevelBuyOrderVolumes, FirstLevelSellNum, FirstLevelSellOrderVolumes): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRtnMarketData(self, pMarketData, FirstLevelBuyNum, FirstLevelBuyOrderVolumes, FirstLevelSellNum, FirstLevelSellOrderVolumes) + + def OnRtnIndex(self, pIndex): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRtnIndex(self, pIndex) + + def OnRtnTransaction(self, pTransaction): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRtnTransaction(self, pTransaction) + + def OnRtnOrderDetail(self, pOrderDetail): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRtnOrderDetail(self, pOrderDetail) + + def OnRtnPHMarketData(self, pPHMarketData, FirstLevelBuyNum, FirstLevelBuyOrderVolumes, FirstLevelSellNum, FirstLevelSellOrderVolumes): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRtnPHMarketData(self, pPHMarketData, FirstLevelBuyNum, FirstLevelBuyOrderVolumes, FirstLevelSellNum, FirstLevelSellOrderVolumes) + + def OnRtnPHTransaction(self, pTransaction): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRtnPHTransaction(self, pTransaction) + + def OnRtnResendTransaction(self, pTransaction): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRtnResendTransaction(self, pTransaction) + + def OnRtnResendOrderDetail(self, pOrderDetail): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRtnResendOrderDetail(self, pOrderDetail) + + def OnRtnXTSMarketData(self, pMarketData, FirstLevelBuyNum, FirstLevelBuyOrderVolumes, FirstLevelSellNum, FirstLevelSellOrderVolumes): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRtnXTSMarketData(self, pMarketData, FirstLevelBuyNum, FirstLevelBuyOrderVolumes, FirstLevelSellNum, FirstLevelSellOrderVolumes) + + def OnRtnXTSTick(self, pTick): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRtnXTSTick(self, pTick) + + def OnRtnNGTSTick(self, pTick): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRtnNGTSTick(self, pTick) + + def OnRtnBondMarketData(self, pMarketData, FirstLevelBuyNum, FirstLevelBuyOrderVolumes, FirstLevelSellNum, FirstLevelSellOrderVolumes): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRtnBondMarketData(self, pMarketData, FirstLevelBuyNum, FirstLevelBuyOrderVolumes, FirstLevelSellNum, FirstLevelSellOrderVolumes) + + def OnRtnBondTransaction(self, pTransaction): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRtnBondTransaction(self, pTransaction) + + def OnRtnBondOrderDetail(self, pOrderDetail): + return _lev2mdapi.CTORATstpLev2MdSpi_OnRtnBondOrderDetail(self, pOrderDetail) + + def __init__(self): + if self.__class__ == CTORATstpLev2MdSpi: + _self = None + else: + _self = self + _lev2mdapi.CTORATstpLev2MdSpi_swiginit(self, _lev2mdapi.new_CTORATstpLev2MdSpi(_self, )) + __swig_destroy__ = _lev2mdapi.delete_CTORATstpLev2MdSpi + def __disown__(self): + self.this.disown() + _lev2mdapi.disown_CTORATstpLev2MdSpi(self) + return weakref.proxy(self) + +# Register CTORATstpLev2MdSpi in _lev2mdapi: +_lev2mdapi.CTORATstpLev2MdSpi_swigregister(CTORATstpLev2MdSpi) + +class CTORATstpLev2MdApi(object): + thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") + + def __init__(self, *args, **kwargs): + raise AttributeError("No constructor defined - class is abstract") + __repr__ = _swig_repr + + @staticmethod + def CreateTstpLev2MdApi(*args): + return _lev2mdapi.CTORATstpLev2MdApi_CreateTstpLev2MdApi(*args) + + @staticmethod + def GetApiVersion(): + return _lev2mdapi.CTORATstpLev2MdApi_GetApiVersion() + + def Release(self): + return _lev2mdapi.CTORATstpLev2MdApi_Release(self) + + def Init(self, *args): + return _lev2mdapi.CTORATstpLev2MdApi_Init(self, *args) + + def Join(self): + return _lev2mdapi.CTORATstpLev2MdApi_Join(self) + + def RegisterFront(self, pszFrontAddress): + return _lev2mdapi.CTORATstpLev2MdApi_RegisterFront(self, pszFrontAddress) + + def RegisterNameServer(self, pszNsAddress): + return _lev2mdapi.CTORATstpLev2MdApi_RegisterNameServer(self, pszNsAddress) + + def RegisterMulticast(self, *args): + return _lev2mdapi.CTORATstpLev2MdApi_RegisterMulticast(self, *args) + + def RegisterSpi(self, pSpi): + return _lev2mdapi.CTORATstpLev2MdApi_RegisterSpi(self, pSpi) + + def DeclareMKSubTypes(self, mkSubTypes): + return _lev2mdapi.CTORATstpLev2MdApi_DeclareMKSubTypes(self, mkSubTypes) + + def SubscribeMarketData(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_SubscribeMarketData(self, ppSecurityID, ExchageID) + + def UnSubscribeMarketData(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_UnSubscribeMarketData(self, ppSecurityID, ExchageID) + + def SubscribeIndex(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_SubscribeIndex(self, ppSecurityID, ExchageID) + + def UnSubscribeIndex(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_UnSubscribeIndex(self, ppSecurityID, ExchageID) + + def SubscribeTransaction(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_SubscribeTransaction(self, ppSecurityID, ExchageID) + + def UnSubscribeTransaction(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_UnSubscribeTransaction(self, ppSecurityID, ExchageID) + + def SubscribeOrderDetail(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_SubscribeOrderDetail(self, ppSecurityID, ExchageID) + + def UnSubscribeOrderDetail(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_UnSubscribeOrderDetail(self, ppSecurityID, ExchageID) + + def SubscribePHMarketData(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_SubscribePHMarketData(self, ppSecurityID, ExchageID) + + def UnSubscribePHMarketData(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_UnSubscribePHMarketData(self, ppSecurityID, ExchageID) + + def SubscribePHTransaction(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_SubscribePHTransaction(self, ppSecurityID, ExchageID) + + def UnSubscribePHTransaction(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_UnSubscribePHTransaction(self, ppSecurityID, ExchageID) + + def SubscribeResendTransaction(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_SubscribeResendTransaction(self, ppSecurityID, ExchageID) + + def UnSubscribeResendTransaction(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_UnSubscribeResendTransaction(self, ppSecurityID, ExchageID) + + def SubscribeResendOrderDetail(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_SubscribeResendOrderDetail(self, ppSecurityID, ExchageID) + + def UnSubscribeResendOrderDetail(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_UnSubscribeResendOrderDetail(self, ppSecurityID, ExchageID) + + def SubscribeXTSMarketData(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_SubscribeXTSMarketData(self, ppSecurityID, ExchageID) + + def UnSubscribeXTSMarketData(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_UnSubscribeXTSMarketData(self, ppSecurityID, ExchageID) + + def SubscribeXTSTick(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_SubscribeXTSTick(self, ppSecurityID, ExchageID) + + def UnSubscribeXTSTick(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_UnSubscribeXTSTick(self, ppSecurityID, ExchageID) + + def SubscribeNGTSTick(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_SubscribeNGTSTick(self, ppSecurityID, ExchageID) + + def UnSubscribeNGTSTick(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_UnSubscribeNGTSTick(self, ppSecurityID, ExchageID) + + def SubscribeBondMarketData(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_SubscribeBondMarketData(self, ppSecurityID, ExchageID) + + def UnSubscribeBondMarketData(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_UnSubscribeBondMarketData(self, ppSecurityID, ExchageID) + + def SubscribeBondTransaction(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_SubscribeBondTransaction(self, ppSecurityID, ExchageID) + + def UnSubscribeBondTransaction(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_UnSubscribeBondTransaction(self, ppSecurityID, ExchageID) + + def SubscribeBondOrderDetail(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_SubscribeBondOrderDetail(self, ppSecurityID, ExchageID) + + def UnSubscribeBondOrderDetail(self, ppSecurityID, ExchageID): + return _lev2mdapi.CTORATstpLev2MdApi_UnSubscribeBondOrderDetail(self, ppSecurityID, ExchageID) + + def ReqUserLogin(self, pReqUserLoginField, nRequestID): + return _lev2mdapi.CTORATstpLev2MdApi_ReqUserLogin(self, pReqUserLoginField, nRequestID) + + def ReqUserLogout(self, pUserLogout, nRequestID): + return _lev2mdapi.CTORATstpLev2MdApi_ReqUserLogout(self, pUserLogout, nRequestID) + +# Register CTORATstpLev2MdApi in _lev2mdapi: +_lev2mdapi.CTORATstpLev2MdApi_swigregister(CTORATstpLev2MdApi) + +def CTORATstpLev2MdApi_CreateTstpLev2MdApi(*args): + return _lev2mdapi.CTORATstpLev2MdApi_CreateTstpLev2MdApi(*args) + +def CTORATstpLev2MdApi_GetApiVersion(): + return _lev2mdapi.CTORATstpLev2MdApi_GetApiVersion() + + + diff --git a/log_module/log.py b/log_module/log.py index 5bdca58..586851b 100644 --- a/log_module/log.py +++ b/log_module/log.py @@ -186,18 +186,18 @@ rotation="00:00", compression="zip", enqueue=True) def get_path(self, dir_name, log_name): - path_str = "{}/logs/gp/{}/{}".format(constant.get_path_prefix(), dir_name, log_name) + ".{time:YYYY-MM-DD}.log" + path_str = "{}/ls_logs/gp/{}/{}".format(constant.get_path_prefix(), dir_name, log_name) + ".{time:YYYY-MM-DD}.log" # print(path_str) return path_str def get_hx_path(self, dir_name, log_name): - path_str = "{}/logs/huaxin/{}/{}".format(constant.get_path_prefix(), dir_name, + path_str = "{}/ls_logs/huaxin/{}/{}".format(constant.get_path_prefix(), dir_name, log_name) + ".{time:YYYY-MM-DD}.log" # print(path_str) return path_str def get_local_huaxin_path(self, dir_name, log_name): - path_str = "{}/logs/huaxin_local/{}/{}".format(constant.get_path_prefix(), dir_name, + path_str = "{}/ls_logs/huaxin_local/{}/{}".format(constant.get_path_prefix(), dir_name, log_name) + ".{time:YYYY-MM-DD}.log" # print(path_str) return path_str diff --git a/main.py b/main.py index e69de29..84a48d7 100644 --- a/main.py +++ b/main.py @@ -0,0 +1,59 @@ +import multiprocessing +import threading +import time + +import requests + +from huaxin_client import l2_market_client, trade_client +from log_module.log import logger_debug +from server import data_server +from strategy.env_info import RealTimeEnvInfo +from third_data import hx_qc_value_util +from trade.huaxin import huaxin_trade_api +from utils import tool + + +def __run_l2_market_subscript(): + def read_results(): + while True: + try: + data = queue_l1_w_strategy_r.get() + if data.get("type") == 'set_target_codes': + # [(浠g爜, 鏃堕棿鎴�, 浠锋牸, 鎬讳氦鏄撻噺, 鎬讳氦鏄撻, 涔�5, 鍗�5)] + market_data_list = data["data"]["data"] + RealTimeEnvInfo().ticks = (tool.get_now_time_str(), len(market_data_list)) + except: + time.sleep(0.1) + + queue_l1_w_strategy_r: multiprocessing.Queue = multiprocessing.Queue() + l2MarketProcess = multiprocessing.Process(target=l2_market_client.run, + args=(queue_l1_w_strategy_r,)) + l2MarketProcess.start() + read_results() + + +def test(): + time.sleep(10) + result = huaxin_trade_api.get_money(blocking=True) + logger_debug.info(f"娴嬭瘯浜ゆ槗璐︽埛鑾峰彇锛歿result}") + # 鍙戦�佷俊鎭� + requests.post("http://127.0.0.1:9008/upload_big_order_datas", [(1, 2, 3, 4, 5)]) + # 鑾峰彇澧炲�兼湇鍔PI + result = hx_qc_value_util.get_next_trading_date("2025-06-06") + logger_debug.info(f"娴嬭瘯鑾峰彇涓嬩竴涓氦鏄撴棩锛歿result}") + + +if __name__ == "__main__": + # -----鍚姩data_server----- + threading.Thread(target=lambda: data_server.run("127.0.0.1", 9008), daemon=True).start() + # -------鍚姩鍗庨懌澧炲�兼湇鍔pi------ + threading.Thread(target=hx_qc_value_util.run, daemon=True).start() + # --------鍚姩浜ゆ槗---------- + huaxin_trade_api.run() + + threading.Thread(target=test, daemon=True).start() + test() + + # -------鍚姩L2 market璁㈤槄------ + __run_l2_market_subscript() + print("鍚姩瀹屾垚") diff --git a/server/data_server.py b/server/data_server.py index 717a7cd..4d7caf9 100644 --- a/server/data_server.py +++ b/server/data_server.py @@ -2,42 +2,13 @@ import json import logging import socketserver -import time -import urllib from http.server import BaseHTTPRequestHandler -import dask -import requests -import constant -from code_attribute.block_special_codes_manager import BlockSpecialCodesManager -from code_attribute.gpcode_manager import BlackListCodeManager, HumanRemoveForbiddenManager -from l2.huaxin import huaxin_target_codes_manager -from l2.l2_transaction_data_manager import HuaXinBuyOrderManager -from log_module.log import logger_system, logger_debug, logger_kpl_limit_up, logger_request_api, \ - logger_kpl_market_strong -from third_data.custom_block_in_money_manager import CodeInMoneyManager -from third_data.kpl_data_constant import LimitUpCodesBlockRecordManager, LimitUpDataConstant, \ - ContainsLimitupCodesBlocksManager -from third_data.kpl_limit_up_data_manager import LatestLimitUpBlockManager, CodeLimitUpSequenceManager -from third_data.third_blocks_manager import BlockMapManager -from trade.buy_radical import radical_buy_data_manager, new_block_processor +from log_module.log import logger_system, logger_debug, logger_request_api -from utils import global_util, tool, data_export_util -from code_attribute import gpcode_manager, code_nature_analyse -from log_module import log_export, async_log_util -from third_data import kpl_util, kpl_data_manager, kpl_api, block_info -from third_data.code_plate_key_manager import RealTimeKplMarketData, KPLPlateForbiddenManager -from third_data.history_k_data_util import HistoryKDatasUtils -from third_data.kpl_data_manager import KPLDataManager, KPLLimitUpDataRecordManager, \ - KPLCodeLimitUpReasonManager -from third_data.kpl_util import KPLDataType, KPLPlatManager +from utils import tool +from log_module import async_log_util import urllib.parse as urlparse -from urllib.parse import parse_qs -from output import code_info_output, limit_up_data_filter, output_util, kp_client_msg_manager - -from trade import bidding_money_manager, trade_manager, l2_trade_util, trade_record_log_util, trade_constant, \ - trade_data_manager, current_price_process_manager -import concurrent.futures # 绂佺敤http.server鐨勬棩蹇楄緭鍑� logger = logging.getLogger("http.server") @@ -46,199 +17,6 @@ class DataServer(BaseHTTPRequestHandler): ocr_temp_data = {} - __kplDataManager = KPLDataManager() - __IgnoreCodeManager = IgnoreCodeManager() - __KPLPlatManager = KPLPlatManager() - __KPLCodeLimitUpReasonManager = KPLCodeLimitUpReasonManager() - # 鍘嗗彶鏉垮潡 - __history_plates_dict = {} - # 鏉垮潡 - __blocks_dict = {} - # 绮鹃��,琛屼笟鏁版嵁缂撳瓨 - __jingxuan_cache_dict = {} - __industry_cache_dict = {} - __latest_limit_up_codes_set = set() - __data_process_thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=10) - # 鏂伴鏉愯姹� - __new_blocks_codes_request_thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=5) - # 浠g爜鐨勬定骞� - __code_limit_rate_dict = {} - - # 绂佺敤鏃ュ織杈撳嚭 - def log_message(self, format, *args): - pass - - def __get_limit_up_statistic_infos(self): - # 缁熻鐩墠涓烘鐨勪唬鐮佹定鍋滄暟閲忥紙鍒嗘定鍋滃師鍥狅級 - currents = LimitUpDataConstant.current_limit_up_datas - records = LimitUpDataConstant.history_limit_up_datas - if not currents: - currents = self.__kplDataManager.get_data(KPLDataType.LIMIT_UP) - if currents is None: - currents = [] - # 鑾峰彇鍘嗗彶娑ㄥ仠 - if not records: - KPLLimitUpDataRecordManager.load_total_datas() - records = KPLLimitUpDataRecordManager.total_datas - - records_map = {x[3]: x for x in records} - current_codes = [d[0] for d in currents] - record_codes = [d[3] for d in records] - # 璁$畻娑ㄥ仠鏃堕棿鎺掑簭 - record_reason_dict = {} - current_reason_dict = {} - for _code in record_codes: - blocks = LimitUpCodesBlockRecordManager().get_radical_buy_blocks(_code) - if not blocks: - blocks = set() - for b in blocks: - if b not in record_reason_dict: - record_reason_dict[b] = [] - record_reason_dict[b].append(_code) - for _code in current_codes: - blocks = LimitUpCodesBlockRecordManager().get_radical_buy_blocks(_code) - if not blocks: - blocks = set() - for b in blocks: - if b not in current_reason_dict: - current_reason_dict[b] = [] - current_reason_dict[b].append(_code) - # (鏉垮潡鍚嶇О锛屾定鍋滀唬鐮佹暟閲忥紝鐐告澘鏁伴噺,娑ㄥ仠鏃堕棿, 鏄惁鏈夎鲸璇嗗害鐨勭エ) - - limit_up_reason_statistic_info = [[k, len(record_reason_dict[k]), len(record_reason_dict[k]) - len( - current_reason_dict.get(k) if k in current_reason_dict else []), - 0, 0] for k in record_reason_dict] - try: - for b in limit_up_reason_statistic_info: - codes_ = BlockSpecialCodesManager().get_block_codes(b[0]) - if not codes_: - codes_ = set() - b[4] = len(set(record_reason_dict[b[0]]) & set(codes_)) - except: - pass - limit_up_reason_statistic_info.sort(key=lambda x: x[1] - x[2]) - limit_up_reason_statistic_info.reverse() - - response_data = json.dumps({"code": 0, "data": {"limit_up_count": len(current_codes), - "open_limit_up_count": len(record_codes) - len(current_codes), - "limit_up_reason_statistic": limit_up_reason_statistic_info}}) - return response_data - - def __get_plate_info(self, ps_dict): - - @dask.delayed - def kpl_getStockIDPlate(code_): - temp_data = kpl_api.getStockIDPlate(code_) - return temp_data - - @dask.delayed - def kpl_getSonPlate(plate_code_): - if not plate_code: - return None - temp_data = kpl_api.getSonPlate(plate_code_) - return temp_data - - @dask.delayed - def kpl_getCodesByPlate(plate_code_): - if not plate_code: - return None - temp_data = kpl_api.getCodesByPlate(plate_code_) - return temp_data - - @dask.delayed - def request_data(f1_, f2_): - temp_data = f1_, f2_ - return temp_data - - # 鑾峰彇鏉垮潡鐨勪唬鐮� - fresult = {} - code = ps_dict["code"] - code_info = KPLLimitUpDataRecordManager.list_by_code(code, tool.get_now_date_str())[0] - hot_block_name = code_info[2] - plate_code = self.__KPLPlatManager.get_plat(hot_block_name) - f1 = kpl_getStockIDPlate(code) - # f2 = kpl_getSonPlate(plate_code) - f3 = kpl_getCodesByPlate(plate_code) - dask_result = request_data(f1, f3) - plate_info, codes_by_plate_info = dask_result.compute() - - if plate_info: - plate_info.sort(key=lambda x: x[2]) - plate_info.reverse() - fresult["plate"] = plate_info - - # 鑾峰彇浠g爜鐨勫巻鍙叉定鍋滄暟鎹�,(娑ㄥ仠鍘熷洜,鏃ユ湡,鏉垮潡) - fresult["code_records"] = KPLLimitUpDataRecordManager.get_latest_infos(code, 4, False)[:2] - # 鑾峰彇浠婃棩鏁版嵁 - fresult["today"] = (code_info[2], code_info[1], code_info[6]) - fresult["industry"] = global_util.code_industry_map.get(code) - if plate_code: - # 鑾峰彇寮哄害 - # datas = son_plate_info - # # (浠g爜,鍚嶇О,寮哄害) - # temp = kpl_util.parseSonPlat(datas) - # temp.sort(key=lambda x: x[2]) - # temp.reverse() - # fresult["plat_strength"] = temp - - # 鑾峰彇娑ㄥ仠鍘熷洜涓嬮潰鐨勫垪琛� - datas = codes_by_plate_info - # (浠g爜,鍚嶇О,鐜颁环,娑ㄥ箙,鑷敱娴侀��,鍑犳澘锛岄緳鍑狅紝涓诲姏鍑�棰�,300w鍑�棰�,鏈烘瀯澧炰粨) - temps = kpl_util.parsePlateCodes(datas) - # --鏁版嵁鍑嗗寮�濮�-- - codes_set = set([d[0] for d in temps]) - limit_up_dict, limit_up_codes, open_limit_up_codes = limit_up_data_filter.get_limit_up_info(codes_set) - score_dict = {} - want_codes = gpcode_manager.WantBuyCodesManager().list_code_cache() - black_codes = BlackListCodeManager().list_codes() - total_datas = KPLLimitUpDataRecordManager.total_datas - code_info_dict = {} - for val in total_datas: - code_info_dict[val[3]] = val - - # --鏁版嵁鍑嗗缁撴潫-- - - ignore_codes = self.__IgnoreCodeManager.list_ignore_codes("2") - # 鏈�缁堢粨鏋滐細(浠g爜,鍚嶇О,娑ㄥ仠鐘舵��(0-鏃犵姸鎬� 1-娑ㄥ仠 2-鐐告澘),榫欏嚑,棣栨澘,鍒嗗��,娑ㄥ仠鏃堕棿,鍘熷洜,鐩稿悓鍘熷洜浠g爜鏁伴噺,鑷敱娴侀��,娑ㄥ仠鍘熷洜鏄惁鍙樺寲,娑ㄥ箙,鐜颁环,榛戝悕鍗�,鎯充拱鍗�,涓诲姏鍑�鍊�,300w,) - codes_info_list = [] - for t in temps: - code = t[0] - limit_up_state = 0 - if code in limit_up_dict: - if limit_up_dict[code][0]: - limit_up_state = 1 - elif limit_up_dict[code][1]: - limit_up_state = 2 - score = "" - if code in score_dict: - score = score_dict[code] - - limit_up_time = '' - if code in code_info_dict: - limit_up_time = output_util.time_format(code_info_dict[code][5]) - final_code_info = {"code_info": ( - t[0], t[1], limit_up_state, t[6], t[5], score, limit_up_time, - code_info[2], code_info[10], output_util.money_desc(t[4]), 0, t[3], t[2], - "榛戝悕鍗�" if code in black_codes else "", "鎯充拱鍗�" if code in want_codes else "", - output_util.money_desc(t[7]), output_util.money_desc(t[8]), output_util.money_desc(t[9]))} - if code in code_info_dict: - final_code_info["today"] = ( - code_info_dict[code][2], code_info_dict[code][1], code_info_dict[code][6]) - # 鍔犺浇鍘嗗彶 - if code in self.__history_plates_dict: - final_code_info["code_records"] = self.__history_plates_dict[code][1] - # 鍔犺浇鏉垮潡 - if code in self.__blocks_dict: - final_code_info["plate"] = self.__blocks_dict[code][1] - - # 鑾峰彇浜岀骇琛屼笟 - final_code_info["industry"] = global_util.code_industry_map.get(code) - - if code not in ignore_codes: - codes_info_list.append(final_code_info) - fresult["code_list_info"] = codes_info_list - response_data = json.dumps({"code": 0, "data": fresult}) - return response_data def do_GET(self): path = self.path @@ -246,586 +24,7 @@ async_log_util.info(logger_request_api, f"寮�濮嬭姹倇tool.get_thread_id()}-{url}") response_data = "" if url.path == "/get_kpl_data": - best_feng_kou = self.__kplDataManager.get_data(kpl_util.KPLDataType.BEST_FENG_KOU) - if not best_feng_kou: - best_feng_kou = [] - best_feng_kou = best_feng_kou[:22] - feng_kou = self.__kplDataManager.get_data(kpl_util.KPLDataType.FENG_KOU) - if not feng_kou: - feng_kou = [] - feng_kou = feng_kou[:22] - industry_rank = self.__kplDataManager.get_data(kpl_util.KPLDataType.INDUSTRY_RANK) - if not industry_rank: - industry_rank = [] - industry_rank = industry_rank[:22] - feng_xiang = self.__kplDataManager.get_data(kpl_util.KPLDataType.FENG_XIANG) - if not feng_xiang: - feng_xiang = [] - feng_xiang = feng_xiang[:22] - response_data = json.dumps({"code": 0, "data": {"best_feng_kou": best_feng_kou, "feng_kou": feng_kou, - "industry_rank": industry_rank, "feng_xiang": feng_xiang}}) - elif url.path == "/get_score_info": - start_time = time.time() - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - code = ps_dict['code'] - name = ps_dict.get('name') - date = ps_dict.get('date') - try: - data = code_info_output.get_output_params(code, self.__jingxuan_cache_dict, self.__industry_cache_dict) - if data["code_name"].find("None") > -1 and name: - data["code_name"] = f"{name} {code}" - - self.__history_plates_dict[code] = (time.time(), data["kpl_code_info"]["code_records"]) - if "plate" in data["kpl_code_info"]: - self.__blocks_dict[code] = (time.time(), data["kpl_code_info"]["plate"]) - - response_data = json.dumps({"code": 0, "data": data}) - print("get_score_info 鑰楁椂锛�", time.time() - start_time) - except Exception as e: - logger_debug.exception(e) - logging.exception(e) - - elif url.path == "/get_trade_records": - # 鑾峰彇鎸傛挙淇℃伅 - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - code = ps_dict['code'] - date = ps_dict.get('date') - local_today_datas = log_export.load_l2_from_log(date) - total_datas = local_today_datas.get(code) - trade_info = code_info_output.load_trade_record(code, total_datas, date) - response_data = json.dumps({"code": 0, "data": {"open_limit_up": trade_info[0], "records": trade_info[2]}}) - - elif url.path == "/get_l2_cant_buy_reasons": - # 鑾峰彇L2娌′拱鐨勫師鍥� - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - code = ps_dict['code'] - fdatas = log_export.get_l2_cant_buy_reasons(code) - response_data = json.dumps({"code": 0, "data": fdatas}) - - elif url.path == "/get_kpl_block_info": - start_time = time.time() - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - code = ps_dict['code'] - try: - data = code_info_output.get_kpl_block_info(code) - response_data = json.dumps({"code": 0, "data": data}) - print("get_kpl_block_info 鑰楁椂锛�", time.time() - start_time) - except Exception as e: - logger_debug.exception(e) - logging.exception(e) - - elif url.path == "/get_trade_progress": - # 鑾峰彇浜ゆ槗杩涘害 - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - code = ps_dict['code'] - trade_progress, is_default = transaction_progress.TradeBuyQueue().get_traded_index(code) - # 鑾峰彇姝e湪鎴愪氦, 璁$畻鎴愪氦杩涘害 - dealing_info = HuaXinBuyOrderManager.get_dealing_order_info(code) - dealing_active_info = HuaXinBuyOrderManager.get_dealing_active_order_info(code) - percent = 100 - if dealing_info: - total_datas = l2_data_util.local_today_datas.get(code) - if str(total_datas[trade_progress]['val']["orderNo"]) == str(dealing_info[0]): - num = total_datas[trade_progress]['val']['num'] - if dealing_active_info and dealing_info[0] == dealing_active_info[0]: - if tool.is_sh_code(code): - num += dealing_active_info[1] // 100 - percent = int(dealing_info[1] / num) - response_data = json.dumps( - {"code": 0, "data": {"trade_progress": trade_progress, "is_default": is_default, "percent": percent}}) - elif url.path == "/kpl/get_limit_up_statistic_infos": - try: - # 缁熻鏈�杩戠殑娑ㄥ仠鏉垮潡 - response_data = self.__get_limit_up_statistic_infos() - except Exception as e: - logger_debug.exception(e) - - elif url.path == "/kpl/get_plate_info": - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - response_data = self.__get_plate_info(ps_dict) - - elif url.path == "/kpl/get_market_data": - # 鑾峰彇鏉垮潡淇℃伅 - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - type_ = int(ps_dict['type']) - result = [] - if type_ == 0: - # 琛屼笟锛屼富鍔涘噣棰濆�掑簭 - result = kpl_api.getMarketIndustryRealRankingInfo(True) - result = kpl_util.parseMarketIndustry(result) - elif type_ == 1: - # 琛屼笟锛屼富鍔涘噣棰濋『搴� - result = kpl_api.getMarketIndustryRealRankingInfo(False) - result = kpl_util.parseMarketIndustry(result) - elif type_ == 2: - # 绮鹃�夛紝涓诲姏鍑�棰濆�掑簭 - result = kpl_api.getMarketJingXuanRealRankingInfo(True) - result = kpl_util.parseMarketJingXuan(result) - elif type_ == 3: - # 绮鹃�夛紝涓诲姏鍑�棰濋『搴� - result = kpl_api.getMarketJingXuanRealRankingInfo(False) - result = kpl_util.parseMarketJingXuan(result) - forbidden_plates = KPLPlateForbiddenManager().list_all() - fresult = [] - for d in result: - if type_ == 2 or type_ == 3: - self.__jingxuan_cache_dict[d[1]] = d - elif type_ == 0 or type_ == 1: - self.__industry_cache_dict[d[1]] = d - d = list(d) - d.append(1 if d[1] in forbidden_plates else 0) - fresult.append(d) - response_data = json.dumps({"code": 0, "data": fresult}) - elif url.path == "/kpl/add_ignore_code": - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - code = ps_dict['code'] - type_ = ps_dict['type'] - self.__IgnoreCodeManager.ignore_code(type_, code) - response_data = json.dumps({"code": 0}) - elif url.path == "/kpl/forbidden_plate": - # 娣诲姞涓嶈兘涔扮殑鏉垮潡 - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - plate = ps_dict["plate"] - # 鍔犲叆绂佹 - KPLPlateForbiddenManager().save_plate(plate) - response_data = json.dumps({"code": 0}) - elif url.path == "/kpl/del_forbidden_plate": - # 鍒犻櫎涓嶈兘涔扮殑鏉垮潡 - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - plate = ps_dict["plate"] - # 鍔犲叆绂佹 - KPLPlateForbiddenManager().delete_plate(plate) - response_data = json.dumps({"code": 0}) - elif url.path == "/kpl/list_forbidden_plate": - # 涓嶈兘涔扮殑鏉垮潡鍒楄〃 - results = KPLPlateForbiddenManager().list_all_cache() - response_data = json.dumps({"code": 0, "data": list(results)}) - elif url.path == "/kpl/list_deleted_forbidden_plate": - # 鑾峰彇宸茬粡鍒犻櫎鐨勬澘鍧� - results = KPLPlateForbiddenManager().list_all_deleted_cache() - if results: - results -= KPLPlateForbiddenManager().list_all_cache() - response_data = json.dumps({"code": 0, "data": list(results)}) - - elif url.path == "/kpl/get_plate_codes": - # 鑾峰彇娑ㄥ仠鍘熷洜涓嬮潰鐨勪唬鐮� - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - plate = kpl_util.filter_block(ps_dict["plate"]) - special_codes = BlockSpecialCodesManager().get_block_codes(plate) - if special_codes is None: - special_codes = set() - # 鑾峰彇鏉垮潡涓嬬殑浠g爜 - # 缁熻鐩墠涓烘鐨勪唬鐮佹定鍋滄暟閲忥紙鍒嗘定鍋滃師鍥狅級 - now_limit_up_codes_info = self.__kplDataManager.get_data(KPLDataType.LIMIT_UP) - now_limit_up_codes = set([d[0] for d in now_limit_up_codes_info]) - # 鑾峰彇鍘嗗彶娑ㄥ仠 - record_limit_up_datas = KPLLimitUpDataRecordManager.total_datas - if not record_limit_up_datas: - KPLLimitUpDataRecordManager.load_total_datas() - record_limit_up_datas = KPLLimitUpDataRecordManager.total_datas - - codes_info = [] - for d in record_limit_up_datas: - if kpl_util.filter_block(d[2]) != plate: - continue - if not tool.is_can_buy_code(d[3]): - continue - # 浠g爜,鍚嶇О,娑ㄥ仠鏃堕棿,鏄惁鐐告澘,鏄惁鎯充拱,鏄惁宸茬粡涓嬭繃鍗�,娑ㄥ仠鏃堕棿,鑷敱娴侀�氬競鍊�,鏄惁鍦ㄩ粦鍚嶅崟閲岄潰 - codes_info.append( - [d[3], d[4], tool.to_time_str(int(d[5])), 1 if d[3] not in now_limit_up_codes else 0, 0, 0, d[12], - output_util.money_desc(d[13]), 1, 1 if l2_trade_util.is_in_forbidden_trade_codes(d[3]) else 0, - 1 if d[3] in special_codes else 0]) - - for d in record_limit_up_datas: - if kpl_util.filter_block(d[2]) == plate: - continue - if plate not in [kpl_util.filter_block(k) for k in d[6].split("銆�")]: - continue - if not tool.is_can_buy_code(d[3]): - continue - # 浠g爜,鍚嶇О,娑ㄥ仠鏃堕棿,鏄惁鐐告澘,鏄惁鎯充拱,鏄惁宸茬粡涓嬭繃鍗�,娑ㄥ仠鏃堕棿,鑷敱娴侀�氬競鍊�,鏄惁鍦ㄩ粦鍚嶅崟閲岄潰 - codes_info.append( - [d[3], d[4], tool.to_time_str(int(d[5])), 1 if d[3] not in now_limit_up_codes else 0, 0, 0, d[12], - output_util.money_desc(d[13]), 0, 1 if l2_trade_util.is_in_forbidden_trade_codes(d[3]) else 0]) - - codes_info.sort(key=lambda x: x[2]) - # 鏌ヨ鏄惁涓烘兂涔板崟 - green_codes = gpcode_manager.GreenListCodeManager().list_codes_cache() - for code_info in codes_info: - code_info[4] = 1 if code_info[0] in green_codes else 0 - # 鑾峰彇浠g爜鐘舵�� - if trade_manager.CodesTradeStateManager().get_trade_state_cache( - code_info[0]) != trade_constant.TRADE_STATE_NOT_TRADE: - code_info[5] = 1 - - response_data = json.dumps({"code": 0, "data": codes_info}) - elif url.path == "/kpl/get_plate_codes_new": - # 鑾峰彇娑ㄥ仠鍘熷洜涓嬮潰鐨勪唬鐮� - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - plate = kpl_util.filter_block(ps_dict["plate"]) - - special_codes = set() - plates = BlockMapManager().filter_blocks({plate}) - for p in plates: - _codes = BlockSpecialCodesManager().get_block_codes(p) - if _codes is None: - _codes = set() - special_codes |= _codes - - # 鑾峰彇鏉垮潡涓嬬殑浠g爜 - # 缁熻鐩墠涓烘鐨勪唬鐮佹定鍋滄暟閲忥紙鍒嗘定鍋滃師鍥狅級 - now_limit_up_codes_info = self.__kplDataManager.get_data(KPLDataType.LIMIT_UP) - now_limit_up_codes = set([d[0] for d in now_limit_up_codes_info]) - # 鑾峰彇鍘嗗彶娑ㄥ仠 - record_limit_up_datas = KPLLimitUpDataRecordManager.total_datas - if not record_limit_up_datas: - KPLLimitUpDataRecordManager.load_total_datas() - record_limit_up_datas = KPLLimitUpDataRecordManager.total_datas - - codes_info = [] - for d in record_limit_up_datas: - _code = d[3] - # blocks = LimitUpDataConstant.get_blocks_with_history(_code) - blocks = LimitUpCodesBlockRecordManager().get_radical_buy_blocks(_code) - if not blocks: - blocks = set() - blocks = BlockMapManager().filter_blocks(blocks) - - if blocks is not None and plate not in blocks: - continue - if not tool.is_can_buy_code(d[3]): - continue - # 浠g爜,鍚嶇О,娑ㄥ仠鏃堕棿,鏄惁鐐告澘,鏄惁鍔犵豢,鏄惁宸茬粡涓嬭繃鍗�,娑ㄥ仠鏃堕棿,鑷敱娴侀�氬競鍊�,鏄惁鍦ㄩ粦鍚嶅崟閲岄潰, 鏄惁鏈夎鲸璇嗗害, 澶у崟鍑�棰�, 鏄惁鍔犳兂 - codes_info.append( - [d[3], - d[4], - tool.to_time_str(int(d[5])), - 1 if d[3] not in now_limit_up_codes else 0, - 0, - 0, - d[12], - output_util.money_desc(d[13]), - 1, - 1 if l2_trade_util.is_in_forbidden_trade_codes(d[3]) else 0, - 1 if d[3] in special_codes else 0, - CodeInMoneyManager().get_money(d[3]), - 0]) - codes_info.sort(key=lambda x: x[2]) - # 鏌ヨ鏄惁涓烘兂涔板崟 - green_codes = gpcode_manager.GreenListCodeManager().list_codes_cache() - want_codes = gpcode_manager.WantBuyCodesManager().list_code_cache() - for code_info in codes_info: - code_info[4] = 1 if code_info[0] in green_codes else 0 - code_info[12] = 1 if code_info[0] in want_codes else 0 - # 鑾峰彇浠g爜鐘舵�� - if trade_manager.CodesTradeStateManager().get_trade_state_cache( - code_info[0]) != trade_constant.TRADE_STATE_NOT_TRADE: - code_info[5] = 1 - - # 娑ㄥ仠鏁版嵁 - fdatas = {"limit_up_list": codes_info} - # 杈ㄨ瘑搴︾エ - fdatas["speical_codes"] = [(x, gpcode_manager.get_code_name(x)) for x in special_codes] - forbidden_refer_codes = KPLPlateForbiddenManager().get_watch_high_codes_by_block(plate) - if forbidden_refer_codes is None: - forbidden_refer_codes = set() - fdatas["forbidden_refer_codes"] = [(x, gpcode_manager.get_code_name(x)) for x in forbidden_refer_codes] - response_data = json.dumps({"code": 0, "data": fdatas}) - elif url.path == "/kpl/get_open_limit_up_count_rank": - # 鑾峰彇鐐告澘娆℃暟鎺掕 - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - code = ps_dict.get("code") - results = log_export.load_kpl_open_limit_up() - statistic = {} - for result in results: - for c in result[1]: - if not tool.is_can_buy_code(c): - continue - if code and code != c: - continue - if c not in statistic: - statistic[c] = 0 - statistic[c] += 1 - # 鍊掑簭鎺� - statistic_list = [(k, statistic[k]) for k in statistic] - statistic_list.sort(key=lambda x: x[1], reverse=True) - fresults = [] - limit_up_records = KPLLimitUpDataRecordManager.list_all_cache(tool.get_now_date_str()) - limit_up_count_dict = {} - if limit_up_records: - for d in limit_up_records: - limit_up_count_dict[d[3]] = d[12] - - for x in statistic_list: - fresults.append((x[0], gpcode_manager.get_code_name(x[0]), x[1], limit_up_count_dict.get(x[0]))) - - fresults = fresults[:30] - response_data = json.dumps({"code": 0, "data": fresults}) - elif url.path == "/kpl/get_latest_limit_up_queue": - # 鑾峰彇鏈�杩戠殑娑ㄥ仠闃熷垪 - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - time_str = ps_dict.get("time") - day = ps_dict.get("day") - if not day: - day = tool.get_now_date_str() - results = log_export.load_kpl_limit_up_records(time_str, date=day) - if not results: - results = [] - response_data = json.dumps({"code": 0, "data": results}) - - elif url.path == "/get_last_trade_day_reasons": - - # 璁$畻骞冲潎娑ㄥ箙 - def get_limit_rate_list(codes): - if not codes: - return [] - need_request_codes = set() - if tool.trade_time_sub(tool.get_now_time_str(), "09:30:00") < 0: - need_request_codes |= set(codes) - else: - now_time = time.time() - for c in codes: - if c not in self.__code_limit_rate_dict: - need_request_codes.add(c) - elif now_time - self.__code_limit_rate_dict[c][1] > 60: - need_request_codes.add(c) - if need_request_codes: - _limit_rate_list = HistoryKDatasUtils.get_codes_limit_rate(list(need_request_codes)) - for d in _limit_rate_list: - self.__code_limit_rate_dict[d[0]] = (d[1], time.time()) - return [(c_, self.__code_limit_rate_dict[c_][0]) for c_ in codes] - - try: - raise Exception("鎺ュ彛鏆傚仠浣跨敤") - # 鑾峰彇涓婁釜浜ゆ槗鏃ョ殑鐩稿悓娑ㄥ仠鍘熷洜鐨勪唬鐮佷俊鎭� - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - code = ps_dict["code"] - # 鑾峰彇鏄ㄦ棩娑ㄥ仠鏁版嵁 - day = HistoryKDatasUtils.get_previous_trading_date_cache(tool.get_now_date_str()) - - limit_up_records = kpl_data_manager.KPLLimitUpDataRecordManager.list_all_cache(day) - reasons = [] - for d in limit_up_records: - if d[3] == code: - reasons.append(d) - # 鑾峰彇浠g爜鐨勫師鍥� - if reasons: - reasons = list(reasons) - reasons.sort(key=lambda x: x[9]) - reason = reasons[-1][2] - # 鑾峰彇娑ㄥ仠鏁版嵁 - datas = self.__kplDataManager.get_from_file_cache(kpl_util.KPLDataType.LIMIT_UP, day) - # (浠g爜,鍚嶇О,棣栨娑ㄥ仠鏃堕棿,鏈�杩戞定鍋滄椂闂�,鍑犳澘,娑ㄥ仠鍘熷洜,鏉垮潡,瀹為檯娴侀��,涓诲姏鍑�棰�,娑ㄥ仠鍘熷洜浠g爜,娑ㄥ仠鍘熷洜浠g爜鏁伴噺) - yesterday_result_list = [] - percent_rate = 0 - if datas: - yesterday_codes = set() - for d in datas: - if d[5] == reason: - yesterday_codes.add(d[0]) - # 鑾峰彇娑ㄥ箙 - limit_rate_list = get_limit_rate_list(yesterday_codes) - limit_rate_dict = {} - if limit_rate_list: - total_rate = 0 - for d in limit_rate_list: - limit_rate_dict[d[0]] = d[1] - total_rate += d[1] - percent_rate = round(total_rate / len(limit_rate_list), 2) - - for d in datas: - if d[5] == reason: - yesterday_codes.add(d[0]) - if d[0] != code: - # (浠g爜,鍚嶇О, 娑ㄥ箙) - yesterday_result_list.append((d[0], d[1], limit_rate_dict.get(d[0]))) - - current_limit_up_list = kpl_data_manager.KPLLimitUpDataRecordManager.latest_origin_datas - current_result_list = [] - if current_limit_up_list: - for c in current_limit_up_list: - if c[5] == reason and c[0] != code: - current_result_list.append((c[0], c[1])) - response_data = json.dumps({"code": 0, "data": {"reason": reason, "reason_rate": percent_rate, - "data": {"yesterday": yesterday_result_list, - "current": current_result_list}}}) - else: - response_data = json.dumps({"code": 1, "msg": "鏄ㄦ棩鏈定鍋�"}) - except Exception as e: - logger_debug.exception(e) - raise e - - elif url.path == "/pull_kp_client_msg": - # 鎷夊彇瀹㈡埛绔秷鎭� - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - client = ps_dict["client"] - msg = kp_client_msg_manager.read_msg(client) - if msg: - response_data = json.dumps({"code": 0, "data": msg}) - else: - response_data = json.dumps({"code": 1, "msg": "鏆傛棤娑堟伅"}) - elif url.path == "/list_kp_client_msg": - msg_list = kp_client_msg_manager.list_msg_from_local() - msg_list.reverse() - msg_list = [f"{msg.split('|')[0]}{msg.split('|')[-1].split('-')[1].strip()}" for msg in msg_list] - response_data = json.dumps({"code": 0, "data": msg_list}) - elif url.path == "/statistic_latest_limit_up_block": - try: - # 缁熻鏈�杩戠殑娑ㄥ仠鏉垮潡 - datas = LatestLimitUpBlockManager().statistics_limit_up_block_infos() - response_data = json.dumps({"code": 0, "data": datas}) - except Exception as e: - logger_debug.exception(e) - - elif url.path == "/get_new_blocks": - # 鑾峰彇鏂版澘鍧� - blocks = KPLLimitUpDataRecordManager.get_new_blocks(tool.get_now_date_str()) - response_data = json.dumps({"code": 0, "data": blocks}) - elif url.path == "/get_account_commission_detail": - # 鑾峰彇鎵嬬画璐硅鎯� - try: - fdata = {"delegates": {}} - # 鑾峰彇鏈湀鐨勬墜缁垂 - end_date = tool.get_now_date_str("%Y%m%d") - start_date = f"{end_date[:6]}01" - delegates_month = trade_data_manager.AccountMoneyManager().get_delegated_count_info(start_date, - end_date) - # 鑲$エ锛屼笂璇佸彲杞�� 锛� 娣辫瘉鍙浆鍊� - - deals_month = trade_data_manager.AccountMoneyManager().get_deal_count_info(start_date, end_date) - cost_month = sum([round(0.1 * x[1], 2) for x in delegates_month]) - make_month = 0 - make_month += max(1 * deals_month[0][1] if deals_month[0][1] else 0, - deals_month[0][2] * 1.854 / 10000 if deals_month[0][2] else 0) + 1 * deals_month[1][ - 1] + 0 * deals_month[2][1] - fdata["month_commission"] = round(make_month - cost_month, 2) - # 璁$畻褰撴棩鎵嬬画璐硅鎯� - delegates = trade_data_manager.AccountMoneyManager().get_delegated_count_info() - delegates = [{"count": x[1], "price": 0.1, "money": round(0.1 * x[1], 2)} for x in delegates] - fdata["delegates"]["buy"] = delegates[0] - fdata["delegates"]["buy_cancel"] = delegates[1] - fdata["delegates"]["sell_cancel"] = delegates[2] - fdata["delegates"]["sell"] = delegates[3] - deals = trade_data_manager.AccountMoneyManager().get_deal_count_info() - fdata["deals"] = {} - fdata["deals"]["stock"] = {"count": deals[0][1], "price": 1, "money": round(1 * deals[0][1], 2)} - fdata["deals"]["sh_cb"] = {"count": deals[1][1], "price": 1, "money": round(1 * deals[1][1], 2)} - fdata["deals"]["sz_cb"] = {"count": deals[2][1], "price": 0, "money": round(0 * deals[2][1], 2)} - fdata["commission"] = trade_data_manager.AccountMoneyManager().get_commission_cache() - response_data = json.dumps({"code": 0, "data": fdata}) - except Exception as e: - logger_debug.exception(e) - elif url.path == "/get_place_order_records": - # 鑾峰彇涓嬪崟璁板綍 - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - try: - day = ps_dict.get("day") - if not day: - day = tool.get_now_date_str() - records = log_export.load_trade_recod_by_type("place_order", date=day) - fdata = [] - for record in records: - print(record) - # (涓嬪崟鏃堕棿, 浠g爜, 鍚嶇О, 涓嬪崟妯″紡, 鏉垮潡淇℃伅) - fdata.append((record[0], record[1], gpcode_manager.get_code_name(record[1]), record[3]["mode_desc"], - record[3].get("block_info"))) - response_data = json.dumps({"code": 0, "data": fdata}) - except: - pass - elif url.path == "/get_blocks_in_money_info": - # 鑾峰彇鏉垮潡璧勯噾娴佸叆鐘跺喌 - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - type_ = int(ps_dict.get("type")) - try: - fdatas = [] - if type_ == 0: - in_blocks = RealTimeKplMarketData().get_top_market_jingxuan_blocks() - if not in_blocks: - in_blocks = set() - fdatas = RealTimeKplMarketData.top_in_list_cache - if not fdatas: - datas = self.__kplDataManager.get_data(KPLDataType.JINGXUAN_RANK) - fdatas = datas - # 杩斿洖鏄惁鍦ㄦ祦鍏ュ墠鍑� - temp_datas = [] - for d in fdatas: - temp = list(d) - if d[1] in in_blocks: - temp.append(1) - else: - temp.append(0) - if in_blocks and d[1] == in_blocks[-1]: - temp.append(RealTimeKplMarketData.get_market_strong()) - else: - temp.append(0) - temp_datas.append(temp) - - fdatas = temp_datas - elif type_ == 1: - out_blocks = RealTimeKplMarketData().get_top_market_jingxuan_out_blocks() - if not out_blocks: - out_blocks = set() - fdatas = RealTimeKplMarketData.top_out_list_cache - if not fdatas: - datas = self.__kplDataManager.get_data(KPLDataType.JINGXUAN_RANK_OUT) - fdatas = datas - # 杩斿洖鏄惁鍦ㄦ祦鍏ュ墠鍑� - temp_datas = [] - for d in fdatas: - temp = list(d) - if d[1] in out_blocks: - temp.append(1) - else: - temp.append(0) - temp_datas.append(temp) - fdatas = temp_datas - - response_data = json.dumps({"code": 0, "data": fdatas}) - except: - pass - elif url.path == "/get_block_codes_with_money": - # 鑾峰彇鏉垮潡璧勯噾娴佸叆鐘跺喌 - ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) - block = ps_dict.get("block") - # 鏄惁鍊掑簭鎺� - desc = int(ps_dict.get("desc")) - try: - response_data = requests.get( - "http://127.0.0.1:9005/get_block_codes_money?block=" + urllib.parse.quote(block)) - r_str = response_data.text - response_data = json.loads(r_str) - if response_data["code"] == 0: - datas = response_data["data"] - fdatas = [] - for d in datas: - # (浠g爜, 鍚嶇О, 娴佸叆閲戦, 鏄惁琚帓闄ゆ垚鍒嗚偂) - fdatas.append((d[0], gpcode_manager.get_code_name(d[0]), d[1], d[2])) - if desc: - fdatas.sort(key=lambda x: x[2], reverse=True) - else: - fdatas.sort(key=lambda x: x[2]) - fdatas = fdatas[:50] - response_data = json.dumps({"code": 0, "data": fdatas}) - else: - response_data = r_str - except Exception as e: - response_data = json.dumps({"code": 1, "data": str(1)}) - - elif url.path == "/get_all_special_codes": - # 鑾峰彇鎵�鏈夎鲸璇嗗害鐨勪唬鐮� - code_blocks_dict = BlockSpecialCodesManager().get_code_blocks_dict() - fdata = {} - for k in code_blocks_dict: - fdata[k] = list(code_blocks_dict[k]) - response_data = json.dumps({"code": 0, "data": fdata}) - elif url.path == "/get_new_blocks_special_codes": - # 鑾峰彇鎵�鏈夎鲸璇嗗害鐨勪唬鐮� - code_blocks_dict = BlockSpecialCodesManager().get_temp_code_blocks_dict() - fdata = {} - for k in code_blocks_dict: - fdata[k] = list(code_blocks_dict[k]) - response_data = json.dumps({"code": 0, "data": fdata}) - + response_data = json.dumps({"code": 0, "data": {}}) async_log_util.info(logger_request_api, f"缁撴潫璇锋眰{tool.get_thread_id()}-{url}") self.send_response(200) # 鍙戠粰璇锋眰瀹㈡埛绔殑鍝嶅簲鏁版嵁 @@ -836,236 +35,19 @@ def do_POST(self): path = self.path url = urlparse.urlparse(path) - if url.path == "/upload_kpl_data": - # 鎺ュ彈寮�鐩樺暒鏁版嵁 + result_str = "" + if url.path == "/upload_big_order_datas": + # 鎺ユ敹鎴愪氦澶у崟鏁版嵁 params = self.__parse_request() - result_str = self.__process_kpl_data(params) - self.__send_response(result_str) - if url.path == "/upload_codes_in_money": - # 鎺ユ敹浠g爜鍑�娴佸叆閲戦 + logger_debug.info("upload_big_order_datas:", f"{params}") + elif url.path == "/upload_block_in_datas": + # 鎺ユ敹鏉垮潡娴佸叆鏁版嵁 params = self.__parse_request() - d = params["data"] - d = json.loads(d) - try: - for code in d: - CodeInMoneyManager().set_money(code, d[code]) - except Exception as e: - logging.exception(e) + logger_debug.info("upload_block_in_datas:", f"{params}") result_str = json.dumps({"code": 0}) - self.__send_response(result_str) - - def __process_kpl_data(self, data_origin): - - def do_limit_up(result_list_): - - def request_new_blocks_codes(blocks_info, all_new_blocks): - """ - 璇锋眰鏂版澘鍧楃殑浠g爜 - @param blocks_info:[(鏉垮潡鍚嶇О,鏉垮潡浠g爜)] - @return: - """ - yesterday_codes = kpl_data_manager.get_yesterday_limit_up_codes() - for bi in blocks_info: - result = kpl_api.getCodesByPlate(bi[1]) - result = json.loads(result) - code_info_list = [] - for d in result["list"]: - if d[0] in yesterday_codes: - continue - # 娑ㄥ箙瑕佸ぇ浜�5% - rate = d[6] / int(round((tool.get_limit_up_rate(d[0]) - 1) * 10)) - if rate / ((tool.get_limit_up_rate(d[0]) - 1) * 10) < 5: - continue - # 鏍煎紡锛�(浠g爜,娑ㄥ箙) - code_info_list.append((d[0], d[6])) - if code_info_list: - # 灏嗕唬鐮佸姞鍏ユ柊棰樻潗 - new_block_processor.process_new_block_by_component_codes(bi[0], - set([x[0] for x in code_info_list]), - all_new_blocks) - - try: - if result_list_: - # 淇濆瓨娑ㄥ仠鏃堕棿 - codes_set = set() - limit_up_reasons = {} - limit_up_time_dict = {} - for d in result_list_: - code = d[0] - limit_up_reasons[code] = d[5] - codes_set.add(code) - limit_up_time = time.strftime("%H:%M:%S", time.localtime(d[2])) - if tool.is_can_buy_code(code): - code_price_manager.Buy1PriceManager().set_limit_up_time(code, limit_up_time) - limit_up_time_dict[code] = limit_up_time - add_codes = codes_set - self.__latest_limit_up_codes_set - self.__latest_limit_up_codes_set = codes_set - - if limit_up_reasons: - # 缁熻娑ㄥ仠鍘熷洜鐨勭エ鐨勪釜鏁� - limit_up_reason_code_dict = {} - for code in limit_up_reasons: - b = limit_up_reasons[code] - if b not in limit_up_reason_code_dict: - limit_up_reason_code_dict[b] = set() - limit_up_reason_code_dict[b].add(code) - # 娑ㄥ仠鏃堕棿code - LCancelRateManager.set_block_limit_up_count(limit_up_reason_code_dict, limit_up_time_dict) - - if add_codes: - for code in add_codes: - # 鏍规嵁娑ㄥ仠鍘熷洜鍒ゆ柇鏄惁鍙互涔� - if tool.is_can_buy_code(code): - try: - # 鍒ゆ柇鏄惁涓嬪崟 - trade_state = trade_manager.CodesTradeStateManager().get_trade_state(code) - if trade_state == trade_constant.TRADE_STATE_BUY_PLACE_ORDER or trade_state == trade_constant.TRADE_STATE_BUY_DELEGATED: - # 濮旀墭涓殑璁㈠崟锛屽垽鏂槸鍚﹂渶瑕佹挙鍗� - if not gpcode_manager.WantBuyCodesManager().is_in_cache(code): - yesterday_codes = kpl_data_manager.get_yesterday_limit_up_codes() - current_limit_up_datas, limit_up_record_datas, yesterday_current_limit_up_codes, before_blocks_dict = kpl_data_manager.KPLLimitUpDataRecordManager.latest_origin_datas, kpl_data_manager.KPLLimitUpDataRecordManager.total_datas, yesterday_codes, block_info.get_before_blocks_dict() - if not current_limit_up_datas: - current_limit_up_datas = [] - if not limit_up_record_datas: - limit_up_record_datas = [] - # 涔扮粷瀵硅�佸ぇ - # 涓�斾笉鑳芥挙鍗� - # if CodePlateKeyBuyManager.is_need_cancel(code, limit_up_reasons.get(code), - # current_limit_up_datas, - # limit_up_record_datas, - # yesterday_current_limit_up_codes, - # before_blocks_dict): - # l2_data_manager_new.L2TradeDataProcessor.cancel_buy(code, - # f"娑ㄥ仠鍘熷洜锛坽limit_up_reasons.get(code)}锛変笉鏄�佸ぇ鎾ゅ崟", - # "鏉垮潡鎾�") - except Exception as e: - logger_debug.exception(e) - kpl_data_manager.KPLLimitUpDataRecordManager.save_record(tool.get_now_date_str(), result_list_) - try: - LatestLimitUpBlockManager().set_current_limit_up_data(tool.get_now_date_str(), result_list_) - except: - pass - try: - CodeLimitUpSequenceManager().set_current_limit_up_datas(result_list_) - ContainsLimitupCodesBlocksManager().set_current_limit_up_datas(result_list_) - except: - pass - try: - OpenLimitUpGoodBlocksBuyStrategy.set_current_limit_up_data(result_list_) - RadicalBuyBlockManager.set_current_limit_up_datas(result_list_) - except: - pass - - try: - # 鏂伴鏉� - new_block_processor.process_limit_up_list({x[0]: x[5] for x in result_list_}) - new_block_codes = new_block_processor.screen_new_blocks_with_limit_up_datas( - [(x[0], x[5]) for x in result_list_]) - if new_block_codes: - # 缁熻鏉垮潡鐨勪唬鐮� - records = KPLLimitUpDataRecordManager.total_datas - block_plate_code_dict = {} - for x in records: - block_plate_code_dict[kpl_util.filter_block(x[2])] = x[15] - # 鏂版澘鍧� - update_new_block_plates = [] - for b in new_block_codes: - for c in new_block_codes[b]: - new_block_processor.process_new_block_by_limit_up_list(c, b) - - for r in new_block_codes: - if r in block_plate_code_dict: - update_new_block_plates.append((r, block_plate_code_dict[r])) - if update_new_block_plates: - # 闇�瑕佽幏鍙栨澘鍧椾笅鐨勪唬鐮� - self.__new_blocks_codes_request_thread_pool.submit( - lambda: request_new_blocks_codes(update_new_block_plates, new_block_codes.keys())) - except Exception as e: - logger_debug.exception(e) - self.__kplDataManager.save_data(type_, result_list_) - except Exception as e: - logger_debug.exception(e) - - # 灏�"姒傚康"浜屽瓧鏇挎崲鎺� - data = data_origin - type_ = data["type"] - print("寮�鐩樺暒type:", type_) - if type_ == KPLDataType.BIDDING.value: - result_list = kpl_util.parseDaBanData(data["data"], kpl_util.DABAN_TYPE_BIDDING) - # 绔炰环鍙栧墠20 - if result_list: - result_list.sort(key=lambda x: x[2]) - result_list.reverse() - result_list = result_list[:20] - bs = [] - for d in result_list: - bs.append((d[0], f"{d[2] // 10000}涓�")) - bidding_money_manager.set_bidding_money(bs[:10]) - - self.__kplDataManager.save_data(type_, result_list) - elif type_ == KPLDataType.LIMIT_UP.value: - result_list, day = kpl_util.parseLimitUpData(data["data"]) - if day and day != tool.get_now_date_str(): - pass - else: - self.__data_process_thread_pool.submit(lambda: do_limit_up(result_list)) - # 璁板綍娑ㄥ仠鏃ュ織 - logger_kpl_limit_up.info(result_list) - elif type_ == KPLDataType.OPEN_LIMIT_UP.value: - result_list = kpl_util.parseDaBanData(data["data"], kpl_util.DABAN_TYPE_OPEN_LIMIT_UP) - if result_list: - self.__kplDataManager.save_data(type_, result_list) - elif type_ == KPLDataType.LIMIT_DOWN.value: - result_list = kpl_util.parseDaBanData(data["data"], kpl_util.DABAN_TYPE_LIMIT_DOWN) - if result_list: - self.__kplDataManager.save_data(type_, result_list) - elif type_ == KPLDataType.EVER_LIMIT_DOWN.value: - result_list = kpl_util.parseDaBanData(data["data"], kpl_util.DABAN_TYPE_EVER_LIMIT_DOWN) - if result_list: - self.__kplDataManager.save_data(type_, result_list) - elif type_ == KPLDataType.FENG_KOU.value: - fdata = data["data"] - result_list = kpl_util.parseFengKou(fdata) - result_list.sort(key=lambda x: x[3]) - result_list.reverse() - self.__kplDataManager.save_data(type_, result_list) - elif type_ == KPLDataType.BEST_FENG_KOU.value: - result_list = kpl_util.parseBestFengKou(data["data"]) - if result_list: - self.__kplDataManager.save_data(type_, result_list) - # 淇濆瓨鏈�寮洪鍙� - elif type_ == KPLDataType.FENG_XIANG.value: - result_list = kpl_util.parseFengXiang(data["data"]) - # 淇濆瓨椋庡悜鏁版嵁 - if result_list: - self.__kplDataManager.save_data(type_, result_list) - elif type_ == KPLDataType.INDUSTRY_RANK.value: - result_list = kpl_util.parseIndustryRank(data["data"]) - # 淇濆瓨琛屼笟鏁版嵁 - if result_list: - self.__kplDataManager.save_data(type_, result_list) - RealTimeKplMarketData.set_top_5_industry(result_list) - elif type_ == KPLDataType.JINGXUAN_RANK.value: - # result_list = kpl_util.parseMarketJingXuan(data["data"]) - result_list = json.loads(data["data"]) - # 淇濆瓨绮鹃�夋暟鎹� - if result_list: - self.__kplDataManager.save_data(type_, result_list) - RealTimeKplMarketData.set_market_jingxuan_blocks(result_list) - elif type_ == KPLDataType.JINGXUAN_RANK_OUT.value: - # result_list = kpl_util.parseMarketJingXuan(data["data"]) - result_list = json.loads(data["data"]) - # 淇濆瓨绮鹃�夋暟鎹� - if result_list: - self.__kplDataManager.save_data(type_, result_list) - RealTimeKplMarketData.set_market_jingxuan_out_blocks(result_list) - elif type_ == KPLDataType.MARKET_STRONG.value: - strong = data["data"] - logger_kpl_market_strong.info(strong) - # 淇濆瓨甯傚満鐑害 - if strong is not None: - RealTimeKplMarketData.set_market_strong(strong) - return json.dumps({"code": 0}) + else: + pass + self.__send_response(result_str) def __send_response(self, data): # 鍙戠粰璇锋眰瀹㈡埛绔殑鍝嶅簲鏁版嵁 @@ -1090,8 +72,6 @@ def run(addr, port): # 杩愯鐪嬬洏娑堟伅閲囬泦 # kp_client_msg_manager.run_capture() - kpl_data_manager.PullTask.run_pull_task() - handler = DataServer # httpd = socketserver.TCPServer((addr, port), handler) try: diff --git a/strategy/data_analyzer.py b/strategy/data_analyzer.py index 0895532..5b7acde 100644 --- a/strategy/data_analyzer.py +++ b/strategy/data_analyzer.py @@ -60,6 +60,24 @@ return k_data[0]['amount'] @classmethod + def get_yesterday_low_price(cls, k_data): + """ + 鑾峰彇鏄ㄦ棩鏈�浣庝环 + @param k_data: K绾挎暟鎹垪琛� + @return: 鏄ㄦ棩鏈�楂樹环 + """ + return k_data[0]['low'] + + @classmethod + def get_yesterday_open_price(cls, k_data): + """ + 鑾峰彇鏄ㄦ棩寮�鐩樹环 + @param k_data: K绾挎暟鎹垪琛� + @return: 鏄ㄦ棩鏈�楂樹环 + """ + return k_data[0]['open'] + + @classmethod def get_recent_days_high(cls, k_data, days): """ 鑾峰彇杩戝嚑涓氦鏄撴棩鐨勬渶楂樹环 @@ -149,6 +167,22 @@ """ return sum( 1 for d in k_data[:days] if d['close'] <= cls.calculate_lower_limit_price(d["sec_id"], d["pre_close"])) + + @classmethod + def get_recent_days_double_volume_date(cls, k_data, days): + """ + 鑾峰彇鏈�杩戝嚑涓氦鏄撴棩鐨勫�嶉噺鏃ユ湡 + @param k_data: K绾挎暟鎹垪琛� + @param days: 浜ゆ槗鏃ユ暟閲� + @return: 鍊嶉噺鐨勬棩鏈� + """ + k_datas: list = k_data[:days] + k_datas.reverse() + for i in range(1, len(k_datas)): + latest_volume = k_datas[i - 1]["volume"] + if k_datas[i]["volume"] > 2 * latest_volume: + return k_datas[i]["bob"] + return None @classmethod def get_first_limit_up_avg_premium(cls, k_data, days): @@ -403,10 +437,96 @@ reason_counts = {} special_reasons = constant.KPL_INVALID_BLOCKS if limit_up_data: - for _, date, reason in limit_up_data: + for _, date, reason, is_open, _blocks in limit_up_data: + if is_open: + continue if min_day <= date <= max_day and reason not in special_reasons: reason_counts[reason] = reason_counts.get(reason, 0) + 1 if not reason_counts: return [] max_count = max(reason_counts.values()) return [(reason, count) for reason, count in reason_counts.items() if count == max_count] + + @classmethod + def get_limit_up_reasons(cls, limit_up_data_list, min_day, max_day, include_recommend_reason=False): + """ + 鑾峰彇鏈�杩戜竴娈垫椂闂寸殑娑ㄥ仠鍘熷洜 + @param include_recommend_reason: 鏄惁鍖呭惈鎺ㄨ崘鍘熷洜 + @param max_day: + @param limit_up_data_list: + @param min_day: + @return: + """ + special_reasons = constant.KPL_INVALID_BLOCKS + day_block_codes = {} + if limit_up_data_list: + for _, date, reason, is_open, _blocks in limit_up_data_list: + if reason in special_reasons: + continue + if date > max_day or date < min_day: + continue + # 姣忓ぉ鐨勬澘鍧楁定鍋滄暟閲� + if date not in day_block_codes: + day_block_codes[date] = {} + reasons = {reason} + if include_recommend_reason and _blocks: + reasons |= set(_blocks.split("銆�")) + for r in reasons: + if r not in day_block_codes[date]: + # {鏃ユ湡:{鏉垮潡锛歔{鐪熸娑ㄥ仠闆嗗悎}, {鐐告澘闆嗗悎}]}} + day_block_codes[date][r] = [set(), set()] + if not is_open: + # 鐪熸娑ㄥ仠 + day_block_codes[date][r][0].add(_) + else: + # 鐐告澘 + day_block_codes[date][r][1].add(_) + blocks = set() + for date in day_block_codes: + for reason in day_block_codes[date]: + if len(day_block_codes[date][reason][0]) >= 2 or len(day_block_codes[date][reason][0]) >= 4: + # 鏈�鍚庢定鍋滄暟>=2 鐐告澘鏁�>=4 + blocks.add(reason) + return blocks + return set() + + @classmethod + def get_continuous_limit_up_reasons(cls, limit_up_data_list, days_list): + """ + 杩炵画鑰侀鏉愶細days_list浜ゆ槗鏃ラ兘鍦ㄨ蛋鐨勯鏉� + @param limit_up_data_list: + @param days_list: ["2025-01-01"] + @return: + """ + special_reasons = constant.KPL_INVALID_BLOCKS + day_block_codes = {} + if limit_up_data_list: + for _, date, reason, is_open, _blocks in limit_up_data_list: + if reason in special_reasons: + continue + if date not in days_list: + continue + # 姣忓ぉ鐨勬澘鍧楁定鍋滄暟閲� + if date not in day_block_codes: + day_block_codes[date] = {} + reasons = {reason} + for r in reasons: + if r not in day_block_codes[date]: + # {鏃ユ湡:{鏉垮潡锛歔{鐪熸娑ㄥ仠闆嗗悎}, {鐐告澘闆嗗悎}]}} + day_block_codes[date][r] = [set(), set()] + if not is_open: + # 鐪熸娑ㄥ仠 + day_block_codes[date][r][0].add(_) + else: + # 鐐告澘 + day_block_codes[date][r][1].add(_) + block_days = {} + for date in day_block_codes: + for reason in day_block_codes[date]: + if len(day_block_codes[date][reason][0]) >= 2 or len(day_block_codes[date][reason][0]) >= 4: + # 鏈�鍚庢定鍋滄暟>=2 鐐告澘鏁�>=4 + if reason not in block_days: + block_days[reason] = set() + block_days[reason].add(date) + return set([b for b in block_days if len(block_days[b])==len(days_list)]) + return set() diff --git a/strategy/data_downloader.py b/strategy/data_downloader.py index c071aed..1831770 100644 --- a/strategy/data_downloader.py +++ b/strategy/data_downloader.py @@ -87,7 +87,7 @@ with open(os.path.join(bar_dir, f"{day}.txt"), encoding='utf-8', mode='w') as f: f.write(f"{day_bars_dict[day]}") - def download_tick_data(self, codes): + def download_tick_data(self, codes, show_log=False): """ 涓嬭浇浠婃棩TICK鏁版嵁 @param codes: @@ -116,7 +116,8 @@ f.write(f"{results}") finally: excute_codes.add(code) - print("鍓╀綑鏁伴噺锛�", len(set(batch_codes) - excute_codes)) + if show_log: + print("鍓╀綑鏁伴噺锛�", len(set(batch_codes) - excute_codes)) # 閲囩敤dask骞宠鎵цdownload鏂规硶 if len(codes) > 10000: @@ -131,7 +132,7 @@ if __name__ == "__main__": - day = "2025-05-12" + day = "2025-06-05" codes, code_pre_close_dict = DataLoader(day).load_target_codes() juejin_local_api = JueJinLocalApi("41c4f5da-2591-11f0-a9c9-f4b5203f67bf", "018db265fa34e241dd6198b7ca507ee0a82ad029") @@ -139,11 +140,12 @@ trade_days = data_loader.load_trade_days() __DataDownloader = DataDownloader(day, trade_days) - special_codes = LowSuctionOriginDataExportManager(day).export_special_codes() - fcodes = set() - for codes in [special_codes[p] for p in special_codes]: - fcodes |= codes - codes = fcodes + # special_codes = LowSuctionOriginDataExportManager(day).export_special_codes() + # fcodes = set() + # for codes in [special_codes[p] for p in special_codes]: + # fcodes |= codes + # codes = fcodes + codes = {'002981', '002317', '600468', '000759', '605138', '301076', '300892', '603315', '002640', '002114', '601608', '001316', '000633', '002995', '600530', '001300', '002331', '600279', '601319', '300542', '002034', '605598', '002227', '600543', '600119', '601068', '600403', '600397', '300204', '603056', '301024', '000639', '002809', '605069', '002780', '002105', '000523', '601908', '002131', '600185', '002549', '600172', '002286', '603185', '603686', '001317', '600284', '002688', '603579', '603086', '600986', '002955', '600551', '600668', '603266', '002849', '000566', '603629', '000066', '600308', '000617', '002365', '001279', '603011', '603332', '001258', '002733', '300422', '000573', '300805', '600735', '600793', '603109', '601008', '605151', '002250', '603090', '000859', '002378', '002190', '001256', '600301', '600391', '002819', '300947', '603072', '002977', '002510', '002251', '002196', '600859', '603329', '000025', '605033', '605136', '603677', '605179', '605286', '000510', '600250', '600865', '000539', '002800', '002162', '300995', '603331', '603797', '603214', '002095', '000981', '002943', '603359', '002757', '002255', '603709', '603016', '603693', '003018', '300945', '000756', '300106', '000612', '000677', '002806', '301156', '001206', '605588', '002961', '301392', '000620', '000681', '600693', '603776', '600697', '000016', '002760', '600463', '002347', '600676', '002045', '600589', '603192', '601002', '002431', '600598', '001336', '601890', '002882', '000026', '600738', '605169', '300963', '000880', '002909', '000665', '000420', '002232', '605208', '002291', '603958', '000062', '603607', '002761', '002278', '301079', '600410', '002537', '000712', '300804', '002151', '002957', '605303', '600149', '002915', '002467', '000561', '002583', '600493', '603335', '000862', '000402', '002571', '002130', '000592', '603767', '002205', '600876', '600053', '002086', '605118', '600262', '002626', '001333', '002795', '001318', '600644', '300530', '002598', '600239', '002773', '002366', '605188', '003030', '002173', '000670', '001328', '002484', '002631', '002165', '600396', '002048', '000632', '002560', '300678', '000813', '002667', '600448', '002369', '603366', '000017', '603506', '001268', '002183', '002261', '002724', '603488', '002735', '300961', '605388', '000007', '002686', '603103', '601956', '603477', '600770', '000014', '605318', '600379', '603065', '603681', '603123', '603822', '601579', '002272', '600540', '603956', '301108', '000722', '603657', '603637', '603108', '600337', '603390', '000626', '603205', '003009', '301335', '600370', '603273', '001202', '603949', '002137', '600774', '301225', '603194', '000710', '000815', '605228', '600510', '603188', '002878', '000953', '002471', '002134', '301301', '002696', '002639', '000599', '002843', '000948', '600965', '603758', '001212', '003003', '002300', '600794', '603578', '601069', '002813', '603336', '301066', '001367', '001337', '002490', '001259', '600371', '002836', '603688', '002229', '603586', '002546', '002163', '603777', '600300', '300946', '001269', '001222', '002343', '002565', '600800', '603083', '000601', '002590', '300884', '000695', '000863', '603639', '600798', '002338', '603215', '002436', '002853', '603605', '002772', '003020', '600281', '002533', '002905', '002682', '605155', '002564', '600882', '300941', '002732', '600320', '002570', '000045', '001330', '603616', '600495', '301317', '002562', '603768', '002963', '600137', '603326', '600650', '001395', '300994', '002982', '603178', '002927', '002166', '600212', '002862', '601083', '600744', '603353', '001230', '002861', '600318', '002842', '002580', '600805', '002584', '600828', '300169', '603518', '002574', '002132', '600593', '002551', '002946', '601825', '000997', '600187', '002310', '002730', '002900', '605255', '603333', '002453', '600841', '600207', '603232', '600616', '603788', '001234', '600280', '002526', '002235', '600571', '002651', '002364', '600539', '002133', '002065', '002084', '603169', '600830', '000505', '605100', '600610', '300581', '002811', '002907', '002194', '603696', '002846', '000558', '603006', '603955', '002920', '603931', '002522', '603150', '601022', '603267', '603618', '300703', '002204', '002068', '600590', '002678', '600698', '002719', '600505', '605055', '002501', '000965', '300773', '000514', '603890', '000655', '603286', '601595', '301316', '002633', '603839', '603040', '002530', '603610', '002104', '002553', '002374', '603630', '000678', '002040', '002094'} __DataDownloader.download_tick_data(codes) # __DataDownloader.download_minute_data(codes) diff --git a/strategy/env_info.py b/strategy/env_info.py new file mode 100644 index 0000000..8a9bf4f --- /dev/null +++ b/strategy/env_info.py @@ -0,0 +1,48 @@ +""" +鐜淇℃伅 +""" +from strategy.strategy_variable_factory import DataLoader +from third_data.history_k_data_manager import HistoryKDataManager +from utils import tool + + +@tool.singleton +class RealTimeEnvInfo: + """ + 瀹炴椂淇℃伅 + """ + + def __init__(self): + # 澶у崟鏇存柊鏃堕棿 + self.big_order_update_time = '' + # 鏉垮潡娴佸叆淇℃伅 (鏇存柊鏃堕棿, 鏁版嵁鏁伴噺) + self.block_in = ('', 0) + # 寮�鐩樺暒瀹炴椂娑ㄥ仠淇℃伅(鏇存柊鏃堕棿, 鏁版嵁鏁伴噺) + self.kpl_current_limit_up = ('', 0) + # Tick鏁版嵁(鏇存柊鏃堕棿, 鏁版嵁鏁伴噺) + self.ticks = ('', 0) + + +def get_leading_limit_up_block_codes_count(day): + """ + 鑾峰彇棰嗘定鏉垮潡鐨勪唬鐮佹暟閲� + @param day: + @return: + """ + codes_info = DataLoader(day).load_all_buy_plates_of_codes() + return len(codes_info) + + +def get_history_k_bars(day): + """ + 鑾峰彇鍘嗗彶K绾挎暟閲� + @param day: + @return: + """ + codes = HistoryKDataManager().get_history_bars_codes(day) + count = len(codes) + return count + + +if __name__ == "__main__": + print(get_history_k_bars("2025-06-04")) diff --git a/strategy/low_suction_strategy.py b/strategy/low_suction_strategy.py index 2fd391e..629d3dc 100644 --- a/strategy/low_suction_strategy.py +++ b/strategy/low_suction_strategy.py @@ -170,7 +170,7 @@ return eval(line) return None - def export_big_order_deal(self): + def export_big_order_deal(self, min_money=299e4): """ 澶у崟鎴愪氦 @return: {"浠g爜":[(涔板崟鍙�, 閲�, 閲戦, 鏃堕棿, 鏈�缁堟垚浜や环)]} @@ -184,12 +184,14 @@ data = eval(line) if data[1] != 0: continue + if data[2][2] < min_money: + continue if data[0] not in fdatas: fdatas[data[0]] = [] fdatas[data[0]].append(data[2]) return fdatas - def export_big_sell_order_deal(self): + def export_big_sell_order_deal(self, min_money=299e4): """ 澶у崟鎴愪氦 @return: {"浠g爜":[(涔板崟鍙�, 閲�, 閲戦, 鏃堕棿, 鏈�缁堟垚浜や环)]} @@ -201,12 +203,14 @@ data = eval(line) if data[1] != 1: continue + if data[2][2] < min_money: + continue if data[0] not in fdatas: fdatas[data[0]] = [] fdatas[data[0]].append(data[2]) return fdatas - def export_big_order_deal_by(self): + def export_big_order_deal_by(self, min_money=299e4): """ 澶у崟鎴愪氦 @return: {"浠g爜":[(涔板崟鍙�, 閲�, 閲戦, 鏃堕棿, 鏈�缁堟垚浜や环)]} @@ -220,7 +224,7 @@ data = eval(line) if data[1] != 0: continue - if data[2][2] < 299e4: + if data[2][2] < min_money: continue if data[2][0] in buy_order_nos: continue @@ -229,7 +233,7 @@ fdatas[data[0]].append(data[2]) return fdatas - def export_big_sell_order_deal_by(self): + def export_big_sell_order_deal_by(self, min_money=299e4): """ 澶у崟鎴愪氦 @return: {"浠g爜":[(涔板崟鍙�, 閲�, 閲戦, 鏃堕棿, 鏈�缁堟垚浜や环)]} @@ -242,7 +246,7 @@ data = eval(line) if data[1] != 1: continue - if data[2][2] < 299e4: + if data[2][2] < min_money: continue if data[2][0] in buy_order_nos: continue diff --git a/strategy/strategy_params_settings.py b/strategy/strategy_params_settings.py new file mode 100644 index 0000000..72f6498 --- /dev/null +++ b/strategy/strategy_params_settings.py @@ -0,0 +1,75 @@ +""" +绛栫暐鍙傛暟璁剧疆 +""" +import json + + +class StrategyParamsSettings: + # 绂佹涔板叆 + STATE_FORBIDDEN_BUY = 0 + # 姝e父涔板叆 + STATE_NORMAL_BUY = 1 + + def __init__(self): + # 浜ゆ槗鐘舵�� + self.trade_state = 1 + # 涔板叆閲戦 + self.buy_money = 2000 + # 浠锋牸鍖洪棿 + self.price_range = (3, 60) + # 鑰侀鏉愭定鍋滄暟 + self.limit_up_count_of_old_plate = 2 + # 鏂伴鏉愭定鍋滄暟 + self.limit_up_count_of_new_plate = 2 + # 鏄ㄦ棩涓嶈兘娑ㄥ仠 + self.cant_yesterday_limit_up = True + # 鏄ㄦ棩涓嶈兘璺屽仠 + self.cant_yesterday_limit_down = True + # 鏄ㄦ棩涓嶈兘鐐告澘 + self.cant_yesterday_open_limit_up = False + # 鏈夋定鍋滅殑浜ゆ槗鏃ユ暟閲� + self.has_limit_up_days = 10 + # xx涓氦鏄撴棩鍐呬笉鑳芥湁xx娆℃定鍋� + self.trade_days_count_of_limit_up = 5 + # 娑ㄥ仠娆℃暟 + self.count_of_limit_up = 3 + + # xx涓氦鏄撴棩鍐呬笉鑳芥湁xx娆℃定鍋� + self.trade_days_count_of_limit_down = 5 + # 璺屽仠娆℃暟 + self.count_of_limit_down = 3 + + # xx涓氦鏄撴棩鍐呬笉鑳芥湁xx娆$偢鏉� + self.trade_days_count_of_open_limit_up = 5 + # 鐐告澘娆℃暟 + self.count_of_open_limit_up = 3 + # 鏄惁鍙拱鍒涗笟鏉� + self.can_buy_ge_code = True + # 鑷敱甯傚�艰寖鍥� + self.zyltgb_range = (10e8, 300e8) + # 鏄惁鍙拱浠婃棩娑ㄥ仠杩囩殑绁� + self.can_buy_limited_up = False + # 鏈�浣庡紑鐩樻定骞� + self.min_open_rate = -0.03 + # 鍙拱鐨勬定骞呮瘮渚� + self.avaiable_rates = (-0.03, 0.07) + # 浠婃棩娑ㄥ仠浠烽渶绐佺牬XX鏃ユ渶楂樹环,None琛ㄧず姝ゆ潯鏁版嵁涓嶇敓鏁� + self.trade_days_count_of_limit_up_price_over_high = None + # 浠婃棩涔颁环涓庢渶楂樹环鐨勫樊鍊煎湪XX姣斾緥浠ュ唴 + self.min_rate_of_highest_and_price = 0.04 + # 鏈�澶氶珮浜庡潎浠穢x姣斾緥 + self.max_rate_than_average_price = 0.03 + + def to_json_str(self): + d = self.__dict__ + return json.dumps(d) + + @classmethod + def to_obj(cls, json_str): + result = json.loads(json_str) + obj = StrategyParamsSettings() + for k in result: + setattr(obj, k, result[k]) + return obj + + diff --git a/strategy/strategy_variable.py b/strategy/strategy_variable.py index 23a292c..cdd43ca 100644 --- a/strategy/strategy_variable.py +++ b/strategy/strategy_variable.py @@ -18,11 +18,15 @@ # ======浠婃棩K绾垮睘鎬�====== self.浠婃棩寮�鐩樹环 = None self.褰撳墠浠� = None - self.浠婃棩鏈�楂樹环 = None + self.浠婃棩鏈�楂樹环淇℃伅 = None self.浠婃棩娑ㄥ仠浠� = None self.浠婃棩鎴愪氦閲� = None + self.浠婃棩鎴愪氦棰� = None self.浠婃棩寮�鐩樻定骞� = None self.浠婃棩鍒嗘椂鏈�楂橀噺浠� = None + self.浠婃棩鏈�浣庝环 = None + # (鏃堕棿,娑ㄥ箙) + self.浠婃棩閲忓淇℃伅 = None # ========浠婃棩澶у崟鎴愪氦鏁版嵁======= self.澶у崟琛ㄨ揪寮� = None # [(璁㈠崟鍙�, 閲�, 閲戦, 鏃堕棿, 鏈�鏂颁环鏍�)] @@ -42,10 +46,13 @@ self.鏄ㄦ棩鎴愪氦棰� = None self.鏄ㄦ棩鏈�楂樹环 = None self.鏄ㄦ棩鍒嗘椂鏈�楂橀噺浠� = None + self.鏄ㄦ棩鏈�浣庝环 = None + self.鏄ㄦ棩寮�鐩樹环 = None self.鍏釜浜ゆ槗鏃ユ定骞呰繃楂� = False # ======鍘嗗彶K绾垮睘鎬�====== + self.鏃ユ渶楂樹环_3 = None self.鏃ユ渶楂樹环_5 = None self.鏃ユ渶楂樹环_10 = None self.鏃ユ渶楂樹环_30 = None @@ -170,17 +177,41 @@ self.鏃ユ渶姝e師鍥犲嚭鐜扮殑澶╂暟_60 = None self.鏃ユ渶姝e師鍥犲嚭鐜扮殑澶╂暟_120 = None + # 鏈�杩憍x涓氦鏄撴棩鍑虹幇鐨勬澘鍧� + self.鏃ュ嚭鐜扮殑鏉垮潡_2 = None + self.鏃ュ嚭鐜扮殑鏉垮潡_5 = None + self.鏃ュ嚭鐜扮殑鏉垮潡_10 = None + self.鏃ュ嚭鐜扮殑鏉垮潡_30 = None + self.鏃ュ嚭鐜扮殑鏉垮潡_60 = None + self.鏃ュ嚭鐜扮殑鏉垮潡_120 = None + # 鏈�杩憍x涓氦鏄撴棩鍑虹幇鍊嶉噺鐨勬棩鏈� + self.鏃ユ斁鍊嶉噺鏃ユ湡_5 = None + self.鏃ユ斁鍊嶉噺鏃ユ湡_10 = None + self.鏃ユ斁鍊嶉噺鏃ユ湡_15 = None + self.鏃ユ斁鍊嶉噺鏃ユ湡_30 = None + self.鏃ユ斁鍊嶉噺鏃ユ湡_60 = None + self.鏃ユ斁鍊嶉噺鏃ユ湡_120 = None + # 褰撴棩鏉垮潡娑ㄥ仠锛歿鏉垮潡:[(浠g爜, 娑ㄥ仠鏃堕棿),(浠g爜, 娑ㄥ仠鏃堕棿)]} self.鏉垮潡娑ㄥ仠 = None + self.寮�鐩樺暒鏉垮潡娑ㄥ仠 = None + self.寮�鐩樺暒棰嗘定鏉垮潡娑ㄥ仠 = None + self.寮�鐩樺暒绮鹃�夋澘鍧楁定鍋� = None + self.寮�鐩樺暒鏈�姝f澘鍧楁定鍋� = None # 褰撴棩鏉垮潡锛歿"鏉垮潡1","鏉垮潡2"} self.浠g爜鏉垮潡 = None + self.鏂颁唬鐮佹澘鍧� = None + self.浠g爜绮鹃�夋澘鍧�=None # 鏉垮潡鎴愪氦浠g爜锛歿"鏉垮潡":{"浠g爜1","浠g爜2"}} self.鏉垮潡鎴愪氦浠g爜 = {} + # 娴佸叆鏉垮潡 + self.璧勯噾娴佸叆鏉垮潡 = [] - - + self.杈ㄨ瘑搴︿唬鐮� = set() + self.棰嗘定鏉垮潡淇℃伅 = set() + self.杩炵画鑰侀鏉� = set() def replace_variables(self, expression): """ diff --git a/strategy/strategy_variable_factory.py b/strategy/strategy_variable_factory.py index 2f366ff..a8a0643 100644 --- a/strategy/strategy_variable_factory.py +++ b/strategy/strategy_variable_factory.py @@ -4,11 +4,14 @@ import datetime import json import os +import re +import constant from code_attribute import global_data_loader from db import mysql_data_delegate from strategy.data_analyzer import KTickLineAnalyzer, KPLLimitUpDataAnalyzer, K60SLineAnalyzer from strategy.strategy_variable import StockVariables +from third_data import kpl_api, kpl_util from third_data.history_k_data_manager import HistoryKDataManager from third_data.history_k_data_util import JueJinLocalApi, HistoryKDatasUtils from utils import global_util, tool @@ -29,11 +32,14 @@ self.jueJinLocalApi = JueJinLocalApi("41c4f5da-2591-11f0-a9c9-f4b5203f67bf", "018db265fa34e241dd6198b7ca507ee0a82ad029") self.trade_days = self.load_trade_days() + self.plate_codes = {} + # 浠g爜鐨勭簿閫夋澘鍧� 锛� {"浠g爜":{鏉垮潡}} + self.jx_blocks = {} def load_kline_data(self): """ 鍔犺浇鏃绾挎暟鎹� - :return: 鏃绾挎暟鎹� + :return: {"浠g爜": 鏃绾挎暟鎹畗 """ dir_path = os.path.join(self.cache_path, "k_bars") day = self.trade_days[0] @@ -86,7 +92,7 @@ k_bar_code_data_dict[code] = date_datas return k_bar_code_data_dict - def load_tick_data(self): + def load_tick_data(self, target_codes=None): """ 鍔犺浇褰撴棩鐨則ick鏁版嵁 :return:tick鏁版嵁瀛楀吀 @@ -99,6 +105,8 @@ if f.find(self.now_day) < 0: continue code = f.split("_")[1][:6] + if target_codes and code not in target_codes: + continue tick_path = os.path.join(tick_dir_path, f) with open(tick_path, mode='r') as f: lines = f.readlines() @@ -124,12 +132,115 @@ def load_limit_up_data(self): """ 鍔犺浇娑ㄥ仠鏁版嵁 - :return: 娑ㄥ仠鏁版嵁璁板綍 + :return: 娑ㄥ仠鏁版嵁璁板綍[(浠g爜, 鏃ユ湡, 鏉垮潡, 鏄惁鐐告澘)] """ mysql = mysql_data_delegate.Mysqldb() results = mysql.select_all( - f"select _code, _day, _hot_block_name from kpl_limit_up_record where _day>='{self.trade_days[-1]}' and _day<='{self.trade_days[0]}' and _open=0") + f"select _code, _day, _hot_block_name, _open, _blocks from kpl_limit_up_record where _day>='{self.trade_days[-1]}' and _day <='{self.trade_days[0]}'") + for r in results: + r[2] = kpl_util.filter_block(r[2]) return results + + def __compute_limit_up_reasons_for_refer(self, block_infos): + """ + 璁$畻鍙傝�冪エ鐨勬定鍋滃師鍥� + @param block_infos: [(鏉垮潡, 鏃ユ湡)] + @return: + """ + # [(鏉垮潡, 鏃ユ湡)] + block_infos.sort(key=lambda x: x[1], reverse=True) + # {"鏉垮潡":[(鍑虹幇娆℃暟, 鏈�杩戝嚭鐜版棩鏈�)]} + temp_dict = {} + for b in block_infos: + if b[0] in constant.KPL_INVALID_BLOCKS: + continue + if b[0] not in temp_dict: + temp_dict[b[0]] = [0, b[1]] + temp_dict[b[0]][0] += 1 + if not temp_dict: + return set() + temp_list = [(k, temp_dict[k][0], temp_dict[k][1]) for k in temp_dict] + # 鎸夌収娑ㄥ仠娆℃暟涓庢渶杩戞定鍋滄椂闂存帓搴� + temp_list.sort(key=lambda x: (x[1], x[2]), reverse=True) + # 鍙栨定鍋滄鏁版渶澶氱殑鍜屾渶杩戞定鍋滅殑 + # 鍙栫浉鍚屾鏁扮殑鍘熷洜 + if temp_list: + _list = [t for t in temp_list if t[1] == temp_list[0][1]] + if _list[0][1] == 1: + _list = _list[:1] + blocks = set([x[0] for x in _list]) + else: + blocks = set() + + blocks -= constant.KPL_INVALID_BLOCKS + # 鍘婚櫎渚嬪姒傚康杩欎簺娉涙寚璇� + return set([kpl_util.filter_block(x) for x in blocks]) + + def load_code_plates_for_refer(self): + """ + 鑾峰彇鍙傝�冪エ鐨勬定鍋滃師鍥� + @return: + """ + sql = f"SELECT r.`_code`, r.`_day`, r.`_hot_block_name`, r.`_blocks`, r.`_open` FROM `kpl_limit_up_record` r WHERE r.`_day`>='{tool.date_sub(self.now_day, 365)}' and r.`_day` <'{self.now_day}'" + mysql = mysql_data_delegate.Mysqldb() + kpl_results = mysql.select_all(sql) + # {"浠g爜":[(鏉垮潡, 鏃ユ湡), (鏉垮潡, 鏃ユ湡)]} + kpl_block_dict = {} + for r in kpl_results: + # 褰撴棩鐐告澘鐨勪笉璁$畻鍘熷洜 + if r[4] == 1: + continue + code = r[0] + if code not in kpl_block_dict: + kpl_block_dict[code] = [] + kpl_block_dict[code].append((r[2], r[1])) # (鏉垮潡, 鏃ユ湡) + reasons_dict = {} + for code in kpl_block_dict: + block_infos = kpl_block_dict.get(code) + reasons_dict[code] = self.__compute_limit_up_reasons_for_refer(block_infos) + return reasons_dict + + def load_target_plate_and_codes(self): + """ + 鍔犺浇鐩爣鏉垮潡涓庡搴旂殑浠g爜锛� + 浠庢渶杩�120涓氦鏄撴棩鐨勭湡姝f定鍋滄暟鎹腑 + @return: {"鏉垮潡":[浠g爜]} + """ + end_date = self.trade_days[:60][-1] + start_date = self.trade_days[:60][0] + mysql = mysql_data_delegate.Mysqldb() + # 鑾峰彇涓婁釜浜ゆ槗鏃ユ定鍋滅殑绁� + results = mysql.select_all( + f"SELECT r.`_code` FROM `kpl_limit_up_record` r where r._day='{self.trade_days[0]}' and r._open = 0") + exclude_codes = set([x[0] for x in results]) + results = mysql.select_all( + f"select r.`_hot_block_name` from `kpl_limit_up_record` r where r.`_open`=0 and r.`_day`>'{end_date}' and r.`_day` <= '{start_date}' group by r.`_hot_block_name`") + blocks = set([x[0] for x in results]) + fresults = {} + all_buy_plates_of_codes = self.load_all_buy_plates_of_codes() + valid_codes = set(all_buy_plates_of_codes.keys()) + for b in blocks: + sql = f""" + SELECT * FROM + ( + SELECT r.`_code`, r.`_code_name`, COUNT(*) AS `count`, MAX(r.`_day`) AS _day FROM `kpl_limit_up_record` r WHERE r.`_open`=0 AND r.`_day`>'{end_date}' AND r.`_day`<='{start_date}' AND r.`_hot_block_name`='{b}' GROUP BY r.`_code` + ) a + + ORDER BY a.count DESC,a._day DESC + """ + + results = mysql.select_all(sql) + # 鍙栧墠1/3 + if results: + results = [x for x in results if + (tool.is_can_buy_code(x[0]) and x[0] in valid_codes and x[0] not in exclude_codes)] + max_count = len(results) // 3 if len(results) % 3 == 0 else len(results) // 3 + 1 + results = results[:max_count] + # 鍙栧墠10 + results = results[:10] + codes = [x[0] for x in results] + fresults[kpl_util.filter_block(b)] = codes + return fresults def load_trade_days(self): """ @@ -182,6 +293,226 @@ except Exception as e: return set(), None + def load_plate_codes(self, plate_code, plate_name): + """ + 鑾峰彇鏉垮潡鏈夊彲鑳戒拱鐨勭洰鏍囦唬鐮� + @param plate_code: + @return:[(浠g爜, 棰嗘定娆℃暟, 鏈�澶ч娑ㄦ鏁�)] + """ + + if not plate_code or plate_name == '鏃�' or plate_name in constant.KPL_INVALID_BLOCKS: + return set() + if plate_code in self.plate_codes: + return self.plate_codes.get(plate_code) + dir_path = os.path.join(self.cache_path, "plate_codes_info", self.now_day) + if not os.path.exists(dir_path): + os.makedirs(dir_path) + path_ = os.path.join(dir_path, plate_code + ".text") + datas = [] + if os.path.exists(path_): + with open(path_, mode='r', encoding='utf-8') as f: + codes_info = [] + lines = f.readlines() + for i in range(len(lines)): + if i == 0: + continue + line = lines[i] + if line: + r = eval(line) + datas.append(r) + else: + codes_info = [] + results = self.request_plate_codes(plate_code) + with open(path_, mode='w', encoding='utf-8') as f: + f.write(plate_name) + f.write("\n") + f.writelines([f"{x}\n" for x in results]) + datas = results + # 淇濆瓨鍒板唴瀛樹腑 + if datas: + max_data = max(datas, key=lambda x: x[3]) + for r in datas: + if r[3] < 1: + continue + if re.match(r"椋庨櫓|绔嬫", r[2]): + continue + if r[1].find("ST") >= 0: + continue + if r[1].find("S") >= 0: + continue + if not tool.is_can_buy_code(r[0]): + continue + codes_info.append((r[0], r[3], max_data[3])) + # if len(codes_info) >= 10: + # break + f_codes_info = codes_info # [d for d in codes_info if d[1] >= d[2] // 2] + self.plate_codes[plate_code] = f_codes_info + return self.plate_codes.get(plate_code) + + def load_all_codes_of_plates(self, is_for_buy=False): + """ + 鍔犺浇鎵�鏈夋澘鍧楃殑棰嗘定绁� + @return:{"鏉垮潡浠g爜":(鏉垮潡鍚嶇О, [(浠g爜,浠g爜鍚嶇О,鏍囩,棰嗘定娆℃暟)])} + """ + dir_path = os.path.join(self.cache_path, "plate_codes_info", self.now_day) + if not os.path.exists(dir_path): + return None + fdata = {} + plate_files = os.listdir(dir_path) + for plate_file in plate_files: + plate_code = plate_file.split(".")[0] + path_ = os.path.join(dir_path, plate_file) + with open(path_, mode='r', encoding='utf-8') as f: + datas = [] + lines = f.readlines() + for i in range(len(lines)): + if i == 0: + continue + line = lines[i] + if line: + r = eval(line) + if not is_for_buy: + if r[3] < 1: + continue + if r[1].find("ST") >= 0: + continue + if r[1].find("S") >= 0: + continue + else: + if re.match(r"椋庨櫓|绔嬫", r[2]): + continue + if r[1].find("ST") >= 0: + continue + if r[1].find("S") >= 0: + continue + if not tool.is_can_buy_code(r[0]): + continue + datas.append(r) + # if len(datas) >= 10: + # break + fdata[plate_code] = (kpl_util.filter_block(lines[0].strip()), datas) + return fdata + + def load_all_refer_plates_of_codes(self): + """ + 鍔犺浇鎵�鏈夋湁棰嗘定浠g爜鐨勯娑ㄦ澘鍧� + @return: + """ + datas = self.load_all_codes_of_plates() + fdata = {} + for plate_code in datas: + plate_name = datas[plate_code][0] + codes_info = datas[plate_code][1] + for item in codes_info: + code, limit_up_count = item[0], item[3] + if code not in fdata: + fdata[code] = [] + fdata[code].append((plate_code, plate_name, limit_up_count)) + for code in fdata: + fdata[code].sort(key=lambda x: x[2], reverse=True) + fdata[code] = fdata[code][:3] + return fdata + + def load_all_buy_plates_of_codes(self): + """ + 鍔犺浇鎵�鏈変唬鐮佺殑棰嗘定鏉垮潡 + @return: {"浠g爜":{"鏉垮潡鍚嶇О":(浠g爜, 棰嗘定娆℃暟, 鏈�澶ч娑ㄦ鏁�)}} + """ + datas = self.load_all_codes_of_plates(is_for_buy=True) + fdata = {} + for plate_code in datas: + plate_name = datas[plate_code][0] + codes_info = datas[plate_code][1] + if not codes_info: + continue + max_count = max(codes_info, key=lambda x: x[3])[3] + for item in codes_info: + code, limit_up_count = item[0], item[3] + if code not in fdata: + fdata[code] = {} + fdata[code][plate_name] = (code, limit_up_count, max_count) + fdata_dict = {c: [(p, fdata[c][p]) for p in fdata[c]] for c in fdata} + for c in fdata_dict: + fdata_dict[c].sort(key=lambda x: x[1], reverse=True) + fdata_dict[c] = fdata_dict[c][:3] + + fdata = {code: {x[0]: x[1] for x in fdata_dict[code]} for code in fdata_dict} + + return fdata + + def request_plate_codes(self, plate_code): + """ + 鑾峰彇鏉垮潡鐨勪唬鐮� + @param plate_code: + @return:[浠g爜, 鍚嶇О, 椋庨櫓椤�, 棰嗘定娆℃暟] + """ + fresults = [] + for i in range(1, 10): + results = kpl_api.getHistoryCodesByPlateOrderByLZCS(plate_code, self.now_day, "0930", i) + results = json.loads(results)["list"] + fresults.extend(results) + if len(results) < 30: + break + fdatas = [] + for result in fresults: + d = result[0], result[1], result[2], result[40] + fdatas.append(d) + return fdatas + + def get_limit_up_reasons_with_plate_code(self): + """ + 鑾峰彇娑ㄥ仠鍘熷洜 + :return: 娑ㄥ仠鏁版嵁璁板綍[(浠g爜, 鏃ユ湡, 鏉垮潡, 鏄惁鐐告澘)] + """ + mysql = mysql_data_delegate.Mysqldb() + sql = """ + SELECT _hot_block_code,_hot_block_name FROM + ( + SELECT r.`_hot_block_code`, r.`_hot_block_name`, r.`_create_time` FROM + (SELECT DISTINCT(c.`_hot_block_code`) FROM `kpl_limit_up_record` c WHERE c.`_day`>'鏈�灏忔棩鏈�' and c.`_day`<'浠婃棩鏃ユ湡') a + LEFT JOIN kpl_limit_up_record r ON r.`_hot_block_code` = a._hot_block_code ORDER BY r.`_create_time` DESC + ) b GROUP BY b._hot_block_code HAVING b._hot_block_code IS NOT NULL + """ + sql = sql.replace("鏈�灏忔棩鏈�", self.trade_days[-1]).replace("浠婃棩鏃ユ湡", self.now_day) + results = mysql.select_all(sql) + return [x for x in results if kpl_util.filter_block(x[1]) not in constant.KPL_INVALID_BLOCKS] + + def load_jx_blocks(self, code): + if code in self.jx_blocks: + self.jx_blocks.get(code) + # 浠庢枃浠朵腑璇诲彇 + dir_path = os.path.join(self.cache_path, "jx_blocks", self.now_day) + path_str = os.path.join(dir_path, f"{code}.txt") + if os.path.exists(path_str): + with open(path_str, mode='r', encoding='utf-8') as f: + lines = f.readlines() + blocks = eval(lines[0]) + self.jx_blocks[code] = blocks + if code in self.jx_blocks: + return self.jx_blocks.get(code) + + blocks = kpl_api.getCodeJingXuanBlocks(code) + blocks = set([kpl_util.filter_block(x[1]) for x in blocks]) + blocks -= constant.KPL_INVALID_BLOCKS + self.jx_blocks[code] = blocks + # 淇濆瓨鍒版枃浠� + if not os.path.exists(dir_path): + os.makedirs(dir_path) + with open(os.path.join(dir_path, f"{code}.txt"), mode='w', encoding='utf-8') as f: + f.write(f"{blocks}") + return blocks + + def load_all_jx_blocks(self): + code_blocks = {} + # 浠庢枃浠朵腑璇诲彇 + dir_path = os.path.join(self.cache_path, "jx_blocks", self.now_day) + files = os.listdir(dir_path) + for file in files: + code = file[:6] + with open(os.path.join(dir_path, file), mode='r', encoding='utf-8') as f: + code_blocks[code] = eval(f.readlines()[0]) + return code_blocks + class StrategyVariableFactory: @staticmethod @@ -204,8 +535,11 @@ instance.鏄ㄦ棩闈炴定鍋� = not KTickLineAnalyzer.is_yesterday_limit_up(kline_data_1d) instance.鏄ㄦ棩闈炵偢鏉� = not KTickLineAnalyzer.is_yesterday_exploded(kline_data_1d) instance.鏄ㄦ棩闈炶穼鍋� = not KTickLineAnalyzer.is_yesterday_limit_down(kline_data_1d) + instance.鏄ㄦ棩鏈�浣庝环 = KTickLineAnalyzer.get_yesterday_low_price(kline_data_1d) + instance.鏄ㄦ棩寮�鐩樹环 = KTickLineAnalyzer.get_yesterday_open_price(kline_data_1d) + day_counts = [5, 10, 30, 60, 120] - for day in day_counts: + for day in [3, 5, 10, 30, 60, 120]: instance.__setattr__(f"鏃ユ渶楂樹环_{day}", KTickLineAnalyzer.get_recent_days_high(kline_data_1d, day)) for day in day_counts: instance.__setattr__(f"鏃ユ渶楂橀噺_{day}", KTickLineAnalyzer.get_recent_days_max_volume(kline_data_1d, day)) @@ -238,12 +572,16 @@ for day in day_counts: instance.__setattr__(f"鏃ュぇ绛変簬4娆¤穼鍋滀釜鏁癬{day}", KTickLineAnalyzer.get_fourth_or_more_limit_down_days(kline_data_1d, day)) + for day in [5, 10, 15, 30, 60, 120]: + instance.__setattr__(f"鏃ユ斁鍊嶉噺鏃ユ湡_{day}", + KTickLineAnalyzer.get_recent_days_double_volume_date(kline_data_1d, day)) for day in day_counts: days = trade_days[:day] instance.__setattr__(f"鏃ヤ釜鑲℃渶姝g殑鍘熷洜_{day}", KPLLimitUpDataAnalyzer.get_most_common_reasons(limit_up_data_records, min_day=days[-1], max_day=days[0])) + if kline_data_60s_dict: for day in day_counts: # 鑾峰彇鏃鏈�楂橀噺鐨勪俊鎭� @@ -258,9 +596,71 @@ return instance +def __test_jx_blocks(__DataLoader): + def load_all_codes(): + codes = set() + with open("D:/codes/codes_sh.text") as f: + lines = f.readlines() + codes |= set([x.strip() for x in lines if x.find("30") != 0]) + with open("D:/codes/codes_sz.text") as f: + lines = f.readlines() + codes |= set([x.strip() for x in lines if x.find("30") != 0]) + return codes + + code_blocks = __DataLoader.load_all_jx_blocks() + # codes = load_all_codes() + # for code in codes: + # print(code) + # __DataLoader.load_jx_blocks(code) + codes = ["002639", "002366"] + same_blocks = set() + for c in codes: + blocks = __DataLoader.load_jx_blocks(c) + if not same_blocks: + same_blocks = blocks + same_blocks &= blocks + print("鐩稿悓鏉垮潡", same_blocks) + for code in code_blocks: + if len(code_blocks[code] & same_blocks) == len(same_blocks): + if code in codes: + continue + print(code, code_blocks[code]) + + if __name__ == "__main__": + __DataLoader = DataLoader("2025-06-05") + # __test_jx_blocks(__DataLoader) + # instance = StockVariables() # day = 5 # instance.__setattr__(f"鏃ユ渶楂樹环_{day}", 12.00) # print(instance.鏃ユ渶楂樹环_5) - DataLoader("2025-05-06").load_tick_data() + + # 涓嬭浇鐩爣绁ㄧ殑鏉垮潡 + # fdata = __DataLoader.load_all_refer_plates_of_codes() + # print(fdata.get("000833")) + + # result_dict = __DataLoader.load_code_plates_for_refer() + # print(result_dict["301279"]) + + results = __DataLoader.load_target_plate_and_codes() + plates = ["鏈夎壊閲戝睘"] + print("==========鏂伴鏉�=======") + for p in plates: + print(p, results.get(p)) + + # print("椋熷搧楗枡", results.get("椋熷搧楗枡")) + # print("閿傜數姹�", results.get("閿傜數姹�")) + # print("鏁板瓧缁忔祹", results.get("鏁板瓧缁忔祹")) + # print("鍦颁骇閾�", results.get("鍦颁骇閾�")) + # print("鐗╂祦", results.get("鐗╂祦")) + + # 涓嬭浇娑ㄥ仠鍘熷洜鏉垮潡瀵瑰簲鐨勪唬鐮� + plates = __DataLoader.get_limit_up_reasons_with_plate_code() + for p in plates: + print(p) + __DataLoader.load_plate_codes(p[0], p[1]) + + # DataLoader("2025-05-06").load_tick_data() + # + # print(re.match(r"椋庨櫓|绔嬫", "椋庨櫓123")) diff --git a/strategy/test.py b/strategy/test.py index f08d26e..d3fa0ba 100644 --- a/strategy/test.py +++ b/strategy/test.py @@ -1,18 +1,21 @@ from strategy.strategy_variable import StockVariables -if __name__ == "__main__": - global_dict = {'x': 10} - codes = "" - with open("浣庡惛鑴氭湰.py", mode='r', encoding='utf-8') as f: - lines = f.readlines() - codes = "\n".join(lines) - # 娉ㄩ噴鎺夐噷闈㈢殑import涓庡彉閲� - codes = codes.replace("from ", "#from ").replace("sv = ", "#sv = ") - stock_variables = StockVariables() - stock_variables.褰撳墠浠� = 10.23 - stock_variables.鏄ㄦ棩鏈�楂樹环 = 10.00 - global_dict = { - "sv": stock_variables} - exec(codes, global_dict) - print(global_dict['compute_result']) +# 缁熻褰撴棩鐨勫钩鍧囨孩浠风巼 +def statistic_average(): + rate_list = [] + with open(r"C:\Users\Administrator\Desktop\3涓エ娑ㄥ仠涔嬪悗涔�.txt", mode='r', encoding='utf-8') as f: + lines = f.readlines() + for line in lines: + if line.find('鍥炴祴缁撴灉锛�') < 0: + continue + if line.find('褰撴棩鐩堜簭锛�') < 0: + continue + r = round(float(line.split("褰撴棩鐩堜簭锛�")[1].split("锛�")[0].replace("%", "")), 2) + rate_list.append(r) + print("骞冲潎鍒╂鼎鐜囷細", round(sum(rate_list) / len(rate_list), 2)) + print("鎬诲埄娑︾巼锛�", round(sum(rate_list), 2)) + + +if __name__ == "__main__": + statistic_average() diff --git a/strategy/time_series_backtest.py b/strategy/time_series_backtest.py index ffbe31e..b69de53 100644 --- a/strategy/time_series_backtest.py +++ b/strategy/time_series_backtest.py @@ -1,22 +1,48 @@ +import constant from code_attribute import gpcode_manager, code_nature_analyse +from strategy.data_analyzer import KPLLimitUpDataAnalyzer +from strategy.data_downloader import DataDownloader from strategy.low_suction_strategy import LowSuctionOriginDataExportManager +from strategy.strategy_params_settings import StrategyParamsSettings from strategy.strategy_variable import StockVariables from strategy.strategy_variable_factory import DataLoader, StrategyVariableFactory +from third_data import kpl_util +from third_data.third_blocks_manager import BlockMapManager from utils import tool, huaxin_util class BackTest: - def __init__(self, day): + def __init__(self, day, script_name="浣庡惛鑴氭湰_杈ㄨ瘑搴v3.py", settings=StrategyParamsSettings()): self.day = day scripts = "" - with open("浣庡惛鑴氭湰_杈ㄨ瘑搴�.py", mode='r', encoding='utf-8') as f: + with open(script_name, mode='r', encoding='utf-8') as f: lines = f.readlines() scripts = "\n".join(lines) # 娉ㄩ噴鎺夐噷闈㈢殑import涓庡彉閲� - scripts = scripts.replace("from ", "#from ").replace("sv = ", "#sv = ") + scripts = scripts.replace("from ", "#from ").replace("sv = ", "#sv = ").replace("settings = ", + "#settings = ").replace( + "target_code = ", "#target_code = ") + self.settings = settings self.scripts = scripts + self.RANGE_TIMES = ("09:25:00", "11:30:00") + self.current_time = '09:25:00' + self.stock_variables_dict = {} + self.data_loader: DataLoader = None + self.timeline_data = None + self.current_data = None + self.current_tick_data = None + self.fcodes = None + # 棰嗘定浠g爜鐨勬澘鍧�,{浠g爜:{"鏉垮潡":(浠g爜, 棰嗘定娆℃暟, 鏉垮潡鏈�澶ч娑ㄦ鏁�)}} + self.head_rise_code_blocks = {} + # 宸茬粡鎴愪氦鐨勪唬鐮� + self.deal_codes = set() + # 鏉垮潡宸茬粡鎴愪氦鐨勪唬鐮� + self.deal_block_codes = {} + + def set_script(self, script): + self.scripts = script def load_before_date_data_by_timeline(self, data_loader: DataLoader): """ @@ -28,6 +54,7 @@ timeline_data = [] # 鍔犺浇鍘嗗彶鏁版嵁 kline_data = data_loader.load_kline_data() + valid_codes = set(kline_data.keys()) minute_data = {} # data_loader.load_minute_data() limit_up_record_data = data_loader.load_limit_up_data() next_trade_day = data_loader.load_next_trade_day() @@ -37,14 +64,53 @@ raise Exception("鍘嗗彶鏃鑾峰彇澶辫触") if not kline_data: raise Exception("鍘嗗彶娑ㄥ仠鑾峰彇澶辫触") + # 缁熻120涓氦鏄撴棩鍐呬唬鐮佹定鍋滃師鍥犲搴旂殑娑ㄥ仠娆℃暟鎺掑悕鍓�3鐨勬澘鍧� + min_day = data_loader.trade_days[120 - 1] + block_code_dates = {} + for d in limit_up_record_data: + # 鍙粺璁″皝鏉� + if d[3] != 0: + continue + if d[1] < min_day: + continue + code, date, block = d[0], d[1], d[2] + if block not in block_code_dates: + block_code_dates[block] = {} + if code not in block_code_dates[block]: + block_code_dates[block][code] = set() + block_code_dates[block][code].add(date) + # 缁熻鐨勪唬鐮佺殑娑ㄥ仠鍘熷洜 + code_blocks = {} + for b in block_code_dates: + if b in constant.KPL_INVALID_BLOCKS: + continue + # if b == '璺ㄥ鐢靛晢': + # print("") + code_limit_up_count_list = [(x, len(block_code_dates[b][x])) for x in block_code_dates[b]] + code_limit_up_count_list.sort(key=lambda e: e[1], reverse=True) + end_index = 3 + # code_limit_up_count_list = code_limit_up_count_list[:3] + for i in range(end_index, len(code_limit_up_count_list)): + if code_limit_up_count_list[end_index - 1][1] == code_limit_up_count_list[i][1]: + end_index = i + 1 + code_limit_up_count_list = code_limit_up_count_list[:end_index] + for x in code_limit_up_count_list: + if x[1] < 3: + continue + if x[0] not in code_blocks: + code_blocks[x[0]] = set() + code_blocks[x[0]].add(b) return { 'date': day, 'kline_data': kline_data, + 'valid_codes': valid_codes, 'minute_data': minute_data, 'limit_up_record_data': limit_up_record_data, + 'limit_up_record_data_list': limit_up_record_data, "trade_days": trade_days, - "next_trade_day": next_trade_day + "next_trade_day": next_trade_day, + "code_blocks": code_blocks } def load_current_date_data_by_timeline(self): @@ -53,14 +119,18 @@ :param day: 鏃ユ湡锛屾牸寮忎负"YYYY-MM-DD :return: 鎸夋椂闂存帓搴忕殑鏁版嵁鍒楄〃 """ + if self.day >= '2025-05-26': + IS_BY_BIG_ORDER = True + else: + IS_BY_BIG_ORDER = False day = self.day fdata = {} __LowSuctionOriginDataExportManager = LowSuctionOriginDataExportManager(day) all_limit_up_list = __LowSuctionOriginDataExportManager.export_limit_up_list() fdata["limit_up_list"] = {d[0][:8]: d[1] for d in all_limit_up_list} - big_order_deals = __LowSuctionOriginDataExportManager.export_big_order_deal() - if not big_order_deals: - big_order_deals = __LowSuctionOriginDataExportManager.export_big_order_deal_by() + big_order_deals = __LowSuctionOriginDataExportManager.export_big_order_deal(BIG_ORDER_MONEY_THRESHOLD) + if not big_order_deals or IS_BY_BIG_ORDER: + big_order_deals = __LowSuctionOriginDataExportManager.export_big_order_deal_by(BIG_ORDER_MONEY_THRESHOLD) # 杞崲鏍煎紡涓猴細{鏃堕棿: [("浠g爜", (涔板崟鍙�, 閲�, 閲戦, 鏃堕棿, 鏈�缁堟垚浜や环))] big_order_deals_dict = {} for code in big_order_deals: @@ -74,9 +144,10 @@ datas = big_order_deals_dict[k] datas.sort(key=lambda x: huaxin_util.convert_time(x[1][3], True)) fdata["big_order"] = big_order_deals_dict - big_sell_order_deals = __LowSuctionOriginDataExportManager.export_big_sell_order_deal() - if not big_sell_order_deals: - big_sell_order_deals = __LowSuctionOriginDataExportManager.export_big_sell_order_deal_by() + big_sell_order_deals = __LowSuctionOriginDataExportManager.export_big_sell_order_deal(BIG_ORDER_MONEY_THRESHOLD) + if not big_sell_order_deals or IS_BY_BIG_ORDER: + big_sell_order_deals = __LowSuctionOriginDataExportManager.export_big_sell_order_deal_by( + BIG_ORDER_MONEY_THRESHOLD) big_sell_order_deals_dict = {} for code in big_sell_order_deals: for order in big_sell_order_deals[code]: @@ -94,8 +165,25 @@ zylt_volume_dict = __LowSuctionOriginDataExportManager.export_zylt_volume() fdata["zylt_volume"] = zylt_volume_dict + # 鍔犺浇鏉垮潡浠g爜 code_plates_dict = __LowSuctionOriginDataExportManager.export_code_plates() + + code_plates_dict_for_refer = self.data_loader.load_code_plates_for_refer() + + plate_codes = self.data_loader.load_target_plate_and_codes() + code_plates_dict_for_buy = {} + for p in plate_codes: + for code in plate_codes.get(p): + if code not in code_plates_dict_for_buy: + code_plates_dict_for_buy[code] = set() + code_plates_dict_for_buy[code].add(p) + fdata["code_plates_for_buy"] = code_plates_dict_for_buy + fdata["code_plates_for_refer"] = code_plates_dict_for_refer + fdata["code_plates"] = code_plates_dict + # 鍔犺浇鏉垮潡娴佸叆(娴佸叆涓烘) + block_in_datas = __LowSuctionOriginDataExportManager.export_block_in_datas() + fdata["block_in"] = {d[0][:8]: d[1] for d in block_in_datas} special_codes = __LowSuctionOriginDataExportManager.export_special_codes() temp_code_plates = {} @@ -106,6 +194,12 @@ temp_code_plates[code].add(plate) for code in temp_code_plates: code_plates_dict[code] = temp_code_plates[code] + # 鑾峰彇鎵�鏈夋定鍋滃師鍥犱笅闈㈢殑棰嗘定涓偂淇℃伅,寰楀埌鐨勪俊鎭牸寮忥細{"浠g爜":{鏉垮潡鍚嶇О}} + refer_plates_of_codes = self.data_loader.load_all_refer_plates_of_codes() + fdata["limit_up_plate_names_of_refer_code"] = refer_plates_of_codes + + fdata["all_buy_plates_of_codes"] = self.data_loader.load_all_buy_plates_of_codes() + # print("*****", plate_names_of_code.get("600774")) if not fdata["zylt_volume"]: raise Exception("鏃犺嚜鐢辨祦閫氭暟鎹�") @@ -115,16 +209,18 @@ raise Exception("鏃犲ぇ鍗曟暟鎹�") if not fdata["limit_up_list"]: raise Exception("鏃犳定鍋滄暟鎹�") + if not fdata["limit_up_plate_names_of_refer_code"]: + raise Exception("鏃犳定鍋滈娑ㄥ師鍥犳暟鎹�") return fdata def load_current_tick_datas(self, data_loader: DataLoader): """ 鍔犺浇Tick鏁版嵁 - :param day: 鏃ユ湡锛屾牸寮忎负"YYYY-MM-DD - :return: Tick鏁版嵁 + @param data_loader: + @return: Tick鏁版嵁 """ - code_tick_datas = data_loader.load_tick_data() + code_tick_datas = data_loader.load_tick_data(target_codes=self.fcodes) # 鏍规嵁鏃堕棿闆嗘垚 fdata = {} for code in code_tick_datas: @@ -146,19 +242,21 @@ """ global_dict = { "sv": stock_variables, - "target_code": code + "target_code": code, + "settings": self.settings } exec(self.scripts, global_dict) return global_dict["compute_result"] def __filter_codes(self, current_data, timeline_data): code_plates = current_data["code_plates"] - start_time, end_time = "09:25:00", "11:30:00" + start_time, end_time = self.RANGE_TIMES[0], self.RANGE_TIMES[1] fplates = set() for i in range(60 * 60 * 5): time_str = tool.trade_time_add_second(start_time, i) if time_str > end_time: break + self.current_time = time_str # 缁熻褰撳墠娑ㄥ仠鏁版嵁 current_limit_up_list = current_data["limit_up_list"].get(time_str) if current_limit_up_list: @@ -187,12 +285,9 @@ return fcodes - def __get_target_codes(self): - special_codes = LowSuctionOriginDataExportManager(self.day).export_special_codes() - fcodes = set() - for codes in [special_codes[p] for p in special_codes]: - fcodes |= codes - return fcodes + def __get_target_codes_v4(self): + valid_codes = self.timeline_data["valid_codes"] + return set(self.current_data["code_plates_for_buy"].keys()) & valid_codes def init_stock_variables(self, code_, timeline_data, current_data): """ @@ -202,73 +297,244 @@ """ if code_ in self.stock_variables_dict: return + stock_variables = StrategyVariableFactory.create_from_history_data( timeline_data["kline_data"].get(code_), timeline_data["minute_data"].get(code_), timeline_data["limit_up_record_data"].get(code_), timeline_data["trade_days"]) + # 鍔犺浇浠婃棩娑ㄥ仠浠� pre_close = timeline_data["kline_data"].get(code_)[0]["close"] stock_variables.浠婃棩娑ㄥ仠浠� = round(float(gpcode_manager.get_limit_up_price_by_preprice(code_, pre_close)), 2) stock_variables.鑷敱娴侀�氬競鍊� = current_data["zylt_volume"].get(code_) * pre_close # 鑾峰彇浠g爜鏉垮潡 - stock_variables.浠g爜鏉垮潡 = current_data["code_plates"].get(code_) + stock_variables.浠g爜鏉垮潡 = current_data["code_plates_for_buy"].get(code_) is_price_too_high = code_nature_analyse.is_price_too_high_in_days(code_, timeline_data["kline_data"].get(code_), stock_variables.浠婃棩娑ㄥ仠浠�) # if is_price_too_high[0]: # print("鍏釜浜ゆ槗鏃ユ定骞呰繃楂�", code_) stock_variables.鍏釜浜ゆ槗鏃ユ定骞呰繃楂� = is_price_too_high[0] + stock_variables.鏂颁唬鐮佹澘鍧� = timeline_data["code_blocks"].get(code_) + stock_variables.杈ㄨ瘑搴︿唬鐮� = self.fcodes + stock_variables.棰嗘定鏉垮潡淇℃伅 = self.head_rise_code_blocks.get(code_) + if code_ in DEBUG_CODES: + print(code_, stock_variables.棰嗘定鏉垮潡淇℃伅) + + for day in [2, 5, 10, 30, 60, 120]: + days = timeline_data["trade_days"][:day] + stock_variables.__setattr__(f"鏃ュ嚭鐜扮殑鏉垮潡_{day}", + KPLLimitUpDataAnalyzer.get_limit_up_reasons( + timeline_data["limit_up_record_data_list"], min_day=days[-1], + max_day=days[0])) + stock_variables.杩炵画鑰侀鏉� = KPLLimitUpDataAnalyzer.get_continuous_limit_up_reasons( + timeline_data["limit_up_record_data_list"], self.data_loader.trade_days[:2]) + self.stock_variables_dict[code_] = stock_variables - def run(self): - data_loader = DataLoader(self.day) - current_data = self.load_current_date_data_by_timeline() + def load_data(self): + """ + 鍔犺浇鏁版嵁 + @return:鍘嗗彶鏁版嵁, 浠婃棩鏁版嵁, tick鏁版嵁 + """ + # 鎻愬墠涓嬭浇鏁版嵁 + __DataLoader = DataLoader(self.day) + plates = __DataLoader.get_limit_up_reasons_with_plate_code() + for p in plates: + __DataLoader.load_plate_codes(p[0], p[1]) + + if not self.data_loader: + self.data_loader = DataLoader(self.day) + if not self.current_data: + self.current_data = self.load_current_date_data_by_timeline() # 鎸夋椂闂磋酱鍔犺浇鏁版嵁 - timeline_data = self.load_before_date_data_by_timeline(data_loader) + if not self.timeline_data: + self.timeline_data = self.load_before_date_data_by_timeline(self.data_loader) # TODO 杈撳嚭鐩爣浠g爜 - fcodes = self.__get_target_codes() # __filter_codes(current_data, timeline_data) - # print(len(fcodes), fcodes) - current_tick_data = self.load_current_tick_datas(data_loader) + if not self.fcodes: + # self.fcodes, self.head_rise_code_blocks = self.__get_target_codes_v3() # __filter_codes(current_data, timeline_data) + self.fcodes, self.head_rise_code_blocks = self.__get_target_codes_v4(), {} + + print(len(self.fcodes), self.fcodes) + if not self.current_tick_data: + try: + self.current_tick_data = self.load_current_tick_datas(self.data_loader) + except: + pass + + __DataDownloader = DataDownloader(self.day, self.data_loader.trade_days) + __DataDownloader.download_tick_data(self.fcodes) + + def __statistic_big_order_info(self, stock_variables: StockVariables): + """ + 缁熻澶у崟淇℃伅 + @param stock_variables: + @return: + """ + infos = [] + thresholds = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 10000] + for i in range(len(thresholds)): + if i >= len(thresholds) - 1: + break + start, end = thresholds[i], thresholds[i + 1] + info = [f"{start}w-{end}w", 0, None, None] + # 缁熻涔板崟 + total_buy_count = 0 + total_buy_volume = 0 + total_buy_money = 0 + if stock_variables.浠婃棩澶у崟鏁版嵁: + order_ids = set() + for d in reversed(stock_variables.浠婃棩澶у崟鏁版嵁): + if d[0] in order_ids: + continue + order_ids.add(d[0]) + if start * 10000 <= d[2] < end * 10000: + total_buy_count += 1 + total_buy_money += d[2] + total_buy_volume += d[1] + total_sell_count = 0 + total_sell_money = 0 + total_sell_volume = 0 + if stock_variables.浠婃棩鍗栧ぇ鍗曟暟鎹�: + order_ids = set() + for d in reversed(stock_variables.浠婃棩鍗栧ぇ鍗曟暟鎹�): + if d[0] in order_ids: + continue + order_ids.add(d[0]) + if start * 10000 <= d[2] < end * 10000: + total_sell_count += 1 + total_sell_money += d[2] + total_sell_volume += d[1] + info[1] = f"{round((total_buy_volume - total_sell_volume) * 100 / stock_variables.浠婃棩鎴愪氦閲�, 2)}%" + info[2] = (total_buy_count, total_buy_money, total_buy_volume) + info[3] = (total_sell_count, total_sell_money, total_sell_volume) + if info[2][0] > 0 or info[3][0] > 0: + infos.append(info) + return ";".join([f"{x[0]}==鍑�棰�:{x[1]},涔板崟锛歿x[2]},鍗栧崟锛歿x[3]}" for x in infos]) + + def run(self): + self.load_data() + # print(self.fcodes) limit_up_record_data_dict = {} - for limit_up_item in timeline_data["limit_up_record_data"]: + for limit_up_item in self.timeline_data["limit_up_record_data"]: if limit_up_item[0] not in limit_up_record_data_dict: limit_up_record_data_dict[limit_up_item[0]] = [] limit_up_record_data_dict[limit_up_item[0]].append(limit_up_item) - timeline_data["limit_up_record_data"] = limit_up_record_data_dict - next_trade_day = timeline_data["next_trade_day"] + self.timeline_data["limit_up_record_data"] = limit_up_record_data_dict + next_trade_day = self.timeline_data["next_trade_day"] start_time, end_time = "09:25:00", "12:00:00" # 鍒嗛挓K绾� minute_bars_dict = {} - code_plates = current_data["code_plates"] - # 鏉垮潡浠ュ強涔颁簡鐨勪唬鐮侊細{"鏉垮潡":{"000333"}} - deal_block_codes = {} - deal_codes = set() - print("======", self.day) - # 鍒堕�犲洖娴嬫椂闂� + code_plates = self.current_data["code_plates"] + code_plates_for_refer = self.current_data["code_plates_for_refer"] + + # 鏉垮潡娑ㄥ仠浠g爜淇℃伅 + kpl_plate_limit_up_codes_info = None + plate_limit_up_codes_info = None + kpl_head_plate_limit_up_codes_info = None + + latest_current_limit_up_list = None + + latest_block_in_datas = None + + # 鏍规嵁鏉垮潡鑾峰彇鐩爣绁� + target_plate_codes_infos = {} + for code in self.head_rise_code_blocks: + for p in self.head_rise_code_blocks[code]: + if p not in target_plate_codes_infos: + target_plate_codes_infos[p] = [] + target_plate_codes_infos[p].append(self.head_rise_code_blocks[code][p]) + for p in target_plate_codes_infos: + target_plate_codes_infos[p].sort(key=lambda x: x[1], reverse=True) + + all_new_plates = set() + for i in range(60 * 60 * 5): time_str = tool.trade_time_add_second(start_time, i) + # print(f"[{tool.get_now_time_str()}]", time_str) if time_str > end_time: break - ticks = current_tick_data.get(time_str) - # 缁熻褰撳墠娑ㄥ仠鏁版嵁 - current_limit_up_list = current_data["limit_up_list"].get(time_str) + ticks = self.current_tick_data.get(time_str) if self.current_tick_data else None + # ===============缁熻褰撳墠娑ㄥ仠鏁版嵁 + origin_current_limit_up_list = self.current_data["limit_up_list"].get(time_str, []) + current_limit_up_list = [x for x in origin_current_limit_up_list if kpl_util.get_high_level_count(x[4]) < 3] + if current_limit_up_list: - # 缁熻鏉垮潡娑ㄥ仠 + latest_current_limit_up_list = current_limit_up_list + + if current_limit_up_list: plate_codes_info = {} + # 缁熻鏉垮潡娑ㄥ仠 for x in current_limit_up_list: + # 鎸変唬鐮佺殑鏉垮潡缁熻娑ㄥ仠鏉垮潡涓殑浠g爜鏁伴噺 + # 娑ㄥ仠杩�1鍒嗛挓鎵嶇畻鏈夋晥娑ㄥ仠 + if tool.trade_time_sub(time_str, tool.timestamp_format(x[2], "%H:%M:%S")) < 60: + continue plates = code_plates.get(x[0]) if plates: for p in plates: if p not in plate_codes_info: plate_codes_info[p] = [] plate_codes_info[p].append((x[0], x[2])) - else: - plate_codes_info = None + plate_limit_up_codes_info = plate_codes_info - # 褰撳墠鏃跺埢澶у崟 - current_big_orders = current_data["big_order"].get(time_str) + plate_codes_info = {} + for x in current_limit_up_list: + # 鎸夊紑鐩樺暒娑ㄥ仠鍘熷洜缁熻 + p = x[5] + if p in constant.KPL_INVALID_BLOCKS: + continue + if p not in plate_codes_info: + plate_codes_info[p] = [] + # 濡傛灉棰嗘定浠g爜閲岄潰娌℃湁褰撳墠绁ㄥ氨涓嶇畻杩欎釜鏉垮潡鐨勬定鍋滃師鍥� + # 鑾峰彇棰嗘定鏁版嵁 + # head_plate_codes_info = self.data_loader.load_plate_codes(x[9], p) + # if head_plate_codes_info: + # plate_codes = set([x[0] for x in head_plate_codes_info]) + # else: + # plate_codes = set() + # if x[0] not in plate_codes: + # continue + plate_codes_info[p].append((x[0], x[2], x[4])) + kpl_plate_limit_up_codes_info = plate_codes_info + + # {"浠g爜":[(鏉垮潡浠g爜, 鏉垮潡鍚嶇О)]} + limit_up_plate_names_of_refer_code = self.current_data["limit_up_plate_names_of_refer_code"] + plate_codes_info = {} + for x in current_limit_up_list: + # 鎸夊紑鐩樺暒娑ㄥ仠鍘熷洜缁熻 + code = x[0] + # if code not in limit_up_plate_names_of_refer_code: + # continue + # 濡傛灉璁板綍娑ㄥ仠鏃堕棿杩囧幓20鍒嗛挓灏遍噰鐢ㄦ定鍋滈槦鍒楃殑娑ㄥ仠鍘熷洜 + if tool.trade_time_sub(time_str, tool.timestamp_format(x[2], "%H:%M:%S")) < 60 * 20 or True: + plates_infos = limit_up_plate_names_of_refer_code.get(code) + plates = set([d[1] for d in plates_infos if d[1] == x[5]]) if plates_infos else set() + else: + plates = {x[5]} + + new_plates = set() + for p in plates: + if p in constant.KPL_INVALID_BLOCKS: + continue + new_plates.add(p) + for p in new_plates: + if p not in plate_codes_info: + plate_codes_info[p] = [] + plate_codes_info[p].append((x[0], x[2])) + kpl_head_plate_limit_up_codes_info = plate_codes_info + + # ==================娉ㄥ叆鏉垮潡娴佸叆 + block_in_datas = self.current_data["block_in"].get(time_str) + if block_in_datas: + blocks = [x[0] for x in block_in_datas if x[1] > 0] + block_in_datas = blocks[:20] + latest_block_in_datas = block_in_datas + + # ================褰撳墠鏃跺埢澶у崟 + current_big_orders = self.current_data["big_order"].get(time_str) if current_big_orders: for big_order in current_big_orders: # 鏍煎紡 ("浠g爜", (涔板崟鍙�, 閲�, 閲戦, 鏃堕棿, 鏈�缁堟垚浜や环)) - self.init_stock_variables(big_order[0], timeline_data, current_data) + self.init_stock_variables(big_order[0], self.timeline_data, self.current_data) stock_variables: StockVariables = self.stock_variables_dict.get(big_order[0]) if stock_variables.浠婃棩澶у崟鏁版嵁 is None: stock_variables.浠婃棩澶у崟鏁版嵁 = [] @@ -287,40 +553,74 @@ stock_variables.浠婃棩澶у崟鍧囦环 = round(total_money / total_volume, 2) else: stock_variables.浠婃棩澶у崟鍧囦环 = 0 - - current_big_sell_orders = current_data["big_sell_order"].get(time_str) + current_big_sell_orders = self.current_data["big_sell_order"].get(time_str) if current_big_sell_orders: for big_order in current_big_sell_orders: # 鏍煎紡 ("浠g爜", (涔板崟鍙�, 閲�, 閲戦, 鏃堕棿, 鏈�缁堟垚浜や环)) - self.init_stock_variables(big_order[0], timeline_data, current_data) + self.init_stock_variables(big_order[0], self.timeline_data, self.current_data) stock_variables: StockVariables = self.stock_variables_dict.get(big_order[0]) if stock_variables.浠婃棩鍗栧ぇ鍗曟暟鎹� is None: stock_variables.浠婃棩鍗栧ぇ鍗曟暟鎹� = [] stock_variables.浠婃棩鍗栧ぇ鍗曟暟鎹�.append(big_order[1]) + + # 寮�鐩樺暒鏈�姝f定鍋滃師鍥� + most_real_kpl_plate_limit_up_codes_info = {} + # 鑾峰彇杩欎釜鏉垮潡鐨勭洰鏍囩エ + if kpl_plate_limit_up_codes_info: + current_limit_up_dict = {x[0]: x for x in latest_current_limit_up_list} + codes = set() + for plate in kpl_plate_limit_up_codes_info: + kpl_plate_codes = kpl_plate_limit_up_codes_info.get(plate) + codes |= set([x[0] for x in kpl_plate_codes]) + for code in codes: + plates = code_plates.get(code) + if not plates: + plates = {current_limit_up_dict.get(code)[5]} + plates -= constant.KPL_INVALID_BLOCKS + if plates: + for p in plates: + if p not in most_real_kpl_plate_limit_up_codes_info: + most_real_kpl_plate_limit_up_codes_info[p] = [] + most_real_kpl_plate_limit_up_codes_info[p].append(code) + if ticks: for tick in ticks: code = tick["symbol"][-6:] - if code not in fcodes: + # if code not in self.fcodes: + # continue + if DEBUG_CODES and code not in DEBUG_CODES: continue + if code not in self.stock_variables_dict: # 鍔犺浇鍩虹鏁版嵁 - self.init_stock_variables(code, timeline_data, current_data) + self.init_stock_variables(code, self.timeline_data, self.current_data) stock_variables: StockVariables = self.stock_variables_dict.get(code) - stock_variables.鏉垮潡鎴愪氦浠g爜 = deal_block_codes - # 璁剧疆娑ㄥ仠鏁版嵁 - if plate_codes_info is not None: - stock_variables.鏉垮潡娑ㄥ仠 = plate_codes_info - if code not in minute_bars_dict: - minute_bars_dict[code] = [tick] - if minute_bars_dict[code][-1]["created_at"][:-2] == tick["created_at"][:-2]: - # 缁熻鍒嗛挓K绾� - minute_bars_dict[code][-1] = tick - else: - # 淇濆瓨鍒嗛挓K绾挎渶楂樹环 - if not stock_variables.浠婃棩鏈�楂樹环: - stock_variables.浠婃棩鏈�楂樹环 = minute_bars_dict[code][-1]["price"] - if minute_bars_dict[code][-1]["price"] > stock_variables.浠婃棩鏈�楂樹环: - stock_variables.浠婃棩鏈�楂樹环 = minute_bars_dict[code][-1]["price"] + if plate_limit_up_codes_info is not None: + stock_variables.鏉垮潡娑ㄥ仠 = plate_limit_up_codes_info + + if kpl_plate_limit_up_codes_info is not None: + stock_variables.寮�鐩樺暒鏉垮潡娑ㄥ仠 = kpl_plate_limit_up_codes_info + + if kpl_head_plate_limit_up_codes_info is not None: + stock_variables.寮�鐩樺暒棰嗘定鏉垮潡娑ㄥ仠 = kpl_head_plate_limit_up_codes_info + + stock_variables.鏉垮潡鎴愪氦浠g爜 = self.deal_block_codes + # 鏉垮潡娴佸叆鏁版嵁 + if latest_block_in_datas: + stock_variables.璧勯噾娴佸叆鏉垮潡 = latest_block_in_datas + # 鏆傛椂涓嶇敤鍒嗛挓K绾� + # if code not in minute_bars_dict: + # minute_bars_dict[code] = [tick] + # if minute_bars_dict[code][-1]["created_at"][:-2] == tick["created_at"][:-2]: + # # 缁熻鍒嗛挓K绾� + # minute_bars_dict[code][-1] = tick + # else: + # # 淇濆瓨鍒嗛挓K绾挎渶楂樹环 + # if not stock_variables.浠婃棩鏈�楂樹环: + # stock_variables.浠婃棩鏈�楂樹环 = minute_bars_dict[code][-1]["price"] + # if minute_bars_dict[code][-1]["price"] > stock_variables.浠婃棩鏈�楂樹环: + # stock_variables.浠婃棩鏈�楂樹环 = minute_bars_dict[code][-1]["price"] + # 淇濆瓨寮�鐩樹环 if tick["created_at"][-8:] < '09:30:00': stock_variables.浠婃棩寮�鐩樹环 = tick["price"] @@ -328,54 +628,167 @@ stock_variables.浠婃棩寮�鐩樻定骞� = round((tick["price"] - stock_variables.鏄ㄦ棩鏀剁洏浠�) / stock_variables.鏄ㄦ棩鏀剁洏浠�, 4) stock_variables.浠婃棩鎴愪氦閲� = tick["cum_volume"] + stock_variables.浠婃棩鎴愪氦棰� = tick["cum_amount"] stock_variables.褰撳墠浠� = tick["price"] - # 鏍规嵁琛ㄨ揪寮忚绠楁槸鍚﹀彲涔� - # compute_result = __run_backtest(code, stock_variables) - # # print("鍥炴祴缁撴灉锛�",code, compute_result) - # if compute_result[0] and code not in deal_codes: - # # TODO 涓嬪崟 - # deal_codes.add(code) - # print("======鍥炴祴缁撴灉锛�", code, tick["created_at"], tick["price"], compute_result[2]) - # for b in compute_result[1]: - # if b not in deal_block_codes: - # deal_block_codes[b] = set() - # deal_block_codes[b].add(code) + if not stock_variables.浠婃棩閲忓淇℃伅: + if stock_variables.浠婃棩鎴愪氦閲� > stock_variables.鏄ㄦ棩鎴愪氦閲� * 0.8: + stock_variables.浠婃棩閲忓淇℃伅 = (time_str, stock_variables.褰撳墠浠�, round( + (stock_variables.褰撳墠浠� - stock_variables.鏄ㄦ棩鏀剁洏浠�) * 100 / stock_variables.鏄ㄦ棩鏀剁洏浠�, 2), + self.__statistic_big_order_info(stock_variables)) + if VOLUME_LOG_ENABLE: + # 缁熻澶у崟鍑�棰濓紝(50w浠ヤ笂,鍑�棰�,涔板崟涓暟/涔板崟鎬婚噾棰�,鍗栧崟涓暟/鍗栧崟鎬婚噾棰�) + print("****閲忓", code, stock_variables.浠婃棩閲忓淇℃伅) + + # 缁熻浠婃棩鏈�楂樹环 + # if stock_variables.浠婃棩鏈�楂樹环 and tick["price"] > stock_variables.浠婃棩鏈�楂樹环: + # print(code, "====绐佺牬鍒嗘椂鏈�楂樹环锛�", tick["created_at"], tick["price"]) + + if not stock_variables.浠婃棩鏈�楂樹环淇℃伅 or tick["price"] > stock_variables.浠婃棩鏈�楂樹环淇℃伅[0]: + stock_variables.浠婃棩鏈�楂樹环淇℃伅 = (tick["price"], time_str) + + if not stock_variables.浠婃棩鏈�浣庝环 or tick["price"] < stock_variables.浠婃棩鏈�浣庝环: + stock_variables.浠婃棩鏈�浣庝环 = tick["price"] + + stock_variables.寮�鐩樺暒鏈�姝f澘鍧楁定鍋� = most_real_kpl_plate_limit_up_codes_info + + # compute_result = self.__run_backtest(code, stock_variables) + # self.__process_test_result(code, stock_variables, next_trade_day, stock_variables.褰撳墠浠�, + # time_str, compute_result) + + # if len(real_codes) >= 2 and time_str > '09:30:00': + # # print(time_str, plate) + # # 鎵捐繖涓澘鍧楅娑ㄦ鏁版渶澶氱殑绁� + # codes_infos = target_plate_codes_infos.get(plate) + # if codes_infos: + # for code_info in codes_infos: + # code = code_info[0] + # self.init_stock_variables(code, self.timeline_data, self.current_data) + # stock_variables: StockVariables = self.stock_variables_dict.get(code) + # compute_result = self.__run_backtest(code, stock_variables) + # if compute_result[0] and plate not in all_new_plates: + # all_new_plates.add(plate) + # print(plate, time_str, code_info, real_codes) + # else: + # pass # 澶у崟椹卞姩 - if current_big_orders: + if current_big_orders and time_str >= '09:30:00': for big_order in current_big_orders: code = big_order[0] - self.init_stock_variables(code, timeline_data, current_data) + if code not in self.fcodes: + continue + self.init_stock_variables(code, self.timeline_data, self.current_data) stock_variables: StockVariables = self.stock_variables_dict.get(code) + if plate_limit_up_codes_info is not None: + stock_variables.鏉垮潡娑ㄥ仠 = plate_limit_up_codes_info + + if kpl_plate_limit_up_codes_info is not None: + stock_variables.寮�鐩樺暒鏉垮潡娑ㄥ仠 = kpl_plate_limit_up_codes_info + + if kpl_head_plate_limit_up_codes_info is not None: + stock_variables.寮�鐩樺暒棰嗘定鏉垮潡娑ㄥ仠 = kpl_head_plate_limit_up_codes_info + + if most_real_kpl_plate_limit_up_codes_info is not None: + stock_variables.寮�鐩樺暒鏈�姝f澘鍧楁定鍋� = most_real_kpl_plate_limit_up_codes_info + + if block_in_datas: + stock_variables.璧勯噾娴佸叆鏉垮潡 = block_in_datas compute_result = self.__run_backtest(code, stock_variables) - # print("鍥炴祴缁撴灉锛�",code, compute_result) - # if code == '002640': - # print(code, big_order, compute_result) - if compute_result[0] and code not in deal_codes: - # TODO 涓嬪崟 - deal_codes.add(code) - next_k_bars = data_loader.load_kline_data_by_day_and_code(next_trade_day, code) - current_k_bars = data_loader.load_kline_data_by_day_and_code(data_loader.now_day, code) - if next_k_bars: - t_rate = round((next_k_bars[0]["open"] - big_order[1][4]) * 100 / big_order[1][4], 2) - t_rate = f"{t_rate}%" - else: - t_rate = "鏈煡" - if current_k_bars: - c_rate = round((current_k_bars[0]["close"] - big_order[1][4]) * 100 / big_order[1][4], 2) - c_rate = f"{c_rate}%" - else: - c_rate = "鏈煡" + # print(compute_result) + self.__process_test_result(code, stock_variables, next_trade_day, big_order[1][4], + huaxin_util.convert_time(big_order[1][3]), compute_result) - print("======鍥炴祴缁撴灉锛�", code, f"婧环鐜囷細{t_rate},褰撴棩鐩堜簭锛歿c_rate}", compute_result[2]) - for b in compute_result[1]: - if b not in deal_block_codes: - deal_block_codes[b] = set() - deal_block_codes[b].add(code) + print("鍙拱棰樻潗锛�", all_new_plates) + def __process_test_result(self, code, stock_variables: StockVariables, next_trade_day, buy_price, time_str, + compute_result): + + # if code == '000628': + # print(time_str, code, compute_result) + + if not compute_result[0]: + if code in DEBUG_CODES: + print(time_str, code, compute_result[1]) + # if compute_result[1].find("澶у崟") >= 0 or compute_result[1].find("浠锋牸瓒呰繃鏄ㄦ棩鏈�浣庝环") >= 0: + pass + + # print(code, time_str,stock_variables.浠g爜鏉垮潡, compute_result) + + if compute_result[0] and code not in self.deal_codes: + # 鏈�澶氫拱5涓� + if len(self.deal_codes) >= 100: + return + # if huaxin_util.convert_time(big_order[1][3]) >= "10:30:00" and len(deal_codes) > 0: + # break + self.deal_codes.add(code) + next_k_bars = self.data_loader.load_kline_data_by_day_and_code(next_trade_day, code) + current_k_bars = self.data_loader.load_kline_data_by_day_and_code(self.data_loader.now_day, + code) + if next_k_bars and buy_price: + t_rate = round((next_k_bars[0]["open"] - buy_price) * 100 / stock_variables.鏄ㄦ棩鏀剁洏浠�, 2) + t_rate = f"{t_rate}%" + else: + # 鑾峰彇褰撳墠鐨則ick绾� + if self.data_loader.now_day >= next_trade_day: + ticks = self.data_loader.jueJinLocalApi.get_history_tick_n(code, 1, frequency='tick', + end_date=f"{next_trade_day} 09:30:03") + else: + ticks = None + if ticks: + t_rate = round((ticks[-1]["price"] - buy_price) * 100 / stock_variables.鏄ㄦ棩鏀剁洏浠�, 2) + t_rate = f"{t_rate}%" + else: + t_rate = "鏈煡" + if current_k_bars and buy_price: + c_rate = round((current_k_bars[0]["close"] - buy_price) * 100 / current_k_bars[0]["pre_close"], 2) + c_rate = f"{c_rate}%" + else: + # 鎷夊彇褰撴棩K绾� + if tool.get_now_date_str() == self.data_loader.now_day and buy_price: + tick = self.data_loader.jueJinLocalApi.get_history_tick_n(code, 1, frequency='tick', + end_date=f"{self.data_loader.now_day} {tool.get_now_time_str()}") + c_rate = round((tick[0]["price"] - buy_price) * 100 / stock_variables.鏄ㄦ棩鏀剁洏浠�, 2) + else: + bar = self.data_loader.jueJinLocalApi.get_history_tick_n(code, 1, + end_date=f"{self.data_loader.now_day} 15:00:00") + if bar: + c_rate = round((bar[0]["close"] - buy_price) * 100 / bar[0]["pre_close"], 2) + else: + c_rate = "鏈煡" + print(f"{len(self.deal_codes)}==鍥炴祴缁撴灉锛�", code, gpcode_manager.CodesNameManager().get_code_name(code), + f"婧环鐜囷細{t_rate},褰撴棩鐩堜簭锛歿c_rate}锛屼笅鍗曟椂闂达細{time_str}锛屾定骞咃細{round((buy_price - stock_variables.鏄ㄦ棩鏀剁洏浠�) * 100 / stock_variables.鏄ㄦ棩鏀剁洏浠�, 2)}", + compute_result[1], + compute_result[2]) + for b in compute_result[3]: + if b not in self.deal_block_codes: + self.deal_block_codes[b] = set() + self.deal_block_codes[b].add(code) + stock_variables.鏉垮潡鎴愪氦浠g爜 = self.deal_block_codes + + +# DEBUG_CODES = ['002194', '002583', '603083', '002130', '002436'] +DEBUG_CODES = [] + +VOLUME_LOG_ENABLE = False +# 澶囩敤澶у崟 + + +DEBUG_BLOCKS = [] + +BIG_ORDER_MONEY_THRESHOLD = 200e4 if __name__ == "__main__": - days = ["2025-05-06", "2025-05-07", "2025-05-08", "2025-05-09", "2025-05-12"] + back_test_dict = {} + # days = ["2025-05-06", "2025-05-07", "2025-05-08", "2025-05-09", "2025-05-12", "2025-05-13", "2025-05-14", + # "2025-05-15", "2025-05-16"] + days = ["2025-05-12", "2025-05-13", "2025-05-14", "2025-05-15", "2025-05-16", "2025-05-19", "2025-05-20", + "2025-05-21", "2025-05-22","2025-05-23", "2025-05-26", "2025-05-27", "2025-05-28", "2025-05-29", + "2025-05-30", "2025-06-03", "2025-06-04", "2025-06-05", "2025-06-06"] days.reverse() for day in days: - BackTest(day).run() + if day not in back_test_dict: + # back_test_dict[day] = BackTest(day, "浠婃棩閲忔槸鍚﹁冻澶�.py") + back_test_dict[day] = BackTest(day, "浣庡惛鑴氭湰_杈ㄨ瘑搴v6.py") + print("=========================", day) + # back_test_dict[day].run_volume() + back_test_dict[day].run() diff --git "a/strategy/\344\273\212\346\227\245\351\207\217\346\230\257\345\220\246\350\266\263\345\244\237.py" "b/strategy/\344\273\212\346\227\245\351\207\217\346\230\257\345\220\246\350\266\263\345\244\237.py" new file mode 100644 index 0000000..3d1edb0 --- /dev/null +++ "b/strategy/\344\273\212\346\227\245\351\207\217\346\230\257\345\220\246\350\266\263\345\244\237.py" @@ -0,0 +1,43 @@ +from strategy.strategy_variable import StockVariables + +sv = StockVariables() + + +def can_buy(): + """ + @return: 鏄惁鍙拱, 涓嶈兘涔扮殑鍘熷洜/鍙拱鐨勬澘鍧� + """ + # print(f"{target_code}:鎵ц绛栫暐") + if target_code.find("60") != 0 and target_code.find("00") != 0: + return False, "鍒涗笟鏉�/绉戝垱鏉跨殑绁ㄤ笉涔�" + if not sv.鏄ㄦ棩闈炶穼鍋� or not sv.鏄ㄦ棩闈炴定鍋� or not sv.鏄ㄦ棩闈炵偢鏉�: + return False, "鏃涓嶆弧瓒虫潯浠�" + if not sv.棰嗘定鏉垮潡淇℃伅: + return False, "娌℃湁鏉垮潡" + if sv.鑷敱娴侀�氬競鍊� > 300e8 or sv.鑷敱娴侀�氬競鍊� < 10e8: + return False, f"鑷敱甯傚�硷紙{sv.鑷敱娴侀�氬競鍊紏锛変笉婊¤冻瑕佹眰" + + if sv.浠婃棩娑ㄥ仠浠� > 60 or sv.浠婃棩娑ㄥ仠浠� < 2.99: + return False, "浠婃棩娑ㄥ仠浠烽珮浜�60/浣庝簬2.99" + if sv.娑ㄥ仠鏁癬30 <= 0 and not sv.鏃ユ斁鍊嶉噺鏃ユ湡_15: + return False, "30涓氦鏄撴棩鏃犳定鍋滀笖15涓氦鏄撴棩鏃犲�嶉噺" + + if abs((sv.褰撳墠浠� - round(sv.浠婃棩鎴愪氦棰� / sv.浠婃棩鎴愪氦閲�, 2)) / sv.鏄ㄦ棩鏀剁洏浠�) >= 0.01: + return False, f"涔板叆浠烽珮浜庡潎浠�1.0涓偣" + + tr = 0.03 + rate = (sv.褰撳墠浠� - sv.鏄ㄦ棩鏀剁洏浠�) / sv.鏄ㄦ棩鏀剁洏浠� + if rate >= tr or rate < 0: + return False, f"娑ㄥ箙杩囬珮:{rate}" + + if sv.浠婃棩鎴愪氦閲� < sv.鏄ㄦ棩鎴愪氦閲� * 0.9: + return False, f"閲忎笉澶�" + if sv.浠g爜绮鹃�夋澘鍧� and sv.寮�鐩樺暒绮鹃�夋澘鍧楁定鍋�: + buy_blocks = sv.浠g爜绮鹃�夋澘鍧� - sv.鏃ュ嚭鐜扮殑鏉垮潡_5 + buy_blocks = buy_blocks & set(sv.寮�鐩樺暒绮鹃�夋澘鍧楁定鍋�.keys()) + if len(buy_blocks) >= 3: + return True, f"鍙拱鏉垮潡{[(b, sv.寮�鐩樺暒绮鹃�夋澘鍧楁定鍋�.get(b)) for b in buy_blocks]}" + return False, "娌℃湁鏉垮潡" + + +compute_result = can_buy() diff --git "a/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246.py" "b/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246.py" index de79391..e3b9109 100644 --- "a/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246.py" +++ "b/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246.py" @@ -30,6 +30,10 @@ big_order_count = 0 if sv.浠婃棩澶у崟鏁版嵁: + # 10涓氦鏄撴棩鍐呮湁鐐告澘鎴栨定鍋滃氨鐪�5涓氦鏄撴棩 + # if sv.娑ㄥ仠鏁癬10 > 0 or sv.鐐告澘鏁癬10 > 0: + # big_order_count = len(set([o[0] for o in sv.浠婃棩澶у崟鏁版嵁 if sv.鏃ユ渶楂樹环_5 <= o[4] < sv.鏄ㄦ棩鏀剁洏浠� * 1.06])) + # else: big_order_count = len(set([o[0] for o in sv.浠婃棩澶у崟鏁版嵁 if sv.鏃ユ渶楂樹环_10 <= o[4] < sv.鏄ㄦ棩鏀剁洏浠� * 1.06])) if big_order_count < 1: # max(1, int(round(sv.鏄ㄦ棩鎴愪氦棰� * 0.33 / 1e8))): return False, f"({big_order_count})灏戜簬1涓ぇ鍗�" @@ -39,19 +43,13 @@ can_buy_blocks = set([k for k in sv.浠g爜鏉垮潡 if sv.鏉垮潡娑ㄥ仠 and k in sv.鏉垮潡娑ㄥ仠 and len(sv.鏉垮潡娑ㄥ仠[k]) >= 1]) if not can_buy_blocks: return False, "鏉垮潡灏戜簬1涓定鍋�" - # 鏄惁杩樻湁鍙拱鐨勬澘鍧� - # can_buy_blocks = sv.浠g爜鏉垮潡 - sv.鏉垮潡鎴愪氦浠g爜.keys() - # if not can_buy_blocks: - # return False, "娌℃湁鍙拱鐨勪唬鐮�" + can_buy_blocks = sv.浠g爜鏉垮潡 - sv.鏉垮潡鎴愪氦浠g爜.keys() + if not can_buy_blocks: + return False, "鏉垮潡宸叉湁鎴愪氦浠g爜" tr = 0.06 if target_code.find("30") != 0 else 0.12 if (sv.浠婃棩澶у崟鏁版嵁[-1][4] - sv.鏄ㄦ棩鏀剁洏浠�) / sv.鏄ㄦ棩鏀剁洏浠� >= tr: return False, "娑ㄥ箙杩囬珮" - - # tr = 1 - # if sv.浠婃棩澶у崟鏁版嵁 and sv.浠婃棩澶у崟鏁版嵁[-1][4] >= sv.鏃ユ渶楂樹环_10 * 1.008 and (sv.浠婃棩澶у崟鏁版嵁[-1][4] - sv.鏄ㄦ棩鏀剁洏浠�) / sv.鏄ㄦ棩鏀剁洏浠� < tr: - # return True, can_buy_blocks, ([(p, sv.鏉垮潡娑ㄥ仠.get(p)) for p in can_buy_blocks], f"澶у崟鏁伴噺锛歿big_order_count}", f"涔板叆浠凤細{sv.浠婃棩澶у崟鏁版嵁[-1][4]}") - # else: buy_money = 0 sell_money = 0 order_ids = set() @@ -77,11 +75,12 @@ # print(target_code, "鍗栧崟澶氫簬涔板崟: ", sv.浠婃棩鍗栧ぇ鍗曟暟鎹�) return False, "鍗栧崟澶氫簬涔板崟" - if (sv.浠婃棩澶у崟鏁版嵁[-1][4] - sv.浠婃棩澶у崟鍧囦环)/sv.鏄ㄦ棩鏀剁洏浠� > 0.03: - return False, "楂樹簬澶у崟鍧囦环3涓偣" + if (sv.浠婃棩澶у崟鏁版嵁[-1][4] - sv.浠婃棩澶у崟鍧囦环) / sv.鏄ㄦ棩鏀剁洏浠� > 0.03: + return False, f"楂樹簬澶у崟鍧囦环({sv.浠婃棩澶у崟鍧囦环})3涓偣" - return True, can_buy_blocks, (f"澶у崟鏁伴噺锛歿big_order_count}", f"涔板叆浠凤細{sv.浠婃棩澶у崟鏁版嵁[-1][4]}锛屾定骞咃細{round((sv.浠婃棩澶у崟鏁版嵁[-1][4] - sv.鏄ㄦ棩鏀剁洏浠�)*100 / sv.鏄ㄦ棩鏀剁洏浠�, 2)}%", - sv.浠婃棩澶у崟鏁版嵁[-1], [(p, sv.鏉垮潡娑ㄥ仠.get(p)) for p in can_buy_blocks]) + return True, can_buy_blocks, ( + f"澶у崟鏁伴噺锛歿big_order_count}", f"涔板叆浠凤細{sv.浠婃棩澶у崟鏁版嵁[-1][4]}锛屾定骞咃細{round((sv.浠婃棩澶у崟鏁版嵁[-1][4] - sv.鏄ㄦ棩鏀剁洏浠�) * 100 / sv.鏄ㄦ棩鏀剁洏浠�, 2)}%", + sv.浠婃棩澶у崟鏁版嵁[-1], [(p, sv.鏉垮潡娑ㄥ仠.get(p)) for p in can_buy_blocks]) compute_result = can_buy() diff --git "a/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246_v2.py" "b/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246_v2.py" new file mode 100644 index 0000000..2eae881 --- /dev/null +++ "b/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246_v2.py" @@ -0,0 +1,96 @@ +from strategy.strategy_variable import StockVariables + +sv = StockVariables() + + +def can_buy(): + """ + @return: 鏄惁鍙拱, 涓嶈兘涔扮殑鍘熷洜/鍙拱鐨勬澘鍧� + """ + # print(f"{target_code}:鎵ц绛栫暐") + if not sv.鏄ㄦ棩闈炶穼鍋� or not sv.鏄ㄦ棩闈炴定鍋� or not sv.鏄ㄦ棩闈炵偢鏉�: + return False, "鏃涓嶆弧瓒虫潯浠�" + # if sv.鍏釜浜ゆ槗鏃ユ定骞呰繃楂�: + # # print(f"{target_code}:鍏釜浜ゆ槗鏃ユ定骞呰繃楂�") + # return False, "鍏釜浜ゆ槗鏃ユ定骞呰繃楂�" + + # if sv.褰撳墠浠� <= sv.鏃ユ渶楂樹环_10: + # return False, "娌$獊鐮�10鏃ユ渶楂樹环" + # 缁熻澶у崟鏁伴噺 + if sv.浠婃棩寮�鐩樹环 and (sv.浠婃棩寮�鐩樹环 - sv.鏄ㄦ棩鏀剁洏浠�) / sv.鏄ㄦ棩鏀剁洏浠� < -0.03: + return False, "寮�鐩樻定骞呭皬浜�-0.03" + + if sv.浠婃棩娑ㄥ仠浠� < sv.鏃ユ渶楂樹环_5: + return False, "浠婃棩娑ㄥ仠浠峰皬浜�5鏃ユ渶楂樹环" + + if sv.娑ㄥ仠鏁癬5 > 3 or sv.璺屽仠鏁癬5 > 3 or sv.鐐告澘鏁癬5 > 3: + return False, "5鏃ユ定鍋滄暟/鐐告澘鏁�/璺屽仠鏁�>3" + if sv.浠婃棩娑ㄥ仠浠� > 60 or sv.浠婃棩娑ㄥ仠浠� < 2.99: + return False, "浠婃棩娑ㄥ仠浠烽珮浜�60/浣庝簬2.99" + + big_order_count = 0 + if sv.浠婃棩澶у崟鏁版嵁: + # 10涓氦鏄撴棩鍐呮湁鐐告澘鎴栨定鍋滃氨鐪�5涓氦鏄撴棩 + # if sv.娑ㄥ仠鏁癬10 > 0 or sv.鐐告澘鏁癬10 > 0: + # big_order_count = len(set([o[0] for o in sv.浠婃棩澶у崟鏁版嵁 if sv.鏃ユ渶楂樹环_5 <= o[4] < sv.鏄ㄦ棩鏀剁洏浠� * 1.06])) + # else: + # big_order_count = len(set([o[0] for o in sv.浠婃棩澶у崟鏁版嵁 if o[4] < sv.鏄ㄦ棩鏀剁洏浠� * 1.06])) + big_order_count = len(set([o[0] for o in sv.浠婃棩澶у崟鏁版嵁 if (sv.鏃ユ渶楂樹环_10 < o[4] < sv.鏄ㄦ棩鏀剁洏浠� * 1.06)])) + if big_order_count < 1: # max(1, int(round(sv.鏄ㄦ棩鎴愪氦棰� * 0.33 / 1e8))): + return False, f"({big_order_count})灏戜簬1涓ぇ鍗�" + if not sv.浠g爜鏉垮潡: + return False, "娌℃湁鏉垮潡" + + can_buy_blocks = set([k for k in sv.浠g爜鏉垮潡 if sv.鏉垮潡娑ㄥ仠 and k in sv.鏉垮潡娑ㄥ仠 and len(sv.鏉垮潡娑ㄥ仠[k]) >= 1]) + if not can_buy_blocks: + return False, "鏉垮潡灏戜簬1涓定鍋�" + # 鏄惁杩樻湁鍙拱鐨勬澘鍧� + can_buy_blocks = sv.浠g爜鏉垮潡 - sv.鏉垮潡鎴愪氦浠g爜.keys() + if not can_buy_blocks: + return False, "鏉垮潡宸叉湁鎴愪氦浠g爜" + tr = 0.06 if target_code.find("30") != 0 else 0.12 + if (sv.浠婃棩澶у崟鏁版嵁[-1][4] - sv.鏄ㄦ棩鏀剁洏浠�) / sv.鏄ㄦ棩鏀剁洏浠� >= tr: + return False, "娑ㄥ箙杩囬珮" + buy_money = 0 + sell_money = 0 + order_ids = set() + if sv.浠婃棩澶у崟鏁版嵁: + for d in reversed(sv.浠婃棩澶у崟鏁版嵁): + if d[0] in order_ids: + continue + order_ids.add(d[0]) + if d[4] >= sv.鏄ㄦ棩鏀剁洏浠� * 1.06: + continue + buy_money += d[2] + if sv.浠婃棩澶у崟鏁版嵁 and str(sv.浠婃棩澶у崟鏁版嵁[-1][3]).find("92") == 0: + return False, "澶у崟鏃堕棿鍦�09:30涔嬪墠" + + if sv.浠婃棩鍗栧ぇ鍗曟暟鎹�: + for d in reversed(sv.浠婃棩鍗栧ぇ鍗曟暟鎹�): + if d[0] in order_ids: + continue + order_ids.add(d[0]) + sell_money += d[2] + + if buy_money - sell_money < 299e4: + # print(target_code, "鍗栧崟澶氫簬涔板崟: ", sv.浠婃棩鍗栧ぇ鍗曟暟鎹�) + return False, "鍗栧崟澶氫簬涔板崟" + + if (sv.浠婃棩澶у崟鏁版嵁[-1][4] - sv.浠婃棩澶у崟鍧囦环) / sv.鏄ㄦ棩鏀剁洏浠� > 0.03: + return False, f"楂樹簬澶у崟鍧囦环({sv.浠婃棩澶у崟鍧囦环})3涓偣" + + # 绠楁姏鍘嬪潎浠� + high_price = sv.鏃ユ渶楂樹环_10 + high_rate = (sv.浠婃棩澶у崟鏁版嵁[-1][4] - high_price) / high_price + if high_rate >= 0.02 or high_rate < -0.1: + pass + else: + return False, f"鎶涘帇娑ㄥ箙({high_rate}/{high_rate})鍦�-10-2涔嬮棿" + print("澶у崟", sv.浠婃棩澶у崟鏁版嵁) + return True, can_buy_blocks, ( + f"澶у崟鏁伴噺锛歿big_order_count}", + f"涔板叆浠凤細{sv.浠婃棩澶у崟鏁版嵁[-1][4]}锛屾定骞咃細{round((sv.浠婃棩澶у崟鏁版嵁[-1][4] - sv.鏄ㄦ棩鏀剁洏浠�) * 100 / sv.鏄ㄦ棩鏀剁洏浠�, 2)}%", + sv.浠婃棩澶у崟鏁版嵁[-1], [(p, sv.鏉垮潡娑ㄥ仠.get(p)) for p in can_buy_blocks]) + + +compute_result = can_buy() diff --git "a/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246_v3.py" "b/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246_v3.py" new file mode 100644 index 0000000..a392d01 --- /dev/null +++ "b/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246_v3.py" @@ -0,0 +1,122 @@ +from strategy.strategy_variable import StockVariables + +sv = StockVariables() + + +def can_buy(): + """ + @return: 鏄惁鍙拱, 涓嶈兘涔扮殑鍘熷洜/鍙拱鐨勬澘鍧� + """ + # print(f"{target_code}:鎵ц绛栫暐") + if not sv.鏄ㄦ棩闈炶穼鍋� or not sv.鏄ㄦ棩闈炴定鍋� or not sv.鏄ㄦ棩闈炵偢鏉�: + return False, "鏃涓嶆弧瓒虫潯浠�" + + if sv.鑷敱娴侀�氬競鍊� > 300e8 or sv.鑷敱娴侀�氬競鍊� < 30e8: + return False, f"鑷敱甯傚�硷紙{sv.鑷敱娴侀�氬競鍊紏锛変笉婊¤冻瑕佹眰" + + # if sv.鍏釜浜ゆ槗鏃ユ定骞呰繃楂�: + # # print(f"{target_code}:鍏釜浜ゆ槗鏃ユ定骞呰繃楂�") + # return False, "鍏釜浜ゆ槗鏃ユ定骞呰繃楂�" + + # if sv.褰撳墠浠� <= sv.鏃ユ渶楂樹环_10: + # return False, "娌$獊鐮�10鏃ユ渶楂樹环" + # 缁熻澶у崟鏁伴噺 + if sv.浠婃棩寮�鐩樹环 and (sv.浠婃棩寮�鐩樹环 - sv.鏄ㄦ棩鏀剁洏浠�) / sv.鏄ㄦ棩鏀剁洏浠� < -0.03: + return False, "寮�鐩樻定骞呭皬浜�-0.03" + + # if sv.浠婃棩娑ㄥ仠浠� < sv.鏃ユ渶楂樹环_5: + # return False, "浠婃棩娑ㄥ仠浠峰皬浜�5鏃ユ渶楂樹环" + + if sv.娑ㄥ仠鏁癬5 > 3 or sv.璺屽仠鏁癬5 > 3 or sv.鐐告澘鏁癬5 > 3: + return False, "5鏃ユ定鍋滄暟/鐐告澘鏁�/璺屽仠鏁�>3" + if sv.浠婃棩娑ㄥ仠浠� > 60 or sv.浠婃棩娑ㄥ仠浠� < 2.99: + return False, "浠婃棩娑ㄥ仠浠烽珮浜�60/浣庝簬2.99" + + if not sv.棰嗘定鏉垮潡淇℃伅: + return False, "娌℃湁鏉垮潡" + + can_buy_blocks = set() + for k in sv.棰嗘定鏉垮潡淇℃伅.keys(): + if sv.寮�鐩樺暒棰嗘定鏉垮潡娑ㄥ仠 and k in sv.寮�鐩樺暒棰嗘定鏉垮潡娑ㄥ仠 and len(sv.寮�鐩樺暒棰嗘定鏉垮潡娑ㄥ仠[k]) >= 1: + can_buy_blocks.add(k) + + can_buy_blocks = can_buy_blocks - sv.鏃ュ嚭鐜扮殑鏉垮潡_5 + # print("鏂伴鏉�", can_buy_blocks) + + if not can_buy_blocks: + return False, "娌℃湁鏂版澘鍧�" + # print("鏂伴鏉�", target_code, can_buy_blocks, [(b, sv.寮�鐩樺暒棰嗘定鏉垮潡娑ㄥ仠.get(b)) for b in can_buy_blocks]) + + big_order_count = 0 + if sv.浠婃棩澶у崟鏁版嵁: + # 10涓氦鏄撴棩鍐呮湁鐐告澘鎴栨定鍋滃氨鐪�5涓氦鏄撴棩 + # if sv.娑ㄥ仠鏁癬10 > 0 or sv.鐐告澘鏁癬10 > 0: + # big_order_count = len(set([o[0] for o in sv.浠婃棩澶у崟鏁版嵁 if sv.鏃ユ渶楂樹环_5 <= o[4] < sv.鏄ㄦ棩鏀剁洏浠� * 1.06])) + # else: + # big_order_count = len(set([o[0] for o in sv.浠婃棩澶у崟鏁版嵁 if o[4] < sv.鏄ㄦ棩鏀剁洏浠� * 1.06])) + big_order_count = len(set([o[0] for o in sv.浠婃棩澶у崟鏁版嵁])) + if big_order_count < 1: # max(1, int(round(sv.鑷敱娴侀�氬競鍊� // 1e9 - 2))): + return False, f"({big_order_count})灏戜簬1涓ぇ鍗�" + + if not can_buy_blocks: + return False, "鏉垮潡灏戜簬1涓定鍋�" + # 鏄惁杩樻湁鍙拱鐨勬澘鍧�,鏉垮潡鍙厑璁镐拱1涓� + # can_buy_blocks = can_buy_blocks - sv.鏉垮潡鎴愪氦浠g爜.keys() + # if not can_buy_blocks: + # return False, "鏉垮潡宸叉湁鎴愪氦浠g爜" + tr = 0.06 if target_code.find("30") != 0 else 0.12 + rate = (sv.浠婃棩澶у崟鏁版嵁[-1][4] - sv.鏄ㄦ棩鏀剁洏浠�) / sv.鏄ㄦ棩鏀剁洏浠� + if rate >= tr: + return False, f"娑ㄥ箙杩囬珮:{rate}" + + tr = 0.1 if target_code.find("30") != 0 else 0.2 + if (sv.浠婃棩澶у崟鏁版嵁[-1][4] - sv.鏄ㄦ棩鏈�浣庝环) / sv.鏄ㄦ棩鏈�浣庝环 >= tr: + return False, "浠锋牸瓒呰繃鏄ㄦ棩鏈�浣庝环鐨�110%" + + buy_money = 0 + sell_money = 0 + order_ids = set() + if sv.浠婃棩澶у崟鏁版嵁: + for d in reversed(sv.浠婃棩澶у崟鏁版嵁): + if d[0] in order_ids: + continue + order_ids.add(d[0]) + if d[4] >= sv.鏄ㄦ棩鏀剁洏浠� * 1.06: + continue + buy_money += d[2] + if sv.浠婃棩澶у崟鏁版嵁 and str(sv.浠婃棩澶у崟鏁版嵁[-1][3]).find("92") == 0: + return False, "澶у崟鏃堕棿鍦�09:30涔嬪墠" + + if sv.浠婃棩鍗栧ぇ鍗曟暟鎹�: + for d in reversed(sv.浠婃棩鍗栧ぇ鍗曟暟鎹�): + if d[0] in order_ids: + continue + order_ids.add(d[0]) + sell_money += d[2] + + if buy_money - sell_money < 299e4: + # print(target_code, "鍗栧崟澶氫簬涔板崟: ", sv.浠婃棩鍗栧ぇ鍗曟暟鎹�) + return False, "鍗栧崟澶氫簬涔板崟" + + # if (sv.浠婃棩澶у崟鏁版嵁[-1][4] - sv.浠婃棩澶у崟鍧囦环) / sv.鏄ㄦ棩鏀剁洏浠� > 0.03: + # return False, f"楂樹簬澶у崟鍧囦环({sv.浠婃棩澶у崟鍧囦环})3涓偣" + + # 绠楁姏鍘嬪潎浠� + # high_price = sv.鏃ユ渶楂樹环_10 + # high_rate = (sv.浠婃棩澶у崟鏁版嵁[-1][4] - high_price) / high_price + # if high_rate < 0.03: + # pass + # else: + # return False, f"鎶涘帇娑ㄥ箙({high_rate}/{high_rate})>0.03" + + if sv.浠婃棩澶у崟鏁版嵁[-1][4] <= max(sv.鏄ㄦ棩鏀剁洏浠�, sv.鏄ㄦ棩寮�鐩樹环): + return False, f"灏氭湭鏄ㄦ棩绐佺牬" + # print(sv.鏉垮潡娑ㄥ仠) + return True, can_buy_blocks, ( + f"澶у崟鏁伴噺锛歿big_order_count}", + f"涔板叆浠凤細{sv.浠婃棩澶у崟鏁版嵁[-1][4]}锛屾定骞咃細{round((sv.浠婃棩澶у崟鏁版嵁[-1][4] - sv.鏄ㄦ棩鏀剁洏浠�) * 100 / sv.鏄ㄦ棩鏀剁洏浠�, 2)}%", + [(p, f"棰嗘定娆℃暟锛歿sv.棰嗘定鏉垮潡淇℃伅.get(p)[1]}/{sv.棰嗘定鏉垮潡淇℃伅.get(p)[2]}", sv.寮�鐩樺暒棰嗘定鏉垮潡娑ㄥ仠.get(p)) for p in can_buy_blocks], + sv.浠婃棩澶у崟鏁版嵁[-1]) + + +compute_result = can_buy() diff --git "a/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246_v4.py" "b/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246_v4.py" new file mode 100644 index 0000000..ae42cba --- /dev/null +++ "b/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246_v4.py" @@ -0,0 +1,101 @@ +from strategy.strategy_variable import StockVariables + +sv = StockVariables() + + +def can_buy(): + """ + @return: 鏄惁鍙拱, 涓嶈兘涔扮殑鍘熷洜/鍙拱鐨勬澘鍧� + """ + # print(f"{target_code}:鎵ц绛栫暐") + if not sv.鏄ㄦ棩闈炶穼鍋� or not sv.鏄ㄦ棩闈炴定鍋� or not sv.鏄ㄦ棩闈炵偢鏉�: + return False, "鏃涓嶆弧瓒虫潯浠�" + # if sv.鍏釜浜ゆ槗鏃ユ定骞呰繃楂�: + # # print(f"{target_code}:鍏釜浜ゆ槗鏃ユ定骞呰繃楂�") + # return False, "鍏釜浜ゆ槗鏃ユ定骞呰繃楂�" + + # if sv.褰撳墠浠� <= sv.鏃ユ渶楂樹环_10: + # return False, "娌$獊鐮�10鏃ユ渶楂樹环" + # 缁熻澶у崟鏁伴噺 + # if sv.浠婃棩寮�鐩樹环 and (sv.浠婃棩寮�鐩樹环 - sv.鏄ㄦ棩鏀剁洏浠�) / sv.鏄ㄦ棩鏀剁洏浠� < -0.03: + # return False, "寮�鐩樻定骞呭皬浜�-0.03" + + # if sv.浠婃棩娑ㄥ仠浠� < sv.鏃ユ渶楂樹环_5: + # return False, "浠婃棩娑ㄥ仠浠峰皬浜�5鏃ユ渶楂樹环" + + if sv.娑ㄥ仠鏁癬5 > 3 or sv.璺屽仠鏁癬5 > 3 or sv.鐐告澘鏁癬5 > 3: + return False, "5鏃ユ定鍋滄暟/鐐告澘鏁�/璺屽仠鏁�>3" + if sv.浠婃棩娑ㄥ仠浠� > 60 or sv.浠婃棩娑ㄥ仠浠� < 2.99: + return False, "浠婃棩娑ㄥ仠浠烽珮浜�60/浣庝簬2.99" + + big_order_count = 0 + if sv.浠婃棩澶у崟鏁版嵁: + # 10涓氦鏄撴棩鍐呮湁鐐告澘鎴栨定鍋滃氨鐪�5涓氦鏄撴棩 + # if sv.娑ㄥ仠鏁癬10 > 0 or sv.鐐告澘鏁癬10 > 0: + # big_order_count = len(set([o[0] for o in sv.浠婃棩澶у崟鏁版嵁 if sv.鏃ユ渶楂樹环_5 <= o[4] < sv.鏄ㄦ棩鏀剁洏浠� * 1.06])) + # else: + # big_order_count = len(set([o[0] for o in sv.浠婃棩澶у崟鏁版嵁 if o[4] < sv.鏄ㄦ棩鏀剁洏浠� * 1.06])) + big_order_count = len(set([o[0] for o in sv.浠婃棩澶у崟鏁版嵁])) + if big_order_count < 1: # max(1, int(round(sv.鏄ㄦ棩鎴愪氦棰� * 0.33 / 1e8))): + return False, f"({big_order_count})灏戜簬1涓ぇ鍗�" + if not sv.鏂颁唬鐮佹澘鍧�: + return False, "娌℃湁鏉垮潡" + can_buy_blocks = set() + for k in sv.鏂颁唬鐮佹澘鍧�: + if sv.鏉垮潡娑ㄥ仠 and len(sv.鏉垮潡娑ㄥ仠.get(k, [])) >= 1: + can_buy_blocks.add(k) + if not can_buy_blocks: + return False, "鏉垮潡灏戜簬1涓定鍋�" + # 鍒ゆ柇鏄惁鏄柊鏉垮潡 + can_buy_blocks = can_buy_blocks - sv.鏃ュ嚭鐜扮殑鏉垮潡_5 + if not can_buy_blocks: + return False, "娌℃湁鏂版澘鍧�" + # 鏄惁杩樻湁鍙拱鐨勬澘鍧� + # can_buy_blocks = sv.鏂颁唬鐮佹澘鍧� - sv.鏉垮潡鎴愪氦浠g爜.keys() + # if not can_buy_blocks: + # return False, "鏉垮潡宸叉湁鎴愪氦浠g爜" + tr = 0.06 if target_code.find("30") != 0 else 0.12 + if (sv.浠婃棩澶у崟鏁版嵁[-1][4] - sv.鏄ㄦ棩鏀剁洏浠�) / sv.鏄ㄦ棩鏀剁洏浠� >= tr: + return False, "娑ㄥ箙杩囬珮" + buy_money = 0 + sell_money = 0 + order_ids = set() + if sv.浠婃棩澶у崟鏁版嵁: + for d in reversed(sv.浠婃棩澶у崟鏁版嵁): + if d[0] in order_ids: + continue + order_ids.add(d[0]) + if d[4] >= sv.鏄ㄦ棩鏀剁洏浠� * 1.06: + continue + buy_money += d[2] + if sv.浠婃棩澶у崟鏁版嵁 and str(sv.浠婃棩澶у崟鏁版嵁[-1][3]).find("92") == 0: + return False, "澶у崟鏃堕棿鍦�09:30涔嬪墠" + + if sv.浠婃棩鍗栧ぇ鍗曟暟鎹�: + for d in reversed(sv.浠婃棩鍗栧ぇ鍗曟暟鎹�): + if d[0] in order_ids: + continue + order_ids.add(d[0]) + sell_money += d[2] + + if buy_money - sell_money < 299e4: + # print(target_code, "鍗栧崟澶氫簬涔板崟: ", sv.浠婃棩鍗栧ぇ鍗曟暟鎹�) + return False, "鍗栧崟澶氫簬涔板崟" + + if (sv.浠婃棩澶у崟鏁版嵁[-1][4] - sv.浠婃棩澶у崟鍧囦环) / sv.鏄ㄦ棩鏀剁洏浠� > 0.03: + return False, f"楂樹簬澶у崟鍧囦环({sv.浠婃棩澶у崟鍧囦环})3涓偣" + + # 绠楁姏鍘嬪潎浠� + # high_price = sv.鏃ユ渶楂樹环_10 + # high_rate = (sv.浠婃棩澶у崟鏁版嵁[-1][4] - high_price) / high_price + # if high_rate < 0.03: + # pass + # else: + # return False, f"鎶涘帇娑ㄥ箙({high_rate}/{high_rate})>0.03" + return True, can_buy_blocks, ( + f"澶у崟鏁伴噺锛歿big_order_count}", + f"涔板叆浠凤細{sv.浠婃棩澶у崟鏁版嵁[-1][4]}锛屾定骞咃細{round((sv.浠婃棩澶у崟鏁版嵁[-1][4] - sv.鏄ㄦ棩鏀剁洏浠�) * 100 / sv.鏄ㄦ棩鏀剁洏浠�, 2)}%", + sv.浠婃棩澶у崟鏁版嵁[-1], f"鏉垮潡锛歿can_buy_blocks}", [(p, sv.鏉垮潡娑ㄥ仠.get(p)) for p in can_buy_blocks]) + + +compute_result = can_buy() diff --git "a/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246_v5.py" "b/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246_v5.py" new file mode 100644 index 0000000..35d7415 --- /dev/null +++ "b/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246_v5.py" @@ -0,0 +1,83 @@ +from strategy.strategy_variable import StockVariables + +sv = StockVariables() + + +def can_buy(): + """ + @return: 鏄惁鍙拱, 涓嶈兘涔扮殑鍘熷洜/鍙拱鐨勬澘鍧� + """ + # print(f"{target_code}:鎵ц绛栫暐") + if target_code.find("60") != 0 and target_code.find("00") != 0: + return False, "鍒涗笟鏉�/绉戝垱鏉跨殑绁ㄤ笉涔�" + if not sv.鏄ㄦ棩闈炶穼鍋� or not sv.鏄ㄦ棩闈炴定鍋� or not sv.鏄ㄦ棩闈炵偢鏉�: + return False, "鏃涓嶆弧瓒虫潯浠�" + if not sv.棰嗘定鏉垮潡淇℃伅: + return False, "娌℃湁鏉垮潡" + if sv.鑷敱娴侀�氬競鍊� > 300e8 or sv.鑷敱娴侀�氬競鍊� < 10e8: + return False, f"鑷敱甯傚�硷紙{sv.鑷敱娴侀�氬競鍊紏锛変笉婊¤冻瑕佹眰" + + if sv.浠婃棩娑ㄥ仠浠� > 60 or sv.浠婃棩娑ㄥ仠浠� < 2.99: + return False, "浠婃棩娑ㄥ仠浠烽珮浜�60/浣庝簬2.99" + + if sv.娑ㄥ仠鏁癬30 <= 0 and not sv.鏃ユ斁鍊嶉噺鏃ユ湡_15: + return False, "30涓氦鏄撴棩鏃犳定鍋滀笖15涓氦鏄撴棩鏃犲�嶉噺" + + if sv.浠婃棩娑ㄥ仠浠� < sv.鏃ユ渶楂樹环_5: + return False, "浠婃棩娑ㄥ仠浠烽渶澶т簬5鏃ユ渶楂樹环" + + if sv.娑ㄥ仠鏁癬5 > 3 or sv.璺屽仠鏁癬5 > 3 or sv.鐐告澘鏁癬5 > 3: + return False, "5鏃ユ定鍋滄暟/鐐告澘鏁�/璺屽仠鏁�>3" + + if sv.浠婃棩寮�鐩樹环 and (sv.浠婃棩寮�鐩樹环 - sv.鏄ㄦ棩鏀剁洏浠�) / sv.鏄ㄦ棩鏀剁洏浠� < -0.03: + return False, "寮�鐩樻定骞呭皬浜�-0.03" + + tr = 0.07 + rate = (sv.褰撳墠浠� - sv.鏄ㄦ棩鏀剁洏浠�) / sv.鏄ㄦ棩鏀剁洏浠� + if rate >= tr: + return False, f"娑ㄥ箙杩囬珮:{rate}" + elif rate > 0.03 and sv.浠婃棩鎴愪氦閲� < sv.鏃ユ渶楂橀噺_10[0] * 0.9: + return False, f"娑ㄥ箙杈冮珮:{rate}锛岄噺涓嶈冻" + if rate < 0: + return False, f"姘翠笅涓嶄拱" + + # 浣庝簬鏈�楂樹环鐨�4%灏变笉涔� + if (sv.浠婃棩鏈�楂樹环 - sv.褰撳墠浠�) / sv.鏄ㄦ棩鏀剁洏浠� > 0.04: + return False, f"浣庝簬鍒嗘椂楂樹环4涓偣" + + if (sv.褰撳墠浠� - round(sv.浠婃棩鎴愪氦棰� / sv.浠婃棩鎴愪氦閲�, 2)) / sv.鏄ㄦ棩鏀剁洏浠� >= 0.02: + return False, f"涔板叆浠烽珮浜庡潎浠�2涓偣" + + # TODO 鑰侀鏉愪拱鍏� + if sv.浠婃棩鎴愪氦閲� < sv.鏄ㄦ棩鎴愪氦閲� * 0.8: + return False, f"瀹炴椂鎴愪氦閲忓繀椤烩墺90%鏄ㄦ棩鎬绘垚浜ら噺" + + if sv.鏄ㄦ棩鎴愪氦閲� <= 0: + return False, f"鏄ㄦ棩閲忔槸0" + + if sv.褰撳墠浠� > sv.鏄ㄦ棩鏈�浣庝环 * 1.1: + return False, f"涔板叆鏃剁殑浠锋牸蹇呴』鈮ゆ槰鏃ユ渶浣庝环*110%" + + if abs(sv.浠婃棩鏈�楂樹环 - sv.浠婃棩娑ㄥ仠浠�) <= 0.001: + return False, f"浠婃棩鏈夋定鍋�" + + can_buy_blocks = set() + for k in sv.棰嗘定鏉垮潡淇℃伅.keys(): + if sv.寮�鐩樺暒棰嗘定鏉垮潡娑ㄥ仠 and k in sv.寮�鐩樺暒棰嗘定鏉垮潡娑ㄥ仠 and len(sv.寮�鐩樺暒棰嗘定鏉垮潡娑ㄥ仠[k]) >= 1: + can_buy_blocks.add(k) + # new_blocks = sv.寮�鐩樺暒棰嗘定鏉垮潡娑ㄥ仠.keys() - sv.鏃ュ嚭鐜扮殑鏉垮潡_5 + # print("鏂伴鏉愭澘鍧楋細", [(b, sv.寮�鐩樺暒棰嗘定鏉垮潡娑ㄥ仠[b]) for b in new_blocks]) + + can_buy_blocks = can_buy_blocks - sv.鏃ュ嚭鐜扮殑鏉垮潡_5 + # print("鏂伴鏉�", can_buy_blocks) + + if not can_buy_blocks: + return False, "娌℃湁鏂版澘鍧�" + # print("鏂伴鏉�", target_code, can_buy_blocks, [(b, sv.寮�鐩樺暒棰嗘定鏉垮潡娑ㄥ仠.get(b)) for b in can_buy_blocks]) + + return True, can_buy_blocks, ( + f"涔板叆浠凤細{sv.褰撳墠浠穧锛屾定骞咃細{round((sv.褰撳墠浠� - sv.鏄ㄦ棩鏀剁洏浠�) * 100 / sv.鏄ㄦ棩鏀剁洏浠�, 2)}% 閲忥細{sv.浠婃棩鎴愪氦閲弣/{sv.鏄ㄦ棩鎴愪氦閲弣, 鍒嗘椂鏈�楂樹环锛歿sv.浠婃棩鏈�楂樹环}, 鑷敱娴侀�氾細{round(sv.鑷敱娴侀�氬競鍊� / 1e8, 2)}浜�", + [(p, f"棰嗘定娆℃暟锛歿sv.棰嗘定鏉垮潡淇℃伅.get(p)[1]}/{sv.棰嗘定鏉垮潡淇℃伅.get(p)[2]}", sv.寮�鐩樺暒棰嗘定鏉垮潡娑ㄥ仠.get(p)) for p in can_buy_blocks]) + + +compute_result = can_buy() diff --git "a/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246_v6.py" "b/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246_v6.py" new file mode 100644 index 0000000..e05a88f --- /dev/null +++ "b/strategy/\344\275\216\345\220\270\350\204\232\346\234\254_\350\276\250\350\257\206\345\272\246_v6.py" @@ -0,0 +1,157 @@ +import logging + +from strategy.strategy_params_settings import StrategyParamsSettings +from strategy.strategy_variable import StockVariables + +sv = StockVariables() +settings = StrategyParamsSettings() +target_code = '' + + +def format_time(huaxin_timestamp): + huaxin_timestamp = str(huaxin_timestamp) + if huaxin_timestamp.find("9") == 0: + return f"0{huaxin_timestamp[0]}:{huaxin_timestamp[1: 3]}:{huaxin_timestamp[3: 5]}" + return f"{huaxin_timestamp[0:2]}:{huaxin_timestamp[2: 4]}:{huaxin_timestamp[4: 6]}" + + +def can_buy(): + """ + @return: 鏄惁鍙拱, 涓嶈兘涔扮殑鍘熷洜/鍙拱鐨勬澘鍧�, 鏄惁閲忓 + """ + # print(f"{target_code}:鎵ц绛栫暐") + if not settings.can_buy_ge_code: + if target_code.find("60") != 0 and target_code.find("00") != 0: + return False, "鍒涗笟鏉�/绉戝垱鏉跨殑绁ㄤ笉涔�" + else: + if target_code.find("60") != 0 and target_code.find("00") != 0 and target_code.find("30") != 0: + return False, "绉戝垱鏉跨殑绁ㄤ笉涔�" + + # 鐩爣绁ㄦ澘鍧楁定鍋滀釜鏁�>=2 + can_buy_plates = set() + for plate in sv.浠g爜鏉垮潡: + if not sv.璧勯噾娴佸叆鏉垮潡 or plate not in sv.璧勯噾娴佸叆鏉垮潡: + continue + if plate in sv.杩炵画鑰侀鏉�: + continue + if plate in sv.鏃ュ嚭鐜扮殑鏉垮潡_2: + # 鑰侀鏉� + threshold_count = settings.limit_up_count_of_old_plate + else: + # 鏂伴鏉� + threshold_count = settings.limit_up_count_of_new_plate + if len(sv.寮�鐩樺暒鏈�姝f澘鍧楁定鍋�.get(plate, [])) >= threshold_count: + can_buy_plates.add(plate) + + if not sv.褰撳墠浠�: + return False, "鏃犲綋鍓嶄环" + + # if getattr(sv, f"娑ㄥ仠鏁癬{settings.has_limit_up_days}") < 1 and getattr(sv, f"鐐告澘鏁癬{settings.has_limit_up_days}") < 1: + # return False, f"杩憑settings.has_limit_up_days}涓氦鏄撴棩鏃犳定鍋�/鏃犵偢鏉�" + + if settings.cant_yesterday_limit_down and not sv.鏄ㄦ棩闈炶穼鍋�: + return False, "鏄ㄦ棩璺屽仠" + if settings.cant_yesterday_limit_up and not sv.鏄ㄦ棩闈炴定鍋�: + return False, "鏄ㄦ棩娑ㄥ仠" + if settings.cant_yesterday_open_limit_up and not sv.鏄ㄦ棩闈炵偢鏉�: + return False, "鏄ㄦ棩鐐告澘" + + if sv.浠婃棩娑ㄥ仠浠� > settings.price_range[1] or sv.浠婃棩娑ㄥ仠浠� < settings.price_range[0]: + return False, f"浠婃棩娑ㄥ仠浠烽珮浜巤settings.price_range[1]}/浣庝簬{settings.price_range[0]}" + + if getattr(sv, f"娑ㄥ仠鏁癬{settings.trade_days_count_of_limit_up}") >= settings.count_of_limit_up: + return False, f"{settings.trade_days_count_of_limit_up}鏃ユ定鍋滄暟>{settings.count_of_limit_up}" + + if getattr(sv, f"璺屽仠鏁癬{settings.trade_days_count_of_limit_down}") >= settings.count_of_limit_down: + return False, f"{settings.trade_days_count_of_limit_down}鏃ヨ穼鍋滄暟>{settings.count_of_limit_down}" + + if getattr(sv, f"鐐告澘鏁癬{settings.trade_days_count_of_open_limit_up}") >= settings.count_of_open_limit_up: + return False, f"{settings.trade_days_count_of_open_limit_up}鏃ョ偢鏉挎暟>{settings.count_of_open_limit_up}" + + if sv.娑ㄥ仠鏁癬10 + sv.鐐告澘鏁癬10 >= 4: + return False, f"10澶╁唴>=4涓定鍋�/鐐告澘" + + if sv.浠婃棩寮�鐩樹环 and (sv.浠婃棩寮�鐩樹环 - sv.鏄ㄦ棩鏀剁洏浠�) / sv.鏄ㄦ棩鏀剁洏浠� < settings.min_open_rate: + return False, f"寮�鐩樻定骞呭皬浜巤settings.min_open_rate}" + + rate = (sv.褰撳墠浠� - sv.鏄ㄦ棩鏀剁洏浠�) / sv.鏄ㄦ棩鏀剁洏浠� + if rate >= settings.avaiable_rates[1] or rate < settings.avaiable_rates[0]: + return False, f"娑ㄥ箙涓嶅湪鍖洪棿鍐咃紙{settings.avaiable_rates[0]}-{settings.avaiable_rates[1]}锛�:{rate}" + + if sv.鑷敱娴侀�氬競鍊� > settings.zyltgb_range[1] or sv.鑷敱娴侀�氬競鍊� < settings.zyltgb_range[0]: + return False, f"鑷敱甯傚�硷紙{sv.鑷敱娴侀�氬競鍊紏锛変笉婊¤冻瑕佹眰" + + if sv.鍏釜浜ゆ槗鏃ユ定骞呰繃楂�: + return False, f"6涓氦鏄撴棩娑ㄥ箙杩囬珮" + + # if sv.褰撳墠浠� > sv.鏄ㄦ棩鏈�浣庝环 * 1.1: + # return False, f"涔板叆鏃剁殑浠锋牸蹇呴』鈮ゆ槰鏃ユ渶浣庝环*110%" + + # if (sv.褰撳墠浠� - sv.浠婃棩鏈�浣庝环) / sv.鏄ㄦ棩鏀剁洏浠� > 0.03: + # return False, f"涔板叆鏃剁殑浠锋牸涓嶈兘楂樹簬浠婃棩鏈�浣庝环鐨�3%" + + if abs((sv.褰撳墠浠� - round(sv.浠婃棩鎴愪氦棰� / sv.浠婃棩鎴愪氦閲�, 2)) / sv.鏄ㄦ棩鏀剁洏浠�) >= settings.max_rate_than_average_price: + return False, f"涔板叆浠烽珮浜庡潎浠穥settings.max_rate_than_average_price}({abs((sv.褰撳墠浠� - round(sv.浠婃棩鎴愪氦棰� / sv.浠婃棩鎴愪氦閲�, 2)) / sv.鏄ㄦ棩鏀剁洏浠�)})" + + if (sv.浠婃棩鏈�楂樹环淇℃伅[0] - sv.褰撳墠浠�) / sv.鏄ㄦ棩鏀剁洏浠� > settings.min_rate_of_highest_and_price: + return False, f"浣庝簬鍒嗘椂楂樹环{settings.min_rate_of_highest_and_price}" + + if not settings.can_buy_limited_up and abs(sv.浠婃棩鏈�楂樹环淇℃伅[0] - sv.浠婃棩娑ㄥ仠浠�) <= 0.001: + return False, f"浠婃棩鏈夋定鍋�" + + # if sv.娑ㄥ仠鏁癬30 <= 0 and not sv.鏃ユ斁鍊嶉噺鏃ユ湡_15: + # return False, "30涓氦鏄撴棩鏃犳定鍋滀笖15涓氦鏄撴棩鏃犲�嶉噺" + + # 鐩爣绁ㄦ澘鍧楁定鍋滀釜鏁�>=2 + + if sv.鏉垮潡鎴愪氦浠g爜: + can_buy_plates -= set(sv.鏉垮潡鎴愪氦浠g爜.keys()) + + if not can_buy_plates: + return False, "娌℃湁娑ㄥ仠鐨勬澘鍧�" + # new_plates = set(can_buy_plates) - sv.鏃ュ嚭鐜扮殑鏉垮潡_2 + # if new_plates: + # # 鏈夋柊棰樻潗锛屽垽鏂槸鍚﹁繃鏄ㄦ棩鍓嶉珮 + # if sv.浠婃棩鏈�楂樹环淇℃伅[0] - sv.鏄ㄦ棩鏈�楂樹环 < 0.02: + # return False, "浠婃棩鏈�楂樹环闇�澶т簬鏄ㄦ棩鏈�楂樹环" + # else: + # if sv.浠婃棩鏈�楂樹环淇℃伅[0] - sv.鏃ユ渶楂樹环_5 < 0.02: + # return False, "浠婃棩鏈�楂樹环闇�澶т簬5鏃ユ渶楂樹环" + + if settings.trade_days_count_of_limit_up_price_over_high and sv.浠婃棩娑ㄥ仠浠� <= getattr(sv, + f"鏃ユ渶楂樹环_{settings.trade_days_count_of_limit_up_price_over_high}"): + return False, f"浠婃棩娑ㄥ仠浠疯绐佺牬{settings.trade_days_count_of_limit_up_price_over_high}鏃ユ渶楂樹环" + + # if sv.浠婃棩鎴愪氦閲� < sv.鏄ㄦ棩鎴愪氦閲� * 0.8: + # return False, f"瀹炴椂鎴愪氦閲忓繀椤烩墺80%鏄ㄦ棩鎬绘垚浜ら噺" + + # =======鎴愪氦澶у崟===== + big_order_money = 0 + if sv.浠婃棩澶у崟鏁版嵁: + # print(sv.浠婃棩澶у崟鏁版嵁[-1][3], format_time(sv.浠婃棩澶у崟鏁版嵁[-1][3])) + # filter_orders = [(o[0], o[2]) for o in sv.浠婃棩澶у崟鏁版嵁 if format_time(o[3]) >= sv.浠婃棩閲忓淇℃伅[0]] + filter_orders = [(o[0], o[2]) for o in sv.浠婃棩澶у崟鏁版嵁] + filter_orders.reverse() + orderids = set() + for o in filter_orders: + if o[0] in orderids: + continue + orderids.add(o[0]) + big_order_money += o[1] + threshold_money = max(sv.鑷敱娴侀�氬競鍊� // 1000, 200e4) + + limit_up_codes_count = max([(p, len(sv.寮�鐩樺暒鏈�姝f澘鍧楁定鍋�.get(p, []))) for p in can_buy_plates], key=lambda x: x[1])[1] + + threshold_money *= max(10 - limit_up_codes_count + 1, 5)/10 + + # print(target_code, sv.鑷敱娴侀�氬競鍊�, threshold_money, limit_up_codes_count) + + + # threshold_money = 200e4 # int(sv.鏄ㄦ棩鎴愪氦閲� * 0.2 * sv.浠婃棩娑ㄥ仠浠� * 0.05) + if big_order_money < threshold_money: + return False, f"({big_order_money}/{threshold_money})澶у崟閲戦涓嶈冻" + + return True, f" \n\t澶у崟淇℃伅锛歿big_order_money}/{threshold_money}\n\t閲忓淇℃伅锛歿sv.浠婃棩閲忓淇℃伅}\n\t浠婃棩鏈�楂樹环:{sv.浠婃棩鏈�楂樹环淇℃伅} \n\t5鏃ユ渶楂樹环锛歿sv.鏃ユ渶楂樹环_5}", f"\n\t鏉垮潡淇℃伅锛歿[(p, sv.寮�鐩樺暒鏈�姝f澘鍧楁定鍋�.get(p)) for p in can_buy_plates]}", can_buy_plates + + +compute_result = can_buy() diff --git a/third_data/code_plate_key_manager.py b/third_data/code_plate_key_manager.py deleted file mode 100644 index b441402..0000000 --- a/third_data/code_plate_key_manager.py +++ /dev/null @@ -1,867 +0,0 @@ -""" -浠g爜琛屼笟鍏抽敭璇嶇鐞� -""" - -# 娑ㄥ仠浠g爜鍏抽敭璇嶆澘鍧楃鐞� -import copy -import json -import time - -import constant -from code_attribute import gpcode_manager -from db.redis_manager_delegate import RedisUtils -from third_data import kpl_api, kpl_util -from third_data.history_k_data_manager import HistoryKDataManager -from third_data.history_k_data_util import HistoryKDatasUtils -from third_data.kpl_data_constant import ContainsLimitupCodesBlocksManager -from third_data.third_blocks_manager import BlockMapManager -from utils import tool -from log_module import async_log_util -from db import redis_manager_delegate as redis_manager, mysql_data_delegate as mysql_data - -from log_module.log import logger_kpl_block_can_buy, logger_kpl_jx_out, logger_kpl_jx_in, logger_debug, \ - logger_kpl_latest_gaobiao -from third_data.kpl_util import KPLPlatManager - -# 浠g爜绮鹃�夋澘鍧楃鐞� -from utils.kpl_data_db_util import KPLLimitUpDataUtil - - -class KPLCodeJXBlockManager: - __db = 3 - __redisManager = redis_manager.RedisManager(3) - __code_blocks = {} - # 澶囩敤 - __code_by_blocks = {} - # 婵�杩涗拱鐨勪唬鐮佹澘鍧� - __code_blocks_for_radical_buy = {} - - __instance = None - - def __new__(cls, *args, **kwargs): - if not cls.__instance: - cls.__instance = super(KPLCodeJXBlockManager, cls).__new__(cls, *args, **kwargs) - try: - cls.__load_data() - except Exception as e: - logger_debug.exception(e) - return cls.__instance - - @classmethod - def __load_data(cls): - keys = RedisUtils.keys(cls.__get_redis(), "kpl_jx_blocks_by-*") - if keys: - for k in keys: - val = RedisUtils.get(cls.__get_redis(), k) - val = json.loads(val) - cls.__code_by_blocks[k.split("-")[1]] = (val, time.time()) - keys = RedisUtils.keys(cls.__get_redis(), "kpl_jx_blocks-*") - if keys: - for k in keys: - val = RedisUtils.get(cls.__get_redis(), k) - val = json.loads(val) - cls.__code_blocks[k.split("-")[1]] = (val, time.time()) - keys = RedisUtils.keys(cls.__get_redis(), "kpl_jx_blocks_radical-*") - if keys: - for k in keys: - val = RedisUtils.get(cls.__get_redis(), k) - val = json.loads(val) - cls.__code_blocks_for_radical_buy[k.split("-")[1]] = (val, time.time()) - - @classmethod - def __get_redis(cls): - return cls.__redisManager.getRedis() - - def save_jx_blocks(self, code, blocks: list, current_limit_up_blocks: set, by=False): - if not blocks: - return - final_blocks = copy.deepcopy(blocks) - if len(blocks) > 2: - final_blocks.clear() - for b in blocks: - if b not in constant.KPL_INVALID_BLOCKS: - final_blocks.append(b) - if len(final_blocks) < 2: - final_blocks = blocks - # 淇濆瓨鍓�2鏉℃暟鎹� - if by: - RedisUtils.setex_async(self.__db, f"kpl_jx_blocks_by-{code}", tool.get_expire(), json.dumps(final_blocks)) - self.__code_by_blocks[code] = (final_blocks, time.time()) - else: - RedisUtils.setex_async(self.__db, f"kpl_jx_blocks-{code}", tool.get_expire(), json.dumps(final_blocks)) - self.__code_blocks[code] = (final_blocks, time.time()) - - def save_jx_blocks_for_radical_buy(self, code, blocks: list): - if not blocks: - return - RedisUtils.setex_async(self.__db, f"kpl_jx_blocks_radical-{code}", tool.get_expire(), json.dumps(blocks)) - self.__code_blocks_for_radical_buy[code] = (blocks, time.time()) - - # 鑾峰彇绮鹃�夋澘鍧楋紙婵�杩涗拱锛� - def get_jx_blocks_radical(self, code): - blocks_info = self.__code_blocks_for_radical_buy.get(code) - if blocks_info: - return set(blocks_info[0]) - return None - - def get_jx_blocks_cache(self, code, by=False): - if by: - return self.__code_by_blocks.get(code) - else: - return self.__code_blocks.get(code) - - # 浠庣綉缁滀笂鍔犺浇绮鹃�夋澘鍧�, 褰撳墠娑ㄥ仠鐨勬澘鍧� - def load_jx_blocks(self, code, buy_1_price, limit_up_price, current_limit_up_blocks): - try: - # logger_kpl_block_can_buy.info(f"鍑嗗鏇存柊绮鹃�夋澘鍧楋細{code}-{buy_1_price}-{limit_up_price}") - if limit_up_price and buy_1_price: - # 澶勭悊涔�1,鍗�1淇℃伅 - pre_close_price = round(float(limit_up_price) / tool.get_limit_up_rate(code), 2) - # 濡傛灉娑ㄥ箙澶т簬7%灏辫鍙栨澘鍧� - price_rate = (buy_1_price - pre_close_price) / pre_close_price - if price_rate > 0.07: - jx_blocks_info = self.get_jx_blocks_cache(code) - if not jx_blocks_info: - start_time = time.time() - blocks = kpl_api.getCodeBlocks(code) - async_log_util.info(logger_kpl_block_can_buy, - f"{code}:鑾峰彇鍒扮簿閫夋澘鍧�-{blocks} 鑰楁椂:{int(time.time() - start_time)}s") - self.save_jx_blocks(code, blocks, current_limit_up_blocks) - # 璺熼殢绮鹃�夋澘鍧椾竴璧锋洿鏂� - self.load_jx_blocks_radical(code) - else: - # 杩樻病娑ㄥ仠鐨勯渶瑕佹洿鏂扮簿閫夋澘鍧� 鏇存柊绮鹃�夋澘鍧� - if abs(float(buy_1_price) - float(limit_up_price)) >= 0.001: - # 闈炴定鍋滅姸鎬� - UPDATE_TIME_SPACE = 5 * 60 - time_diff = tool.trade_time_sub(tool.get_now_time_str(), "09:30:00") - if time_diff < 0: - UPDATE_TIME_SPACE = 60 * 60 - else: - UPDATE_TIME_SPACE = int(time_diff / 30) + 60 - if UPDATE_TIME_SPACE > 5 * 60: - UPDATE_TIME_SPACE = 5 * 60 - - if time.time() - jx_blocks_info[1] > UPDATE_TIME_SPACE: - start_time = time.time() - # 璺濈涓婃鏇存柊鏃堕棿杩囧幓浜�5鍒嗛挓 - blocks = kpl_api.getCodeBlocks(code) - async_log_util.info(logger_kpl_block_can_buy, - f"{code}:鑾峰彇鍒扮簿閫夋澘鍧楋紙鏇存柊锛�-{blocks} 鑰楁椂:{int(time.time() - start_time)}s") - self.save_jx_blocks(code, blocks, current_limit_up_blocks) - # 璺熼殢绮鹃�夋澘鍧椾竴璧锋洿鏂� - self.load_jx_blocks_radical(code) - elif price_rate > 0.03: - # 娣诲姞澶囩敤鏉垮潡 - if not self.get_jx_blocks_cache(code, by=True): - start_time = time.time() - blocks = kpl_api.getCodeBlocks(code) - self.save_jx_blocks(code, blocks, current_limit_up_blocks, by=True) - async_log_util.info(logger_kpl_block_can_buy, - f"{code}:鑾峰彇鍒扮簿閫夋澘鍧�(澶囩敤)-{blocks} 鑰楁椂:{int(time.time() - start_time)}s") - # 璺熼殢绮鹃�夋澘鍧椾竴璧锋洿鏂� - self.load_jx_blocks_radical(code) - - if price_rate > 0.03: - if not self.__code_blocks_for_radical_buy.get(code): - self.load_jx_blocks_radical(code) - except Exception as e: - logger_kpl_block_can_buy.error(f"{code} 鑾峰彇鏉垮潡鍑洪敊") - logger_kpl_block_can_buy.exception(e) - - def load_jx_blocks_radical(self, code): - start_time = time.time() - blocks = kpl_api.getCodeJingXuanBlocks(code, jx=False) - blocks = set([b[1] for b in blocks]) - # fblocks = BlockMapManager().filter_blocks(blocks) - async_log_util.info(logger_kpl_block_can_buy, - f"{code}:鑾峰彇鍒版澘鍧�(婵�杩涗拱) 杩囨护鍓�-{blocks} 鑰楁椂:{int(time.time() - start_time)}s") - self.save_jx_blocks_for_radical_buy(code, list(blocks)) - - -# 绂佹涓嬪崟鐨勬澘鍧� -class ForbiddenBlockManager: - __db = 3 - __redisManager = redis_manager.RedisManager(3) - __instance = None - __forbidden_blocks = set() - - def __new__(cls, *args, **kwargs): - if not cls.__instance: - cls.__instance = super(ForbiddenBlockManager, cls).__new__(cls, *args, **kwargs) - cls.__load_data() - return cls.__instance - - @classmethod - def __get_redis(cls): - return cls.__redisManager.getRedis() - - # 鍔犺浇鏁版嵁 - @classmethod - def __load_data(cls): - blocks = cls.__get_redis().smembers("forbidden_blocks") - if blocks: - for b in blocks: - cls.__forbidden_blocks.add(b) - - def add(self, block): - self.__forbidden_blocks.add(block) - RedisUtils.sadd_async(self.__db, "forbidden_blocks", block) - RedisUtils.expire_async(self.__db, "forbidden_blocks", tool.get_expire()) - - def remove(self, block): - if block in self.__forbidden_blocks: - self.__forbidden_blocks.remove(block) - RedisUtils.srem_async(self.__db, "forbidden_blocks", block) - - def get_blocks(self): - return copy.deepcopy(self.__forbidden_blocks) - - def is_in(self, block): - return block in self.__forbidden_blocks - - -# 寮�鐩樺暒绂佹浜ゆ槗鏉垮潡绠$悊 -class KPLPlateForbiddenManager: - """ - 涓嶈兘涔扮殑鏉垮潡绠$悊 - """ - __redis_manager = redis_manager.RedisManager(3) - __kpl_forbidden_plates_cache = set() - # 宸茬粡鍒犻櫎浜嗙殑鏉垮潡 - __deleted_kpl_forbidden_plates_cache = set() - - # 鐩戞帶鐨勯珮鏍囨澘鍧椾唬鐮佸瓧鍏革細{"鏉垮潡":{"浠g爜1","浠g爜2"}} - __watch_block_high_codes = {} - # 楂樻爣浠g爜 - __watch_high_codes = set() - - __instance = None - - def __new__(cls, *args, **kwargs): - if not cls.__instance: - cls.__instance = super(KPLPlateForbiddenManager, cls).__new__(cls, *args, **kwargs) - cls.__load_datas() - return cls.__instance - - @classmethod - def __load_datas(cls): - __redis = cls.__get_redis() - try: - cls.__kpl_forbidden_plates_cache = RedisUtils.smembers(__redis, "kpl_forbidden_plates") - cls.__deleted_kpl_forbidden_plates_cache = RedisUtils.smembers(__redis, "deleted_kpl_forbidden_plates") - finally: - RedisUtils.realse(__redis) - cls.__load_latest_gb() - - @classmethod - def __get_redis(cls): - return cls.__redis_manager.getRedis() - - def save_plate(self, plate): - self.__kpl_forbidden_plates_cache.add(plate) - RedisUtils.sadd(self.__get_redis(), "kpl_forbidden_plates", plate) - RedisUtils.expire(self.__get_redis(), "kpl_forbidden_plates", tool.get_expire()) - - self.__deleted_kpl_forbidden_plates_cache.discard(plate) - RedisUtils.srem(self.__get_redis(), "deleted_kpl_forbidden_plates", plate) - RedisUtils.expire(self.__get_redis(), "deleted_kpl_forbidden_plates", tool.get_expire()) - - def delete_plate(self, plate): - self.__kpl_forbidden_plates_cache.discard(plate) - RedisUtils.srem(self.__get_redis(), "kpl_forbidden_plates", plate) - RedisUtils.expire(self.__get_redis(), "kpl_forbidden_plates", tool.get_expire()) - self.__deleted_kpl_forbidden_plates_cache.add(plate) - RedisUtils.sadd(self.__get_redis(), "deleted_kpl_forbidden_plates", plate) - RedisUtils.expire(self.__get_redis(), "deleted_kpl_forbidden_plates", tool.get_expire()) - - def list_all(self): - return RedisUtils.smembers(self.__get_redis(), "kpl_forbidden_plates") - - def list_all_cache(self): - return self.__kpl_forbidden_plates_cache - - def list_all_deleted_cache(self): - return self.__deleted_kpl_forbidden_plates_cache - - def is_in_cache(self, plate): - if self.__kpl_forbidden_plates_cache and plate in self.__kpl_forbidden_plates_cache: - return True - return False - - @classmethod - def __load_latest_gb(cls): - """ - 鍔犺浇鏈�杩戠殑甯傚満楂樻爣 - @return: - """ - # 鑾峰彇鏈�杩�10涓氦鏄撴棩娑ㄥ仠鐨勬定鍋滄暟鎹� - dates = HistoryKDatasUtils.get_latest_trading_date_cache(10) - if not dates: - return - min_date = dates[-1] - sql = f"SELECT r.`_code`, r.`_hot_block_name`, r.`_day`, r.`_open` FROM `kpl_limit_up_record` r WHERE r.`_day`>='{min_date}'" - mysqldb = mysql_data.Mysqldb() - results = mysqldb.select_all(sql) - code_days_map = {} - # 姣忕偢鏉� - f_code_days_map = {} - for r in results: - if r[0] not in code_days_map: - code_days_map[r[0]] = set() - code_days_map[r[0]].add(r[2]) - if not r[3]: - if r[0] not in f_code_days_map: - f_code_days_map[r[0]] = set() - f_code_days_map[r[0]].add(r[2]) - - # 杩囨护娑ㄥ仠娆℃暟>=3娆$殑鏁版嵁 - target_codes = set() - for code in code_days_map: - if f_code_days_map.get(code) and (len(f_code_days_map.get(code)) >= 4 or ( - tool.is_ge_code(code) and len(f_code_days_map.get(code)) >= 2)): - # 涓旀湁3澶╁睘浜庤繛缁定鍋� - day_list = list(code_days_map[code]) - day_list.sort(reverse=True) - step = 3 - has_continue = False - for i in range(0, len(day_list) - step + 1): - item_list = day_list[i:i + step] - # 鏄惁灞炰簬杩炵画娑ㄥ仠 - is_sub = False - for j in range(0, len(dates) - step): - if f"{dates[j:j + step]}" == f"{item_list}": - is_sub = True - break - if is_sub: - has_continue = True - break - if not has_continue: - continue - - has_big_deal = False - # 鏈�杩�10涓氦鏄撴棩鐨勬垚浜ら瑕佸ぇ浜�10浜� - volumes_data = HistoryKDataManager().get_history_bars(code, dates[0]) - if volumes_data: - for d in volumes_data[:10]: - if d["amount"] > 10e8: - has_big_deal = True - break - if not has_big_deal: - continue - target_codes.add(code) - # 浠g爜瀵瑰簲鐨勬澘鍧� - code_blocks = {} - for r in results: - if r[0] not in target_codes: - continue - if r[0] not in code_blocks: - code_blocks[r[0]] = set() - code_blocks[r[0]].add(kpl_util.filter_block(r[1])) - # 鎵�鏈夋澘鍧楀搴旂殑浠g爜闆嗗悎 - block_codes = {} - for code in code_blocks: - for b in code_blocks[code]: - if b in constant.KPL_INVALID_BLOCKS: - continue - if b not in block_codes: - block_codes[b] = set() - block_codes[b].add(code) - print(block_codes) - cls.__watch_block_high_codes = block_codes - logger_kpl_latest_gaobiao.info(f"{block_codes}") - cls.__watch_high_codes.clear() - for b in block_codes: - cls.__watch_high_codes |= block_codes[b] - - for k in block_codes: - print(k, [(x, gpcode_manager.get_code_name(x)) for x in block_codes[k]]) - - def get_watch_high_codes(self): - return self.__watch_high_codes - - def get_watch_high_codes_by_block(self, b): - return self.__watch_block_high_codes.get(b) - - def compute(self, code_rate_dict: dict): - """ - 鏍规嵁姣斾緥璁$畻闇�瑕佹媺榛戠殑浠g爜 - @param code_rate_dict: 娑ㄥ箙鐧惧垎鏁� - @return: - """ - try: - if self.__watch_block_high_codes: - forbidden_blocks = set() - for b in self.__watch_block_high_codes: - total_rate = 0 - for code in self.__watch_block_high_codes[b]: - if code in code_rate_dict: - total_rate += code_rate_dict.get(code) - average_rate = total_rate / len(self.__watch_block_high_codes[b]) - if average_rate < 1: - forbidden_blocks.add(b) - # async_log_util.info(logger_debug, f"鏉垮潡骞冲潎娑ㄥ箙 {b}-{average_rate}") - - self.__kpl_forbidden_plates_cache = forbidden_blocks - async_log_util.info(logger_debug, f"鎷夐粦鏉垮潡锛歿forbidden_blocks}") - except Exception as e: - logger_debug.exception(e) - - -class LimitUpCodesPlateKeyManager: - # 浠婃棩娑ㄥ仠鍘熷洜 - today_limit_up_reason_dict = {} - __today_total_limit_up_reason_dict = {} - total_code_keys_dict = {} - total_key_codes_dict = {} - __redisManager = redis_manager.RedisManager(1) - - def __get_redis(self): - return self.__redisManager.getRedis() - - # 鑾峰彇浠婃棩娑ㄥ仠鏁版嵁锛屾牸寮忥細[(浠g爜,娑ㄥ仠鍘熷洜,绮鹃�夋澘鍧楀垪琛�)] - def set_today_limit_up(self, datas): - temp_dict = {} - if datas: - for item in datas: - temp_dict[item[0]] = item[1] - self.today_limit_up_reason_dict = temp_dict - if datas: - for item in datas: - self.__set_total_keys(item[0]) - self.set_today_total_limit_up(datas) - - # 璁剧疆浠婃棩鍘嗗彶娑ㄥ仠鏁版嵁 - # 鏍煎紡锛�(浠g爜,娑ㄥ仠鍘熷洜,绮鹃�夋澘鍧楀垪琛�) - @classmethod - def set_today_total_limit_up(cls, datas): - for item in datas: - code = item[0] - # 璁剧疆娑ㄥ仠浠g爜鐨勬澘鍧楀強鍘熷洜 - cls.__today_total_limit_up_reason_dict[code] = (item[1], item[2]) - - @classmethod - def get_today_limit_up_reason(cls, code): - return cls.__today_total_limit_up_reason_dict.get(code) - - # 璁剧疆浠g爜鐨勪粖鏃ユ定鍋滃師鍥� - def __set_total_keys(self, code): - keys = set() - # keys_his = self.__get_redis().smembers(f"kpl_limit_up_reason_his-{code}") - # keys |= keys_his - if code in self.today_limit_up_reason_dict: - if self.today_limit_up_reason_dict.get(code) not in constant.KPL_INVALID_BLOCKS: - keys.add(self.today_limit_up_reason_dict.get(code)) - self.total_code_keys_dict[code] = keys - for k in keys: - if k not in self.total_key_codes_dict: - self.total_key_codes_dict[k] = set() - self.total_key_codes_dict[k].add(code) - - # logger_kpl_limit_up.info("{}鏉垮潡鍏抽敭璇�:{}", code, keys) - - # 鏍规嵁浼犲叆鐨勫叧閿瘝涓庢定鍋滀唬鐮佷俊鎭尮閰嶈韩浣� - - def get_codes_by_key_without_mine(self, key, code): - # 鍙瘮杈冧粖鏃ユ定鍋滃師鍥� - codes_set = set() - if key in self.total_key_codes_dict: - codes_set |= self.total_key_codes_dict[key] - codes_set.discard(code) - return codes_set - - # 娑ㄥ仠鍘熷洜鍖归厤鍏抽敭瀛�(鍜屾定鍋滃垪琛ㄤ腑鐨勬定鍋滃師鍥犲仛瀵规瘮),杩斿洖:{鍏抽敭璇�:浠g爜闆嗗悎} - def match_limit_up_reason_keys(self, code, keys): - fresult = {} - for k in keys: - if k in self.total_key_codes_dict: - codes = set(self.total_key_codes_dict[k]) - codes.discard(code) - if codes: - fresult[k] = codes - return fresult - - -# 瀹炴椂寮�鐩樺暒甯傚満鏁版嵁 -class RealTimeKplMarketData: - # 娴佸叆缂撳瓨 [ID, 鏉垮潡鍚嶇О, 鏉垮潡娑ㄥ箙, 娴佸叆閲戦] - top_in_list_cache = [] - # 娴佸嚭缂撳瓨 - top_out_list_cache = [] - # 琛屼笟鍓�5 - top_5_industry_list = [] - # - top_5_key_dict = {} - total_reason_dict = {} - total_industry_dict = {} - __KPLPlateForbiddenManager = KPLPlateForbiddenManager() - __LimitUpCodesPlateKeyManager = LimitUpCodesPlateKeyManager() - __KPLPlatManager = KPLPlatManager() - # 绮鹃�夋祦鍏ュ墠鍑� - __top_jx_blocks = [] - # 绮鹃�夋祦鍑哄墠鍑� - __top_jx_out_blocks = [] - # 绮鹃�夋澘鍧楁祦鍏ラ噾棰� - __jx_blocks_in_money_dict = {} - # 甯傚満琛屾儏鐑害锛岄粯璁や负60 - __market_strong = 60 - - @classmethod - def get_jingxuan_in_block_threshold_count(cls): - """ - 鑾峰彇涔扮簿閫夋祦鍏ュ墠鍑� - @return: - """ - score = 60 - if cls.__market_strong is not None: - score = int(cls.__market_strong) - for info in constant.RADICAL_BUY_TOP_IN_COUNT_BY_MARKET_STRONG: - if info[0] <= score < info[1]: - return info[2] - return 10 - - @classmethod - def set_market_jingxuan_blocks(cls, datas): - """ - 璁剧疆绮鹃�夋祦鍏ユ暟鎹� - @param datas:[(鏉垮潡缂栧彿,鏉垮潡鍚嶇О,娑ㄥ箙, 鏉垮潡娴佸叆閲戦)] - @return: - """ - # 娴佸叆闃堝�� - # THRESHOLD_MONEY = 50 * (tool.trade_time_sub(tool.get_now_time_str(), "09:30:00") // 60) + 1000 - # THRESHOLD_MONEY = min(THRESHOLD_MONEY, 10000) - # THRESHOLD_MONEY = max(THRESHOLD_MONEY, 1000) - # THRESHOLD_MONEY = THRESHOLD_MONEY * 10000 - THRESHOLD_MONEY = 0 - # 鏈�澶ф暟閲� - # MAX_COUNT = cls.get_jingxuan_in_block_threshold_count() - - cls.top_in_list_cache = datas - blocks = set() - count = 0 - fblock_money = {} - for data in datas: - cls.__jx_blocks_in_money_dict[data[1]] = data[3] - if data[1] in constant.KPL_INVALID_BLOCKS: - continue - if data[3] < THRESHOLD_MONEY: - continue - # 杩囨护鍑烘潵涓哄悓涓�涓澘鍧楀氨鍙畻1涓暟閲� - fb = BlockMapManager().filter_blocks({data[1]}) - if blocks & fb: - continue - - for b in fb: - fblock_money[b] = data[3] - blocks |= fb - - # 濡傛灉璇ュ師鍥犳病鏈夋定鍋滅エ瑕佸線鍚庣Щ涓�浣� - has_code = False - for b in fb: - if ContainsLimitupCodesBlocksManager().get_block_codes(b): - has_code = True - break - if has_code: - count += 1 - if count == 10: - strong = cls.get_market_strong() - if strong is None: - strong = 60 - if data[3] > 3e7: - # 澶т簬3鍗冧竾 - THRESHOLD_MONEY = int((1 - strong / 200) * data[3]) - else: - THRESHOLD_MONEY = data[3] - # if count >= MAX_COUNT: - # break - # 璁板綍绮鹃�夋祦鍑烘棩蹇� - async_log_util.info(logger_kpl_jx_in, f"鍘熸暟鎹細{datas[:50]} 鏉垮潡锛歿blocks}") - blocks = list(blocks) - blocks.sort(key=lambda x: fblock_money.get(x), reverse=True) - cls.__top_jx_blocks = blocks - - @classmethod - def set_market_jingxuan_out_blocks(cls, datas): - """ - 璁剧疆绮鹃�夋祦鍑烘暟鎹� - @param datas: - @return: - """ - cls.top_out_list_cache = datas - count = 0 - blocks = set() - for data in datas: - cls.__jx_blocks_in_money_dict[data[1]] = data[3] - if data[1] in constant.KPL_INVALID_BLOCKS: - continue - if data[3] > -5e7: - # 杩囨护5鍗冧竾浠ヤ笂鐨� - break - # 杩囨护鍑烘潵涓哄悓涓�涓澘鍧楀氨鍙畻1涓暟閲� - fb = BlockMapManager().filter_blocks({data[1]}) - if blocks & fb: - continue - blocks |= fb - count += 1 - if count >= 10: - break - # 璁板綍绮鹃�夋祦鍑烘棩蹇� - async_log_util.info(logger_kpl_jx_out, f"鍘熸暟鎹細{datas[:10]} 鏉垮潡锛歿blocks}") - cls.__top_jx_out_blocks = list(blocks) - - @classmethod - def set_market_strong(cls, strong): - """ - 璁剧疆甯傚満琛屾儏寮哄害 - @param strong: - @return: - """ - cls.__market_strong = strong - - @classmethod - def is_ignore_block_in_money(cls): - if cls.__market_strong and cls.__market_strong >= constant.IGNORE_BLOCK_IN_MONEY_MARKET_STRONG: - return True - return False - - @classmethod - def get_market_strong(cls): - return cls.__market_strong - - @classmethod - def get_top_market_jingxuan_blocks(cls): - return cls.__top_jx_blocks - - @classmethod - def get_top_market_jingxuan_out_blocks(cls): - return cls.__top_jx_out_blocks - - @classmethod - def get_block_info_at_block_in(cls, b): - """ - 鑾峰彇鏉垮潡鐨勫噣娴佸叆鎯呭喌 - @param b: - @return: (鏉垮潡鍚嶇О,韬綅,娴佸叆閲戦) - """ - for i in range(0, len(cls.top_in_list_cache)): - if cls.top_in_list_cache[i][1] == b: - return b, i, cls.top_in_list_cache[i][3] - return b, -1, 0 - - @classmethod - def set_top_5_industry(cls, datas): - for d in datas: - cls.total_industry_dict[d[1]] = d - temp_list = [] - for i in range(0, len(datas)): - if datas[i][1] in constant.KPL_INVALID_BLOCKS: - continue - temp_list.append((datas[i][1], datas[i][2], len(temp_list))) - if len(temp_list) > 10: - break - if datas[i][2] < 3 * 10000 * 10000: - break - cls.top_5_industry_list = temp_list - cls.__reset_top_5_dict() - - @classmethod - def __reset_top_5_dict(cls): - temp_dict = {} - for t in cls.top_5_industry_list: - temp_dict[t[0]] = t - for t in cls.top_5_reason_list: - temp_dict[t[0]] = t - cls.top_5_key_dict = temp_dict - - # 鑾峰彇鑳藉涔扮殑琛屼笟鍏抽敭瀛梥et - @classmethod - def get_can_buy_key_set(cls): - temp_set = cls.top_5_key_dict.keys() - return temp_set - - @classmethod - def is_in_top(cls, keys): - reasons = cls.get_can_buy_key_set() - forbidden_plates = cls.__KPLPlateForbiddenManager.list_all_cache() - reasons = reasons - forbidden_plates - temp_set = keys & reasons - if temp_set: - return True, temp_set - else: - return False, None - - @classmethod - def get_jx_block_in_money(cls, block): - return cls.__jx_blocks_in_money_dict.get(block) - - -# 浠g爜鍘嗗彶娑ㄥ仠鍘熷洜涓庢澘鍧楃鐞� -class CodesHisReasonAndBlocksManager: - __redisManager = redis_manager.RedisManager(1) - # 鍘嗗彶娑ㄥ仠鍘熷洜 - __history_limit_up_reason_dict = {} - # 鏉垮潡 - __blocks_dict = {} - - __instance = None - - def __new__(cls, *args, **kwargs): - if not cls.__instance: - cls.__instance = super(CodesHisReasonAndBlocksManager, cls).__new__(cls, *args, **kwargs) - - return cls.__instance - - def __get_redis(self): - return self.__redisManager.getRedis() - - def set_history_limit_up_reason(self, code, reasons): - self.__history_limit_up_reason_dict[code] = set(reasons) - RedisUtils.setex(self.__get_redis(), f"kpl_his_limit_up_reason-{code}", tool.get_expire(), - json.dumps(list(reasons))) - - # 濡傛灉杩斿洖鍊间笉涓篘one琛ㄧず宸茬粡鍔犺浇杩囧巻鍙插師鍥犱簡 - def get_history_limit_up_reason(self, code): - reasons = self.__history_limit_up_reason_dict.get(code) - if reasons is None: - # 浠庡唴瀛樹腑鍔犺浇 - val = RedisUtils.get(self.__get_redis(), f"kpl_his_limit_up_reason-{code}") - if val is not None: - val = set(json.loads(val)) - self.__history_limit_up_reason_dict[code] = val - if code in self.__history_limit_up_reason_dict: - return self.__history_limit_up_reason_dict.get(code) - else: - return None - else: - return reasons - - def get_history_limit_up_reason_cache(self, code): - reasons = self.__history_limit_up_reason_dict.get(code) - return reasons - - def set_blocks(self, code, blocks): - self.__blocks_dict[code] = set(blocks) - RedisUtils.setex(self.__get_redis(), f"kpl_blocks-{code}", tool.get_expire(), json.dumps(list(blocks))) - - def get_blocks(self, code): - reasons = self.__blocks_dict.get(code) - if reasons is None: - # 浠庡唴瀛樹腑鍔犺浇 - val = RedisUtils.get(self.__get_redis(), f"kpl_blocks-{code}") - if val is not None: - val = set(json.loads(val)) - self.__blocks_dict[code] = val - if code in self.__blocks_dict: - return self.__blocks_dict.get(code) - else: - return None - else: - return reasons - - def get_total_keys(self, code): - reasons = self.get_history_limit_up_reason(code) - if reasons is None: - reasons = set() - blocks = self.get_blocks(code) - if blocks is None: - blocks = set() - return reasons | blocks - - __history_blocks_dict_cache = {} - - def get_history_blocks(self, code): - """ - 鑾峰彇180澶╃殑鍘嗗彶娑ㄥ仠鍘熷洜 - @param code: - @return: - """ - if code in self.__history_blocks_dict_cache: - return self.__history_blocks_dict_cache.get(code) - try: - kpl_results = KPLLimitUpDataUtil.get_latest_block_infos(code=code) - # 鍙栨渶杩�2鏉℃暟鎹� - if kpl_results and len(kpl_results) > 2: - kpl_results = kpl_results[-2:] - keys = set() - if kpl_results: - keys |= set([x[2] for x in kpl_results]) - for r in kpl_results: - if r[3]: - keys |= set(r[3].split("銆�")) - self.__history_blocks_dict_cache[code] = keys - return keys - except: - pass - return set() - - def get_history_blocks_cache(self, code): - """ - 鑾峰彇180澶╃殑鍘嗗彶娑ㄥ仠鍘熷洜缂撳瓨 - @param code: - @return: - """ - return self.__history_blocks_dict_cache.get(code) - - -# 鐩爣浠g爜鏉垮潡鍏抽敭璇嶇鐞� -class TargetCodePlateKeyManager: - __redisManager = redis_manager.RedisManager(1) - __CodesPlateKeysManager = CodesHisReasonAndBlocksManager() - __KPLCodeJXBlockManager = KPLCodeJXBlockManager() - - def __get_redis(self): - return self.__redisManager.getRedis() - - # 杩斿洖key闆嗗悎(鎺掗櫎鏃犳晥鏉垮潡),浠婃棩娑ㄥ仠鍘熷洜,浠婃棩鍘嗗彶娑ㄥ仠鍘熷洜,鍘嗗彶娑ㄥ仠鍘熷洜,浜岀骇,绮鹃�夋澘鍧� - def get_plate_keys(self, code, contains_today=True): - """ - 鑾峰彇浠g爜鐨勬澘鍧�: 锛�180澶╃殑娑ㄥ仠鍘熷洜+鎺ㄨ崘鍘熷洜锛�+浠婃棩娑ㄥ仠鍘熷洜+浠婃棩娑ㄥ仠鎺ㄨ崘鍘熷洜+浠婃棩鎺ㄨ崘鍘熷洜 - @param code: - @return: 锛堟澘鍧楀叧閿瘝闆嗗悎,浠婃棩娑ㄥ仠鍘熷洜+娑ㄥ仠鎺ㄨ崘鍘熷洜,浠婃棩鍘嗗彶娑ㄥ仠鍘熷洜,鍘嗗彶娑ㄥ仠鍘熷洜,绮鹃�夋澘鍧楋級 - """ - keys = set() - k1 = set() - - limit_up_reason_info = LimitUpCodesPlateKeyManager.get_today_limit_up_reason(code) - if limit_up_reason_info: - k1 = {limit_up_reason_info[0]} | set(limit_up_reason_info[1]) - # 鍔犺浇浠婃棩鍘嗗彶鍘熷洜,鏆傛椂涓嶉渶瑕佸巻鍙插師鍥犱簡 - k11 = set() # RedisUtils.smembers(self.__get_redis(), f"kpl_limit_up_reason_his-{code}") - k2 = self.__CodesPlateKeysManager.get_history_limit_up_reason_cache(code) - if k2 is None: - k2 = set() - - k3 = self.__CodesPlateKeysManager.get_history_blocks(code) - if k3: - keys |= k3 - # industry = global_util.code_industry_map.get(code) - # if industry: - # k3 = {industry} - - k4 = set() - jingxuan_block_info = self.__KPLCodeJXBlockManager.get_jx_blocks_cache(code) - if not jingxuan_block_info: - jingxuan_block_info = self.__KPLCodeJXBlockManager.get_jx_blocks_cache(code, by=True) - if jingxuan_block_info: - jingxuan_blocks = jingxuan_block_info[0] - k4 |= set(jingxuan_blocks) # set([x[1] for x in jingxuan_blocks]) - if k1 and contains_today: - # 娑ㄥ仠杩� - keys |= k1 - - # 鑾峰彇涓嶅埌娑ㄥ仠鍘熷洜 - if contains_today: - keys |= k4 - keys = keys - set(constant.KPL_INVALID_BLOCKS) - return keys, k1, k11, k2, k3, k4 - - def get_plate_keys_for_radical_buy(self, code): - """ - 婵�杩涗拱鍏ョ殑鏉垮潡 - @param code: - @return: - """ - - -if __name__ == "__main__": - pass diff --git a/third_data/hx_qc_value_util.py b/third_data/hx_qc_value_util.py index cfa2f3e..ffdd2e4 100644 --- a/third_data/hx_qc_value_util.py +++ b/third_data/hx_qc_value_util.py @@ -7,7 +7,6 @@ import time from huaxin_client import l1_api_client -from log_module.log import logger_debug from utils import tool __response_data = {} diff --git a/third_data/kpl_api.py b/third_data/kpl_api.py index 689facd..552e7fc 100644 --- a/third_data/kpl_api.py +++ b/third_data/kpl_api.py @@ -149,6 +149,34 @@ data=data) +def getCodesByPlateOrderByLZCS(plate_code): + """ + 鏍规嵁棰嗘定娆℃暟鎺掑簭 + @param plate_code: + @return: + """ + data = f"Order=1&a=ZhiShuStockList_W8&st=30&c=ZhiShuRanking&PhoneOSNew=1&old=1&DeviceID=a38adabd-99ef-3116-8bb9-6d893c846e23&VerSion=5.8.0.2&IsZZ=0&Token=0&Index=0&apiv=w32&Type=27&IsKZZType=0&UserID=0&PlateID={plate_code}&" + return __base_request("https://apphq.longhuvip.com/w1/api/index.php", + data=data) + + +def getHistoryCodesByPlateOrderByLZCS(plate_code, date, time_str, page = 1): + """ + 鏍规嵁棰嗘定娆℃暟鎺掑簭 + @param page: 椤电爜 + @param date: 2025-05-25 + @param time_str: 1025 + @param plate_code: 110505 + @return: + """ + if tool.get_now_date_str() == date: + data = f"Order=1&a=ZhiShuStockList_W8&st=30&c=ZhiShuRanking&PhoneOSNew=1&RStart=0925&old=1&DeviceID=b692e51c-1bc4-3e8c-a01b-620aa6240e28&VerSion=5.8.0.4&IsZZ=0&Token=0&Index={(page-1)*30}&REnd={time_str}&apiv=w33&Type=27&IsKZZType=0&UserID=0&PlateID={plate_code}&" + else: + data = f"Order=1&a=ZhiShuStockList_W8&st=30&c=ZhiShuRanking&PhoneOSNew=1&RStart=0925&old=1&DeviceID=b692e51c-1bc4-3e8c-a01b-620aa6240e28&VerSion=5.8.0.4&IsZZ=0&Token=0&Index={(page-1)*30}&Date={date}&REnd={time_str}&apiv=w33&Type=27&IsKZZType=0&UserID=0&PlateID={plate_code}&" + return __base_request("https://apphq.longhuvip.com/w1/api/index.php", + data=data) + + # 鑾峰彇姒傚康涓殑鏉垮潡寮哄害 def getSonPlate(plate_code): data = f"a=SonPlate_Info&apiv=w32&c=ZhiShuRanking&PhoneOSNew=1&DeviceID=a38adabd-99ef-3116-8bb9-6d893c846e23&VerSion=5.8.0.2&PlateID={plate_code}&" @@ -326,10 +354,18 @@ if __name__ == "__main__": - request_new_blocks_codes([("鏈哄櫒浜�", "801159")]) + # request_new_blocks_codes([("鏈哄櫒浜�", "801159")]) # result = getCodesByPlate("801159") # getHistoryLimitUpInfo("2024-02-19") # result = json.loads(result) # for d in result["list"]: # print(d) # # print(result) + print(getCodeJingXuanBlocks("002519")) + # results = getHistoryCodesByPlateOrderByLZCS("801199", "2025-05-16", "0930", 3) + # results = json.loads(results)["list"] + # for result in results: + # d = result[0], result[1], result[2], result[40] + # if d[3] < 3: + # continue + # print(d) diff --git a/third_data/kpl_data_constant.py b/third_data/kpl_data_constant.py index 635b227..07cb9a8 100644 --- a/third_data/kpl_data_constant.py +++ b/third_data/kpl_data_constant.py @@ -6,8 +6,7 @@ from third_data.third_blocks_manager import BlockMapManager -from utils import tool, global_util -from utils.kpl_data_db_util import KPLLimitUpDataUtil +from utils import tool # 鐢ㄤ簬璁$畻婵�杩涗拱寮�1鐨勬澘鏁帮細{"浠g爜":(鍑犵増,{鏉垮潡})} from utils.tool import singleton diff --git a/third_data/kpl_data_manager.py b/third_data/kpl_data_manager.py deleted file mode 100644 index 4c094cd..0000000 --- a/third_data/kpl_data_manager.py +++ /dev/null @@ -1,686 +0,0 @@ -import copy -import json -import logging -import os -import threading -import time - -import requests - -import constant -from db.redis_manager_delegate import RedisUtils -from log_module import async_log_util, log -from third_data.kpl_data_constant import LimitUpDataConstant, TodayLimitUpReasonChangeManager -from utils import tool - -# 寮�鐩樺暒鍘嗗彶娑ㄥ仠鏁版嵁绠$悊 -from db import mysql_data_delegate as mysql_data, redis_manager_delegate as redis_manager -from log_module.log import logger_kpl_limit_up_reason_change, logger_debug, logger_kpl_limit_up, \ - logger_kpl_open_limit_up -from third_data import kpl_util, kpl_api -from third_data.code_plate_key_manager import LimitUpCodesPlateKeyManager, CodesHisReasonAndBlocksManager - -# 浠g爜瀵瑰簲鐨勬定鍋滃師鍥犱繚瀛� -from third_data.kpl_util import KPLPlatManager, KPLDataType - - -class KPLCodeLimitUpReasonManager: - __redisManager = redis_manager.RedisManager(3) - - def __get_redis(self): - return self.__redisManager.getRedis() - - def save_reason(self, code, reason): - RedisUtils.setex(self.__get_redis(), f"kpl_limitup_reason-{code}", tool.get_expire(), reason) - - def list_all(self): - keys = RedisUtils.keys(self.__get_redis(), "kpl_limitup_reason-*") - dict_ = {} - for k in keys: - val = RedisUtils.get(self.__get_redis(), k) - dict_[k.split("-")[1]] = val - return dict_ - - -class KPLLimitUpDataRecordManager: - total_datas = None - latest_datas = {} - latest_origin_datas = [] - __kplPlatManager = KPLPlatManager() - __LimitUpCodesPlateKeyManager = LimitUpCodesPlateKeyManager() - __CodesPlateKeysManager = CodesHisReasonAndBlocksManager() - __current_code_reasons_dict = {} - # 褰撳墠娑ㄥ仠鍘熷洜+鎺ㄨ崘鍘熷洜鐨勪唬鐮侀泦鍚� - __current_reason_codes_dict = {} - # 褰撳墠娑ㄥ仠鍘熷洜鐨勪唬鐮侀泦鍚� - __current_limit_up_reason_codes_dict = {} - __records_cache = {} - record_code_dict = {} - - @classmethod - def __load_hist_and_blocks(cls, code): - # 鏈夋暟鎹柊澧烇紝鍔犺浇鍘嗗彶鍘熷洜涓庢澘鍧� - his_reasons = cls.get_latest_infos(code, 10, False) - his_reasons = set([r[0] for r in his_reasons]) - cls.__CodesPlateKeysManager.set_history_limit_up_reason(code, his_reasons) - try: - if not cls.__CodesPlateKeysManager.get_blocks(code): - results = kpl_api.getStockIDPlate(code) - bs = [r[1] for r in results] - cls.__CodesPlateKeysManager.set_blocks(code, bs) - except Exception as e: - pass - - @classmethod - def save_record(cls, day, records, set_not_open=False): - """ - @param day: - @param records: - @param set_not_open: 鏄惁闇�瑕佽缃偢鏉夸笌鍚� - @return: - """ - # 缁熻鐐告澘 - try: - last_codes = set() - if cls.latest_origin_datas: - last_codes = set([x[0] for x in cls.latest_origin_datas]) - now_codes = set() - if records: - now_codes = set([x[0] for x in records]) - open_limit_up_codes = last_codes - now_codes - if open_limit_up_codes: - logger_kpl_open_limit_up.info(f"鐐告澘浠g爜锛歿open_limit_up_codes}") - except Exception as e: - pass - - # 缁熻浠g爜鎵�灞炴澘鍧� - code_block_dict = {} - for data in records: - cls.record_code_dict[data[0]] = data - blocks = set(data[5].split("銆�")) - code = data[0] - for b in blocks: - if not code_block_dict.get(code): - code_block_dict[code] = set() - code_block_dict[code].add(b) - # 璁剧疆娑ㄥ仠鏁版嵁 - if records: - cls.latest_origin_datas = records - cls.__LimitUpCodesPlateKeyManager.set_today_limit_up( - [(r[0], r[5], r[6].split('銆�') if r[6] else []) for r in records]) - LimitUpDataConstant.set_current_limit_up_datas(records) - - code_reasons_dict = {} - reason_codes_dict = {} - limit_up_reason_codes_dict = {} - for d in records: - if d[5] not in limit_up_reason_codes_dict: - limit_up_reason_codes_dict[d[5]] = set() - limit_up_reason_codes_dict[d[5]].add(d[0]) - - # 娑ㄥ仠鍘熷洜 + 鎺ㄨ崘鍘熷洜 - bs = {d[5]} - if d[6]: - bs |= set(d[6].split("銆�")) - code_reasons_dict[d[0]] = bs - for b in bs: - if b not in reason_codes_dict: - reason_codes_dict[b] = set() - reason_codes_dict[b].add(d[0]) - cls.__current_code_reasons_dict = code_reasons_dict - cls.__current_reason_codes_dict = reason_codes_dict - cls.__current_limit_up_reason_codes_dict = limit_up_reason_codes_dict - - # 娑ㄥ仠鏁版嵁璁板綍 - mysqldb = mysql_data.Mysqldb() - # 缁熻娑ㄥ仠鍘熷洜鍜屾蹇典唬鐮� - plats = {} - for d in records: - plats[d[5]] = d[9] - for p in plats: - cls.__kplPlatManager.save_plat(plats[p], p) - - for d in records: - # (浠g爜, 鍚嶇О, 棣栨娑ㄥ仠鏃堕棿, 鏈�杩戞定鍋滄椂闂�, 鍑犳澘, 娑ㄥ仠鍘熷洜, 鏉垮潡, 瀹為檯娴侀��, 涓诲姏鍑�棰�,娑ㄥ仠鍘熷洜浠g爜,娑ㄥ仠鍘熷洜浠g爜鏁伴噺) - code = d[0] - _id = f"{day}_{code}_{d[5]}" - - result = mysqldb.select_one("select * from kpl_limit_up_record where _id='{}'".format(_id)) - if not result: - mysqldb.execute( - f"insert into kpl_limit_up_record(_id,_day,_hot_block_name,_code,_code_name,_limit_up_time,_blocks,_latest_limit_up_time,_update_time,_create_time,_hot_block_code_count,_limit_up_high_info,_zylt_val,_hot_block_code) values('{_id}','{day}','{d[5]}','{d[0]}','{d[1]}','{d[2]}','{d[6]}','{d[3]}',now(),now(),{d[10]},'{d[4]}',{d[7]},{d[9]})") - cls.__load_hist_and_blocks(code) - else: - if _id in cls.latest_datas and json.dumps(cls.latest_datas.get(_id)) != json.dumps(d): - mysqldb.execute( - f"update kpl_limit_up_record set _latest_limit_up_time='{d[3]}',_limit_up_time='{d[2]}',_hot_block_code_count={d[10]},_limit_up_high_info='{d[4]}' ,_update_time=now() where _id='{_id}'") - cls.latest_datas[_id] = d - if set_not_open: - # 闇�瑕佽缃笉鐐告澘 - mysqldb.execute(f"update kpl_limit_up_record set _open = 0, _update_time = now() where _id='{_id}'") - - cls.latest_datas[_id] = d - - # 鑾峰彇鍘熸潵鐨勪唬鐮佹墍灞炴澘鍧�,鍒犻櫎涔嬪墠閿欒鐨勬澘鍧� - old_datas = KPLLimitUpDataRecordManager.list_by_code(code, day) - if old_datas: - for dd in old_datas: - if dd[2] not in code_block_dict[code]: - mysqldb.execute(f"delete from kpl_limit_up_record where _id='{dd[0]}'") - logger_kpl_limit_up_reason_change.info(f"code-{dd[3]}:{dd[2]}-{code_block_dict[code]}") - # 鏉垮潡鏇存敼杩� - mysqldb.execute( - f"update kpl_limit_up_record set _hot_block_change = f'{dd[2]}' where _day='{dd[1]}' and _code='{code}'") - TodayLimitUpReasonChangeManager().set_today_limit_up_reason_change(code, dd[2], - code_block_dict[code]) - - if dd[0] in cls.latest_datas: - cls.latest_datas.pop(dd[0]) - cls.total_datas = KPLLimitUpDataRecordManager.list_all(tool.get_now_date_str()) - LimitUpDataConstant.set_history_limit_up_datas(cls.total_datas) - - @classmethod - def load_total_datas(cls): - cls.total_datas = KPLLimitUpDataRecordManager.list_all(tool.get_now_date_str()) - cls.__LimitUpCodesPlateKeyManager.set_today_total_limit_up( - [(r[3], r[2], r[6].split("銆�") if r[6] else []) for r in cls.total_datas]) - for d in cls.total_datas: - cls.__load_hist_and_blocks(d[3]) - - @staticmethod - def list_all(day, max_limit_up_time=None): - mysqldb = mysql_data.Mysqldb() - sql = f"select * from kpl_limit_up_record where _day='{day}'" - if max_limit_up_time: - sql += f" and cast(_limit_up_time as unsigned)<={max_limit_up_time}" - return mysqldb.select_all(sql) - - @classmethod - def list_all_cache(cls, day): - if day in cls.__records_cache: - return cls.__records_cache[day] - fdata = cls.list_all(day) - if fdata: - cls.__records_cache[day] = fdata - return fdata - - @staticmethod - def list_by_code(code, day): - mysqldb = mysql_data.Mysqldb() - return mysqldb.select_all(f"select * from kpl_limit_up_record where _code='{code}' and _day='{day}'") - - @staticmethod - def list_by_block(block_name, day): - mysqldb = mysql_data.Mysqldb() - return mysqldb.select_all( - f"select * from kpl_limit_up_record where _hot_block_name='{block_name}' and _day='{day}'") - - @staticmethod - def list_blocks_with_day(days): - mysqldb = mysql_data.Mysqldb() - sql = "select _hot_block_name,_day from kpl_limit_up_record where " - wheres = [] - for day in days: - wheres.append(f"_day = '{day}'") - sql += " or ".join(wheres) - sql += " group by _hot_block_name,_day" - - results = mysqldb.select_all(sql) - return results - - @staticmethod - def get_latest_blocks(code): - wheres = [] - for b in constant.KPL_INVALID_BLOCKS: - wheres.append(f"hb.`_hot_block_name` != '{b}'") - wheres = " and ".join(wheres) - sql = f"SELECT GROUP_CONCAT(_hot_block_name) FROM (SELECT hb.`_hot_block_name`,hb.`_day` FROM `kpl_limit_up_record` hb WHERE hb.`_code`='{code}' AND {wheres} ORDER BY hb.`_day` DESC LIMIT 2) a GROUP BY a._day ORDER BY a._day DESC LIMIT 1" - mysqldb = mysql_data.Mysqldb() - return mysqldb.select_one(sql) - - # 鑾峰彇浠g爜鏈�杩戠殑鏉垮潡锛岃繑鍥瀃(鏉垮潡,鏃ユ湡)] - @classmethod - def get_latest_infos(cls, code, count, contains_today=True): - wheres = [] - for b in constant.KPL_INVALID_BLOCKS: - wheres.append(f"hb.`_hot_block_name` != '{b}'") - wheres = " and ".join(wheres) - # 鍙幏鍙栨渶杩�180澶╃殑鏁版嵁 - min_day = tool.date_sub(tool.get_now_date_str(), 180) - sql = f"SELECT GROUP_CONCAT(_hot_block_name),`_day`,_blocks FROM (SELECT hb.`_hot_block_name`,hb.`_day`,hb._blocks FROM `kpl_limit_up_record` hb WHERE hb.`_code`='{code}' and {wheres} and hb.`_day` > '{min_day}' ORDER BY hb.`_day` DESC LIMIT 10) a GROUP BY a._day ORDER BY a._day DESC LIMIT {count}" - mysqldb = mysql_data.Mysqldb() - results = mysqldb.select_all(sql) - if results and not contains_today and results[0][1] == tool.get_now_date_str(): - return results[1:] - return results - - @classmethod - def get_latest_block_infos(cls, min_day=tool.date_sub(tool.get_now_date_str(), 180), code=None): - """ - - @param min_day: 榛樿鑾峰彇180澶╀箣鍓嶇殑 - @param code: 浠g爜 - @return: 鏈�杩戠殑娑ㄥ仠鏉垮潡淇℃伅 - """ - sql = f"SELECT r.`_code`, r.`_day`, r.`_hot_block_name`, r.`_blocks` FROM `kpl_limit_up_record` r WHERE r.`_day`>'{min_day}'" - if code: - sql += f" AND _code='{code}'" - sql += " order by _create_time" - mysqldb = mysql_data.Mysqldb() - results = mysqldb.select_all(sql) - return results - - @classmethod - def get_latest_blocks_set(cls, code): - results = cls.get_latest_infos(code, 2, False) - bs = set([b[0] for b in results]) - return bs - - @classmethod - def get_current_blocks(cls, code): - return cls.__current_code_reasons_dict.get(code) - - @classmethod - def get_current_codes_by_block(cls, block): - return cls.__current_reason_codes_dict.get(block) - - @classmethod - def get_current_reason_codes_dict(cls): - return copy.deepcopy(cls.__current_reason_codes_dict) - - @classmethod - def get_current_limit_up_reason_codes_dict(cls): - return copy.deepcopy(cls.__current_limit_up_reason_codes_dict) - - @classmethod - def get_current_reasons(cls): - if cls.__current_reason_codes_dict: - return cls.__current_reason_codes_dict.keys() - return set() - - @classmethod - def get_new_blocks(cls, day): - """ - 鑾峰彇鏌愪竴澶╂柊鍑虹幇鐨勬澘鍧�(鏂版澘鍧�) - @param day: - @return: - """ - sql = f"SELECT k.`_hot_block_name`, k.`_day` FROM `kpl_limit_up_record` k GROUP BY k.`_hot_block_name` HAVING k.`_day`='{day}' ORDER BY k.`_day` DESC" - mysqldb = mysql_data.Mysqldb() - results = mysqldb.select_all(sql) - return [x[0] for x in results] - - -class KPLDataManager: - __latest_datas = {} - kpl_data_update_info = {} - __file_content_cache = {} - - @classmethod - def __save_in_file(cls, key, datas): - name = f"{tool.get_now_date_str()}_{key}.log" - path = f"{constant.CACHE_PATH}/{name}" - with open(path, 'w') as f: - f.write(json.dumps(datas)) - - @classmethod - def __get_from_file(cls, key, day=tool.get_now_date_str()): - name = f"{day}_{key}.log" - path = f"{constant.CACHE_PATH}/{name}" - if not os.path.exists(path): - return None - with open(path, 'r') as f: - lines = f.readlines() - if lines: - return json.loads(lines[0]) - return None - - @classmethod - def get_from_file(cls, type, day): - name = f"{day}_{type.value}.log" - path = f"{constant.CACHE_PATH}/{name}" - if not os.path.exists(path): - return None - with open(path, 'r') as f: - lines = f.readlines() - if lines: - return json.loads(lines[0]) - return None - - @classmethod - def get_from_file_cache(cls, type, day): - key = f"{type}-{day}" - if key in cls.__file_content_cache: - return cls.__file_content_cache.get(key) - fdata = cls.get_from_file(type, day) - if fdata: - cls.__file_content_cache[key] = fdata - return fdata - - @classmethod - # 鑾峰彇鏈�杩戝嚑澶╃殑鏁版嵁锛屾牴鎹棩鏈熷�掑簭杩斿洖 - def get_latest_from_file(cls, type, count, max_day=tool.get_now_date_str()): - files = os.listdir(constant.CACHE_PATH) - file_name_list = [] - for f in files: - if f[10:] == f"_{type.value}.log": - file_name_list.append((f.split("_")[0], f)) - - file_name_list.sort(key=lambda x: x[0], reverse=True) - fresults = [] - for file in file_name_list: - path = f"{constant.CACHE_PATH}/{file[1]}" - if not os.path.exists(path): - continue - with open(path, 'r') as f: - lines = f.readlines() - if lines: - if int(file[0].replace("-", "")) <= int(max_day.replace("-", "")): - fresults.append((file[0], json.loads(lines[0]))) - if len(fresults) >= count: - break - - return fresults - - @classmethod - def save_data(cls, type, datas): - cls.kpl_data_update_info[type] = (tool.get_now_time_str(), len(datas)) - cls.__latest_datas[type] = datas - cls.__save_in_file(type, datas) - - @classmethod - def get_data(cls, type): - type = type.value - if type in cls.__latest_datas: - return cls.__latest_datas[type] - result = cls.__get_from_file(type) - if result is not None: - cls.__latest_datas[type] = result - return result - - -def load_history_limit_up(): - for file_name in os.listdir(f"{constant.get_path_prefix()}/kpl/his"): - if file_name.find("HisDaBanList_1.log") < 0: - continue - day = file_name[:10] - with open(f"{constant.get_path_prefix()}/kpl/his/{file_name}", 'r', encoding="utf-16") as f: - lines = f.readlines() - line = lines[0] - result = json.loads(line) - list_ = kpl_util.parseDaBanData(result, kpl_util.DABAN_TYPE_LIMIT_UP) - # KPLLimitUpDataRecordManager.save_record(day, list_) - for r in list_: - print(r[-1], r[5]) - KPLPlatManager().save_plat(r[-1], r[5]) - - # print(day, list_) - - -# 鍘嗗彶娑ㄥ仠鍒楄〃 -__limit_up_list_records_dict = {} - - -# 鑾峰彇鏈�杩戝嚑澶╃殑瀹炴椂娑ㄥ仠淇℃伅 -# 杩斿洖鏍煎紡锛圼鏃ユ湡,鏁版嵁]锛� -def get_current_limit_up_data_records(count, day=tool.get_now_date_str()): - fresults = [] - datas = [] - if day in __limit_up_list_records_dict: - datas = __limit_up_list_records_dict[day] - else: - logger_debug.info("浠庢枃浠朵腑鑾峰彇鍓嶅嚑澶╃殑瀹炴椂娑ㄥ仠鏁版嵁") - datas = KPLDataManager().get_latest_from_file(KPLDataType.LIMIT_UP, count + 2, max_day=day) - # 绉婚櫎姣斾粖澶╄繕澶х殑鏁版嵁 - fdatas = [] - for d in datas: - if int(d[0].replace("-", "")) > int(day.replace("-", "")): - continue - fdatas.append(d) - if fdatas: - # 淇濆瓨鏁版嵁 - __limit_up_list_records_dict[day] = fdatas - datas = __limit_up_list_records_dict[day] - for i in range(len(datas)): - if datas[i][0] == day: - continue - fresults.append(datas[i]) - if len(fresults) >= count: - break - return fresults - - -def get_yesterday_limit_up_codes(): - yesterday_limit_up_data_records = get_yesterday_current_limit_up_records() - yesterday_codes = set([x[0] for x in yesterday_limit_up_data_records]) - return yesterday_codes - - -def get_yesterday_current_limit_up_records(): - yesterday_limit_up_data_records = get_current_limit_up_data_records(1)[0][1] - return yesterday_limit_up_data_records - - -# 鑾峰彇鏈�杩戝嚑澶╂定鍋滃師鍥� -__latest_current_limit_up_records = {} - - -def get_latest_current_limit_up_records(day=tool.get_now_date_str(), max_day_count=15): - if day not in __latest_current_limit_up_records: - fdatas = get_current_limit_up_data_records(max_day_count) - __latest_current_limit_up_records[day] = fdatas - return __latest_current_limit_up_records.get(day) - - -class PullTask: - # 鏈�杩戞洿鏂版椂闂� - __latest_update_time_dict = {} - - @classmethod - def __upload_data(cls, type, datas): - root_data = { - "type": type, - "data": datas - } - requests.post("http://127.0.0.1:9004/upload_kpl_data", json.dumps(root_data)) - - @classmethod - def repaire_pull_task(cls): - """ - 淇鎷夊彇浠诲姟 - @return: - """ - # 淇娑ㄥ仠 - logger_debug.info("浠诲姟淇-寮�鐩樺暒锛氬惎鍔ㄤ慨澶�") - key = "limit_up" - if key not in cls.__latest_update_time_dict or time.time() - cls.__latest_update_time_dict[key] > 20: - logger_debug.info("浠诲姟淇-寮�鐩樺暒锛氭定鍋滃垪琛�") - # 澶т簬20s灏遍渶瑕佹洿鏂� - threading.Thread(target=cls.run_limit_up_task, daemon=True).start() - # key = "jingxuan_rank" - # if key not in cls.__latest_update_time_dict or time.time() - cls.__latest_update_time_dict[key] > 20: - # logger_debug.info("浠诲姟淇-寮�鐩樺暒锛氱簿閫夋祦鍏ュ垪琛�") - # # 澶т簬20s灏遍渶瑕佹洿鏂� - # threading.Thread(target=cls.run_market_jingxuan_in, daemon=True).start() - # - # key = "jingxuan_rank_out" - # if key not in cls.__latest_update_time_dict or time.time() - cls.__latest_update_time_dict[key] > 20: - # logger_debug.info("浠诲姟淇-寮�鐩樺暒锛氱簿閫夋祦鍑哄垪琛�") - # # 澶т簬20s灏遍渶瑕佹洿鏂� - # threading.Thread(target=cls.run_market_jingxuan_out, daemon=True).start() - - key = "market_strong" - if key not in cls.__latest_update_time_dict or time.time() - cls.__latest_update_time_dict[key] > 20: - logger_debug.info("浠诲姟淇-寮�鐩樺暒锛氬競鍦哄己搴�") - # 澶т簬20s灏遍渶瑕佹洿鏂� - threading.Thread(target=cls.run_market_strong, daemon=True).start() - - @classmethod - def run_limit_up_task(cls): - # 鍏抽棴log - log.close_print() - while True: - try: - if (tool.is_trade_time() and int(tool.get_now_time_str().replace(':', '')) > int("092530")): - results = kpl_api.getLimitUpInfoNew() - result = json.loads(results) - start_time = time.time() - cls.__upload_data("limit_up", result) - except Exception as e: - try: - logging.exception(e) - logger_debug.exception(e) - except: - pass - except: - pass - finally: - cls.__latest_update_time_dict["limit_up"] = time.time() - time.sleep(3) - - @classmethod - def run_market_jingxuan_in(cls): - """ - 绮鹃�夋祦鍏� - @return: - """ - while True: - try: - if tool.is_trade_time(): - results = kpl_api.getMarketJingXuanRealRankingInfo() - result = json.loads(results) - cls.__upload_data("jingxuan_rank", result) - except: - pass - finally: - cls.__latest_update_time_dict["jingxuan_rank"] = time.time() - time.sleep(3) - - @classmethod - def run_market_jingxuan_out(cls): - """ - 绮鹃�夋祦鍑� - @return: - """ - while True: - try: - if tool.is_trade_time(): - results = kpl_api.getMarketJingXuanRealRankingInfo(False) - result = json.loads(results) - cls.__upload_data("jingxuan_rank_out", result) - except: - pass - finally: - cls.__latest_update_time_dict["jingxuan_rank_out"] = time.time() - time.sleep(3) - - @classmethod - def run_market_strong(cls): - """ - 绮鹃�夋祦鍑� - @return: - """ - while True: - try: - if tool.is_trade_time(): - strong_value = kpl_api.getMarketStrong() - cls.__upload_data("market_strong", strong_value) - except: - pass - finally: - cls.__latest_update_time_dict["market_strong"] = time.time() - time.sleep(3) - - @classmethod - # 杩愯鎷夊彇浠诲姟 - def run_pull_task(cls): - def get_bidding_money(): - # 绔炰环鏁版嵁涓婁紶 - while True: - if int("092600") < int(tool.get_now_time_str().replace(":", "")) < int("092700"): - try: - results = kpl_api.daBanList(kpl_api.DABAN_TYPE_BIDDING) - result = json.loads(results) - cls.__upload_data("biddings", result) - except Exception as e: - pass - time.sleep(3) - - def get_market_industry(): - while True: - if tool.is_trade_time(): - try: - results = kpl_api.getMarketIndustryRealRankingInfo() - result = json.loads(results) - cls.__upload_data("industry_rank", result) - except: - pass - time.sleep(3) - - def get_market_jingxuan(): - while True: - if tool.is_trade_time(): - try: - results = kpl_api.getMarketJingXuanRealRankingInfo() - result = json.loads(results) - cls.__upload_data("jingxuan_rank", result) - except: - pass - finally: - cls.__latest_update_time_dict["jingxuan_rank"] = time.time() - time.sleep(3) - else: - time.sleep(3) - - threading.Thread(target=cls.run_limit_up_task, daemon=True).start() - threading.Thread(target=cls.run_market_strong, daemon=True).start() - # threading.Thread(target=get_bidding_money, daemon=True).start() - # threading.Thread(target=get_market_industry, daemon=True).start() - # threading.Thread(target=cls.run_market_jingxuan_in, daemon=True).start() - # threading.Thread(target=cls.run_market_jingxuan_out, daemon=True).start() - - -@tool.singleton -class CodeHighLevel: - """ - 浠g爜楂樺害绠$悊 - """ - __instance = None - # 涓嬪崟鏉垮潡鐨勪唬鐮佽褰� - __code_level_dict = {} - __codes = set() - - def __init__(self, day=tool.get_now_date_str()): - self.__day = day - self.__load_data(day) - - @classmethod - def __load_data(cls, day): - fdatas = get_current_limit_up_data_records(15, day=day) - temp_dict = {d[0]: 2 for d in fdatas[0][1]} - break_codes = set() - for i in range(1, len(fdatas)): - codes = [d[0] for d in fdatas[i][1]] - for k in temp_dict: - if k in break_codes: - continue - if k in codes: - temp_dict[k] += 1 - else: - break_codes.add(k) - cls.__code_level_dict = temp_dict - - def get_high_level(self, code): - """ - 鑾峰彇娑ㄥ仠楂樺害锛岄粯璁�1鏉� - @param code: - @return: - """ - if code in self.__code_level_dict: - return self.__code_level_dict[code] - return 1 - - -if __name__ == "__main__": - print(CodeHighLevel("2024-11-11").get_high_level("000833")) - input() diff --git a/third_data/third_blocks_manager.py b/third_data/third_blocks_manager.py new file mode 100644 index 0000000..3879e5e --- /dev/null +++ b/third_data/third_blocks_manager.py @@ -0,0 +1,124 @@ +""" +涓夋柟鏉垮潡绠$悊 +""" + +from db.mysql_data_delegate import Mysqldb + +SOURCE_TYPE_KPL = 1 # 寮�鐩樺暒 +SOURCE_TYPE_TDX = 2 # 閫氳揪淇� +SOURCE_TYPE_THS = 3 # 鍚岃姳椤� +SOURCE_TYPE_EASTMONEY = 4 # 涓滄柟璐㈠瘜 +SOURCE_TYPE_KPL_RECORD = 5 # 寮�鐩樺暒鍘嗗彶鏁版嵁 + + +class BlockMapManager: + """ + 鏉垮潡鏄犲皠绠$悊 + """ + __mysql = Mysqldb() + __instance = None + __block_map = {} + + def __new__(cls, *args, **kwargs): + if not cls.__instance: + cls.__instance = super(BlockMapManager, cls).__new__(cls, *args, **kwargs) + cls.__load_data() + return cls.__instance + + @classmethod + def __load_data(cls): + results = cls.__mysql.select_all("select origin_block,blocks from block_map") + cls.__block_map.clear() + for result in results: + cls.__block_map[result[0]] = set(result[1].split("銆�")) + + def set_block_map(self, origin_block, blocks): + if not blocks: + blocks = {origin_block} + blocks_str = "銆�".join(blocks) + result = self.__mysql.select_one(f"select * from block_map where origin_block='{origin_block}'") + if result: + # 鏇存柊 + self.__mysql.execute( + f"update block_map set blocks='{blocks_str}', update_time=now() where origin_block='{origin_block}'") + else: + self.__mysql.execute( + f"insert into block_map(origin_block, blocks, create_time) values('{origin_block}','{blocks_str}', now())") + + def get_map_blocks_cache(self, block): + """ + 鑾峰彇鏄犲皠濂界殑鏉垮潡 + @param block: + @return: + """ + return self.__block_map.get(block) + + def filter_blocks(self, blocks): + """ + 鎵归噺杩囨护鏉垮潡 + @param blocks: + @return: + """ + if blocks is None or len(blocks) == 0: + return set() + fbs = set() + invalid_blocks = InvalidBlockManager().get_invalid_blocks() + for block in blocks: + if block.endswith("姒傚康"): + block = block[:-2] + b = self.get_map_blocks_cache(block) + if b: + fbs |= b + if block in invalid_blocks: + continue + fbs.add(block) + return fbs + + def get_all_blocks(self): + return self.__block_map.keys() + + +class InvalidBlockManager: + """ + 鏃犳晥鏉垮潡绠$悊 + """ + __mysql = Mysqldb() + __instance = None + __block = set() + + def __new__(cls, *args, **kwargs): + if not cls.__instance: + cls.__instance = super(InvalidBlockManager, cls).__new__(cls, *args, **kwargs) + cls.__load_data() + return cls.__instance + + @classmethod + def __load_data(cls): + results = cls.__mysql.select_all("select _block from invalid_block") + cls.__block.clear() + for result in results: + if result[0]: + cls.__block.add(result[0]) + + def get_invalid_blocks(self): + """ + 鑾峰彇鏃犳晥鐨勬澘鍧� + @return: + """ + return self.__block + + def set_incalid_blocks(self, blocks): + """ + 璁剧疆鏃犳晥鐨勬澘鍧� + @param blocks: + @return: + """ + # 鍏堝垹闄ゆ墍鏈夛紝鐒跺悗鍐嶆坊鍔� + self.__mysql.execute("delete from invalid_block") + for b in blocks: + self.__mysql.execute(f"insert into invalid_block(_block) values('{b}')") + self.__block = set(blocks) + + +if __name__ == '__main__': + pass diff --git a/trade/huaxin/huaxin_trade_api.py b/trade/huaxin/huaxin_trade_api.py new file mode 100644 index 0000000..6fbfcff --- /dev/null +++ b/trade/huaxin/huaxin_trade_api.py @@ -0,0 +1,733 @@ +""" +浜ゆ槗API +""" +import copy +import json +import logging +import multiprocessing +import queue +import random +import threading +import time +import concurrent.futures + +import zmq + +from code_attribute import gpcode_manager +from huaxin_client import constant as huaxin_client_constant, trade_client +from log_module import async_log_util +from log_module.log import hx_logger_trade_debug, hx_logger_trade_loop, hx_logger_trade_callback, \ + logger_system +from trade.huaxin import huaxin_trade_data_update, huaxin_trade_record_manager +from trade.huaxin.huaxin_trade_record_manager import TradeOrderIdManager +from trade.huaxin.huaxin_trade_order_processor import CancelOrderManager, HuaxinOrderEntity, TradeResultProcessor +from utils import socket_util, huaxin_util, tool + +__response_thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=15) +__save_data_queue = queue.Queue(maxsize=1000) + + +def __run_save_data(): + while True: + try: + data = __save_data_queue.get() + huaxin_trade_record_manager.DelegateRecordManager.add_one(data) + except: + pass + finally: + time.sleep(0.1) + + +def __run_recv_queue_trade(queue: multiprocessing.Queue): + def __cancel_order(code, order_ref): + # 2s娌℃垚浜ゅ氨鎾ゅ崟 + time.sleep(2) + order_: HuaxinOrderEntity = TradeResultProcessor.get_huaxin_order_by_order_ref(order_ref) + if order_ is not None: + if huaxin_util.is_can_cancel(order_.orderStatus): + cancel_order(TRADE_DIRECTION_SELL, code, order_.orderSysID) + + def __process_order(data): + # 鏇存柊濮旀墭闃熷垪 + push_msg_manager.push_delegate_queue_update() + code = data["securityID"] + accountID = data["accountID"] + orderStatus = data["orderStatus"] + orderRef = data["orderRef"] + orderSysID = data["orderSysID"] + insertTime = data.get("insertTime") + acceptTime = data.get("acceptTime") + insertDate = data.get("insertDate") + direction = data.get("direction") + limitPrice = data.get("limitPrice") + volume = data.get("volume") + is_shadow_order = False + # 鑾峰彇娑ㄥ仠浠� + limit_up_price = gpcode_manager.get_limit_up_price(code) + if limit_up_price and volume == huaxin_client_constant.SHADOW_ORDER_VOLUME: + if abs(float(limitPrice) - float(limit_up_price)) >= 0.001: + is_shadow_order = True + + order = HuaxinOrderEntity(code, orderStatus, orderRef, accountID, orderSysID, + insertTime=insertTime, acceptTime=acceptTime, + insertDate=insertDate, direction=direction, + is_shadow_order=is_shadow_order) + try: + if str(order.direction) == str(huaxin_util.TORA_TSTP_D_Sell): + # 鍒锋柊鎸佷粨鍒楄〃 + huaxin_trade_data_update.add_position_list() + if huaxin_util.is_deal(order.orderStatus): + # 濡傛灉鎴愪氦浜嗛渶瑕佸埛鏂板鎵樺垪琛� + huaxin_trade_data_update.add_delegate_list("鍗栨垚浜�") + else: + if huaxin_util.is_deal(order.orderStatus): + # 濡傛灉鎴愪氦浜嗛渶瑕佸埛鏂板鎵樺垪琛� + huaxin_trade_data_update.add_delegate_list("涔版垚浜�") + need_cancel = TradeResultProcessor.process_buy_order(order) + # if need_cancel: + # # 闇�瑕佹挙涔板崟 + # threading.Thread(target=lambda: cancel_order(TRADE_DIRECTION_SELL, order.code, order.orderSysID), + # daemon=True).start() + need_watch_cancel = TradeResultProcessor.process_sell_order(order) + # if need_watch_cancel: + # # 闇�瑕佹挙鍗栧崟 + # threading.Thread(target=lambda: __cancel_order(order.code, order.orderRef), daemon=True).start() + finally: + try: + # 鍔犲叆2娆★紝澧炲ぇ鍔犲叆鎴愬姛鐜� + __save_data_queue.put_nowait(data) + except Exception as e: + hx_logger_trade_debug.exception(e) + + if not is_shadow_order: + # 璁㈠崟鐩稿叧鍥炶皟 + # 閲嶆柊璇锋眰濮旀墭鍒楄〃涓庤祫閲� + # huaxin_trade_data_update.add_delegate_list("鏉ヨ嚜浜ゆ槗绠¢亾") + huaxin_trade_data_update.add_deal_list() + huaxin_trade_data_update.add_money_list() + + # 璁剧疆缁撴灉 + def __set_response(data_json): + if 'request_id' not in data_json: + return + # 澶勭悊鏁版嵁 + async_log_util.info(hx_logger_trade_callback, f"response锛歳equest_id-{data_json['request_id']}") + # 璁剧疆鍝嶅簲鍐呭 + set_response(data_json["request_id"], data_json['data']) + + logger_system.info(f"huaxin_trade_api __run_recv_pipe_trade 绾跨▼ID:{tool.get_thread_id()}") + + if queue is not None: + while True: + try: + val = queue.get() + if val: + data_json = json.loads(val) + # 澶勭悊鏁版嵁 + type_ = data_json["type"] + if type_ == "response": + # 涓诲姩瑙﹀彂鐨勫搷搴� + request_id = data_json['request_id'] + async_log_util.info(hx_logger_trade_callback, + f"response锛歳equest_id-{request_id}") + __response_thread_pool.submit(__set_response, data_json) + if type(data_json.get("data")) == dict: + data = data_json["data"].get("data") + if type(data) == dict and "orderRef" in data: + __response_thread_pool.submit(__process_order, data) + elif type_ == "trade_callback": + try: + # 浜ゆ槗鍥炶皟 + data_json = data_json["data"] + ctype = data_json["type"] + # 璁板綍浜ゆ槗鍙嶉鏃ュ織 + async_log_util.info(hx_logger_trade_callback, f"{data_json}") + if ctype == 0: + data = data_json.get("data") + # 鑾峰彇璁㈠崟鐘舵�� + __process_order(data) + finally: + pass + except: + pass + + +def __create_trade_ipc_context(trade_ipc_addr): + """ + 鍒涘缓IPC鍙戦�佺鍙� + @param trade_ipc_addr:锛堜笅鍗曞湴鍧�,鎾ゅ崟鍦板潃锛� + @return: + """ + context = zmq.Context() + global order_socket, cancel_order_socket + order_socket = context.socket(zmq.REQ) + order_socket.connect(trade_ipc_addr[0]) + cancel_order_socket = context.socket(zmq.REQ) + cancel_order_socket.connect(trade_ipc_addr[1]) + # while True: + # try: + # # datas = ('000990', 7.52, 400, 93000030, 2012, 380422, 380421, 375477, '1') * 150 + # # L2SharedMemoryDataUtil.set_data(datas, shared_memory) + # socket.send_json({'data': [], "time": time.time()}) + # response = socket.recv_string() + # except Exception as e: + # logging.exception(e) + + +# 涓嬪崟ZMQ閫氫俊閿� +__order_zmq_lock = threading.Lock() + + +def __order_by_zmq(data_json): + """ + 閫氳繃zmq鍙戦�佷笅鍗曚俊鎭� + @param data_json: + @return: + """ + with __order_zmq_lock: + order_socket.send_json(data_json) + response = order_socket.recv_string() + + +def __cancel_order_by_zmq(data_json): + cancel_order_socket.send_json(data_json) + response = cancel_order_socket.recv_string() + + +def __test_order(): + time.sleep(60) + for i in range(20): + time.sleep(30) + order_ref = huaxin_util.create_order_ref() + order(1, "000333", 100, 1.00, price_type=2, blocking=False, order_ref=order_ref, shadow_price=0.99) + time.sleep(30) + cancel_order(1, "000333", '123123', orderRef=order_ref, blocking=False) + + +def run(): + queue_strategy_r_trade_w, queue_strategy_w_trade_r, queue_strategy_w_trade_r_for_read = multiprocessing.Queue(), multiprocessing.Queue(), multiprocessing.Queue() + order_ipc_addr, cancel_order_ipc_addr = "ipc://trade_order_ls.ipc", "ipc://trade_order_ls_cancel.ipc" + trade_process = multiprocessing.Process( + target=trade_client.run, + args=(order_ipc_addr, cancel_order_ipc_addr, queue_strategy_r_trade_w, queue_strategy_w_trade_r, + queue_strategy_w_trade_r_for_read)) + trade_process.start() + + t1 = threading.Thread(target=lambda: __run_recv_queue_trade(queue_strategy_r_trade_w), daemon=True) + t1.start() + t1 = threading.Thread(target=lambda: __run_save_data(), daemon=True) + t1.start() + t1 = threading.Thread(target=lambda: CancelOrderManager().run(cancel_order), daemon=True) + t1.start() + # 鍒涘缓IPC鍙戦�佺鍙� + __create_trade_ipc_context(order_ipc_addr) + + +# 浜ゆ槗閫氶亾鐨勯敊璇鏁� +trade_pipe_channel_error_count = 0 + + +# pipe鐨勪氦鏄撻�氶亾鏄惁姝e父 +def is_pipe_channel_normal(): + return True + + +# 娴嬭瘯浜ゆ槗閫氶亾 +def test_trade_channel(): + global trade_pipe_channel_error_count + sid = random.randint(0, 1000000) + result = __test_trade_channel(sid) + if result["code"] == 0 and result["data"]["data"]["sid"] == sid: + trade_pipe_channel_error_count = 0 + return True + trade_pipe_channel_error_count += 1 + if trade_pipe_channel_error_count > 100: + trade_pipe_channel_error_count = 100 + return False + + +class ClientSocketManager: + # 瀹㈡埛绔被鍨� + CLIENT_TYPE_TRADE = "trade" + CLIENT_TYPE_DELEGATE_LIST = "delegate_list" + CLIENT_TYPE_DEAL_LIST = "deal_list" + CLIENT_TYPE_POSITION_LIST = "position_list" + CLIENT_TYPE_MONEY = "money" + CLIENT_TYPE_DEAL = "deal" + CLIENT_TYPE_CMD_L2 = "l2_cmd" + socket_client_dict = {} + socket_client_lock_dict = {} + active_client_dict = {} + + @classmethod + def list_client(cls, _type): + if _type == cls.CLIENT_TYPE_TRADE: + if _type in cls.socket_client_dict: + return cls.socket_client_dict.get(_type) + else: + if _type in cls.socket_client_dict: + return [cls.socket_client_dict.get(_type)] + return [] + + @classmethod + def add_client(cls, _type, rid, sk): + if _type == cls.CLIENT_TYPE_TRADE: + # 浜ゆ槗鍒楄〃 + if _type not in cls.socket_client_dict: + cls.socket_client_dict[_type] = [] + cls.socket_client_dict[_type].append((rid, sk)) + cls.socket_client_lock_dict[rid] = threading.Lock() + hx_logger_trade_debug.info(f"add_client:{rid}") + else: + cls.socket_client_dict[_type] = (rid, sk) + cls.socket_client_lock_dict[rid] = threading.Lock() + + # 鏄惁宸茬粡琚攣浣� + @classmethod + def is_client_locked(cls, rid): + if rid in cls.socket_client_lock_dict: + return cls.socket_client_lock_dict[rid].locked() + return None + + @classmethod + def acquire_client(cls, _type): + if _type == cls.CLIENT_TYPE_TRADE: + if _type in cls.socket_client_dict: + # 鏍规嵁鎺掑簭娲昏穬鏃堕棿鎺掑簭 + client_list = sorted(cls.socket_client_dict[_type], key=lambda x: cls.active_client_dict.get(x[0]) if x[ + 0] in cls.active_client_dict else 0, + reverse=True) + hx_logger_trade_debug.info(f"acquire_client client_list鏁伴噺锛歿len(client_list)}") + hx_logger_trade_debug.info( + f"acquire_client socket_client_lock_dict鏁伴噺锛歿len(cls.socket_client_lock_dict.keys())}") + for d in client_list: + if d[0] in cls.socket_client_lock_dict: + try: + if cls.socket_client_lock_dict[d[0]].acquire(blocking=False): + hx_logger_trade_debug.info(f"acquire_client success:{d[0]}") + return d + except threading.TimeoutError: + hx_logger_trade_debug.error("acquire_client TimeoutError") + else: + if _type in cls.socket_client_dict: + try: + d = cls.socket_client_dict[_type] + if d[0] in cls.socket_client_lock_dict: + if cls.socket_client_lock_dict[d[0]].acquire(blocking=False): + return d + except threading.TimeoutError: + pass + return None + + @classmethod + def release_client(cls, client_id): + sucess = False + if client_id in cls.socket_client_lock_dict: + sucess = True + # 閲婃斁閿� + if cls.socket_client_lock_dict[client_id].locked(): + cls.socket_client_lock_dict[client_id].release() + if sucess: + hx_logger_trade_debug.info(f"release_client success:{client_id}") + else: + hx_logger_trade_debug.info(f"release_client fail:{client_id}") + + @classmethod + def del_client(cls, rid): + # 鍒犻櫎绾跨▼閿� + if rid in cls.socket_client_lock_dict: + cls.socket_client_lock_dict.pop(rid) + # 鍒犻櫎sk + for t in cls.socket_client_dict: + if type(cls.socket_client_dict[t]) == list: + for d in cls.socket_client_dict[t]: + if d[0] == rid: + try: + # 鍏抽棴socket + d[1].close() + except: + pass + cls.socket_client_dict[t].remove(d) + break + + elif type(cls.socket_client_dict[t]) == tuple: + if cls.socket_client_dict[t][0] == rid: + try: + # 鍏抽棴socket + cls.socket_client_dict[t][1].close() + except: + pass + cls.socket_client_dict.pop(t) + break + + # 蹇冭烦淇℃伅 + @classmethod + def heart(cls, rid): + cls.active_client_dict[rid] = time.time() + + @classmethod + def del_invalid_clients(cls): + # 娓呴櫎闀挎椂闂存棤蹇冭烦鐨勫鎴风閫氶亾 + for k in cls.active_client_dict.keys(): + if time.time() - cls.active_client_dict[k] > 20: + # 蹇冭烦鏃堕棿闂撮殧20s浠ヤ笂瑙嗕负鏃犳晥 + cls.del_client(k) + + +TRADE_DIRECTION_BUY = 1 +TRADE_DIRECTION_SELL = 2 + +# 瓒呮椂鏃堕棿2s +TIMEOUT = 2.0 + +# 绛夊緟鍝嶅簲鐨剅equest_id +__request_response_dict = {} + + +def __get_request_id(type): + return f"r_{type}_{round(time.time() * 10000)}_{random.randint(0, 100000)}" + + +# 缃戠粶璇锋眰 +def __request(_type, data, request_id=None, log_enable=True, is_trade=False): + """ + 璇锋眰锛屽皢浜ゆ槗锛堝寘鍚笅鍗�/鎾ゅ崟锛変笌鏌ヨ锛堝寘鍚煡鎸佷粨/璐︽埛鍙敤閲戦/濮旀墭鍒楄〃/鎴愪氦鍒楄〃锛夐槦鍒楀垎绂� + @param _type: + @param data: + @param request_id: + @param log_enable: + @param is_trade: + @return: + """ + if not request_id: + request_id = __get_request_id(_type) + try: + if log_enable: + async_log_util.info(hx_logger_trade_loop, "璇锋眰鍙戦�佸紑濮嬶細client_id-{} request_id-{}", 0, request_id) + root_data = {"type": _type, + "data": data, + "request_id": request_id, + "time": time.time() + } + root_data = socket_util.encryp_client_params_sign(root_data) + start_time = time.time() + if is_trade: + # queue_strategy_w_trade_r.put_nowait(root_data) + # 閲囩敤zmq閫氫俊 + if data['trade_type'] == 1: + __order_by_zmq(root_data) + elif data['trade_type'] == 2: + __cancel_order_by_zmq(root_data) + else: + queue_strategy_w_trade_r.put_nowait(root_data) + else: + queue_strategy_w_trade_r_for_read.put_nowait(root_data) + + use_time = int((time.time() - start_time) * 1000) + if use_time > 10: + async_log_util.info(hx_logger_trade_loop, f"鍙戦�佽�楁椂锛歳equest_id-{request_id} 鑰楁椂鏃堕棿锛歿use_time}") + if log_enable: + async_log_util.info(hx_logger_trade_loop, "璇锋眰鍙戦�佹垚鍔燂細request_id-{}", request_id) + except BrokenPipeError as e: + async_log_util.info(hx_logger_trade_loop, "璇锋眰鍙戦�佸紓甯革細request_id-{} error-{}", request_id, str(e)) + raise e + except Exception as e: + async_log_util.info(hx_logger_trade_loop, "璇锋眰鍙戦�佸紓甯革細 request_id-{} error-{}", request_id, str(e)) + logging.exception(e) + raise e + return request_id + + +def __read_response(request_id, blocking, timeout=TIMEOUT, log_enable=True): + if blocking: + start_time = time.time() + try: + while True: + time.sleep(0.005) + if request_id in __request_response_dict: + # 鑾峰彇鍒颁簡鍝嶅簲鍐呭 + result = __request_response_dict.pop(request_id) + if log_enable: + async_log_util.info(hx_logger_trade_loop, "璇锋眰璇诲彇鎴愬姛锛� request_id-{}", request_id) + return result + if time.time() - start_time > timeout: + if log_enable: + async_log_util.info(hx_logger_trade_loop, "璇锋眰璇诲彇瓒呮椂锛� request_id-{}", request_id) + # 璇诲彇鍐呭瓒呮椂鎵嶄細閲婃斁 + raise Exception(f"璇诲彇鍐呭瓒呮椂: request_id={request_id}") + finally: + pass + + return None + + +__TradeOrderIdManager = TradeOrderIdManager() + + +def set_response(request_id, response): + if request_id: + async_log_util.info(hx_logger_trade_loop, f"璇锋眰鍝嶅簲: request_id-{request_id} 鍐呭-{response}") + # 涓诲姩瑙﹀彂 + __request_response_dict[request_id] = response + else: + # 琚姩瑙﹀彂 + pass + + +def order(direction, code, volume, price, price_type=2, blocking=False, sinfo=None, request_id=None, + order_ref=None, shadow_price=None, shadow_volume=100): + """ + 涓嬪崟濮旀墭 + @param shadow_volume: 褰卞瓙鍗曠殑閲� + @param direction: 1-涔� 2-鍗� + @param code: + @param volume:浜ゆ槗閲� + @param price:浠锋牸锛堝鏋滄槸鍗栨椂涓嶄紶浠锋牸灏辨寜鐓�5鎸′环鍗栵級 + @param price_type: + @param blocking:鏄惁闃诲杩涚▼ + @param sinfo: + @param request_id: + @param order_ref: + @param shadow_price: + @return: + """ + timestamp = round(time.time() * 1000) + if not sinfo: + sinfo = f"ba_{code}_{timestamp}" + if not order_ref: + order_ref = huaxin_util.create_order_ref() + if not request_id: + request_id = __get_request_id(ClientSocketManager.CLIENT_TYPE_TRADE) + for i in range(1): + cancel_shadow = True + if int(tool.get_now_time_str().replace(":", "")) < int("091500"): + # 棰勫煁鍗曚笉鑳芥挙褰卞瓙鍗� + cancel_shadow = False + request_id = __request(ClientSocketManager.CLIENT_TYPE_TRADE, + {"type": ClientSocketManager.CLIENT_TYPE_TRADE, "trade_type": 1, + "direction": direction, + "code": code, + "order_ref": order_ref, + "volume": volume, + "price_type": price_type, + "price": price, + "shadow_price": shadow_price, + "shadow_volume": shadow_volume, + "sinfo": sinfo, + "blocking": blocking, + "cancel_shadow": cancel_shadow}, + request_id=request_id, + is_trade=True) + try: + if blocking: + return __read_response(request_id, blocking) + else: + return {"order_ref": order_ref} + finally: + # huaxin_trade_data_update.add_delegate_list("涓嬪崟", delay=0.2) + huaxin_trade_data_update.add_money_list() + + +def order_new(direction, code, order_info_list, price_type=2, blocking=False, sinfo=None, request_id=None): + """ + 涓嬪崟濮旀墭 + @param direction: + @param code: + @param order_info_list: 涓嬪崟淇℃伅锛歔(閲�,浠�, order_ref),(閲�,浠�, order_ref)] + @param price_type: + @param blocking: 鏄惁闃诲杩涚▼ + @param sinfo: + @param request_id: + @return: + """ + timestamp = round(time.time() * 1000) + if not sinfo: + sinfo = f"ba_{code}_{timestamp}" + if not request_id: + request_id = __get_request_id(ClientSocketManager.CLIENT_TYPE_TRADE) + for i in range(1): + request_id = __request(ClientSocketManager.CLIENT_TYPE_TRADE, + {"type": ClientSocketManager.CLIENT_TYPE_TRADE, "trade_type": 1, + "direction": direction, + "code": code, + "order_info_list": order_info_list, + "price_type": price_type, + "sinfo": sinfo, + "blocking": blocking, + "cancel_shadow": False}, + request_id=request_id, + is_trade=True) + try: + if blocking: + return __read_response(request_id, blocking) + else: + return {"order_ref_list": [x[2] for x in order_info_list]} + finally: + # huaxin_trade_data_update.add_delegate_list("涓嬪崟", delay=0.2) + huaxin_trade_data_update.add_money_list() + + +__canceling_order_dict = {} + + +def cancel_order(direction, code, orderSysID, orderRef=None, blocking=False, sinfo=None, request_id=None, + recancel=False): + """ + 娴嬪崟 + @param direction: 1-涔� 2-鍗� + @param code: + @param orderSysID: + @param orderRef: + @param blocking: + @param sinfo: + @param request_id: + @param recancel: + @return: + """ + if tool.trade_time_sub(tool.get_now_time_str(), "14:57:00") >= 0 and tool.trade_time_sub(tool.get_now_time_str(), + "15:00:01") <= 0: + # 闆嗗悎绔炰环涓嶆挙鍗� + return + + if not recancel: + CancelOrderManager().start_cancel(code, orderRef, orderSysID) + if not sinfo: + sinfo = f"cb_{code}_{round(time.time() * 1000)}_{random.randint(0, 10000)}" + order_action_ref = huaxin_util.create_order_ref() + if not request_id: + request_id = __get_request_id(ClientSocketManager.CLIENT_TYPE_TRADE) + # 鍔犲叆鎾ゅ崟璁板綍锛岀敤浜庢牎楠屾渶鍚庣殑鎾ゅ崟鏄惁鎴愬姛 + if code not in __canceling_order_dict: + __canceling_order_dict[code] = set() + __canceling_order_dict[code].add(json.dumps((orderRef, orderSysID))) + # 鎵ц2娆℃挙鍗曪紝闃叉娌℃湁鎾ゅ埌 + for i in range(2): + request_id = __request(ClientSocketManager.CLIENT_TYPE_TRADE, + {"type": ClientSocketManager.CLIENT_TYPE_TRADE, "trade_type": 2, + "direction": direction, + "code": code, + "orderRef": orderRef, + "orderActionRef": order_action_ref, + "orderSysID": orderSysID, "sinfo": sinfo}, request_id=request_id, is_trade=True) + try: + return __read_response(request_id, blocking) + finally: + huaxin_trade_data_update.add_money_list() + + +def batch_cancel_order(direction, code, orderInfos: list, blocking=False, + request_id=None, + recancel=False): + """ + 娴嬪崟 + @param direction: 1-涔� 2-鍗� + @param code: + @param orderInfos:[(orderRef, orderSysID)] + @param blocking: + @param request_id: + @param recancel: + @return: + """ + if tool.trade_time_sub(tool.get_now_time_str(), "14:57:00") >= 0 and tool.trade_time_sub(tool.get_now_time_str(), + "15:00:01") <= 0: + # 闆嗗悎绔炰环涓嶆挙鍗� + return + + if not recancel: + for orderInfo in orderInfos: + CancelOrderManager().start_cancel(code, orderInfo[0], orderInfo[1]) + sinfos = [] + for i in range(len(orderInfos)): + sinfo = f"cb_{code}_{round(time.time() * 1000)}_{random.randint(0, 10000)}_{i}" + sinfos.append(sinfo) + order_action_refs = [] + for i in range(len(orderInfos)): + order_action_ref = huaxin_util.create_order_ref() + order_action_refs.append(order_action_ref) + if not request_id: + request_id = __get_request_id(ClientSocketManager.CLIENT_TYPE_TRADE) + # 鍔犲叆鎾ゅ崟璁板綍锛岀敤浜庢牎楠屾渶鍚庣殑鎾ゅ崟鏄惁鎴愬姛 + if code not in __canceling_order_dict: + __canceling_order_dict[code] = set() + for orderInfo in orderInfos: + __canceling_order_dict[code].add(json.dumps((orderInfo[0], orderInfo[1]))) + # 鎵ц2娆℃挙鍗曪紝闃叉娌℃湁鎾ゅ埌 + for i in range(2): + request_id = __request(ClientSocketManager.CLIENT_TYPE_TRADE, + {"type": ClientSocketManager.CLIENT_TYPE_TRADE, "trade_type": 2, + "direction": direction, + "code": code, + "orderInfos": orderInfos, + "orderActionRefs": order_action_refs, + "sinfos": sinfos}, request_id=request_id, is_trade=True) + try: + return __read_response(request_id, blocking) + finally: + huaxin_trade_data_update.add_money_list() + + +# CLIENT_TYPE_DELEGATE_LIST = "delegate_list" +# CLIENT_TYPE_DEAL_LIST = "deal_list" +# CLIENT_TYPE_POSITION_LIST = "position_list" +# CLIENT_TYPE_MONEY = "money" +# CLIENT_TYPE_DEAL = "deal" + +# 鑾峰彇濮旀墭鍒楄〃 +# can_cancel:鏄惁鍙互鎾� +def get_delegate_list(can_cancel=True, blocking=True, timeout=TIMEOUT): + request_id = __request(ClientSocketManager.CLIENT_TYPE_DELEGATE_LIST, + {"type": ClientSocketManager.CLIENT_TYPE_DELEGATE_LIST, + "can_cancel": 1 if can_cancel else 0}) + + return __read_response(request_id, blocking, timeout=timeout) + + +# 鑾峰彇鎴愪氦鍒楄〃 +def get_deal_list(blocking=True, timeout=TIMEOUT): + request_id = __request(ClientSocketManager.CLIENT_TYPE_DEAL_LIST, + {"type": ClientSocketManager.CLIENT_TYPE_DEAL_LIST}) + return __read_response(request_id, blocking, timeout=timeout) + + +# 鑾峰彇鎸佷粨鍒楄〃 +def get_position_list(blocking=True): + request_id = __request(ClientSocketManager.CLIENT_TYPE_POSITION_LIST, + {"type": ClientSocketManager.CLIENT_TYPE_POSITION_LIST}) + return __read_response(request_id, blocking) + + +# 鑾峰彇璐︽埛璧勯噾鐘跺喌 +def get_money(blocking=True): + request_id = __request(ClientSocketManager.CLIENT_TYPE_MONEY, + {"type": ClientSocketManager.CLIENT_TYPE_MONEY}) + return __read_response(request_id, blocking) + + +# 璁剧疆L2璁㈤槄鏁版嵁 +def set_l2_codes_data(codes_data, blocking=True): + request_id = __request(ClientSocketManager.CLIENT_TYPE_CMD_L2, + {"type": ClientSocketManager.CLIENT_TYPE_CMD_L2, "data": codes_data}) + return __read_response(request_id, blocking) + + +# 璁剧疆L2璁㈤槄鏁版嵁 +def __test_trade_channel(sid): + request_id = __request("test", + {"type": "test", "data": {"sid": sid}}, log_enable=False) + return __read_response(request_id, True, log_enable=False) + + +def parseResponse(data_str): + if not data_str: + raise Exception("鍙嶉鍐呭涓虹┖") + res = data_str + if type(res) == str: + res = json.loads(data_str) + res = res['data'] + if res['code'] != 0: + raise Exception(res['msg']) + return res['data'] + + +if __name__ == "__main__": + pass diff --git a/trade/huaxin/huaxin_trade_data_update.py b/trade/huaxin/huaxin_trade_data_update.py new file mode 100644 index 0000000..959b5f2 --- /dev/null +++ b/trade/huaxin/huaxin_trade_data_update.py @@ -0,0 +1,138 @@ +""" +鍗庨懌浜ゆ槗鏁版嵁鏇存柊 +""" +import logging +import queue +import threading +import time + +from log_module import async_log_util +from log_module.log import hx_logger_trade_debug, logger_system, logger_debug +from trade import trade_manager, trade_data_manager +from trade.huaxin import huaxin_trade_api, huaxin_trade_record_manager + +from utils import huaxin_util +import concurrent.futures + +trade_data_request_queue = queue.Queue(maxsize=1000) +__process_thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=10) + + +# 涓诲姩鏇存柊鏁版嵁 +def __read_update_task_queue(): + logger_system.info("鍚姩璇诲彇浜ゆ槗鏁版嵁鏇存柊闃熷垪") + while True: + try: + data = trade_data_request_queue.get() + if data: + type_ = data["type"] + delay = data.get("delay") + if delay and delay > 0: + time.sleep(delay) + async_log_util.info(hx_logger_trade_debug, f"鑾峰彇浜ゆ槗鏁版嵁寮�濮嬶細{type_}") + try: + if type_ == "delegate_list": + dataJSON = huaxin_trade_api.get_delegate_list(can_cancel=False, timeout=10) + if dataJSON["code"] == 0: + data = dataJSON["data"] + __process_thread_pool.submit(huaxin_trade_record_manager.DelegateRecordManager.add, data) + + elif type_ == "money": + dataJSON = huaxin_trade_api.get_money() + if dataJSON["code"] == 0: + data = dataJSON["data"] + huaxin_trade_record_manager.MoneyManager.save_data(data) + if data: + usefulMoney = data[0]["usefulMoney"] + commission = data[0]["commission"] + # 璁剧疆鍙敤璧勯噾 + trade_data_manager.AccountMoneyManager().set_available_money(0, usefulMoney) + trade_data_manager.AccountMoneyManager().set_commission(commission) + # 璁剧疆鍙敤璧勯噾 + elif type_ == "deal_list": + dataJSON = huaxin_trade_api.get_deal_list(timeout=10) + print("鎴愪氦鍝嶅簲锛�", dataJSON) + if dataJSON["code"] == 0: + datas = dataJSON["data"] + if datas is None: + datas = [] + try: + buy_deal_codes = set() + for d in datas: + if str(d['direction']) == str(huaxin_util.TORA_TSTP_D_Buy): + buy_deal_codes.add(d['securityID']) + except Exception as e: + logger_debug.exception(e) + huaxin_trade_record_manager.DealRecordManager.add(datas) + if datas: + tempList = [ + {"time": d["tradeTime"], "type": int(d['direction']), "code": d['securityID']} + for d in datas] + try: + trade_manager.process_trade_success_data(tempList) + except Exception as e: + logging.exception(e) + # 鎸佷粨鑲� + elif type_ == "position_list": + dataJSON = huaxin_trade_api.get_position_list() + if dataJSON["code"] == 0: + datas = dataJSON["data"] + huaxin_trade_record_manager.PositionManager.cache(datas) + __process_thread_pool.submit(huaxin_trade_record_manager.PositionManager.add, datas) + async_log_util.info(hx_logger_trade_debug, f"鑾峰彇浜ゆ槗鏁版嵁鎴愬姛锛歿type_}") + except Exception as e1: + # if str(e1).find("瓒呮椂") >= 0: + # # 璇诲彇缁撴灉瓒呮椂闇�瑕侀噸鏂拌姹� + # trade_data_request_queue.put_nowait({"type": type_}) + raise e1 + except Exception as e: + hx_logger_trade_debug.exception(e) + finally: + # 鏈�0.1s鐨勯棿闅� + time.sleep(0.01) + + +def get_request_queue_size(): + """ + 鑾峰彇璇锋眰闃熷垪鐨勫ぇ灏� + @return: + """ + return trade_data_request_queue.qsize() + + +def repaire_task(): + """ + 浠诲姟淇 + @return: + """ + queue_size = get_request_queue_size() + if queue_size < 2: + return + threading.Thread(target=lambda: __read_update_task_queue(), daemon=True).start() + + +def __add_data(data): + trade_data_request_queue.put_nowait(data) + + +def add_delegate_list(source, delay=0): + __add_data({"type": "delegate_list", "delay": delay}) + async_log_util.info(hx_logger_trade_debug, f"璇锋眰濮旀墭鍒楄〃锛屾潵婧愶細{source}") + + +def add_deal_list(): + __add_data({"type": "deal_list"}) + + +def add_money_list(delay=0): + __add_data({"type": "money", "delay": delay}) + + +def add_position_list(): + __add_data({"type": "position_list"}) + + +# 杩愯 +def run(): + t1 = threading.Thread(target=lambda: __read_update_task_queue(), daemon=True) + t1.start() diff --git a/trade/huaxin/huaxin_trade_order_processor.py b/trade/huaxin/huaxin_trade_order_processor.py new file mode 100644 index 0000000..2b7606e --- /dev/null +++ b/trade/huaxin/huaxin_trade_order_processor.py @@ -0,0 +1,186 @@ +""" +鍗庨懌浜ゆ槗缁撴灉澶勭悊鍣� +""" +import copy +import json +import time + +from log_module import async_log_util +from log_module.log import logger_trade, hx_logger_trade_debug +from trade.huaxin.huaxin_trade_record_manager import TradeOrderIdManager +from utils import huaxin_util +import concurrent.futures + + +class HuaxinOrderEntity: + def __init__(self, code, orderStatus, orderRef, accountID, orderSysID, direction=None, insertDate=None, + insertTime=None, + acceptTime=None): + self.code = code + self.orderStatus = orderStatus + self.orderRef = orderRef + self.accountID = accountID + self.orderSysID = orderSysID + self.insertTime = insertTime + self.insertDate = insertDate + self.acceptTime = acceptTime + self.direction = direction + + +class CancelOrderManager: + __canceling_order_dict = {} + __recancel_order_count = {} + + __instance = None + + def __new__(cls, *args, **kwargs): + if not cls.__instance: + cls.__instance = super(CancelOrderManager, cls).__new__(cls, *args, **kwargs) + return cls.__instance + + # 寮�濮嬫挙鍗� + def start_cancel(self, code, order_ref, order_sys_id): + if code not in self.__canceling_order_dict: + self.__canceling_order_dict[code] = set() + self.__canceling_order_dict[code].add(json.dumps((order_ref, order_sys_id, int(time.time() * 1000)))) + + def __cancel_finish(self, code, order_ref, order_sys_id): + if code not in self.__canceling_order_dict: + return + if not self.__canceling_order_dict[code]: + return + infos = copy.deepcopy(self.__canceling_order_dict[code]) + for info in infos: + _info = json.loads(info) + if _info[0] == order_ref or _info[1] == order_sys_id: + # 鍖归厤鍒扮洰鏍囨暟鎹� + self.__canceling_order_dict[code].discard(info) + + def __add_recancel_count(self, code, order_ref, order_sys_id): + key = f"{code}_{order_ref}_{order_sys_id}" + if key not in self.__recancel_order_count: + self.__recancel_order_count[key] = 0 + self.__recancel_order_count[key] += 1 + + def __can_recancel(self, code, order_ref, order_sys_id): + key = f"{code}_{order_ref}_{order_sys_id}" + if key not in self.__recancel_order_count: + return True + return self.__recancel_order_count[key] < 2 + + # 鎾ゅ崟鎴愬姛 + def cancel_success(self, code, order_ref, order_sys_id): + self.__cancel_finish(code, order_ref, order_sys_id) + + # 涔板叆鎴愬姛 + def buy_success(self, code, order_ref, order_sys_id): + self.__cancel_finish(code, order_ref, order_sys_id) + + # 浼犲叆閲嶆柊涓嬪崟 + def run(self, re_cancel_method): + while True: + try: + if self.__canceling_order_dict: + for code in self.__canceling_order_dict: + infos = self.__canceling_order_dict[code] + infos = copy.deepcopy(infos) + for info in infos: + _info = json.loads(info) + timestamp = _info[2] + # 鏌ヨ鏄惁杩樿兘閲嶆柊鎾ゅ崟 + if not self.__can_recancel(code, _info[0], _info[1]): + self.__canceling_order_dict[code].discard(info) + continue + + if time.time() * 1000 - timestamp > 100: + async_log_util.info(logger_trade, f"{code}瑙﹀彂閲嶆柊鎾ゅ崟锛歿info}") + # 100ms鍚庢墠杩涜 + self.__add_recancel_count(code, _info[0], _info[1]) + re_cancel_method(1, code, _info[1], orderRef=_info[0], recancel=True) + time.sleep(0.05) + except: + pass + + +class TradeResultProcessor: + __TradeOrderIdManager = TradeOrderIdManager() + __processed_keys = set() + __thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=50) + # 璁㈠崟绱㈠紩鍙峰瓧鍏� + order_ref_dict = {} + + # 澶勭悊涔板崟 + @classmethod + def process_buy_order(cls, order: HuaxinOrderEntity): + """ + 澶勭悊涔板崟 + @param order: + @return: 鏄惁闇�瑕佹挙鍗� + """ + + # 澶勭悊涓嬪崟鎴愬姛 + def process_order_success(order_: HuaxinOrderEntity, delay_s=0.0): + if delay_s > 0: + time.sleep(delay_s) + # TODO 澶勭悊涓嬪崟鎴愬姛 + + # 鍙鐞嗕拱鍏ュ崟 + if order.direction != str(huaxin_util.TORA_TSTP_D_Buy): + return False + + # 鍚屼竴璁㈠崟鍙峰彧鏈夌姸鎬佸彉鍖栦簡鎵嶉渶瑕佸鐞� + key = f"{order.insertDate}_{order.code}_{order.orderSysID}_{order.orderStatus}" + if key in cls.__processed_keys: + return False + try: + async_log_util.info(hx_logger_trade_debug, f"澶勭悊鍗庨懌璁㈠崟锛歿key}") + cls.__processed_keys.add(key) + if huaxin_util.is_can_cancel(order.orderStatus): + # 璁剧疆涓嬪崟鎴愬姛 + process_order_success(order) + elif huaxin_util.is_canceled(order.orderStatus) or huaxin_util.is_deal( + order.orderStatus): + # 宸茬粡鎾ゅ崟/宸茬粡鎴愪氦锛岄渶瑕佸鐞嗕复鏃朵繚瀛樼殑绯荤粺璁㈠崟鍙� + cls.__TradeOrderIdManager.remove_order_id(order.code, + order.accountID, + order.orderSysID) + if huaxin_util.is_deal(order.orderStatus): + # TODO 澶勭悊鎴愪氦 + pass + elif huaxin_util.is_canceled(order.orderStatus): + CancelOrderManager().cancel_success(order.code, order.orderRef, order.orderSysID) + except Exception as e: + async_log_util.exception(hx_logger_trade_debug, e) + return False + + @classmethod + def get_huaxin_order_by_order_ref(cls, order_ref) -> HuaxinOrderEntity: + return cls.order_ref_dict.get(order_ref) + + @classmethod + def get_huaxin_sell_order_by_code(cls, code): + results = [] + for k in cls.order_ref_dict: + entity = cls.order_ref_dict[k] + if entity.code == code and entity.direction == huaxin_util.TORA_TSTP_D_Sell: + results.append(entity) + return results + + @classmethod + def order_success(cls, order: HuaxinOrderEntity): + async_log_util.info(hx_logger_trade_debug, f"澶勭悊鍗庨懌璁㈠崟涓嬪崟鎴愬姛锛歿order.code}, {order.orderRef}, {order.orderSysID}") + # 鍔犲叆绯荤粺璁㈠崟鍙� + cls.__TradeOrderIdManager.add_order_id(order.code, order.accountID, order.orderSysID) + # 鍒犻櫎涓存椂璁㈠崟鍙� + cls.__TradeOrderIdManager.remove_order_ref(order.code, order.orderRef) + return None + + @classmethod + def cancel_order_success(cls, code, accountId, orderSysID): + cls.__TradeOrderIdManager.remove_order_id(code, accountId, orderSysID) + + +if __name__ == "__main__": + CancelOrderManager().start_cancel("000333", 1, "123123") + # CancelOrderManager().cancel_success("000333", 1, "123123") + # CancelOrderManager().buy_success("000333", 1, "123123") diff --git a/trade/huaxin/huaxin_trade_record_manager.py b/trade/huaxin/huaxin_trade_record_manager.py new file mode 100644 index 0000000..a48f811 --- /dev/null +++ b/trade/huaxin/huaxin_trade_record_manager.py @@ -0,0 +1,488 @@ +""" +鍗庡叴浜ゆ槗璁板綍 +""" + +# 濮旀墭璁板綍 +import copy +import datetime +import json + +from db.redis_manager_delegate import RedisUtils, RedisManager +from utils import tool, huaxin_util +from db import mysql_data_delegate as mysql_data, redis_manager_delegate as redis_manager +from third_data.history_k_data_util import HistoryKDatasUtils + + +# 濮旀墭鍒楄〃 +class DelegateRecordManager: + # 褰撳墠澶勪簬濮旀墭鐘舵�佺殑鏁版嵁 + __current_delegate_records_dict_cache = {} + mysqldb = mysql_data.Mysqldb() + __instance = None + + def __new__(cls, *args, **kwargs): + if not cls.__instance: + cls.__instance = super(DelegateRecordManager, cls).__new__(cls, *args, **kwargs) + cls.__load_data() + return cls.__instance + + @classmethod + def __load_data(cls): + fresults, max_update_time = cls.list_by_day(tool.get_now_date_str("%Y%m%d"), None, + orderStatus=[huaxin_util.TORA_TSTP_OST_Cached, + huaxin_util.TORA_TSTP_OST_Accepted]) + cls.__current_delegate_records_dict_cache.clear() + for d in fresults: + cls.__current_delegate_records_dict_cache[d['orderSysID']] = d + + # 鑾峰彇褰撳墠澶勪簬濮旀墭鐘舵�佺殑璁㈠崟 + def list_current_delegates(self, code=None): + if self.__current_delegate_records_dict_cache: + fresults = [] + for k in self.__current_delegate_records_dict_cache: + item = self.__current_delegate_records_dict_cache[k] + if code and item["securityID"] != code: + continue + fresults.append(item) + return fresults + return None + + @classmethod + def add(cls, datas): + try: + if datas: + for d in datas: + cls.add_one(d) + finally: + pass + + @classmethod + def add_one(cls, d): + if huaxin_util.is_can_cancel(str(d["orderStatus"])): + cls.__current_delegate_records_dict_cache[d['orderSysID']] = d + else: + if d['orderSysID'] in cls.__current_delegate_records_dict_cache: + cls.__current_delegate_records_dict_cache.pop(d['orderSysID']) + # 鏌ヨ鏄惁鏈夋暟鎹� + _id = f"{d['insertDate']}-{d['orderLocalID']}" + result = cls.mysqldb.select_one( + f"select * from hx_trade_delegate_record where id='{_id}'") + if not result: + # 鏂板鏁版嵁 + nameDict = HistoryKDatasUtils.get_gp_codes_names([d['securityID']]) + name = nameDict.get(d['securityID']) + cls.mysqldb.execute( + "insert into hx_trade_delegate_record values('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s', '%s', '%s')" % ( + _id, d["orderLocalID"], d["securityID"], name, d["direction"], + d["orderSysID"], d["insertTime"], d["insertDate"], d["acceptTime"], d["cancelTime"], + d["limitPrice"], d["turnover"], d["volume"], d["volumeTraded"], d["orderStatus"], + d["orderSubmitStatus"], d["statusMsg"], tool.get_now_datetime_str(), + tool.get_now_datetime_str(), d["accountID"], d["orderRef"], d["sinfo"])) + else: + # 淇敼鏁版嵁 + updateDict = {} + if result[5] != d['orderSysID']: + updateDict['orderSysID'] = d['orderSysID'] + if result[8] != d['acceptTime']: + updateDict['acceptTime'] = d['acceptTime'] + if result[9] != d['cancelTime']: + updateDict['cancelTime'] = d['cancelTime'] + if result[11] != str(d['turnover']): + updateDict['turnover'] = d['turnover'] + if result[13] != d['volumeTraded']: + updateDict['volumeTraded'] = d['volumeTraded'] + if result[14] != int(d['orderStatus']): + updateDict['orderStatus'] = d['orderStatus'] + if result[15] != int(d['orderSubmitStatus']): + updateDict['orderSubmitStatus'] = d['orderSubmitStatus'] + if result[16] != d['statusMsg']: + updateDict['statusMsg'] = d['statusMsg'] + if result[20] != d['orderRef']: + updateDict['orderRef'] = d['orderRef'] + if result[21] != d['sinfo']: + updateDict['sinfo'] = d['sinfo'] + if updateDict: + # 鏈夋洿鏂版暟鎹� + updateDict['updateTime'] = tool.get_now_datetime_str() + where_list = [] + for k in updateDict: + if type(updateDict[k]) == str: + where_list.append(f"{k}='{updateDict[k]}'") + else: + where_list.append(f"{k}={updateDict[k]}") + cls.mysqldb.execute( + f"update hx_trade_delegate_record set {','.join(where_list)} where id='{result[0]}'") + + @classmethod + def list_by_day(cls, day, min_update_time, orderStatus=[]): + mysqldb = mysql_data.Mysqldb() + try: + where_list = [f"r.insertDate='{day}'"] + if min_update_time: + where_list.append(f"updateTime > '{min_update_time}'") + if orderStatus: + ss = " or ".join([f"orderStatus = {k}" for k in orderStatus]) + where_list.append(f"({ss})") + results = mysqldb.select_all( + f"select * from hx_trade_delegate_record r where {' and '.join(where_list)} order by createTime") + # 杞琩ict + key_list = ["id", "orderLocalID", "securityID", "securityName", "direction", "orderSysID", "insertTime", + "insertDate", "acceptTime", "cancelTime", "limitPrice", "turnover", "volume", "volumeTraded", + "orderStatus", "orderSubmitStatus", "statusMsg", "createTime", "updateTime", "accountID", + "orderRef", "sinfo"] + fresults = [] + max_update_time = None + if results: + for r in results: + + temp = {} + for i in range(len(r)): + if type(r[i]) == datetime.datetime: + temp[key_list[i]] = r[i].strftime("%Y-%m-%d %H:%M:%S") + else: + temp[key_list[i]] = r[i] + fresults.append(temp) + if not max_update_time: + max_update_time = temp["updateTime"] + if r[18] > max_update_time: + max_update_time = temp["updateTime"] + return fresults, max_update_time + finally: + pass + + +# 鎸佷粨璁板綍 +class PositionManager: + __redisManager = redis_manager.RedisManager(2) + latest_positions = [] + + @classmethod + def __get_redis(cls): + return cls.__redisManager.getRedis() + + # 淇濆瓨浠g爜鐨勯噺 + @classmethod + def __save_code_volume(cls, code, volume): + RedisUtils.setex(cls.__get_redis(), f"available_position_{code}", tool.get_expire(), f"{volume}") + + @classmethod + def get_code_volume(cls, code): + val = RedisUtils.get(cls.__get_redis(), f"available_position_{code}") + if not val: + return 0 + return int(val) + + @classmethod + def cache(cls, datas): + cls.latest_positions = copy.deepcopy(datas) + + @classmethod + def add(cls, datas): + mysqldb = mysql_data.Mysqldb() + try: + if datas: + # 缁熻鍙敤閲� + volume_dict = {} + for d in datas: + if d["securityID"] not in volume_dict: + volume_dict[d["securityID"]] = 0 + volume_dict[d["securityID"]] = volume_dict[d["securityID"]] + d["availablePosition"] + for k in volume_dict: + cls.__save_code_volume(k, volume_dict[k]) + + for d in datas: + _id = f"{d['investorID']}-{d['tradingDay']}-{d['securityID']}" + # 鏌ヨ鏄惁鏈夋暟鎹� + result = mysqldb.select_one( + f"select * from hx_trade_position where id='{_id}'") + if not result: + # 鏂板鏁版嵁 + mysqldb.execute( + "insert into hx_trade_position values('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')" % ( + _id, d["investorID"], d["tradingDay"], d["securityName"], d["securityID"], + d["historyPos"], d["historyPosFrozen"], d["todayBSPos"], d["todayBSPosFrozen"], + d["historyPosPrice"], + d["totalPosCost"], d["prePosition"], d["availablePosition"], d["currentPosition"], + d["openPosCost"], + d["todayCommission"], d["todayTotalBuyAmount"], d["todayTotalSellAmount"], + tool.get_now_datetime_str(), + tool.get_now_datetime_str())) + else: + # 淇敼鏁版嵁 + updateDict = {} + if result[5] != d['historyPos']: + updateDict['historyPos'] = d['historyPos'] + if result[6] != d['historyPosFrozen']: + updateDict['historyPosFrozen'] = d['historyPosFrozen'] + if result[7] != d['todayBSPos']: + updateDict['todayBSPos'] = d['todayBSPos'] + if result[8] != d['todayBSPosFrozen']: + updateDict['todayBSPosFrozen'] = d['todayBSPosFrozen'] + if result[9] != f"{d['historyPosPrice']}": + updateDict['historyPosPrice'] = d['historyPosPrice'] + if result[10] != f"{d['totalPosCost']}": + updateDict['totalPosCost'] = d['totalPosCost'] + if result[11] != d['prePosition']: + updateDict['prePosition'] = d['prePosition'] + if result[12] != d['availablePosition']: + updateDict['availablePosition'] = d['availablePosition'] + if result[13] != d['currentPosition']: + updateDict['currentPosition'] = d['currentPosition'] + if result[14] != f"{d['openPosCost']}": + updateDict['openPosCost'] = d['openPosCost'] + if result[15] != f"{d['todayCommission']}": + updateDict['todayCommission'] = d['todayCommission'] + if result[16] != f"{d['todayTotalBuyAmount']}": + updateDict['todayTotalBuyAmount'] = d['todayTotalBuyAmount'] + if result[17] != f"{d['todayTotalSellAmount']}": + updateDict['todayTotalSellAmount'] = d['todayTotalSellAmount'] + if updateDict: + # 鏈夋洿鏂版暟鎹� + updateDict['updateTime'] = tool.get_now_datetime_str() + where_list = [] + for k in updateDict: + if type(updateDict[k]) == str: + where_list.append(f"{k}='{updateDict[k]}'") + else: + where_list.append(f"{k}={updateDict[k]}") + mysqldb.execute( + f"update hx_trade_position set {','.join(where_list)} where id='{result[0]}'") + finally: + pass + + @classmethod + def list_by_day(cls, day): + mysqldb = mysql_data.Mysqldb() + try: + results = mysqldb.select_all( + f"select * from hx_trade_position r where r.tradingDay='{day}' order by createTime") + # 杞琩ict + key_list = ["id", "investorID", "securityName", "securityID", "historyPos", "historyPosFrozen", + "todayBSPos", "todayBSPosFrozen", "historyPosPrice", "totalPosCost", "prePosition", + "availablePosition", "currentPosition", + "openPosCost", "todayCommission", "todayTotalBuyAmount", "todayTotalSellAmount", "createTime", + "updateTime"] + fresults = [] + + if results: + for r in results: + temp = {} + for i in range(len(r)): + if type(r[i]) == datetime.datetime: + temp[key_list[i]] = r[i].strftime("%Y-%m-%d %H:%M:%S") + else: + temp[key_list[i]] = r[i] + fresults.append(temp) + return fresults + finally: + pass + + @classmethod + def get_volume_by_code(cls, code): + mysqldb = mysql_data.Mysqldb() + mysqldb.select_one(f"select currentPosition from hx_trade_position where securityID='{code}'") + + # 鑾峰彇鎸佷粨浠g爜 + @classmethod + def get_position_codes(cls): + codes = [] + if cls.latest_positions: + for d in cls.latest_positions: + if d["prePosition"] <= 0: + continue + codes.append(d["securityID"]) + return codes + + +# 鎴愪氦璁板綍 +class DealRecordManager: + __latest_deal_trade_id_dict = {} + + __instance = None + + def __new__(cls, *args, **kwargs): + if not cls.__instance: + cls.__instance = super(DealRecordManager, cls).__new__(cls, *args, **kwargs) + cls.__load_data() + return cls.__instance + + @classmethod + def __load_data(cls): + fresults = cls.list_by_day(tool.get_now_date_str("%Y%m%d")) + if fresults: + for r in fresults: + cls.__latest_deal_trade_id_dict[r["tradeID"]] = r + + def list_sell_by_code_cache(self, code): + fresults = [] + for k in self.__latest_deal_trade_id_dict: + d = self.__latest_deal_trade_id_dict[k] + if d["securityID"] != code: + continue + if int(d["direction"]) != 1: + continue + fresults.append(d) + return fresults + + @classmethod + def add(cls, datas): + mysqldb = mysql_data.Mysqldb() + try: + if datas: + for d in datas: + cls.__latest_deal_trade_id_dict[d['tradeID']] = d + # 鏌ヨ鏄惁鏈夋暟鎹� + result = mysqldb.select_one( + f"select * from hx_trade_deal_record where tradeID='{d['tradeID']}'") + if not result: + # 鏂板鏁版嵁 + mysqldb.execute( + "insert into hx_trade_deal_record values('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')" % ( + d["tradeID"], d["securityID"], d["orderLocalID"], d["direction"], + d["orderSysID"], round(d["price"], 2), d["tradeTime"], d["volume"], + d["tradeDate"], + d["tradingDay"], d["pbuID"], d["accountID"], + tool.get_now_datetime_str(), + tool.get_now_datetime_str())) + finally: + pass + + @classmethod + def list_by_day(cls, day): + mysqldb = mysql_data.Mysqldb() + try: + results = mysqldb.select_all( + f"select * from hx_trade_deal_record r where r.tradeDate='{day}' order by createTime") + # 杞琩ict + key_list = ["tradeID", "securityID", "orderLocalID", "direction", "orderSysID", "price", + "tradeTime", "volume", "tradeDate", "tradingDay", "pbuID", + "accountID", "createTime", + "updateTime"] + fresults = [] + if results: + for r in results: + temp = {} + for i in range(len(r)): + if type(r[i]) == datetime.datetime: + temp[key_list[i]] = r[i].strftime("%Y-%m-%d %H:%M:%S") + else: + temp[key_list[i]] = r[i] + fresults.append(temp) + return fresults + finally: + pass + return [] + + +# 璧勯噾绠$悊 +class MoneyManager: + __redisMananger = redis_manager.RedisManager(2) + + @classmethod + def get_redis(cls): + return cls.__redisMananger.getRedis() + + @classmethod + def save_data(cls, data): + RedisUtils.setex(cls.get_redis(), "huaxin_money", tool.get_expire(), json.dumps(data)) + + @classmethod + def get_data(cls): + val = RedisUtils.get(cls.get_redis(), "huaxin_money") + if not val: + return None + return json.loads(val) + + +# 浜ゆ槗璁㈠崟鍙风鐞� +class TradeOrderIdManager: + __db = 2 + __redisManager = RedisManager(2) + __instance = None + __huaxin_order_id_cache = {} + __huaxin_order_ref_cache = {} + + def __new__(cls, *args, **kwargs): + if not cls.__instance: + cls.__instance = super(TradeOrderIdManager, cls).__new__(cls, *args, **kwargs) + cls.__load_datas() + return cls.__instance + + @classmethod + def __get_redis(cls): + return cls.__redisManager.getRedis() + + @classmethod + def __load_datas(cls): + __redis = cls.__get_redis() + try: + keys = RedisUtils.keys(__redis, "huaxin_order_id-*") + for k in keys: + code = k.split("-")[-1] + vals = RedisUtils.smembers(__redis, k) + tool.CodeDataCacheUtil.set_cache(cls.__huaxin_order_id_cache, code, vals) + keys = RedisUtils.keys(__redis, "huaxin_order_ref-*") + for k in keys: + code = k.split("-")[-1] + vals = RedisUtils.smembers(__redis, k) + tool.CodeDataCacheUtil.set_cache(cls.__huaxin_order_ref_cache, code, vals) + finally: + RedisUtils.realse(__redis) + # 娣诲姞璁㈠崟ID + + def add_order_ref(self, code, order_ref): + self.add_order_refs(code, [order_ref]) + + def add_order_refs(self, code, order_ref_list): + if code not in self.__huaxin_order_ref_cache: + self.__huaxin_order_ref_cache[code] = set() + for val in order_ref_list: + self.__huaxin_order_ref_cache[code].add(val) + RedisUtils.sadd_async(self.__db, f"huaxin_order_ref-{code}", val) + RedisUtils.expire_async(self.__db, f"huaxin_order_ref-{code}", tool.get_expire()) + + # 鍒犻櫎璁㈠崟ID + def remove_order_ref(self, code, order_ref): + val = order_ref + if code in self.__huaxin_order_ref_cache: + self.__huaxin_order_ref_cache[code].discard(val) + RedisUtils.srem_async(self.__db, f"huaxin_order_ref-{code}", val) + + # 鏌ヨ鎵�鏈夌殑璁㈠崟鍙� + def list_order_refs(self, code): + return RedisUtils.smembers(self.__get_redis(), f"huaxin_order_ref-{code}") + + def list_order_refs_cache(self, code): + if code in self.__huaxin_order_ref_cache: + return self.__huaxin_order_ref_cache[code] + return set() + + # 娣诲姞璁㈠崟ID + def add_order_id(self, code, account_id, sys_order_id): + val = json.dumps((account_id, sys_order_id)) + if code not in self.__huaxin_order_id_cache: + self.__huaxin_order_id_cache[code] = set() + self.__huaxin_order_id_cache[code].add(val) + RedisUtils.sadd_async(self.__db, f"huaxin_order_id-{code}", val) + RedisUtils.expire_async(self.__db, f"huaxin_order_id-{code}", tool.get_expire()) + + # 鍒犻櫎璁㈠崟ID + def remove_order_id(self, code, account_id, order_id): + val = json.dumps((account_id, order_id)) + if code in self.__huaxin_order_id_cache: + self.__huaxin_order_id_cache[code].discard(val) + RedisUtils.srem_async(self.__db, f"huaxin_order_id-{code}", val) + + # 鏌ヨ鎵�鏈夌殑璁㈠崟鍙� + + def list_order_ids(self, code): + return RedisUtils.smembers(self.__get_redis(), f"huaxin_order_id-{code}") + + def list_order_ids_cache(self, code): + if code in self.__huaxin_order_id_cache: + return self.__huaxin_order_id_cache[code] + return set() + + +if __name__ == "__main__": + print(DelegateRecordManager().list_current_delegates("600239")) diff --git a/trade/trade_constant.py b/trade/trade_constant.py new file mode 100644 index 0000000..3a3c25b --- /dev/null +++ b/trade/trade_constant.py @@ -0,0 +1,56 @@ +# 鏈氦鏄� +TRADE_STATE_NOT_TRADE = 0 +# 涓嬪崟 +TRADE_STATE_BUY_PLACE_ORDER = 10 +# 宸插鎵樹拱 +TRADE_STATE_BUY_DELEGATED = 11 +# 濮旀墭鍙栨秷杩涜涓� +TRADE_STATE_BUY_CANCEL_ING = 13 +# 鎾ら攢鎴愬姛 +TRADE_STATE_BUY_CANCEL_SUCCESS = 14 +# 涔版垚鍔� +TRADE_STATE_BUY_SUCCESS = 12 + + +# 浜哄伐鎾ゅ崟 +CANCEL_TYPE_HUMAN = 20 +# F鎾� +CANCEL_TYPE_F = 1 +# H鎾� +CANCEL_TYPE_H = 2 + +CANCEL_TYPE_L = 3 + +# L鍓� +CANCEL_TYPE_L_UP = 31 +# L鍚� +CANCEL_TYPE_L_DOWN = 32 +# G鎾ゅ崟 +CANCEL_TYPE_G = 5 +# S鎾� +CANCEL_TYPE_S = 6 +# S蹇� +CANCEL_TYPE_S_FAST = 61 +# S鎱� +CANCEL_TYPE_S_SLOW = 62 + +# J鎾� +CANCEL_TYPE_J = 7 + +# L2寤惰繜 +CANCEL_TYPE_L2_DELAY = 8 + +# 澶у競鍊兼棤澶у崟 +CANCEL_TYPE_NB = 9 + +# W鎾� +CANCEL_TYPE_W = 10 + +# D鎾� +CANCEL_TYPE_D = 11 + +# RD鎾� +CANCEL_TYPE_RD = 12 + +# P鎾� +CANCEL_TYPE_P = 13 diff --git a/trade/trade_data_manager.py b/trade/trade_data_manager.py new file mode 100644 index 0000000..064ddb8 --- /dev/null +++ b/trade/trade_data_manager.py @@ -0,0 +1,489 @@ +""" +浜ゆ槗鏁版嵁鑲¢偅閲屽櫒 +鐢ㄤ簬瀵逛氦鏄撲复鏃舵暟鎹紙浜ゆ槗鐘舵�侊紝浠g爜鐘舵�佺瓑锛夎繘琛岀鐞� +""" +import json +import time + +# 浜ゆ槗鎾ら攢鏁版嵁绠$悊鍣� +import constant +from db.mysql_data_delegate import Mysqldb +from db.redis_manager_delegate import RedisUtils +from utils import global_util, tool +from db import redis_manager_delegate as redis_manager +from log_module.log import logger_trade + + +class TradeCancelDataManager: + capture_time_dict = {} + + # 淇濆瓨鎴浘鏃堕棿 + @classmethod + def save_l2_capture_time(cls, client_id, pos, code, capture_time): + cls.capture_time_dict["{}-{}-{}".format(client_id, pos, code)] = {"create_time": round(time.time() * 1000), + "capture_time": capture_time} + + # 鑾峰彇鏈�杩戜竴娆$殑鎴浘鏃堕棿 + @classmethod + def get_latest_l2_capture_time(cls, client_id, pos, code): + val = cls.capture_time_dict.get("{}-{}-{}".format(client_id, pos, code)) + if val is None: + return -1 + # 闂撮殧鏃堕棿涓嶈兘澶т簬1s + if round(time.time() * 1000) - val["create_time"] > 1000: + return -1 + return val["capture_time"] + + # 鑾峰彇l2鏁版嵁鐨勫闀块�熷害 + @classmethod + def get_l2_data_grow_speed(cls, client_id, pos, code, add_datas, capture_time): + count = 0 + for data in add_datas: + count += data["re"] + lastest_capture_time = cls.get_latest_l2_capture_time(client_id, pos, code) + if lastest_capture_time < 0: + raise Exception("鑾峰彇涓婃l2鏁版嵁鎴浘鏃堕棿鍑洪敊") + return count / (capture_time - lastest_capture_time) + + # 鑾峰彇涔板叆纭鐐圭殑浣嶇疆 + @classmethod + def get_buy_sure_position(cls, index, speed, trade_time): + return index + round(speed * trade_time) + + +class TradeBuyDataManager: + __db = 0 + redisManager = redis_manager.RedisManager(0) + buy_sure_position_dict = {} + __buy_position_info_cache = {} + + __instance = None + + def __new__(cls, *args, **kwargs): + if not cls.__instance: + cls.__instance = super(TradeBuyDataManager, cls).__new__(cls, *args, **kwargs) + cls.__load_datas() + return cls.__instance + + @classmethod + def __get_redis(cls): + return cls.redisManager.getRedis() + + @classmethod + def __load_datas(cls): + __redis = cls.__get_redis() + try: + keys = RedisUtils.keys(__redis, "buy_position_info-*") + for k in keys: + code = k.split("-")[-1] + val = RedisUtils.get(__redis, k) + val = json.loads(val) + tool.CodeDataCacheUtil.set_cache(cls.__buy_position_info_cache, code, val) + finally: + RedisUtils.realse(__redis) + + # 璁剧疆涔板叆鐐圭殑淇℃伅 + # trade_time: 涔板叆鐐规埅鍥炬椂闂翠笌涓嬪崟鎻愪氦鏃堕棿宸�� + # capture_time: 涔板叆鐐规埅鍥炬椂闂� + # last_data: 涔板叆鐐规渶鍚庝竴鏉℃暟鎹� + + def set_buy_position_info(self, code, capture_time, trade_time, last_data, last_data_index): + val = (capture_time, trade_time, last_data, last_data_index) + tool.CodeDataCacheUtil.set_cache(self.__buy_position_info_cache, code, val) + RedisUtils.setex_async(self.__db, "buy_position_info-{}".format(code), tool.get_expire(), + json.dumps(val)) + + # 鑾峰彇涔板叆鐐逛俊鎭� + + def get_buy_position_info(self, code): + val_str = RedisUtils.get(self.redisManager.getRedis(), "buy_position_info-{}".format(code)) + if val_str is None: + return None, None, None, None + else: + val = json.loads(val_str) + return val[0], val[1], val[2], val[3] + + def get_buy_position_info_cache(self, code): + cache_result = tool.CodeDataCacheUtil.get_cache(self.__buy_position_info_cache, code) + if cache_result[0]: + return cache_result[1] + return None, None, None, None + + # 鍒犻櫎涔板叆鐐逛俊鎭� + + def remove_buy_position_info(self, code): + tool.CodeDataCacheUtil.clear_cache(self.__buy_position_info_cache, code) + RedisUtils.delete_async(self.__db, "buy_position_info-{}".format(code)) + + # 璁剧疆涔板叆纭鐐逛俊鎭� + + def __set_buy_sure_position(self, code, index, data): + logger_trade.debug("涔板叆纭鐐逛俊鎭細 code:{} index:{} data:{}", code, index, data) + key = "buy_sure_position-{}".format(code) + RedisUtils.setex(self.redisManager.getRedis(), key, tool.get_expire(), json.dumps((index, data))) + self.buy_sure_position_dict[code] = (index, data) + # 绉婚櫎涓嬪崟淇″彿鐨勮缁嗕俊鎭� + self.remove_buy_position_info(code) + + # 娓呴櫎涔板叆纭鐐逛俊鎭� + + def __clear_buy_sure_position(self, code): + key = "buy_sure_position-{}".format(code) + RedisUtils.delete(self.redisManager.getRedis(), key) + if code in self.buy_sure_position_dict: + self.buy_sure_position_dict.pop(code) + + # 鑾峰彇涔板叆纭鐐逛俊鎭� + + def get_buy_sure_position(self, code): + temp = self.buy_sure_position_dict.get(code) + if temp is not None: + return temp[0], temp[1] + + key = "buy_sure_position-{}".format(code) + val = RedisUtils.get(self.redisManager.getRedis(), key) + if val is None: + return None, None + else: + val = json.loads(val) + self.buy_sure_position_dict[code] = (val[0], val[1]) + return val[0], val[1] + + +# 浠g爜瀹炴椂浠锋牸绠$悊鍣� +class CodeActualPriceProcessor: + __code_current_rate_cache = {} + __code_current_rate_latest = {} + __db = 0 + __redisManager = redis_manager.RedisManager(0) + __instance = None + + def __new__(cls, *args, **kwargs): + if not cls.__instance: + cls.__instance = super(CodeActualPriceProcessor, cls).__new__(cls, *args, **kwargs) + cls.__load_datas() + return cls.__instance + + @classmethod + def __get_redis(cls): + return cls.__redisManager.getRedis() + + @classmethod + def __load_datas(cls): + __redis = cls.__get_redis() + try: + keys = RedisUtils.keys(__redis, "code_current_rate-*") + for k in keys: + code = k.split("-")[-1] + val = RedisUtils.get(__redis, k) + tool.CodeDataCacheUtil.set_cache(cls.__code_current_rate_cache, code, float(val)) + except Exception as e: + pass + finally: + RedisUtils.realse(__redis) + + def __save_current_price_codes_count(self, count): + key = "current_price_codes_count" + RedisUtils.setex(self.__get_redis(), key, 10, count) + + def __get_current_price_codes_count(self): + key = "current_price_codes_count" + count = RedisUtils.get(self.__get_redis(), key) + return 0 if count is None else count + + # 淇濆瓨褰撳墠娑ㄥ箙 + def __save_current_rate(self, code, rate): + # 鍙樺寲涔嬪悗鎵嶄細鎸佷箙鍖� + if self.__code_current_rate_latest.get(code) == rate: + return + self.__code_current_rate_latest[code] = rate + tool.CodeDataCacheUtil.set_cache(self.__code_current_rate_cache, code, rate) + key = "code_current_rate-{}".format(code) + RedisUtils.setex_async(self.__db, key, tool.get_expire(), rate) + + # 鎵归噺淇濆瓨 + def __save_current_rates(self, datas): + # 鍙樺寲涔嬪悗鎵嶄細鎸佷箙鍖� + for d in datas: + if self.__code_current_rate_latest.get(d[0]) == d[1]: + continue + self.__code_current_rate_latest[d[0]] = d[1] + tool.CodeDataCacheUtil.set_cache(self.__code_current_rate_cache, d[0], d[1]) + key = "code_current_rate-{}".format(d[0]) + RedisUtils.setex_async(self.__db, key, tool.get_expire(), d[1]) + + # 鑾峰彇褰撳墠娑ㄥ箙 + def __get_current_rate(self, code): + key = "code_current_rate-{}".format(code) + rate = RedisUtils.get(self.__get_redis(), key) + if rate is not None: + return float(rate) + return None + + def get_current_rate(self, code): + cache_result = tool.CodeDataCacheUtil.get_cache(self.__code_current_rate_cache, code) + if cache_result[0]: + return cache_result[1] + return None + + # 淇濆瓨鐜颁环 + def save_current_price(self, code, price, is_limit_up): + global_util.cuurent_prices[code] = (price, is_limit_up, round(time.time())) + pass + + # 鑾峰彇鐜颁环 + def get_current_price(self, code): + return global_util.cuurent_prices.get(code) + + # 鐜颁环浠g爜鏁伴噺 + def save_current_price_codes_count(self, count): + self.__save_current_price_codes_count(count) + + def get_current_price_codes_count(self): + return self.__get_current_price_codes_count() + + # 褰撳墠浠g爜鏄惁娑ㄥ仠 + def current_is_limit_up(self, code): + data = self.get_current_price(code) + if data is None: + return None + return data[1] + + # 鑾峰彇娑ㄥ箙鍓嶅嚑鐨勪唬鐮� + def get_top_rate_codes(self, top_n): + keys = "code_current_rate-*" + keys = RedisUtils.keys(self.__get_redis(), keys) + infos = [] + for k in keys: + code = k.split("-")[1] + rate = self.get_current_rate(code) + infos.append((code, rate)) + # 鎺掑簭淇℃伅 + sorted_infos = sorted(infos, key=lambda tup: tup[1], reverse=True) + sorted_infos = sorted_infos[:top_n] + codes = [] + for data in sorted_infos: + codes.append(data[0]) + return codes + + +# 娑ㄥ仠娆℃暟绠$悊 +class PlaceOrderCountManager: + __db = 0 + __redisManager = redis_manager.RedisManager(0) + __place_order_count_cache = {} + __instance = None + + def __new__(cls, *args, **kwargs): + if not cls.__instance: + cls.__instance = super(PlaceOrderCountManager, cls).__new__(cls, *args, **kwargs) + cls.__load_datas() + return cls.__instance + + @classmethod + def __get_redis(cls): + return cls.__redisManager.getRedis() + + @classmethod + def __load_datas(cls): + redis_ = cls.__get_redis() + try: + keys = RedisUtils.keys(redis_, "place_order_count-*") + for k in keys: + code = k.split("-")[-1] + count = RedisUtils.get(redis_, k) + cls.__place_order_count_cache[code] = int(count) + finally: + RedisUtils.realse(redis_) + + def __incre_place_order_count(self, code): + if code not in self.__place_order_count_cache: + self.__place_order_count_cache[code] = 0 + self.__place_order_count_cache[code] += 1 + + key = "place_order_count-{}".format(code) + RedisUtils.incrby_async(self.__db, key, 1) + RedisUtils.expire_async(self.__db, key, tool.get_expire()) + + def __get_place_order_count(self, code): + key = "place_order_count-{}".format(code) + count = RedisUtils.get(self.__get_redis(), key) + if count is not None: + return int(count) + return 0 + + def __get_place_order_count_cache(self, code): + cache_result = tool.CodeDataCacheUtil.get_cache(self.__place_order_count_cache, code) + if cache_result[0]: + return cache_result[1] + return 0 + + def place_order(self, code): + self.__incre_place_order_count(code) + + def get_place_order_count(self, code): + return self.__get_place_order_count_cache(code) + + def clear_place_order_count(self, code): + self.__place_order_count_cache[code] = 0 + key = "place_order_count-{}".format(code) + RedisUtils.delete_async(self.__db, key) + + def clear(self): + self.__place_order_count_cache.clear() + keys = RedisUtils.keys(self.__get_redis(), "place_order_count-*") + for k in keys: + RedisUtils.delete(self.__get_redis(), k) + + +# 璐︽埛鍙敤璧勯噾绠$悊 +class AccountMoneyManager: + __db = 2 + __redis_manager = redis_manager.RedisManager(2) + __available_money_cache = None + __commission_cache = None + __instance = None + __mysqldb = Mysqldb() + + def __new__(cls, *args, **kwargs): + if not cls.__instance: + cls.__instance = super(AccountMoneyManager, cls).__new__(cls, *args, **kwargs) + __redis = cls.__get_redis() + result = RedisUtils.get(cls.__get_redis(), "trade-account-canuse-money") + if result: + cls.__available_money_cache = round(float(result), 2) + return cls.__instance + + @classmethod + def __get_redis(cls): + return cls.__redis_manager.getRedis() + + def set_available_money(self, client_id, money): + self.__available_money_cache = round(float(money), 2) + RedisUtils.set(self.__get_redis(), "trade-account-canuse-money", money) + + def set_commission(self, commission): + self.__commission_cache = commission + + # 鑾峰彇浜ゆ槗璐︽埛鐨勫彲鐢ㄩ噾棰� + def get_available_money(self): + result = RedisUtils.get(self.__get_redis(), "trade-account-canuse-money") + if result is None: + return None + return round(float(result), 2) + + def get_available_money_cache(self): + return self.__available_money_cache + + def get_commission_cache(self): + return self.__commission_cache + + def get_delegated_count_info(self, from_date=None, to_date=None): + """ + 鑾峰彇濮旀墭鏁伴噺淇℃伅 + @return: + """ + if not from_date: + from_date = tool.get_now_date_str("%Y%m%d") + if not to_date: + to_date = tool.get_now_date_str("%Y%m%d") + + sql = f"SELECT * FROM (SELECT '鎸備拱', COUNT(*) AS '鏁伴噺' FROM `hx_trade_delegate_record` r WHERE r.`direction`=0 AND r.`insertDate`>='{from_date}' AND r.`insertDate`<='{to_date}'" + sql += " UNION ALL " + sql += f"SELECT '鎾ゆ寕涔�',COUNT(*) AS '鏁伴噺' FROM `hx_trade_delegate_record` r WHERE r.`direction`=0 AND r.`cancelTime`!='' AND r.`cancelTime`IS NOT NULL AND r.`insertDate`>='{from_date}' AND r.`insertDate`<='{to_date}'" + sql += " UNION ALL " + sql += f"SELECT '鎾ゆ寕鍗�', COUNT(*) AS '鏁伴噺' FROM `hx_trade_delegate_record` r WHERE r.`direction`=1 AND r.`cancelTime`!='' AND r.`cancelTime`IS NOT NULL AND r.`insertDate`>='{from_date}' AND r.`insertDate`<='{to_date}'" + sql += " UNION ALL " + sql += f"SELECT '鎸傚崠' ,COUNT(*) AS '鏁伴噺' FROM `hx_trade_delegate_record` r WHERE r.`direction`=1 AND r.`insertDate`>='{from_date}' AND r.`insertDate`<='{to_date}'" + sql += ") a" + return self.__mysqldb.select_all(sql) + + def get_deal_count_info(self, from_date=None, to_date=None): + if not from_date: + from_date = tool.get_now_date_str("%Y%m%d") + if not to_date: + to_date = tool.get_now_date_str("%Y%m%d") + + sql = "SELECT * FROM ( " + + sql += f"SELECT '鑲$エ', COUNT(*), sum(a.price*a.volume) as '閲戦' FROM (SELECT * FROM `hx_trade_deal_record` r WHERE r.`tradeDate` >='{from_date}' and r.`tradeDate` <='{to_date}' AND (r.`securityID` LIKE '30%' OR r.`securityID` LIKE '60%' OR r.`securityID` LIKE '68%' OR r.`securityID` LIKE '00%') GROUP BY r.`orderSysID`) a" + + sql += " UNION ALL " + + sql += f"SELECT '涓婅瘉鍩洪噾', COUNT(*) AS '鏁伴噺', sum(a.price*a.volume) as '閲戦' FROM (SELECT * FROM `hx_trade_deal_record` r WHERE r.`tradeDate` >='{from_date}' and r.`tradeDate` <='{to_date}' AND (r.`securityID` LIKE '11%') GROUP BY r.`orderSysID`) a" + + sql += " UNION ALL " + + sql += f"SELECT '娣辫瘉鍩洪噾', COUNT(*) AS '鏁伴噺', sum(a.price*a.volume) as '閲戦' FROM (SELECT * FROM `hx_trade_deal_record` r WHERE r.`tradeDate` >='{from_date}' and r.`tradeDate` <='{to_date}' AND (r.`securityID` LIKE '12%') GROUP BY r.`orderSysID`) a" + sql += ") a" + return self.__mysqldb.select_all(sql) + + +# 婵�杩涗拱鎴愪氦浠g爜 +class RadicalBuyDealCodesManager: + """ + 婵�杩涗拱鎴愪氦浠g爜绠$悊 + """ + __db = 2 + __redis_manager = redis_manager.RedisManager(2) + __deal_codes_cache = set() + __instance = None + # 鏍规嵁L2鏁版嵁鏉ユ縺杩涗拱鍏ョ殑鏈夋晥鏃堕棿:{"code":(鏈夋晥鎴嚦鏃堕棿, 涔板崟鍙�, 鎵叆鐨勬澘鍧�, 鏈�杩戞垚浜ゆ椂闂�, 涔板叆鏉垮潡鍑�娴佸叆鎯呭喌, 鏄惁鏄澘涓婃斁閲忎拱鍏�)} + buy_by_l2_delegate_expire_time_dict = {} + # 浠呬粎涔扮殑鏉垮潡 + __radical_buy_blocks_dict = {} + + def __new__(cls, *args, **kwargs): + if not cls.__instance: + cls.__instance = super(RadicalBuyDealCodesManager, cls).__new__(cls, *args, **kwargs) + cls.__load_data() + + return cls.__instance + + @classmethod + def __load_data(cls): + result = RedisUtils.smembers(cls.__get_redis(), "radical_buy_deal_codes") + if result: + cls.__deal_codes_cache = set(result) + keys = RedisUtils.keys(cls.__get_redis(), "radical_buy_blocks-*") + if keys: + for k in keys: + code = k.split("-")[1] + val = RedisUtils.get(cls.__get_redis(), k) + val = json.loads(val) + cls.__radical_buy_blocks_dict[code] = set(val) + cls.__deal_codes_cache = set(result) + + def set_code_blocks(self, code, blocks): + self.__radical_buy_blocks_dict[code] = set(blocks) + RedisUtils.setex_async(self.__db, f"radical_buy_blocks-{code}", tool.get_expire(), json.dumps(list(blocks))) + + def get_code_blocks(self, code): + return self.__radical_buy_blocks_dict.get(code) + + @classmethod + def __get_redis(cls): + return cls.__redis_manager.getRedis() + + def add_deal_code(self, code): + """ + 娣诲姞宸叉垚浜ょ殑浠g爜 + @param code: + @return: + """ + self.__deal_codes_cache.add(code) + RedisUtils.sadd_async(self.__db, "radical_buy_deal_codes", code) + RedisUtils.expire_async(self.__db, "radical_buy_deal_codes", tool.get_expire()) + + def get_deal_codes(self): + """ + 鑾峰彇宸茬粡鎴愪氦鐨勪唬鐮� + @return: + """ + if self.__deal_codes_cache: + return self.__deal_codes_cache + return set() + + +if __name__ == "__main__": + pass diff --git a/trade/trade_manager.py b/trade/trade_manager.py new file mode 100644 index 0000000..c56e4f6 --- /dev/null +++ b/trade/trade_manager.py @@ -0,0 +1,168 @@ +""" +浜ゆ槗绠$悊鍣紝 +瀵逛竴绯诲垪鐨勪唬鐮佷氦鏄撳彉閲忥紝涓嬪崟锛屾挙鍗曡繘琛岀鐞� +""" +# 浜ゆ槗绠$悊鍣� +import copy + +from db import redis_manager_delegate as redis_manager +from db.redis_manager_delegate import RedisUtils +from log_module import async_log_util +from trade import trade_constant + + +from log_module.log import * +from utils import import_util, tool, huaxin_util + +trade_gui = import_util.import_lib("trade.trade_gui") + +__db = 12 +__redis_manager = redis_manager.RedisManager(__db) + +guiTrade = None # trade_gui.THSGuiTrade() if trade_gui is not None else None + +latest_trade_delegate_data = [] + + +# 鍏抽棴璐拱鍏ュ彛 +# 寮�鍚喘涔板叆鍙� +class TradeStateManager: + __instance = None + __db = 12 + redisManager = redis_manager.RedisManager(12) + + def __new__(cls, *args, **kwargs): + if not cls.__instance: + cls.__instance = super(TradeStateManager, cls).__new__(cls, *args, **kwargs) + cls.__instance.__trade_buy_state_cache = cls.is_can_buy() + return cls.__instance + + @classmethod + def __get_redis(cls): + return cls.redisManager.getRedis() + + def sync(self): + self.__trade_buy_state_cache = self.is_can_buy() + + # 寮�鍚喘涔板叆鍙� + def open_buy(self): + self.__trade_buy_state_cache = True + RedisUtils.setex_async(self.__db, "trade_buy_state", tool.get_expire(), 1) + + # 鍏抽棴璐拱鍏ュ彛 + def close_buy(self): + self.__trade_buy_state_cache = False + RedisUtils.setex_async(self.__db, "trade_buy_state", tool.get_expire(), 0) + + # 鏄惁鍙互涓嬪崟 + @classmethod + def is_can_buy(cls): + # 榛樿璁剧疆涓哄彲浜ゆ槗 + val = RedisUtils.get(cls.__get_redis(), "trade_buy_state") + if val is None: + return True + if int(val) == 1: + return True + else: + return False + + # 鏄惁鍙互涓嬪崟 + + def is_can_buy_cache(self): + # 榛樿璁剧疆涓哄彲浜ゆ槗 + return self.__trade_buy_state_cache + + +# 浠g爜鐨勪氦鏄撶姸鎬佺鐞� +class CodesTradeStateManager: + __trade_state_cache = {} + __db = 12 + __redis_manager = redis_manager.RedisManager(12) + __instance = None + + def __new__(cls, *args, **kwargs): + if not cls.__instance: + cls.__instance = super(CodesTradeStateManager, cls).__new__(cls, *args, **kwargs) + cls.__load_datas() + + return cls.__instance + + @classmethod + def __get_redis(cls): + return cls.__redis_manager.getRedis() + + @classmethod + def __load_datas(cls): + __redis = cls.__get_redis() + try: + # 鍒濆鍖栨暟鎹� + keys = RedisUtils.keys(__redis, "trade-state-*", auto_free=False) + if keys: + for key in keys: + code = key.replace("trade-state-", '') + cls.__trade_state_cache[code] = int(RedisUtils.get(__redis, key, auto_free=False)) + finally: + RedisUtils.realse(__redis) + + # 鑾峰彇浜ゆ槗鐘舵�� + def get_trade_state(self, code): + state = RedisUtils.get(self.__get_redis(), "trade-state-{}".format(code)) + if state is None: + return trade_constant.TRADE_STATE_NOT_TRADE + return int(state) + + def get_trade_state_cache(self, code): + cache_result = tool.CodeDataCacheUtil.get_cache(self.__trade_state_cache, code) + if cache_result[0]: + return cache_result[1] + return trade_constant.TRADE_STATE_NOT_TRADE + + def get_trade_state_dict(self): + return copy.deepcopy(self.__trade_state_cache) + + # 璁剧疆浜ゆ槗鐘舵�� + def set_trade_state(self, code, state): + async_log_util.info(logger_trade, "set_trade_state {}-{}".format(code, state)) + tool.CodeDataCacheUtil.set_cache(self.__trade_state_cache, code, state) + RedisUtils.setex_async(self.__db, "trade-state-{}".format(code), tool.get_expire(), state) + + def get_codes_by_trade_state(self, state): + redis = self.__get_redis() + try: + keys = RedisUtils.keys(redis, "trade-state-*", auto_free=False) + codes = [] + if keys is not None: + for key in keys: + if int(RedisUtils.get(redis, key, auto_free=False)) == state: + codes.append(key.replace("trade-state-", '')) + return codes + finally: + RedisUtils.realse(redis) + + def get_codes_by_trade_states(self, states): + redis = self.__get_redis() + try: + keys = RedisUtils.keys(redis, "trade-state-*", auto_free=False) + codes = [] + if keys is not None: + for key in keys: + if int(RedisUtils.get(redis, key, auto_free=False)) in states: + codes.append(key.replace("trade-state-", '')) + return codes + finally: + RedisUtils.realse(redis) + + def get_codes_by_trade_states_cache(self, states): + # 鑾峰彇 + codes = [] + for code in self.__trade_state_cache: + if self.__trade_state_cache[code] in states: + codes.append(code) + return codes + + # 璁剧疆浜ゆ槗璐︽埛鐨勫彲鐢ㄩ噾棰� + + +__CodesTradeStateManager = CodesTradeStateManager() + + -- Gitblit v1.8.0