1. 委托账本的设计
1.0 课程视频
https://www.bilibili.com/video/BV13v4y1A7qH?p=51&spm_id_from=pageDriver&vd_source=ff8b7f852278821525f11666b36f180a
1.1 数据库表设计
1. model-> OrderBooks // 不同价格的数据库表
2. model-> MergeOrder // 相同价格的不同时间的数据库表
3. 枚举类的使用
2. 构建数据处理方法
2.1 数据初始化方法
public void initialize() {
log.info("init CoinTrader for symbol {}", symbol);
// 载入比较器
buyLimitPrice = new TreeMap<>(Comparator.reverseOrder()); //价格从大到小 Comparator 比较器
sellLimitPrice = new TreeMap<>(Comparator.naturalOrder()); // 价格从小到大
buyTradePlate = new TradePlate(symbol, OrderDirection.BUY);
sellTradePlate = new TradePlate(symbol, OrderDirection.SELL);
dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
2.2 获取当前的交易的队列方法
public TreeMap<BigDecimal, MergeOrder> getCurrentLimitPrices(OrderDirection direction) {
return direction == OrderDirection.BUY ? buyLimitPrice : sellLimitPrice;
}
2.3 添加 删除使用的迭代器方法
public Iterator<Map.Entry<BigDecimal, MergeOrder>> getCurrentLimitPriceIterator(OrderDirection direction) { // 之后 删除 添加 操作使用的
return getCurrentLimitPrices(direction).entrySet().iterator();
}
2.4 添加订单到队列的方法
// 原理:横向mergeOrder数据库表, 通过价格不同 判断是否存在mergeOrder 不存在就添加mergerOrder 再添加数据, 存在就直接在里面添加数据
public void addOrder(Order order) {
TreeMap<BigDecimal, MergeOrder> currentLimitPrices = getCurrentLimitPrices(order.getOrderDirection());
MergeOrder mergeOrder = currentLimitPrices.get(order.getPrice());
//
if (mergeOrder == null) { // 之前在红黑树里面没有这个价格的key
mergeOrder = new MergeOrder();
currentLimitPrices.put(order.getPrice(), mergeOrder);
}
//
mergeOrder.add(order);
// 将新的订单添加到盘口里面
if(order.getOrderDirection()==OrderDirection.BUY){
buyTradePlate.add(order);
}else{
sellTradePlate.add(order);
}
}
2.5 取消订单 -> 使用迭代器
// 原理: 取消订单 并判断 取消后 mergeOrder表中这个价格 是否还有其他订单,有则删取消的订单,无 则删除此价格的mergeOrder
public void cancelOrder(Order order) {
TreeMap<BigDecimal, MergeOrder> currentLimitPrices = getCurrentLimitPrices(order.getOrderDirection());
MergeOrder mergeOrder = currentLimitPrices.get(order);
if (mergeOrder == null) {
return;
}
Iterator<Order> iterator = mergeOrder.iterator();
while (iterator.hasNext()) {
Order next = iterator.next();
// 找到之前的我们的订单记录
if (next.getOrderId().equals(order.getOrderId())) {
iterator.remove(); // 使用迭代器
}
}
int size = mergeOrder.size(); // 删除之前,我们看合并订单的大小
if (size == 0) { // 若我们的红黑树里面的合并订单的数据为空,我们摘除
currentLimitPrices.remove(order.getPrice());
}
if(order.getOrderDirection()==OrderDirection.BUY){
buyTradePlate.remove(order);
}else{
sellTradePlate.remove(order);
}
}
2.6 获取队列第一个数据
public Map.Entry<BigDecimal, MergeOrder> getBestSuitOrder(OrderDirection orderDirection) {
return getCurrentLimitPrices(orderDirection).firstEntry();
}
2.7 OrderBooks构造器方法-> 初始化时数据构造 实时使用时数据构造
public OrderBooks(String symbol) {
this(symbol, 4, 4);
} // 小数点后4位
// 构造器
public OrderBooks(String symbol, int coinScale, int baseCoinScale) { // MatchEngineProperties 在这里面定义的方法类
this.symbol = symbol;
this.coinScale = coinScale; // 交易币种的精度
this.baseCoinScale = baseCoinScale; //基币的精度
this.initialize(); // 初始化方法
}
2.8 数据 交易对的加载器
// 配置类
@Data
@ConfigurationProperties(prefix = "spring.match")
public class MatchEngineProperties {
/**
* 交易对的信息
*/
private Map<String,CoinScale> symbols ; // CoinScale 精度
@Data
public static class CoinScale {
/**
* 交易币种的精度
*/
private int coinScale;
/**
* 基币的精度
*/
private int baseCoinScale;
}
}
@Bean("eventHandlers") // 事件处理器 -> 加载交易对
public EventHandler<OrderEvent>[] eventHandlers() {
Map<String, MatchEngineProperties.CoinScale> symbols = matchEngineProperties.getSymbols();
Set<Map.Entry<String, MatchEngineProperties.CoinScale>> entries = symbols.entrySet();
EventHandler<OrderEvent>[] eventHandlers = new EventHandler[symbols.size()];
int i = 0;
for (Map.Entry<String, MatchEngineProperties.CoinScale> entry : entries) {
String symbol = entry.getKey();
MatchEngineProperties.CoinScale value = entry.getValue();
OrderBooks orderBooks = null;
if (value != null) {
orderBooks = new OrderBooks(symbol, value.getCoinScale(), value.getBaseCoinScale());
} else {
orderBooks = new OrderBooks(symbol);
}
eventHandlers[i++] = new OrderEventHandler(orderBooks);
}
return eventHandlers;
}