返回题库

协程生成器行情

Coroutine Generator Prices

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

题目详情

高频交易系统需要高效状态管理以最小化延迟处理行情流。通过维护订单簿状态仅在成交发生时 yield 交易事件,系统可优化资源使用和事件处理。

任务:实现 PriceGenerator 类,使用 C++20 协程 generator 逐笔生成价格事件。维护内部订单簿状态,每次 yield 返回成交事件(价格、数量、方向)。支持多标的并发生成。

英文原题

High-frequency trading systems require efficient state management to process market data streams with minimal latency. By maintaining the state of the order book and yielding trade events only when matches occur, systems can optimize resource usage similar to lazy evaluation patterns. This problem simulates a matching engine using a stateful functor to process orders and generate trade prices.
Task
Implement the TradeGenerator class to act as a simplified matching engine for a continuous double

解析

问题分析

C++20 协程可用于生成惰性序列。在量化系统中,协程生成器可以从行情源逐条产出价格数据,调用方按需拉取,无需一次性加载全部数据。

实现

#include <coroutine>
#include <optional>
template<typename T>
struct generator {
    struct promise_type {
        T value;
        auto get_return_object() { return generator{this}; }
        auto initial_suspend() { return std::suspend_always{}; }
        auto final_suspend() noexcept { return std::suspend_always{}; }
        auto yield_value(T v) { value = v; return std::suspend_always{}; }
        void return_void() {}
        void unhandled_exception() { std::terminate(); }
    };
    struct iterator {
        std::coroutine_handle<promise_type> h;
        T operator*() const { return h.promise().value; }
        iterator& operator++() { h.resume(); return *this; }
        bool operator!=(std::default_sentinel_t) const { return !h.done(); }
    };
    iterator begin() { h.resume(); return {h}; }
    std::default_sentinel_t end() { return {}; }
private: std::coroutine_handle<promise_type> h;
};

复杂度与边界

  • 时间复杂度:每个值 O(1) 恢复
  • 空间复杂度:协程帧 ~数百字节
  • 边界条件:(1) 生成器析构前必须完成或销毁协程 (2) 异常传播需正确实现 unhandled_exception

英文解析

Analysis

C++20 coroutines can be used to produce lazy sequences. In quantitative systems, a coroutine generator can yield price data one item at a time from a market data source, with the caller pulling on demand, avoiding loading all data at once.

Solution

#include <coroutine>
#include <optional>
template<typename T>
struct generator {
    struct promise_type {
        T value;
        auto get_return_object() { return generator{this}; }
        auto initial_suspend() { return std::suspend_always{}; }
        auto final_suspend() noexcept { return std::suspend_always{}; }
        auto yield_value(T v) { value = v; return std::suspend_always{}; }
        void return_void() {}
        void unhandled_exception() { std::terminate(); }
    };
    struct iterator {
        std::coroutine_handle<promise_type> h;
        T operator*() const { return h.promise().value; }
        iterator& operator++() { h.resume(); return *this; }
        bool operator!=(std::default_sentinel_t) const { return !h.done(); }
    };
    iterator begin() { h.resume(); return {h}; }
    std::default_sentinel_t end() { return {}; }
private: std::coroutine_handle<promise_type> h;
};

Complexity & Edge Cases

  • Time complexity: Each value O(1) resume
  • Space complexity: Coroutine frame ~hundreds of bytes
  • Edge cases: (1) Generator must complete or destroy coroutine before destructor (2) Exception propagation requires correct unhandled_exception implementation

Verification

Generate price sequence from generator, verify lazy evaluation. Test iteration stops at end. Confirm coroutine cleanup on early termination.

Key Considerations

Coroutine generators provide the cleanest abstraction for streaming market data. A price generator can yield from mmap'd data, network feeds, or computed series - the consumer code is identical regardless of source, enabling interchangeable data pipelines in backtesting frameworks.