""" Strategy consistency tests """ import pytest from datetime import date from sqlalchemy.orm import Session from app.strategies.composite.multi_factor import MultiFactorStrategy from app.strategies.composite.magic_formula import MagicFormulaStrategy from app.strategies.composite.super_quality import SuperQualityStrategy from app.strategies.factors.momentum import MomentumStrategy from app.strategies.factors.f_score import FScoreStrategy from app.strategies.factors.value import ValueStrategy from app.strategies.factors.quality import QualityStrategy from app.strategies.factors.all_value import AllValueStrategy @pytest.mark.unit class TestStrategyInterface: """Test strategy interface implementation""" def test_multi_factor_strategy_interface(self): """Test MultiFactorStrategy implements BaseStrategy""" strategy = MultiFactorStrategy(config={"count": 20}) assert hasattr(strategy, "select_stocks") assert hasattr(strategy, "get_prices") assert strategy.name == "multi_factor" def test_magic_formula_strategy_interface(self): """Test MagicFormulaStrategy implements BaseStrategy""" strategy = MagicFormulaStrategy(config={"count": 20}) assert hasattr(strategy, "select_stocks") assert hasattr(strategy, "get_prices") assert strategy.name == "magic_formula" def test_super_quality_strategy_interface(self): """Test SuperQualityStrategy implements BaseStrategy""" strategy = SuperQualityStrategy(config={"count": 20}) assert hasattr(strategy, "select_stocks") assert hasattr(strategy, "get_prices") assert strategy.name == "super_quality" def test_momentum_strategy_interface(self): """Test MomentumStrategy implements BaseStrategy""" strategy = MomentumStrategy(config={"count": 20}) assert hasattr(strategy, "select_stocks") assert hasattr(strategy, "get_prices") assert strategy.name == "momentum" def test_f_score_strategy_interface(self): """Test FScoreStrategy implements BaseStrategy""" strategy = FScoreStrategy(config={"count": 20}) assert hasattr(strategy, "select_stocks") assert hasattr(strategy, "get_prices") assert strategy.name == "f_score" def test_value_strategy_interface(self): """Test ValueStrategy implements BaseStrategy""" strategy = ValueStrategy(config={"count": 20}) assert hasattr(strategy, "select_stocks") assert hasattr(strategy, "get_prices") assert strategy.name == "value" def test_quality_strategy_interface(self): """Test QualityStrategy implements BaseStrategy""" strategy = QualityStrategy(config={"count": 20}) assert hasattr(strategy, "select_stocks") assert hasattr(strategy, "get_prices") assert strategy.name == "quality" def test_all_value_strategy_interface(self): """Test AllValueStrategy implements BaseStrategy""" strategy = AllValueStrategy(config={"count": 20}) assert hasattr(strategy, "select_stocks") assert hasattr(strategy, "get_prices") assert strategy.name == "all_value" @pytest.mark.integration @pytest.mark.slow class TestStrategyExecution: """Test strategy execution with sample data""" def test_multi_factor_select_stocks( self, db_session: Session, sample_assets, sample_price_data ): """Test MultiFactorStrategy stock selection""" strategy = MultiFactorStrategy(config={"count": 3}) rebal_date = date(2023, 1, 15) # Note: May fail if insufficient data, that's expected try: selected_stocks = strategy.select_stocks(rebal_date, db_session) # Should return list of tickers assert isinstance(selected_stocks, list) assert len(selected_stocks) <= 3 for ticker in selected_stocks: assert isinstance(ticker, str) assert len(ticker) == 6 except Exception as e: # Insufficient data is acceptable for test pytest.skip(f"Insufficient data for strategy execution: {e}") def test_momentum_select_stocks( self, db_session: Session, sample_assets, sample_price_data ): """Test MomentumStrategy stock selection""" strategy = MomentumStrategy(config={"count": 3}) rebal_date = date(2023, 1, 15) try: selected_stocks = strategy.select_stocks(rebal_date, db_session) assert isinstance(selected_stocks, list) assert len(selected_stocks) <= 3 except Exception as e: pytest.skip(f"Insufficient data for strategy execution: {e}") def test_value_select_stocks( self, db_session: Session, sample_assets, sample_price_data ): """Test ValueStrategy stock selection""" strategy = ValueStrategy(config={"count": 3}) rebal_date = date(2023, 1, 15) try: selected_stocks = strategy.select_stocks(rebal_date, db_session) assert isinstance(selected_stocks, list) assert len(selected_stocks) <= 3 for ticker in selected_stocks: assert isinstance(ticker, str) assert len(ticker) == 6 except Exception as e: pytest.skip(f"Insufficient data for strategy execution: {e}") def test_quality_select_stocks( self, db_session: Session, sample_assets, sample_price_data ): """Test QualityStrategy stock selection""" strategy = QualityStrategy(config={"count": 3}) rebal_date = date(2023, 1, 15) try: selected_stocks = strategy.select_stocks(rebal_date, db_session) assert isinstance(selected_stocks, list) assert len(selected_stocks) <= 3 for ticker in selected_stocks: assert isinstance(ticker, str) assert len(ticker) == 6 except Exception as e: pytest.skip(f"Insufficient data for strategy execution: {e}") def test_all_value_select_stocks( self, db_session: Session, sample_assets, sample_price_data ): """Test AllValueStrategy stock selection""" strategy = AllValueStrategy(config={"count": 3}) rebal_date = date(2023, 1, 15) try: selected_stocks = strategy.select_stocks(rebal_date, db_session) assert isinstance(selected_stocks, list) assert len(selected_stocks) <= 3 for ticker in selected_stocks: assert isinstance(ticker, str) assert len(ticker) == 6 except Exception as e: pytest.skip(f"Insufficient data for strategy execution: {e}") def test_strategy_get_prices( self, db_session: Session, sample_assets, sample_price_data ): """Test strategy price retrieval""" strategy = MultiFactorStrategy(config={"count": 3}) tickers = ["005930", "000660", "035420"] price_date = date(2023, 1, 15) prices = strategy.get_prices(tickers, price_date, db_session) # Should return dict of prices assert isinstance(prices, dict) # May not have all prices if data is incomplete for ticker, price in prices.items(): assert ticker in tickers assert price > 0 @pytest.mark.integration class TestStrategyConfiguration: """Test strategy configuration handling""" def test_strategy_default_config(self): """Test strategy with default configuration""" strategy = MultiFactorStrategy(config={}) # Should use default count assert "count" in strategy.config or hasattr(strategy, "count") def test_strategy_custom_count(self): """Test strategy with custom count""" strategy = MultiFactorStrategy(config={"count": 50}) assert strategy.config["count"] == 50 def test_strategy_invalid_config(self): """Test strategy with invalid configuration""" # Should handle gracefully or raise appropriate error try: strategy = MultiFactorStrategy(config={"count": -1}) # If it doesn't raise, it should handle gracefully assert True except ValueError: # Expected for negative count assert True