Generating Inventory Positions

Inventory positions are computed by the Inventory engine based on transfers of cash and securities. They can be monitored through the Inventory Position report which reports funding requirements over a user-defined period.

 

Inventory Position Flow

 

1. Inventory Engine Configuration

The Inventory engine is configured in the Engine Manager of Web Admin: event subscription and engine parameters.

The Inventory engine can subscribe to the following events:

PSEventTransfer
PSEventProcessTransfer

The Inventory engine uses the following engine filter:

InventoryEventFilter. It only accepts known transfers related to a processing organization.

 

The behavior of the Inventory engine may be modified with the following engine parameters and environment properties.

If a parameter is not available for setup, you can register it in the "engineParam" domain.

Environment properties are specified in your Environment.

Parameters and Properties

Description

EXCLUDE_STATUS

Engine Parameter

Comma-separated list of status codes that are included in the "failed position".

INIT_DATE

No longer used as of version 14.1.

INV_MAX_POSITION

Engine Parameter

Number of positions that will be kept in memory by the Inventory engine. For example, a value of 10000 will allow a maximum of 10000 cash positions and 10000 security positions to be kept in the Inventory Engine memory. The default value of 0 means no limit.

INVENTORY_LOAD_TRADE

Environment Property

True or False. When false, trades are not loaded in the inventory engine. Default is True.

MAX_BATCH_EVENT

Engine Parameter

Maximum number of persistent events loaded at one time by an engine in batch mode. The engine will load events in MAX_BATCH_EVENT chunks until all events are processed. Persistent events received after MAX_QUEUE_SIZE is reached will be processed in batch mode.

Allows controlling engine memory usage, therefore improving the performance.

MAX_QUEUE_SIZE

Engine Parameter

Maximum number of events buffered on an engine event queue.

When this number is exceeded, real time events are discarded and the engine restarts based on the restart timer (TIMEOUT_RESTART), in order to process the unprocessed persistent events using batch mode. This parameter can be useful for controlling the engine’s memory usage. If not set, the default value for this parameter is no limit on queue size.

Allows controlling engine memory usage, therefore improving the performance.

ORACLE12_BATCH_MODE

Environment Property

True or false. Default is true.

When true, and database is Oracle 12 (or greater), the saving of inventory positions is optimized by using batch mode for events processing and engine_process table.

POSITION_FILTER

Engine Parameter

If value equals CASH the inventory engine calculates only cash positions, if value equals SECURITY it calculates only security positions, otherwise it calculates both.

Default is empty.

PricingEnv

Engine Parameter

Pricing environment used by the engine. If not set, the default Pricing Environment of the user running the engine will be used.

PROJECTED_DAYS

No longer used as of version 14.1.

TIMEOUT_RESTART

Engine Parameter

Number of seconds to wait before an engine restarts after MAX_QUEUE_SIZE has been reached. The default value is 3600 seconds (1 hour).

TWO_PHASE_ENGINE_NUMBER_OF_RETRY

Environment Property

Number of times the engine will retry to process the list of events in the TwoPhaseEngine used by Inventory engine, Margin Call Position engine and Position engine. Default value is 3.

 

2. Starting the Inventory Engine

The Inventory engine can be started from the Engine Manager in Web Admin.

The Inventory engine publishes the following events:

PSEventInventoryCashPosition
PSEventInventorySecurityPosition

 

Please refer to Calypso Web Admin documentation for complete details.

 

2.1 Inventory Positions Definition

Inventory positions are computed based on transfers of cash and securities.

Multiple types of positions are computed by the inventory engine and viewed from the Inventory Position report.

 

Actual Position

The actual position contains transfers that have settled.

 

Bank Confirmed Position

The "bank confirmed" position is the cash position confirmed by bank statements MT940/950.

 

Failed Position

The failed position contains transfers for which the settlement has failed. Status codes corresponding to failed transfers should be set in the domain "transferFailedStatus".

You can also use domains "transferSettledStatus" and “transferCashSettledStatus” (for cash transfers only) as described below.

If domain “transferFailedStatus” is not empty, then the failed position is determined based on the status codes in that domain. The other status codes populate the actual position.

If domain “transferFailedStatus” is empty, the system considers domain “transferCashSettledStatus” instead.

If domain “transferCashSettledStatus” is not empty, the status codes in that domain populate the actual cash position, and the status codes in domain “transferSettledStatus” populate the actual security position. The other status codes populate the failed position.
If domain “transferCashSettledStatus” is empty, the status codes in domain “transferSettledStatus” populate the actual cash and security positions. The other status codes populate the failed position.

Note that the transfer status codes set in the engine parameter EXCLUDE_STATUS are also added to the failed position.

 

Theoretical Position

The theoretical position contains all transfers regardless of their status (except status codes set in engine parameter EXCLUDE_STATUS).

 

Forecast Position

The forecast position shows the position of forecasted unknown transfers.

 

Expected Position

The expected position shows the positions based on the Available Date of the transfers when not settled, else it is based on the Real Settle Date. However, if Available Date < Settle Date, the expected position is still based on Available Date when the transfer is settled.

By default, the Available Date is set to the Trade Date.

You can set it to Value Date + number of days using domain "XferAvailableDate". Add a value that gives the number of days for a given static data filter in the following way: “<Number of Days>.<Static Data Filter>”.

For example: “1.MyEquityFilter”, and “2.MyBondFilter”.

If the transfer is accepted by MyEquityFilter, "1" business day is added to the Value Date using the Book holidays of the transfer to compute the Available Date.

For MyBondFilter, it would be 2 business days.

You can also add the number of days to the Trade Date, if you set the Comment to "TradeDate".

For example, if you set: Value = "1.MyFilter" and Comment = "TradeDate", then the Available Date is Trade Date + 1 business day.

 Ⓘ   [NOTE: As soon as this domain contains 1 value, the Available Date defaults to the Value Date. Make sure that you configure ALL your transfers accordingly]

 

You can add Value = SetDefault to the "XferAvailableDate" domain.

If Comment = true, the XferAvailableDate is defaulted based on the configuration when a transfer is modified (default behavior).

If Comment = false, the XferAvailableDate is not defaulted when a transfer is modified.

 

Statement Position

The statement position shows back-value movements and back-value failed movements (transfer value date is before transfer settlement date).

See Back-dated Movements for setup details.

 

Position Calculation

Each position is calculated by book / agent / agent account, and for the following dates:

trade date
settlement date
available date (for client positions only). Client positions are calculated on transfers with a given legal entity, for which the processing org and the agent are the same.
settlement frozen date, allows simulating a snapshot

Settlement Frozen Date for setup details

All inventory positions to be monitored by the Inventory engine are stored in the domain “InventoryPositions” in the form “<position class>-<position type>-<position date>”. For example, “INTERNAL-ACTUAL-SETTLE”.

 

2.2 Processing Transfers

If the transfer is a new transfer or is in CANCELED status, the THEORETICAL positions by SETTLE date and TRADE date are updated.

If the transfer has a status of SETTLED or the transfer is in CANCELED status and was previously in SETTLED status, the ACTUAL position by SETTLE date is updated.

You can define the list of transfer status codes to be considered as CANCELED in the domain "transferCanceledStatus".

If the transfer is in status FAILED or is in another status but was previously in a FAILED status (or any status in the "transferFailedStatus" domain), the FAILED position by SETTLE date is updated.

As described above, you can also define a domain "transferSettledStatus" that contains all settled status codes, and remove the domain "transferFailedStatus". All status codes not in "transferSettledStatus" will be considered not settled.

The failed position is updated by checking the value date and the settle date of the transfers. To update the settle date on a failed transfer, you can run the scheduled task FAILED_TRANSFERS and it will modify the settle date of failed transfers to the following day.

If a failed transfer is later settled, it will then appear in the ACTUAL position.

 

2.3 Updating Positions

The positions corresponding to the SETTLE DATE or TRADE DATE of the transfer are retrieved.

If no position exists for the given transfer, a new position is created by duplicating the latest known position before that date. If no position existed before, a new position is created.

If the transfer is in CANCELED status (or any status in the domain "transferCanceledStatus"), amounts are removed from the positions. Otherwise, the amounts are added to the positions.

When the positions are updated, all future positions which may depend on the updated position are updated.

 

2.4 Computing Custom Positions

In addition to computing positions by Book / Agent / Agent Account, you can add custom criteria to compute and display the positions. For example, Book / Agent / Agent Account / Product Type.

For this, you need to define the custom criteria using a Netting Config that contains the IsAggregation criteria. From the Calypso Navigator, navigate to Configuration > Settlements > Netting.

Sample setup for computing positions by Product Type: You need to define a netting config with keys "IsAggregation" and "ProductType".

Then add the netting config to the domain "InventoryAggregations".

Then restart the Inventory engine.

In the Inventory Position report, select the aggregation type “Agg. Config = Product Type” (the netting config you have created) to view the positions by product type.

You can also configure aggregation related columns using Data > Configure Columns.

You can define which positions are computed for a given aggregation using the domain “InventoryPositions<aggregation name>” , for example “InventoryPositionsProduct Type”. Then you can define the positions in the form “<position class>-<position type>-<position date>”. For example, “INTERNAL-ACTUAL-SETTLE”.

Create a domain for the "InventoryPositions<aggregation name>", then add the positions you want to compute as values.

In that case, it will only compute that position. If the "<aggregation name>" domain is not defined, it will compute all positions.

 

2.5 Back-dated Movements

In order to monitor back-value movements in statements, a STATEMENT position has been added. You need to add “INTERNAL-STATEMENT-SETTLE” to the domain “InventoryPositions”.

The domain "transferStatementStatus" has also been added – It should contain the transfer status codes that populate the position “INTERNAL-STATEMENT-SETTLE”: FAILED – SETTLED – VERIFIED.

The environment property XFER_BV_REAL_SETTLE_DATE must be set to true.

The statement account can be triggered for this type of position:

The following rule must be added to the transfer workflow:

In case the Statement Config is NOT based on Payment, iterator MT950NonPaymentIterator should be used instead of MT950Itereator in the MT950 XML template - MT950NonPaymentIterator iterates over the netted transfers rather than the Underlying Transfer.

 

2.6 Settlement Frozen Date

In order to activate this position you need to:

Add INTERNAL-THEORETICAL-SETTLE(FROZEN) to the domain “InventoryPositions”.
Add the rule CheckAllowCancel to the domain “mandatoryTransferRule”.

The rule ensures that the transfer is not UPDATED or ends up in a Canceled status once it is part of the Frozen position. It is possible to CANCEL a future transfer up to the value date of the transfer.

 

This position is using the transfer settlement amount and the position date as follows:

Settlement Frozen Date = Booking Date of the transfer when Booking Date > Value Date
Settlement Frozen Date = Value date of the transfer otherwise.

 

3. Inventory Snapshots

The INVENTORY_SNAPSHOT scheduled task allows freezing an inventory position at any time. You can run the Inventory Position report and BO Position Reconciliation report on inventory snapshots.

Please refer to Calypso Scheduled Tasks documentation for details.

 

4. Inventory Position Check

This function allows checking the inventory position before accepting a trade. The inventory position is checked by the LifeCycle engine based on Inventory Check configurations. The Inventory Check configuration allows selecting the workflow transition where the check should be performed and the nature of the check. If the Inventory Check configuration is satisfied, the action of the selected workflow transition is applied, otherwise the action is not applied and the LifeCycle engine generates an EX_INVENTORY_CHECK exception task.

 

4.1 Setup Requirements

 

Domains

Domain name = lifeCycleEntityType, Value = InventoryCheck

Domain name = exceptionType, Value = INVENTORY_CHECK

Domain name = eventType, Value = EX_INVENTORY_CHECK, Comment = "Exception generated by Inventory Check"

Domain name = groupStaticDataFilter, value = BOPosition

 

LifeCycle Engine

Please make sure you have started the LifeCycle engine as it is not started by default.

The LifeCycle engine must be subscribing to PSEventTrade and use the event filter LifeCycleEngineEventFilter.

 

4.2 Inventory Check Configuration

Bring up the Inventory Check Configuration window using menu action refdata.inventory.InventoryCheckConfigWindow.

» Click New to create a configuration and enter the fields described below as needed.
» Click Save to save the configuration.

 

Fields Description
Config ID

Given by the system upon saving.

Is Security Check

Check to check security positions, or clear to check cash positions.

Treat mirror as one Check to check that both the trade and the mirror trade (if any) satisfy the configuration, or clear to ignore the mirror trade (if any).
Task Comment Enter a comment as needed.
SDFilter

Mandatory.

Select a static data filter to restrict the trades to which the check is applied.

Example: For Bond Buy trades you want to check that the Cash Position is sufficient, and for Bond Sell trades you want to check that the Security Position is sufficient.

Workflow Transition

Mandatory.

Select the Trade workflow transition to which the check applies. If the configuration is satisfied, the action of the selected transition is applied, otherwise the action is not applied and an EX_INVENTORY_CHECK exception task is generated.

Inventory Template

Mandatory.

Select an Inventory Position report template to determine which position needs to be checked.

The system only uses the template to get the class/type/date, the movement type and the aggregation. Please make sure that the Inventory Aggregation in your template if applicable, matches the other criteria in the Inventory Check Configuration.

Operator

Mandatory.

Select an operator to check the position. The trade quantity (for security positions) / settlement amount (for cash positions) is added to / subtracted from the position (depending on the trade direction) and compared to 0 using the operator.

Examples:

If you select Greater (>), the check is Trade Quantity/Settlement Amount +/- Position > 0
If you select Less or Equal (<=), the check is Trade Quantity/Settlement Amount +/- Position <= 0
Account check

Mandatory.

Select the aggregation level to be checked.

Make sure that the selection matches the criteria of the Inventory Position report template.

Book/Agent/Account - Check is done at Book/Agent/Account level.
Book - Check is done at book level.
GL Account (from XferRule) - Check is done at Agent/Account level on PO Accounts
ClientAccount - Check is done at Agent/Account level on trades with trade keyword ClientAccount
Payer Pledge Account - Check is done at Agent/Account level. When selected, for margin calls and simple transfers with POPledgeSDI non null or PledgeSDI=true:
If the transfer rule direction is Pay, check the PO GL Account.
If the transfer rule direction is Receive, check the Cpty Intermediary Account.
Reference Date check

Select SettleDate or TradeDate - The date on the trade to use as a reference date for the inventory check.

Default is SettleDate.

Period check

Select 0D, 1D, 2D, TradeDuration.

This defines the Period End Date to check the position.

Default is TradeDuration.

The system checks positions from Period Start Date until Period End Date with:

Period Start Date = Reference Date check

Period End Date = Trade End Date if Period check=TradeDuration, Period Start Date + 0D/1D/2D Cal or Bus if Period check=xD

For Repo/SecLending trades, you need to set Period check = 0D so that securities are not checked after substitution.

For an OPEN Repo, Trade End Date = Current date + Notice days.

Is Bus. Day

Only applies if Period check is 0D, 1D or 2D.

Check to indicate that the days are business days, or calendars otherwise.

Holidays

Only applies if Is Bus. Day is checked.

Holiday calendar to determine the business days.

 

5. Custom Position Type

You can setup the computation of a custom position based on a custom transfer attribute. Custom position types can be defined for Internal positions and Client positions.

 

5.1 Configuration Requirements

 

Example with "Disbursed" position.

 

In the domain "cashInventoryCustomPositionType", add Value = Disbursed.

 

In the domain "InventoryCashBucketFactory", add Value = CustomBucketInventoryCash.

 

In the domain "cashInventoryCustomPositionType.Disbursed", add the transfer status codes eligible for this position:

Value = ALLOCATED

Value = SETTLED

 

In the domain cashInventoryCustomBucket, add the buckets. You can define up to 10 buckets (from Bucket0 to Bucket9).

Example:

Value = Bucket0

Value = Bucket1

etc.

 

In the domain "cashInventoryCustomBucket.Bucket#", define the actual name of the buckets:

 

Example:

Domain = cashInventoryCustomBucket.Bucket0

Value = Capital Retain

 

Domain = cashInventoryCustomBucket.Bucket1

Value = Treasury

 

etc.

 

In order for the Inventory engine to populate those buckets, the transfer attribute "Custom Bucket" must contain the bucket name.

Example: Custom Bucket = Capital Retain

You can add "Custom Bucket" to the "XferAttributes.UPDATE_XFER_ATTR.Editable" domain so that you can set the value of the attribute when applying action UPDATE_XFER_ATTR to a transfer.

 

This way, the Inventory engine will create a bucket named "Capital Retain" for the Disbursed position type and the transfers with Custom Bucket = Capital Retain.

 

5.2 Inventory Report

Select the cash movement types: Balance <bucket name> and Movement <bucket name> as needed.

Example: