82e8474625d9af933d6ab5825b43f6a248005010..32203dcb2d06b93e4b6c81f9121b00531a91395e
2025-06-06 Administrator
bug修复
32203d 对比 | 目录
2025-06-06 Administrator
bug修复
d97bea 对比 | 目录
2025-06-06 Administrator
bug修复
6940ed 对比 | 目录
2025-06-06 Administrator
Linux平台不导入gmapi
3b5d19 对比 | 目录
2025-06-06 Administrator
初始化导入
6df8d9 对比 | 目录
7个文件已删除
19个文件已修改
18个文件已添加
11286 ■■■■ 已修改文件
api/outside_api_command_manager.py 273 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
code_attribute/zyltgb_util.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin_client/command_manager.py 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin_client/l1_client.py 329 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin_client/l2_client.py 740 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin_client/l2_client_test.py 322 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin_client/l2_client_v2.py 727 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin_client/l2_data_manager.py 452 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin_client/l2_market_client.py 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin_client/trade_client.py 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lev2mdapi.py 1166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
log_module/log.py 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main.py 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/data_server.py 1048 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/data_analyzer.py 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/data_downloader.py 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/env_info.py 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/low_suction_strategy.py 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/strategy_params_settings.py 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/strategy_variable.py 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/strategy_variable_factory.py 412 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/test.py 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/time_series_backtest.py 623 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/今日量是否足够.py 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/低吸脚本_辨识度.py 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/低吸脚本_辨识度_v2.py 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/低吸脚本_辨识度_v3.py 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/低吸脚本_辨识度_v4.py 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/低吸脚本_辨识度_v5.py 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
strategy/低吸脚本_辨识度_v6.py 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/code_plate_key_manager.py 867 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/history_k_data_util.py 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/hx_qc_value_util.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/kpl_api.py 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/kpl_data_constant.py 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/kpl_data_manager.py 686 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/third_blocks_manager.py 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/huaxin/huaxin_trade_api.py 738 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/huaxin/huaxin_trade_data_update.py 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/huaxin/huaxin_trade_order_processor.py 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/huaxin/huaxin_trade_record_manager.py 488 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/trade_constant.py 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/trade_data_manager.py 489 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/trade_manager.py 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/outside_api_command_manager.py
New file
@@ -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  # æ–°å¢ž
# ä»£ç åå•类型
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"  # ä»£ç åå•
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"  # ä»£ç å±žæ€§
API_TYPE_CODE_TRADE_STATE = "code_trade_state"  # ä»£ç äº¤æ˜“状态
API_TYPE_GET_ENV = "get_env"  # èŽ·å–çŽ¯å¢ƒä¿¡æ¯
API_TYPE_SYNC_L1_TARGET_CODES = "sync_l1_subscript_codes"  # åŒæ­¥L1需要订阅的代码
API_TYPE_SYSTEM_LOG = "system_log"  # ç³»ç»Ÿæ—¥å¿—
API_TYPE_GET_FROM_DATA_SERVER = "get_from_data_server"  # ä»Žæ•°æ®æœåŠ¡å™¨æ‹‰å–æ•°æ®
API_TYPE_CODE_TRADE_INFO = "code_trade_info"  # ä»£ç äº¤æ˜“信息
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"  # èŽ·å–ä»£ç æŒä»“ä¿¡æ¯
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
    # ä»£ç åå•
    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
    # ä»£ç çš„交易信息
    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,连接server
        # 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()
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
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:
huaxin_client/l1_client.py
File was deleted
huaxin_client/l2_client.py
File was deleted
huaxin_client/l2_client_test.py
File was deleted
huaxin_client/l2_client_v2.py
File was deleted
huaxin_client/l2_data_manager.py
File was deleted
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()
    # æ¶¨åœä»£ç 
    __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"涨停代码:{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'])
             ]
             }
        # (代码, æ—¶é—´æˆ³, ä»·æ ¼, æ€»äº¤æ˜“量, æ€»äº¤æ˜“额, ä¹°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)
    # -------------------正式模式-------------------------------------
    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)
    # è®°å½•新增加的代码
    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})新增加订阅的代码:{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})新增加订阅的代码:{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:
            # (代码,现价,涨幅,量,时间)
            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)
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
# æ­£å¼è´¦å·
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'
    # ç»æµŽå…¬å¸éƒ¨é—¨ä»£ç 
    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
lev2mdapi.py
New file
@@ -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()
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
main.py
@@ -0,0 +1,60 @@
import json
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':
                    # [(代码, æ—¶é—´æˆ³, ä»·æ ¼, æ€»äº¤æ˜“量, æ€»äº¤æ˜“额, ä¹°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", json.dumps([(1, 2, 3, 4, 5)]))
    # èŽ·å–å¢žå€¼æœåŠ¡API
    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()
    # -------启动华鑫增值服务api------
    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("启动完成")
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)
    # ä»£ç çš„æ¶¨å¹…
    __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
        # èŽ·å–ä»£ç çš„åŽ†å²æ¶¨åœæ•°æ®,(涨停原因,日期,板块)
        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
            # # (代码,名称,强度)
            # temp = kpl_util.parseSonPlat(datas)
            # temp.sort(key=lambda x: x[2])
            # temp.reverse()
            # fresult["plat_strength"] = temp
            # èŽ·å–æ¶¨åœåŽŸå› ä¸‹é¢çš„åˆ—è¡¨
            datas = codes_by_plate_info
            # (代码,名称,现价,涨幅,自由流通,几板,龙几,主力净额,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")
            # æœ€ç»ˆç»“果:(代码,名称,涨停状态(0-无状态 1-涨停 2-炸板),龙几,首板,分值,涨停时间,原因,相同原因代码数量,自由流通,涨停原因是否变化,涨幅,现价,黑名单,想买单,主力净值,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)
            # èŽ·å–æ­£åœ¨æˆäº¤, è®¡ç®—成交进度
            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()
            # èŽ·å–æ¿å—ä¸‹çš„ä»£ç 
            # ç»Ÿè®¡ç›®å‰ä¸ºæ­¢çš„代码涨停数量(分涨停原因)
            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
                # ä»£ç ,名称,涨停时间,是否炸板,是否想买,是否已经下过单,涨停时间,自由流通市值,是否在黑名单里面
                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
                # ä»£ç ,名称,涨停时间,是否炸板,是否想买,是否已经下过单,涨停时间,自由流通市值,是否在黑名单里面
                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
                # èŽ·å–ä»£ç çŠ¶æ€
                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
            # èŽ·å–æ¿å—ä¸‹çš„ä»£ç 
            # ç»Ÿè®¡ç›®å‰ä¸ºæ­¢çš„代码涨停数量(分涨停原因)
            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
                # ä»£ç ,名称,涨停时间,是否炸板,是否加绿,是否已经下过单,涨停时间,自由流通市值,是否在黑名单里面, æ˜¯å¦æœ‰è¾¨è¯†åº¦, å¤§å•净额, æ˜¯å¦åŠ æƒ³
                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
                # èŽ·å–ä»£ç çŠ¶æ€
                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)
                # èŽ·å–ä»£ç çš„åŽŸå› 
                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)
                    # (代码,名称,首次涨停时间,最近涨停时间,几板,涨停原因,板块,实际流通,主力净额,涨停原因代码,涨停原因代码数量)
                    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:
                                    # (代码,名称, æ¶¨å¹…)
                                    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)
                    # (下单时间, ä»£ç , åç§°, ä¸‹å•模式, æ¿å—信息)
                    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:
                        # (代码, åç§°, æµå…¥é‡‘额, æ˜¯å¦è¢«æŽ’除成分股)
                        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":
            # æŽ¥æ”¶ä»£ç å‡€æµå…¥é‡‘额
            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):
                """
                è¯·æ±‚新板块的代码
                @param blocks_info:[(板块名称,板块代码)]
                @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
                        # æ ¼å¼ï¼š(代码,涨幅)
                        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:
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()
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)
strategy/env_info.py
New file
@@ -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"))
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: {"代码":[(买单号, é‡, é‡‘额, æ—¶é—´, æœ€ç»ˆæˆäº¤ä»·)]}
@@ -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: {"代码":[(买单号, é‡, é‡‘额, æ—¶é—´, æœ€ç»ˆæˆäº¤ä»·)]}
@@ -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: {"代码":[(买单号, é‡, é‡‘额, æ—¶é—´, æœ€ç»ˆæˆäº¤ä»·)]}
@@ -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: {"代码":[(买单号, é‡, é‡‘额, æ—¶é—´, æœ€ç»ˆæˆäº¤ä»·)]}
@@ -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
strategy/strategy_params_settings.py
New file
@@ -0,0 +1,75 @@
"""
策略参数设置
"""
import json
class StrategyParamsSettings:
    # ç¦æ­¢ä¹°å…¥
    STATE_FORBIDDEN_BUY = 0
    # æ­£å¸¸ä¹°å…¥
    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
        # æœ€å¤šé«˜äºŽå‡ä»·xx比例
        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
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.日最正原因出现的天数_60 = None
        self.日最正原因出现的天数_120 = None
        # æœ€è¿‘xx个交易日出现的板块
        self.日出现的板块_2 = None
        self.日出现的板块_5 = None
        self.日出现的板块_10 = None
        self.日出现的板块_30 = None
        self.日出现的板块_60 = None
        self.日出现的板块_120 = None
        # æœ€è¿‘xx个交易日出现倍量的日期
        self.日放倍量日期_5 = None
        self.日放倍量日期_10 = None
        self.日放倍量日期_15 = None
        self.日放倍量日期_30 = None
        self.日放倍量日期_60 = None
        self.日放倍量日期_120 = None
        # å½“日板块涨停:{板块:[(代码, æ¶¨åœæ—¶é—´),(代码, æ¶¨åœæ—¶é—´)]}
        self.板块涨停 = None
        self.开盘啦板块涨停 = None
        self.开盘啦领涨板块涨停 = None
        self.开盘啦精选板块涨停 = None
        self.开盘啦最正板块涨停 = None
        # å½“日板块:{"板块1","板块2"}
        self.代码板块 = None
        self.新代码板块 = None
        self.代码精选板块=None
        # æ¿å—成交代码:{"板块":{"代码1","代码2"}}
        self.板块成交代码 = {}
        # æµå…¥æ¿å—
        self.资金流入板块 = []
        self.辨识度代码 = set()
        self.领涨板块信息 = set()
        self.连续老题材 = set()
    def replace_variables(self, expression):
        """
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 = {}
        # ä»£ç çš„精选板块 ï¼š {"代码":{板块}}
        self.jx_blocks = {}
    def load_kline_data(self):
        """
        åŠ è½½æ—¥K线数据
        :return: æ—¥K线数据
        :return: {"代码": æ—¥K线数据}
        """
        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):
        """
        åŠ è½½å½“æ—¥çš„tick数据
        :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: æ¶¨åœæ•°æ®è®°å½•[(代码, æ—¥æœŸ, æ¿å—, æ˜¯å¦ç‚¸æ¿)]
        """
        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)
        # {"代码":[(板块, æ—¥æœŸ), (板块, æ—¥æœŸ)]}
        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):
        """
        åŠ è½½ç›®æ ‡æ¿å—ä¸Žå¯¹åº”çš„ä»£ç ï¼š
        ä»Žæœ€è¿‘120个交易日的真正涨停数据中
        @return: {"板块":[代码]}
        """
        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:[(代码, é¢†æ¶¨æ¬¡æ•°, æœ€å¤§é¢†æ¶¨æ¬¡æ•°)]
        """
        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:{"板块代码":(板块名称, [(代码,代码名称,标签,领涨次数)])}
        """
        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):
        """
        åŠ è½½æ‰€æœ‰æœ‰é¢†æ¶¨ä»£ç çš„é¢†æ¶¨æ¿å—
        @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: {"代码":{"板块名称":(代码, é¢†æ¶¨æ¬¡æ•°, æœ€å¤§é¢†æ¶¨æ¬¡æ•°)}}
        """
        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:[代码, åç§°, é£Žé™©é¡¹, é¢†æ¶¨æ¬¡æ•°]
        """
        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: æ¶¨åœæ•°æ®è®°å½•[(代码, æ—¥æœŸ, æ¿å—, æ˜¯å¦ç‚¸æ¿)]
        """
        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"日个股最正的原因_{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:
                # èŽ·å–æ—¥K最高量的信息
@@ -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"))
strategy/test.py
@@ -1,18 +1,25 @@
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(path):
    rate_list = []
    with open(path, 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), "总买票数量:", len(rate_list))
if __name__ == "__main__":
    print("======2个票涨停之后买")
    statistic_average(r"C:\Users\Administrator\Desktop\2个票涨停之后买.txt")
    print("======3个票涨停之后买")
    statistic_average(r"C:\Users\Administrator\Desktop\3个票涨停之后买.txt")
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
        # é¢†æ¶¨ä»£ç çš„æ¿å—,{代码:{"板块":(代码, é¢†æ¶¨æ¬¡æ•°, æ¿å—最大领涨次数)}}
        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("历史日K获取失败")
        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)
        # è½¬æ¢æ ¼å¼ä¸ºï¼š{时间: [("代码", (买单号, é‡, é‡‘额, æ—¶é—´, æœ€ç»ˆæˆäº¤ä»·))]
        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
        # åŠ è½½æ¿å—ä»£ç 
        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]
        # èŽ·å–æ‰€æœ‰æ¶¨åœåŽŸå› ä¸‹é¢çš„é¢†æ¶¨ä¸ªè‚¡ä¿¡æ¯,得到的信息格式:{"代码":{板块名称}}
        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
        # èŽ·å–ä»£ç æ¿å—
        stock_variables.代码板块 = current_data["code_plates"].get(code_)
        stock_variables.代码板块 = 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 è¾“出目标代码
        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"]
        # æ¿å—涨停代码信息
        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:
                    # æŒ‰ä»£ç çš„æ¿å—统计涨停板块中的代码数量
                    # æ¶¨åœè¿‡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] = []
                    # å¦‚果领涨代码里面没有当前票就不算这个板块的涨停原因
                    # èŽ·å–é¢†æ¶¨æ•°æ®
                    # 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
                # {"代码":[(板块代码, æ¿å—名称)]}
                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:
                    # æ ¼å¼ ("代码", (买单号, é‡, é‡‘额, æ—¶é—´, æœ€ç»ˆæˆäº¤ä»·))
                    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:
                    # æ ¼å¼ ("代码", (买单号, é‡, é‡‘额, æ—¶é—´, æœ€ç»ˆæˆäº¤ä»·))
                    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])
            # å¼€ç›˜å•¦æœ€æ­£æ¶¨åœåŽŸå› 
            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.板块成交代码 = 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.板块成交代码 = 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.开盘啦最正板块涨停 = 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.开盘啦最正板块涨停 = 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.代码板块, 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:
                # èŽ·å–å½“å‰çš„tick线
                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.板块成交代码 = 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()
strategy/½ñÈÕÁ¿ÊÇ·ñ×ã¹».py
New file
@@ -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, "日K不满足条件"
    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.代码精选板块 and sv.开盘啦精选板块涨停:
        buy_blocks = sv.代码精选板块 - 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()
strategy/µÍÎü½Å±¾_±æÊ¶¶È.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.代码板块 if sv.板块涨停 and k in sv.板块涨停 and len(sv.板块涨停[k]) >= 1])
    if not can_buy_blocks:
        return False, "板块少于1个涨停"
    # æ˜¯å¦è¿˜æœ‰å¯ä¹°çš„æ¿å—
    # can_buy_blocks = sv.代码板块 - sv.板块成交代码.keys()
    # if not can_buy_blocks:
    #     return False, "没有可买的代码"
    can_buy_blocks = sv.代码板块 - sv.板块成交代码.keys()
    if not can_buy_blocks:
        return False, "板块已有成交代码"
    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()
strategy/µÍÎü½Å±¾_±æÊ¶¶È_v2.py
New file
@@ -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, "日K不满足条件"
    # 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.代码板块:
        return False, "没有板块"
    can_buy_blocks = set([k for k in sv.代码板块 if sv.板块涨停 and k in sv.板块涨停 and len(sv.板块涨停[k]) >= 1])
    if not can_buy_blocks:
        return False, "板块少于1个涨停"
    # æ˜¯å¦è¿˜æœ‰å¯ä¹°çš„æ¿å—
    can_buy_blocks = sv.代码板块 - sv.板块成交代码.keys()
    if not can_buy_blocks:
        return False, "板块已有成交代码"
    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()
strategy/µÍÎü½Å±¾_±æÊ¶¶È_v3.py
New file
@@ -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, "日K不满足条件"
    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.板块成交代码.keys()
    # if not can_buy_blocks:
    #     return False, "板块已有成交代码"
    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()
strategy/µÍÎü½Å±¾_±æÊ¶¶È_v4.py
New file
@@ -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, "日K不满足条件"
    # 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.板块成交代码.keys()
    # if not can_buy_blocks:
    #     return False, "板块已有成交代码"
    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()
strategy/µÍÎü½Å±¾_±æÊ¶¶È_v5.py
New file
@@ -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, "日K不满足条件"
    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()
strategy/µÍÎü½Å±¾_±æÊ¶¶È_v6.py
New file
@@ -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.代码板块:
        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.开盘啦最正板块涨停.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.板块成交代码:
        can_buy_plates -= set(sv.板块成交代码.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.开盘啦最正板块涨停.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.开盘啦最正板块涨停.get(p)) for p in can_buy_plates]}", can_buy_plates
compute_result = can_buy()
third_data/code_plate_key_manager.py
File was deleted
third_data/history_k_data_util.py
@@ -6,8 +6,10 @@
import json
import time
import constant as constant
import requests
import gm.api as gmapi
if constant.is_windows():
    import gm.api as gmapi
import constant
from db.redis_manager_delegate import RedisUtils
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 = {}
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)
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的板数:{"代码":(几版,{板块})}
from utils.tool import singleton
third_data/kpl_data_manager.py
File was deleted
third_data/third_blocks_manager.py
New file
@@ -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
trade/huaxin/huaxin_trade_api.py
New file
@@ -0,0 +1,738 @@
"""
交易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:request_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:request_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)
queue_strategy_w_trade_r_for_read = None
queue_strategy_w_trade_r = None
def run():
    global queue_strategy_w_trade_r_for_read, queue_strategy_w_trade_r
    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, cancel_order_ipc_addr))
# äº¤æ˜“通道的错误次数
trade_pipe_channel_error_count = 0
# pipe的交易通道是否正常
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
# ç­‰å¾…响应的request_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"发送耗时:request_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
trade/huaxin/huaxin_trade_data_update.py
New file
@@ -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()
trade/huaxin/huaxin_trade_order_processor.py
New file
@@ -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")
trade/huaxin/huaxin_trade_record_manager.py
New file
@@ -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")
            # è½¬dict
            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()
    # ä¿å­˜ä»£ç çš„量
    @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")
            # è½¬dict
            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}'")
    # èŽ·å–æŒä»“ä»£ç 
    @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")
            # è½¬dict
            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"))
trade/trade_constant.py
New file
@@ -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
trade/trade_data_manager.py
New file
@@ -0,0 +1,489 @@
"""
交易数据股那里器
用于对交易临时数据(交易状态,代码状态等)进行管理
"""
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]
# ä»£ç å®žæ—¶ä»·æ ¼ç®¡ç†å™¨
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)
    # çŽ°ä»·ä»£ç æ•°é‡
    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()
    # å½“前代码是否涨停
    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)
# æ¿€è¿›ä¹°æˆäº¤ä»£ç 
class RadicalBuyDealCodesManager:
    """
    æ¿€è¿›ä¹°æˆäº¤ä»£ç ç®¡ç†
    """
    __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):
        """
        æ·»åŠ å·²æˆäº¤çš„ä»£ç 
        @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
trade/trade_manager.py
New file
@@ -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
# ä»£ç çš„交易状态管理
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()