Order Execution Analytics Configuration Settings

The .fsi.eqea.generateOrderAnalytics API provides a certain level of flexibility with a number of options that can be configured in the file src/equitiesEa.api.config.q.

This page serves as a glossary of the different configuration settings.

.eqea.mapToCompositeTicker

If .eqea.mapToCompositeTicker:1b then instrumentIDs are mapped to their corresponding composite ticker before running order analytics generation.

.eqea.queryWindowAdjustmentFactor

When .eqea.queryWindowAdjustmentFactor > 0, the functions .eqea.util.tickData.getDataAndAggFromCfg and .eqea.util.tickData.getDataAndAggregate query where eventTimestamp within (startTime ; endTime + .eqea.queryWindowAdjustmentFactor).

.eqea.restrictOrderGenToSingleDate

Boolean flag that, if true, prevents .fsi.eqea.generateOrderAnalytics from running order analytic generation on time windows that span more than a single date.

The order analytic generation is a resource intensive and potentially long running operation. This restriction has been put in place as a safe guard against accidental large queries that can take over a lot of resources.

.eqea.trapErrs

Error trap calculation of each execution analytic function:

  • If true, an error is logged on the DAP but calculation of the other execution analytics continues.

  • If false, an error halts calculation of the other execution analytics. The error is visible in the UI if running in a pipeline or as an API.

.eqea.useIntervalPrevailingValues

Boolean flag to dictate the data assigned to .eqea.analytics.prevailing.cfg.

inf2null

Helper function used in the participationRate analytic. Swaps infinite values for null values.

.eqea.analytics.cfg

The table .eqea.analytics.cfg is at the heart of the order analytics generation.

The function .fsi.eqea.generateOrderAnalytics uses the data in .eqea.analytics.cfg to determine:

  • What analytics are calculated.

  • The order in which the functions to calculate the analytics are run.

    • This ensures analytics can be chained together, where analytics further down the table can use the output of previous analytics as their input.

The utility functions also use the data in .eqea.analytics.cfg to define each analytic is calculated.

Brief summary of each column in .eqea.analytics.cfg:

  • analytic. The name of the analytic we are calculating, this should match a corresponding column name in the OrderAnalytics table.

  • analyticType. This is simply a value that can be used to group analytics together beyond funcName.

  • funcName. The name of the functions used to calculate analytics.

    First a distinct list of function names is returned from the funcName column using eqeaFuncs:exec distinct funcName from .eqea.analytics.cfg.

    The API .fsi.eqea.generateOrderAnalytics then runs these functions in the order that they appear in this eqeaFuncs variable.

    Based on this information, you can chain analytics that are dependent on other analytics by placing them lower down the config table than the analytics they depend on.

    Example: The analytic intervalSpread depends on the values of arrivalAskPrice and arrivalBidPrice so it appears in the .eqea.analytics.cfg table after these analytics.

  • aggClause. The behavior of this column depends on the utility function it is passed to:

    • .eqea.util.simpleAnalytics. A q-language parse tree which defines the calculation for each analytic. Note that we match the aggregation clause to the corresponding analytic / column name by creating a dictionary with analytic as the key and aggClause as the values, as shown below:

      q

      Copy
      // Create a dictionary to be used in a functional select to calculate our analytics.
      aggDict:(exec analytic from cfg)!(exec aggClause from cfg);
                
      // This dictionary is then used in a functional select, similar to below to generate our analytics:
      ?[data;wc;bc;aggDict]

      Refer to the q documentation for more information on functional qSQL

      Note

      For .eqea.util.simpleAnalytics the aggClause should only reference columns in the OrderAnalytics table.

    • .eqea.util.tickData.getDataAndAggFromCfg. A q-language parse tree which defines the calculation for each analytic.

      The aggregation dictionary is created using analytic and aggClause values as outlined above.

      Note

      For .eqea.util.tickData.getDataAndAggFromCfg the aggClause should only reference columns in the table defined by the corresponding value of marketDataTabName.

    • .eqea.util.asof.ajFromCfg. This the name of the column containing the values for our analytic. This column needs to exist in the table specified by the corresponding value of `marketDataTabName`.

      Note

      In the case of .eqea.util.asof.ajFromCfg, as this is an as-of join, not an aggregation, this value should be an atomic symbol.

  • marketDataTabName. Used by utility functions .eqea.util.tickData.getDataAndAggFromCfg and .eqea.util.asof.ajFromCfg.

    In both cases this defines the name of the partitioned market data table used by the analytic in question.

  • joinTimeOffset. Used by .eqea.util.asof.ajFromCfg only.

    This timestamp value added to the joinOrderTimeCol when building the dataset used in the as-of join.

    This can be a simple timestamp value (for example, 00:00:30) or it can be a derived timestamp (for example, (*;`bucketDuration;4)).

.eqea.analytics.prevailing.cfg

Configuration table that defines how to use .eqea.util.simpleAnalyticsWithWc to replace unwanted values.

Used to define prevailing value corrections in the event no value is available for interval open/close/high/low/etc.

  • If .eqea.useIntervalPrevailingValues:1b then unwanted infinite values are replaced with their preceding value where relevant. For example, if intervalHigh_3:-0w then it is to be replaced by the value of intervalHigh_2.

  • If .eqea.useIntervalPrevailingValues:0b then unwanted infinite values are simply replaced with nulls.

.eqea.api.cfg.logStEtWarn

Logs a warning for each order ID if start time >= end time when calculating "Volatility" OrderExecution Analytics.

.eqea.cfg.ajLookBackByFuncName

Number of days to look back if analytics that make use of .eqea.util.asof.ajFromCfg return null values.

Used by the .eqea.util.asof.ajFromCfg utility function.

This is particularly useful for two edge cases:

  1. Orders placed at or near midnight, with no corresponding market data preceding in the date partition, need to get the latest value from the previous date partition.

  2. Very illiquid instruments that might only be traded once every few days.

Note

If .eqea.util.asof.ajFromCfg is used within a function that does not exist in this table then no lookback logic is applied to that function. This could cause null values for the edge cases described above.

.eqea.cfg.removeAnalyticsList

List of analytics to remove from .eqea.analytics.cfg.

Use this to remove / skip analytics calculated by .fsi.eqea.generateOrderAnalytics.

Contents of this variable should be a symbolic list of analytic values from .eqea.analytics.cfg.

Note

This prevents analytics from being calculated but does not remove columns from the OrderAnalytics schema. If you wish to remove the corresponding columns from the OrderAnalytics schema then delete the relevant entries from ${PKG_NAME}/tables/OrderAnalytics.yaml and redeploy the package.

.eqea.volatility.bucketSize

Bucket size used by all intervalVolatility and intervalVolatility_N calculations.