EMS API¶
The Execution Management System API surface manages placement creation, response handling, strategy selection, RFQ workflows, and transaction cost analysis. All operations go through the sidecar on localhost:9191 and are routed to the order-book kernel via command topics.
There is no UpdatePlacement operation. To modify a placement, cancel it and create a new one.
Placement Management¶
CreatePlacement¶
Creates a placement (child order) for execution at a venue. The parent order must be in PRE_TRADE_COMPLIANCE_PASSED or ROUTED state. Transitions the order to ROUTED if not already.
placement_id = client.ems.create_placement(
order_id=order_id,
broker_id="BRK-GS",
venue="XNYS",
strategy="VWAP", # VWAP | TWAP | IS | POV | DMA | Care | RFQ
quantity=500,
params=[
{"name": "StartTime", "type": "UTCTimestamp", "value": "09:30:00"},
{"name": "EndTime", "type": "UTCTimestamp", "value": "16:00:00"},
{"name": "MaxPctVolume", "type": "Percentage", "value": "0.05"},
],
)
placementID, err := client.EMS.CreatePlacement(ctx, &ems.CreatePlacementRequest{
OrderID: orderID,
BrokerID: "BRK-GS",
Venue: "XNYS",
Strategy: "VWAP",
Quantity: decimal.NewFromFloat(500),
Params: []ems.StrategyParam{
{Name: "StartTime", Type: "UTCTimestamp", Value: "09:30:00"},
{Name: "EndTime", Type: "UTCTimestamp", Value: "16:00:00"},
},
})
Errors: ORDER_NOT_FOUND, INVALID_STATE, INVALID_VENUE.
CancelPlacement¶
Cancels an active placement. There is no modify path; cancel and re-create.
Errors: PLACEMENT_NOT_FOUND, ALREADY_CANCELED.
CloseOrder¶
Closes the parent order when execution is complete. Returns executed and unfilled quantities for remainder order creation.
result = client.ems.close_order(order_id=order_id)
# result.executed_quantity -> Decimal("500")
# result.unfilled_quantity -> Decimal("0")
Response Management¶
Responses represent venue events against a placement: fills, quotes, rejections, and amendments. CCM plugins typically create responses when they receive execution reports from venues.
CreateResponse¶
Records a venue response against a placement.
response_id = client.ems.create_response(
placement_id=placement_id,
status="FILLED", # see 10-state lifecycle below
filled_quantity=500,
filled_price=150.12,
venue="XNYS",
)
responseID, err := client.EMS.CreateResponse(ctx, &ems.CreateResponseRequest{
PlacementID: placementID,
Status: ems.ResponseFilled,
FilledQuantity: decimal.NewFromFloat(500),
FilledPrice: decimal.NewFromFloat(150.12),
Venue: "XNYS",
})
UpdateResponseStatus¶
Transitions a response to a new state.
AmendResponse¶
Amends the quantity or price of a response. Amended responses can be re-amended.
CancelResponse¶
Cancels a response. Transitions to CANCELLED.
Strategy Wheel¶
SelectStrategy¶
Recommends a broker, algorithm, and parameters for an order based on market context. The result is advisory; the caller may override.
selection = client.ems.select_strategy(
order=order,
market_context={"volatility": 0.23, "spread_bps": 2.5, "adv": 5_000_000},
)
# selection.broker_id -> "BRK-GS"
# selection.algo -> "VWAP"
# selection.params -> [{"name": "MaxPctVolume", "value": "0.05"}]
# selection.confidence -> 0.82
ListBrokers¶
Lists brokers available for a given asset class.
brokers = client.ems.list_brokers(asset_class="EQUITY")
# [{"broker_id": "BRK-GS", "name": "Goldman Sachs", ...}, ...]
ListStrategies¶
Lists execution strategies available from a broker for an asset class.
strategies = client.ems.list_strategies(broker_id="BRK-GS", asset_class="EQUITY")
# [{"name": "VWAP", "description": "Volume-weighted average price"}, ...]
GetStrategyParams¶
Returns the parameter schema for a broker's strategy.
schema = client.ems.get_strategy_params(broker_id="BRK-GS", strategy="VWAP")
# schema.params -> [{"name": "StartTime", "type": "UTCTimestamp", "required": True}, ...]
RFQ Workflow¶
Request-for-quote is a first-class execution paradigm for quote-driven markets (fixed income, FX, derivatives). An RFQ creates one placement per dealer with strategy RFQ.
RequestQuotes¶
rfq_id = client.ems.request_quotes(
order=order,
dealers=["BRK-TW", "BRK-MA", "BRK-BBG"], # Tradeweb, MarketAxess, Bloomberg
)
GetQuotes¶
Returns responses in QUOTED state for an RFQ.
quotes = client.ems.get_quotes(rfq_id=rfq_id)
for q in quotes:
print(f"{q.broker_id}: {q.filled_price} for {q.filled_quantity}")
SelectQuote¶
Accepts a quote. The selected response transitions to FILLED; all other responses for the same RFQ are automatically canceled.
TCA (Transaction Cost Analysis)¶
RecordTCAResult¶
Records transaction cost metrics against a response. At least one metric must be present.
client.ems.record_tca_result(
response_id=response_id,
metrics={
"implementation_shortfall": -0.0012,
"vwap_slippage": 0.0003,
"market_impact": 0.0008,
"timing_cost": 0.0002,
"spread_capture": 0.45,
"participation_rate": 0.03,
},
)
Real-Time Streams¶
SubscribeOrders¶
for event in client.ems.subscribe_orders(filter={"portfolio_id": "PORT-001"}):
print(event.order_id, event.old_state, "->", event.new_state)
SubscribeResponses¶
for event in client.ems.subscribe_responses(order_id=order_id):
print(event.response_id, event.status, event.filled_quantity)
SubscribePositions¶
for event in client.ems.subscribe_positions(portfolio_id="PORT-001"):
print(event.instrument_id, event.quantity, event.avg_price)
10-State Response Lifecycle¶
| # | State | Description |
|---|---|---|
| 1 | SENT |
Placement dispatched to venue |
| 2 | VIEWED |
Venue acknowledged receipt |
| 3 | QUOTED |
Dealer returned a quote (RFQ) |
| 4 | PARTIALLY_FILLED |
Some quantity executed |
| 5 | FILLED |
Full quantity executed |
| 6 | CONFIRMED |
Broker confirmed the fill |
| 7 | AMENDED |
Price or quantity amended (can be re-amended) |
| 8 | CANCELLED |
Response canceled |
| 9 | REJECTED |
Venue rejected the placement |
| 10 | EXPIRED |
Placement expired (time-in-force) |