Problem · Math

Risk Limits and Inventory Skew

Learn this problem
MediumMillennium logoMillenniumNEW GRADINTERNOA

Problem statement

Decide whether to accept, widen, or reject one market-making quote request while respecting liquidity-scaled inventory limits.

Use these values:

  • hard = baseLimit * liquidityScore
  • soft = softFraction * hard
  • signedQuantity = -quantity for BUY and +quantity for SELL
  • projected = currentInventory + signedQuantity

Apply the rules in order:

  1. If abs(projected) > hard, return ["reject", "null"].
  2. Otherwise compute skew = -skewCoefficient * currentInventory. The base BUY quote is reference + halfSpread + skew; the base SELL quote is reference - halfSpread + skew.
  3. If abs(projected) > soft, the action is widen and one extra halfSpread is added for BUY or subtracted for SELL. Otherwise the action is accept.

Every decimal input is exact and has at most seven digits after the decimal point. Return a two-element string array [action, quote]. A non-rejected quote is rounded half upward to six decimal places and serialized with exactly six digits after the decimal point.

Function

decideRequest(currentInventory: int, side: String, quantity: int, reference: double, halfSpread: double, liquidityScore: double, baseLimit: int, softFraction: double, skewCoefficient: double) → String[]

Examples

Example 1

currentInventory = 0side = "BUY"quantity = 100reference = 100.0halfSpread = 0.05liquidityScore = 1.0baseLimit = 50000softFraction = 0.6skewCoefficient = 0.0001return = ["accept","100.050000"]

The projected inventory is -100, which is inside both limits. Current inventory is zero, so skew is zero and the base BUY quote is 100.050000.

Example 2

currentInventory = 300side = "BUY"quantity = 50reference = 100.0halfSpread = 0.05liquidityScore = 0.5baseLimit = 1000softFraction = 0.3skewCoefficient = 0.001return = ["widen","99.800000"]

The hard and soft limits are 500 and 150. Projected inventory is 250, so the request is widened. Skew is -0.3; the base quote 99.75 receives one extra 0.05 on the BUY side.

Constraints

  • -10^9 <= currentInventory <= 10^9
  • side is either BUY or SELL.
  • 1 <= quantity <= 10^9
  • 0 < reference <= 2 * 10^8 and 0 <= halfSpread <= 10^6.
  • 0.1 <= liquidityScore <= 1.
  • 1 <= baseLimit <= 10^9 and 0 <= softFraction <= 1.
  • 0 <= skewCoefficient <= 10^3.
  • Each decimal input has at most seven digits after the decimal point.
  • Every non-rejected quote is positive and at most 10^12.

Source note: The original assessment screenshot defines the liquidity-scaled limits, signed trade direction, skew, widening rule, and output action.

More Millennium problems

drafts saved locally
public String[] decideRequest(int currentInventory, String side, int quantity, double reference, double halfSpread, double liquidityScore, int baseLimit, double softFraction, double skewCoefficient) {
    // write your code here
}
currentInventory0
side"BUY"
quantity100
reference100.0
halfSpread0.05
liquidityScore1.0
baseLimit50000
softFraction0.6
skewCoefficient0.0001
expected["accept", "100.050000"]
checking account