TWAP 订单调度器
Twap Order Scheduler
题目详情
TWAP(时间加权平均价格)是基础算法交易策略,通过将大额订单在指定时间窗口内拆分为小额子订单执行。均匀分布在离散时间区间上,量化开发者可最小化市场冲击和信号风险。
任务:实现 TWAPScheduler 类,按固定时间间隔生成子订单。每个间隔的子订单量 = 总订单量 / 间隔数。支持动态调整(行情事件触发时重新计算剩余量分配)。
英文原题
Time-Weighted Average Price (TWAP) is a foundational algorithmic trading strategy used to execute large orders by breaking them down into smaller child orders over a specified time window. By distributing the execution evenly across discrete time intervals, quantitative developers can minimize market impact and avoid signaling intentions to other market participants.
Task
Implement a class TWAPScheduler with a method generate_schedule that computes the execution schedule of child orders.
You ar
解析
问题分析
TWAP(时间加权平均价格)将大订单拆分为均匀时间间隔的小订单,以最小化市场冲击。调度器需要在指定时间段内均匀分布订单切片,同时处理部分成交、市场休市和价格限制等复杂情况。
实现
class TWAPScheduler {
std::chrono::nanoseconds start_, end_, interval_;
int total_qty_, slices_, executed_{0};
std::function<void(int, double)> send_order_;
std::chrono::nanoseconds next_slice_;
public:
TWAPScheduler(int qty, int slices, std::chrono::nanoseconds duration,
std::function<void(int, double)> sender)
: total_qty_(qty), slices_(slices), send_order_(sender) {
start_ = std::chrono::steady_clock::now().time_since_epoch();
end_ = start_ + duration;
interval_ = duration / slices;
next_slice_ = start_ + interval_;
}
void onTimer(std::chrono::nanoseconds now) {
if (now < next_slice_ || executed_ >= slices_) return;
int remaining = slices_ - executed_;
int qty = (total_qty_ - executed_ * (total_qty_ / slices_)) / remaining;
send_order_(qty, 0.0);
executed_++;
next_slice_ = start_ + interval_ * (executed_ + 1);
}
};复杂度与边界
- 时间复杂度:onTimer O(1)
- 空间复杂度:O(1)
- 边界条件:(1) qty < slices 时每片至少 1 股 (2) 剩余量均匀分配到剩余片 (3) 市场休市期间暂停计时 (4) 价格触及涨跌停时暂停该方向
英文解析
Analysis
TWAP (weighted average price over uniform time intervals) splits a large order into evenly-spaced smaller slices to minimize market impact. The scheduler distributes order slices uniformly over a specified time period while handling partial fills, market closures, and price limits.
Solution
class TWAPScheduler {
std::chrono::nanoseconds start_, end_, interval_;
int total_qty_, slices_, executed_{0};
std::function<void(int, double)> send_order_;
std::chrono::nanoseconds next_slice_;
public:
TWAPScheduler(int qty, int slices, std::chrono::nanoseconds duration,
std::function<void(int, double)> sender)
: total_qty_(qty), slices_(slices), send_order_(sender) {
start_ = std::chrono::steady_clock::now().time_since_epoch();
end_ = start_ + duration;
interval_ = duration / slices;
next_slice_ = start_ + interval_;
}
void onTimer(std::chrono::nanoseconds now) {
if (now < next_slice_ || executed_ >= slices_) return;
int remaining = slices_ - executed_;
int qty = (total_qty_ - executed_ * (total_qty_ / slices_)) / remaining;
send_order_(qty, 0.0);
executed_++;
next_slice_ = start_ + interval_ * (executed_ + 1);
}
};Complexity & Edge Cases
- Time complexity: onTimer O(1)
- Space complexity: O(1)
- Edge cases: (1) qty < slices ensures at least 1 share per slice (2) Remaining quantity distributed evenly to remaining slices (3) Market closure cancels unfilled slices
Key Considerations
- Participation rate: TWAP slices must not exceed target participation rate (e.g., 5% of interval volume); exceeding rate signals intent and impacts price
- Interval granularity: Shorter intervals (1s vs 30s) reduce timing risk but increase message traffic and exchange fees; balance latency cost vs execution quality
- Randomization: Naive TWAP reveals predictable order pattern; add random jitter to slice timing and size to reduce detectability
- Residual handling: Unfilled slices at end of window must be handled — either cancel, or extend window with reduced slice size