问题
看到一些股票数据或者数字货币的市场交易深度数据, 不同的价位, 交易的数量不同. 因为买价和卖价精度问题, 这就导致了市场深度可以非常深, 如下图所示:
这是一个火币网数字货币市场交易深度的示例图, 在页面上能看到100个深度, 实际在Rest API请求数据的时候,返回的市场深度可以是150个. 当然, 有些官网也可以返回深度合并的数据. 所以我在遇到这个问题的时候, 走了一点弯路, 实现了这个小的算法问题.
需求
对于盘口数据,买单向下合并,卖单向上合并. 同时, 合并的时候就遇到了几个问题需要解决.
- 合并的精度问题
- 相同深度订单数量计算
算法
我找到了API文档中的ask,bid数据作为样本.
1 2 3 4 5 6 7 8
| "bids": [ [3.7721, 344.86],// [price, quote volume] [3.7709, 46.66] ], "asks": [ [3.7745, 15.44], [3.7746, 70.52] ]
|
在数据样本中, bids是一个二维数组, 第一列是该深度的价格, 第二列是该深度的订单数量.
首先解决第一个问题, 如何解决合并深度问题:
比如卖单
1 2 3 4 5 6
| [3.1225, 7], [3.1229, 1], [3.1231, 3], [3.1232, 5], [3.1233, 2], [3.1234, 1]
|
对于上面的数据, 合并最后一位价格精度, 那深度数据是如何呢? 应该是这样的:
如果合并最后两位呢? 应该如下:
可以看到算法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
public float getCeilByLastNumber(float number, int precision) { if (precision < 0) { return number; } int numberLengthAfterPoint = 0; float tempNum = 0; if (number > 0) { tempNum = number + 1; } else { tempNum = number - 1; } String numStr = tempNum + ""; String[] numStrArray = numStr.split("\\."); numberLengthAfterPoint = numStrArray[1].length(); if (numberLengthAfterPoint >= precision) { return getCeilNumberWithPrecision(number, numberLengthAfterPoint - precision + 1); } else { return number; } }
public float getCeilNumberWithPrecision(float number, int precision) { return (float) (Math.ceil(number * ((int) Math.pow(10, precision))) / (((int) Math.pow(10, precision)) * 1.0f)); }
|
同理, 对于向下合并也是类似的.