4、订单路由基础:路由的概念、路由节点、路由路径、路由决策因子(价格、时间、成本)

订单路由,说白了就是你的订单该走哪条路去交易所。我刚开始接触暗池时,觉得这玩意儿不就是把单子扔过去嘛,有什么好研究的?后来被市场狠狠教育了一顿,才明白路由才是整个交易系统的命门。

你想想看,一个订单从你的交易终端出发,到最终成交,中间要经过多少道关卡?每个关卡怎么走,走哪条路,什么时候走,这些决策直接决定了你的成交质量。嗯,今天我们就来拆解一下这个基础但极其重要的环节。

路由的概念:不只是“发单”那么简单

路由,本质上是一个决策过程。它决定了你的订单应该被发送到哪个交易场所(交易所、暗池、ATS等),以及通过什么路径到达那里。

我习惯把路由比作导航。你输入目的地(交易标的),导航系统(路由引擎)会根据实时路况(市场状态)、你的偏好(成本、速度、隐蔽性)来规划最佳路线。不同的是,交易路由的决策时间窗口是以毫秒甚至微秒计算的。

核心要点:路由不是简单的“发单”,而是“在正确的时间,把正确的订单,送到正确的地方”。

我在项目中遇到过最典型的反例:有人把路由写成了一个固定的IP地址列表,轮询发送。结果某个交易所宕机了,订单还在往那里发,白白浪费了成交机会。这就是没理解路由的动态性。

路由节点:订单旅程中的驿站

一个订单从诞生到成交,会经过若干个节点。每个节点都可能影响订单的命运。

节点类型 作用 延迟影响
客户端节点 订单生成、本地校验 低(本地处理)
路由引擎节点 决策目的地、路径选择 中(计算+网络)
网关节点 协议转换、连接管理 中(协议解析)
交易所节点 订单匹配、成交 高(排队+撮合)
暗池节点 隐蔽匹配、大单处理 中(匹配逻辑)

每个节点都有自己的“脾气”。比如网关节点,如果连接池配置不当,高峰期会直接拒绝新连接。我曾经因为没注意网关的并发限制,导致一批大单被拒,那叫一个惨。

路由路径:条条大路通罗马,但有的路是死胡同

路由路径就是订单从起点到终点的具体路线。常见的路径模式有几种:

  • 直连路径:客户端直接连交易所。延迟最低,但灵活性差。
  • 代理路径:通过中间节点转发。可以聚合流量、做协议转换,但多一跳就多一份延迟。
  • 智能路径:根据实时条件动态选择。这是暗池路由的核心。

我建议在设计路径时,一定要考虑冗余。别只依赖一条路。我记得有一次,某交易所的专线光纤被施工队挖断了,幸好我们预留了公网备用路径,虽然慢了点,但至少没断单。

实战技巧:路径选择时,可以给每条路径打一个“健康分”。延迟、丢包率、历史成交率都可以作为评分因子。低于阈值的路径自动降权。

路由决策因子:价格、时间、成本

这是路由决策的三大支柱。说白了,就是你要在“成交价格”、“成交速度”和“交易成本”之间做权衡。

价格因子

价格因子不是指订单本身的报价,而是目标场所的预期成交价格。比如,A交易所的买一价是10.00,B暗池的买一价是10.01,那显然B暗池对卖方更友好。

但要注意,价格因子不能只看当前盘口。我习惯用预期滑点来评估。比如你的订单是100万股,A交易所盘口只有5万股,那你的大单进去肯定会把价格打穿。这时候暗池可能反而能给你更好的均价。

// 伪代码:价格因子评估
function evaluatePriceFactor(venue, orderSize) {
    let currentPrice = venue.getBestBid();
    let depth = venue.getOrderBookDepth();
    let expectedSlippage = calculateSlippage(orderSize, depth);
    let effectivePrice = currentPrice - expectedSlippage; // 卖方视角
    return effectivePrice;
}

时间因子

时间因子,说白了就是成交概率和速度。有些场所流动性好,订单进去秒成交;有些场所虽然价格好,但半天没人接盘。

我建议把时间因子拆成两个维度:

  • 预期等待时间:订单进入后,预计多久能成交。
  • 成交概率:在给定时间内,订单成交的可能性。

举个例子,暗池的成交概率通常低于交易所,但一旦成交,价格冲击小。如果你的订单对时间敏感(比如套利单),那交易所可能是更好的选择。

避坑指南:我曾经为了追求低延迟,把所有订单都往同一个低延迟交易所发。结果那个交易所的流动性其实很差,订单挂在那里半天不成交,反而错过了其他场所的机会。时间因子不能只看延迟,还要看流动性。

成本因子

成本因子包括显性成本和隐性成本:

  • 显性成本:手续费、交易所费用、清算费、数据费。
  • 隐性成本:市场冲击、信息泄露风险、机会成本。

我习惯把成本因子做成一个综合成本模型。比如:

综合成本 = 手续费 + 预期滑点 + 信息泄露风险溢价

信息泄露风险溢价怎么算?嗯,这个比较主观。我一般根据订单规模和场所的透明度来估算。暗池的信息泄露风险低,所以溢价可以设为负值(即成本优势)。

决策因子的动态权重

这三个因子不是固定权重的。市场环境变了,权重也得变。

比如:

  • 市场剧烈波动时,时间因子的权重应该提高。因为价格变化快,晚一秒可能就亏大了。
  • 大单交易时,成本因子(尤其是市场冲击)的权重应该提高。这时候暗池可能比交易所更合适。
  • 套利交易时,价格因子和时间因子并重,成本因子可以适当放宽。

我建议把权重做成可配置的,甚至可以根据历史数据自动调整。说白了,就是让系统自己学会在什么情况下该看重什么。

路由决策的完整流程

好了,我们把上面这些串起来,看看一个完整的路由决策流程是什么样的。

订单路由决策流程 订单接收 因子评估:价格 / 时间 / 成本 路径评分与排序 选择最优路径 → 发送订单 成交结果反馈 → 更新因子权重 反馈学习

这个流程看起来简单,但每个环节都有坑。比如因子评估阶段,如果数据源延迟太高,你评估出来的价格可能已经是过时的了。我建议在评估前先做一次数据新鲜度检查。

实战中的路由策略示例

最后,我分享一个我在项目中用过的简单路由策略。它不复杂,但很实用。

class SimpleRouter {
    constructor(venues) {
        this.venues = venues; // 所有可用的交易场所
        this.weights = {
            price: 0.4,
            time: 0.3,
            cost: 0.3
        };
    }
    
    route(order) {
        let bestScore = -Infinity;
        let bestVenue = null;
        
        for (let venue of this.venues) {
            let priceScore = this.evaluatePrice(venue, order);
            let timeScore = this.evaluateTime(venue, order);
            let costScore = this.evaluateCost(venue, order);
            
            let totalScore = 
                this.weights.price * priceScore +
                this.weights.time * timeScore +
                this.weights.cost * costScore;
            
            if (totalScore > bestScore) {
                bestScore = totalScore;
                bestVenue = venue;
            }
        }
        
        return bestVenue;
    }
    
    evaluatePrice(venue, order) {
        // 计算预期成交价格 vs 当前市场价格
        let expectedPrice = venue.getExpectedFillPrice(order);
        let marketPrice = this.getMarketPrice(order.symbol);
        return (marketPrice - expectedPrice) / marketPrice; // 越高越好
    }
    
    evaluateTime(venue, order) {
        // 基于历史数据估算成交时间
        let avgFillTime = venue.getAverageFillTime(order.size);
        return 1.0 / (1.0 + avgFillTime); // 时间越短分数越高
    }
    
    evaluateCost(venue, order) {
        // 综合成本评估
        let fee = venue.getFee(order);
        let impact = venue.estimateMarketImpact(order);
        let totalCost = fee + impact;
        return 1.0 / (1.0 + totalCost);
    }
}

这个策略虽然简单,但已经能处理大部分常规场景了。实际生产环境中,你还需要加入熔断机制、异常处理、动态权重调整等。嗯,这些我们后面会慢慢展开。

我的建议:刚开始做路由系统时,别追求完美。先跑通一个简单的版本,然后根据实际成交数据不断优化。纸上谈兵永远比不上实战数据来得真实。

好了,路由基础就讲到这里。记住,路由不是一成不变的,它需要根据市场的变化不断调整。你想想看,如果市场都变了,你的路由策略还停留在原地,那跟闭着眼睛开车有什么区别?


公众号:蓝海资料掘金营,微信deep3321