Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 57 additions & 1 deletion test.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class YFinanceCompatibilityTest(TestCase):
_stock = wrap(
df=yf.download(
"002032.SZ",
auto_adjust=False, # raw prices
auto_adjust=False, # <- raw prices
actions=True, # keep dividends & splits separate
period="max",
)
Expand Down Expand Up @@ -314,6 +314,62 @@ def test_z_kdj(self):
assert_that(row["kdjd"], near_to(55.555))
assert_that(row["kdjj"], near_to(88.888))

@staticmethod
def test_kdj_flat_candles():
"""Regression test for issue #185.

When high == low for every bar (perfectly flat candles), the
RSV denominator is zero. _divide() must return 0.0 rather than
raising ZeroDivisionError or producing NaN/inf, and the
downstream K, D, J values must all be finite numbers.
"""
import numpy as np
data = pd.DataFrame({
'open': [10.0] * 20,
'high': [10.0] * 20,
'low': [10.0] * 20,
'close': [10.0] * 20,
'volume': [1000] * 20,
})
stock = wrap(data)
kdjk = stock['kdjk']
kdjd = stock['kdjd']
kdjj = stock['kdjj']
for series, name in ((kdjk, 'kdjk'), (kdjd, 'kdjd'), (kdjj, 'kdjj')):
for i, val in enumerate(series.values):
assert_that(
np.isfinite(val),
equal_to(True),
f"{name}[{i}] is not finite: {val}",
)

@staticmethod
def test_vr_neutral_days():
"""Regression test for issue #115.

When all volume days are neutral (change == 0), both avs and bvs
are 0, so the VR formula should return 100.0
(half_cvs / half_cvs * 100 == 100) rather than 0 or NaN.
"""
import numpy as np
data = pd.DataFrame({
'open': [10.0] * 30,
'high': [10.5] * 30,
'low': [9.5] * 30,
'close': [10.0] * 30, # no change => all neutral days
'volume': [1000] * 30,
})
stock = wrap(data)
vr = stock['vr']
for i, val in enumerate(vr.values):
assert_that(
np.isfinite(val),
equal_to(True),
f"vr[{i}] is not finite: {val}",
)
# all neutral: VR should be 100
assert_that(val, near_to(100.0))

def test_column_cross(self):
stock = self.get_stock_30days()
cross = stock["kdjk_3_x_kdjd_3"]
Expand Down
Loading