from __future__ import annotations from hypothesis import given, settings, strategies as st from app.services.recommendation_service import direction_analyzer, probability_estimator @settings(max_examples=100, deadline=None) @given( technical=st.floats(min_value=0, max_value=100), momentum=st.floats(min_value=0, max_value=100), fundamental=st.floats(min_value=0, max_value=100), sentiment=st.sampled_from(["bearish", "neutral", "bullish", None]), ) def test_property_confidence_bounds(technical, momentum, fundamental, sentiment): """Feature: intelligent-trade-recommendations, Property 3: Confidence Score Bounds.""" scores = { "technical": technical, "momentum": momentum, "fundamental": fundamental, } long_conf = direction_analyzer.calculate_confidence("long", scores, sentiment, conflicts=[]) short_conf = direction_analyzer.calculate_confidence("short", scores, sentiment, conflicts=[]) assert 0 <= long_conf <= 100 assert 0 <= short_conf <= 100 @settings(max_examples=100, deadline=None) @given( strength_low=st.floats(min_value=0, max_value=50), strength_high=st.floats(min_value=50, max_value=100), ) def test_property_strength_monotonic_probability(strength_low, strength_high): """Feature: intelligent-trade-recommendations, Property 11: S/R Strength Monotonicity.""" config = { "recommendation_signal_alignment_weight": 0.15, "recommendation_sr_strength_weight": 0.20, "recommendation_distance_penalty_factor": 0.10, } scores = {"technical": 65.0, "momentum": 65.0} base_target = { "classification": "Moderate", "distance_atr_multiple": 3.0, } low = probability_estimator.estimate_probability( {**base_target, "sr_strength": strength_low}, scores, "bullish", "long", config, ) high = probability_estimator.estimate_probability( {**base_target, "sr_strength": strength_high}, scores, "bullish", "long", config, ) assert high >= low @settings(max_examples=100, deadline=None) @given( near_distance=st.floats(min_value=1.0, max_value=3.0), far_distance=st.floats(min_value=3.1, max_value=8.0), ) def test_property_distance_probability_relationship(near_distance, far_distance): """Feature: intelligent-trade-recommendations, Property 12: Distance Probability Relationship.""" config = { "recommendation_signal_alignment_weight": 0.15, "recommendation_sr_strength_weight": 0.20, "recommendation_distance_penalty_factor": 0.10, } scores = {"technical": 65.0, "momentum": 65.0} near_prob = probability_estimator.estimate_probability( { "classification": "Conservative", "sr_strength": 60, "distance_atr_multiple": near_distance, }, scores, "bullish", "long", config, ) far_prob = probability_estimator.estimate_probability( { "classification": "Aggressive", "sr_strength": 60, "distance_atr_multiple": far_distance, }, scores, "bullish", "long", config, ) assert near_prob >= far_prob