Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- **Build an API that external partners can use to determine whether an order they receive is valid or not.**
- ### Input
- For the purpose of this exercise, imagine all incoming data to be in JSON. Here's an example order object:
- ```js
- let order = {
- profile: {
- age: 58,
- income_bracket: 'FROM_25K_TO_49K',
- liquid_net_worth: 'FROM_100K_TO_249K',
- investment_time_horizon: 'SIX_TO_TEN_YEARS',
- investment_risk: 'BALANCE_OF_RISK_AND_RETURN',
- investment_experience : [
- {
- name: 4,
- num_years: 15
- }
- ],
- is_employed: true,
- blockscore: 'green'
- },
- maturities: [
- {
- cusip_9: '777FJSJSK',
- interest_rate: 3.9,
- principal_amount: 1000,
- sp_rating_long: 'AAA',
- moody_rating_long: 'Baa2',
- fitch_rating_long: 'BBB' ,
- amount_available: 50000,
- series: 'A',
- maturity_year: 2028,
- quantity: 2
- },
- {
- cusip_9: '777FJSJSJ',
- interest_rate: 3.5,
- principal_amount: 5000,
- sp_rating_long: 'BBB',
- moody_rating_long: 'Aa1',
- fitch_rating_long: 'AAA',
- amount_available: 4000,
- maturity_year: 2035,
- series: 'B',
- quantity: 3
- },
- {
- cusip_9: '777FJSJSA',
- interest_rate: 2.7,
- principal_amount: 5000,
- sp_rating_long: 'AA+',
- moody_rating_long: 'Aa3',
- fitch_rating_long: 'BB+',
- amount_available: 7000,
- maturity_year: 2040,
- series: 'C',
- quantity: 1
- }
- ],
- total_amount: 22000,
- };
- ```
- ### Output
- API responses may look something like the following:
- ```json
- {
- "status": 1,
- "flagged_checks": [],
- "declined_checks": []
- }
- ```
- ```json
- {
- "status": 2,
- "flagged_checks": [
- {
- "key": "liquid_net_worth",
- "name": "Liquid net worth / income"
- }
- ],
- "declined_checks": []
- }
- ```
- ```json
- {
- "status": 3,
- "flagged_checks": [
- {
- "key": "liquid_net_worth",
- "name": "Liquid net worth / income"
- },
- {
- "key": "investment_risk",
- "name": "Investment risk"
- }
- ],
- "declined_checks": [
- {
- "key": "liquid_net_worth",
- "name": "Liquid net worth / income"
- }
- ]
- }
- ```
- Status output map:
- ```js
- const statusMap = {
- STATUS_PASS: 1,
- STATUS_FLAG: 2,
- STATUS_DECLINE: 3
- }
- ```
- ### Algorithm
- See the rules this algorithm consists of below (7 total checks).
- Take account of how many issues the order is flagged on, and on which issues the order is flagged on.
- If more than 2/3 are flagged, we automatically decline the order.
- If at least one check is decline, we decline the order.
- #### 1. Liquid net worth / income
- ##### Data values:
- We take the highest value of the bracket for liquid net worth and income, that are all integers.
- ```js
- const liquidNetWorthMap = {
- LESS_THAN_50K: 50,
- FROM_50K_TO_99K: 99,
- FROM_100K_TO_249K: 249,
- FROM_250K_TO_499K: 499,
- FROM_500K_TO_999K: 999,
- FROM_1M_TO_3M: 3000,
- GREATER_THAN_3M: 9999
- };
- const incomeBracketMap = {
- LESS_THAN_25K: 25,
- FROM_25K_TO_49K: 49,
- FROM_50K_TO_99K: 99,
- FROM_100K_TO_249K: 249,
- FROM_250K_TO_499K: 499,
- FROM_500K_TO_999K: 999,
- FROM_1M_TO_3M: 3000,
- GREATER_THAN_3M: 9999
- };
- ```
- ##### Pass
- ```
- total_amount / liquid_net_worth <= 0.15 OR total_amount / income_bracket <= 0.10
- ```
- ##### Flag
- ```
- total_amount / liquid_net_worth > 0.15 AND total_amount / income_bracket > 0.10
- ```
- #### 2. Risk tolerance
- ##### Data Values:
- Risk Tolerance of User:
- ```
- I want my money to be safe: 1
- I want a balance of risk & return: 2
- I only care about high returns: 3
- ```
- ```js
- const investmentRiskMap = {
- SAFE: 1,
- BALANCE_OF_RISK_AND_RETURN: 2,
- HIGHEST_RETURN: 3
- };
- ```
- S&P
- ```
- AAA, AA+, AA, AA-, A+, A: 1
- A-, BBB+, BBB, BBB-, BB+, BB, BB-, B+, B, B-: 2
- Other: 3
- ```
- Moody's
- ```
- Aaa, Aa1, Aa2, Aa3, A1, A2: 1
- A3, Baa1, Baa2, Baa3, Ba1, Ba2, Ba3, B1, B2, B3: 2
- Other: 3
- ```
- Fitch
- ```
- AAA, AA+, AA, AA-, A+, A: 1
- A-, BBB+, BBB, BBB-, BB+, BB, BB-, B+, B, B-: 2
- Other: 3
- ```
- Risk value of an order: highest maturity risk value from any agency (S&P, Moody's or Fitch)
- ###### Pass
- ```
- profile investment_risk >= the risk of Order
- ```
- ###### Flag
- ```
- profile investment risk < risk of Order
- ```
- #### 3. Investment experience
- ##### Data Values:
- ```
- Primary asset classes:
- Futures
- Options
- Commodities
- Bonds
- Stocks
- Mutual Funds
- Unit Investment Trusts
- Secondary asset classes:
- Everything else, including Other
- ```
- ```js
- const AssetClassMap = {
- BONDS: 1,
- STOCKS: 2,
- MUTUAL_FUNDS: 3,
- COMMODITIES: 4,
- EXCHANGE_TRADED_FUNDS: 5,
- FIXED_ANNUITIES: 6,
- FUTURES: 7,
- INSURANCE: 8,
- OPTIONS: 9,
- PRECIOUS_METALS: 10,
- REAL_ESTATE: 11,
- RETIREMENT_ACCOUNT_401K_OR_IRA: 12,
- UNIT_INVESTMENT_TRUSTS: 13,
- VARIABLE_ANNUITIES: 14,
- OTHER: 99
- };
- const AssetClassYearsOfExperience = {
- name: AssetClassMap['BONDS'],
- num_years: 10
- };
- ```
- Using the above, we need to calculate an experience level for each investor profile
- ```
- < 3 years experience in any primary asset class : 1
- => 3 years experience AND < 10 years experience in any primary asset class : 2
- => 10 years experience in any primary asset class : 3
- ```
- ##### Pass
- ```
- profile experience level >= the risk level of the order
- ```
- ##### Flag
- ```
- profile experience level < the risk level of the order
- ```
- #### 4. Age
- ##### Pass
- ```
- max years to maturity of the order + age <= 70 years
- ```
- ##### Flag
- ```
- max years to maturity of the order + age > 70 years
- ```
- years to maturity = maturity_year - current year
- #### 5. Time horizon
- ```js
- const timeHorizonMap = {
- UNDER_THREE_YEARS: 4,
- THREE_TO_FIVE_YEARS: 6,
- SIX_TO_TEN_YEARS: 11,
- ELEVEN_TO_TWENTY_YEARS: 21,
- MORE_THAN_TWENTY_YEARS: 31,
- DONT_KNOW: 31
- };
- ```
- ##### Pass
- ```
- max years to maturity <= time horizon
- ```
- ##### Flag
- ```
- max years to maturity > time horizon
- ```
- ##### Decline
- ```
- max years to maturity > time horizon * 2
- ```
- #### 6. Employment status
- ##### Pass
- ```
- true
- ```
- ##### Flag
- ```
- false
- ```
- #### 7. Blockscore Result
- ##### Pass
- ```
- green
- ```
- ##### Decline
- ```
- red
- ```
Add Comment
Please, Sign In to add comment