| | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.util.List; |
| | | import java.util.Random; |
| | | |
| | | |
| | | public abstract class AbstractGetDataJob implements Runnable { |
| | |
| | | |
| | | public abstract String getName(); |
| | | |
| | | // 在类中定义静态Random实例 |
| | | private static final Random random = new Random(); |
| | | |
| | | public abstract void realtimeHandle(String symbols); |
| | | |
| | |
| | | AdjustmentValue delayValue = AdjustmentValueCache.getDelayValue().get(symbol); |
| | | |
| | | if (delayValue != null) { |
| | | // 延时几次 |
| | | int frequency = (int) Arith.div(Arith.mul(delayValue.getSecond(), 1000.0D), this.interval); |
| | | //延时几次 缓存frequency |
| | | Integer frequency = AdjustmentValueCache.getFrequency().get(symbol); |
| | | if (frequency == null) { //首次计算 缓存 |
| | | frequency = (int) Arith.div(Arith.mul(delayValue.getSecond(), 1000.0D), this.interval); |
| | | AdjustmentValueCache.getFrequency().put(symbol, frequency); |
| | | } |
| | | |
| | | if (frequency <= 1) { |
| | | if (currentValue == null) { |
| | |
| | | itemService.saveOrUpdate(item); |
| | | } |
| | | AdjustmentValueCache.getDelayValue().remove(symbol); |
| | | AdjustmentValueCache.getFrequency().remove(symbol); |
| | | } else { |
| | | // 本次调整值 |
| | | /*// 本次调整值 |
| | | BigDecimal currentValue_frequency = delayValue.getValue().divide(new BigDecimal(frequency), decimal, RoundingMode.HALF_UP); |
| | | |
| | | if (currentValue == null) { |
| | |
| | | if (!item.getAdjustmentValue().equals(AdjustmentValueCache.getCurrentValue().get(symbol))) { |
| | | item.setAdjustmentValue(AdjustmentValueCache.getCurrentValue().get(symbol)); |
| | | itemService.saveOrUpdate(item); |
| | | }*/ |
| | | //计算延时加大精度 |
| | | Integer delayDecimal = 10; |
| | | // 保存原始总值用于计算随机分配 |
| | | BigDecimal totalValue = delayValue.getValue(); |
| | | // 计算已分配次数(从缓存中获取) |
| | | Integer allocatedCount = AdjustmentValueCache.getAllocatedCount().get(symbol); |
| | | if (allocatedCount == null) { |
| | | allocatedCount = 0; |
| | | // 首次分配时保存总值到缓存,用于后续计算 |
| | | AdjustmentValueCache.getTotalValue().put(symbol, totalValue); |
| | | } else { |
| | | //不是首次 |
| | | totalValue = AdjustmentValueCache.getTotalValue().get(symbol); |
| | | } |
| | | |
| | | // ########## 新增:判断调整方向(正向/负向)########## |
| | | boolean isPositiveAdjustment = totalValue.compareTo(BigDecimal.ZERO) > 0; // 正向调整(>0) |
| | | boolean isNegativeAdjustment = totalValue.compareTo(BigDecimal.ZERO) < 0; // 负向调整(<0) |
| | | |
| | | BigDecimal currentValue_frequency; |
| | | // 计算剩余分配次数 |
| | | int remainingAllocations = frequency - allocatedCount; |
| | | |
| | | if (remainingAllocations > 1) { |
| | | BigDecimal average = totalValue.divide(new BigDecimal(frequency), delayDecimal, RoundingMode.HALF_UP); |
| | | BigDecimal randomFactor; |
| | | |
| | | // 根据调整方向动态调整负因子概率 |
| | | double negativeProbability = isNegativeAdjustment ? 0.6 : 0.3; |
| | | if (Math.random() <= negativeProbability) { |
| | | // 负因子:范围 [-0.5, 0) |
| | | double randomNeg = -0.5 + Math.random() * 0.5; // 简化计算:max - min = 0 - (-0.5) = 0.5 |
| | | randomFactor = new BigDecimal(randomNeg).setScale(delayDecimal, RoundingMode.HALF_UP); |
| | | } else { |
| | | // 正因子:范围 [0.3, 1.7) |
| | | double randomPos = 0.3 + Math.random() * 1.4; // 简化计算:max - min = 1.7 - 0.3 = 1.4 |
| | | randomFactor = new BigDecimal(randomPos).setScale(delayDecimal, RoundingMode.HALF_UP); |
| | | } |
| | | |
| | | currentValue_frequency = average.multiply(randomFactor).setScale(delayDecimal, RoundingMode.HALF_UP); |
| | | |
| | | // 核心修改1:根据调整方向动态约束累计值 |
| | | BigDecimal currentAccumulated = AdjustmentValueCache.getAccumulatedValue().getOrDefault(symbol, BigDecimal.ZERO); |
| | | BigDecimal tempAccumulated = currentAccumulated.add(currentValue_frequency); |
| | | if (isPositiveAdjustment) { |
| | | // 正向调整:累计值不能为负 |
| | | if (tempAccumulated.compareTo(BigDecimal.ZERO) < 0) { |
| | | currentValue_frequency = BigDecimal.ONE.divide(new BigDecimal("10").pow(delayDecimal), delayDecimal, RoundingMode.HALF_UP); |
| | | } |
| | | } else if (isNegativeAdjustment) { |
| | | // 负向调整:累计值不能小于目标值(避免过度减值) |
| | | if (tempAccumulated.compareTo(totalValue) < 0) { |
| | | currentValue_frequency = totalValue.subtract(currentAccumulated).divide(new BigDecimal(2), delayDecimal, RoundingMode.HALF_UP); |
| | | } |
| | | } |
| | | |
| | | //剩余的待分配值 |
| | | BigDecimal remainingValue = totalValue.subtract(currentAccumulated); |
| | | //本次分配后剩余的待分配值 |
| | | BigDecimal tempDelayValue = remainingValue.subtract(currentValue_frequency); |
| | | |
| | | // 提取公共变量(剩余值的80%) |
| | | BigDecimal remaining80Percent = remainingValue.multiply(new BigDecimal("0.8")) |
| | | .setScale(delayDecimal, RoundingMode.HALF_UP); |
| | | |
| | | // 统一判断“是否需要修正剩余值” |
| | | boolean needFixRemaining = (isPositiveAdjustment && tempDelayValue.compareTo(BigDecimal.ZERO) < 0) |
| | | || (isNegativeAdjustment && tempDelayValue.compareTo(totalValue) > 0); |
| | | if (needFixRemaining) { |
| | | // 直接使用公共变量,避免重复计算 |
| | | currentValue_frequency = remaining80Percent; |
| | | } |
| | | |
| | | // 直接使用公共变量作为maxAllowed,无需重复计算 |
| | | if ((isPositiveAdjustment && currentValue_frequency.compareTo(remaining80Percent) > 0) |
| | | || (isNegativeAdjustment && currentValue_frequency.compareTo(remaining80Percent) < 0)) { |
| | | currentValue_frequency = remaining80Percent; |
| | | } |
| | | |
| | | } else { |
| | | // 最后一次分配兜底(支持负值) |
| | | BigDecimal accumulated = AdjustmentValueCache.getAccumulatedValue().getOrDefault(symbol, BigDecimal.ZERO); |
| | | currentValue_frequency = totalValue.subtract(accumulated).setScale(delayDecimal, RoundingMode.HALF_UP); |
| | | |
| | | // 正向调整:最后一次分配值不能为负;负向调整:不能为正(无重复,无需优化) |
| | | if (isPositiveAdjustment && currentValue_frequency.compareTo(BigDecimal.ZERO) < 0) { |
| | | currentValue_frequency = BigDecimal.ZERO.setScale(delayDecimal, RoundingMode.HALF_UP); |
| | | } else if (isNegativeAdjustment && currentValue_frequency.compareTo(BigDecimal.ZERO) > 0) { |
| | | currentValue_frequency = BigDecimal.ZERO.setScale(delayDecimal, RoundingMode.HALF_UP); |
| | | } |
| | | } |
| | | |
| | | |
| | | // 更新累计值 |
| | | BigDecimal newAccumulated = AdjustmentValueCache.getAccumulatedValue().getOrDefault(symbol, BigDecimal.ZERO) |
| | | .add(currentValue_frequency); |
| | | AdjustmentValueCache.getAccumulatedValue().put(symbol, newAccumulated); |
| | | // 更新分配次数 |
| | | AdjustmentValueCache.getAllocatedCount().put(symbol, allocatedCount + 1); |
| | | |
| | | // 更新当前值 |
| | | if (currentValue == null) { |
| | | AdjustmentValueCache.getCurrentValue().put(symbol, currentValue_frequency.setScale(decimal, RoundingMode.HALF_UP)); |
| | | } else { |
| | | AdjustmentValueCache.getCurrentValue().put(symbol, |
| | | currentValue.add(currentValue_frequency).setScale(decimal, RoundingMode.HALF_UP)); |
| | | } |
| | | |
| | | // 更新延迟值 |
| | | delayValue.setValue(delayValue.getValue().subtract(currentValue_frequency).setScale(decimal, RoundingMode.HALF_UP)); |
| | | delayValue.setSecond(Arith.sub(delayValue.getSecond(), Arith.div(this.interval, 1000.0D))); |
| | | AdjustmentValueCache.getDelayValue().put(symbol, delayValue); |
| | | |
| | | // 如果是最后一次分配,清理缓存 |
| | | if (remainingAllocations <= 1) { |
| | | AdjustmentValueCache.getAllocatedCount().remove(symbol); |
| | | AdjustmentValueCache.getTotalValue().remove(symbol); |
| | | AdjustmentValueCache.getAccumulatedValue().remove(symbol); |
| | | AdjustmentValueCache.getFrequency().remove(symbol); |
| | | |
| | | AdjustmentValueCache.getDelayValue().remove(symbol); |
| | | } |
| | | |
| | | // 保存更新 |
| | | if (!item.getAdjustmentValue().equals(AdjustmentValueCache.getCurrentValue().get(symbol))) { |
| | | item.setAdjustmentValue(AdjustmentValueCache.getCurrentValue().get(symbol)); |
| | | itemService.saveOrUpdate(item); |
| | | } |
| | | } |
| | | } |