> 文章列表 > coinex03 // level2数据展示

coinex03 // level2数据展示

coinex03 // level2数据展示

目录

1. 委托账本的设计

1.0 课程视频

1.1 数据库表设计

2. 构建数据处理方法

2.1 数据初始化方法

2.2 获取当前的交易的队列方法

2.3 添加 删除使用的迭代器方法

2.4 添加订单到队列的方法

2.5 取消订单 -> 使用迭代器

2.6  获取队列第一个数据

2.7 OrderBooks构造器方法-> 初始化时数据构造 实时使用时数据构造

3. 撮合引擎

3.0 课程视频


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) { // 之前在红黑树里面没有这个价格的keymergeOrder = 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(); // 初始化方法}

3. 撮合引擎

3.0 课程视频

https://www.bilibili.com/video/BV13v4y1A7qH?p=52&spm_id_from=pageDriver&vd_source=ff8b7f852278821525f11666b36f180a


0. 课程视频

https://www.bilibili.com/video/BV13v4y1A7qH/?p=45&spm_id_from=pageDriver&vd_source=ff8b7f852278821525f11666b36f180a

1. 实体类DepthsVo 选出属性 解耦

import org.example.domain.DepthItemVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;@Data
@ApiModel(value = "深度盘口数据")
public class DepthsVo {/* 委托买单*/@ApiModelProperty(value = "委托买单")private List<DepthItemVo> bids = Collections.emptyList() ;/* 委托卖单*/@ApiModelProperty(value = "委托卖单")private List<DepthItemVo> asks = Collections.emptyList() ;/* 当前成交价(GCN)*/@ApiModelProperty(value = "当前成交价GCN")private BigDecimal price = BigDecimal.ZERO;/* 当前成交价对应CNY价格*/@ApiModelProperty(value = "当前成交价CNY")private BigDecimal cnyPrice =  BigDecimal.ZERO;
}

2. 前端确定 请求url

 http://127.0.0.1/exchange/markets/depth/BTCGCN/DEFAULT

3. DepthItemVo 

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.math.BigDecimal;@ApiModel("明细")
@NoArgsConstructor
@AllArgsConstructor
@Data
public class DepthItemVo implements Comparable<DepthItemVo> {/* 价格*/@ApiModelProperty(value = "价格")private BigDecimal price = BigDecimal.ZERO;;/* 数量*/@ApiModelProperty(value = "数量")private BigDecimal volume = BigDecimal.ZERO;@Overridepublic int compareTo(DepthItemVo o) {return this.price.compareTo(o.getPrice());}
}

4. controller ->MarketController

public R<DepthsVo> findDeptVosSymbol(@PathVariable("symbol") String symbol, String dept) { // @PathVariable("symbol") 路径里的值// 交易市场Market market = marketService.getMarkerBySymbol(symbol);DepthsVo depthsVo = new DepthsVo();depthsVo.setCnyPrice(market.getOpenPrice()); // CNY的价格depthsVo.setPrice(market.getOpenPrice()); // GCN的价格Map<String, List<DepthItemVo>> depthMap = orderBooksFeignClient.querySymbolDepth(symbol);if (!CollectionUtils.isEmpty(depthMap)) {depthsVo.setAsks(depthMap.get("asks"));depthsVo.setBids(depthMap.get("bids"));}return R.ok(depthsVo);}