diff --git a/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.cpp b/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.cpp index ead42f4f..4ec0ddc9 100644 --- a/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.cpp +++ b/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.cpp @@ -53,7 +53,6 @@ void MdApi::OnRspUserLogin(CUstpFtdcRspUserLoginField *pRspUserLogin, CUstpFtdcR } if (pRspInfo) { - cout << "md OnRspUserLogin pRspInfo" << endl; CUstpFtdcRspInfoField *task_error = new CUstpFtdcRspInfoField(); *task_error = *pRspInfo; task.task_error = task_error; @@ -314,7 +313,6 @@ void MdApi::processRspUserLogin(Task *task) dict error; if (task->task_error) { - cout << "md processRspUserLogin task_error" << endl; CUstpFtdcRspInfoField *task_error = (CUstpFtdcRspInfoField*)task->task_error; error["ErrorID"] = task_error->ErrorID; error["ErrorMsg"] = toUtf(task_error->ErrorMsg); diff --git a/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj b/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj index 7d639493..dea02d7d 100644 --- a/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj +++ b/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj @@ -80,8 +80,8 @@ true - C:\ProgramData\VNConda\include;$(SolutionDir);$(SolutionDir)..\include;$(SolutionDir)..\include\femas;$(IncludePath) - C:\ProgramData\VNConda\libs;$(SolutionDir)..\libs;$(LibraryPath) + C:\Python37\include;$(SolutionDir);$(SolutionDir)..\include;$(SolutionDir)..\include\femas;$(IncludePath) + C:\Python37\libs;$(SolutionDir)..\libs;$(LibraryPath) .pyd $(SolutionDir)..\ @@ -95,10 +95,10 @@ false - C:\ProgramData\VNConda\include;$(SolutionDir);$(SolutionDir)..\include;$(SolutionDir)..\include\femas;$(IncludePath) + C:\Python37\include;$(SolutionDir);$(SolutionDir)..\include;$(SolutionDir)..\include\femas;$(IncludePath) $(ReferencePath) .pyd - C:\ProgramData\VNConda\libs;$(SolutionDir)..\libs;$(LibraryPath) + C:\Python37\libs;$(SolutionDir)..\libs;$(LibraryPath) $(SolutionDir)..\ @@ -110,6 +110,7 @@ NOMINMAX;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;VNFEMASMD_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true stdafx.h + true Console @@ -125,6 +126,7 @@ NOMINMAX;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_DEBUG;VNFEMASMD_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true stdafx.h + true Console @@ -145,6 +147,9 @@ true stdafx.h MultiThreaded + true + AnySuitable + Speed Console @@ -167,6 +172,9 @@ stdafx.h MultiThreaded + true + AnySuitable + Speed Console diff --git a/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj.filters b/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj.filters index 8578d85d..6f061d28 100644 --- a/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj.filters +++ b/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj.filters @@ -21,24 +21,24 @@ 头文件 - - 头文件 - - - 头文件 - - - 头文件 - - - 头文件 - 头文件 头文件 + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + diff --git a/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj.user b/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj.user index be250787..baf24173 100644 --- a/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj.user +++ b/vnpy/api/femas/vnfemas/vnfemasmd/vnfemasmd.vcxproj.user @@ -1,4 +1,6 @@  - + + false + \ No newline at end of file diff --git a/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.cpp b/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.cpp index e02fcda5..a071f8c1 100644 --- a/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.cpp +++ b/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.cpp @@ -91,11 +91,8 @@ void TdApi::OnRspUserLogin(CUstpFtdcRspUserLoginField *pRspUserLogin, CUstpFtdcR } if (pRspInfo) { - cout << "td OnRspUserLogin pRspInfo" << endl; CUstpFtdcRspInfoField *task_error = new CUstpFtdcRspInfoField(); *task_error = *pRspInfo; - cout << "td OnRspUserLogin pRspInfo errorid" <ErrorID << endl; task.task_error = task_error; } task.task_id = nRequestID; @@ -630,15 +627,12 @@ void TdApi::OnRspQryInvestorAccount(CUstpFtdcRspInvestorAccountField *pRspInvest task.task_name = ONRSPQRYINVESTORACCOUNT; if (pRspInvestorAccount) { - cout << "OnRspQryInvestorAccount" << endl; - cout << pRspInvestorAccount->AccountID << endl; CUstpFtdcRspInvestorAccountField *task_data = new CUstpFtdcRspInvestorAccountField(); *task_data = *pRspInvestorAccount; task.task_data = task_data; } if (pRspInfo) { - cout << pRspInfo->ErrorMsg << endl; CUstpFtdcRspInfoField *task_error = new CUstpFtdcRspInfoField(); *task_error = *pRspInfo; task.task_error = task_error; @@ -1427,7 +1421,6 @@ void TdApi::processRspUserLogin(Task *task) dict error; if (task->task_error) { - cout << "td processRspUserLogin task_error" << endl; CUstpFtdcRspInfoField *task_error = (CUstpFtdcRspInfoField*)task->task_error; error["ErrorID"] = task_error->ErrorID; error["ErrorMsg"] = toUtf(task_error->ErrorMsg); diff --git a/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj b/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj index 73b0ea91..8fc2e28a 100644 --- a/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj +++ b/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj @@ -80,8 +80,8 @@ true - C:\ProgramData\VNConda\include;$(SolutionDir);$(SolutionDir)..\include;$(SolutionDir)..\include\femas;$(IncludePath) - C:\ProgramData\VNConda\libs;$(SolutionDir)..\libs;$(LibraryPath) + C:\Python37\include;$(SolutionDir);$(SolutionDir)..\include;$(SolutionDir)..\include\femas;$(IncludePath) + C:\Python37\libs;$(SolutionDir)..\libs;$(LibraryPath) .pyd $(SolutionDir)..\ @@ -95,8 +95,8 @@ false .pyd - C:\ProgramData\VNConda\include;$(SolutionDir);$(SolutionDir)..\include;$(SolutionDir)..\include\femas;$(IncludePath) - C:\ProgramData\VNConda\libs;$(SolutionDir)..\libs;$(LibraryPath) + C:\Python37\include;$(SolutionDir);$(SolutionDir)..\include;$(SolutionDir)..\include\femas;$(IncludePath) + C:\Python37\libs;$(SolutionDir)..\libs;$(LibraryPath) $(SolutionDir)..\ @@ -108,6 +108,7 @@ NOMINMAX;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;VNFEMASTD_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true stdafx.h + true Console @@ -123,6 +124,7 @@ NOMINMAX;_CRT_SECURE_NO_WARNINGS;_DEBUG;VNFEMASTD_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true stdafx.h + true Console @@ -142,6 +144,9 @@ true stdafx.h MultiThreaded + true + AnySuitable + Speed Console @@ -164,6 +169,9 @@ stdafx.h MultiThreaded + true + AnySuitable + Speed Console diff --git a/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj.filters b/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj.filters index e3ccc39a..ffdc3ec2 100644 --- a/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj.filters +++ b/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj.filters @@ -21,21 +21,21 @@ 头文件 - - 头文件 - - - 头文件 - - - 头文件 - - - 头文件 - 头文件 + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + diff --git a/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj.user b/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj.user index be250787..baf24173 100644 --- a/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj.user +++ b/vnpy/api/femas/vnfemas/vnfemastd/vnfemastd.vcxproj.user @@ -1,4 +1,6 @@  - + + false + \ No newline at end of file diff --git a/vnpy/api/femas/vnfemasmd.pyd b/vnpy/api/femas/vnfemasmd.pyd index a833a8e6..42069546 100644 Binary files a/vnpy/api/femas/vnfemasmd.pyd and b/vnpy/api/femas/vnfemasmd.pyd differ diff --git a/vnpy/api/femas/vnfemastd.pyd b/vnpy/api/femas/vnfemastd.pyd index d835714c..13222642 100644 Binary files a/vnpy/api/femas/vnfemastd.pyd and b/vnpy/api/femas/vnfemastd.pyd differ diff --git a/vnpy/gateway/femas/femas_gateway.py b/vnpy/gateway/femas/femas_gateway.py index 53a97415..9e2acc3e 100644 --- a/vnpy/gateway/femas/femas_gateway.py +++ b/vnpy/gateway/femas/femas_gateway.py @@ -14,7 +14,7 @@ from vnpy.api.femas import ( USTP_FTDC_OS_PartTradedQueueing, USTP_FTDC_OS_AllTraded, USTP_FTDC_OS_Canceled, - USTP_FTDC_D_Buy, + USTP_FTDC_D_Buy, USTP_FTDC_D_Sell, USTP_FTDC_OPT_LimitPrice, USTP_FTDC_OPT_AnyPrice, @@ -30,7 +30,7 @@ from vnpy.api.femas import ( USTP_FTDC_VC_AV, USTP_FTDC_TC_IOC, USTP_FTDC_VC_CV, - USTP_FTDC_AF_Delete + USTP_FTDC_AF_Delete, ) from vnpy.trader.constant import ( Direction, @@ -39,7 +39,7 @@ from vnpy.trader.constant import ( OrderType, Product, Status, - OptionType + OptionType, ) from vnpy.trader.gateway import BaseGateway from vnpy.trader.object import ( @@ -56,8 +56,8 @@ from vnpy.trader.object import ( from vnpy.trader.utility import get_folder_path from vnpy.trader.event import EVENT_TIMER -USTP_FTDC_PD_Long = '2' -USTP_FTDC_PD_Short = '3' +USTP_FTDC_PD_Long = "2" +USTP_FTDC_PD_Short = "3" STATUS_FEMAS2VT = { USTP_FTDC_CAS_Submitted: Status.SUBMITTING, @@ -66,21 +66,21 @@ STATUS_FEMAS2VT = { USTP_FTDC_OS_NoTradeQueueing: Status.NOTTRADED, USTP_FTDC_OS_PartTradedQueueing: Status.PARTTRADED, USTP_FTDC_OS_AllTraded: Status.ALLTRADED, - USTP_FTDC_OS_Canceled: Status.CANCELLED + USTP_FTDC_OS_Canceled: Status.CANCELLED, } DIRECTION_VT2FEMAS = { - Direction.LONG: USTP_FTDC_D_Buy, - Direction.SHORT: USTP_FTDC_D_Sell + Direction.LONG: USTP_FTDC_D_Buy, + Direction.SHORT: USTP_FTDC_D_Sell, } ORDERTYPE_VT2FEMAS = { OrderType.LIMIT: USTP_FTDC_OPT_LimitPrice, - OrderType.MARKET: USTP_FTDC_OPT_AnyPrice + OrderType.MARKET: USTP_FTDC_OPT_AnyPrice, } OFFSET_VT2FEMAS = { - Offset.OPEN: USTP_FTDC_OF_Open, + Offset.OPEN: USTP_FTDC_OF_Open, Offset.CLOSE: USTP_FTDC_OF_Close, Offset.CLOSETODAY: USTP_FTDC_OF_CloseYesterday, Offset.CLOSEYESTERDAY: USTP_FTDC_OF_CloseToday, @@ -92,18 +92,17 @@ DIRECTION_FEMAS2VT[USTP_FTDC_PD_Long] = Direction.LONG DIRECTION_FEMAS2VT[USTP_FTDC_PD_Short] = Direction.SHORT - EXCHANGE_FEMAS2VT = { "CFFEX": Exchange.CFFEX, "SHFE": Exchange.SHFE, "CZCE": Exchange.CZCE, "DCE": Exchange.DCE, - "INE": Exchange.INE + "INE": Exchange.INE, } OPTIONTYPE_FEMAS2VT = { USTP_FTDC_OT_CallOptions: OptionType.CALL, - USTP_FTDC_OT_PutOptions: OptionType.PUT + USTP_FTDC_OT_PutOptions: OptionType.PUT, } @@ -122,7 +121,7 @@ class FemasGateway(BaseGateway): "password": "", "brokerid": "", "td_address": "", - "md_address": "" + "md_address": "", } def __init__(self, event_engine): @@ -140,15 +139,14 @@ class FemasGateway(BaseGateway): td_address = setting["td_address"] md_address = setting["md_address"] - if not td_address.startswith("tcp://"): td_address = "tcp://" + td_address if not md_address.startswith("tcp://"): md_address = "tcp://" + md_address - + self.td_api.connect(td_address, userid, password, brokerid) self.md_api.connect(md_address, userid, password, brokerid) - + self.init_query() def subscribe(self, req: SubscribeRequest): @@ -176,24 +174,31 @@ class FemasGateway(BaseGateway): self.td_api.close() self.md_api.close() - def write_error(self, msg: str, error: dict): - """""" - error_id = error["ErrorID"] - error_msg = error["ErrorMsg"] + def write_error(self, msg: str, error_id: int, error_msg: str): msg = f"{msg},代码:{error_id},信息:{error_msg}" - self.write_log(msg) - + self.write_log(msg) + + def if_error_write_error(self, msg: str, error: dict): + """ + 当有错误的时候就输出错误,并返回True + """ + error_id = error["ErrorID"] + if error_id: + error_msg = error["ErrorMsg"] + self.write_error(msg, error_id, error_msg) + return True + def process_timer_event(self, event): """""" self.count += 1 if self.count < 2: return self.count = 0 - + func = self.query_functions.pop(0) func() self.query_functions.append(func) - + def init_query(self): """""" self.count = 0 @@ -207,20 +212,20 @@ class FemasMdApi(MdApi): def __init__(self, gateway): """Constructor""" super(FemasMdApi, self).__init__() - + self.gateway = gateway self.gateway_name = gateway.gateway_name - + self.reqid = 0 - + self.connect_status = False self.login_status = False self.subscribed = set() - + self.userid = "" self.password = "" self.brokerid = 0 - + def onFrontConnected(self): """ Callback when front server is connected. @@ -241,28 +246,25 @@ class FemasMdApi(MdApi): """ Callback when user is logged in. """ - if not error["ErrorID"]: - self.login_status = True - self.gateway.write_log("onRspUserLogin行情服务器登录成功") - self.gateway.write_log("行情服务器登录成功") - - for symbol in self.subscribed: - self.subMarketData(symbol) - else: - self.gateway.write_error("行情登录失败", error) - + if self.gateway.if_error_write_error("行情登录失败", error): + return + self.login_status = True + self.gateway.write_log("onRspUserLogin行情服务器登录成功") + self.gateway.write_log("行情服务器登录成功") + + for symbol in self.subscribed: + self.subMarketData(symbol) + def onRspError(self, error: dict, reqid: int, last: bool): """ Callback when error occured. """ - self.gateway.write_error("行情接口报错", error) - + self.gateway.if_error_write_error("行情接口报错", error) + def onRspSubMarketData(self, data: dict, error: dict, reqid: int, last: bool): """""" - if not error or not error["ErrorID"]: + if self.gateway.if_error_write_error("行情订阅失败", error): return - - self.gateway.write_error("行情订阅失败", error) def onRtnDepthMarketData(self, data: dict): """ @@ -274,7 +276,7 @@ class FemasMdApi(MdApi): return timestamp = f"{data['TradingDay']} {data['UpdateTime']}.{int(data['UpdateMillisec']/100)}" - + tick = TickData( symbol=symbol, exchange=exchange, @@ -292,9 +294,9 @@ class FemasMdApi(MdApi): ask_price_1=data["AskPrice1"], bid_volume_1=data["BidVolume1"], ask_volume_1=data["AskVolume1"], - gateway_name=self.gateway_name + gateway_name=self.gateway_name, ) - self.gateway.on_tick(tick) + self.gateway.on_tick(tick) def connect(self, address: str, userid: str, password: str, brokerid: int): """ @@ -303,7 +305,7 @@ class FemasMdApi(MdApi): self.userid = userid self.password = password self.brokerid = brokerid - + # If not connected, then start connection first. if not self.connect_status: path = get_folder_path(self.gateway_name.lower()) @@ -315,7 +317,7 @@ class FemasMdApi(MdApi): # If already connected, then login immediately. elif not self.login_status: self.login() - + def login(self): """ Login onto server. @@ -323,12 +325,12 @@ class FemasMdApi(MdApi): req = { "UserID": self.userid, "Password": self.password, - "BrokerID": self.brokerid + "BrokerID": self.brokerid, } - + self.reqid += 1 self.reqUserLogin(req, self.reqid) - + def subscribe(self, req: SubscribeRequest): """ Subscribe to tick data update. @@ -336,7 +338,7 @@ class FemasMdApi(MdApi): if self.login_status: self.subMarketData(req.symbol) self.subscribed.add(req.symbol) - + def close(self): """ Close the connection. @@ -351,58 +353,59 @@ class FemasTdApi(TdApi): def __init__(self, gateway): """Constructor""" super(FemasTdApi, self).__init__() - + self.gateway = gateway self.gateway_name = gateway.gateway_name - - self.reqid = 0 - self.localID = 0 - + + self.reqid = int(10e5) + self.localID = int(10e5 + 8888) + self.connect_status = False self.login_status = False self.login_failed = False - + self.userid = "" self.password = "" self.brokerid = 0 - + self.order_data = [] self.trade_data = [] self.positions = {} self.sysid_orderid_map = {} - + def onFrontConnected(self): """""" self.connect_status = True self.gateway.write_log("onFrontConnected交易连接成功") self.login() - + def onFrontDisconnected(self, reason: int): """""" self.connect_status = False self.login_status = False self.gateway.write_log(f"交易连接断开,原因{reason}") - + def onRspUserLogin(self, data: dict, error: dict, reqid: int, last: bool): """""" if not error["ErrorID"]: - for k, v in data.items(): - print(k, ':', v) - - if data['MaxOrderLocalID']: - self.localID = int(data['MaxOrderLocalID']) # 目前最大本地报单号 + if data["MaxOrderLocalID"]: + self.localID = max( + self.localID, int(data["MaxOrderLocalID"]) + ) # 目前最大本地报单号 self.login_status = True self.gateway.write_log("onRspUserLogin交易登录成功") self.reqid += 1 self.reqQryInstrument({}, self.reqid) else: self.login_failed = True - - self.gateway.write_error("交易登录失败", error) - + + self.gateway.if_error_write_error("交易登录失败", error) + def onRspOrderInsert(self, data: dict, error: dict, reqid: int, last: bool): """""" + if self.gateway.if_error_write_error("交易委托失败", error): + return orderid = data["UserOrderLocalID"] symbol = data["InstrumentID"] @@ -416,34 +419,35 @@ class FemasTdApi(TdApi): price=data["LimitPrice"], volume=data["Volume"], status=Status.REJECTED, - gateway_name=self.gateway_name + gateway_name=self.gateway_name, ) self.gateway.on_order(order) - self.gateway.write_error("交易委托失败", error) - def onRspOrderAction(self, data: dict, error: dict, reqid: int, last: bool): """""" - self.gateway.write_error("交易撤单失败", error) - + if self.gateway.if_error_write_error("交易撤单失败", error): + return + def onRspQueryMaxOrderVolume(self, data: dict, error: dict, reqid: int, last: bool): """""" pass - - def onRspSettlementInfoConfirm(self, data: dict, error: dict, reqid: int, last: bool): + + def onRspSettlementInfoConfirm( + self, data: dict, error: dict, reqid: int, last: bool + ): """ Callback of settlment info confimation. """ self.gateway.write_log("结算信息确认成功") - + self.reqid += 1 self.reqQryInstrument({}, self.reqid) - + def onRspQryInvestorPosition(self, data: dict, error: dict, reqid: int, last: bool): """""" if not data: return - + # Get buffered position object key = f"{data['InstrumentID'], data['Direction']}" position = self.positions.get(key, None) @@ -452,50 +456,49 @@ class FemasTdApi(TdApi): symbol=data["InstrumentID"], exchange=symbol_exchange_map[data["InstrumentID"]], direction=DIRECTION_FEMAS2VT[data["Direction"]], - gateway_name=self.gateway_name + gateway_name=self.gateway_name, ) self.positions[key] = position position.yd_volume = data["YdPosition"] # Calculate previous position cost cost = position.price * position.volume - + # Update new position volume position.volume += data["Position"] - + # Calculate average position price if position.volume: cost += data["PositionCost"] position.price = cost / position.volume - + # Get frozen volume position.frozen += data["FrozenPosition"] - + if last: for position in self.positions.values(): self.gateway.on_position(position) - + self.positions.clear() - + def onRspQryInvestorAccount(self, data: dict, error: dict, reqid: int, last: bool): """""" - print ("onRspQryInvestorAccount") account = AccountData( accountid=data["AccountID"], - frozen = data['LongMargin']+data['ShortMargin'], - balance= data['PreBalance'], - gateway_name=self.gateway_name + frozen=data["LongMargin"] + data["ShortMargin"], + balance=data["PreBalance"], + gateway_name=self.gateway_name, ) - + # todo: check for error self.gateway.on_account(account) - + def onRspQryInstrument(self, data: dict, error: dict, reqid: int, last: bool): """ Callback of instrument query. """ contract = ContractData( - product = data["ProductID"], + product=data["ProductID"], symbol=data["InstrumentID"], exchange=EXCHANGE_FEMAS2VT[data["ExchangeID"]], name=data["InstrumentName"], @@ -505,15 +508,15 @@ class FemasTdApi(TdApi): option_type=OPTIONTYPE_FEMAS2VT.get(data["OptionsType"], None), option_strike=data["StrikePrice"], option_expiry=datetime.strptime(data["ExpireDate"], "%Y%m%d"), - gateway_name=self.gateway_name + gateway_name=self.gateway_name, ) - + self.gateway.on_contract(contract) - + symbol_exchange_map[contract.symbol] = contract.exchange symbol_name_map[contract.symbol] = contract.name symbol_size_map[contract.symbol] = contract.size - + if last: self.gateway.write_log("合约信息查询成功") @@ -522,7 +525,7 @@ class FemasTdApi(TdApi): Callback of order status update. """ # 更新最大报单编号 - self.localID = max(self.localID, int(data['UserOrderLocalID'])) # 检查并增加本地报单编号 + self.localID = max(self.localID, int(data["UserOrderLocalID"])) # 检查并增加本地报单编号 symbol = data["InstrumentID"] exchange = symbol_exchange_map.get(symbol, "") @@ -530,8 +533,7 @@ class FemasTdApi(TdApi): self.order_data.append(data) return - orderid = data['UserOrderLocalID'] - print ("---------onRtnOrder-----------") + orderid = data["UserOrderLocalID"] order = OrderData( symbol=symbol, exchange=exchange, @@ -543,12 +545,12 @@ class FemasTdApi(TdApi): traded=data["VolumeTraded"], status=STATUS_FEMAS2VT[data["OrderStatus"]], time=data["InsertTime"], - gateway_name=self.gateway_name + gateway_name=self.gateway_name, ) self.gateway.on_order(order) - + self.sysid_orderid_map[data["OrderSysID"]] = orderid - + def onRtnTrade(self, data: dict): """ Callback of trade status update. @@ -560,7 +562,7 @@ class FemasTdApi(TdApi): return orderid = self.sysid_orderid_map[data["OrderSysID"]] - + trade = TradeData( symbol=symbol, exchange=exchange, @@ -571,10 +573,10 @@ class FemasTdApi(TdApi): price=data["TradePrice"], volume=data["TradeVolume"], time=data["TradeTime"], - gateway_name=self.gateway_name + gateway_name=self.gateway_name, ) - self.gateway.on_trade(trade) - + self.gateway.on_trade(trade) + def connect(self, address: str, userid: str, password: str, brokerid: int): """ Start connection to server. @@ -584,21 +586,20 @@ class FemasTdApi(TdApi): self.brokerid = brokerid self.address = address - if not self.connect_status: path = get_folder_path(self.gateway_name.lower()) self.createFtdcTraderApi(str(path) + "\\Td") - + self.subscribePrivateTopic(0) self.subscribePublicTopic(0) self.subscribeUserTopic(0) - + self.registerFront(address) - self.init() + self.init() else: if not self.login_status: - self.login() - + self.login() + def login(self): """ Login onto server. @@ -609,22 +610,21 @@ class FemasTdApi(TdApi): req = { "UserID": self.userid, "Password": self.password, - "BrokerID": self.brokerid + "BrokerID": self.brokerid, } - + self.reqid += 1 self.reqUserLogin(req, self.reqid) - + def send_order(self, req: OrderRequest): """ Send new order. """ self.localID += 1 - strLocalID = str(self.localID) - print ('----femasgateway type' + str(req.type)) + strLocalID = str(self.localID).rjust(12, "0") femas_req = { "InstrumentID": req.symbol, - "ExchangeID": str(req.exchange).split('.')[1], + "ExchangeID": str(req.exchange).split(".")[1], "BrokerID": self.brokerid, "InvestorID": self.userid, "UserID": self.userid, @@ -639,55 +639,48 @@ class FemasTdApi(TdApi): "IsAutoSuspend": 0, "TimeCondition": USTP_FTDC_TC_GFD, "VolumeCondition": USTP_FTDC_VC_AV, - "MinVolume": 1 + "MinVolume": 1, } - + if req.type == OrderType.FAK: femas_req["OrderPriceType"] = USTP_FTDC_OPT_LimitPrice femas_req["TimeCondition"] = USTP_FTDC_TC_IOC femas_req["VolumeCondition"] = USTP_FTDC_VC_AV - print ("------------fak") elif req.type == OrderType.FOK: femas_req["OrderPriceType"] = USTP_FTDC_OPT_LimitPrice femas_req["TimeCondition"] = USTP_FTDC_TC_IOC femas_req["VolumeCondition"] = USTP_FTDC_VC_CV - print ("------------fok") - - for key in femas_req: - print(key + ':' + str(femas_req[key])) self.reqid += 1 self.reqOrderInsert(femas_req, self.reqid) - + orderid = femas_req["UserOrderLocalID"] req.volume = femas_req["Volume"] order = req.create_order_data(orderid, self.gateway_name) self.gateway.on_order(order) - + return order.vt_orderid - + def cancel_order(self, req: CancelRequest): """ Cancel existing order. """ self.localID += 1 strLocalID = str(self.localID) - print ('--cancel exchange--' + str(req.exchange).split('.')[1]) - print ('--cancel orderid--' + req.orderid) femas_req = { "InstrumentID": req.symbol, - "ExchangeID": str(req.exchange).split('.')[1], + "ExchangeID": str(req.exchange).split(".")[1], "UserOrderLocalID": req.orderid, "UserOrderActionLocalID": strLocalID, "ActionFlag": USTP_FTDC_AF_Delete, "BrokerID": self.brokerid, "InvestorID": self.userid, - "UserID": self.userid + "UserID": self.userid, } - + self.reqid += 1 self.reqOrderAction(femas_req, self.reqid) - + def query_account(self): """ Query account balance data. @@ -695,27 +688,27 @@ class FemasTdApi(TdApi): req = { "BrokerID": self.brokerid, "InvestorID": self.userid, - "UserID": self.userid + "UserID": self.userid, } self.reqid += 1 self.reqQryInvestorAccount(req, self.reqid) - + def query_position(self): """ Query position holding data. """ if not symbol_exchange_map: return - + req = { "BrokerID": self.brokerid, "InvestorID": self.userid, - "UserID": self.userid + "UserID": self.userid, } - - self.reqid += 1 + + self.reqid += 1 self.reqQryInvestorPosition(req, self.reqid) - + def close(self): """""" if self.connect_status: