← Voleon Interview Insights

Voleon·Software Engineer·Technical Phone Screen·Senior

Senior
May 2026

Summary

Voleon SWE interview with a three-part trading simulation problem. The whole thing was one big coding question and it escalated pretty fast from a basic order book to a multi-client fairness allocator.

Questions Asked (3)

Q1

Design a minimal limit order book simulator for a single symbol that handles NEW and CANCEL events, matches orders by price then time priority, and outputs the list of trades generated by each event.

Algorithms & Data StructuresSystem Design
Author's notes

The matching logic itself is not that bad once you commit to a structure.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements and assumptions (e.g., order types, price-time priority, output format). Then outline the core data structures: a price-sorted structure for bids and asks, and a FIFO queue per price level. Walk through the matching logic for NEW and CANCEL events, emphasizing efficiency and correctness.

Pro tip: Discuss the trade-offs between different data structures (e.g., heap vs. balanced BST vs. sorted list) and how they affect performance for high-frequency trading scenarios. Mention that you would use a doubly linked list for the FIFO queue to allow O(1) cancellation.

1. Clarify Requirements

Ask about order types (limit only?), event types (NEW, CANCEL), matching rules (price-time priority), and output format (list of trades per event). Confirm assumptions like no partial fills or self-trade prevention unless specified.

2. Design Data Structures

Propose using two sorted structures (e.g., balanced BST or heap) for bids and asks, each mapping price levels to a FIFO queue of orders. Use a hash map for O(1) order lookup by ID to support cancellations.

3. Implement Matching Logic

For a NEW order, match against the opposite side while prices cross, consuming orders from the best price level in time priority. For CANCEL, remove the order from its price level and clean up empty levels.

4. Handle Edge Cases and Output

Consider edge cases like cancelling non-existent orders, empty book, and orders that don't match. Ensure each event outputs the list of trades generated (price, quantity, buy/sell order IDs).

5. Analyze Complexity and Optimize

Discuss time complexity: O(log P) for insertion/removal from price levels (P = number of price levels), O(1) for order lookup and queue operations. Mention potential optimizations like using a skip list or array for price levels if price range is bounded.

Key Points to Mention

  • Price-time priority: orders match at the best price, and within the same price, earlier orders execute first.
  • Data structures: balanced BST (e.g., TreeMap) for price levels, doubly linked list for FIFO queue, hash map for order ID lookup.
  • Matching algorithm: while best bid >= best ask, execute trades at the resting order's price, updating quantities and removing filled orders.
  • Cancellation: O(1) removal from the queue using the hash map, and O(log P) removal of empty price levels.
  • Trade output: each event returns a list of trades, each with price, quantity, and the IDs of the matching orders.
  • Complexity analysis: O(log P) per event for price level updates, O(1) for order operations; space O(N) for N active orders.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

Given a stream of market prints representing executed market volume, implement an execution algorithm for a single client with a participation rate constraint, outputting how many shares to execute at each print without exceeding floor(p * cumulativeMarketVolume) at any point.

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

The floor function tripped me up more than I expected.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Clarify the problem constraints and edge cases, then propose a greedy algorithm that tracks cumulative market volume and cumulative executed shares, ensuring the participation constraint is never violated. Discuss trade-offs between simplicity and optimality, and consider potential improvements like smoothing or predictive adjustments.

Pro tip: Emphasize the importance of maintaining the invariant that executed shares never exceed floor(p * cumulative market volume) at any point, and discuss how to handle fractional shares and rounding consistently.

1. Understand the problem and constraints

Restate the problem: given a stream of market prints (each with a volume), output the number of shares to execute at each print such that cumulative executed shares ≤ floor(p * cumulative market volume) at all times. Clarify if p is a fixed participation rate, if there are any other constraints (e.g., minimum execution), and how to handle rounding.

2. Design a greedy algorithm

Maintain cumulative market volume (CMV) and cumulative executed shares (CES). At each print with volume V, compute the maximum allowed cumulative execution: maxCES = floor(p * (CMV + V)). The number of shares to execute at this print is max(0, maxCES - CES). Update CES and CMV accordingly.

3. Analyze correctness and edge cases

Prove that the greedy algorithm never violates the constraint: after each step, CES ≤ floor(p * CMV). Discuss edge cases: p=0 (execute nothing), p=1 (execute full volume), very small p causing zero execution for many prints, and handling of fractional shares (e.g., using integer arithmetic to avoid floating-point errors).

4. Discuss trade-offs and potential improvements

Mention that the greedy approach is simple and optimal for maximizing execution while respecting the constraint. However, in practice, one might want to smooth execution over time or use predictive models to avoid being too aggressive early on. Discuss the impact of latency and the difference between theoretical and practical implementations.

5. Consider implementation details

Talk about data structures: just a few variables to track cumulative volumes. Use integer arithmetic to avoid floating-point precision issues (e.g., represent p as a fraction). Ensure the algorithm is O(1) per print and can handle high-frequency streams.

Key Points to Mention

  • Greedy algorithm: execute as much as possible without exceeding the cumulative participation limit.
  • Maintain cumulative market volume and cumulative executed shares to enforce the constraint.
  • Use integer arithmetic (e.g., floor(p * CMV) computed with integer multiplication and division) to avoid floating-point errors.
  • Edge cases: p=0, p=1, small p, and prints with zero volume.
  • Trade-offs: simplicity vs. potential need for smoothing or predictive execution in real-world scenarios.
  • Complexity: O(1) time per print, O(1) space.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

Extend the participation rate executor to handle multiple simultaneous clients, allocating available volume at each print fairly by prioritizing clients with the lowest ratio of executed quantity to total target quantity, with ties broken by client ID.

Algorithms & Data StructuresSystem DesignTechnical Trade-offs
Author's notes

This part took me the longest.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Clarify the problem constraints and requirements, then propose a data structure that efficiently tracks each client's ratio and supports fair allocation. Describe the algorithm for processing each print, including how to update ratios and break ties, and discuss trade-offs and potential optimizations.

Pro tip: Emphasize the importance of fairness and determinism in financial systems, and mention how your solution ensures both while being efficient. Also, proactively discuss edge cases like zero targets or no available volume.

1. Clarify Requirements

Ask questions to confirm assumptions: What is the definition of 'fair'? How are clients represented? What is the expected scale (number of clients, prints per second)? Are there constraints on latency or memory?

2. Choose Data Structures

Propose a priority queue (min-heap) keyed by the ratio of executed quantity to total target quantity, with client ID as a tiebreaker. Alternatively, consider a balanced BST or a custom heap that supports efficient updates.

3. Design Allocation Algorithm

For each print, repeatedly extract the client with the smallest ratio, allocate a unit of volume (or the remaining volume) to them, update their executed quantity and ratio, and reinsert them into the heap. Continue until the print volume is exhausted or all clients have reached their targets.

4. Analyze Complexity and Optimize

Analyze time complexity per print: O(k log n) where k is the number of allocations and n is the number of clients. Discuss potential optimizations, such as batch processing or lazy updates, and trade-offs between fairness and performance.

5. Address Edge Cases and Testing

Consider edge cases: zero target quantities, clients with no remaining capacity, print volume larger than total remaining target, and ties in ratios. Describe how to test the solution for correctness and fairness.

Key Points to Mention

  • Priority queue (min-heap) keyed by ratio with client ID tiebreaker
  • Incremental updates to ratios after each allocation
  • Time complexity: O(k log n) per print, where k is number of allocations
  • Fairness definition: prioritizing lowest ratio ensures proportional allocation
  • Handling ties deterministically by client ID
  • Edge cases: zero targets, exhausted clients, insufficient volume

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.