Ember Configuration Reference
Overview
The Ember can be used in diverse solutions: as a matching engine, as a FIX Gateway, as a platform to host trading SELL side and BUY algorithms and trading connectors, etc.
The module design and configuration flexibility make these diverse solutions possible.
Format
Ember configuration uses text files in the HOCON (Human-Optimized Config Object Notation) format described here.
HOCON is more flexible than the JSON (JavaScript Object Notation) format in that there are several ways to write valid HOCON. Below are two examples of valid HOCON.
Example #1:
settings: {
topic: "NIAGARA",
maxSnapshotDepth: 30 # This is a comment
}
Example #2:
settings {
topic = NIAGARA
maxSnapshotDepth = 30 // This is also a comment
}
If a HOCON configuration does not appear to be working, check the following.
- Curly brackets must be balanced. (Keep identation and formatting neat. This helps spot errors.)
- Quotation marks must be balanced.
- Duplicate keys that appear later take precedence (override earlier values).
General Pattern
The most pluggable services in Ember follow the declaration pattern shown below:
MYSERVICE {
factory: <fully-qualified-name-of-Java-implementation>
settings {
parameter1: value1 // custom
parameter2: value2 // parameters
}
}
This Spring Beans-like approach allows extending the system with custom-build services. See the Custom Service settings section for more information.
Configuration files
Most components have the default configuration described in the “template” configuration file ember-default.conf. The main configuration file ember.conf overrides and refines the default configuration. For example:
On startup, the Ember searches the following locations for configuration files:
- Java System properties (For example,
-Dember.home=/home/deltix/emberhome). - The file ember.conf in Ember home directory.
- The resource ember.conf in CLASSPATH.
- Resource ember-default.conf.
The last resource (ember-default.conf) is shipped with installation and defines default values for all server configuration parameters.
Configuration secrets
Currently, there are several methods of storing sensitive information in configuration files (passwords, API keys, etc.).
- Secret as a Service: Ember is integrated with:
- Hashicorp Vault - This separately installed service is free to use for smaller deployments. See this article for more information.
- AWS Secret Manager. See this article for more information.
- Azure Key Vault. See this article for more information.
- Hashing Passwords can be hashed using a special utility (
bin/mangle). Ember automatically detects an encrypted secret and decrypt it at runtime. See this article for more information. - Environment variables. Sometimes secrets can be securely injected into environment variables. You can reference environment variables in HOCON using
${ENV_VARIABLE_NAME}notation.
Configuration Reference
TimeBase
Almost every deployment of Ember requires the Deltix TimeBase service:
timebase.settings {
url = dxtick://timebasehost1:8011
}
If your TimeBase has User Access control enabled, you need to define them as well:
timebase.settings {
url = dxtick://timebasehost1:8011
username = ember
password = EVcec95166e01fcf5792b8fc215a5dfb62 # NB: encrypted
}
If TimeBase is configured to use TLS(SSL), use dstick:// in URL schema:
timebase.settings {
url = dstick://timebasehost1:8011
}
When using self-signed certificate on TimeBase server side be sure to configure Ember per instructions here (as TimeBase client).
OAUTH2 TimeBase connection
When TimeBase is using OAUTH2 authentication, use the following configuration stanza to define connection parameters:
timebase {
factory = "deltix.ember.app.Oauth2TimeBaseFactory"
settings = null
settings {
url = "dxtick://localhost:8011"
oauth2url = "http://localhost:8282/realms/timebase/protocol/openid-connect/token"
clientId = "client id goes here"
clientSecret = "client secret" # use hashed value or vault
scope = "api://quantoffice/shell openid profile" # optional
}
}
For more information about configuring OAUTH2 authentication read documentation for TimeBase and TimeBase Admin.
OMS settings
Validation Logic
The configuration stanza engine.validation configures various parameters that affect the validation of inbound trading requests:
- allowCancelOfFinalOrders – When set to true, OMS rejects attempts to cancel orders that are in a completed state. By default, ember forwards such requests to a destination venue even if the order seems to be complete (according to state maintained by Ember OMS).
- allowFastCancel - Allows cancelling of unacknowledged orders (some destination venues does not allow this).
- allowFastReplace - Allows replacing of unacknowledged orders or orders that have pending replacement requests (pessimistic/optimistic approach to cancel replace chains).
- maxPendingReplaceCount – When fast replace is allowed, this parameter controls how many order replacement requests may be pending (unacknowledged by order destination venue).
- pricesMustBePositive – When set, OMS rejects orders that have a negative limit price (negative prices may be normal in some markets, e.g., exchange-traded synthetics). Default value is true.
- maxOrderRequestTimeDifference –
This parameter helps to detect order requests that spent too much time in transit to Ember OMS. Make sure the order source periodically synchronizes the local clock with some reliable source. This setting was removed in Ember 1.10.38+. You can now control this behavior via a similar setting in the FIX Order Entry gateway. - allowReplaceTrader – Allows modification of order’s trader (e.g., to follow the CME tag 50 requirement). Mutually exclusive with using Trader as a risk projection key: if Trader is configured as a projection key, replace requests that attempt to change the trader will be rejected regardless of this setting. See Mutable Keys.
- allowReplaceUserData - Allows modification of an order’s user data (e.g., when users put some free text notes into this field). When the modification of an order’s user data is allowed, the UserData projection cannot be used in risk rules.
- nullDestinations – An array of destinations that are no longer needed but might have accumulated orders and positions (this setting simply suppresses ember startup warnings).
The following example shows default values for each parameter:
engine {
validation {
settings {
allowCancelOfFinalOrders = true
allowFastCancel = true
allowFastReplace = false
pricesMustBePositive = true
maxPendingReplaceCount = 10
}
}
nullDestinations = [ “CME”, “ILINK2” ]
}
Order Router
Order Router is an OMS component that controls where trading requests flow. Normally, requests are routed according to their destination. The custom order router can handle requests with an undefined destination or even override the intended destination in certain cases.
Here is an example of a simple order router:
engine.router {
factory = "deltix.ember.service.engine.router.SimpleOrderRouterFactory"
settings {
defaultDestination = SIMULATOR
# ‘true’ routes ALL trading request to destination defined as defaultDestination
force: false
# if destination is not provided, tries to use request’s exchange as destination
fallbackToExchange: true
}
}
This is another example of a custom order router that re-routes trading requests that are designated to KRAKEN to one of the trading connectors, depending on the trader’s group:
engine {
router {
factory = "deltix.ember.service.engine.router.custom.TraderGroupOrderRouterFactory"
settings {
interceptedDestination = "KRAKEN"
traderGroupToDestination : [
"NewYorkGroup : KRAKEN-US",
"LondonGroup : KRAKEN-GB",
"SingaporeGroup : KRAKEN-SG"
]
}
}
}
Changing the router on a production system may result in a change in system behavior:
All historical trading requests that relied on the previous routing destinations are routed according to the new router logic after restart.
Cache
The configuration stanza engine.cache allows tuning internal OMS cache parameters:
engine {
cache {
orderCacheCapacity = 16K
maxInactiveOrdersCacheSize = 4K
initialActiveOrdersCacheSize = 4K
initialClientsCapacity = 16
hashFunction = DEFAULT
mapType = CHAINING
}
}
Where:
- initialClientsCapacity – How many sources of orders to expect (not a limit, just a hint).
- initialActiveOrdersCacheSize – How many active orders to expect (not a limit, just a hint).
- orderCacheCapacity – Defines the total expected order count that ember keeps in memory at any moment in time (not a limit). This is a hint to the order pool to pre-allocate a given number of blank order instances.
- maxInactiveOrdersCacheSize – Defines how many inactive (REJECTED/CANCELLED/COMPLETELY_FILLED) orders ember keeps in memory per order source.
- hashFunction - Defines hash function used, one of DEFAULT | NATIVE | XXHASH | METRO. Default is DEFAULT. Since Ember 1.15.
- mapType - Defines underlying data structure used for cache, one of CHAINING | LINEAR_PROBING | ROBIN_HOOD (default is CHAINING). Since Ember 1.15
** hashFunction = DEFAULT** indicates that Java Default hash function will be used for the cache.
** hashFunction = NATIVE** indicates that native hash from this blog will be used for the cache.
** hashFunction = XXHASH** indicates that xxHash from implementation here will be used for the cache.
** hashFunction = METRO** indicates that metro hash from implementation here will be used for the cache.
Ember OMS reloads journal on startup, but once started it but relies solely on in-memory cache of orders. This cache contains all active and last N inactive orders for each order source. The idea is to be able to process rare cases of "fill after cancel". For some exchanges Fill events may take slightly longer path than other order events like Cancel (and hence may arrive out of normal order lifecycle sequence). This out-of-sequence fill usually happens within a second or two of order completion.
We suggest the following math: let's say each order source (each algorithm, or API client) sends us up to 1000 orders per second. We want to be able to process late fills reported within 5 seconds of order completion. In this case inactive (completed) order cache size is set to 5000. Default value is 4096
# Maximum amount of inactive (complete) orders to keep in cache (per source)
engine.cache.maxInactiveOrdersCacheSize = 5000
We strongly advise not to set this to larger numbers - increased cache size leads to excessive memory consumption and slows down OMS order processing.
Engine Order Transformer
You can define a custom transformer of in-bound order requests.
Here is an example:
engine {
transformer: {
factory = …
settings {
…
}
}
}
Use this option with care. Ember stores the result of this transformation into Ember Journal. There is no durable trace of the original order request.
Transformation of inbound events or other message types is not yet supported.
See Order Request Transformer for the interface contract and how to implement a custom transformer.
Custom Instrument Metadata
In some rare cases, the engine needs access to additional information about each instrument. For example, a custom risk rule may want to keep track of some extra information like the instrument industry sector or per-exchange minNotional. This can be achieved using a custom Instrument Factory:
engine {
instrumentInfoFactory {
factory = "deltix.ember.service.engine.CustomExtendedInstrumentInfoFactory"
settings {}
}
}
Error Handling
The engine’s configuration stanza exceptions {} defines the system reaction to abnormal situations.
TimeBase Disconnect
Ember components (algorithms and connectors) can recover from the loss of a TimeBase connection, however, there may be a gap in market data, message loss in output channels, and other side effects. You can define how Ember should react to the loss of a TimeBase connection:
engine.exceptions.timebaseDisconnect = HaltTrading
Possible values are:
Continue- Logs the error, let Ember recover.HaltTrading- Halts Trading (forces the operator to confirm that the system fully recovered on TimeBase reconnect).Shutdown- Graceful Ember shutdown.ShutdownLeaderWithFollower- Shutdown when leader-with-follower, continue when follower, or leader without follower.
Prior to Ember 1.10.14:
exceptions.haltOnTimebaseLoss (true)- Halts trading every time Ember loses its TimeBase connection.
Misc parameters
This section describes the remaining parameters. If you want to change these, you can place them inside the engine configuration stanza:
-
maxNumberOfRequestErrorsToLog (64) - Threshold on the amount of exceptions Ember prints into the output log (subsequent errors are logged as request reject reasons on messages). The engine has a performance counter for it.
-
maxInactiveUnknownWarningsToLog (16) - Maximum number of warnings about events for no-longer active (or unknown) orders. These events cannot be processed. The engine has a performance counter for it.
-
maxRiskVetosToLog (16) - Maximum number of risk rule vetos (order rejects) to log. The engine has a performance counter for it.
-
convertStatusEventsToNormalEvents (true) - A "do not send Order Status to algorithms" event. Convert them to normal events that report incremental differences.
-
useMaxRemainingQuantity (false) - Instruct OMS to enrich messages using
maxRemainingQuantityrather than the remaining quantity of the working order. Slower. -
allowUnrestrictedPositionRequests (false) - By default system is configured in "single API client can only see own positions" mode. Clients are identified by API keys that are mapped to order Source IDs hence by default Source ID is a required part of projection when requesting positions. When this security-driven restriction is removed, different API Clients can see the positions of each other (as well as system-wide positions).
Security Metadata (Instruments)
By default, Ember uses the local TimeBase stream “securities” to learn about Security Metadata (AKA security master). This stream is supported by most QuantServer/QuantOffice/CryptoCortex ecosystems.
On startup, Ember reads a copy of the security metadata from the “securities” stream. During run time, Ember watches this stream for updates (only for inserts/updates; deletes are ignored). You can override the stream name as follows:
instruments {
subscription {
stream = "securities"
filter = null # SELECT * FROM $stream WHERE $filter
}
useCentralSMD = true
}
Instrument filter
You can also define a filter that is used to skip some instruments. For example, the following line excludes instruments that do not have a TradeableSymbol column defined:
instruments.subscription.filter = "TradeableSymbol != NULL"
Instrument attributes filter
By default Ember loads all available non-empty instrument attributes. The non-standard attributes are exposed as key-value style custom attributes in case they are required for some custom logic. If security metadata stream contains a lot of unneeded custom attributes, you could optimize memory usage by by limiting the number of custom attributes loaded for each instrument. For example, you can do this by explicitly listing only the custom attributes that should be loaded:
instruments.subscripion.includeCustomAttributes = [ "minNotionalApplyToMarket" ]
minNotionalApplyToMarket is the only custom attribute used by Ember at this point. So unless your custom logic is using other custom attributes, you could safely apply this setting.
Instead of whitelisting custom attributes you could also blacklist them as follows:
instruments.subscripion.excludeCustomAttributes = [ "someUnneededAttribute" ]
Central Security Master
Ember can also provide an API wrapper to access the Deltix Central Security MetaData service. This centrally maintained service contains detailed information about FX, Crypto, and some FUTURE markets. This information can be used by algorithms like the Smart Order Router. If your environment has no access to the internet, or is not covered by this service, you can disable this feature in the following way:
instruments.useCentralSMD = false
Security Metadata Watch service
By default Ember loads all instruments from "securities" stream on startup and keeps live TimeBase cursor that listens for any changes (mostly additions of new instruments).
However when Ember is used in tandem with Universe Configurator you may want to switch to canonical approach: whoever wants to change "securities" stream must do it under write lock, Ember is notified every time write lock on "securities" is released and performs full re-load of instruments under read lock. To enable this mode add the following configuration stanza to your ember.conf:
instrumentsWorker {
factory = "deltix.ember.service.smd.CanonicalInstrumentServiceWorkerFactory"
settings {
}
}
-
Advantages of canonical approach - this is how other TimeBase clients watch securities changes.
-
Disadvantages of canonical approach - it is less efficient, it results in full reload of securities stream on any change.
Pricing Service
While trading algorithms receive market data prices directly from TimeBase, other components like position and risk use a pricing service. The pricing service provides access to recent BBO prices. This is a performance trade off - a direct subscription for market data requires extra CPU and memory resources.
Here is an example of a pricing service configuration for a simple case when market data comes from three TimeBase streams:
pricing {
settings {
liveSubscription.streams = [COINBASE, BINANCE, BITFINEX]
}
}
Alternatively, if market data is distributed via high-performance TimeBase topics, configuration looks like this:
pricing {
settings {
liveSubscription.topics = [COINBASE, BINANCE, BITFINEX]
}
}
Topics and Streams cannot be mixed.
If market data streams or topics have a lot of irrelevant instruments, you can limit your subscription by specifying what symbols and/or types of messages you want to subscribe for.
pricing {
settings {
liveSubscription {
streams = [COINBASE, BINANCE, BITFINEX]
symbols = [BTCUSD, LTCUSD, ETHUSD]
types = [deltix.timebase.api.messages.universal.PackageHeader]
}
}
}
Settlement Prices
The pricing service also provides previous day settlement prices for interested consumers.
To enable this data, add the settlementPriceSubscription configuration stanza as shown in this example:
pricing {
settings {
…
settlementPriceSubscription {
streams: [ "settlementPrices" ]
symbols: [ "TSLA", "AMZN", …] // Optional, all symbols if omitted
types: [ "deltix.timebase.api.messages.TradeMessage" ] // Optional, all message types if omitted
}
}
}
Ember expects the settlement prices stream to have the last known message broadcast enabled (so-called TimeBase unique streams).
Ember can extract settlement prices from traditional TradeMessages that have been around since QuantServer 1.0 or from the Universal Market Data format introduced in version 5.X. (In the latter case, StatisticsEntry[type = SETTLEMENT_PRICE] is used).
Historical Prices
The pricing service receives and caches live market data. However, for traditional markets that have periodic trading sessions, or for rarely traded instruments, there may be a need to warm-up a cache of BBO prices using historical data. Warm up is performed during server startup. The following configuration snippet shows how to warm up the pricing service with 1 hour of historical data:
pricing {
settings {
liveSubscription {
streams = [COINBASE, BINANCE, BITFINEX]
}
historicalDepth = 1h # specifies duration
}
}
A historical subscription can be fine-tuned with its own subscription stanza:
pricing {
settings {
liveSubscription {
streams = [COINBASE, BINANCE, BITFINEX]
symbols = [BTCUSD, LTCUSD, ETHUSD]
}
historicalSubscription {
streams = [COINBASE, BINANCE, BITFINEX]
symbols = [BTCUSD]
}
historicalDepth = 3d # specifies duration
}
}
Mockup Pricing Service
In some rare cases, you may need to run Ember without real market data.
There is a mockup version of a pricing service that can be configured as follows:
pricing {
factory = "deltix.ember.app.price.FakePricingServiceFactory"
settings {
fixedPrices: {
BTCUSD: 3909.70
ETHUSD: 133
LTCUSD: 31.899
LTCBTC: 0.008148
BCHUSD: 170.27
BCHBTC: 0.046
ETHBTC: 0.034045
XRPUSD: 0.39287
}
}
}
Main currency
The pricing service also helps some OMS and disk components with currency conversion. Risk limits, like the Net Open Position limit, covert positions in each individual currency to the main currency. The default main currency is USD.
pricing {
…
settings {
…
mainCurrency: USD
}
}
Advanced Pricing Service Settings
pricing {
settings {
exchanges = 32 # how many exchanges L1 NBBO aggregator can expect at most
useFullOrderBookProcessor = false # false = process only snapshots but save system resources; true = process every message, NBBO L2
reconnectDelay { # TimeBase reconnect settings: exponential delay with base 2
min = 5s
max = 60s
}
}
}
Algorithms
This section describes the configuration options for deploying Ember algorithms. See the Algorithm Developer’s Guide for more information about algorithm capabilities.
Algorithms are the building blocks of the custom business logic inside Ember. The following example shows the configuration of the BOLLINGER algorithm. As you can see below, each algorithm must be defined under the algorithms { } stanza.
algorithms {
BOLLINGER: ${template.algorithm.default} {
factory = deltix.ember.service.algorithm.samples.bollinger.BollingerBandAlgorithmFactory
settings {
bandSettings {
numStdDevs: 1.5
commissionPerShare: 0.001
openOrderSizeCoefficient: 1
profitPercent: 20
stopLossPercent: 40
numPeriods: 100
enableShort: true
enableLong: true
}
}
subscription { # input channels
streams = ["sine"]
symbols = ["BTCUSD", "LTCUSD"]
types = ["deltix.timebase.api.messages.TradeMessage"]
typeLoader: {
factory: deltix.ember.algorithm.pack.sor.balance.SORMessageTypeLoaderFactory
settings { }
}
}
}
}
Each algorithm configuration stanza has the following parts:
- Algorithm identifier: BOLLINGER or NIAGARA in this case. This identifier must be a valid
ALPHANUMERIC(10)text value. Basically, the identifier may use capital English letters, digits, and punctuation characters, and must not exceed 10 characters (See Deltix Trading Model for more information about theALPHANUMERIC(10)data type). - Algorithm Factory Class: This parameter tells Ember where an algorithm’s code can be found during startup.
- Settings: This configuration block defines the custom deployment parameters of each algorithm. Each setting in this block corresponds to a property of algorithm factory class.
- Subscription: If an algorithm uses a standard way of receiving market data, this section references the source of it. Typically, this is a set of TimeBase Streams or Topics that broadcast market data inside Deltix infrastructure. Optionally, a subscription can be limited to a specific set of instruments (defined by the
symbolsparameter).
Let's review one more example of an algorithm definition:
NIAGARA: ${template.algorithm.NIAGARA} {
settings {
symbols: ${contractsString}
bookSnapshotInterval: 15s
maxSnapshotDepth: 64
feedTopicKey = "l2feed" #output channel
validateFeed = true
}
}
Algorithm Market Data Subscription
In the above sample, the subscription stanza defines what market data is available to an algorithm.
Note the difference between Stream-based and Topic based market data configuration - streams are defined inside subscription { } stanza and can include symbol and message type filters. Algorithm cannot define symbol or message type filters for topics - you have to consume entire topic feed.
An algorithm can subscribe for market data from TimeBase streams:
BOLLINGER: ${template.algorithm.default} {
subscription {
streams = ["stream1", "stream2"]
symbols = ["BTCUSD", "LTCUSD"]
types = ["deltix.timebase.api.messages.TradeMessage"]
channelPerformance = MIN_CPU_USAGE
allInstruments = false
}
}
A subscription stanza may have the following optional parameters:
- symbols - Defines a symbol filter (a list of instrument symbols that the algorithm receives, usually a subset of what is available in the market data streams). If this parameter is missing or set to null then algorithm will subscribe for all symbols in the provided TimeBase streams. Special case is empty symbols array - this configuration will deploy algorithm with empty initial subscription (the algorithm may still add symbols during runtime).
- note: missing
subscriptionstanza deploys an algorithm without market data. - types - Defines a type filter - a list of message types that the algorithm receives. When this setting is skipped, the algorithm gets messages of all types. Types are identified by the TimeBase type name, which usually matches the name of the corresponding Java message class, for example "
deltix.timebase.api.messages.TradeMessage". - typeLoader - Defines a custom TimeBase type loader. Type loaders allow mapping TimeBase message types to Java message classes available in the Ember CLASSPATH. The type loader is defined by the factory class (as usual for config). See the Type Loader section in Algorithm Developer's Guide for more information.
- channelPerformance - defines TimeBase market data cursor operation mode. Possible values are:
MIN_CPU_USAGE- Prefer to minimize CPU usage. Don't do anything extra to minimize latency (default mode).LOW_LATENCY- Prefer to minimize latency at the expense of higher CPU usage (one CPU core per process).LATENCY_CRITICAL- Focus on minimizing latency even if this means heavy load on CPU. Danger! Read Timebase cursor API before using.HIGH_THROUGHPUT- Prefer to maximize messages throughput. For loopback connections IPC communication will be used.
- allInstruments - normally when algorithm tracks instrument metadata (from "securities" TimeBase stream) only for instrument set that matches market data subscription. This flag configures algorithm to track instrument metadata for all symbols in securities stream. In other words, when "allInstruments = true", algorithm will track securities metadata for all available instruments in configured securities stream. When "allInstruments = false" or not specified, algorithm will only track securities metadata for instruments that it is subscribed to (For example, parameter
symbolsis missing or null* implies that algorithm will subscribe to all market data and all instruments).
Subscription Examples
In the following example algorithm subscribes to AAPL and MSFT instruments from the NASDAQ TimeBase market data stream:
subscription {
streams = ["NASDAQ"]
symbols = ["AAPL", "MSFT"]
}
In the following example algorithm subscribes to market data for all symbols (all instruments) from NASDAQ stream:
subscription {
streams = ["NASDAQ"]
}
Identical configuration:
subscription {
streams = ["NASDAQ"]
symbols = null
}
In many cases, trading algorithms only need market data for instruments that this algorithm wants to trade. Avoid subscribing to entire stream of market data where possible, as this may be wasteful.
In the next example you can see initially empty market data subscription:
subscription {
streams = ["stream1", "stream2"]
symbols = [] # empty filter means "no market data initially"
}
an algorithm may control market data subscription during runtime using special API.
And finally, algorithms that do not need market data may skip the subscription section completely:
NOMARKET: ${template.algorithm.default} {
// subscription block is not present
}
Market Data from TimeBase Topics
As an option, an algorithm may receive market data from a TimeBase topic:
BOLLINGER: ${template.algorithm.default} {
topic = "topic1"
}
or multiple topics:
BOLLINGER: ${template.algorithm.default} {
topics = ["topic1", "topic2"]
}
There is no per-symbol filtering capability for topics.
Key differences:
- Topics are defined outside the subscription stanza
- Topics cannot define type/symbol filters. The entire content of the topic is fed into the algorithm.
Starting from Ember version 1.14.67 algorithm receive data from both topics and streams:
BOLLINGER: ${template.algorithm.default} {
topics = ["topic1", "topic2"]
subscription {
streams = ["stream1", "stream2"]
}
...
Furthermore, Deltix Universe Configurator has special convention - when market data connector output name starts with % sign it automatically creates a topic with provided name (and also instructs TimeBase to keep carbon-copy stream. For example, when Coinbase exchange connector uses %COINBASE as output name, the data will be broadcasted into %COINBASE TimeBase topic and also recorded into COINBASE TimeBase stream.
Ember supports this naming convention. In the following configuration algorithm will be receiving market data from to %COINBASE Topic.
BOLLINGER: ${template.algorithm.default} {
subscription {
streams = ["%COINBASE%"]
}
...
This was done to simplify conversion of existing setups from streams to topics for market data delivery. One can simply add % prefix to stream name in Universe Configurator and Ember configuration to switch existing setup to Topic. More about this subject can be found in Algorithm Developer's Guide.
Algorithm Configuration Template
The template define low-level settings available for each algorithm. For example:
- CPU idle strategies
- Default order cache capacity
- Interval of reconnection to TimeBase market data in case of failures
template.algorithm.default {
queueCapacity = ${template.queueCapacity.default}
idleStrategy = ${template.idleStrategy.default}
# exponential delay with base 2
reconnectDelay {
min = 5s
max = 60s
}
settings {
orderCacheCapacity = 4096
maxInactiveOrdersCacheSize = 1024