Summary
TerminalLinkBrokerageModel.CanSubmitOrder rejects every order on a
SecurityType.Index security, even when the order is explicitly marked as an
EMSX CFD trade (TerminalLinkOrderProperties.IsCfdTrade = true). This blocks a
legitimate Bloomberg EMSX workflow: submitting a custom basket (e.g. a Morgan
Stanley basket swap) whose market data is delivered via B-Pipe as an index, by
providing the index ticker directly in the EMSX security field and booking the
ticket as a CFD/swap. In a standard (non-LEAN) EMSX ticket this is a normal,
supported booking flow.
Evidence
Common/Brokerages/TerminalLinkBrokerageModel.cs:27-33 -- _supportedSecurityTypes
is { Equity, Option, IndexOption, Future }; Index is absent, so
CanSubmitOrder (line 60) always returns false with NotSupported /
UnsupportedSecurityType for any Index order, regardless of order properties.
Tests/Common/Brokerages/TerminalLinkBrokerageModelTests.cs:43-49 -- the
existing test suite documents this as deliberate: "Index is data-only on
TerminalLink", with an explicit CannotSubmitOrder_ForUnsupportedSecurityTypes
case for SPX/SecurityType.Index. That assumption (index = data-only, never
order-eligible) is what this ticket contradicts for the CFD/basket-swap case.
Common/Orders/TerminalLinkOrderProperties.cs:102-111 -- IsCfdTrade is an
order-level flag (EMSX_CFD_FLAG) that is explicitly documented as
"applicable to trades on an order level, and does not populate on a per
security basis" -- i.e. the CFD booking type is independent of the security's
type, by design.
QuantConnect.TerminalLink/TerminalLinkBrokerage.cs:395-429 -- PlaceOrder
already sends EMSX_CFD_FLAG (via SetAdditionalProperties, populated from
IsCfdTrade) on the outgoing EMSX request, so the brokerage adapter itself
is fully wired for a CFD-flagged order on any security type. The block happens
earlier, at the engine-level CanSubmitOrder pre-flight check, before
PlaceOrder is ever reached.
QuantConnect.TerminalLink/TerminalLinkSymbolMapper.cs:468-479 -- Index
ticker resolution (e.g. "MSXXAI Index" -> Symbol.Create(ticker, SecurityType.Index, market)) is already implemented, so the symbol side of
this workflow works; only the brokerage-model gate blocks the order.
Repro
Reported live (conv 215475638579180, support plan Institution, deploy
L-60ec350cc89032ff271d9a04ecc009b8, 2026-08-25 14:37:36 UTC):
New Order Event: ... Symbol: MSXXAI Status: Invalid Quantity: 1 Message:
BrokerageModel declared unable to submit order: [1] Warning - Code:
NotSupported - The TerminalLinkBrokerageModel does not support Index security
type.
The algorithm added MSXXAI Index (a custom Morgan Stanley basket, market data
via B-Pipe as an index) as an Index security and submitted an order with
TerminalLinkOrderProperties { IsCfdTrade = true }, intending to route it as a
CFD/swap through EMSX -- the same thing a standard EMSX ticket allows by typing
the index ticker into the security field.
Proposed change
Relax TerminalLinkBrokerageModel._supportedSecurityTypes (or the
CanSubmitOrder check specifically) to allow SecurityType.Index at least when
order.Properties is TerminalLinkOrderProperties { IsCfdTrade: true }, so a
CFD-flagged index/basket order reaches PlaceOrder the same way a normal
EMSX ticket would accept it. Whether to gate this strictly on IsCfdTrade or
open Index up generally is an engineering call -- the existing
"Index is data-only" test comment suggests the restriction was written before
this CFD/basket-swap use case existed, not as a deliberate rejection of it.
Open questions
- Does EMSX itself require the CFD flag to accept an index ticker in the
security field, or does it accept a plain index ticket too (customer's
description of "a normal EMSX ticket" suggests the ticker itself is always
accepted; the CFD flag only changes the booking type)? If the latter, the fix
may not need to be conditioned on IsCfdTrade at all.
- Should
IndexOption's underlying Index security (already added implicitly
for IndexOption support) be distinguished from a directly-tradable Index like
this basket, or is a blanket allow sufficient?
Intercom conversation: 215475638579180
Summary
TerminalLinkBrokerageModel.CanSubmitOrderrejects every order on aSecurityType.Indexsecurity, even when the order is explicitly marked as anEMSX CFD trade (
TerminalLinkOrderProperties.IsCfdTrade = true). This blocks alegitimate Bloomberg EMSX workflow: submitting a custom basket (e.g. a Morgan
Stanley basket swap) whose market data is delivered via B-Pipe as an index, by
providing the index ticker directly in the EMSX security field and booking the
ticket as a CFD/swap. In a standard (non-LEAN) EMSX ticket this is a normal,
supported booking flow.
Evidence
Common/Brokerages/TerminalLinkBrokerageModel.cs:27-33--_supportedSecurityTypesis
{ Equity, Option, IndexOption, Future };Indexis absent, soCanSubmitOrder(line 60) always returnsfalsewithNotSupported/UnsupportedSecurityTypefor any Index order, regardless of order properties.Tests/Common/Brokerages/TerminalLinkBrokerageModelTests.cs:43-49-- theexisting test suite documents this as deliberate: "Index is data-only on
TerminalLink", with an explicit
CannotSubmitOrder_ForUnsupportedSecurityTypescase for
SPX/SecurityType.Index. That assumption (index = data-only, neverorder-eligible) is what this ticket contradicts for the CFD/basket-swap case.
Common/Orders/TerminalLinkOrderProperties.cs:102-111--IsCfdTradeis anorder-level flag (
EMSX_CFD_FLAG) that is explicitly documented as"applicable to trades on an order level, and does not populate on a per
security basis" -- i.e. the CFD booking type is independent of the security's
type, by design.
QuantConnect.TerminalLink/TerminalLinkBrokerage.cs:395-429--PlaceOrderalready sends
EMSX_CFD_FLAG(viaSetAdditionalProperties, populated fromIsCfdTrade) on the outgoing EMSX request, so the brokerage adapter itselfis fully wired for a CFD-flagged order on any security type. The block happens
earlier, at the engine-level
CanSubmitOrderpre-flight check, beforePlaceOrderis ever reached.QuantConnect.TerminalLink/TerminalLinkSymbolMapper.cs:468-479-- Indexticker resolution (e.g.
"MSXXAI Index"->Symbol.Create(ticker, SecurityType.Index, market)) is already implemented, so the symbol side ofthis workflow works; only the brokerage-model gate blocks the order.
Repro
Reported live (conv 215475638579180, support plan Institution, deploy
L-60ec350cc89032ff271d9a04ecc009b8, 2026-08-25 14:37:36 UTC):The algorithm added
MSXXAI Index(a custom Morgan Stanley basket, market datavia B-Pipe as an index) as an Index security and submitted an order with
TerminalLinkOrderProperties { IsCfdTrade = true }, intending to route it as aCFD/swap through EMSX -- the same thing a standard EMSX ticket allows by typing
the index ticker into the security field.
Proposed change
Relax
TerminalLinkBrokerageModel._supportedSecurityTypes(or theCanSubmitOrdercheck specifically) to allowSecurityType.Indexat least whenorder.Properties is TerminalLinkOrderProperties { IsCfdTrade: true }, so aCFD-flagged index/basket order reaches
PlaceOrderthe same way a normalEMSX ticket would accept it. Whether to gate this strictly on
IsCfdTradeoropen
Indexup generally is an engineering call -- the existing"Index is data-only" test comment suggests the restriction was written before
this CFD/basket-swap use case existed, not as a deliberate rejection of it.
Open questions
security field, or does it accept a plain index ticket too (customer's
description of "a normal EMSX ticket" suggests the ticker itself is always
accepted; the CFD flag only changes the booking type)? If the latter, the fix
may not need to be conditioned on
IsCfdTradeat all.IndexOption's underlyingIndexsecurity (already added implicitlyfor IndexOption support) be distinguished from a directly-tradable Index like
this basket, or is a blanket allow sufficient?
Intercom conversation: 215475638579180