Trayport COM Trade Connector
Features
custom-trayportConnector KeyNotes
Description
Trayport Connector is Windows console application running under .NET Framework 4.7.
It accepts incoming orders by FIX (Deltix FIX Dialect) and sends them further to Trayport via GV API.
On Ember side you should use Ember (ES5) Trade Connector to communicate with Trayport Connector app.
Shutdown
For graceful shutdown press Ctrl+Q
Time In Force
Unfortunately Trayport does not reject orders with wrong TIF.
For example, if instrument does not support IOC/FOK Time In Force order is silently open as GTC.
Rate Limits
A rate limiter prevents more than 25 trades per second for each provider. If more than 25 private order updates are received, the "Private quotes rate limit exceeded" error will be displayed. After one second, more order updates can be submitted.
TradeOrder Action
To use trade order action instead of order you need to fill quoteID in new order request. Supported two formats:
engineId#brokerId#orderIdorderId(in this case engId and brokerId will be set to0)
Also supported MiFID attributes like for Order action
Trayport Connector Deployment
Prerequisites
- Add
NEXUS_USERandNEXUS_PASSto env variables - Start
PowerShellas Administrator# update ExecutionPolicy if neededSet-ExecutionPolicy -ExecutionPolicy RemoteSigned
Download and Deploy Trayport connector
Define connector home, download and extract connector via script below:
PowerShell Script
$TrayportConnectorHome = "C:\TrayportConnector"
$TrayportConnectorVersion = "3.0.22"
$NexusPath = "https://nexus.deltixhub.com/repository/epm-rtc-public/QuantServer/Trade"
$DistributionArchive = "TrayportConnector-$TrayportConnectorVersion.zip"
$DistributionUrl = "$NexusPath/TrayportConnector/$TrayportConnectorVersion/$DistributionArchive"
# Nexus credentials - assuming that NEXUS_USER and NEXUS_PASS env variables are defined
$NexusPath = ConvertTo-SecureString $env:NEXUS_PASS -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential($env:NEXUS_USER, $NexusPath)
# create directory if not exist
New-Item -ItemType Directory -Force -Path $TrayportConnectorHome
# download connector distribution archive
Invoke-WebRequest -Uri $DistributionUrl `
-OutFile $home\Downloads\$DistributionArchive -Credential $Credential
# unzip downloaded connector distribution
Expand-Archive -Path $home\Downloads\$DistributionArchive -DestinationPath $TrayportConnectorHome
# create copy of appsettings.json
Copy-Item "$TrayportConnectorHome\config\appsettings.json" `
-Destination "$TrayportConnectorHome\config\appsettings.Production.json"
# setting-up client-side logging for GVAPI
$RegPath = 'HKCU:\Software\Trayport\GV8API1.0'
New-Item $RegPath -Force
New-ItemProperty -Path $RegPath -Name LogEnable -Value 1 -PropertyType DWORD -Force
New-ItemProperty -Path $RegPath -Name LogPath `
-Value $TrayportConnectorHome\gvlog -PropertyType String -Force
Configure Trayport Connector
Define valid settings in /config/appsettings.Production.json
Configure Ember Trade Connector
Add the Ember TC configuration to ember.conf
Symbology
Trayport connector expects symbol as instrument attributes concatenated with #:
<InstID>#<SeqSpan>#<FirstSequenceID>#<FirstSequenceItemID>#<SecondSequenceItemID>
Symbology for TradeOrder Action
For some brokers information for instrument is ignored.
Term Labels
Trayport connector support sending terms for Instrument Identifiers via 7000 custom attribute
or via SMD column with column name <attributeKey>7000.
Terms should be in following format: Label#Default#Type,Label#Default#Type
<TERM> Attributes
| Attribute | Description |
|---|---|
| Label | A label for the term. |
| Default | The default value for this term. |
| Type | The data type of the term. This attribute can have the following values: string, integer, double, dateTime, boolean |
NOTE: To avoid unexpected behavior please use one of the proposed method when set tag 7000
Schedule
FIX schedule is weekly and should be the same both in Ember TC config and in /config/QuickFix.cfg
| Parameter | Value |
|---|---|
| Time Zone | America/New_York |
| Start Day | Sunday |
| Start Time | 17:30:00 |
| End Day | Sunday |
| End Time | 17:00:00 |
| Daily Session? | No |
Configuration
Connector settings
The default connector settings are defined in appsettings.json file under /config folder.
Yor can override defaults in separate config file: appsettings.Production.json.
Settings option to generate info about instruments: SecurityDefinitionFolder: "path"
TermsMapping
TermsMapping allows defining, per BrokerID, default values for Account, RouteID and Terms
(see Term Labels) that are applied to outgoing orders automatically, without the
trading client having to send them explicitly via custom attributes 7000/7001/7002.
A per-order value received via custom attribute always takes precedence over a TermsMapping default.
An empty string value for Account or RouteID in the mapping blanks out that field for the given
broker rather than being ignored.
TermsMapping[] Attributes
| Attribute | Description |
|---|---|
| BrokerID | Broker ID this entry applies to. Required. |
| Account | Default account name for this broker. Optional. |
| RouteID | Default route ID for this broker. Optional. |
| Terms | Default term labels for this broker: array of TermLabel/TermDefault/TermType. Optional. |
Example:
"TermsMapping": [
{
"BrokerID": "37",
"Account": "SUB_ACCOUNT_A",
"RouteID": "671",
"Terms": [
{ "TermLabel": "Execution", "TermDefault": "", "TermType": "string" },
{ "TermLabel": "Customer", "TermDefault": "", "TermType": "string" }
]
},
{
"BrokerID": "36",
"RouteID": "371"
}
]
Timebase settings
| Parameter | Value |
|---|---|
| Host | Timebase host |
| Port | Timebase port |
| Username | Timebase username |
| Password | Timebase password |
| AttributeKey | Value that is prefix for “Symbol”, “Tradable” columns in timebase |
| SkipTradableField | If tradable column is not present or should be skipped value should be set to true. |
| ConnectionRetries | Number of attempts to connect to TimeBase at startup. After the last failed attempt the application stops. Default is 5. Failed attempts are retried every 3 seconds. |
| ListOfSpecificBrokers | Accepted array of broker ids where we should generate synthetix MLEG trade report. Use only if broker report only legs as executions |
| SecurityType | If specified during connection will be used specified security connection. Supported only "SSO" value |
SSO settings
| Parameter | Value |
|---|---|
| URI | Base URL |
| Scope | Scope |
KeyVault settings
Usernames, passwords and any other setting can be read from Azure Key Vault instead of being stored in config files. Set the value to a Key Vault reference:
"Connector": {
"Username": "vault:/trayport-jd-username",
"Password": "vault:/trayport-jd-password"
},
"Timebase": {
"Username": "vault:/timebase-client-id",
"Password": "vault:/datalayer-ce-client-secret"
}
Reference format: vault:/<secret-name> (latest version) or vault:/<secret-name>/<version> (a specific version).
References work in any configuration source: JSON files, environment variables (Connector__Password=vault:/trayport-jd-password)
and command line (--Connector:Password=vault:/trayport-jd-password).
References are resolved once at startup. The connector fails to start if a referenced secret cannot be read.
After rotating a secret in Key Vault, restart the connector.
Values read from Key Vault are used as-is (legacy EV... password decryption is not applied to them).
Key Vault access is configured in the KeyVault section:
| Parameter | Value |
|---|---|
| VaultUri | Key Vault URI, e.g. https://my-vault.vault.azure.net/. Required when references are used |
| AuthMode | Default, ManagedIdentity, ClientSecret or Certificate. Default: Default |
| TenantId | Microsoft Entra tenant ID. Required for ClientSecret and Certificate |
| ClientId | Application (client) ID. Required for ClientSecret and Certificate; for ManagedIdentity - user-assigned identity client ID (omit for system-assigned) |
| ClientSecret | Application client secret for ClientSecret mode. Can be EV-encrypted. Prefer passing it via the KeyVault__ClientSecret environment variable |
| CertificateThumbprint | Thumbprint of the application certificate for Certificate mode, looked up in LocalMachine\My, then CurrentUser\My |
Auth modes:
ManagedIdentity- recommended on Azure VMs, no bootstrap secret is required.Certificate- recommended for on-premises hosts. The certificate private key must be readable by the connector's account.ClientSecret- app registration with a client secret.Default- DefaultAzureCredential chain (environment, managed identity, Azure CLI, Visual Studio, etc.). Useful for development.
The identity needs only read access to secrets: the Key Vault Secrets User role (RBAC) or the Get secret permission (access policies).
KeyVault settings themselves cannot be Key Vault references.
Example:
"KeyVault": {
"VaultUri": "https://my-vault.vault.azure.net/",
"AuthMode": "Certificate",
"TenantId": "00000000-0000-0000-0000-000000000000",
"ClientId": "00000000-0000-0000-0000-000000000000",
"CertificateThumbprint": "0123456789ABCDEF0123456789ABCDEF01234567"
}
Supported order attributes
| Name | Custom tag | Description |
|---|---|---|
| Terms for Instrument Identifiers | 7000 | See Symbology section for details. |
| AccountName | 7001 | The name of the trading account associated with this order, if applicable. |
| RouteID | 7002 | ID of the route to market used to place the order, if applicable |
| DecisionMaker | 7010 | Code used to identify the person or algorithm within the company who is responsible for the investment decision. |
| ExecutionMaker | 7011 | Code used to identify the person or algorithm within the company who is responsible for the execution. |
| DerivativeIndicator | 7012 | Specify true if the transaction reduces risk in an objectively measurable way. |
| DEA | 7013 | Specify true if the order is being submitted to the trading venue using Direct Electronic Access (DEA) |
| DEAClientID | 7014 | If DEA is used, the code of the DEA user must be specified in this field. |
| LiquidityProvision | 7015 | Specify true if the order is submitted to a trading venue as part of a market making strategy. |
| TradingCapacity | 7016 | Specifies whether the order results from the counterparty carrying out matched principal trading |
| Status | 7020 | The type of order. Valid values are: Firm, Withheld, Reference |
| CompanyID | 7021 | The ID of the company. This is an integer and must be a valid company ID. |
| BrokerID | 7022 | The ID of the broker to which you are submitting this order. This is an integer and must be a valid broker ID. |
| AllOrNone | 7023 | The all or none status of the order. To submit the order on an all or none basis, set this attribute to true |
| JDMemo | 7123 | Value that will reflect back to sender in trades and orders. Only for TradeOrder. |
| SkipPrice | 7124 | True or False. Price will be skipped. Only for TradeOrder. |
GUI
Trayport Connector Config
Connector.Password and Timebase.Password secrets can be encrypted with help of Ember Mangle Tool.
Example of Trayport Connector configuration (appsettings.json)
{
"Connector": {
"Host": "jouledirecttest",
"Port": 443,
"Username": "<USERNAME>",
"Password": "<PASSWORD>",
"BrokerID": "37",
"RouteID": null,
"Status": "Firm",
"AllOrNone": "false",
"CompanyID": "<COMPANY_ID>",
"Account": null,
"SkipPrice": false,
"GenerateTradeReport": false,
"ListOfSpecificBrokers": null,
"TermsMapping": [
{
"BrokerID": "37",
"Account": "SUB_ACCOUNT_A",
"RouteID": "671",
"Terms": [
{ "TermLabel": "Execution", "TermDefault": "", "TermType": "string" },
{ "TermLabel": "Customer", "TermDefault": "", "TermType": "string" }
]
},
{
"BrokerID": "36",
"RouteID": "371"
}
],
"MarketToGTD": false
},
"Timebase": {
"Host": "localhost",
"Port": 8014,
"Username": null,
"Password": null,
"AttributeKey": null,
"SkipTradableField": false
},
"MIFID": {
"DecisionMaker": "300",
"ExecutionMaker": "328",
"DEA": "true",
"LiquidityProvision": "false",
"DerivativeIndicator": "false"
},
"CalculatedPrices": {
"Enabled": false,
"MaximumDepth": 4,
"EnableNonConsecutiveSpreads": true
}
}
Ember Trade Connector Config
Example of Ember Trade Connector configuration (ember.conf)
connectors {
TRAYPORT: ${template.connector.fix.es5} {
settings: {
attributeKey = trayport
host = localhost
port = 9021
senderCompId = DELTIX
targetCompId = TRAYPORT
resetSeqNums = true
schedule = {
zoneId = "America/New_York"
intervals = [
{
startTime = "17:30:00",
startDay = SUNDAY,
endTime = "17:00:00",
endDay = SUNDAY
}
]
}
}
}
}