1. 连接UFT接口后,报如下错误

选择恒生UFT网关,连接后就报如下错误:

KeyError: ('TradeDate',)

At:
  D:\ProgramFiles\VnStudio\lib\site-packages\vnpy\gateway\uft\uft_gateway.py(728): update_trade
  D:\ProgramFiles\VnStudio\lib\site-packages\vnpy\gateway\uft\uft_gateway.py(502): onRspQryTrade

2. 错误的位置

错误位置是gateway\uft\uft_gateway.py的728行:

    def update_trade(self, data: dict) -> None:
        """"""
        symbol = data["InstrumentID"]
        exchange = EXCHANGE_UFT2VT[data["ExchangeID"]]
        sessionid = data["SessionID"]
        order_ref = data["OrderRef"]
        orderid = f"{sessionid}_{order_ref}"

        order = self.orders.get(orderid, None)
        if order:
            order.traded += data["TradeVolume"]

            if order.traded < order.volume:
                order.status = Status.PARTTRADED
            else:
                order.status = Status.ALLTRADED

            self.gateway.on_order(order)

        trade_time = generate_time(data["TradeTime"])
        timestamp = f"{data['TradeDate']} {trade_time}"         # 就是这里的TradeDate出错,意思是没有该字典项目
        dt = datetime.strptime(timestamp, "%H:%M:%S")
        dt = CHINA_TZ.localize(dt)

        trade = TradeData(
            symbol=symbol,
            exchange=exchange,
            orderid=orderid,
            tradeid=data["TradeID"],
            direction=DIRECTION_UFT2VT[data["Direction"]],
            offset=OFFSET_UFT2VT[data["OffsetFlag"]],
            price=data["TradePrice"],
            volume=data["TradeVolume"],
            datetime=dt,
            gateway_name=self.gateway_name
        )
        self.gateway.on_trade(trade)

3. CHSTradeField中的交易日叫’TradingDay‘不叫’TradeDate‘

找到api\uft\include\HSStruct.h中的CHSTradeField,发现CHSTradeField结构中没有TradeDate字段,应该是TradingDay字段。

///成交信息
struct CHSTradeField
{
    /// 账号
    HSAccountID                   AccountID;
    /// 成交编码
    HSTradeID                     TradeID;
    /// 报单编码
    HSOrderSysID                  OrderSysID;
    /// 经纪公司报单编码
    HSBrokerOrderID               BrokerOrderID;
    /// 会话编码
    HSSessionID                   SessionID;
    /// 报单引用
    HSRef                         OrderRef;
    /// 交易所代码
    HSExchangeID                  ExchangeID;
    /// 合约代码
    HSInstrumentID                InstrumentID;
    /// 买卖方向
    HSDirection                   Direction;
    /// 开平标志
    HSOffsetFlag                  OffsetFlag;
    /// 投机/套保/备兑类型
    HSHedgeType                   HedgeType;
    /// 成交数量
    HSVolume                      TradeVolume;
    /// 成交价格
    HSPrice                       TradePrice;
    /// 交易日
    HSDate                        TradingDay;   # 这里是交易日 !!!
    /// 成交时间
    HSTime                        TradeTime;
    /// 期权对应的标的合约代码
    HSInstrumentID                UnderlyingInstrID;
};

4. 如何修改错误

打开gateway\uft\uft_gateway.py中UftTdApi的这个update_trade()函数做如下修改就OK了:

    def update_trade(self, data: dict) -> None:
        """"""
        symbol = data["InstrumentID"]
        exchange = EXCHANGE_UFT2VT[data["ExchangeID"]]
        sessionid = data["SessionID"]
        order_ref = data["OrderRef"]
        orderid = f"{sessionid}_{order_ref}"

        order = self.orders.get(orderid, None)
        if order:
            order.traded += data["TradeVolume"]

            if order.traded < order.volume:
                order.status = Status.PARTTRADED
            else:
                order.status = Status.ALLTRADED

            self.gateway.on_order(order)

        trade_time = generate_time(data["TradeTime"])
        # timestamp = f"{data['TradeDate']} {trade_time}"   # hxxjava debug 不是TradeDate
        timestamp = f"{data['TradingDay']} {trade_time}"    # hxxjava debug 是TradingDay
        # dt = datetime.strptime(timestamp, "%H:%M:%S")     # hxxjava 日期提取格式不对
        dt = datetime.strptime(timestamp, "%Y%m%d %H:%M:%S") # hxxjava 日期提取格式 %Y%m%d %H:%M:%S
        dt = CHINA_TZ.localize(dt)

        trade = TradeData(
            symbol=symbol,
            exchange=exchange,
            orderid=orderid,
            tradeid=data["TradeID"],
            direction=DIRECTION_UFT2VT[data["Direction"]],
            offset=OFFSET_UFT2VT[data["OffsetFlag"]],
            price=data["TradePrice"],
            volume=data["TradeVolume"],
            datetime=dt,
            gateway_name=self.gateway_name
        )
        self.gateway.on_trade(trade)