folio / tests /test_cash_detection.py
dystomachina's picture
Initial commit for Folio project
ce4bc73
from unittest.mock import patch
import pytest
from src.folio.cash_detection import is_cash_or_short_term
@pytest.fixture
def mock_get_beta():
"""Mock get_beta function to return controlled values for testing."""
with patch("src.folio.utils.get_beta") as mock:
yield mock
def test_low_beta_instruments(mock_get_beta):
"""Test that instruments with low beta are identified as cash-like."""
# Test with pre-calculated beta
assert is_cash_or_short_term("SPAXX", beta=0.01) # Money market fund
assert is_cash_or_short_term("BIL", beta=0.001) # Treasury bill ETF
assert not is_cash_or_short_term(
"TLT", beta=0.15
) # Long-term treasury (higher beta)
# Test with calculated beta
mock_get_beta.return_value = 0.05
assert is_cash_or_short_term("SHY") # Short-term treasury ETF
mock_get_beta.return_value = 0.2
assert not is_cash_or_short_term("AAPL") # Regular stock
def test_regular_stocks(mock_get_beta):
"""Test that regular stocks are not identified as cash-like."""
mock_get_beta.return_value = 1.2
assert not is_cash_or_short_term("AAPL")
assert not is_cash_or_short_term("GOOGL")
def test_beta_calculation_error(mock_get_beta):
"""Test that beta calculation errors are handled gracefully."""
# Our new implementation catches exceptions and returns False
mock_get_beta.side_effect = RuntimeError("Failed to fetch data")
assert not is_cash_or_short_term("INVALID")
mock_get_beta.side_effect = ValueError("Invalid beta calculation")
assert not is_cash_or_short_term("INVALID")
mock_get_beta.side_effect = KeyError("Missing required data")
assert not is_cash_or_short_term("INVALID")
def test_beta_threshold_edge_cases():
"""Test edge cases around the beta threshold."""
assert is_cash_or_short_term("TEST1", beta=0.099) # Just under threshold
assert not is_cash_or_short_term("TEST2", beta=0.1) # At threshold
assert not is_cash_or_short_term("TEST3", beta=0.101) # Just over threshold
assert is_cash_or_short_term("TEST4", beta=-0.099) # Negative but under threshold
assert not is_cash_or_short_term(
"TEST5", beta=-0.101
) # Negative and over threshold
def test_pattern_based_detection(mock_get_beta):
"""Test pattern-based detection of money market funds."""
# Set up mock to return a default beta value
mock_get_beta.return_value = 0.5 # Non-cash-like beta
# Test XX pattern in symbol
assert is_cash_or_short_term("SPAXX")
assert is_cash_or_short_term("FMPXX")
assert is_cash_or_short_term("ABCXX")
# Test money market terms in description
assert is_cash_or_short_term("XYZ", description="MONEY MARKET FUND")
assert is_cash_or_short_term("ABC", description="Cash Reserves")
assert is_cash_or_short_term("DEF", description="Treasury Fund")
# Test that non-matching patterns return False
assert not is_cash_or_short_term("ABCDE")
assert not is_cash_or_short_term("XYZ", description="Growth Fund")