| | |
| | | |
| | | TEST = False |
| | | |
| | | |
| | | JUEJIN_LOCAL_API = False |
| | | |
| | | |
| | | def is_windows(): |
| | | system = platform.system() |
| | |
| | | |
| | | 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() |
| | |
| | | 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) |
| | |
| | | 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}") |
| | |
| | | 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: |
| | |
| | | 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) |
| | |
| | | "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): |
| | |
| | | logging.exception(e) |
| | | finally: |
| | | time.sleep(10) |
| | | |
| | | |
| | | |
| | | def run(queue_r: multiprocessing.Queue, data_callbacks: list) -> None: |
New file |
| | |
| | | |
| | | 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) |
| | | |
| | |
| | | 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 |
| | |
| | | |
| | | 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"] |
| | |
| | | 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: |
| | |
| | | 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 |
| | |
| | | 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_}") |
| | |
| | | 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 |
| | |
| | | |
| | | 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): |
| | |
| | | # 记录当前的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) |
| | |
| | | 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: |
| | |
| | | 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): |
| | |
| | | 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) |