Administrator
2024-08-20 b50893f5e694a04a5f4b2ddd9826f9abba627d79
可转债买卖接口
8个文件已修改
1个文件已添加
181 ■■■■■ 已修改文件
_lev2mdapi.cp37-win32.pyd 补丁 | 查看 | 原始文档 | blame | 历史
_lev2mdapi.cp37-win_amd64.pyd 补丁 | 查看 | 原始文档 | blame | 历史
_lev2mdapi.cpython-37m-x86_64-linux-gnu.so 补丁 | 查看 | 原始文档 | blame | 历史
constant.py 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin_client/l2_client.py 65 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_data_manager.py 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/huaxin_trade_api.py 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/huaxin_trade_data_update.py 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/trade_strategy.py 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
_lev2mdapi.cp37-win32.pyd
Binary files differ
_lev2mdapi.cp37-win_amd64.pyd
Binary files differ
_lev2mdapi.cpython-37m-x86_64-linux-gnu.so
Binary files differ
constant.py
@@ -3,8 +3,8 @@
TEST = False
JUEJIN_LOCAL_API = False
def is_windows():
    system = platform.system()
@@ -50,6 +50,11 @@
LOG_DIR = "sell_logs"
# 获取根路径
def get_path_prefix():
    return 'D:' if is_windows() else '/home/userzjj'
    return 'D:' if is_windows() else '/home/userzjj'
# 订阅L2代码数据
SUBSCRIPT_L2_CODES = set()
huaxin_client/l2_client.py
@@ -85,10 +85,9 @@
        logger_local_huaxin_l2_subscript.info(f"取消订阅上证:{sh}")
        logger_local_huaxin_l2_subscript.info(f"取消订阅深证:{sz}")
        if sh:
            # 取消订阅逐笔委托
            self.__api.UnSubscribeOrderDetail(sh, lev2mdapi.TORA_TSTP_EXD_SSE)
            # 取消订阅逐笔成交
            self.__api.UnSubscribeTransaction(sh, lev2mdapi.TORA_TSTP_EXD_SSE)
            # 取消订阅
            result = self.__api.UnSubscribeNGTSTick(sh, lev2mdapi.TORA_TSTP_EXD_SSE)
            logger_local_huaxin_l2_subscript.info(f"逐笔NGTS订阅结果sh:{result}")
        if sz:
            self.__api.UnSubscribeOrderDetail(sz, lev2mdapi.TORA_TSTP_EXD_SZSE)
            self.__api.UnSubscribeTransaction(sz, lev2mdapi.TORA_TSTP_EXD_SZSE)
@@ -98,12 +97,9 @@
        logger_local_huaxin_l2_subscript.info(f"订阅上证:{sh}")
        logger_local_huaxin_l2_subscript.info(f"订阅深证:{sz}")
        if sh:
            # 订阅逐笔委托
            result = self.__api.SubscribeOrderDetail(sh, lev2mdapi.TORA_TSTP_EXD_SSE)
            logger_local_huaxin_l2_subscript.info(f"逐笔委托订阅结果sh:{result}")
            # 订阅逐笔成交
            result = self.__api.SubscribeTransaction(sh, lev2mdapi.TORA_TSTP_EXD_SSE)
            logger_local_huaxin_l2_subscript.info(f"逐笔成交订阅结果sh:{result}")
            # 订阅上证逐笔
            result = self.__api.SubscribeNGTSTick(sh, lev2mdapi.TORA_TSTP_EXD_SSE)
            logger_local_huaxin_l2_subscript.info(f"逐笔NGTS订阅结果sh:{result}")
        if sz:
            result = self.__api.SubscribeOrderDetail(sz, lev2mdapi.TORA_TSTP_EXD_SZSE)
            logger_local_huaxin_l2_subscript.info(f"逐笔委托订阅结果sz:{result}")
@@ -190,7 +186,7 @@
        printlog("OnRspSubOrderDetail", pRspInfo)
        # try:
        printlog("订阅结果:", pSpecificSecurity["ExchangeID"], pSpecificSecurity["SecurityID"], pRspInfo["ErrorID"],
              pRspInfo["ErrorMsg"])
                 pRspInfo["ErrorMsg"])
        async_log_util.info(logger_local_huaxin_l2_subscript,
                            f"订阅结果:{pSpecificSecurity['SecurityID']} {pRspInfo['ErrorID']} {pRspInfo['ErrorMsg']}")
        if pRspInfo["ErrorID"] == 0:
@@ -207,6 +203,27 @@
            self.subscripted_codes.discard(code)
            if bIsLast == 1:
                printlog("取消订阅响应结束", self.subscripted_codes)
                l2_data_manager.add_subscript_codes(self.subscripted_codes)
        except Exception as e:
            logging.exception(e)
    def OnRspSubNGTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast):
        async_log_util.info(logger_local_huaxin_l2_subscript,
                            f"NGTS订阅结果:{pSpecificSecurity['SecurityID']} {pRspInfo['ErrorID']} {pRspInfo['ErrorMsg']}")
        if pRspInfo["ErrorID"] == 0:
            print("订阅成功")
            self.subscripted_codes.add(pSpecificSecurity['SecurityID'])
        if bIsLast == 1:
            print("订阅响应结束", self.subscripted_codes)
            l2_data_manager.add_subscript_codes(self.subscripted_codes)
    def OnRspUnSubNGTSTick(self, pSpecificSecurity, pRspInfo, nRequestID, bIsLast):
        try:
            code = pSpecificSecurity['SecurityID']
            logger_local_huaxin_l2_subscript.info(f"NGTS取消订阅:{code}")
            self.subscripted_codes.discard(code)
            if bIsLast == 1:
                print("取消订阅响应结束", self.subscripted_codes)
                l2_data_manager.add_subscript_codes(self.subscripted_codes)
        except Exception as e:
            logging.exception(e)
@@ -251,6 +268,31 @@
                "SubSeq": pOrderDetail['SubSeq'], "OrderNO": pOrderDetail['OrderNO'],
                "OrderStatus": pOrderDetail['OrderStatus'].decode()}
        self.l2_data_upload_manager.add_l2_order_detail(item, 0)
    def OnRtnNGTSTick(self, pTick):
        # logger_debug.info(f"OnRtnNGTSTick: {pTick}")
        # 输出逐笔成交数据
        if pTick['TickType'] == b'T':
            item = {"SecurityID": pTick['SecurityID'], "TradePrice": pTick['Price'],
                    "TradeVolume": pTick['Volume'],
                    "OrderTime": pTick['TickTime'], "MainSeq": pTick['MainSeq'],
                    "SubSeq": pTick['SubSeq'], "BuyNo": pTick['BuyNo'],
                    "SellNo": pTick['SellNo'],
                    "ExecType": '1'}
            self.l2_data_upload_manager.add_transaction_detail(item)
        elif pTick['TickType'] == b'A' or pTick['TickType'] == b'D':
            # 撤单
            item = {"SecurityID": pTick['SecurityID'], "Price": pTick['Price'],
                    "Volume": pTick['Volume'],
                    "Side": pTick['Side'].decode(), "OrderType": pTick['TickType'].decode(),
                    "OrderTime": pTick['TickTime'], "MainSeq": pTick['MainSeq'],
                    "SubSeq": pTick['SubSeq'], "OrderNO": '',
                    "OrderStatus": pTick['TickType'].decode()}
            if pTick['Side'] == b'1':
                item['OrderNO'] = pTick['BuyNo']
            elif pTick['Side'] == b'2':
                item['OrderNO'] = pTick['SellNo']
            self.l2_data_upload_manager.add_l2_order_detail(item, 0)
class MyL2ActionCallback(L2ActionCallback):
@@ -367,7 +409,6 @@
            logging.exception(e)
        finally:
            time.sleep(10)
def run(queue_r: multiprocessing.Queue, data_callbacks: list) -> None:
l2/l2_data_manager.py
New file
@@ -0,0 +1,24 @@
class L2DataProcessor:
    __latest_deal_price_info = {}
    @classmethod
    def set_deal_price(cls, code, price, time_str):
        """
        设置成交价格
        :param code: 代码
        :param price: 价格
        :param time_str: 时间
        :return:
        """
        cls.__latest_deal_price_info[code] = (price, time_str)
    @classmethod
    def get_deal_price(cls, code):
        """
        获取成交价格
        :param code:
        :return:
        """
        return cls.__latest_deal_price_info.get(code)
trade/huaxin_trade_api.py
@@ -11,6 +11,7 @@
import concurrent.futures
from code_atrribute import history_k_data_util
from l2.l2_data_manager import L2DataProcessor
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
@@ -35,13 +36,19 @@
    def __sell_cb_code(code, volume):
        # 获取现价
        results = history_k_data_util.HistoryKDatasUtils.get_gp_current_info([code])
        if results:
            current_price = results[0]["price"]
            price = round(tool.get_buy_min_price(current_price, True), 3)
            results = order(2, code, volume, price)
            async_log_util.info(hx_logger_trade_debug, f"卖出可转债结果:{results}")
            # TODO 判断Ref是否被卖掉,如果没有卖掉,要继续卖
        current_price = None
        deal_price_info = L2DataProcessor.get_deal_price(code)
        if deal_price_info:
            current_price = deal_price_info[0]
        if not current_price:
            results = history_k_data_util.HistoryKDatasUtils.get_gp_current_info([code])
            if results:
                current_price = results[0]["price"]
        if current_price is None:
            raise Exception("获取到的现价为空")
        price = round(tool.get_buy_min_price(current_price, True), 3)
        results = order(2, code, volume, price)
        async_log_util.info(hx_logger_trade_debug, f"自动卖出可转债结果:{results}")
    def __process_order(data):
        code = data["securityID"]
@@ -69,11 +76,13 @@
                    huaxin_trade_data_update.add_delegate_list("卖成交")
            else:
                # 买入
                if tool.is_cb_code(code) and sinfo in cb_data_util.need_sell_sinfos and str(
                        orderStatus) == huaxin_util.TORA_TSTP_OST_AllTraded:
                    # 可转债买入
                    # 卖出可转债
                    __sell_cb_code(code, volume)
                if tool.is_cb_code(code):
                    async_log_util.info(hx_logger_trade_debug, f"可转债买入:代码-{code} sinfo-{sinfo} 订单状态-{orderStatus}  需要卖的sinfo-{cb_data_util.need_sell_sinfos}")
                    if sinfo in cb_data_util.need_sell_sinfos and str(
                            orderStatus) == huaxin_util.TORA_TSTP_OST_AllTraded:
                        # 可转债买入
                        # 卖出可转债
                        __sell_cb_code(code, volume)
            # TradeResultProcessor.process_buy_order(order)
            need_watch_cancel = TradeResultProcessor.process_sell_order(order)
            if need_watch_cancel:
trade/huaxin_trade_data_update.py
@@ -6,6 +6,7 @@
import threading
import time
import constant
from code_atrribute import gpcode_manager
from code_atrribute.history_k_data_util import HistoryKDatasUtils
from log_module import async_log_util
@@ -55,8 +56,9 @@
                                async_log_util.info(hx_logger_trade_debug, f"获取收盘价:{type_}")
                            queue_l1_trade_r_strategy_w.put_nowait(
                                {"type": "set_target_codes", "data": list(position_codes)})
                            constant.SUBSCRIPT_L2_CODES |= position_codes
                            queue_strategy_w_l2_r.put_nowait(json.dumps(
                                {"type": "l2_cmd", "data": list(position_codes)}))
                                {"type": "l2_cmd", "data": list(constant.SUBSCRIPT_L2_CODES)}))
                            # 9点25之前需要订阅持仓票
                            __process_thread_pool.submit(huaxin_trade_record_manager.PositionManager.add, datas)
                    async_log_util.info(hx_logger_trade_debug, f"获取交易数据结束:{type_}")
trade/trade_strategy.py
@@ -14,6 +14,7 @@
from huaxin_client.l2_data_transform_protocol import L2DataCallBack
from l2 import l2_data_util
from l2.huaxin import l2_huaxin_util
from l2.l2_data_manager import L2DataProcessor
from l2.l2_data_util import local_today_datas, local_today_num_operate_map, local_today_buyno_map, \
    local_today_canceled_buyno_map, L2DataUtil
from log_module import async_log_util
@@ -29,6 +30,9 @@
class OutsideApiCommandCallback(ActionCallback):
    __cancel_sell_thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=8)
    def __init__(self, queue_strategy_w_l2_r):
        self.queue_strategy_w_l2_r = queue_strategy_w_l2_r
    @classmethod
    def __send_response(cls, data_bytes):
@@ -338,6 +342,10 @@
                        # 记录当前的sinfo
                async_log_util.info(logger_trade, f"API可转债买结果: {result}")
                self.send_response(result, client_id, request_id)
                # 订阅L2,用于卖
                constant.SUBSCRIPT_L2_CODES.add(code)
                self.queue_strategy_w_l2_r.put_nowait(json.dumps(
                    {"type": "l2_cmd", "data": list(constant.SUBSCRIPT_L2_CODES)}))
            except Exception as e:
                if str(e).find("超时") >= 0:
                    self.send_response({"code": 0, "data": {"orderRef": order_ref}}, client_id, request_id)
@@ -348,16 +356,20 @@
            code = data["code"]
            volume = data["volume"]
            current_price = None
            results = history_k_data_util.HistoryKDatasUtils.get_gp_current_info([code])
            if results:
                current_price = results[0]["price"]
            deal_price_info = L2DataProcessor.get_deal_price(code)
            if deal_price_info:
                current_price = deal_price_info[0]
            else:
                results = history_k_data_util.HistoryKDatasUtils.get_gp_current_info([code])
                if results:
                    current_price = results[0]["price"]
            order_ref = huaxin_util.create_order_ref()
            try:
                if not current_price:
                    raise Exception("尚未获取到现价")
                price = round(tool.get_buy_min_price(current_price) + 0.001, 3)
                result = huaxin_trade_api.order(2, code, volume, price, order_ref=order_ref,  blocking=True)
                async_log_util.info(logger_trade, f"API可转债卖结果: {result}")
                async_log_util.info(logger_trade, f"API可转债卖结果: {result},成交价信息:{deal_price_info}")
                self.send_response(result, client_id, request_id)
            except Exception as e:
                if str(e).find("超时") >= 0:
@@ -482,30 +494,6 @@
                logging.exception(e)
class L2DataProcessor:
    __latest_deal_price_info = {}
    @classmethod
    def set_deal_price(cls, code, price, time_str):
        """
        设置成交价格
        :param code: 代码
        :param price: 价格
        :param time_str: 时间
        :return:
        """
        cls.__latest_deal_price_info[code] = (price, time_str)
    @classmethod
    def get_deal_price(cls, code):
        """
        获取成交价格
        :param code:
        :return:
        """
        return cls.__latest_deal_price_info.get(code)
class MyL2DataCallback(L2DataCallBack):
    def OnL2Order(self, code, origin_datas, timestamp):
@@ -595,7 +583,7 @@
        manager = outside_api_command_manager.ApiCommandManager()
        manager.init(middle_api_protocol.SERVER_HOST,
                     middle_api_protocol.SERVER_PORT,
                     OutsideApiCommandCallback())
                     OutsideApiCommandCallback(queue_strategy_w_l2_r))
        manager.run(blocking=True)
    except Exception as e:
        logger_system.exception(e)