返回题库

TWAP 订单调度器

Twap Order Scheduler

专题
Systems & Architecture / 系统与架构
难度
L2
来源
MyntBit

题目详情

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

  1. Participation rate: TWAP slices must not exceed target participation rate (e.g., 5% of interval volume); exceeding rate signals intent and impacts price
  2. Interval granularity: Shorter intervals (1s vs 30s) reduce timing risk but increase message traffic and exchange fees; balance latency cost vs execution quality
  3. Randomization: Naive TWAP reveals predictable order pattern; add random jitter to slice timing and size to reduce detectability
  4. Residual handling: Unfilled slices at end of window must be handled — either cancel, or extend window with reduced slice size