"""
|
华鑫交易管理
|
"""
|
import concurrent.futures
|
import json
|
import logging
|
import time
|
import multiprocessing
|
|
import traderapi
|
from huaxin_client.client_network import SendResponseSkManager
|
from huaxin_client.command_manager import TradeActionCallback
|
from log_module import async_log_util
|
from log_module.log import logger_trade, logger_local_huaxin_trade_debug, printlog
|
from utils import tool, socket_util
|
|
ENABLE_ORDER = True
|
|
TYPE_ORDER = 0
|
TYPE_CANCEL_ORDER = 1
|
TYPE_LIST_DELEGATE = 2
|
TYPE_LIST_TRADED = 3
|
TYPE_LIST_POSITION = 4
|
TYPE_LIST_MONEY = 5
|
# 成交
|
TYPE_DEAL = 6
|
|
__queue_result: multiprocessing.Queue = None
|
|
|
def set_result_read_queue(queue_result):
|
"""
|
设置结果读取队列
|
:param queue_result:
|
:return:
|
"""
|
global __queue_result
|
__queue_result = queue_result
|
|
|
def __send_response(type, data_bytes):
|
sk = SendResponseSkManager.create_send_response_sk()
|
try:
|
data_bytes = socket_util.load_header(data_bytes)
|
sk.sendall(data_bytes)
|
result, header_str = socket_util.recv_data(sk)
|
result = json.loads(result)
|
if result["code"] != 0:
|
raise Exception(result['msg'])
|
finally:
|
sk.close()
|
|
|
def send_response(data, type, _client_id, _request_id, show_log=True):
|
if show_log:
|
async_log_util.debug(logger_local_huaxin_trade_debug, f"回调返回内容:{data}")
|
__queue_result.put_nowait(data)
|
|
|
# 交易反馈回调
|
def __traderapi_callback(type, req_id, data):
|
async_log_util.info(logger_local_huaxin_trade_debug, "回调:type-{} req_id-{}", type, req_id)
|
key = req_id
|
if type == TYPE_ORDER or type == TYPE_CANCEL_ORDER:
|
key = data["sinfo"]
|
try:
|
if req_rid_dict and key in req_rid_dict:
|
temp_params = req_rid_dict.pop(key)
|
client_id, request_id = temp_params[0], temp_params[1]
|
# 本地订单号-系统订单号映射
|
if len(temp_params) >= 4 and type == TYPE_ORDER:
|
order_ref = temp_params[3]
|
data["orderRef"] = order_ref
|
|
async_log_util.info(logger_local_huaxin_trade_debug, "API回调 request_id-{}", request_id)
|
# 测试
|
# send_response(
|
# json.dumps({"type": "response", "data": {"code": 0, "data": data}, "client_id": client_id,
|
# "request_id": request_id}), type, client_id, request_id, temp_params[2])
|
send_response(
|
json.dumps({"type": "response", "data": {"code": 0, "data": data}, "client_id": client_id,
|
"request_id": request_id}), type, client_id, request_id)
|
|
async_log_util.info(logger_local_huaxin_trade_debug, "API回调结束 req_id-{} request_id-{}", req_id, request_id)
|
else:
|
async_log_util.info(logger_local_huaxin_trade_debug, "非API回调 req_id-{}", req_id)
|
send_response(
|
json.dumps({"type": "trade_callback", "data": {"code": 0, "data": data, "type": type}}),
|
type,
|
None,
|
req_id)
|
except Exception as e:
|
logging.exception(e)
|
|
|
# 采用异步回调
|
def traderapi_callback(type, req_id, data):
|
__traderapi_callback(type, req_id, data)
|
|
|
req_rid_dict = {}
|
|
|
class TradeSimpleApi:
|
req_id = 0
|
__buy_sinfo_set = set()
|
__sell_sinfo_set = set()
|
__cancel_buy_sinfo_set = set()
|
__cancel_sell_sinfo_set = set()
|
|
def __init__(self, UserID, Password, SZSE_ShareHolderID, SSE_ShareHolderID, api: traderapi.CTORATstpTraderApi):
|
"""
|
|
:param SZSE_ShareHolderID: 深证投资者代码
|
:param SSE_ShareHolderID: 上证投资者代码
|
:param api: 交易接口
|
"""
|
self.UserID = UserID
|
self.Password = Password
|
self.SZSE_ShareHolderID = SZSE_ShareHolderID
|
self.SSE_ShareHolderID = SSE_ShareHolderID
|
self.api = api
|
|
|
@classmethod
|
def set_login_info(cls, session_id, front_id):
|
cls.__session_id = session_id
|
cls.__front_id = front_id
|
|
# sinfo char(32)
|
def buy(self, code, count, price, sinfo, order_ref, shadow_price=None):
|
if not ENABLE_ORDER:
|
return
|
if sinfo in self.__buy_sinfo_set:
|
raise Exception(f'下单请求已经提交:{sinfo}')
|
async_log_util.info(logger_trade, f"{code}华鑫本地真实下单开始")
|
async_log_util.info(logger_local_huaxin_trade_debug,
|
f"进入买入方法:code-{code} sinfo-{sinfo} order_ref-{order_ref}")
|
self.__buy_sinfo_set.add(sinfo)
|
self.req_id += 1
|
# 请求报单
|
req_field = traderapi.CTORATstpInputOrderField()
|
# TORA_TSTP_EXD_COMM(0): 通用(内部使用)
|
# TORA_TSTP_EXD_SSE(1): 上海交易所
|
# TORA_TSTP_EXD_SZSE(2): 深圳交易所
|
# TORA_TSTP_EXD_HK(3): 香港交易所
|
# TORA_TSTP_EXD_BSE(4): 北京证券交易所
|
if tool.get_market_type(code) == tool.MARKET_TYPE_SZSE:
|
req_field.ExchangeID = traderapi.TORA_TSTP_EXD_SZSE
|
req_field.ShareholderID = self.SZSE_ShareHolderID
|
elif tool.get_market_type(code) == tool.MARKET_TYPE_SSE:
|
req_field.ExchangeID = traderapi.TORA_TSTP_EXD_SSE
|
req_field.ShareholderID = self.SSE_ShareHolderID
|
|
# 证券代码
|
req_field.SecurityID = code
|
req_field.Direction = traderapi.TORA_TSTP_D_Buy
|
req_field.VolumeTotalOriginal = count
|
req_field.SInfo = sinfo
|
req_field.OrderRef = order_ref
|
|
'''
|
上交所支持限价指令和最优五档剩撤、最优五档剩转限两种市价指令,对于科创板额外支持本方最优和对手方最优两种市价指令和盘后固定价格申报指令
|
深交所支持限价指令和立即成交剩余撤销、全额成交或撤销、本方最优、对手方最优和最优五档剩撤五种市价指令
|
限价指令和上交所科创板盘后固定价格申报指令需填写报单价格,其它市价指令无需填写报单价格
|
以下以上交所限价指令为例,其它指令参考开发指南相关说明填写OrderPriceType、TimeCondition和VolumeCondition三个字段:
|
'''
|
req_field.LimitPrice = price
|
req_field.OrderPriceType = traderapi.TORA_TSTP_OPT_LimitPrice
|
req_field.TimeCondition = traderapi.TORA_TSTP_TC_GFD
|
req_field.VolumeCondition = traderapi.TORA_TSTP_VC_AV
|
|
'''
|
OrderRef为报单引用,类型为整型,该字段报单时为选填
|
若不填写,则系统会为每笔报单自动分配一个报单引用
|
若填写,则需保证同一个TCP会话下报单引用严格单调递增,不要求连续递增,至少需从1开始编号
|
'''
|
# req_field.OrderRef = 1
|
|
'''
|
InvestorID为选填,若填写则需保证填写正确
|
Operway为委托方式,根据券商要求填写,无特殊说明置空即可
|
终端自定义字段,终端可根据需要填写如下字段的值,该字段值不会被柜台系统修改,在报单回报和查询报单时返回给终端
|
'''
|
# req_field.SInfo = 'sinfo'
|
# req_field.IInfo = 123
|
|
'''
|
其它字段置空
|
'''
|
# 给L2发送消息
|
|
ret = self.api.ReqOrderInsert(req_field, self.req_id)
|
if ret != 0:
|
raise Exception('ReqOrderInsert fail, ret[%d]' % ret)
|
# 常态化监听不需要单独设置
|
# if queue_other_w_l2_r is not None:
|
# queue_other_w_l2_r.put_nowait(
|
# json.dumps({"type": "listen_volume", "data": {"code": code,
|
# "volume": count}}).encode(
|
# 'utf-8'))
|
async_log_util.info(logger_trade, f"{code}华鑫本地真实下单结束")
|
# --------------------------------影子订单--------------------------------
|
if shadow_price:
|
if order_ref:
|
# 下一个影子订单
|
shadow_order_ref = order_ref + 1
|
shadow_sinfo = f"s_b_{order_ref}"
|
req_field.LimitPrice = shadow_price
|
req_field.SInfo = shadow_sinfo
|
req_field.OrderRef = shadow_order_ref
|
req_field.VolumeTotalOriginal = 100
|
self.req_id += 1
|
ret = self.api.ReqOrderInsert(req_field, self.req_id)
|
if ret != 0:
|
raise Exception('ReqOrderInsert fail, ret[%d]' % ret)
|
# 影子订单撤单
|
# 撤掉影子单
|
shadow_cancel_order_ref = shadow_order_ref + 1
|
# 深证停留50ms上证停留200ms
|
delay_s = 0.05 if code.find("00") == 0 else 0.2
|
self.cancel_buy(code, f"s_c_{shadow_order_ref}", order_sys_id=None,
|
order_ref=shadow_order_ref,
|
order_action_ref=None, delay_s=delay_s)
|
|
return ret
|
|
# 撤买
|
def cancel_buy(self, code, sinfo, order_sys_id=None, order_ref=None, order_action_ref=None, delay_s=0.0):
|
if delay_s > 0:
|
time.sleep(delay_s)
|
if sinfo in self.__cancel_buy_sinfo_set:
|
raise Exception(f'撤单请求已经提交:{sinfo}')
|
async_log_util.info(logger_local_huaxin_trade_debug,
|
f"进入撤单方法:code-{code} order_sys_id-{order_sys_id} order_ref-{order_ref} sinfo-{sinfo}")
|
self.__cancel_buy_sinfo_set.add(sinfo)
|
self.req_id += 1
|
# 请求撤单
|
req_field = traderapi.CTORATstpInputOrderActionField()
|
if code.find('00') == 0:
|
req_field.ExchangeID = traderapi.TORA_TSTP_EXD_SZSE
|
elif code.find('60') == 0:
|
req_field.ExchangeID = traderapi.TORA_TSTP_EXD_SSE
|
|
req_field.ActionFlag = traderapi.TORA_TSTP_AF_Delete
|
|
# 撤单支持以下两种方式定位原始报单:
|
# (1)报单引用方式
|
# req_field.FrontID = self.__front_id
|
# req_field.SessionID = self.__session_id
|
# req_field.OrderRef = 1
|
# (2)系统报单编号方式
|
if order_sys_id:
|
req_field.OrderSysID = order_sys_id
|
elif order_ref is not None:
|
req_field.OrderRef = order_ref
|
req_field.SessionID = self.__session_id
|
req_field.FrontID = self.__front_id
|
if order_action_ref:
|
req_field.OrderActionRef = order_action_ref
|
|
# OrderActionRef报单操作引用,用法同报单引用,可根据需要选填
|
|
'''
|
终端自定义字段,终端可根据需要填写如下字段的值,该字段值不会被柜台系统修改,在查询撤单时返回给终端
|
'''
|
req_field.SInfo = sinfo
|
# req_field.IInfo = 123
|
|
'''
|
委托方式字段根据券商要求填写,无特殊说明置空即可
|
其它字段置空
|
'''
|
ret = self.api.ReqOrderAction(req_field, self.req_id)
|
if ret != 0:
|
raise Exception('ReqOrderAction fail, ret[%d]' % ret)
|
return
|
|
# 卖
|
def sell(self, code, count, price, price_type, sinfo, order_ref=None):
|
if sinfo in self.__sell_sinfo_set:
|
raise Exception(f'下单请求已经提交:{sinfo}')
|
self.__sell_sinfo_set.add(sinfo)
|
self.req_id += 1
|
# 请求报单
|
req_field = traderapi.CTORATstpInputOrderField()
|
# TORA_TSTP_EXD_COMM(0): 通用(内部使用)
|
# TORA_TSTP_EXD_SSE(1): 上海交易所
|
# TORA_TSTP_EXD_SZSE(2): 深圳交易所
|
# TORA_TSTP_EXD_HK(3): 香港交易所
|
# TORA_TSTP_EXD_BSE(4): 北京证券交易所
|
if tool.get_market_type(code) == tool.MARKET_TYPE_SZSE:
|
req_field.ExchangeID = traderapi.TORA_TSTP_EXD_SZSE
|
req_field.ShareholderID = self.SZSE_ShareHolderID
|
elif tool.get_market_type(code) == tool.MARKET_TYPE_SSE:
|
req_field.ExchangeID = traderapi.TORA_TSTP_EXD_SSE
|
req_field.ShareholderID = self.SSE_ShareHolderID
|
|
# 证券代码
|
req_field.SecurityID = code
|
req_field.Direction = traderapi.TORA_TSTP_D_Sell
|
req_field.VolumeTotalOriginal = count
|
req_field.SInfo = sinfo
|
|
'''
|
上交所支持限价指令和最优五档剩撤、最优五档剩转限两种市价指令,对于科创板额外支持本方最优和对手方最优两种市价指令和盘后固定价格申报指令
|
深交所支持限价指令和立即成交剩余撤销、全额成交或撤销、本方最优、对手方最优和最优五档剩撤五种市价指令
|
限价指令和上交所科创板盘后固定价格申报指令需填写报单价格,其它市价指令无需填写报单价格
|
以下以上交所限价指令为例,其它指令参考开发指南相关说明填写OrderPriceType、TimeCondition和VolumeCondition三个字段:
|
'''
|
|
printlog('卖 price', price, price_type)
|
if price and price > 0:
|
req_field.LimitPrice = price
|
if price_type == 1:
|
req_field.OrderPriceType = traderapi.TORA_TSTP_OPT_AnyPrice
|
elif price_type == 2:
|
req_field.OrderPriceType = traderapi.TORA_TSTP_OPT_LimitPrice
|
elif price_type == 3:
|
req_field.OrderPriceType = traderapi.TORA_TSTP_OPT_BestPrice
|
elif price_type == 4:
|
req_field.OrderPriceType = traderapi.TORA_TSTP_OPT_FixPrice
|
elif price_type == 5:
|
req_field.OrderPriceType = traderapi.TORA_TSTP_OPT_FiveLevelPrice
|
elif price_type == 6:
|
req_field.OrderPriceType = traderapi.TORA_TSTP_OPT_HomeBestPrice
|
|
req_field.TimeCondition = traderapi.TORA_TSTP_TC_GFD
|
req_field.VolumeCondition = traderapi.TORA_TSTP_VC_AV
|
if order_ref:
|
req_field.OrderRef = order_ref
|
|
'''
|
OrderRef为报单引用,类型为整型,该字段报单时为选填
|
若不填写,则系统会为每笔报单自动分配一个报单引用
|
若填写,则需保证同一个TCP会话下报单引用严格单调递增,不要求连续递增,至少需从1开始编号
|
'''
|
# req_field.OrderRef = 1
|
|
'''
|
InvestorID为选填,若填写则需保证填写正确
|
Operway为委托方式,根据券商要求填写,无特殊说明置空即可
|
终端自定义字段,终端可根据需要填写如下字段的值,该字段值不会被柜台系统修改,在报单回报和查询报单时返回给终端
|
'''
|
# req_field.SInfo = 'sinfo'
|
# req_field.IInfo = 123
|
|
'''
|
其它字段置空
|
'''
|
ret = self.api.ReqOrderInsert(req_field, self.req_id)
|
if ret != 0:
|
raise Exception('ReqOrderInsert fail, ret[%d]' % ret)
|
return
|
|
# 撤卖
|
def cancel_sell(self, code, order_sys_id, sinfo):
|
if sinfo in self.__cancel_sell_sinfo_set:
|
raise Exception(f'撤单请求已经提交:{sinfo}')
|
self.__cancel_sell_sinfo_set.add(sinfo)
|
self.req_id += 1
|
# 请求撤单
|
req_field = traderapi.CTORATstpInputOrderActionField()
|
if code.find('00') == 0:
|
req_field.ExchangeID = traderapi.TORA_TSTP_EXD_SZSE
|
elif code.find('60') == 0:
|
req_field.ExchangeID = traderapi.TORA_TSTP_EXD_SSE
|
|
req_field.ActionFlag = traderapi.TORA_TSTP_AF_Delete
|
|
# 撤单支持以下两种方式定位原始报单:
|
# (1)报单引用方式
|
# req_field.FrontID = self.__front_id
|
# req_field.SessionID = self.__session_id
|
# req_field.OrderRef = 1
|
# (2)系统报单编号方式
|
req_field.OrderSysID = order_sys_id
|
|
# OrderActionRef报单操作引用,用法同报单引用,可根据需要选填
|
|
'''
|
终端自定义字段,终端可根据需要填写如下字段的值,该字段值不会被柜台系统修改,在查询撤单时返回给终端
|
'''
|
req_field.SInfo = sinfo
|
# req_field.IInfo = 123
|
|
'''
|
委托方式字段根据券商要求填写,无特殊说明置空即可
|
其它字段置空
|
'''
|
ret = self.api.ReqOrderAction(req_field, self.req_id)
|
if ret != 0:
|
raise Exception('ReqOrderAction fail, ret[%d]' % ret)
|
return
|
|
# 查询当日可撤销的委托
|
def list_delegate_orders(self, is_cancel):
|
self.req_id += 1
|
req_id = self.req_id
|
req_field = traderapi.CTORATstpQryOrderField()
|
# 以下字段不填表示不设过滤条件,即查询所有报单
|
# req_field.SecurityID = '600000'
|
req_field.InsertTimeStart = '09:15:00'
|
req_field.InsertTimeEnd = '15:00:00'
|
# IsCancel字段填1表示只查询可撤报单
|
if is_cancel:
|
req_field.IsCancel = 1
|
# req_field.SInfo = sinfo
|
ret = self.api.ReqQryOrder(req_field, req_id)
|
if ret != 0:
|
raise Exception('ReqQryOrder fail, ret[%d]' % ret)
|
return req_id
|
|
# 查询当日成交的订单
|
def list_traded_orders(self):
|
self.req_id += 1
|
req_id = self.req_id
|
req_field = traderapi.CTORATstpQryTradeField()
|
ret = self.api.ReqQryTrade(req_field, req_id)
|
if ret != 0:
|
raise Exception('ReqQryTrade fail, ret[%d]' % ret)
|
return req_id
|
|
# 查询持仓
|
def list_positions(self):
|
self.req_id += 1
|
req_id = self.req_id
|
req_field = traderapi.CTORATstpQryPositionField()
|
ret = self.api.ReqQryPosition(req_field, req_id)
|
if ret != 0:
|
raise Exception('ReqQryPosition fail, ret[%d]' % ret)
|
return req_id
|
|
# 查询资金账户
|
def get_money_account(self):
|
self.req_id += 1
|
req_id = self.req_id
|
req_field = traderapi.CTORATstpQryTradingAccountField()
|
req_field.CurrencyID = traderapi.TORA_TSTP_CID_CNY
|
ret = self.api.ReqQryTradingAccount(req_field, req_id)
|
if ret != 0:
|
raise Exception('ReqQryTradingAccount fail, ret[%d]' % ret)
|
return req_id
|
|
def login(self):
|
# 请求登录
|
login_req = traderapi.CTORATstpReqUserLoginField()
|
|
# 支持以用户代码、资金账号和股东账号方式登录
|
# (1)以用户代码方式登录
|
login_req.LogInAccount = self.UserID
|
login_req.LogInAccountType = traderapi.TORA_TSTP_LACT_UserID
|
# (2)以资金账号方式登录
|
# login_req.DepartmentID = DepartmentID
|
# login_req.LogInAccount = AccountID
|
# login_req.LogInAccountType = traderapi.TORA_TSTP_LACT_AccountID
|
# (3)以上海股东账号方式登录
|
# login_req.LogInAccount = SSE_ShareHolderID
|
# login_req.LogInAccountType = traderapi.TORA_TSTP_LACT_SHAStock
|
# (4)以深圳股东账号方式登录
|
# login_req.LogInAccount = SZSE_ShareHolderID
|
# login_req.LogInAccountType = traderapi.TORA_TSTP_LACT_SZAStock
|
|
# 支持以密码和指纹(移动设备)方式认证
|
# (1)密码认证
|
# 密码认证时AuthMode可不填
|
# login_req.AuthMode = traderapi.TORA_TSTP_AM_Password
|
login_req.Password = self.Password
|
# (2)指纹认证
|
# 非密码认证时AuthMode必填
|
# login_req.AuthMode = traderapi.TORA_TSTP_AM_FingerPrint
|
# login_req.DeviceID = '03873902'
|
# login_req.CertSerial = '9FAC09383D3920CAEFF039'
|
|
# 终端信息采集
|
# UserProductInfo填写终端名称
|
login_req.UserProductInfo = 'jiabei'
|
# 按照监管要求填写终端信息
|
login_req.TerminalInfo = 'PC;IIP=123.112.154.118;IPORT=50361;LIP=192.168.118.107;MAC=54EE750B1713FCF8AE5CBD58;HD=TF655AY91GHRVL'
|
# 以下内外网IP地址若不填则柜台系统自动采集,若填写则以终端填值为准报送
|
# login_req.MacAddress = '5C-87-9C-96-F3-E3'
|
# login_req.InnerIPAddress = '10.0.1.102'
|
# login_req.OuterIPAddress = '58.246.43.50'
|
|
TradeSimpleApi.req_id += 1
|
ret = self.api.ReqUserLogin(login_req, TradeSimpleApi.req_id)
|
if ret != 0:
|
raise Exception('ReqUserLogin fail, ret[%d]' % ret)
|
|
|
class MyTradeActionCallback(TradeActionCallback):
|
trade_thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=30)
|
|
def __init__(self, UserID, Password, SZSE_ShareHolderID, SSE_ShareHolderID, api: traderapi.CTORATstpTraderApi):
|
self.__tradeSimpleApi = TradeSimpleApi(UserID, Password, SZSE_ShareHolderID, SSE_ShareHolderID, api)
|
|
|
def OnTrade(self, client_id, request_id, sk, type_, data):
|
if type_ == 1:
|
async_log_util.info(logger_local_huaxin_trade_debug,
|
f"\n---------------------\n请求下单:client_id-{client_id} request_id-{request_id} data:{data}")
|
# 下单
|
# 1-买 2-卖
|
direction = data["direction"]
|
code = data["code"]
|
volume = data["volume"]
|
price = data["price"]
|
sinfo = data["sinfo"]
|
order_ref = data.get("order_ref")
|
shadow_price = data.get("shadow_price")
|
blocking = data.get("blocking")
|
|
if direction == 1:
|
async_log_util.info(logger_trade, f"{code}华鑫本地开始下单")
|
# 买
|
try:
|
if blocking:
|
req_rid_dict[sinfo] = (client_id, request_id, sk, order_ref)
|
# threading.Thread(target=lambda: self.__tradeSimpleApi.buy(code, volume, price, sinfo, order_ref),
|
# daemon=True).start()
|
self.trade_thread_pool.submit(self.__tradeSimpleApi.buy, code, volume, price, sinfo, order_ref,
|
shadow_price)
|
|
async_log_util.info(logger_trade, f"{code}华鑫本地下单线程结束")
|
except Exception as e:
|
send_response(json.dumps({"code": 1, "msg": str(e)}), TYPE_ORDER, client_id,
|
request_id)
|
async_log_util.info(logger_local_huaxin_trade_debug,
|
f"买入结束:code-{code} sinfo-{sinfo}")
|
elif direction == 2:
|
try:
|
price_type = data["price_type"]
|
if blocking:
|
req_rid_dict[sinfo] = (client_id, request_id, sk)
|
self.__tradeSimpleApi.sell(code, volume, price, price_type, sinfo, order_ref)
|
printlog("sell", req_rid_dict)
|
except Exception as e:
|
logging.exception(e)
|
send_response(json.dumps({"code": 1, "msg": str(e)}), TYPE_ORDER, client_id,
|
request_id)
|
|
elif type_ == 2:
|
async_log_util.info(logger_local_huaxin_trade_debug,
|
f"\n---------------------\n请求撤单:client_id-{client_id} request_id-{request_id} data-{data}")
|
# 撤单
|
direction = data["direction"]
|
code = data["code"]
|
orderSysID = data.get("orderSysID")
|
orderRef = data.get("orderRef")
|
orderActionRef = data.get("orderActionRef")
|
sinfo = data["sinfo"]
|
if direction == 1:
|
# 撤买
|
try:
|
if not orderSysID and orderRef is None:
|
raise Exception("没有找到系统订单号或者报单引用")
|
req_rid_dict[sinfo] = (client_id, request_id, sk)
|
self.trade_thread_pool.submit(
|
lambda: self.__tradeSimpleApi.cancel_buy(code, sinfo, order_sys_id=orderSysID,
|
order_ref=orderRef, order_action_ref=orderActionRef))
|
async_log_util.info(logger_local_huaxin_trade_debug,
|
f"撤单结束:code-{code} order_sys_id-{orderSysID} sinfo-{sinfo}")
|
except Exception as e:
|
send_response(json.dumps({"code": 1, "msg": str(e)}), TYPE_CANCEL_ORDER, client_id,
|
request_id)
|
|
elif direction == 2:
|
# 撤卖
|
try:
|
req_rid_dict[sinfo] = (client_id, request_id, sk)
|
self.__tradeSimpleApi.cancel_sell(code, orderSysID, sinfo)
|
except Exception as e:
|
send_response(json.dumps({"code": 1, "msg": str(e)}), TYPE_CANCEL_ORDER, client_id,
|
request_id)
|
|
def OnDealList(self, client_id, request_id, sk):
|
async_log_util.info(logger_local_huaxin_trade_debug, f"请求成交列表:client_id-{client_id} request_id-{request_id}")
|
try:
|
# printlog("开始请求成交列表")
|
req_id = self.__tradeSimpleApi.list_traded_orders()
|
req_rid_dict[req_id] = (client_id, request_id, sk)
|
except Exception as e:
|
logging.exception(e)
|
SendResponseSkManager.send_error_response("common", request_id, client_id, str(e))
|
|
def OnDelegateList(self, client_id, request_id, sk, is_cancel):
|
async_log_util.info(logger_local_huaxin_trade_debug, f"请求委托列表:client_id-{client_id} request_id-{request_id}")
|
try:
|
req_id = self.__tradeSimpleApi.list_delegate_orders(is_cancel)
|
req_rid_dict[req_id] = (client_id, request_id, sk)
|
except Exception as e:
|
send_response(json.dumps({"code": 1, "msg": str(e)}), "common", client_id,
|
request_id)
|
|
def OnMoney(self, client_id, request_id, sk):
|
async_log_util.info(logger_local_huaxin_trade_debug, f"请求账户:client_id-{client_id} request_id-{request_id}")
|
try:
|
req_id = self.__tradeSimpleApi.get_money_account()
|
req_rid_dict[req_id] = (client_id, request_id, sk)
|
except Exception as e:
|
send_response(json.dumps({"code": 1, "msg": str(e)}), "common", client_id,
|
request_id)
|
|
def OnPositionList(self, client_id, request_id, sk):
|
async_log_util.info(logger_local_huaxin_trade_debug, f"请求持仓:client_id-{client_id} request_id-{request_id}")
|
try:
|
req_id = self.__tradeSimpleApi.list_positions()
|
req_rid_dict[req_id] = (client_id, request_id, sk)
|
except Exception as e:
|
send_response(json.dumps({"code": 1, "msg": str(e)}), "common", client_id,
|
request_id)
|
|
def OnTest(self, client_id, request_id, data, sk):
|
send_response(
|
json.dumps({"type": "response", "data": {"code": 0, "data": data}, "client_id": client_id,
|
"request_id": request_id}), type, client_id, request_id, show_log=False, sk=sk)
|