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:
|
|||||||||||||||||||||
Account check |
Mandatory. Select the aggregation level to be checked. Make sure that the selection matches the criteria of the Inventory Position report template.
|
|||||||||||||||||||||
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: