# -*- coding: utf-8 -*-
|
import concurrent.futures
|
import threading
|
import time
|
|
import traderapi
|
|
# 正式账号
|
from huaxin_client import constant, trade_manager
|
from huaxin_client.command_manager import TradeCommandManager
|
from huaxin_client.trade_manager import TradeSimpleApi
|
from log_module import async_log_util
|
from log_module.log import logger_local_huaxin_trade_debug as logger, logger_system, logger_local_huaxin_trade_debug, \
|
logger_info, printlog
|
|
TEST_TRADE = True
|
|
########B类########
|
UserID = '388000013349'
|
# 登陆密码
|
Password = '110808'
|
# 投资者账户
|
InvestorID = '388000013349'
|
# 经济公司部门代码
|
DepartmentID = '0003'
|
# 资金账户
|
AccountID = '388000013349'
|
# 沪市股东账号
|
SSE_ShareHolderID = 'A641420991'
|
# 深市股东账号
|
SZSE_ShareHolderID = '0345104949'
|
|
LOCAL_IP = constant.LOCAL_IP
|
FRONT_ADDRESS = "tcp://192.168.84.31:6500"
|
FRONT_ADDRESS1 = "tcp://192.168.84.32:26500"
|
|
if TEST_TRADE:
|
# # 仿真
|
# from mylog import logger_trade_debug
|
#
|
UserID = '00032047'
|
# 登陆密码
|
Password = '59009218'
|
# 投资者账户
|
InvestorID = '00032047'
|
# 经济公司部门代码
|
DepartmentID = '0003'
|
# 资金账户
|
AccountID = '00032047'
|
# 沪市股东账号
|
SSE_ShareHolderID = 'A00032047'
|
# 深市股东账号
|
SZSE_ShareHolderID = '700032047'
|
|
|
class TraderSpi(traderapi.CTORATstpTraderSpi):
|
def __init__(self, api, callback):
|
traderapi.CTORATstpTraderSpi.__init__(self)
|
self.__api = api
|
self.__front_id = 0
|
self.__session_id = 0
|
self.__data_callback = callback
|
self.__temp_order_list_dict = {}
|
self.__temp_position_list_dict = {}
|
self.__temp_money_account_list_dict = {}
|
self.call_back_thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=10)
|
|
def OnFrontConnected(self) -> "void":
|
logger_info.debug('Trader OnFrontConnected')
|
|
# 获取终端信息
|
TradeSimpleApi.req_id += 1
|
|
ret = self.__api.ReqGetConnectionInfo(TradeSimpleApi.req_id)
|
if ret != 0:
|
printlog('ReqGetConnectionInfo fail, ret[%d]' % ret)
|
|
def OnFrontDisconnected(self, nReason: "int") -> "void":
|
printlog('OnFrontDisconnected: [%d]' % nReason)
|
|
def OnRspGetConnectionInfo(self, pConnectionInfoField: "CTORATstpConnectionInfoField",
|
pRspInfoField: "CTORATstpRspInfoField", nRequestID: "int") -> "void":
|
if pRspInfoField.ErrorID == 0:
|
logger.info('inner_ip_address[%s]' % pConnectionInfoField.InnerIPAddress)
|
logger.info('inner_port[%d]' % pConnectionInfoField.InnerPort)
|
logger.info('outer_ip_address[%s]' % pConnectionInfoField.OuterIPAddress)
|
logger.info('outer_port[%d]' % pConnectionInfoField.OuterPort)
|
logger.info('mac_address[%s]' % pConnectionInfoField.MacAddress)
|
|
# 请求登录
|
login_req = traderapi.CTORATstpReqUserLoginField()
|
|
# 支持以用户代码、资金账号和股东账号方式登录
|
# (1)以用户代码方式登录
|
login_req.LogInAccount = 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 = 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 = f'PC;IIP=NA;IPORT=NA;LIP={LOCAL_IP};MAC=5C6F69CC2B40;HD=004bc76004aff0882b9052ba0eb00506;@jiabei'
|
# 以下内外网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:
|
printlog('ReqUserLogin fail, ret[%d]' % ret)
|
else:
|
printlog('GetConnectionInfo fail, [%d] [%d] [%s]!!!' % (
|
nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
|
|
def OnRspUserLogin(self, pRspUserLoginField: "CTORATstpRspUserLoginField", pRspInfoField: "CTORATstpRspInfoField",
|
nRequestID: "int") -> "void":
|
if pRspInfoField.ErrorID == 0:
|
printlog('Login success! [%d]' % nRequestID)
|
self.__front_id = pRspUserLoginField.FrontID
|
self.__session_id = pRspUserLoginField.SessionID
|
# TradeSimpleApi.set_login_info(self.__session_id, self.__front_id)
|
|
# if 1:
|
# # 查询股东账号
|
# req_field = traderapi.CTORATstpQryShareholderAccountField()
|
#
|
# # 以下字段不填表示不设过滤条件,即查询所有股东账号
|
# # req_field.ExchangeID = traderapi.TORA_TSTP_EXD_SSE
|
#
|
# TradeSimpleApi.req_id += 1
|
# ret = api.ReqQryShareholderAccount(req_field, TradeSimpleApi.req_id)
|
# if ret != 0:
|
# logger_info.info('ReqQryShareholderAccount fail, ret[%d]' % ret)
|
|
else:
|
logger_info.info('Login fail!!! [%d] [%d] [%s]'
|
% (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
|
|
def OnRspUserPasswordUpdate(self, pUserPasswordUpdateField: "CTORATstpUserPasswordUpdateField",
|
pRspInfoField: "CTORATstpRspInfoField", nRequestID: "int") -> "void":
|
if pRspInfoField.ErrorID == 0:
|
printlog('OnRspUserPasswordUpdate: OK! [%d]' % nRequestID)
|
else:
|
printlog('OnRspUserPasswordUpdate: Error! [%d] [%d] [%s]'
|
% (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
|
|
def OnRspOrderInsert(self, pInputOrderField: "CTORATstpInputOrderField", pRspInfoField: "CTORATstpRspInfoField",
|
nRequestID: "int") -> "void":
|
try:
|
if pRspInfoField.ErrorID == 0:
|
async_log_util.info(logger_local_huaxin_trade_debug,
|
'[%d] OnRspOrderInsert: OK! [%d]' % (round(time.time() * 1000), nRequestID))
|
else:
|
async_log_util.error(logger_local_huaxin_trade_debug,
|
f"OnRspOrderInsert 报单出错:{pRspInfoField.ErrorID}-{pRspInfoField.ErrorMsg}")
|
self.call_back_thread_pool.submit(self.__data_callback, trade_manager.TYPE_ORDER, nRequestID,
|
{"sinfo": pInputOrderField.SInfo,
|
"orderStatus": -1,
|
"orderStatusMsg": pRspInfoField.ErrorMsg})
|
except:
|
pass
|
|
# 撤单响应
|
def OnRspOrderAction(self, pInputOrderActionField: "CTORATstpInputOrderActionField",
|
pRspInfoField: "CTORATstpRspInfoField", nRequestID: "int") -> "void":
|
try:
|
if pRspInfoField.ErrorID == 0:
|
async_log_util.info(logger_local_huaxin_trade_debug, 'OnRspOrderAction: OK! [%d]' % nRequestID)
|
self.call_back_thread_pool.submit(self.__data_callback, trade_manager.TYPE_CANCEL_ORDER, nRequestID,
|
{"sinfo": pInputOrderActionField.SInfo,
|
"orderSysID": pInputOrderActionField.OrderSysID,
|
"cancel": 1})
|
|
else:
|
async_log_util.info(logger_local_huaxin_trade_debug, 'OnRspOrderAction: Error! [%d] [%d] [%s]'
|
% (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
|
self.call_back_thread_pool.submit(self.__data_callback, trade_manager.TYPE_CANCEL_ORDER, nRequestID,
|
{"sinfo": pInputOrderActionField.SInfo,
|
"orderSysID": pInputOrderActionField.OrderSysID,
|
"cancel": 0, "errorID": pRspInfoField.ErrorID,
|
"errorMsg": pRspInfoField.ErrorMsg})
|
except:
|
pass
|
|
# 撤单错误回报
|
def OnErrRtnOrderAction(self, pInputOrderActionField: "CTORATstpInputOrderActionField",
|
pRspInfoField: "CTORATstpRspInfoField", nRequestID: "int") -> "void":
|
try:
|
if pInputOrderActionField and pRspInfoField:
|
async_log_util.info(logger_local_huaxin_trade_debug, 'OnErrRtnOrderAction: Error! [%d] [%d] [%d] [%s]'
|
% (nRequestID, pInputOrderActionField.OrderSysID,
|
pRspInfoField.ErrorID,
|
pRspInfoField.ErrorMsg))
|
except:
|
async_log_util.info(logger_local_huaxin_trade_debug, "OnErrRtnOrderAction: 撤单出错")
|
|
def OnRspInquiryJZFund(self, pRspInquiryJZFundField: "CTORATstpRspInquiryJZFundField",
|
pRspInfoField: "CTORATstpRspInfoField", nRequestID: "int") -> "void":
|
# try:
|
# if pRspInfoField.ErrorID == 0:
|
# logger.info('OnRspInquiryJZFund: OK! [%d] [%.2f] [%.2f]'
|
# % (nRequestID, pRspInquiryJZFundField.UsefulMoney, pRspInquiryJZFundField.FetchLimit))
|
# else:
|
# logger.info('OnRspInquiryJZFund: Error! [%d] [%d] [%s]'
|
# % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
|
# except:
|
# pass
|
pass
|
|
def OnRspTransferFund(self, pInputTransferFundField: "CTORATstpInputTransferFundField",
|
pRspInfoField: "CTORATstpRspInfoField", nRequestID: "int") -> "void":
|
# try:
|
# if pRspInfoField.ErrorID == 0:
|
# logger.info('OnRspTransferFund: OK! [%d]' % nRequestID)
|
# else:
|
# logger.info('OnRspTransferFund: Error! [%d] [%d] [%s]'
|
# % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
|
# except:
|
# pass
|
pass
|
|
def OnRtnOrder(self, pOrderField: "CTORATstpOrderField") -> "void":
|
try:
|
async_log_util.info(logger_local_huaxin_trade_debug,
|
'[%d] OnRtnOrder: SInfo[%s] InvestorID[%s] SecurityID[%s] OrderRef[%d] OrderLocalID[%s] LimitPrice[%.2f] VolumeTotalOriginal[%d] OrderSysID[%s] OrderStatus[%s] InsertTime[%s]'
|
% (round(time.time() * 1000), pOrderField.SInfo, pOrderField.InvestorID,
|
pOrderField.SecurityID,
|
pOrderField.OrderRef, pOrderField.OrderLocalID,
|
pOrderField.LimitPrice, pOrderField.VolumeTotalOriginal, pOrderField.OrderSysID,
|
pOrderField.OrderStatus, pOrderField.InsertTime))
|
if pOrderField.OrderStatus == traderapi.TORA_TSTP_OST_Unknown:
|
pass
|
# if queue_trade_w_l2_r is not None:
|
# queue_trade_w_l2_r.put_nowait(
|
# json.dumps({"type": "listen_volume", "data": {"code": pOrderField.SecurityID,
|
# "volume": pOrderField.VolumeTotalOriginal}}).encode(
|
# 'utf-8'))
|
else:
|
order_data = {"sinfo": pOrderField.SInfo, "securityID": pOrderField.SecurityID,
|
"orderLocalID": pOrderField.OrderLocalID,
|
"direction": pOrderField.Direction, "orderSysID": pOrderField.OrderSysID,
|
"insertTime": pOrderField.InsertTime, "insertDate": pOrderField.InsertDate,
|
"acceptTime": pOrderField.AcceptTime, "cancelTime": pOrderField.CancelTime,
|
"limitPrice": pOrderField.LimitPrice, "accountID": pOrderField.AccountID,
|
"orderRef": pOrderField.OrderRef, "turnover": pOrderField.Turnover,
|
"volume": pOrderField.VolumeTotalOriginal, "volumeTraded": pOrderField.VolumeTraded,
|
"orderStatus": pOrderField.OrderStatus,
|
"orderSubmitStatus": pOrderField.OrderSubmitStatus,
|
"statusMsg": pOrderField.StatusMsg}
|
self.call_back_thread_pool.submit(self.__data_callback, trade_manager.TYPE_ORDER, 0, order_data)
|
except Exception as e:
|
async_log_util.error(logger_local_huaxin_trade_debug, "OnRtnOrder 出错")
|
except:
|
async_log_util.error(logger_local_huaxin_trade_debug, "OnRtnOrder 出错")
|
|
def OnRtnTrade(self, pTradeField: "CTORATstpTradeField") -> "void":
|
try:
|
async_log_util.info(logger_local_huaxin_trade_debug,
|
'OnRtnTrade: TradeID[%s] InvestorID[%s] SecurityID[%s] OrderRef[%d] OrderLocalID[%s] Price[%.2f] Volume[%d]'
|
% (pTradeField.TradeID, pTradeField.InvestorID, pTradeField.SecurityID,
|
pTradeField.OrderRef, pTradeField.OrderLocalID, pTradeField.Price,
|
pTradeField.Volume))
|
except:
|
pass
|
|
def OnRtnMarketStatus(self, pMarketStatusField: "CTORATstpMarketStatusField") -> "void":
|
# TORA_TSTP_MKD_SHA(1): 上海A股
|
# TORA_TSTP_MKD_SZA(2): 深圳A股
|
# TORA_TSTP_MKD_BJMain(a):北京主板
|
|
# TORA_TSTP_MST_UnKnown( # ):未知
|
# TORA_TSTP_MST_BeforeTrading(0): 开盘前
|
# TORA_TSTP_MST_Continous(1): 连续交易
|
# TORA_TSTP_MST_Closed(2): 收盘
|
# TORA_TSTP_MST_OpenCallAuction(3): 开盘集合竞价
|
try:
|
logger.info('OnRtnMarketStatus: MarketID[%s] MarketStatus[%s]'
|
% (pMarketStatusField.MarketID, pMarketStatusField.MarketStatus))
|
except:
|
pass
|
|
def OnRspQrySecurity(self, pSecurityField: "CTORATstpSecurityField", pRspInfoField: "CTORATstpRspInfoField",
|
nRequestID: "int", bIsLast: "bool") -> "void":
|
if bIsLast != 1:
|
logger.info(
|
'OnRspQrySecurity[%d]: SecurityID[%s] SecurityName[%s] MarketID[%s] OrderUnit[%s] OpenDate[%s] UpperLimitPrice[%.2f] LowerLimitPrice[%.2f]'
|
% (nRequestID, pSecurityField.SecurityID, pSecurityField.SecurityName, pSecurityField.MarketID,
|
pSecurityField.OrderUnit, pSecurityField.OpenDate, pSecurityField.UpperLimitPrice,
|
pSecurityField.LowerLimitPrice))
|
else:
|
logger.info('查询合约结束[%d] ErrorID[%d] ErrorMsg[%s]'
|
% (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
|
|
def OnRspQryInvestor(self, pInvestorField: "CTORATstpInvestorField", pRspInfoField: "CTORATstpRspInfoField",
|
nRequestID: "int", bIsLast: "bool") -> "void":
|
if bIsLast != 1:
|
logger.info('OnRspQryInvestor[%d]: InvestorID[%s] InvestorName[%s] Operways[%s]'
|
% (nRequestID, pInvestorField.InvestorID, pInvestorField.InvestorName,
|
pInvestorField.Operways))
|
else:
|
logger.info('查询投资者结束[%d] ErrorID[%d] ErrorMsg[%s]'
|
% (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
|
|
def OnRspQryShareholderAccount(self, pShareholderAccountField: "CTORATstpShareholderAccountField",
|
pRspInfoField: "CTORATstpRspInfoField", nRequestID: "int",
|
bIsLast: "bool") -> "void":
|
if bIsLast != 1:
|
logger_local_huaxin_trade_debug.info(
|
'OnRspQryShareholderAccount[%d]: InvestorID[%s] ExchangeID[%s] ShareholderID[%s]'
|
% (nRequestID, pShareholderAccountField.InvestorID, pShareholderAccountField.ExchangeID,
|
pShareholderAccountField.ShareholderID))
|
else:
|
logger.info('查询股东账户结束[%d] ErrorID[%d] ErrorMsg[%s]'
|
% (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
|
|
def OnRspQryTradingAccount(self, pTradingAccountField: "CTORATstpTradingAccountField",
|
pRspInfoField: "CTORATstpRspInfoField", nRequestID: "int", bIsLast: "bool") -> "void":
|
try:
|
if nRequestID not in self.__temp_money_account_list_dict:
|
self.__temp_money_account_list_dict[nRequestID] = []
|
if bIsLast != 1:
|
self.__temp_money_account_list_dict[nRequestID].append(
|
{"departmentID": pTradingAccountField.DepartmentID, "investorID": pTradingAccountField.InvestorID,
|
"accountID": pTradingAccountField.AccountID, "currencyID": pTradingAccountField.CurrencyID,
|
"usefulMoney": round(pTradingAccountField.UsefulMoney, 2),
|
"frozenCash": round(pTradingAccountField.FrozenCash, 2),
|
"fetchLimit": round(pTradingAccountField.FetchLimit, 2),
|
"preDeposit": round(pTradingAccountField.PreDeposit, 2)})
|
# logger.info(
|
# 'OnRspQryTradingAccount[%d]: DepartmentID[%s] InvestorID[%s] AccountID[%s] CurrencyID[%s] UsefulMoney[%.2f] FetchLimit[%.2f]'
|
# % (nRequestID, pTradingAccountField.DepartmentID, pTradingAccountField.InvestorID,
|
# pTradingAccountField.AccountID, pTradingAccountField.CurrencyID,
|
# pTradingAccountField.UsefulMoney, pTradingAccountField.FetchLimit))
|
else:
|
results = self.__temp_money_account_list_dict.pop(nRequestID)
|
self.call_back_thread_pool.submit(self.__data_callback, trade_manager.TYPE_LIST_MONEY, nRequestID,
|
results)
|
# logger.info('查询资金账号结束[%d] ErrorID[%d] ErrorMsg[%s]'
|
# % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
|
except:
|
pass
|
|
def OnRspQryOrder(self, pOrderField: "CTORATstpOrderField", pRspInfoField: "CTORATstpRspInfoField",
|
nRequestID: "int", bIsLast: "bool") -> "void":
|
try:
|
if nRequestID not in self.__temp_order_list_dict:
|
self.__temp_order_list_dict[nRequestID] = []
|
if not bIsLast:
|
# logger.info(
|
# 'OnRspQryOrder[%d]: SecurityID[%s] OrderLocalID[%s] Direction[%s] OrderRef[%d] OrderSysID[%s] VolumeTraded[%d] OrderStatus[%s] OrderSubmitStatus[%s], StatusMsg[%s]'
|
# % (nRequestID, pOrderField.SecurityID, pOrderField.OrderLocalID, pOrderField.Direction,
|
# pOrderField.OrderRef, pOrderField.OrderSysID,
|
# pOrderField.VolumeTraded, pOrderField.OrderStatus, pOrderField.OrderSubmitStatus,
|
# pOrderField.StatusMsg))
|
self.__temp_order_list_dict[nRequestID].append(
|
{"securityID": pOrderField.SecurityID, "orderLocalID": pOrderField.OrderLocalID,
|
"direction": pOrderField.Direction, "orderSysID": pOrderField.OrderSysID,
|
"insertTime": pOrderField.InsertTime, "insertDate": pOrderField.InsertDate,
|
"acceptTime": pOrderField.AcceptTime, "cancelTime": pOrderField.CancelTime,
|
"limitPrice": pOrderField.LimitPrice, "accountID": pOrderField.AccountID,
|
"turnover": pOrderField.Turnover, "orderRef": pOrderField.OrderRef,
|
"volume": pOrderField.VolumeTotalOriginal,
|
"volumeTraded": pOrderField.VolumeTraded, "orderStatus": pOrderField.OrderStatus,
|
"orderSubmitStatus": pOrderField.OrderSubmitStatus, "statusMsg": pOrderField.StatusMsg})
|
else:
|
# logger.info('查询报单结束[%d] ErrorID[%d] ErrorMsg[%s]'
|
# % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
|
self.call_back_thread_pool.submit(self.__data_callback, trade_manager.TYPE_LIST_DELEGATE, nRequestID,
|
self.__temp_order_list_dict[nRequestID])
|
|
self.__temp_order_list_dict.pop(nRequestID)
|
except:
|
pass
|
|
def OnRspQryPosition(self, pPositionField: "CTORATstpPositionField", pRspInfoField: "CTORATstpRspInfoField",
|
nRequestID: "int", bIsLast: "bool") -> "void":
|
try:
|
if nRequestID not in self.__temp_position_list_dict:
|
self.__temp_position_list_dict[nRequestID] = []
|
if bIsLast != 1:
|
self.__temp_position_list_dict[nRequestID].append(
|
{"investorID": pPositionField.InvestorID, "tradingDay": pPositionField.TradingDay,
|
"securityName": pPositionField.SecurityName,
|
"securityID": pPositionField.SecurityID, "historyPos": pPositionField.HistoryPos,
|
"historyPosFrozen": pPositionField.HistoryPosFrozen,
|
"todayBSPos": pPositionField.TodayBSPos, "todayBSPosFrozen": pPositionField.TodayBSPosFrozen,
|
"historyPosPrice": pPositionField.HistoryPosPrice, "totalPosCost": pPositionField.TotalPosCost,
|
"prePosition": pPositionField.PrePosition, "availablePosition": pPositionField.AvailablePosition,
|
"currentPosition": pPositionField.CurrentPosition, "openPosCost": pPositionField.OpenPosCost,
|
"todayCommission": pPositionField.TodayCommission,
|
"todayTotalBuyAmount": pPositionField.TodayTotalBuyAmount,
|
"todayTotalSellAmount": pPositionField.TodayTotalSellAmount})
|
else:
|
# logger.info('查询持仓结束[%d] ErrorID[%d] ErrorMsg[%s]'
|
# % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
|
self.call_back_thread_pool.submit(self.__data_callback, trade_manager.TYPE_LIST_POSITION, nRequestID,
|
self.__temp_position_list_dict[nRequestID])
|
|
self.__temp_position_list_dict.pop(nRequestID)
|
except:
|
pass
|
|
# 成交回报,参数pTradeField是一个CTORATstpTradeField类对象
|
def OnRtnTrade(self, pTradeField: "CTORATstpTradeField") -> "void":
|
pass
|
# logger.info("OnRtnTrade")
|
|
# 查询成交响应,参数pTradeField是一个CTORATstpTradeField类对象
|
def OnRspQryTrade(self, pTradeField: "CTORATstpTradeField", pRspInfoField: "CTORATstpRspInfoField",
|
nRequestID: "int", bIsLast: "bool") -> "void":
|
try:
|
# logger.info("查询成交响应")
|
pass
|
if nRequestID not in self.__temp_order_list_dict:
|
self.__temp_order_list_dict[nRequestID] = []
|
if not bIsLast:
|
self.__temp_order_list_dict[nRequestID].append(
|
{"tradeID": pTradeField.TradeID, "securityID": pTradeField.SecurityID,
|
"orderLocalID": pTradeField.OrderLocalID,
|
"direction": pTradeField.Direction, "orderSysID": pTradeField.OrderSysID,
|
"price": pTradeField.Price,
|
"tradeTime": pTradeField.TradeTime,
|
"volume": pTradeField.Volume, "tradeDate": pTradeField.TradeDate,
|
"tradingDay": pTradeField.TradingDay,
|
"pbuID": pTradeField.PbuID, "accountID": pTradeField.AccountID})
|
else:
|
self.call_back_thread_pool.submit(self.__data_callback, trade_manager.TYPE_LIST_TRADED, nRequestID,
|
self.__temp_order_list_dict[nRequestID])
|
self.__temp_order_list_dict.pop(nRequestID)
|
except:
|
pass
|
|
|
def run(queue_strategy_w_trade_r, queue_strategy_w_trade_r_for_query, queue_result):
|
"""
|
交易运行
|
:param queue_strategy_w_trade_r:
|
:return:
|
"""
|
# -----------初始化交易环境---------------------
|
trade_manager.set_result_read_queue(queue_result)
|
api = traderapi.CTORATstpTraderApi.CreateTstpTraderApi('./flow', False)
|
# 创建回调对象
|
spi = TraderSpi(api, trade_manager.traderapi_callback)
|
|
# 注册回调接口
|
api.RegisterSpi(spi)
|
|
# 注册多个交易前置服务地址,用逗号隔开
|
# api.RegisterFront('tcp://10.0.1.101:6500,tcp://10.0.1.101:26500')
|
# 注册名字服务器地址,支持多服务地址逗号隔开
|
# api.RegisterNameServer('tcp://10.0.1.101:52370')
|
# api.RegisterNameServer('tcp://10.0.1.101:52370,tcp://10.0.1.101:62370')
|
|
if not TEST_TRADE: # 模拟环境,TCP 直连Front方式
|
# 注册单个交易前置服务地址
|
##B类服务器##
|
logger.info(f"注册交易地址:{FRONT_ADDRESS}/{FRONT_ADDRESS1}")
|
api.RegisterFront(FRONT_ADDRESS) # 正式环境主地址
|
api.RegisterFront(FRONT_ADDRESS1) # 正式环境备用地址
|
|
##A类服务器##
|
# api.RegisterFront("tcp://10.224.123.143:6500") # 正式环境主地址
|
# api.RegisterFront("tcp://10.224.123.147:26500") # 正式环境备用地址
|
|
# TD_TCP_FrontAddress = "tcp://210.14.72.21:4400" # 仿真交易环境
|
# TD_TCP_FrontAddress = "tcp://210.14.72.15:4400" # 24小时环境A套
|
# TD_TCP_FrontAddress="tcp://210.14.72.16:9500" #24小时环境B套
|
# api.RegisterFront(TD_TCP_FrontAddress)
|
# 注册多个交易前置服务地址,用逗号隔开 形如: api.RegisterFront("tcp://10.0.1.101:6500,tcp://10.0.1.101:26500")
|
# printlog("TD_TCP_FensAddress[sim or 24H]::%s\n" % TD_TCP_FrontAddress)
|
|
else: # 模拟环境,FENS名字服务器方式
|
TD_TCP_FrontAddress = "tcp://210.14.72.21:4400" # 仿真交易环境
|
# TD_TCP_FrontAddress="tcp://210.14.72.15:4400" #24小时环境A套
|
# TD_TCP_FrontAddress="tcp://210.14.72.16:9500" #24小时环境B套
|
api.RegisterFront(TD_TCP_FrontAddress)
|
# 注册多个交易前置服务地址,用逗号隔开 形如: api.RegisterFront("tcp://10.0.1.101:6500,tcp://10.0.1.101:26500")
|
printlog("TD_TCP_FensAddress[sim or 24H]::%s\n" % TD_TCP_FrontAddress)
|
|
# 订阅私有流
|
api.SubscribePrivateTopic(traderapi.TORA_TERT_QUICK)
|
# 订阅公有流
|
api.SubscribePublicTopic(traderapi.TORA_TERT_QUICK)
|
# 启动接口
|
api.Init()
|
|
threading.Thread(target=async_log_util.run_sync, daemon=True).start()
|
|
data_callback = trade_manager.MyTradeActionCallback(UserID, Password, SZSE_ShareHolderID, SSE_ShareHolderID, api)
|
# 不需要运行命令解析
|
tradeCommandManager = TradeCommandManager()
|
tradeCommandManager.init(
|
data_callback,
|
queue_strategy_w_trade_r, queue_strategy_w_trade_r_for_query)
|
logger_info.debug("全部初始化完成")
|
tradeCommandManager.run(True)
|
while True:
|
time.sleep(2)
|
|
|
if __name__ == "__main__":
|
pass
|