第27章:高级订单类型:条件订单与算法交易

做市商系统里,普通限价单和市价单只是基本功。真正让系统拉开差距的,是那些高级订单类型。我个人习惯把这类订单叫做「智能订单」——它们不是简单地报个价格等成交,而是带着策略逻辑去执行。

今天咱们重点聊三种:条件订单(Stop Loss/Take Profit)、TWAP 和 VWAP。这三种订单,我在不同项目里都踩过坑,也积累了一些实战经验,分享给你。

27.1 条件订单:止损与止盈

条件订单,说白了就是「当市场达到某个条件时,自动触发一个动作」。最常见的两种:止损单(Stop Loss)和止盈单(Take Profit)。

嗯,这里要注意:条件订单不是立即成交的订单,它是一个触发器。触发后,系统会生成一个市价单或限价单去执行。

27.1.1 止损单(Stop Loss)

止损单的逻辑很简单:当市场价格跌破某个价位时,立即卖出(做多场景)。目的是限制亏损。

我曾经在开发一个期权做市系统时,遇到过一个大坑:止损单触发后,如果市场流动性不足,市价单会以极差的价格成交。那次我们亏了不少钱。

所以后来我建议:止损单最好配合限价使用,或者设置一个滑点容忍度。

// 止损单核心逻辑(伪代码)
class StopLossOrder {
    double triggerPrice;   // 触发价格
    double limitPrice;     // 限价(可选)
    double quantity;       // 数量
    OrderSide side;        // 买卖方向
    
    bool checkTrigger(double currentPrice) {
        if (side == LONG) {
            return currentPrice <= triggerPrice;
        } else {
            return currentPrice >= triggerPrice;
        }
    }
    
    Order generateMarketOrder() {
        // 生成市价单或限价单
        return new MarketOrder(side, quantity);
    }
}

27.1.2 止盈单(Take Profit)

止盈单和止损单正好相反。当价格涨到目标位时,自动平仓获利。

你想想看,做市商每天处理成千上万笔交易,如果每笔都手动盯盘止盈,那根本不可能。所以止盈单是自动化交易的基础组件。

关键点:止损和止盈的触发价格,建议留一个缓冲区间(buffer)。比如止损价是100,实际触发价可以设在99.98。这样可以避免价格刚好在边界震荡时反复触发。

27.2 时间加权平均价格算法(TWAP)

TWAP 的全称是 Time-Weighted Average Price。它的目标很简单:在指定时间内,把大单拆成小单,均匀地执行。

为什么要用 TWAP?因为大单直接砸进去,会把市场砸出个大坑,成交价格很差。TWAP 就是为了「隐藏意图」,让市场感觉不到你在大量买入或卖出。

27.2.1 TWAP 的核心逻辑

TWAP 把总时间分成 N 个等长的时间片,每个时间片执行等量的订单。

// TWAP 算法核心逻辑
class TWAPExecutor {
    double totalQuantity;    // 总数量
    int totalSeconds;        // 总时间(秒)
    int sliceSeconds;        // 每个时间片长度(秒)
    
    double getSliceQuantity() {
        int slices = totalSeconds / sliceSeconds;
        return totalQuantity / slices;
    }
    
    void executeSlice() {
        double qty = getSliceQuantity();
        // 发送限价单或市价单
        sendOrder(qty);
    }
}

举个例子:你想在 10 分钟内买入 1000 个 ETH。TWAP 会把 10 分钟分成 10 个 1 分钟的时间片,每个时间片只买 100 个 ETH。

实战技巧:我建议 TWAP 的时间片长度不要固定死。可以加入随机偏移,比如 55-65 秒之间随机。这样更不容易被市场察觉你的交易模式。

27.2.2 TWAP 的优缺点

优点 缺点
实现简单,逻辑清晰 不考虑市场成交量变化
适合流动性较好的品种 在成交量稀疏时段效果差
执行成本可预测 无法利用流动性好的时机

27.3 成交量加权平均价格算法(VWAP)

VWAP 比 TWAP 更聪明一些。它不只是均匀地按时间拆分订单,而是根据市场的成交量分布来分配订单量。

说白了:市场成交量大的时候,我多买点;成交量小的时候,我少买点。这样我的订单对市场的影响更小,成交价格也更接近市场均价。

27.3.1 VWAP 的核心逻辑

VWAP 需要历史成交量数据作为参考。通常我们会取过去 5-10 个交易日的成交量分布,预测今天的成交量曲线。

// VWAP 算法核心逻辑
class VWAPExecutor {
    double totalQuantity;
    vector<double> volumeProfile;  // 历史成交量分布
    
    double getSliceQuantity(int timeIndex) {
        double totalVolume = sum(volumeProfile);
        double volumeRatio = volumeProfile[timeIndex] / totalVolume;
        return totalQuantity * volumeRatio;
    }
    
    void executeSlice(int timeIndex) {
        double qty = getSliceQuantity(timeIndex);
        // 根据当前市场深度调整价格
        double price = getAdjustedPrice(qty);
        sendLimitOrder(price, qty);
    }
}

注意:VWAP 依赖历史数据。如果今天市场出现异常事件(比如突发新闻),历史成交量分布可能完全失效。我曾经在某个币种上吃过这个亏——那天成交量分布完全变了,VWAP 执行效果很差。

27.3.2 VWAP vs TWAP 对比

维度 TWAP VWAP
拆分依据 时间均匀 成交量分布
市场影响 中等 较小
实现复杂度
适用场景 流动性好、波动小 流动性一般、有规律

27.4 三种订单类型的知识体系

下面这张图,是我自己整理的知识结构。你可以看到三种订单类型在整个交易系统中的位置和关系。

高级订单类型知识体系 条件订单 TWAP VWAP 止损单 (Stop Loss) 止盈单 (Take Profit) 时间均匀拆分 固定时间片执行 成交量分布拆分 历史数据驱动 共同目标:降低市场冲击,隐藏交易意图 实现层:订单管理引擎 + 风控模块 + 行情接口 (限价单/市价单生成、滑点控制、重试机制)

27.5 实战中的选择建议

这三种订单类型,在实际做市商系统中怎么选?我个人的经验是这样的:

  • 风控场景:用条件订单。止损止盈是底线,必须优先保障。
  • 大单执行:用 TWAP 或 VWAP。如果品种流动性好,TWAP 就够了;如果流动性一般,VWAP 更优。
  • 混合使用:我见过最成熟的系统,是把条件订单和算法订单结合起来。比如:TWAP 执行过程中,如果价格跌破止损线,立即触发止损单。

一个小技巧:在开发这些订单类型时,建议先实现一个「模拟模式」。在模拟模式下,订单不会真的发到交易所,而是记录执行路径和成交价格。这样你可以回测策略,避免真金白银踩坑。

好了,这一章的内容就到这里。三种订单类型各有适用场景,关键是根据你的交易品种和市场环境来选。下一章我们会聊更高级的订单路由策略,到时候再细说。


交易系统化学习资料 微信Strategy888888