Optiver 是全球顶尖的做市商(Market Maker),其 OA 考察方向与传统科技公司有显著差异——除了标准的数据结构与算法,还会融入交易逻辑、订单簿模拟和概率推理等金融场景题。本文基于一亩三分地最新面经,系统拆解 Optiver OA 的核心题型与解题策略。
Optiver OA 概览
| 维度 | 详情 |
|---|---|
| 平台 | HackerRank |
| 时长 | 90 分钟 |
| 题量 | 2-3 道编程题 |
| 难度 | Medium - Hard |
| 考察重点 | 模拟、贪心、数学推理、低延迟思维 |
题型一:Trading Sequences(交易序列分析)
题目描述
给定一组交易价格序列 prices[] 和交易量 volumes[],需要找出满足特定条件的最优交易窗口。具体来说,你需要在序列中选择一个连续子区间 [l, r],使得该区间内的加权收益最大化。
解题思路
这道题本质上是加权最大子数组和的变体:
- 计算每个时间点的收益:
profit[i] = (prices[i+1] - prices[i]) * volumes[i] - 使用 Kadane's Algorithm 的变体求解最大连续子数组和
- 注意边界条件:交易窗口至少包含 2 个时间点
Python 解法
def max_trading_profit(prices, volumes):
n = len(prices)
if n < 2:
return 0
profits = [(prices[i+1] - prices[i]) * volumes[i] for i in range(n-1)]
max_profit = float('-inf')
current_sum = 0
for p in profits:
current_sum = max(p, current_sum + p)
max_profit = max(max_profit, current_sum)
return max(0, max_profit)
时间复杂度:O(n)
空间复杂度:O(n)
题型二:Order Book 模拟
题目描述
实现一个简化的订单簿系统,支持以下操作:
ADD side price quantity:添加限价单(side 为 BUY 或 SELL)CANCEL order_id:取消订单MATCH:执行撮合,当最高买价 ≥ 最低卖价时成交
解题思路
这是一道设计 + 模拟题,核心数据结构选择:
- 买单:使用最大堆(按价格降序)
- 卖单:使用最小堆(按价格升序)
- 订单索引:使用 HashMap 支持 O(1) 取消
Python 解法
import heapq
from collections import defaultdict
class OrderBook:
def __init__(self):
self.buy_orders = [] # max-heap (negate price)
self.sell_orders = [] # min-heap
self.cancelled = set()
self.order_map = {}
self.order_id = 0
def add(self, side, price, quantity):
self.order_id += 1
order = (price, self.order_id, quantity)
self.order_map[self.order_id] = order
if side == 'BUY':
heapq.heappush(self.buy_orders, (-price, self.order_id, quantity))
else:
heapq.heappush(self.sell_orders, (price, self.order_id, quantity))
return self.order_id
def cancel(self, order_id):
if order_id in self.order_map:
self.cancelled.add(order_id)
return True
return False
def match(self):
trades = []
while self.buy_orders and self.sell_orders:
# 清理已取消的订单
while self.buy_orders and self.buy_orders[0][1] in self.cancelled:
heapq.heappop(self.buy_orders)
while self.sell_orders and self.sell_orders[0][1] in self.cancelled:
heapq.heappop(self.sell_orders)
if not self.buy_orders or not self.sell_orders:
break
best_buy = -self.buy_orders[0][0]
best_sell = self.sell_orders[0][0]
if best_buy >= best_sell:
buy_order = heapq.heappop(self.buy_orders)
sell_order = heapq.heappop(self.sell_orders)
trade_qty = min(buy_order[2], sell_order[2])
trade_price = best_sell
trades.append((trade_price, trade_qty))
# 部分成交处理
if buy_order[2] > trade_qty:
heapq.heappush(self.buy_orders,
(buy_order[0], buy_order[1], buy_order[2] - trade_qty))
if sell_order[2] > trade_qty:
heapq.heappush(self.sell_orders,
(sell_order[0], sell_order[1], sell_order[2] - trade_qty))
else:
break
return trades
时间复杂度:ADD O(log n),CANCEL O(1),MATCH O(k log n)
空间复杂度:O(n)
题型三:Allocation(资源分配)
题目描述
给定 n 个交易员和 m 个交易机会,每个交易员有不同的资金上限和风险偏好。需要将交易机会分配给交易员,使得总收益最大化,同时满足每个交易员的约束条件。
解题思路
这是一个贪心 + 排序问题:
- 将交易机会按收益率降序排列
- 对每个交易机会,找到能承担该风险且资金充足的交易员
- 使用贪心策略分配
def allocate_trades(traders, opportunities):
# traders: [(capital, risk_tolerance)]
# opportunities: [(required_capital, risk_level, profit)]
opportunities.sort(key=lambda x: -x[2]) # 按收益降序
assigned = [False] * len(traders)
total_profit = 0
for cap_req, risk, profit in opportunities:
best_trader = -1
min_excess = float('inf')
for i, (capital, tolerance) in enumerate(traders):
if not assigned[i] and capital >= cap_req and tolerance >= risk:
excess = capital - cap_req
if excess < min_excess:
min_excess = excess
best_trader = i
if best_trader != -1:
assigned[best_trader] = True
total_profit += profit
return total_profit
Optiver OA 备考策略
核心能力要求
- 低延迟思维:Optiver 极度重视代码效率,O(n²) 在大数据量下不可接受
- 金融直觉:理解 bid/ask spread、order matching 等基本概念
- 边界处理:交易系统对精度和边界条件要求极高
- 并发意识:部分题目会考察对竞态条件的理解
推荐练习题
| LeetCode 题号 | 题目 | 对应考点 |
|---|---|---|
| 53 | Maximum Subarray | Trading Sequences |
| 1353 | Maximum Number of Events | Allocation |
| 295 | Find Median from Data Stream | Order Book |
| 480 | Sliding Window Median | 价格窗口分析 |
FAQ
Optiver OA 用什么平台?
Optiver 的 OA 通常在 HackerRank 上进行,时长约 90 分钟,包含 2-3 道编程题。部分岗位(如 Trader)还会有额外的数学和概率测试环节。
Optiver OA 难度如何?和 LeetCode 相比是什么水平?
Optiver OA 的编程题难度大约在 LeetCode Medium 到 Hard 之间,但题目风格偏向实际交易场景模拟,而非纯粹的算法竞赛题。需要候选人具备一定的金融市场基础知识。
Optiver SWE 和 Trader 的 OA 有什么区别?
SWE 岗位的 OA 侧重数据结构、算法和系统设计能力;Trader 岗位则更注重数学推理、概率计算和心算速度。两者都会涉及交易相关的场景题,但侧重点不同。
Optiver OA 之后的面试流程是什么?
通过 OA 后,通常会进入 HR 电话面试,然后是技术面试(1-2 轮),最后是 Superday(全天面试),包含系统设计、行为面试和团队匹配环节。
如何准备 Optiver 的交易模拟题?
建议先了解基本的做市商概念(bid-ask spread、order book、market making),然后练习堆、优先队列相关的 LeetCode 题目。同时可以参加 Optiver 的 Ready Trader Go 比赛来积累实战经验。
正在准备 Optiver OA?
oavoservice 提供专业的量化公司 OA/VO 辅助服务,覆盖 Optiver、Citadel、Jane Street 等顶级做市商。我们的团队成员来自各大量化机构,熟悉交易系统设计与算法面试。
👉 立即添加微信:Coding0201,获取真题与辅助方案。
联系方式
Email: [email protected]
Telegram: @OAVOProxy