如何建立回测系统(二)
一个简单的回放市场实现
public class MarketPlace {
private Map<String, List<Order>> orderChannel;
private Map<String, Long> lastComplete;
public MarketPlace() {
orderChannel = new ConcurrentHashMap<>();
lastComplete = new ConcurrentHashMap<>();
}
public void order(Order order) {
List<Order> list = orderChannel.get(order.getTradeCode());
if (Objects.isNull(list)) {
list = new ArrayList<>();
orderChannel.put(order.getTradeCode(), list);
}
synchronized (list) {
List<Order> targetPriceOrder;
List<Order> sellOrder = list.stream()
.filter(order1 -> !order1.isComplete())
.filter(Order::sell)
.sorted(Comparator.comparing(Order::getPrice)
.thenComparing(Order::getTimestamp))
.collect(Collectors.toList());
List<Order> buyOrder = list.stream()
.filter(order1 -> !order1.isComplete())
.filter(order1 -> !order1.sell())
.sorted(Comparator.comparing(Order::getPrice, Comparator.reverseOrder())
.thenComparing(Order::getTimestamp))
.collect(Collectors.toList());
//进来的是买单
if (!order.sell()) {
if (!buyOrder.isEmpty() && buyOrder.get(0).getPrice() > order.getPrice()) {
list.add(order);
return;
}
//处理好后,是按照价格小,时间先排列
targetPriceOrder = sellOrder.stream()
//需要找到挂单中比当前订单要价低或者相等的
.filter(order1 -> order.getPrice() <= order1.getPrice())
.collect(Collectors.toList());
} else {
if (!sellOrder.isEmpty() && sellOrder.get(0).getPrice() < order.getPrice()) {
list.add(order);
return;
}
//进来的是卖单,找买单 , 卖单进来,先开始撮合最高价的买单
targetPriceOrder = buyOrder.stream()
//需要找到买单中比当前订单要价高的
.filter(order1 -> order.getPrice() <= order1.getPrice())
.collect(Collectors.toList());
//新入订单需要撮合的数量
}
//新入订单需要撮合的数量
long count = order.getRemainCount();
//连续竞价,买单进来,开始先撮合最低价的卖单
for (Order order1 : targetPriceOrder) {
count = count - order1.getRemainCount();
if (count < 0) {
//说明当前订单已经满足,order不需要进入队列排队,order1更新成交数,中断循环
order1.addCompleteCount(order1.getCount() - Math.abs(count));
order.addCompleteCount(order.getCount());
order.complete();
this.lastComplete.put(order.getTradeCode(), order.getPrice());
break;
} else if (count == 0) {
//说明订单恰好满足,中断循环,将order1添加移除队列
order.addCompleteCount(order.getCount());
order1.addCompleteCount(order1.getCount());
order1.complete();
order.complete();
this.lastComplete.put(order.getTradeCode(), order.getPrice());
} else {
//说明订单未满足,将order1添加移除队列,并继续循环
order1.complete();
order.addCompleteCount(order1.getRemainCount());
}
count = order.getRemainCount();
}
if (!order.isComplete()) {
list.add(order);
}
}
}
public Long getLastPrice(String security) {
return this.lastComplete.get(security);
}
性能分析
最高对单个标的物单线程,且订单越多,处理速度越慢
T = f(m*n)
可能的优化点
- 减少每次对全部订单进行筛选排序,分出买卖单
- 针对国内涨跌幅限制,对价格进行分级,每个价格中订单按照实践排序
- 尽可能用基础类型