Files
2026-05-31 19:11:14 +08:00

90 lines
2.6 KiB
Python

"""
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("所有测试通过 ✅")