跳转到内容

事件合约订单示例

下面是事件合约订单的结构示例。示例重点是订单对象和回调。发送订单前,应先把 contract 设置为已经通过 reqContractDetails() 验证的具体事件合约。

from ibapi.order import Order
def build_event_limit_order():
order = Order()
order.action = "BUY" # 先用买入方向验证;ForecastEx 反向结果通常用另一张合约表达
order.orderType = "LMT" # 使用限价单
order.totalQuantity = 1 # 调试时先用最小数量
order.lmtPrice = 0.05 # 示例限价,实际必须参考买卖价和最小跳动
order.tif = "DAY" # 常见有效期,具体以该合约支持项为准
return order
class EventOrderApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
self.next_order_id = None
def nextValidId(self, orderId):
self.next_order_id = orderId
def openOrder(self, orderId, contract, order, orderState):
print("订单已被 TWS 接收:", orderId, contract.localSymbol, orderState.status)
def orderStatus(
self,
orderId,
status,
filled,
remaining,
avgFillPrice,
permId,
parentId,
lastFillPrice,
clientId,
whyHeld,
mktCapPrice,
):
print("订单状态:", orderId, status, "已成交", filled, "剩余", remaining)
def error(self, reqId, errorTime, errorCode, errorString, advancedOrderRejectJson=""):
print("错误:", reqId, errorCode, errorString)

发送订单:

if app.next_order_id is None:
raise RuntimeError("还没有收到 nextValidId,不能下单")
contract = build_gce_forecastex_contract() # 使用已确认合约
order = build_event_limit_order()
app.placeOrder(app.next_order_id, contract, order)
位置必须改吗说明
build_gce_forecastex_contract()必须替换为已经通过 reqContractDetails() 验证的事件合约。
order.action必须确认BUYSELL 的含义要结合事件合约方向理解。
order.totalQuantity必须确认调试时先用最小数量。
order.lmtPrice必须确认参考买卖价、最小跳动和订单保护。
order.tif建议确认不同产品可能支持不同有效期。

事件合约下单失败时,不要只看 placeOrder() 是否执行。placeOrder() 只是把订单发给 TWS,真正的接收、拒绝、成交状态都在回调里。

placeOrder() 成功调用
-> openOrder() 可能返回订单详情
-> orderStatus() 返回 Submitted / Cancelled / Filled 等状态
-> error() 返回权限、价格、合约或保护规则错误

如果 TWS 弹出人工确认窗口,程序会停在 TWS 的风控保护流程上。调试时应先在模拟账户确认订单保护设置,并保持订单规模极小。