Guest User

Untitled

a guest
Mar 3rd, 2018
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.87 KB | None | 0 0
  1. **Build an API that external partners can use to determine whether an order they receive is valid or not.**
  2.  
  3. ### Input
  4.  
  5. For the purpose of this exercise, imagine all incoming data to be in JSON. Here's an example order object:
  6.  
  7. ```js
  8. let order = {
  9. profile: {
  10. age: 58,
  11. income_bracket: 'FROM_25K_TO_49K',
  12. liquid_net_worth: 'FROM_100K_TO_249K',
  13. investment_time_horizon: 'SIX_TO_TEN_YEARS',
  14. investment_risk: 'BALANCE_OF_RISK_AND_RETURN',
  15. investment_experience : [
  16. {
  17. name: 4,
  18. num_years: 15
  19. }
  20. ],
  21. is_employed: true,
  22. blockscore: 'green'
  23. },
  24. maturities: [
  25. {
  26. cusip_9: '777FJSJSK',
  27. interest_rate: 3.9,
  28. principal_amount: 1000,
  29. sp_rating_long: 'AAA',
  30. moody_rating_long: 'Baa2',
  31. fitch_rating_long: 'BBB' ,
  32. amount_available: 50000,
  33. series: 'A',
  34. maturity_year: 2028,
  35. quantity: 2
  36. },
  37. {
  38. cusip_9: '777FJSJSJ',
  39. interest_rate: 3.5,
  40. principal_amount: 5000,
  41. sp_rating_long: 'BBB',
  42. moody_rating_long: 'Aa1',
  43. fitch_rating_long: 'AAA',
  44. amount_available: 4000,
  45. maturity_year: 2035,
  46. series: 'B',
  47. quantity: 3
  48. },
  49. {
  50. cusip_9: '777FJSJSA',
  51. interest_rate: 2.7,
  52. principal_amount: 5000,
  53. sp_rating_long: 'AA+',
  54. moody_rating_long: 'Aa3',
  55. fitch_rating_long: 'BB+',
  56. amount_available: 7000,
  57. maturity_year: 2040,
  58. series: 'C',
  59. quantity: 1
  60. }
  61. ],
  62. total_amount: 22000,
  63. };
  64. ```
  65.  
  66. ### Output
  67.  
  68. API responses may look something like the following:
  69.  
  70. ```json
  71. {
  72. "status": 1,
  73. "flagged_checks": [],
  74. "declined_checks": []
  75. }
  76.  
  77. ```
  78.  
  79. ```json
  80. {
  81. "status": 2,
  82. "flagged_checks": [
  83. {
  84. "key": "liquid_net_worth",
  85. "name": "Liquid net worth / income"
  86. }
  87. ],
  88. "declined_checks": []
  89. }
  90.  
  91. ```
  92.  
  93. ```json
  94. {
  95. "status": 3,
  96. "flagged_checks": [
  97. {
  98. "key": "liquid_net_worth",
  99. "name": "Liquid net worth / income"
  100. },
  101. {
  102. "key": "investment_risk",
  103. "name": "Investment risk"
  104. }
  105. ],
  106. "declined_checks": [
  107. {
  108. "key": "liquid_net_worth",
  109. "name": "Liquid net worth / income"
  110. }
  111. ]
  112. }
  113.  
  114. ```
  115. Status output map:
  116.  
  117. ```js
  118. const statusMap = {
  119. STATUS_PASS: 1,
  120. STATUS_FLAG: 2,
  121. STATUS_DECLINE: 3
  122. }
  123. ```
  124.  
  125. ### Algorithm
  126.  
  127. See the rules this algorithm consists of below (7 total checks).
  128.  
  129. Take account of how many issues the order is flagged on, and on which issues the order is flagged on.
  130. If more than 2/3 are flagged, we automatically decline the order.
  131. If at least one check is decline, we decline the order.
  132.  
  133.  
  134. #### 1. Liquid net worth / income
  135.  
  136. ##### Data values:
  137.  
  138. We take the highest value of the bracket for liquid net worth and income, that are all integers.
  139.  
  140. ```js
  141. const liquidNetWorthMap = {
  142. LESS_THAN_50K: 50,
  143. FROM_50K_TO_99K: 99,
  144. FROM_100K_TO_249K: 249,
  145. FROM_250K_TO_499K: 499,
  146. FROM_500K_TO_999K: 999,
  147. FROM_1M_TO_3M: 3000,
  148. GREATER_THAN_3M: 9999
  149. };
  150.  
  151. const incomeBracketMap = {
  152. LESS_THAN_25K: 25,
  153. FROM_25K_TO_49K: 49,
  154. FROM_50K_TO_99K: 99,
  155. FROM_100K_TO_249K: 249,
  156. FROM_250K_TO_499K: 499,
  157. FROM_500K_TO_999K: 999,
  158. FROM_1M_TO_3M: 3000,
  159. GREATER_THAN_3M: 9999
  160. };
  161. ```
  162.  
  163. ##### Pass
  164.  
  165. ```
  166. total_amount / liquid_net_worth <= 0.15 OR total_amount / income_bracket <= 0.10
  167. ```
  168.  
  169. ##### Flag
  170.  
  171. ```
  172. total_amount / liquid_net_worth > 0.15 AND total_amount / income_bracket > 0.10
  173. ```
  174.  
  175. #### 2. Risk tolerance
  176.  
  177. ##### Data Values:
  178.  
  179. Risk Tolerance of User:
  180.  
  181. ```
  182. I want my money to be safe: 1
  183. I want a balance of risk & return: 2
  184. I only care about high returns: 3
  185. ```
  186.  
  187. ```js
  188. const investmentRiskMap = {
  189. SAFE: 1,
  190. BALANCE_OF_RISK_AND_RETURN: 2,
  191. HIGHEST_RETURN: 3
  192. };
  193. ```
  194.  
  195. S&P
  196. ```
  197. AAA, AA+, AA, AA-, A+, A: 1
  198. A-, BBB+, BBB, BBB-, BB+, BB, BB-, B+, B, B-: 2
  199. Other: 3
  200. ```
  201.  
  202. Moody's
  203. ```
  204. Aaa, Aa1, Aa2, Aa3, A1, A2: 1
  205. A3, Baa1, Baa2, Baa3, Ba1, Ba2, Ba3, B1, B2, B3: 2
  206. Other: 3
  207. ```
  208.  
  209. Fitch
  210. ```
  211. AAA, AA+, AA, AA-, A+, A: 1
  212. A-, BBB+, BBB, BBB-, BB+, BB, BB-, B+, B, B-: 2
  213. Other: 3
  214. ```
  215.  
  216. Risk value of an order: highest maturity risk value from any agency (S&P, Moody's or Fitch)
  217.  
  218. ###### Pass
  219.  
  220. ```
  221. profile investment_risk >= the risk of Order
  222. ```
  223.  
  224. ###### Flag
  225.  
  226. ```
  227. profile investment risk < risk of Order
  228. ```
  229.  
  230. #### 3. Investment experience
  231.  
  232. ##### Data Values:
  233.  
  234. ```
  235. Primary asset classes:
  236. Futures
  237. Options
  238. Commodities
  239. Bonds
  240. Stocks
  241. Mutual Funds
  242. Unit Investment Trusts
  243. Secondary asset classes:
  244. Everything else, including Other
  245. ```
  246.  
  247. ```js
  248. const AssetClassMap = {
  249. BONDS: 1,
  250. STOCKS: 2,
  251. MUTUAL_FUNDS: 3,
  252. COMMODITIES: 4,
  253. EXCHANGE_TRADED_FUNDS: 5,
  254. FIXED_ANNUITIES: 6,
  255. FUTURES: 7,
  256. INSURANCE: 8,
  257. OPTIONS: 9,
  258. PRECIOUS_METALS: 10,
  259. REAL_ESTATE: 11,
  260. RETIREMENT_ACCOUNT_401K_OR_IRA: 12,
  261. UNIT_INVESTMENT_TRUSTS: 13,
  262. VARIABLE_ANNUITIES: 14,
  263. OTHER: 99
  264. };
  265.  
  266. const AssetClassYearsOfExperience = {
  267. name: AssetClassMap['BONDS'],
  268. num_years: 10
  269. };
  270.  
  271. ```
  272.  
  273. Using the above, we need to calculate an experience level for each investor profile
  274.  
  275. ```
  276. < 3 years experience in any primary asset class : 1
  277. => 3 years experience AND < 10 years experience in any primary asset class : 2
  278. => 10 years experience in any primary asset class : 3
  279. ```
  280.  
  281. ##### Pass
  282. ```
  283. profile experience level >= the risk level of the order
  284. ```
  285.  
  286. ##### Flag
  287. ```
  288. profile experience level < the risk level of the order
  289. ```
  290.  
  291. #### 4. Age
  292.  
  293. ##### Pass
  294.  
  295. ```
  296. max years to maturity of the order + age <= 70 years
  297. ```
  298.  
  299. ##### Flag
  300.  
  301. ```
  302. max years to maturity of the order + age > 70 years
  303. ```
  304. years to maturity = maturity_year - current year
  305.  
  306. #### 5. Time horizon
  307.  
  308. ```js
  309. const timeHorizonMap = {
  310. UNDER_THREE_YEARS: 4,
  311. THREE_TO_FIVE_YEARS: 6,
  312. SIX_TO_TEN_YEARS: 11,
  313. ELEVEN_TO_TWENTY_YEARS: 21,
  314. MORE_THAN_TWENTY_YEARS: 31,
  315. DONT_KNOW: 31
  316. };
  317. ```
  318.  
  319. ##### Pass
  320. ```
  321. max years to maturity <= time horizon
  322. ```
  323.  
  324. ##### Flag
  325. ```
  326. max years to maturity > time horizon
  327. ```
  328.  
  329. ##### Decline
  330. ```
  331. max years to maturity > time horizon * 2
  332. ```
  333.  
  334. #### 6. Employment status
  335.  
  336. ##### Pass
  337. ```
  338. true
  339. ```
  340.  
  341. ##### Flag
  342. ```
  343. false
  344. ```
  345.  
  346. #### 7. Blockscore Result
  347.  
  348. ##### Pass
  349. ```
  350. green
  351. ```
  352.  
  353. ##### Decline
  354. ```
  355. red
  356. ```
Add Comment
Please, Sign In to add comment