""" Bollinger Bands 单元测试 Author: 张飞 翼德 Date: 2026-05-31 """ import math from bollinger import calc_bollinger def test_basic(): """基本功能测试""" prices = [float(10 + i) for i in range(25)] upper, middle, lower = calc_bollinger(prices, period=5) assert len(upper) == 21 # 25 - 5 + 1 assert len(middle) == 21 assert len(lower) == 21 def test_sma_correctness(): """验证 middle 等于 SMA""" prices = [10.0, 11.0, 12.0, 13.0, 14.0] upper, middle, lower = calc_bollinger(prices, period=3) # SMA of [10,11,12] = 11.0 assert math.isclose(middle[0], 11.0) # SMA of [11,12,13] = 12.0 assert math.isclose(middle[1], 12.0) # SMA of [12,13,14] = 13.0 assert math.isclose(middle[2], 13.0) def test_upper_lower_symmetry(): """验证上下轨关于中轨对称""" prices = [float(44 + i * 0.5 + (i % 3) * 0.2) for i in range(30)] upper, middle, lower = calc_bollinger(prices, period=10) for u, m, l in zip(upper, middle, lower): assert math.isclose(u - m, m - l, rel_tol=1e-9) def test_upper_gt_middle_gt_lower(): """上轨 > 中轨 > 下轨""" prices = [10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0] upper, middle, lower = calc_bollinger(prices, period=5) for u, m, l in zip(upper, middle, lower): assert u > m > l def test_num_std_zero(): """num_std=0 → 三条线重合""" prices = [10.0, 11.0, 12.0, 13.0, 14.0] upper, middle, lower = calc_bollinger(prices, period=3, num_std=0.0) for u, m, l in zip(upper, middle, lower): assert math.isclose(u, m) assert math.isclose(m, l) def test_insufficient_data(): """数据不足 → 空列表""" prices = [10.0, 11.0, 12.0] upper, middle, lower = calc_bollinger(prices, period=5) assert upper == [] and middle == [] and lower == [] def test_period_invalid(): """period <= 0""" prices = [10.0, 11.0, 12.0] upper, middle, lower = calc_bollinger(prices, period=0) assert upper == [] and middle == [] and lower == [] upper, middle, lower = calc_bollinger(prices, period=-1) assert upper == [] and middle == [] and lower == [] def test_empty_input(): """空输入""" upper, middle, lower = calc_bollinger([], period=5) assert upper == [] and middle == [] and lower == [] if __name__ == "__main__": test_basic() test_sma_correctness() test_upper_lower_symmetry() test_upper_gt_middle_gt_lower() test_num_std_zero() test_insufficient_data() test_period_invalid() test_empty_input() print("所有测试通过 ✅")