C#基于ConcurrentDictionary如何实现显示最近3个高位与3个低位价格
基于ConcurrentDictionary的多档位高低价获取方案
现有实现的局限
你当前写的紧邻高位价获取逻辑如下,全程只跟踪了一个最小tick差值,也就是只能拿到离当前价最近的那1个高位档位,没法存下多档位的排序结果,自然取不到第2、第3层的高位价:
foreach (var eachPrice in Prices.Values) { if (eachPrice.Location > 1000) { double itop = (eachPrice.Location - 1000) / 0.25; if (itop < ticksCeiling) { ticksCeiling = itop; priceCeiling = eachPrice.Location; } } }
实现方案
不用循环多次去逐层找每个档位,单次遍历就能把所有高低档位按离基准价的远近理清楚,直接按顺位取就行:
- 所有比当前基准价高的档位,按「和基准价的tick距离」从小到大排序,排完的列表第0位就是紧邻高位(对应目标值1001),第1位是第2个高位(1002),第2位是第3个高位(1003)
- 所有比当前基准价低的档位,按「和基准价的tick距离」从小到大排序,排完的列表第0位就是紧邻低位(999),第1位是第2个低位(998),第2位是第3个低位(997)
ConcurrentDictionary本身的遍历是安全快照,不会因为盘口实时更新价格导致遍历报错,匹配当前的存储结构
参考实现代码
// 当前盘口基准价 const decimal basePrice = 1000; // 最小价格跳动步长 const decimal priceStep = 0.25; // 遍历过程中分别收集高低档位的距离、对应价格 var highPriceRanks = new List<(double tickDistance, decimal price)>(); var lowPriceRanks = new List<(double tickDistance, decimal price)>(); foreach (var eachPrice in Prices.Values) { // 计算当前档位和基准价的绝对差值、对应tick数 var priceDiff = Math.Abs(eachPrice.Location - basePrice); var tickDist = priceDiff / (double)priceStep; if (eachPrice.Location > basePrice) { highPriceRanks.Add((tickDist, eachPrice.Location)); } else if (eachPrice.Location < basePrice) { lowPriceRanks.Add((tickDist, eachPrice.Location)); } } // 按离基准价的距离从小到大排序,排序后直接按下标取对应顺位的档位即可 highPriceRanks = highPriceRanks.OrderBy(x => x.tickDistance).ToList(); lowPriceRanks = lowPriceRanks.OrderBy(x => x.tickDistance).ToList();
低延迟优化建议
如果是高频交易场景下盘口档位特别多,完全没必要把所有档位都存下来排序。只需要在遍历的时候维护一个最多3个元素的有序列表,遇到比当前列表内距离更近的档位就插入到对应位置,同时把列表里距离最远的那个值淘汰,整个遍历过程的时间复杂度是O(n),比全量排序的延迟低很多,完全满足实盘要求。
内容的提问来源于stack exchange,提问作者XK8ER
相关产品推荐
相关产品推荐

