Skip to main content

Analytics Engine

Overview

Analytics Engine (AE) is the platform's fixed income valuation service. It acts as a high-performance calculation layer built on QuantLib, exposing a set of RPC functions that translate between market observables (clean price, yield, discount margin) and derived analytics (PV01, cashflows, workout date).

AE is a calculation server — it does not store or publish data of its own. It listens for platform data (instruments, business dates, yield curves, index fixings) and responds to on-demand requests from other services and from the Bond Calculator UI.

What AE provides:

  • Price ↔ Yield conversions — clean price to yield to worst/maturity, yield to clean price
  • Discount Margin — clean price to discount margin and back (floating rate bonds)
  • PV01 — interest rate sensitivity from price or yield input
  • Workout Date — determine the yield-to-worst redemption date from a clean price (callable bonds)
  • Yields to Call Dates — yield computed for every possible redemption date
  • Cashflow schedule — full coupon and principal payment dates and amounts
  • Bond Diagnostics — raw internal state of the QuantLib bond model for troubleshooting
note

AE currently supports a single currency per instance. To value bonds in multiple currencies, deploy one AE instance per currency and configure each with KS_AE_CURRENCY.

Installation

Analytics Engine is distributed as a standalone binary or Docker image.

The package for this component is analytics-engine-{version}.tar.gz.
Please reach out to us if you'd like to try analytics-engine.

Please follow the instructions in deployment guide on how to install components.

Remember to register the new application. The simplest way to do this is by importing the app-permissions.json included in the component's package.

Entitlements

The following entitlements must be configured in KeyAccess for the analytics-engine application.

If you imported the permissions using the supplied app-permissions.json then most of these should already be setup for you.

Simplified

PUB/SUBSchemaSourceGroup
SUB**analytics-engine
SUB*static-data-server*
SUB*curve-engine*
PUB*analytics-engine*

Full Detail

PUB/SUBSchemaSourceGroup
SUBKsPricing.* (RPC Requests)*analytics-engine
SUBKsStaticDataServer.InstrumentIdReverseMappingstatic-data-server*
SUBKsCanonical.Instrumentstatic-data-server*
SUBKsCanonical.BusinessDatesstatic-data-server*
SUBKsCanonical.Indexstatic-data-server*
SUBKsCanonical.IndexFixingstatic-data-server*
SUBKsPricing.Curvecurve-engine*
PUBKsPricing.* (RPC Responses)analytics-engine*

Dependencies

AE depends on keysquare-platform and Static Data Server being healthy before it reaches READY.

In a typical platform boot sequence:

  1. aeron-media-driver
  2. key-access
  3. sequencer
  4. relay-cache, relay-live
  5. static-data-server
  6. analytics-engine ← starts here

AE waits for SDS to signal LivenessState.ONLINE and ReadinessState.READY before subscribing to instruments, business dates, and indices. It signals its own ReadinessState.READY only after all instrument subscriptions are complete.

As evident from the entitlements, AE subscribes to the following data types from static data server:

  • Instrument i.e. list of instruments to price
  • Business Date i.e. current business or evaluation date
  • Index + IndexFixing i.e. what indices to be aware of (for FRN support)

Additionally, AE subscribes to forecast curves published by Curve Engine. AE subscribes to forecast curve specified in forecastCurve field of the Index

note

Because AE loads the full instrument set on startup, it will not respond to valuation requests until all subscriptions to SDS are complete. Monitor ApplicationStatus to verify AE is ready before routing requests to it.

Supported Bond Types

  • Fixed Maturity Fixed Coupon
  • Fixed Maturity Float Coupon
  • Callable Maturity Fixed Coupon
  • Callable Maturity Float Coupon
  • Callable Maturity Fixed-to-Float Coupon

Supported Valuations

  • CLEAN_PRICE to YIELD
  • CLEAN_PRICE to DISCOUNT_MARGIN
  • CLEAN_PRICE to PV01
  • YIELD to CLEAN_PRICE
  • YIELD to PV01
  • DISCOUNT_MARGIN TO CLEAN_PRICE
  • DISCOUNT_MARGIN TO PV01

RPC Functions

Analytics Engine exposes six RPC functions.

RPC NameDescription
ValuationRequestPrice/yield/PV01/discount margin conversions
ComputeWorkoutDateYield-to-worst redemption date from clean price
ComputeYieldsToCallDatesYield for every call date from clean price
ComputeCashflowsFull coupon and principal schedule
GetBondDiagnosticsRaw QuantLib model state as JSON
GetBondDetailsSettlement date, maturity, accrued, cashflows

ValuationRequest

The primary valuation RPC. Accepts an input value (clean price, yield, or discount margin) plus a list of metrics to compute, and returns all requested results in a single response.

Called by: Price Engine (every pricing cycle), Bond Calculator UI

Request:

FieldTypeDescription
instrumentIdFullInstrumentIdentifierInstrument to value. Resolved using ISIN, CUSIP, or platform ID
currencyCurrencyMust match the AE instance's configured currency
valuationDateint (YYYYMMDD)Must match the current business date for the currency
settlementDateint (YYYYMMDD)Settlement date override. 0 = use standard settlement days
workoutDateint (YYYYMMDD)Redemption date to use. 0 = determine from yield to worst
inputValueTypeValuationMetricOne of: CLEAN_PRICE, YIELD_TO_WORST, YIELD_TO_MATURITY, DISCOUNT_MARGIN
inputValuedoubleThe input value corresponding to inputValueType
requestsEntryRequestsEntry[]List of metrics to compute

Supported inputValueTyperequestType combinations:

InputComputable Outputs
CLEAN_PRICEYIELD_TO_WORST, YIELD_TO_MATURITY, PV01, DISCOUNT_MARGIN*
YIELD_TO_WORSTCLEAN_PRICE, PV01
YIELD_TO_MATURITYCLEAN_PRICE, PV01
DISCOUNT_MARGINCLEAN_PRICE, PV01

*DISCOUNT_MARGIN is only supported for floating rate bonds.

Response: ValuationResponse — contains ok flag and a resultsEntry list, one per requested metric. Each entry has its own ok and message field so partial failures are visible.

ComputeWorkoutDate

Determines the yield-to-worst redemption date for a callable bond from a given clean price. Price Engine uses this to establish which call date minimises the yield before computing YIELD_TO_WORST.

Called by: Price Engine (callable bonds only), Bond Calculator UI

Request:

FieldTypeDescription
instrumentIdFullInstrumentIdentifierInstrument to evaluate
currencyCurrencyMust match configured currency
valuationDateint (YYYYMMDD)Current business date
cleanPricedoubleInput clean price

Response: ComputeWorkoutDateResponseworkoutDate is the resulting redemption date in YYYYMMDD format.

ComputeYieldsToCallDates

Computes the yield for every possible redemption date (all call dates plus maturity) from a single clean price. Useful for understanding option-adjusted behaviour across the call schedule.

Called by: Bond Calculator UI (Yields tab)

Request:

FieldTypeDescription
instrumentIdFullInstrumentIdentifierMust be a callable bond
currencyCurrency
valuationDateint (YYYYMMDD)
cleanPricedoubleInput clean price

Response: ComputeYieldsToCallDatesResponsecalculatedYieldsEntry list of (date, yield) pairs, one per redemption date.

ComputeCashflows

Returns the full projected cashflow schedule for a bond: all coupon payment dates and amounts plus the final principal repayment.

Called by: Bond Calculator UI (Cash Flows tab)

Request:

FieldTypeDescription
instrumentIdFullInstrumentIdentifier
currencyCurrency
valuationDateint (YYYYMMDD)

Response: ComputeCashFlowsResponsecashflowsEntry list of (date, value) pairs.

GetBondDiagnostics

Returns the raw key-value state of the QuantLib bond model as a JSON string. This includes all inputs AE used to construct the bond (coupon rate, conventions, settlement, accrued amount, cashflows) and is useful for verifying that AE is interpreting instrument data correctly.

Called by: Bond Calculator UI (Diagnostics tab), developers via the RPC tool

Request:

FieldTypeDescription
instrumentIdFullInstrumentIdentifier
currencyCurrency
valuationDateint (YYYYMMDD)

Response: GetBondDiagnosticsResponsedetails is a JSON string containing the full internal model state.

GetBondDetails

Returns high-level bond details including settlement date, maturity date, accrued amount, and the full cashflow schedule. A lighter-weight alternative to GetBondDiagnostics when you only need the structured outputs rather than the full internal state.

Called by: Developers and tools via the RPC tool

Request:

FieldTypeDescription
instrumentIdFullInstrumentIdentifier
currencyCurrency
valuationDateint (YYYYMMDD)

Response: GetBondDetailsResponse — settlement date, maturity date, accrued amount, and cashflow list.

Integration with Price Engine

Price Engine is the primary production consumer of Analytics Engine. On each pricing cycle, PE calls AE to convert the input price to yield and PV01:

Price Engine also subscribes to AE's ApplicationStatus to detect when AE becomes unavailable — it will continue publishing prices without analytics in degraded mode.

Troubleshooting

Analytics Engine surfaces errors in two ways: through the ok and message fields of each response, and through runtime exceptions thrown when a request cannot be processed.

Valuation Response Errors

Each entry in ValuationResponse.resultsEntry has its own ok and message field. A partial failure is possible — some metrics succeed while others fail within the same request.

MessageReasonResolution
Request currency does not match KS_AE_CURRENCYUnsupportedOperationException: Unsupported currency: <currency>Route requests to the AE instance configured for the correct currency
valuationDate is zero in the requestIllegalArgumentException: No valuation date suppliedEnsure the requesting service has received a business date before sending valuation requests
Request's valuation date does not match AE's current business dateIllegalStateException: Requested valuation date: <date> does not match engine valuation date: <date>This typically means a stale request arrived after a date rollover; the requesting service should retry after receiving the updated business date
Instrument ID in request is not known to AEIllegalStateException: Couldn't find a bond with id: <id>The instrument has not yet arrived from Static Data Server. Wait for AE to signal ReadinessState.READY before sending requests
Bond ID is blankIllegalArgumentException: Id is blankEnsure instrumentId is populated in the request
Bond coupon type is not FLOATDISCOUNT_MARGIN metric requested for a fixed-coupon bondOnly request DISCOUNT_MARGIN for floating rate bonds
Not a callable bondYIELD_TO_WORST requested with no workout date and the bond is not callableSupply a workoutDate, or only request YIELD_TO_MATURITY for non-callable bonds
<id> is not a callable bondsComputeYieldsToCallDates called on a non-callable bondOnly call ComputeYieldsToCallDates for bonds with a call schedule
Input value type not supportedThe inputValueType cannot be converted to the requested output metricCheck the supported input → output combinations table
Unsupported metricAn unrecognised ValuationMetric was included in requestsEntryUse a supported metric: CLEAN_PRICE, YIELD_TO_WORST, YIELD_TO_MATURITY, PV01, DISCOUNT_MARGIN
Non-standard settle date not supportedsettlementDate field is non-zero in the requestSet settlementDate = 0 to use standard settlement conventions
<QuantLib exception message>QuantLib threw an exception (e.g. convergence failure, invalid date, coupon schedule error)Check bond static data in Static Data Server for accuracy

Startup and Connectivity

These errors are thrown as exceptions and will appear in AE logs rather than in response messages:

SymptomLikely CauseResolution
AE stays in ReadinessState.NOT_READYNot connected to Static Data Server, or SDS is not yet READYVerify SDS is running and healthy. Check AE logs for Static Data Server ready message
AE received 0 business datesSDS is running but has no business date for the configured currencyEnsure SDS has a business date configured for KS_AE_CURRENCY
AE received 0 instrumentsSDS is running but the configured KS_AE_INSTRUMENT_TOPIC_GROUPS does not match any SDS groupsVerify KS_AE_INSTRUMENT_TOPIC_GROUPS matches the groups SDS publishes to
Price Engine reports Analytics Engine unavailableAE is not online or not reachable on the platform busConfirm AE is running, registered in KeyAccess, and PE is subscribed to analytics-engine application status

Implementing a Custom Analytics Engine

If you need to replace or extend the default Analytics Engine — for example, to support additional instrument types or a different pricing library — you can build your own service that implements the same RPC interface.

Your application must:

  1. Register the same RPC handlers with the RPC names and schema types listed in the RPC Functions above.
  2. Configure Price Engine to point at your app using KS_ANALYTICS_ENGINE_TOPIC_SOURCE.
  3. Permission your app as described in the Entitlements section.

The request and response DTOs are defined in the ks-model-pricing artifact:

<dependency>
<groupId>trading.keysquare</groupId>
<artifactId>ks-model-pricing</artifactId>
<version>${version}</version>
</dependency>

User Interface

Analytics Engine has a UI module in Key UI. See enabling the module below, and the Bond Calculator page for a detailed walkthrough.

Enabling the Module

  1. Update the configuration for web-data-server:
    • Append analytics-engine to KS_WEB_DATA_SERVER_UI_MODULES (comma-separated)
      e.g. KS_WEB_DATA_SERVER_UI_MODULES=analytics-engine,static-data-server,price-engine
    • Restart web-data-server
  2. Log in to Key UI with an admin account
    • Navigate to Admin → Modules
    • Select Analytics Engine from the module list
    • Toggle Enabled on and click Save

analytics engine module configuration

Detailed Topics