打开导航 打开导航 Open menu
量化交易系统开发(C++)/ 期权策略与风控 / 行业研究分析
量化交易系统開發(C++)/ 期权策略与风控 / 行业研究分析
C++ trading systems / options strategy & risk controls / equity research
adrian@adrianxv.cn
文章目录

交易系统:FeatureEngine 交易系统:FeatureEngine 交易系统:FeatureEngine

先来总结一下,交易所侧和客户端侧分别有多少线程

进程业务工作线程Logger 线程主线程总计
交易所 exchange_main45110
每个客户端 trading_main3418

交易所侧的业务工作线程:

线程职责
OrderServer通过 TCPServer 接收客户端订单请求,由 FIFOSequencer 按接收时间排序后送入撮合请求队列;从响应队列读取撮合结果,发送给对应客户端。
MatchingEngine消费订单请求,维护交易所订单簿并执行撮合;生成客户端订单响应和公开市场行情,写入各自的输出队列。
MarketDataPublisher消费撮合引擎生成的市场行情,添加行情序号并通过组播发布增量行情;同时将行情转交给快照合成线程。
SnapshotSynthesizer消费增量行情并维护当前订单簿状态,定期通过组播发布完整快照,供客户端启动或丢包后恢复同步。

客户端侧的业务工作线程:

线程职责
MarketDataConsumer接收、处理市场行情,交给交易线程
TradeEngine更新本地订单簿、计算特征、运行策略,处理订单响应
OrderGateway向交易所发送订单请求,接收订单响应

FeatureEngine 的成员对象

class FeatureEngine {
private:
    std::string time_str_;
    Common::Logger *logger_ = nullptr;

    // 以下全部是本 feature engine 要采用的 feature
    double mkt_price_ = Feature_INVALID;
    double agg_trade_qty_ratio_ = Feature_INVALID;
}

feature engine 要采用哪些 feature 是和具体策略内容关系很大的事情。书中为了演示,采用 mkt_priceagg_trade_qty_ratio_ 两个 feature。这里的 mkt_price 采取了 “fair market price” 的一种算法:

$$mkt_price = \frac{bid_price \times ask_qty + ask_price \times bid_qty} {bid_qty + ask_qty}$$

//??:而生产级交易系统这里是用因子?生产级的流式因子计算引擎就是对于 feature engine 的扩充是不是?

有两种事件可能触发 FeatureEngine 的 feature 计算:订单簿更新和交易,这两种事件分别触发以下的两种回调函数:onOrderBookUpdateonTradeUpdate

onOrderBookUpdate

这个方法在 TradeEngine 持有的订单簿发生变化时调用,计算受到订单簿订单影响的 feature。在本书定义的两个 feature 当中,只有 mkt_price 是受到订单簿影响的(准确点说是只受到 bbo_ 的影响),因此此处只计算 mkt_price 这一个 feature。

auto FeatureEngine::onOrderBookUpdate(TickerId ticker_id, Price price, Side side, MarketOrderBook* book) noexcept {
    const auto bbo = book->getBBO();

    if (LIKELY(bbo->bid_price_ != Price_INVALID && bbo->ask_price_ != Price_INVALID)) { // bbo 当中的价格有意义
        mkt_price_ = (bbo->bid_price_ * bbo->ask_qty_ + bbo->ask_price_ * bbo->bid_qty_) / (bbo->ask_qty_ + bbo->bid_qty_);
    }
}

onTradeUpdate

与上面的方法相对,当前方法在发生交易的时候调用。

auto FeatureEngine::onTradeUpdate(const Exchange::MEMarketUpdate* market_update, MarketOrderBook* book) noexcept {
    const bbo = book->getBBO();
    if (LIKELY(bbo->bid_price_ != Price_INVALID && bbo->ask_price != Price_INVALID)) { // bbo 当中的价格有意义
        agg_trade_qty_ratio_ = static_cast<double>(market_update->qty_) / (market_update->side_ == Side::BUY ? bbo->bid_qty_ : bbo->ask_qty_);
    }
}

FeatureEngine 可能的扩展

  1. 独立计算服务

不同的因子对计算量、延迟有不同的要求时,可以按需求分配计算:

方式分工适用情况
同步计算交易线程更新订单簿、计算特征、执行策略计算轻、要求严格事件顺序和低延迟
异步计算计算线程或外部服务更新因子,交易线程接收结果计算较重、跨标的、可容忍一定延迟
混合计算快速盘口特征同步算,较慢的统计或模型异步算不同特征有不同更新频率和延迟要求
  1. 扩展因子
  • 可以使用更多元的数据来计算因子,包括历史数据、订单簿数据
  1. 引入机器学习评分
  • 由独立的线程采取已经训练好参数的机器学习/深度学习模型,直接加载参数
  • 加载 FeatureEngine 算好的因子,得到评分
  1. 管理计算依赖
  • 将因子拆成算子,按 DAG 顺序更新,共享中间结果,避免重复计算
  • 也就是,计算引擎保持由状态,维护

还有很多。我想这一块“计算什么因子、用什么模型来评分”就是量化研究的重点