JJobsMoi
Robinhood

Fractional Share Inventory Trading

Coding

Problem

Problem Overview

Robinhood supports fractional share trading. Instead of sending every fractional order directly to the exchange, Robinhood can keep a small internal inventory of fractional shares for each stock symbol.

This is usually asked as a two-part simulation problem:

  1. First, process buy and sell orders and return Robinhood's final fractional inventory.
  2. Then, print the actual transactions Robinhood performs with users and the exchange.

The core data structure is a hash map from stock symbol to the fractional inventory currently held for that symbol. The main implementation detail is to avoid floating-point arithmetic. Store every share quantity as an integer number of hundredths, so 0.50 shares is stored as 50 and 1.00 share is stored as 100.

Part 1: Update Fractional Inventory

Problem Statement

You are given Robinhood's current fractional inventory and a list of user orders.

Inventory entries are strings in this format:

<symbol>/<quantity>

Order entries are strings in this format:

<side>/<symbol>/<quantity>

where:

  • BUY means the user buys shares from Robinhood.
  • SELL means the user sells shares to Robinhood.
  • quantity is a decimal share quantity with two digits of precision.

Rules:

  • Robinhood only keeps fractional inventory internally.
  • When a user buys shares, Robinhood first uses existing inventory.
  • If inventory is not enough, Robinhood buys the minimum whole number of shares from the exchange needed to fill the order, then keeps any remainder as inventory.
  • When a user sells shares, Robinhood adds those shares to inventory.
  • Whenever inventory reaches at least 1.00 share, Robinhood sells the whole-share portion to the exchange and keeps only the fractional remainder.
  • Return final non-zero inventory entries sorted by symbol in the same <symbol>/<quantity> format.

Example

inventory = ["AAPL/0.60"]
orders = [
    "SELL/AAPL/0.50",
    "BUY/AAPL/0.70",
    "BUY/TSLA/0.40",
]

Step-by-step:

Initial AAPL inventory = 0.60

User sells 0.50 AAPL:
  inventory becomes 1.10
  sell 1.00 whole share to the exchange
  remaining AAPL inventory = 0.10

User buys 0.70 AAPL:
  inventory has only 0.10
  buy 1.00 share from the exchange
  sell 0.70 to the user
  remaining AAPL inventory = 0.40

User buys 0.40 TSLA:
  inventory has 0.00
  buy 1.00 share from the exchange
  sell 0.40 to the user
  remaining TSLA inventory = 0.60

Output:

["AAPL/0.40", "TSLA/0.60"]

Complexity

Let N be the number of inventory entries, M be the number of orders, and K be the number of stock symbols tracked.

  • Time: O(N + M + K log K)
  • Space: O(K)

The K log K term is only for sorted output. The order simulation itself is O(N + M).

Part 2: Print Each Transaction

Follow-Up Prompt

The interviewer may then ask:

"Can you also print each transaction Robinhood executes?"

For example, if a user sells 0.50 shares while Robinhood already has 0.60 shares of that stock in inventory, Robinhood should print two transactions:

BUY 0.50 from the user
SELL 1.00 to the exchange

The final inventory is 0.10.

Key Insight

The inventory update rules do not change. The follow-up adds an audit log of Robinhood's actions:

  • User BUY: Robinhood may first buy whole shares from the exchange, then sells the requested quantity to the user.
  • User SELL: Robinhood buys the requested quantity from the user, then sells any whole-share inventory to the exchange.

Keep the log from Robinhood's perspective. A user sell is a Robinhood buy from the user. A user buy is a Robinhood sell to the user.

Example

inventory = ["AAPL/0.60"]
orders = [
    "SELL/AAPL/0.50",
    "BUY/AAPL/0.70",
    "BUY/TSLA/0.40",
]

final_inventory, trades = process_fractional_orders_with_trades(
    inventory,
    orders,
)

Output:

final_inventory == ["AAPL/0.40", "TSLA/0.60"]

trades == [
    "BUY/AAPL/0.50/USER",
    "SELL/AAPL/1.00/EXCHANGE",
    "BUY/AAPL/1.00/EXCHANGE",
    "SELL/AAPL/0.70/USER",
    "BUY/TSLA/1.00/EXCHANGE",
    "SELL/TSLA/0.40/USER",
]

Complexity

Let T be the number of generated transactions.

  • Time: O(N + M + T + K log K)
  • Space: O(K + T)

Each order generates at most two transactions in this model, so T is O(M).

Why This Works

For each stock symbol, the only state that matters for future orders is the fractional remainder currently held by Robinhood.

When a user buys, any shortage can be covered by buying whole shares from the exchange. Buying the ceiling of shortage / 1.00 shares is the minimum whole-share exchange order that can fill the user's fractional buy.

When a user sells, Robinhood's inventory increases. Any whole-share portion can be immediately sold to the exchange, leaving only inventory % 1.00 as the fractional inventory.

Because each order only touches one symbol and all updates are constant-time arithmetic, a hash map is enough.

Common Variants

Quantities Already Multiplied By 100

Some versions avoid decimals entirely and give quantities as integers:

AAPL/60
SELL/AAPL/50

In that case, parse_quantity() should return int(raw) directly, and format_quantity() should still divide by 100 for display if formatted output is required.

Different String Layout

Several reported versions pass each inventory and order element as a string with fields separated by /, but the order of fields may differ. Keep parsing isolated in helper functions so the simulation logic does not change.

Preserve Input Symbol Order

If the interviewer wants output in first-seen symbol order instead of sorted order, maintain a separate symbols list when parsing inventory and orders. The update rules stay the same.

Print From The User Perspective

The follow-up can ask for logs from the user's perspective instead of Robinhood's perspective. Clarify this before coding. The same events are emitted, but the trade sides are inverted for user-facing logs.

Solution

Loading editor…

Sign in to get AI feedback on your answer. Your work is saved while you do.

Sign in to evaluate