证券交易系统是金融市场上能够提供的最有流动性,效率最高的交易场所。
和传统的商品交易不同的是,证券交易系统提供的买卖标的物是标准的数字化资产,如USD、股票、BTC等,它们的特点是数字计价,可分割买卖。
证券交易系统通过买卖双方各自的报价,按照价格优先、时间优先的顺序,对买卖双方进行撮合,实现每秒成千上万的交易量,可以为市场提供高度的流动性和价格发现机制。
本文讨论如何设计并实现一个证券交易系统。
我们以一个美元计价的数字货币交易所为例,实现一个比特币的BTC/USD交易系统。
一个完整的证券交易系统是由用户系统、账户系统、订单系统、撮合系统以及清算系统等子系统构成的。各个子系统相互配合,完成证券报价交易。
1 ┌───────────┐ 2 ┌───────────┐ 7 ┌───────────┐
Request ────▶│ User │────▶│ Account │◀────│ Clearing │
└───────────┘ └───────────┘ └───────────┘
3│ ▲
▼ │
┌───────────┐ │
│ Order │ 6│
└───────────┘ │
4│ │
▼ │
┌───────────┐ 5 ┌───────────┐
│ Sequence │────▶│ Match │
└───────────┘ └───────────┘
│
▼
┌───────────┐
Market ◀────────────────────────────────────────│ Quotation │
└───────────┘
当一个请求进入交易系统后,首先由用户系统(User)识别用户身份,然后由账户系统(Account)对用户资产进行冻结,买入冻结USD,卖出冻结BTC,冻结如果成功,订单就进入定序系统(Sequence)。
为什么需要设计一个定序系统?因为交易系统的所有订单是一个有序队列。不同的用户在同一时刻下单,也必须由定序系统确定先后顺序。
经过定序的订单被送入撮合引擎(Match)。
撮合引擎是交易系统的核心。撮合引擎本质上就是维护一个买卖盘列表,然后按价格优先原则对订单进行撮合,能够成交的就输出成交结果,不能成交的放入买卖盘。这里注意没有时间优先原则,因为经过定序的订单队列已经是一个时间优先的队列了。
当撮合引擎输出了成交结果后,该成交记录由清算系统(Clearing)进行清算。清算的工作就是把买单冻结的USD扣掉,并加上买入所得的BTC,同时,把卖单冻结的BTC扣掉,并加上卖出所得的USD。根据taker/maker的费率,向买卖双方收取手续费。
清算系统完成清算后,更新订单状态,再通知用户,用户就可以查询到买卖的成交情况。
在撮合引擎输出成交记录给清算系统的同时,它还把去除用户和订单相关信息的成交记录输出给行情系统(Quotation),由行情系统保存市场的成交价、成交量等信息,并输出实时价格、K线图等技术数据,以便公开市场查询。
经过这样的模块化设计,一个证券交易系统就具备了雏型。
下一步,我们就需要把这个交易系统用代码实现出来。
先定义入口函数:
/**
* A crypto exchange.
*
* @author liaoxuefeng
*/
public class CryptoExchangeApplication {
public static void main(String[] args) {
// TODO:
}
}
接下来,实现各个模块的功能,一个证券交易系统就成功地开发出来了!