Skip to content

Deep Analysis Integration Guide

Overview

This guide explains how the Python scoring engine, Jinja2 templates, and performance configuration work together to provide high-performance deep analysis in FinWiz. The integration demonstrates the AI Minimalism principle in practice.

Integration Architecture

Component Interaction Flow

Text Only
┌─────────────────────────────────────────────────────────────┐
│                    CrewAI Flow                              │
├─────────────────────────────────────────────────────────────┤
│  1. Data Collection Task (AI Agent)                        │
│     • Fetch market data, sentiment, technical indicators   │
│     • Validate ticker and gather comprehensive data        │
│     • Store structured data for Python processing          │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│              Python Scoring Engine                          │
├─────────────────────────────────────────────────────────────┤
│  2. DeepAnalysisScorer.analyze_and_export()                │
│     • Calculate composite score (40% fund + 30% tech + 30% risk) │
│     • Assign grade (A+ to F) and recommendation (BUY/HOLD/SELL) │
│     • Generate detailed rationale and preserve all data    │
│     • Complete in 10-30 seconds with 0 LLM calls          │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│            Jinja2 Template Rendering                       │
├─────────────────────────────────────────────────────────────┤
│  3. DeepAnalysisReportGenerator.generate_report()          │
│     • Render professional HTML from Python data            │
│     • French localization with responsive design           │
│     • Asset-specific sections and conditional formatting   │
│     • Complete in <100ms with no AI costs                  │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│              Performance Monitoring                         │
├─────────────────────────────────────────────────────────────┤
│  4. PerformanceConfigManager tracks metrics                │
│     • Execution time, LLM calls, cost estimates           │
│     • Optimization mode validation                         │
│     • Performance regression detection                     │
└─────────────────────────────────────────────────────────────┘

Step-by-Step Integration

Step 1: Data Collection (AI Agent)

The data collection task uses AI agents to gather comprehensive data:

Python
# In DeepAnalysisCrew
@task
def data_collection_task(self) -> Task:
    return Task(
        description="""
        Collect comprehensive data for {ticker} ({asset_class}).

        Required data:
        - Current price and historical data
        - Fundamental metrics (ROE, debt, growth)
        - Technical indicators (RSI, MACD, moving averages)
        - Risk metrics (volatility, beta, drawdown)
        - Sentiment analysis and news data

        Store all data in structured format for Python processing.
        """,
        agent=self.data_collector(),
        expected_output="Comprehensive data dictionary with all metrics",
        async_execution=True  # Can run in parallel
    )

Data Structure Output:

Python
collected_data = {
    # Price data
    "current_price": 150.0,
    "moving_avg_50": 145.0,
    "moving_avg_200": 140.0,

    # Fundamental data (asset-specific)
    "roe": 0.25,              # Stock: Return on Equity
    "debt_to_equity": 0.3,    # Stock: Debt ratio
    "revenue_growth": 0.15,   # Stock: Growth rate
    "expense_ratio": 0.0015,  # ETF: Expense ratio
    "market_cap": 1e11,       # Crypto: Market cap

    # Technical indicators
    "rsi": 55.0,
    "macd": 0.05,
    "macd_signal": 0.03,

    # Risk metrics
    "volatility": 0.18,
    "max_drawdown": -0.15,
    "beta": 1.1,

    # Sentiment data
    "sentiment_score": 0.65,
    "trending_topics": ["earnings", "growth"],
    "article_count": 25,

    # Metadata
    "collection_timestamp": "2025-01-25T10:30:00Z",
    "data_sources": ["Yahoo Finance", "Alpha Vantage"]
}

Step 2: Python Scoring (Deterministic)

The Python scoring engine processes the collected data:

Python
# In DeepAnalysisCrew
@task
def python_scoring_task(self) -> Task:
    return Task(
        description="""
        Use Python scoring engine for deterministic analysis of {ticker}.

        Process:
        1. Receive collected_data from data_collection_task
        2. Call DeepAnalysisScorer.analyze_and_export()
        3. Calculate composite score using mathematical formulas
        4. Assign grade and generate recommendation
        5. Create comprehensive crew export with all data preserved

        NO AI REASONING - Pure Python calculations only.
        Performance target: Complete in <30 seconds with 0 LLM calls.
        """,
        agent=self.python_scorer(),
        expected_output="DeepAnalysisResult with scores and crew export dict",
        output_pydantic=DeepAnalysisResult,
        async_execution=False  # Final task must be synchronous
    )

Python Scoring Implementation:

Python
from finwiz.scoring.deep_analysis_scorer import DeepAnalysisScorer

def execute_python_scoring(collected_data: Dict[str, Any]) -> tuple[DeepAnalysisResult, Dict[str, Any]]:
    """Execute Python scoring pipeline."""

    # Initialize scorer
    scorer = DeepAnalysisScorer()

    # Extract parameters
    ticker = collected_data.get("ticker", "UNKNOWN")
    asset_class = collected_data.get("asset_class", "stock")
    session_id = collected_data.get("session_id", "default")

    # Execute complete analysis pipeline
    result, crew_export = scorer.analyze_and_export(
        ticker=ticker,
        asset_class=asset_class,
        collected_data=collected_data,
        session_id=session_id
    )

    return result, crew_export

Step 3: HTML Report Generation (Template-Based)

Generate professional HTML reports using Jinja2 templates:

Python
from finwiz.reporting.deep_analysis_report_generator import DeepAnalysisReportGenerator

def generate_html_report(result: DeepAnalysisResult, detailed_analysis: Dict[str, Any]) -> str:
    """Generate HTML report from Python scoring results."""

    # Initialize report generator
    generator = DeepAnalysisReportGenerator()

    # Prepare output path
    output_path = f"output/reports/{result.session_id}/deep_analysis/{result.ticker}_report.html"

    # Generate HTML report
    html_path = generator.generate_report(
        result=result,
        detailed_analysis=detailed_analysis,
        output_path=output_path
    )

    return html_path

Template Data Structure:

Python
template_data = {
    # From DeepAnalysisResult
    "ticker": result.ticker,
    "asset_class": result.asset_class,
    "composite_score": result.composite_score,
    "grade": result.grade,
    "recommendation": result.recommendation,
    "confidence": result.confidence,
    "rationale": result.rationale,

    # Component scores
    "fundamental_score": result.fundamental_score,
    "technical_score": result.technical_score,
    "risk_score": result.risk_score,

    # Component details
    "fundamental_details": result.fundamental_details,
    "technical_details": result.technical_details,
    "risk_details": result.risk_details,

    # From detailed_analysis
    "data_sources": detailed_analysis.get("data_sources", []),
    "analysis_date": detailed_analysis.get("analysis_timestamp"),
    "session_id": detailed_analysis.get("session_id"),

    # File paths
    "report_html_path": output_path,
    "report_json_path": output_path.replace(".html", ".json")
}

Step 4: Performance Monitoring

Track and validate performance throughout the process:

Python
from finwiz.utils.performance_config import get_performance_config_manager
from finwiz.utils.performance_monitor import PerformanceMonitor

def monitor_deep_analysis_performance(ticker: str, asset_class: str):
    """Monitor deep analysis performance."""

    # Get configuration
    config_manager = get_performance_config_manager()
    monitor = PerformanceMonitor()

    # Track analysis
    with monitor.track_analysis(ticker, asset_class) as tracker:

        # Step 1: Data Collection (AI - measured)
        start_time = time.time()
        collected_data = execute_data_collection(ticker, asset_class)
        data_collection_time = time.time() - start_time
        tracker.record_phase("data_collection", data_collection_time)

        # Step 2: Python Scoring (Deterministic - measured)
        start_time = time.time()
        result, crew_export = execute_python_scoring(collected_data)
        scoring_time = time.time() - start_time
        tracker.record_phase("python_scoring", scoring_time)
        tracker.record_llm_call(0)  # Python scoring = 0 LLM calls
        tracker.record_cost(0.0)    # Python scoring = $0 cost

        # Step 3: HTML Generation (Template - measured)
        start_time = time.time()
        html_path = generate_html_report(result, crew_export["detailed_analysis"])
        template_time = time.time() - start_time
        tracker.record_phase("html_generation", template_time)

        # Validate performance targets
        total_time = data_collection_time + scoring_time + template_time

        if config_manager.is_maximum_speed_mode():
            assert total_time < 30.0, f"Maximum speed mode exceeded 30s: {total_time:.2f}s"
            assert tracker.llm_call_count == 0, f"Maximum speed mode had LLM calls: {tracker.llm_call_count}"
            assert tracker.total_cost == 0.0, f"Maximum speed mode had costs: ${tracker.total_cost:.2f}"

        # Log performance achievement
        logger.info(
            f"🚀 DEEP ANALYSIS PERFORMANCE for {ticker}:\n"
            f"  ✅ Total time: {total_time:.2f}s\n"
            f"  ✅ Data collection: {data_collection_time:.2f}s\n"
            f"  ✅ Python scoring: {scoring_time:.2f}s (0 LLM calls, $0 cost)\n"
            f"  ✅ HTML generation: {template_time:.2f}s\n"
            f"  ✅ Mode: {config_manager.get_mode().value}\n"
            f"  ✅ Grade: {result.grade}, Recommendation: {result.recommendation}"
        )

Configuration Integration

Environment-Based Configuration

The integration automatically adapts based on environment variables:

Python
# Maximum Speed Mode (Production)
def configure_maximum_speed_mode():
    """Configure for maximum speed and cost efficiency."""
    os.environ.update({
        "RISK_ASSESSMENT_USE_MINI": "true",
        "USE_MINIMAL_RISK_TOOLS": "true",
        "DEEP_ANALYSIS_AI_SUMMARY": "false",
        "DEEP_ANALYSIS_BATCH_SIZE": "5"
    })

    # Expected performance
    return {
        "execution_time": "10-30 seconds",
        "llm_calls": 0,
        "cost_per_ticker": 0.0,
        "components": ["Python scoring", "Jinja2 templates", "gpt-4o-mini for data collection"]
    }

# Balanced Mode (Development)
def configure_balanced_mode():
    """Configure for balanced performance and quality."""
    os.environ.update({
        "RISK_ASSESSMENT_USE_MINI": "true",
        "USE_MINIMAL_RISK_TOOLS": "true",
        "DEEP_ANALYSIS_AI_SUMMARY": "true",  # Optional AI summary
        "DEEP_ANALYSIS_BATCH_SIZE": "3"
    })

    return {
        "execution_time": "15-40 seconds",
        "llm_calls": 1,  # For optional AI summary
        "cost_per_ticker": 0.01,
        "components": ["Python scoring", "Optional AI summary", "Jinja2 templates"]
    }

Dynamic Mode Detection

The system automatically detects and configures the appropriate mode:

Python
from finwiz.utils.performance_config import PerformanceConfigManager

def setup_deep_analysis_integration():
    """Setup deep analysis integration based on configuration."""

    # Initialize configuration manager
    config_manager = PerformanceConfigManager()

    # Configure components based on mode
    if config_manager.is_maximum_speed_mode():
        # Configure for maximum performance
        crew_config = {
            "reasoning": False,
            "planning": False,
            "allow_delegation": False,
            "llm": "gpt-4o-mini"
        }

        # Use minimal tool set
        tools = get_minimal_deep_analysis_tools()

        # Disable AI summary
        enable_ai_summary = False

    elif config_manager.is_balanced_mode():
        # Configure for balanced approach
        crew_config = {
            "reasoning": True,
            "planning": False,
            "allow_delegation": False,
            "llm": "gpt-4o-mini"
        }

        # Use standard tool set
        tools = get_standard_deep_analysis_tools()

        # Enable optional AI summary
        enable_ai_summary = True

    else:  # Baseline mode
        # Configure for full AI analysis
        crew_config = {
            "reasoning": True,
            "planning": True,
            "allow_delegation": True,
            "llm": "gpt-4"
        }

        # Use full tool set
        tools = get_full_deep_analysis_tools()

        # Enable AI summary
        enable_ai_summary = True

    return crew_config, tools, enable_ai_summary

Error Handling Integration

Graceful Degradation

The integration includes comprehensive error handling:

Python
def execute_deep_analysis_with_fallback(ticker: str, asset_class: str) -> tuple[DeepAnalysisResult, str]:
    """Execute deep analysis with graceful fallback handling."""

    try:
        # Step 1: Try data collection
        collected_data = execute_data_collection(ticker, asset_class)

    except Exception as e:
        logger.warning(f"Data collection failed for {ticker}: {e}")
        # Use minimal data for Python scoring
        collected_data = create_minimal_data_structure(ticker, asset_class)

    try:
        # Step 2: Python scoring (should always work)
        result, crew_export = execute_python_scoring(collected_data)

    except Exception as e:
        logger.error(f"Python scoring failed for {ticker}: {e}")
        # Create error result
        result = create_error_result(ticker, asset_class, str(e))
        crew_export = create_error_export(result)

    try:
        # Step 3: HTML generation (should always work)
        html_path = generate_html_report(result, crew_export.get("detailed_analysis", {}))

    except Exception as e:
        logger.error(f"HTML generation failed for {ticker}: {e}")
        # Create minimal HTML report
        html_path = create_minimal_html_report(result)

    return result, html_path

def create_minimal_data_structure(ticker: str, asset_class: str) -> Dict[str, Any]:
    """Create minimal data structure for fallback scenarios."""
    return {
        "ticker": ticker,
        "asset_class": asset_class,
        "current_price": 100.0,  # Default values
        "rsi": 50.0,
        "volatility": 0.20,
        "beta": 1.0,
        "collection_timestamp": datetime.now().isoformat(),
        "data_sources": ["Fallback Data"],
        "error_mode": True
    }

Validation and Recovery

Python
def validate_integration_health() -> Dict[str, bool]:
    """Validate that all integration components are healthy."""

    health_status = {}

    # Test Python scoring engine
    try:
        scorer = DeepAnalysisScorer()
        test_result = scorer.calculate_composite_score("TEST", "stock", {
            "roe": 0.15, "debt_to_equity": 0.5, "rsi": 50.0, "volatility": 0.20
        })
        health_status["python_scoring"] = True
    except Exception as e:
        logger.error(f"Python scoring health check failed: {e}")
        health_status["python_scoring"] = False

    # Test template rendering
    try:
        generator = DeepAnalysisReportGenerator()
        test_html = generator.render_test_template()
        health_status["template_rendering"] = True
    except Exception as e:
        logger.error(f"Template rendering health check failed: {e}")
        health_status["template_rendering"] = False

    # Test performance configuration
    try:
        config_manager = PerformanceConfigManager()
        config = config_manager.get_config()
        health_status["performance_config"] = True
    except Exception as e:
        logger.error(f"Performance config health check failed: {e}")
        health_status["performance_config"] = False

    return health_status

Testing Integration

End-to-End Testing

Test the complete integration pipeline:

Python
def test_complete_deep_analysis_integration():
    """Test complete deep analysis integration pipeline."""

    # Setup test data
    ticker = "AAPL"
    asset_class = "stock"
    test_data = create_comprehensive_test_data(ticker, asset_class)

    # Execute complete pipeline
    start_time = time.time()

    # Step 1: Python scoring
    scorer = DeepAnalysisScorer()
    result, crew_export = scorer.analyze_and_export(ticker, asset_class, test_data)

    # Step 2: HTML generation
    generator = DeepAnalysisReportGenerator()
    html_path = generator.generate_report(
        result, crew_export["detailed_analysis"], "/tmp/test_report.html"
    )

    total_time = time.time() - start_time

    # Validate results
    assert result.ticker == ticker
    assert result.asset_class == asset_class
    assert 0.0 <= result.composite_score <= 1.0
    assert result.grade in ["A+", "A", "B", "C", "D", "F"]
    assert result.recommendation in ["BUY", "HOLD", "SELL"]
    assert len(result.rationale) >= 50

    # Validate HTML output
    assert Path(html_path).exists()
    with open(html_path, 'r') as f:
        html_content = f.read()
    assert ticker in html_content
    assert result.grade in html_content
    assert result.recommendation in html_content

    # Validate performance
    assert total_time < 1.0, f"Integration too slow: {total_time:.2f}s"

    # Validate data preservation
    detailed = crew_export["detailed_analysis"]
    assert "raw_metrics" in detailed
    assert "sentiment_data" in detailed
    assert "technical_indicators" in detailed
    assert "fundamental_data" in detailed
    assert "calculation_results" in detailed

Performance Regression Testing

Python
def test_performance_regression():
    """Test that performance doesn't regress over time."""

    # Baseline performance targets
    performance_targets = {
        OptimizationMode.MAXIMUM_SPEED: {
            "max_time": 30.0,
            "max_llm_calls": 0,
            "max_cost": 0.0
        },
        OptimizationMode.BALANCED: {
            "max_time": 40.0,
            "max_llm_calls": 1,
            "max_cost": 0.01
        }
    }

    for mode, targets in performance_targets.items():
        # Configure mode
        configure_mode(mode)

        # Execute analysis
        monitor = PerformanceMonitor()
        with monitor.track_analysis("TEST", "stock") as tracker:
            result, html_path = execute_complete_analysis("TEST", "stock")

        # Validate performance targets
        assert tracker.total_time <= targets["max_time"]
        assert tracker.llm_call_count <= targets["max_llm_calls"]
        assert tracker.total_cost <= targets["max_cost"]

        logger.info(f"Performance test passed for {mode.value}")

Best Practices

Integration Guidelines

  1. Separation of Concerns:

  2. AI agents handle data collection and interpretation

  3. Python handles deterministic calculations
  4. Templates handle presentation and formatting

  5. Error Handling:

  6. Each component has independent error handling

  7. Graceful degradation with fallback options
  8. Comprehensive logging for debugging

  9. Performance Monitoring:

  10. Track metrics at each integration point

  11. Validate performance targets continuously
  12. Alert on performance regression

  13. Configuration Management:

  14. Use environment variables for configuration

  15. Automatic mode detection and optimization
  16. Clear documentation of configuration options

  17. Testing Strategy:

  18. Unit tests for each component
  19. Integration tests for complete pipeline
  20. Performance regression tests
  21. Error scenario testing

Deployment Considerations

  1. Production Setup:

  2. Use Maximum Speed Mode for production

  3. Monitor performance metrics continuously
  4. Set up alerts for failures or performance issues
  5. Cache frequently accessed data

  6. Development Setup:

  7. Use Balanced Mode for development

  8. Enable detailed logging for debugging
  9. Test all optimization modes
  10. Validate against baseline AI results

  11. Scaling Considerations:

  12. Batch processing for large portfolios
  13. Resource monitoring and management
  14. Load balancing for high-volume processing
  15. Database optimization for data storage

Conclusion

The deep analysis integration demonstrates how AI Minimalism principles can be applied to create a high-performance, cost-effective, and maintainable system. By combining:

  • AI agents for data collection and interpretation
  • Python algorithms for deterministic calculations
  • Jinja2 templates for professional report generation
  • Performance monitoring for continuous optimization

FinWiz achieves 10-20x performance improvements and 100% cost reduction while maintaining analysis quality and providing full reproducibility.

This integration serves as a model for other financial analysis systems seeking to optimize performance while preserving analytical depth and accuracy.


Version: 1.0 Last Updated: 2025-01-25 Related Documentation: