最难的部份是委托单
如某股票当前股价是6.00元, 用户下了5.90的买入单
系统就要按监控周期不停的监控这张委托单和股票的价格变化, 直到股票的价格<=5.90
在多用户多委托单的情况下, 解决起来还是比较麻烦的, 这也是整个系统的核心所在.
因为委托单是自动成交的, 所以必须把股票的实时行情本地化, 这将加大开销.
自己举个例子算一下数据:
上深所有A股 = 2000支
用户数 = 100人
每人每天下单数量 = 10单
监控是否可以成交周期 = 5秒
这样每5秒就要执行一次, 以下代码我直接在这里现写的, 未测试...
$stocks = $db->get_result("SELECT code,price FROM last_price ORDER BY code ASC;"); // 这里会有严重的问题
//$order_codes = $db->get_col('SELECT DISTINCT code FROM orders;');
$buy_orders = $db->get_result("SELECT code,price FROM orders WHERE type = 'buy';");
$sell_orders = $db->get_result("SELECT code,price FROM orders WHERE type = 'sell';");
foreach ($stocks AS $stock) { // 遍历所有股票 2000支
foreach ($buy_orders AS $border) { // 遍历个股买入委托 1000单 = 100人*10单
if ($stock->code != $border->code || $stock->price >= $border->price)
continue;
// 开始买入委托成交, 更新订单成交时间, 移出order表
}
foreach ($sell_orders AS $sorder) { // 遍历个股卖出委托 1000单 = 100人*10单
if ($stock->code != $sorder->code || $stock->price <= $border->price)
continue;
// 开始卖出委托成交, 更新订单成交时间, 移出order表
}
}
上面注了, "这里会有严重的问题", last_price表是所有股票的最新行情, 那么它的变化可能就是1秒以内的事
而监控5秒才执行一次, 这里会错过价格变化.
其实上面的可以简化为
$buy_orders = $db->get_result("SELECT o.code,o.price FROM orders o JOIN last_price l ON o.code = l.code WHERE o.type = 'buy' AND o.price <= l.price;"); // 可成交的买入委托
$sell_orders = $db->get_result("SELECT o.code,o.price FROM orders o JOIN last_price l ON o.code = l.code WHERE o.type = 'sell' AND o.price >= l.price;"); // 可成交的卖出委托
总结办法有2个:
1. 在更新每支股票股价的时候, 查找每支股票相应可以成交的委托单
可以实时最快成交. 但这样消耗可能会很大, 每1秒都要重复做的事: 更新2000支股票的价格, 还要每支股票查找一次可以成交的订单, 还要其他成交后一系列的操作.
2. 定时遍历股票
这就是我上面说的方法, 但这样会错过价格变化, 取价格的方法不对. 不能取单一时间的价格, 而是要取时间段的最小(大)价格.这样就不能从最终价格表来取, 而要从历史价格表取.