Technical Overview
The Landmark system, from Longview Consultants, is implemented at Nicholas Applegate as your traditional Vertically Integrated highly customised system. We essentially bought a database model with stored procedures and a front end (Triangle) which we subsequently replaced.
This is broken out into 3 applications, Weights, NATS (Nicholas Applegate Trading System) and NATS Explorer and 4 main sets of users, Portfolio Managers, Traders, Operations / Trade Support and Compliance.
Portfolio Managers use Weights, which contain 3 spreadsheet style forms to help them manage accounts.
Appraisal Rebalance, shows account details, listing all securities held in an account with their market valuation and % of account, allowing rebalancing of holding based off targets or existing models. Models are templates or idealised holdings which can be applied to accounts. These are maintained by a separate Model form which lists the security and target percent. This needs enhancing to allow models to be rebalanced by change of security price.
Security Cross Reference, shows all accounts, or combinations of accounts that hold a particular security. This is used to say sell off all holdings or review the exposure of the firm or portfolio group to a security
Composite Rebalance works off a group of accounts and allows a PM to add / remove a security or sector from groups of accounts.
Portfolio Managers create proposed orders to internally store possible new trades. There can only be one proposed order per account / security. When they are happy with their proposed orders they will create real orders. Proposed orders can be deleted and are in no way an obligation to trade that account / security combination.
This includes the main trade flow processing, with 4 screens: Trading, Placements, Executions and Allocations. In addition, 3 blotter screens are available, a Main / Retail / Conflict blotter running off blocked orders, a Proposed Orders blotter based off proposed orders, and a Notifications blotter listing any changes to any proposed orders / orders on the system.
The main trading screen allows manual entry of proposed orders, or loading from a CSV file. The proposed orders can then run compliance checks on them, and then create real orders off them. The real orders will be blocked with other orders entered on the same screen for the same security and direction.
Traders will use the Trading and Placement forms and have multiple blotters open to tell them of new orders. Trade Support / Ops will use the Execution and Allocation forms.
NATS Explorer is the static data maintenance application, allowing users to maintain Accounts, Securities, Holdings, Brokers, and a whole lot more. Typically used by Operations / Trade Support, and by Compliance to maintain their Compliance Models.
This is no processing engine as such for the Landmark system, but there are a patchwork of perl jobs run from the Autosys job scheduler maintained by Production Support. These perl jobs are responsible for:
|
Job |
Description |
|
Nightly Load |
Various tables are reloaded from the Corporate Database every night. These include Securities, Prices, Holdings, Hierarchies, Compliance checks. We create a table of required rows on Landmark. BCP that table into the Corporate Database. Populate a number of tables with the required rows. BCP those tables back into Landmark. |
|
Oasys Feed |
A job that runs at user request to send allocation detail from us to the brokers. A file is generated and placed on a Network drive to be picked up by an oasys terminal which does the transmission on the Oasys network |
|
Shaw Feed |
A job that runs at user request to send allocation detail to the accounting system Shaw. A file is generated and FTPed over a leased line from MCI Worldcom to Shaw. We wait until a reply file is generated, ftp it back and mail it to users. |
|
EOD Job |
Clears non-sent allocations from the system and performs housekeeping jobs |
|
Control Panel |
A web based interface to allow users to kick off the Oasys, Shaw and EOD Jobs. Two interfaces, one for Domestic Ops, one for Global Ops. Based off file semaphores which are picked up by daemons which execute the real jobs. |
|
SMC |
Settlement Messaging Centre routes allocations from Landmark either onto the Swift network, or prints out a fax message which is then manually faxed. SMC is a Java client server system used to verify the messages before they are sent. |
|
Refresh Jobs |
The blotter table is rebuilt every 11 seconds by a background daemon job. Hence the foreground VB apps only need to read a single table rather than do an 11 table join. A similar job runs to maintain the security_data table. |
There are maybe 100 reports on the system. Most are Crystal Reports, tied into the front end, runnable at request by the users, however these are not schedulable overnight. InfoReports is also used, as a strategic project, and is run overnight. Reports are emailed to the users or are available on the web via Datasurfer. Unfortunately these reports are not available to online users.
|
Trade Type |
Description |
|
Proposed Orders |
These are throw away possible orders generated by Weights rebalance processes and the NATS Trading screen. Before these can be converted to real trades, Compliance Checks need to be run on them. Processing: Compliance Checks Order Creation and Blocked Order creation |
|
Orders |
These are Account / Security level orders. Processing is done to create the blocked orders |
|
Blocked orders |
These are security level orders and combine all orders for that security / direction (e.g. all buy orders can be combined) that are done in a users screen, or those that have been merged to the block from the blotter. Processing: these appear on the blotter |
|
Placements / Tickets |
A trader sees a blocked order and decides to trade it. They will place part or all of the blocked order at a brokerage firm, creating a placement or ticket. Currently the broker notification is done over the phone. This should be replaced by Global Oasys |
|
Executions |
A broker will phone back giving execution details on the ticket. Trade Support will take the ticket and add executions to it till it is fully executed. |
|
Allocations |
Once a ticket is executed, it can be allocated to the accounts that requested the buy / sell. Again a manual process, users are given a list of executed tickets and can allocate them to accounts. They then mark them ready for Oasys / Shaw. In the nightly load, we get a list of allocations that have been processed by Shaw, and a confirmed flag is set on them. When all allocations for a blocked order are confirmed, the entire blocked order tree is removed (audited into _history tables). An allocation confirmed means the positions table has been updated. |
Before a proposed order can become a real order which can be traded, compliance checks are run on it to ensure we meet various criteria. This is essentially a rule based check, and there are 5 levels: a pass, warning, override required (someone other than the trader has to enter a password), 2 overrides required (2 different people are required) and a hard error (we cannot trade this account / security combination).
Compliance Checks are defined at an account level, with any checks defined for any parents / grandparents etc of the account also included. The currently used restrictions are:
|
Restriction |
Description |
|
Buy / Sell |
puts a restriction against every proposed order |
|
Buy |
restricts any buys |
|
Sell |
restricts any sells |
|
Industry |
restricts buys if the securitys industry market value is outside the percentage range specified for the account |
|
Cash |
restricts if the cash in the account is outside the percentage range specified for the account |
|
Country |
Does Country of Issue, Origin and Exposure checks. If the security has a country that this account is restricted from, or is not on the approved list, a restriction is generated. |
|
Exchange |
restricts if the security has an exchange that this account is restricted from, or is not on the approved list. |
|
Holdings Range |
restricts if the number of securities held outside specified range, eg account can only hold 15 securities |
|
List |
restricts if security has a hierarchy / level 1 that is restricted on the account level. |
|
Market Capitalisation Range |
restricts buys if the market capitalisation of the security is outside the set range for the account. |
|
Security in Model |
restricts if security is in a restriction model for the account |
|
Prohibited Country |
restricts if we are prohibited from trading with the securitys country of issue, origin, exposure or exchange, eg Iraq. This is a firm wide restriction. |
|
Shares Outstanding |
restricts buys if Nicholas Applegate accounts will own more than a percentage of the total market capitalisation of the security |
|
Single Issue |
restricts buys if the percent that security makes of account market value is outside a specified percent range. |
An example of a restriction would be the Sisters of Mercy account, which has a restriction against any Tabacco companies. If a buy for Philip Morris went against this account, a hard error would be created and the proposed order could not be promoted to a real order.
This is the heard of the Weights application and what Portfolio Managers do most of the time. The key form is the Appraisal screen which lists the holdings for an Account, and the percent of the account market value they make eg:
|
Security |
Percent |
Price |
Qty Booked |
Market Value |
|
Technology |
|
|
|
|
|
IBM |
30% |
30 |
10,000 |
$300,000 |
|
Amazon |
25% |
25 |
10,000 |
$250,000 |
|
subtotal |
55% |
|
20,000 |
$550,000 |
|
Telecoms |
|
|
|
|
|
MCI Worldcom |
45% |
22.5 |
20,000 |
$450,000 |
|
subtotal |
45% |
|
20,000 |
$450,000 |
|
TOTAL PORT |
100% |
|
40,000 |
$1,000,000 |
Say that the account had a policy of having 50% of its account market value in Telecoms, 50% in Technology. Hence the Target Percent for MCI Worldcom should be 50%, and say the IBM target percent should be 25%
The target quantity would be: Account Market Value in USD x Target Percent / USD Price
For MCI Worldcom: $1,000,000 x 50% / 22.5 = 22,222
For IBM: $1,000,000 x 25% / 30 = 8,333
Hence the order quantity would be: Target Quantity - (Held + Open)
For MCI Worldcom: 22,222 - 20,000 = 2,222. Round lot to: Buy of 2,200
For IBM: 8333 - 10,000 = -1,666. Round lot to: Sell of 1,700
Hence with the 2 proposed orders the account would be brought back into line.
To keep a number of accounts following the same investment strategy, a model could be created with the securities and their target percents, so in the above, we would have IBM 25%, Amazon 25%, MCI Worldcom 50%. This could then be applied to various accounts, and whatever their previous makeup, after rebalancing to the model, buys and sells would be generated to bring the account back into line.
Full rebalance documentation on http://sunrise/~pstephen
There are 3 databases in Landmark. The database landmark is the core database containing all the tables supplied by Longview Consultants. The database landmark_client contains tables added by Nicholas Applegate, eg configuration tables. The database nats_history is an overflow database to contain history data for trades.
Each trade type has its own table, which contains fields for every attribute held, so we have proposed_orders, orders, tickets, equity_execution and allocations.
proposed_orders is keyed on account_id and security_id. If a proposed order already exists, and a PM or trader wants to create a new proposed order for that account / security, the old one is deleted.
orders is keyed on order_id, and contains a link to the blocked_order via block_id. History is kept in orders_history
blocked_orders is keyed on block_id. This is the key table to the entity relationships. One blocked order may map to many orders. Once blocked order may map to many tickets, which may in turn map to many executions, which may in turn map to many allocations. History is kept in blocked_orders_history
Tickets are held on ticket with vertically split tables equity_ticket and equity_placement. These are keyed on ticket_id. History is kept in ticket_history, equity_ticket_history and equity_placement_history.
equity_execution is keyed on ticket_id and execution_id. History is on equity_execution_history
allocations is keyed on allocation_id, with a more common key used as ticket_id, order_id. History is on allocations_history.
Trades are only held on the main tables till the entire blocked_order is allocated and confirmed. Then all the rows are moved onto the history tables. Hence the main tables are relatively small, hence reducing any performance problems present in trade processing. Once on the history tables, there is little that can be done for them, no reports etc.
There is no real Amendment or Cancel / Correct logic. If a user wants to amend the quantity on an order or another value, it simply updates the fields on the table. There is online processing that tries to recalculate blocks etc, this is well dodgy. There is no trade version history.
There is no back end trade processing as such, no transaction engine. Any trade processing occurs synchronously when the user commits a trade. Any trade processing on a trade is hard wired in, there is no trade type definition.
Oh dear. Landmark does not keep positions and relies on the external accounting system Shaw to provide a positions table which is loaded in the overnight load. Sometimes, open orders are needed to be included in the positions, and this is done by additional queries which simply sum the open orders on the system. Positions are keyed on account / security and contain the allocated position as of last night. There is no history kept on the system. There is no Trade Date positions or Settle Date positions, no depot positions or anything else.
If a position is wrong (users chose the wrong symbol etc), users can directly modify the positions table via NATS Explorer Accounts / Security Detail form, inserting / amending / deleting rows.
Account detail is held in the account table, integer indexed on the account_id field. Related tables are:
|
Table |
Description |
|
account_hierarchy |
contains parent - child account relationships |
|
expanded_account_id |
contains expanded parent - child relationships going down the tree, so grandchild etc are included |
|
account_restriction |
maps accounts to any restriction models in force on that account |
|
expanded_account_restriction |
denormalized structure. |
Security detail is held on the security table, integer indexed on the security_id field. Related tables are:
|
Table |
Description |
|
Security_data |
denormalised table, used by blotter queries |
|
Equity |
information related to equities only |
|
currency |
information related to currencies only. Contains exchange rate to USD. |
|
Fixed_income |
information related to debt securities only. However debt processing is missing from the functionality currently supported. |
|
Price |
the latest price only. No price history is kept. |
|
Hierarchy_map |
A way of classifying securities. Currently there are 14 different classifications which can be defined down 3 levels (though only 2 are currently used). |
|
Issuer |
brief information about the issuer of the security |
|
restriction_model_security |
specifies which models the security belongs to, eg Philip Morris belongs to Tabacco Products Services |
User information is pretty simple. Security is maintained by having the user log directly into Sybase and relying on Sybases username / password checks. user_information table contains name and functional restriction information. It is integer indexed on user_id, and also contains the related suid for the user. Many tables have created_by (smallint) and created_time (datetime) fields and some also have modified_by (smallint) and modified_time (datetime), to aid auditing. The created_by and modified_by contains either the user_id from the user_information table, or the suid - there is no method in the madness.
Landmarks way of supporting extensible data - or user defined fields - is particularly crude. Each main table has a number of user_field_1-8 or user_id_1-8 fields, which can be filled with whatever you want. So for the security table, user_id_1 = Ticker, user_id_2 = Reuters, user_id_3 = Cusip, user_id_4 = Sedol, user_id_5 = ISIN. The stored procedures are then modified to use these user fields. There are no static data defined attributes, no external refs table or traditional normalisation.
Triggers have thankfully been reduced down to the minimum possible, due to problems with transaction length and their maintainability issues. Returning errors to VB code is normally done via raiserror 99999. Most processing in Landmark is done one trade at a time, though work is underway to change the compliance checks and order creation to process sets of trades. Transaction protection is sometimes present, sometimes not, and even where it is present, there is no deadlock detection in VB to loop around and repeat code that has deadlocked.
All 3 main applications, Weights, NATS and NATS Explorer are written in Visual Basic. Each one has its own source base, even though some forms are duplicated across the applications, eg New Security and Notifications forms.
Database access is done via RDO, with most calls placed in a separate module called DB or DatabaseRoutines, with functions called DB_GetSecurity etc. Unfortunately, the rdo calls are called directly with no wrapper routine. There is little error detection, sometimes non at all, so any errors returned by stored procedures are normally ignored or may even cause a run time error. All output is returned as result sets as there is no code to interpret parameter outputs. Deadlocks are not detected and no warnings are displayed about them. However stored procedures are not always transaction protected so this doesnt happen too frequently.
True DBGrid Pro 6.0 is heavily used, appearing in most forms. This allows users to view all appropriate rows and select rows for further actions. Active Thread Plus is used in NATS for Trading form processing.
NATS and Weights are pretty traditional applications. NATS Explorer relies on the forms fields to build up SQL to update tables. So on the Account Detail form, the particular fields all match the account tables fields. This provided quick application build time. It has however proved difficult to maintain, particularly handling the special cases that invariably turn up.