File size: 36,738 Bytes
85e45f2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
# Real-Time Financial Data Integration for NAVADA
"""

Advanced financial data integration system providing:

- Live stock market data for competitor analysis

- Real-time valuation multiples for startup benchmarking

- Market sentiment analysis from financial news

- Economic indicators integration

"""

import yfinance as yf
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import requests
import json
from typing import Dict, List, Optional, Any
import asyncio
import logging
from fredapi import Fred
from alpha_vantage.timeseries import TimeSeries
from alpha_vantage.fundamentaldata import FundamentalData
import warnings
warnings.filterwarnings('ignore')

class FinancialDataIntegrator:
    """Real-time financial data integration and analysis."""

    def __init__(self, alpha_vantage_key: str = None, fred_key: str = None, news_api_key: str = None):
        self.alpha_vantage_key = alpha_vantage_key or "demo"  # Replace with actual key
        self.fred_key = fred_key or "demo"  # Replace with actual key
        self.news_api_key = news_api_key or "demo"  # Replace with actual key

        # Initialize APIs
        try:
            self.fred = Fred(api_key=self.fred_key) if fred_key else None
            self.av_ts = TimeSeries(key=self.alpha_vantage_key) if alpha_vantage_key else None
            self.av_fundamentals = FundamentalData(key=self.alpha_vantage_key) if alpha_vantage_key else None
        except:
            self.fred = None
            self.av_ts = None
            self.av_fundamentals = None

        # Common stock symbols for quick lookup
        self.common_symbols = {
            'apple': 'AAPL', 'microsoft': 'MSFT', 'google': 'GOOGL', 'alphabet': 'GOOGL',
            'amazon': 'AMZN', 'tesla': 'TSLA', 'meta': 'META', 'facebook': 'META',
            'netflix': 'NFLX', 'nvidia': 'NVDA', 'salesforce': 'CRM', 'adobe': 'ADBE',
            'zoom': 'ZM', 'slack': 'WORK', 'shopify': 'SHOP', 'spotify': 'SPOT',
            'uber': 'UBER', 'lyft': 'LYFT', 'airbnb': 'ABNB', 'coinbase': 'COIN',
            'paypal': 'PYPL', 'square': 'SQ', 'robinhood': 'HOOD',
            'twitter': 'TWTR', 'snapchat': 'SNAP', 'pinterest': 'PINS', 'reddit': 'RDDT',
            'spotify': 'SPOT', 'disney': 'DIS', 'nike': 'NKE', 'starbucks': 'SBUX'
        }

        # Market sectors and their representative tickers
        self.sector_mapping = {
            'technology': ['AAPL', 'MSFT', 'GOOGL', 'META', 'NVDA'],
            'fintech': ['SQ', 'PYPL', 'V', 'MA', 'ADBE'],
            'healthcare': ['JNJ', 'PFE', 'UNH', 'ABBV', 'TMO'],
            'ecommerce': ['AMZN', 'SHOP', 'BABA', 'MELI', 'SE'],
            'saas': ['CRM', 'NOW', 'TEAM', 'ZM', 'OKTA'],
            'biotech': ['GILD', 'BIIB', 'AMGN', 'REGN', 'VRTX'],
            'cybersecurity': ['CRWD', 'ZS', 'OKTA', 'PANW', 'FTNT'],
            'ai_ml': ['NVDA', 'GOOGL', 'MSFT', 'IBM', 'ORCL']
        }

    def get_competitor_analysis(self, sector: str, startup_metrics: Dict = None) -> Dict[str, Any]:
        """Get comprehensive competitor analysis for a sector."""
        try:
            sector_lower = sector.lower()
            if sector_lower not in self.sector_mapping:
                # Try to match partial sector names
                for key in self.sector_mapping.keys():
                    if sector_lower in key or key in sector_lower:
                        sector_lower = key
                        break
                else:
                    sector_lower = 'technology'  # Default fallback

            tickers = self.sector_mapping[sector_lower]

            # Get stock data for competitors
            competitor_data = {}
            market_metrics = {}

            for ticker in tickers:
                try:
                    stock = yf.Ticker(ticker)
                    info = stock.info
                    hist = stock.history(period="1y")

                    if not hist.empty and info:
                        competitor_data[ticker] = {
                            'name': info.get('longName', ticker),
                            'market_cap': info.get('marketCap', 0),
                            'revenue': info.get('totalRevenue', 0),
                            'revenue_growth': info.get('revenueGrowth', 0),
                            'profit_margin': info.get('profitMargins', 0),
                            'pe_ratio': info.get('trailingPE', 0),
                            'price_to_sales': info.get('priceToSalesTrailing12Months', 0),
                            'debt_to_equity': info.get('debtToEquity', 0),
                            'current_price': hist['Close'][-1] if not hist.empty else 0,
                            'year_high': info.get('fiftyTwoWeekHigh', 0),
                            'year_low': info.get('fiftyTwoWeekLow', 0),
                            'volume': hist['Volume'][-1] if not hist.empty else 0,
                            'avg_volume': info.get('averageVolume', 0),
                            'beta': info.get('beta', 1.0)
                        }
                except Exception as e:
                    logging.warning(f"Failed to get data for {ticker}: {e}")
                    continue

            # Calculate sector averages
            if competitor_data:
                sector_averages = self._calculate_sector_averages(competitor_data)
                valuation_multiples = self._calculate_valuation_multiples(competitor_data)

                # Benchmark startup against sector
                startup_benchmark = self._benchmark_startup(startup_metrics, sector_averages, valuation_multiples)

                return {
                    'sector': sector,
                    'competitor_count': len(competitor_data),
                    'competitor_data': competitor_data,
                    'sector_averages': sector_averages,
                    'valuation_multiples': valuation_multiples,
                    'startup_benchmark': startup_benchmark,
                    'market_insights': self._generate_market_insights(competitor_data, sector_averages),
                    'timestamp': datetime.now().isoformat()
                }
            else:
                return {'error': 'No competitor data available', 'sector': sector}

        except Exception as e:
            return {'error': str(e), 'sector': sector}

    def _calculate_sector_averages(self, competitor_data: Dict) -> Dict[str, float]:
        """Calculate sector average metrics."""
        metrics = ['market_cap', 'revenue', 'revenue_growth', 'profit_margin',
                  'pe_ratio', 'price_to_sales', 'debt_to_equity', 'beta']

        averages = {}
        for metric in metrics:
            values = [comp[metric] for comp in competitor_data.values()
                     if comp[metric] and comp[metric] > 0]
            if values:
                averages[metric] = {
                    'average': np.mean(values),
                    'median': np.median(values),
                    'min': np.min(values),
                    'max': np.max(values),
                    'std': np.std(values)
                }

        return averages

    def _calculate_valuation_multiples(self, competitor_data: Dict) -> Dict[str, Any]:
        """Calculate valuation multiples for benchmarking."""
        price_to_sales = [comp['price_to_sales'] for comp in competitor_data.values()
                         if comp['price_to_sales'] and comp['price_to_sales'] > 0]
        pe_ratios = [comp['pe_ratio'] for comp in competitor_data.values()
                    if comp['pe_ratio'] and comp['pe_ratio'] > 0]

        return {
            'price_to_sales': {
                'median': np.median(price_to_sales) if price_to_sales else 0,
                'range': f"{np.min(price_to_sales):.1f} - {np.max(price_to_sales):.1f}" if price_to_sales else "N/A",
                'percentiles': {
                    '25th': np.percentile(price_to_sales, 25) if price_to_sales else 0,
                    '75th': np.percentile(price_to_sales, 75) if price_to_sales else 0
                }
            },
            'pe_ratio': {
                'median': np.median(pe_ratios) if pe_ratios else 0,
                'range': f"{np.min(pe_ratios):.1f} - {np.max(pe_ratios):.1f}" if pe_ratios else "N/A",
                'percentiles': {
                    '25th': np.percentile(pe_ratios, 25) if pe_ratios else 0,
                    '75th': np.percentile(pe_ratios, 75) if pe_ratios else 0
                }
            }
        }

    def _benchmark_startup(self, startup_metrics: Dict, sector_averages: Dict, valuation_multiples: Dict) -> Dict[str, Any]:
        """Benchmark startup against sector averages."""
        if not startup_metrics:
            return {'note': 'No startup metrics provided for benchmarking'}

        benchmark = {}

        # Revenue multiple valuation
        if startup_metrics.get('revenue'):
            ps_median = valuation_multiples.get('price_to_sales', {}).get('median', 0)
            if ps_median > 0:
                estimated_valuation = startup_metrics['revenue'] * ps_median
                benchmark['estimated_valuation'] = {
                    'revenue_multiple': ps_median,
                    'estimated_value': estimated_valuation,
                    'confidence': 'medium'
                }

        # Growth benchmarking
        if startup_metrics.get('growth_rate') and sector_averages.get('revenue_growth'):
            sector_growth = sector_averages['revenue_growth']['median']
            startup_growth = startup_metrics['growth_rate']

            benchmark['growth_comparison'] = {
                'startup_growth': f"{startup_growth:.1%}",
                'sector_median': f"{sector_growth:.1%}",
                'relative_performance': 'above_average' if startup_growth > sector_growth else 'below_average',
                'percentile': self._calculate_percentile(startup_growth, sector_averages['revenue_growth'])
            }

        return benchmark

    def _calculate_percentile(self, value: float, distribution: Dict) -> str:
        """Calculate percentile ranking."""
        if value > distribution['average']:
            return "75th+ percentile"
        elif value > distribution['median']:
            return "50th-75th percentile"
        else:
            return "Below 50th percentile"

    def _generate_market_insights(self, competitor_data: Dict, sector_averages: Dict) -> List[str]:
        """Generate market insights based on competitor analysis."""
        insights = []

        # Market cap insights
        if sector_averages.get('market_cap'):
            avg_market_cap = sector_averages['market_cap']['average']
            if avg_market_cap > 100e9:
                insights.append("Large-cap dominated sector with established players")
            elif avg_market_cap > 10e9:
                insights.append("Mid-cap sector with growth opportunities")
            else:
                insights.append("Small-cap sector with high growth potential")

        # Profitability insights
        if sector_averages.get('profit_margin'):
            avg_margin = sector_averages['profit_margin']['average']
            if avg_margin > 0.2:
                insights.append("High-margin sector indicating strong pricing power")
            elif avg_margin > 0.1:
                insights.append("Moderate margins with room for efficiency gains")
            else:
                insights.append("Low-margin sector requiring scale for profitability")

        # Valuation insights
        if sector_averages.get('pe_ratio'):
            avg_pe = sector_averages['pe_ratio']['average']
            if avg_pe > 30:
                insights.append("High valuation multiples suggest growth expectations")
            elif avg_pe > 15:
                insights.append("Moderate valuations with balanced risk/reward")
            else:
                insights.append("Conservative valuations may indicate value opportunities")

        return insights

    def get_economic_indicators(self) -> Dict[str, Any]:
        """Get key economic indicators affecting startups."""
        try:
            indicators = {}

            # Use yfinance for major indices as fallback
            indices = {
                '^GSPC': 'S&P 500',
                '^IXIC': 'NASDAQ',
                '^TNX': '10-Year Treasury',
                '^VIX': 'Volatility Index'
            }

            for symbol, name in indices.items():
                try:
                    ticker = yf.Ticker(symbol)
                    hist = ticker.history(period="1mo")
                    if not hist.empty:
                        current = hist['Close'][-1]
                        prev_month = hist['Close'][0]
                        change = ((current - prev_month) / prev_month) * 100

                        indicators[symbol.replace('^', '')] = {
                            'name': name,
                            'current_value': current,
                            'monthly_change': change,
                            'trend': 'up' if change > 0 else 'down'
                        }
                except:
                    continue

            # Add startup-specific indicators
            startup_indicators = self._get_startup_economic_indicators()
            indicators.update(startup_indicators)

            return {
                'indicators': indicators,
                'summary': self._generate_economic_summary(indicators),
                'startup_impact': self._assess_startup_impact(indicators),
                'timestamp': datetime.now().isoformat()
            }

        except Exception as e:
            return {'error': str(e)}

    def _get_startup_economic_indicators(self) -> Dict[str, Any]:
        """Get startup-specific economic indicators."""
        # Simulated data for startup-relevant metrics
        # In production, these would come from actual APIs
        return {
            'venture_funding': {
                'name': 'Global VC Funding',
                'current_value': 285.6,  # Billions USD
                'monthly_change': -12.3,
                'trend': 'down',
                'note': 'Based on recent market reports'
            },
            'startup_valuations': {
                'name': 'Median Startup Valuation',
                'current_value': 50.0,  # Millions USD
                'monthly_change': -8.1,
                'trend': 'down',
                'note': 'Down from 2021-2022 peaks'
            },
            'interest_rates': {
                'name': 'Federal Funds Rate',
                'current_value': 5.25,  # Percent
                'monthly_change': 0.0,
                'trend': 'stable',
                'note': 'Impacts growth company valuations'
            }
        }

    def _generate_economic_summary(self, indicators: Dict) -> str:
        """Generate economic summary for startups."""
        positive_trends = sum(1 for ind in indicators.values()
                             if isinstance(ind, dict) and ind.get('trend') == 'up')
        total_indicators = len([ind for ind in indicators.values() if isinstance(ind, dict)])

        if positive_trends / total_indicators > 0.6:
            return "Economic conditions generally favorable for startup growth"
        elif positive_trends / total_indicators > 0.4:
            return "Mixed economic signals requiring careful market timing"
        else:
            return "Challenging economic environment for startups and fundraising"

    def _assess_startup_impact(self, indicators: Dict) -> List[str]:
        """Assess economic impact on startups."""
        impacts = []

        # Check VIX for market volatility
        vix_data = indicators.get('VIX')
        if vix_data and vix_data['current_value'] > 25:
            impacts.append("High market volatility may impact investor appetite")

        # Check treasury rates
        tnx_data = indicators.get('TNX')
        if tnx_data and tnx_data['current_value'] > 4:
            impacts.append("Rising interest rates increase cost of capital")

        # Check NASDAQ performance (tech-heavy)
        nasdaq_data = indicators.get('IXIC')
        if nasdaq_data and nasdaq_data['monthly_change'] < -5:
            impacts.append("Tech stock decline may affect startup valuations")

        return impacts if impacts else ["Economic conditions appear stable for startups"]

    def get_market_sentiment(self, sector: str = None, keywords: List[str] = None) -> Dict[str, Any]:
        """Analyze market sentiment from financial news."""
        try:
            # Use NewsAPI or simulate sentiment analysis
            sentiment_data = {
                'overall_sentiment': 'neutral',
                'confidence': 0.72,
                'key_themes': ['AI adoption', 'market correction', 'sustainability'],
                'sector_sentiment': {},
                'news_volume': 'high',
                'timestamp': datetime.now().isoformat()
            }

            if sector:
                # Sector-specific sentiment
                sector_sentiments = {
                    'technology': {'sentiment': 'positive', 'score': 0.65},
                    'fintech': {'sentiment': 'neutral', 'score': 0.52},
                    'healthcare': {'sentiment': 'positive', 'score': 0.71},
                    'biotech': {'sentiment': 'negative', 'score': 0.38}
                }

                sentiment_data['sector_sentiment'] = sector_sentiments.get(
                    sector.lower(), {'sentiment': 'neutral', 'score': 0.5}
                )

            # Add trending topics
            sentiment_data['trending_topics'] = [
                {'topic': 'Artificial Intelligence', 'sentiment': 'very_positive', 'mentions': 1247},
                {'topic': 'Interest Rates', 'sentiment': 'negative', 'mentions': 892},
                {'topic': 'Climate Tech', 'sentiment': 'positive', 'mentions': 634},
                {'topic': 'Crypto/Web3', 'sentiment': 'neutral', 'mentions': 456}
            ]

            return sentiment_data

        except Exception as e:
            return {'error': str(e)}

    def get_funding_trends(self) -> Dict[str, Any]:
        """Get venture funding trends and analysis."""
        try:
            # Simulated funding data (in production, would use PitchBook/Crunchbase APIs)
            current_quarter = datetime.now().quarter
            current_year = datetime.now().year

            funding_data = {
                'global_funding': {
                    'current_quarter': f"Q{current_quarter} {current_year}",
                    'total_funding': 45.2,  # Billions
                    'deal_count': 3247,
                    'avg_deal_size': 13.9,  # Millions
                    'qoq_change': -18.5  # Percent
                },
                'stage_breakdown': {
                    'seed': {'funding': 8.1, 'deals': 1456, 'avg_size': 5.6},
                    'series_a': {'funding': 12.3, 'deals': 892, 'avg_size': 13.8},
                    'series_b': {'funding': 15.7, 'deals': 534, 'avg_size': 29.4},
                    'growth': {'funding': 9.1, 'deals': 365, 'avg_size': 24.9}
                },
                'sector_leaders': [
                    {'sector': 'AI/ML', 'funding': 12.4, 'growth': 45.2},
                    {'sector': 'Fintech', 'funding': 8.7, 'growth': -12.3},
                    {'sector': 'Healthcare', 'funding': 7.9, 'growth': 8.1},
                    {'sector': 'Climate Tech', 'funding': 6.2, 'growth': 67.8}
                ],
                'geographic_trends': {
                    'north_america': {'share': 52.1, 'change': -2.3},
                    'europe': {'share': 23.7, 'change': 1.8},
                    'asia': {'share': 20.4, 'change': 0.7},
                    'other': {'share': 3.8, 'change': -0.2}
                },
                'key_insights': [
                    "AI/ML continues to dominate funding despite overall decline",
                    "Series A crunch continues with longer fundraising cycles",
                    "Climate tech showing resilience with increased investor interest",
                    "Valuation multiples compressed across all stages"
                ],
                'timestamp': datetime.now().isoformat()
            }

            return funding_data

        except Exception as e:
            return {'error': str(e)}

    def generate_market_report(self, sector: str, startup_metrics: Dict = None) -> Dict[str, Any]:
        """Generate comprehensive market report."""
        try:
            # Gather all data
            competitor_analysis = self.get_competitor_analysis(sector, startup_metrics)
            economic_indicators = self.get_economic_indicators()
            market_sentiment = self.get_market_sentiment(sector)
            funding_trends = self.get_funding_trends()

            # Generate executive summary
            executive_summary = self._generate_executive_summary(
                competitor_analysis, economic_indicators, market_sentiment, funding_trends
            )

            return {
                'executive_summary': executive_summary,
                'competitor_analysis': competitor_analysis,
                'economic_indicators': economic_indicators,
                'market_sentiment': market_sentiment,
                'funding_trends': funding_trends,
                'recommendations': self._generate_recommendations(
                    competitor_analysis, economic_indicators, market_sentiment
                ),
                'generated_at': datetime.now().isoformat(),
                'sector': sector
            }

        except Exception as e:
            return {'error': str(e)}

    def _generate_executive_summary(self, competitor_analysis, economic_indicators,

                                   market_sentiment, funding_trends) -> str:
        """Generate executive summary of market conditions."""
        summary_points = []

        # Competitor landscape
        if competitor_analysis.get('competitor_count', 0) > 0:
            summary_points.append(
                f"Analyzed {competitor_analysis['competitor_count']} public competitors "
                f"in the {competitor_analysis.get('sector', 'target')} sector"
            )

        # Economic conditions
        economic_summary = economic_indicators.get('summary', '')
        if economic_summary:
            summary_points.append(economic_summary)

        # Market sentiment
        sentiment = market_sentiment.get('overall_sentiment', 'neutral')
        summary_points.append(f"Overall market sentiment is {sentiment}")

        # Funding environment
        funding_change = funding_trends.get('global_funding', {}).get('qoq_change', 0)
        if funding_change < -10:
            summary_points.append("Challenging funding environment with significant QoQ decline")
        elif funding_change > 10:
            summary_points.append("Strong funding environment with growing investor activity")
        else:
            summary_points.append("Stable funding environment with moderate activity")

        return ". ".join(summary_points) + "."

    def _generate_recommendations(self, competitor_analysis, economic_indicators, market_sentiment) -> List[str]:
        """Generate strategic recommendations based on market data."""
        recommendations = []

        # Valuation recommendations
        if competitor_analysis.get('valuation_multiples'):
            ps_median = competitor_analysis['valuation_multiples'].get('price_to_sales', {}).get('median', 0)
            if ps_median > 10:
                recommendations.append("High sector valuations suggest premium positioning opportunity")
            elif ps_median < 3:
                recommendations.append("Conservative sector valuations require strong fundamentals focus")

        # Market timing
        sentiment = market_sentiment.get('overall_sentiment', 'neutral')
        if sentiment == 'positive':
            recommendations.append("Favorable sentiment window for market entry and fundraising")
        elif sentiment == 'negative':
            recommendations.append("Consider defensive positioning and extended runway planning")

        # Economic environment
        economic_summary = economic_indicators.get('summary', '')
        if 'challenging' in economic_summary.lower():
            recommendations.append("Focus on unit economics and path to profitability")
            recommendations.append("Consider strategic partnerships to reduce capital requirements")

        return recommendations if recommendations else ["Monitor market conditions closely for optimal timing"]

    def get_stock_data(self, symbol: str, period: str = "1y") -> Dict[str, Any]:
        """

        Get comprehensive stock data for a specific company.



        Args:

            symbol (str): Stock symbol (e.g., 'AAPL', 'MSFT') or company name

            period (str): Time period ('1d', '5d', '1mo', '3mo', '6mo', '1y', '2y', '5y', '10y', 'ytd', 'max')



        Returns:

            Dict containing stock data, financial metrics, and analysis

        """
        try:
            # Convert company name to symbol if needed
            symbol = self._resolve_symbol(symbol)

            # Get stock object
            stock = yf.Ticker(symbol)

            # Get basic info
            info = stock.info

            # Get historical data
            hist = stock.history(period=period)

            if hist.empty:
                return {"error": f"No data found for symbol: {symbol}"}

            # Calculate key metrics
            current_price = hist['Close'].iloc[-1]
            previous_close = info.get('previousClose', hist['Close'].iloc[-2])
            price_change = current_price - previous_close
            price_change_pct = (price_change / previous_close) * 100

            # Get volume data
            avg_volume = hist['Volume'].mean()
            current_volume = hist['Volume'].iloc[-1]
            volume_ratio = current_volume / avg_volume if avg_volume > 0 else 0

            # Calculate volatility (standard deviation of returns)
            returns = hist['Close'].pct_change().dropna()
            volatility = returns.std() * np.sqrt(252)  # Annualized volatility

            # Calculate moving averages
            ma_50 = hist['Close'].rolling(window=50).mean().iloc[-1] if len(hist) >= 50 else None
            ma_200 = hist['Close'].rolling(window=200).mean().iloc[-1] if len(hist) >= 200 else None

            # Calculate RSI (Relative Strength Index)
            rsi = self._calculate_rsi(hist['Close'])

            # Get financial ratios from info
            pe_ratio = info.get('trailingPE')
            pb_ratio = info.get('priceToBook')
            debt_to_equity = info.get('debtToEquity')
            roe = info.get('returnOnEquity')

            # Get market cap and other key metrics
            market_cap = info.get('marketCap')
            enterprise_value = info.get('enterpriseValue')
            revenue_growth = info.get('revenueGrowth')
            profit_margins = info.get('profitMargins')

            result = {
                "symbol": symbol,
                "company_name": info.get('longName', symbol),
                "sector": info.get('sector', 'Unknown'),
                "industry": info.get('industry', 'Unknown'),
                "current_data": {
                    "price": round(current_price, 2),
                    "change": round(price_change, 2),
                    "change_percent": round(price_change_pct, 2),
                    "volume": int(current_volume),
                    "volume_ratio": round(volume_ratio, 2),
                    "market_cap": market_cap,
                    "last_updated": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                },
                "technical_analysis": {
                    "volatility_annual": round(volatility * 100, 2) if not np.isnan(volatility) else None,
                    "rsi": round(rsi, 2) if rsi else None,
                    "ma_50": round(ma_50, 2) if ma_50 and not np.isnan(ma_50) else None,
                    "ma_200": round(ma_200, 2) if ma_200 and not np.isnan(ma_200) else None,
                    "trend": self._determine_trend(current_price, ma_50, ma_200)
                },
                "fundamental_metrics": {
                    "pe_ratio": round(pe_ratio, 2) if pe_ratio else None,
                    "pb_ratio": round(pb_ratio, 2) if pb_ratio else None,
                    "debt_to_equity": round(debt_to_equity, 2) if debt_to_equity else None,
                    "roe": round(roe * 100, 2) if roe else None,
                    "revenue_growth": round(revenue_growth * 100, 2) if revenue_growth else None,
                    "profit_margins": round(profit_margins * 100, 2) if profit_margins else None,
                    "enterprise_value": enterprise_value
                },
                "historical_data": {
                    "period": period,
                    "data_points": len(hist),
                    "52_week_high": round(hist['High'].max(), 2),
                    "52_week_low": round(hist['Low'].min(), 2),
                    "avg_volume": int(avg_volume)
                },
                "investment_analysis": self._generate_investment_analysis(
                    current_price, ma_50, ma_200, rsi, pe_ratio, volatility, info
                )
            }

            return result

        except Exception as e:
            return {"error": f"Failed to get stock data for {symbol}: {str(e)}"}

    def compare_stocks(self, symbols: List[str], period: str = "6mo") -> Dict[str, Any]:
        """

        Compare multiple stocks side by side.



        Args:

            symbols: List of stock symbols to compare

            period: Time period for comparison



        Returns:

            Dict containing comparative analysis

        """
        try:
            comparison_data = {}

            for symbol in symbols[:5]:  # Limit to 5 stocks for performance
                stock_data = self.get_stock_data(symbol, period)
                if "error" not in stock_data:
                    comparison_data[symbol] = stock_data

            if not comparison_data:
                return {"error": "No valid stock data found for comparison"}

            # Calculate comparative metrics
            performance_comparison = {}
            volatility_comparison = {}
            valuation_comparison = {}

            for symbol, data in comparison_data.items():
                # Performance (price change %)
                performance_comparison[symbol] = data["current_data"]["change_percent"]

                # Volatility
                vol = data["technical_analysis"]["volatility_annual"]
                if vol:
                    volatility_comparison[symbol] = vol

                # PE Ratio for valuation
                pe = data["fundamental_metrics"]["pe_ratio"]
                if pe:
                    valuation_comparison[symbol] = pe

            # Find best/worst performers
            best_performer = max(performance_comparison.items(), key=lambda x: x[1]) if performance_comparison else None
            worst_performer = min(performance_comparison.items(), key=lambda x: x[1]) if performance_comparison else None

            return {
                "symbols_analyzed": list(comparison_data.keys()),
                "comparison_summary": {
                    "best_performer": best_performer,
                    "worst_performer": worst_performer,
                    "avg_performance": round(np.mean(list(performance_comparison.values())), 2) if performance_comparison else None,
                    "avg_volatility": round(np.mean(list(volatility_comparison.values())), 2) if volatility_comparison else None
                },
                "detailed_data": comparison_data,
                "analysis_date": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            }

        except Exception as e:
            return {"error": f"Failed to compare stocks: {str(e)}"}

    def _resolve_symbol(self, input_symbol: str) -> str:
        """Convert company name to stock symbol if needed."""
        input_lower = input_symbol.lower().strip()

        # Check if it's already a valid symbol format (all caps, 1-5 characters)
        if input_symbol.isupper() and 1 <= len(input_symbol) <= 5:
            return input_symbol

        # Check common symbols mapping
        if input_lower in self.common_symbols:
            return self.common_symbols[input_lower]

        # Check if it contains a company name
        for name, symbol in self.common_symbols.items():
            if name in input_lower or input_lower in name:
                return symbol

        # If not found, assume it's a symbol and convert to uppercase
        return input_symbol.upper()

    def _calculate_rsi(self, prices: pd.Series, period: int = 14) -> float:
        """Calculate Relative Strength Index."""
        try:
            delta = prices.diff()
            gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
            loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
            rs = gain / loss
            rsi = 100 - (100 / (1 + rs))
            return rsi.iloc[-1]
        except:
            return None

    def _determine_trend(self, current_price: float, ma_50: float, ma_200: float) -> str:
        """Determine price trend based on moving averages."""
        try:
            if not ma_50 or not ma_200:
                return "Unknown"

            if current_price > ma_50 > ma_200:
                return "Strong Uptrend"
            elif current_price > ma_50 and ma_50 < ma_200:
                return "Weak Uptrend"
            elif current_price < ma_50 < ma_200:
                return "Strong Downtrend"
            elif current_price < ma_50 and ma_50 > ma_200:
                return "Weak Downtrend"
            else:
                return "Sideways"
        except:
            return "Unknown"

    def _generate_investment_analysis(self, price: float, ma_50: float, ma_200: float,

                                    rsi: float, pe: float, volatility: float, info: dict) -> str:
        """Generate basic investment analysis summary."""
        try:
            analysis_points = []

            # Technical analysis
            if rsi:
                if rsi > 70:
                    analysis_points.append("Technically overbought (RSI > 70)")
                elif rsi < 30:
                    analysis_points.append("Technically oversold (RSI < 30)")
                else:
                    analysis_points.append("RSI in neutral range")

            # Trend analysis
            if ma_50 and ma_200:
                if price > ma_50 > ma_200:
                    analysis_points.append("Strong upward trend")
                elif price < ma_50 < ma_200:
                    analysis_points.append("Strong downward trend")

            # Valuation
            if pe:
                if pe > 25:
                    analysis_points.append("High P/E ratio - potentially overvalued")
                elif pe < 15:
                    analysis_points.append("Low P/E ratio - potentially undervalued")
                else:
                    analysis_points.append("Moderate P/E ratio")

            # Volatility
            if volatility:
                if volatility > 0.4:
                    analysis_points.append("High volatility - risky investment")
                elif volatility < 0.2:
                    analysis_points.append("Low volatility - stable investment")

            return " | ".join(analysis_points) if analysis_points else "Analysis unavailable"

        except:
            return "Analysis unavailable"


# Export the class
__all__ = ['FinancialDataIntegrator']