quantwise 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/README.md +80 -0
- package/.claude/skills/backtest-expert/SKILL.md +206 -0
- package/.claude/skills/backtest-expert/references/failed_tests.md +236 -0
- package/.claude/skills/backtest-expert/references/methodology.md +227 -0
- package/.claude/skills/breadth-chart-analyst/SKILL.md +583 -0
- package/.claude/skills/breadth-chart-analyst/assets/SP500_Breadth_Index_200MA_8MA.jpeg +0 -0
- package/.claude/skills/breadth-chart-analyst/assets/US_Stock_Market_Uptrend_Ratio.jpeg +0 -0
- package/.claude/skills/breadth-chart-analyst/assets/breadth_analysis_template.md +558 -0
- package/.claude/skills/breadth-chart-analyst/references/breadth_chart_methodology.md +590 -0
- package/.claude/skills/canslim-screener/SKILL.md +599 -0
- package/.claude/skills/canslim-screener/references/canslim_methodology.md +606 -0
- package/.claude/skills/canslim-screener/references/fmp_api_endpoints.md +707 -0
- package/.claude/skills/canslim-screener/references/interpretation_guide.md +516 -0
- package/.claude/skills/canslim-screener/references/scoring_system.md +597 -0
- package/.claude/skills/canslim-screener/scripts/calculators/earnings_calculator.py +343 -0
- package/.claude/skills/canslim-screener/scripts/calculators/growth_calculator.py +334 -0
- package/.claude/skills/canslim-screener/scripts/calculators/institutional_calculator.py +347 -0
- package/.claude/skills/canslim-screener/scripts/calculators/leadership_calculator.py +380 -0
- package/.claude/skills/canslim-screener/scripts/calculators/market_calculator.py +244 -0
- package/.claude/skills/canslim-screener/scripts/calculators/new_highs_calculator.py +194 -0
- package/.claude/skills/canslim-screener/scripts/calculators/supply_demand_calculator.py +221 -0
- package/.claude/skills/canslim-screener/scripts/finviz_stock_client.py +227 -0
- package/.claude/skills/canslim-screener/scripts/fmp_client.py +393 -0
- package/.claude/skills/canslim-screener/scripts/report_generator.py +405 -0
- package/.claude/skills/canslim-screener/scripts/scorer.py +625 -0
- package/.claude/skills/canslim-screener/scripts/screen_canslim.py +361 -0
- package/.claude/skills/canslim-screener/scripts/test_institutional_endpoint.py +109 -0
- package/.claude/skills/chart/SKILL.md +20 -0
- package/.claude/skills/dividend-growth-pullback-screener/SKILL.md +322 -0
- package/.claude/skills/dividend-growth-pullback-screener/references/dividend_growth_compounding.md +400 -0
- package/.claude/skills/dividend-growth-pullback-screener/references/fmp_api_guide.md +642 -0
- package/.claude/skills/dividend-growth-pullback-screener/references/rsi_oversold_strategy.md +333 -0
- package/.claude/skills/dividend-growth-pullback-screener/scripts/screen_dividend_growth_rsi.py +1155 -0
- package/.claude/skills/earnings-calendar/SKILL.md +721 -0
- package/.claude/skills/earnings-calendar/assets/earnings_report_template.md +102 -0
- package/.claude/skills/earnings-calendar/references/fmp_api_guide.md +590 -0
- package/.claude/skills/earnings-calendar/scripts/fetch_earnings_fmp.py +443 -0
- package/.claude/skills/earnings-calendar/scripts/generate_report.py +366 -0
- package/.claude/skills/economic-calendar-fetcher/SKILL.md +365 -0
- package/.claude/skills/economic-calendar-fetcher/references/fmp_api_documentation.md +345 -0
- package/.claude/skills/economic-calendar-fetcher/scripts/get_economic_calendar.py +267 -0
- package/.claude/skills/ftd-detector/SKILL.md +147 -0
- package/.claude/skills/ftd-detector/references/ftd_methodology.md +188 -0
- package/.claude/skills/ftd-detector/references/post_ftd_guide.md +185 -0
- package/.claude/skills/ftd-detector/scripts/fmp_client.py +158 -0
- package/.claude/skills/ftd-detector/scripts/ftd_detector.py +280 -0
- package/.claude/skills/ftd-detector/scripts/post_ftd_monitor.py +404 -0
- package/.claude/skills/ftd-detector/scripts/rally_tracker.py +508 -0
- package/.claude/skills/ftd-detector/scripts/report_generator.py +341 -0
- package/.claude/skills/ftd-detector/scripts/tests/conftest.py +9 -0
- package/.claude/skills/ftd-detector/scripts/tests/helpers.py +107 -0
- package/.claude/skills/ftd-detector/scripts/tests/test_post_ftd_monitor.py +311 -0
- package/.claude/skills/ftd-detector/scripts/tests/test_rally_tracker.py +302 -0
- package/.claude/skills/institutional-flow-tracker/README.md +362 -0
- package/.claude/skills/institutional-flow-tracker/SKILL.md +357 -0
- package/.claude/skills/institutional-flow-tracker/references/13f_filings_guide.md +383 -0
- package/.claude/skills/institutional-flow-tracker/references/institutional_investor_types.md +580 -0
- package/.claude/skills/institutional-flow-tracker/references/interpretation_framework.md +573 -0
- package/.claude/skills/institutional-flow-tracker/scripts/analyze_single_stock.py +457 -0
- package/.claude/skills/institutional-flow-tracker/scripts/track_institution_portfolio.py +108 -0
- package/.claude/skills/institutional-flow-tracker/scripts/track_institutional_flow.py +450 -0
- package/.claude/skills/macro-regime-detector/SKILL.md +86 -0
- package/.claude/skills/macro-regime-detector/references/historical_regimes.md +124 -0
- package/.claude/skills/macro-regime-detector/references/indicator_interpretation_guide.md +144 -0
- package/.claude/skills/macro-regime-detector/references/regime_detection_methodology.md +138 -0
- package/.claude/skills/macro-regime-detector/scripts/calculators/__init__.py +1 -0
- package/.claude/skills/macro-regime-detector/scripts/calculators/concentration_calculator.py +165 -0
- package/.claude/skills/macro-regime-detector/scripts/calculators/credit_conditions_calculator.py +124 -0
- package/.claude/skills/macro-regime-detector/scripts/calculators/equity_bond_calculator.py +198 -0
- package/.claude/skills/macro-regime-detector/scripts/calculators/sector_rotation_calculator.py +123 -0
- package/.claude/skills/macro-regime-detector/scripts/calculators/size_factor_calculator.py +131 -0
- package/.claude/skills/macro-regime-detector/scripts/calculators/utils.py +347 -0
- package/.claude/skills/macro-regime-detector/scripts/calculators/yield_curve_calculator.py +279 -0
- package/.claude/skills/macro-regime-detector/scripts/fmp_client.py +134 -0
- package/.claude/skills/macro-regime-detector/scripts/macro_regime_detector.py +278 -0
- package/.claude/skills/macro-regime-detector/scripts/report_generator.py +327 -0
- package/.claude/skills/macro-regime-detector/scripts/scorer.py +574 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/conftest.py +9 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_concentration.py +78 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_credit_conditions.py +59 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_equity_bond.py +74 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_helpers.py +90 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_scorer.py +439 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_sector_rotation.py +78 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_size_factor.py +59 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_utils.py +126 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_yield_curve.py +64 -0
- package/.claude/skills/market-breadth-analyzer/SKILL.md +121 -0
- package/.claude/skills/market-breadth-analyzer/references/breadth_analysis_methodology.md +168 -0
- package/.claude/skills/market-breadth-analyzer/scripts/calculators/__init__.py +1 -0
- package/.claude/skills/market-breadth-analyzer/scripts/calculators/bearish_signal_calculator.py +150 -0
- package/.claude/skills/market-breadth-analyzer/scripts/calculators/cycle_calculator.py +168 -0
- package/.claude/skills/market-breadth-analyzer/scripts/calculators/divergence_calculator.py +119 -0
- package/.claude/skills/market-breadth-analyzer/scripts/calculators/historical_context_calculator.py +120 -0
- package/.claude/skills/market-breadth-analyzer/scripts/calculators/ma_crossover_calculator.py +115 -0
- package/.claude/skills/market-breadth-analyzer/scripts/calculators/trend_level_calculator.py +103 -0
- package/.claude/skills/market-breadth-analyzer/scripts/csv_client.py +225 -0
- package/.claude/skills/market-breadth-analyzer/scripts/market_breadth_analyzer.py +307 -0
- package/.claude/skills/market-breadth-analyzer/scripts/report_generator.py +330 -0
- package/.claude/skills/market-breadth-analyzer/scripts/scorer.py +271 -0
- package/.claude/skills/market-environment-analysis/SKILL.md +139 -0
- package/.claude/skills/market-environment-analysis/references/analysis_patterns.md +124 -0
- package/.claude/skills/market-environment-analysis/references/indicators.md +99 -0
- package/.claude/skills/market-environment-analysis/scripts/market_utils.py +127 -0
- package/.claude/skills/market-news-analyst/SKILL.md +714 -0
- package/.claude/skills/market-news-analyst/references/corporate_news_impact.md +446 -0
- package/.claude/skills/market-news-analyst/references/geopolitical_commodity_correlations.md +499 -0
- package/.claude/skills/market-news-analyst/references/market_event_patterns.md +393 -0
- package/.claude/skills/market-news-analyst/references/trusted_news_sources.md +510 -0
- package/.claude/skills/market-top-detector/SKILL.md +159 -0
- package/.claude/skills/market-top-detector/references/distribution_day_guide.md +100 -0
- package/.claude/skills/market-top-detector/references/historical_tops.md +142 -0
- package/.claude/skills/market-top-detector/references/market_top_methodology.md +167 -0
- package/.claude/skills/market-top-detector/scripts/calculators/__init__.py +17 -0
- package/.claude/skills/market-top-detector/scripts/calculators/breadth_calculator.py +116 -0
- package/.claude/skills/market-top-detector/scripts/calculators/defensive_rotation_calculator.py +127 -0
- package/.claude/skills/market-top-detector/scripts/calculators/distribution_day_calculator.py +161 -0
- package/.claude/skills/market-top-detector/scripts/calculators/index_technical_calculator.py +254 -0
- package/.claude/skills/market-top-detector/scripts/calculators/leading_stock_calculator.py +198 -0
- package/.claude/skills/market-top-detector/scripts/calculators/sentiment_calculator.py +213 -0
- package/.claude/skills/market-top-detector/scripts/fmp_client.py +158 -0
- package/.claude/skills/market-top-detector/scripts/market_top_detector.py +349 -0
- package/.claude/skills/market-top-detector/scripts/report_generator.py +314 -0
- package/.claude/skills/market-top-detector/scripts/scorer.py +473 -0
- package/.claude/skills/market-top-detector/scripts/tests/conftest.py +9 -0
- package/.claude/skills/market-top-detector/scripts/tests/helpers.py +49 -0
- package/.claude/skills/market-top-detector/scripts/tests/test_breadth.py +62 -0
- package/.claude/skills/market-top-detector/scripts/tests/test_defensive_rotation.py +56 -0
- package/.claude/skills/market-top-detector/scripts/tests/test_distribution_day.py +92 -0
- package/.claude/skills/market-top-detector/scripts/tests/test_index_technical.py +73 -0
- package/.claude/skills/market-top-detector/scripts/tests/test_leading_stock.py +57 -0
- package/.claude/skills/market-top-detector/scripts/tests/test_scorer.py +180 -0
- package/.claude/skills/market-top-detector/scripts/tests/test_sentiment.py +64 -0
- package/.claude/skills/options-strategy-advisor/README.md +469 -0
- package/.claude/skills/options-strategy-advisor/SKILL.md +959 -0
- package/.claude/skills/options-strategy-advisor/scripts/black_scholes.py +495 -0
- package/.claude/skills/pair-trade-screener/README.md +389 -0
- package/.claude/skills/pair-trade-screener/SKILL.md +622 -0
- package/.claude/skills/pair-trade-screener/references/cointegration_guide.md +745 -0
- package/.claude/skills/pair-trade-screener/references/methodology.md +853 -0
- package/.claude/skills/pair-trade-screener/scripts/analyze_spread.py +394 -0
- package/.claude/skills/pair-trade-screener/scripts/find_pairs.py +535 -0
- package/.claude/skills/portfolio-manager/README.md +394 -0
- package/.claude/skills/portfolio-manager/SKILL.md +750 -0
- package/.claude/skills/portfolio-manager/references/alpaca-mcp-setup.md +367 -0
- package/.claude/skills/portfolio-manager/references/asset-allocation.md +502 -0
- package/.claude/skills/portfolio-manager/references/diversification-principles.md +553 -0
- package/.claude/skills/portfolio-manager/references/portfolio-risk-metrics.md +603 -0
- package/.claude/skills/portfolio-manager/references/position-evaluation.md +477 -0
- package/.claude/skills/portfolio-manager/references/rebalancing-strategies.md +715 -0
- package/.claude/skills/portfolio-manager/references/risk-profile-questionnaire.md +608 -0
- package/.claude/skills/portfolio-manager/references/target-allocations.md +558 -0
- package/.claude/skills/portfolio-manager/scripts/test_alpaca_connection.py +286 -0
- package/.claude/skills/scenario-analyzer/SKILL.md +317 -0
- package/.claude/skills/scenario-analyzer/references/headline_event_patterns.md +264 -0
- package/.claude/skills/scenario-analyzer/references/scenario_playbooks.md +320 -0
- package/.claude/skills/scenario-analyzer/references/sector_sensitivity_matrix.md +217 -0
- package/.claude/skills/sector-analyst/SKILL.md +206 -0
- package/.claude/skills/sector-analyst/assets/industory_performance_1.jpeg +0 -0
- package/.claude/skills/sector-analyst/assets/industory_performance_2.jpeg +0 -0
- package/.claude/skills/sector-analyst/assets/sector_performance.jpeg +0 -0
- package/.claude/skills/sector-analyst/references/sector_rotation.md +170 -0
- package/.claude/skills/stanley-druckenmiller-investment/SKILL.md +84 -0
- package/.claude/skills/stanley-druckenmiller-investment/references/case-studies.md +148 -0
- package/.claude/skills/stanley-druckenmiller-investment/references/investment-philosophy.md +80 -0
- package/.claude/skills/stanley-druckenmiller-investment/references/market-analysis-guide.md +146 -0
- package/.claude/skills/stock/NOTION_SETUP.md +33 -0
- package/.claude/skills/stock/SKILL.md +38 -0
- package/.claude/skills/technical-analyst/SKILL.md +238 -0
- package/.claude/skills/technical-analyst/assets/analysis_template.md +183 -0
- package/.claude/skills/technical-analyst/references/technical_analysis_framework.md +282 -0
- package/.claude/skills/theme-detector/SKILL.md +320 -0
- package/.claude/skills/theme-detector/assets/report_template.md +155 -0
- package/.claude/skills/theme-detector/references/cross_sector_themes.md +252 -0
- package/.claude/skills/theme-detector/references/finviz_industry_codes.md +403 -0
- package/.claude/skills/theme-detector/references/thematic_etf_catalog.md +333 -0
- package/.claude/skills/theme-detector/references/theme_detection_methodology.md +430 -0
- package/.claude/skills/theme-detector/scripts/calculators/__init__.py +1 -0
- package/.claude/skills/theme-detector/scripts/calculators/heat_calculator.py +123 -0
- package/.claude/skills/theme-detector/scripts/calculators/industry_ranker.py +98 -0
- package/.claude/skills/theme-detector/scripts/calculators/lifecycle_calculator.py +172 -0
- package/.claude/skills/theme-detector/scripts/calculators/theme_classifier.py +195 -0
- package/.claude/skills/theme-detector/scripts/calculators/theme_discoverer.py +280 -0
- package/.claude/skills/theme-detector/scripts/config_loader.py +142 -0
- package/.claude/skills/theme-detector/scripts/default_theme_config.py +254 -0
- package/.claude/skills/theme-detector/scripts/etf_scanner.py +609 -0
- package/.claude/skills/theme-detector/scripts/finviz_performance_client.py +131 -0
- package/.claude/skills/theme-detector/scripts/report_generator.py +490 -0
- package/.claude/skills/theme-detector/scripts/representative_stock_selector.py +673 -0
- package/.claude/skills/theme-detector/scripts/scorer.py +87 -0
- package/.claude/skills/theme-detector/scripts/tests/README.md +21 -0
- package/.claude/skills/theme-detector/scripts/tests/conftest.py +9 -0
- package/.claude/skills/theme-detector/scripts/tests/test_config_loader.py +239 -0
- package/.claude/skills/theme-detector/scripts/tests/test_etf_scanner.py +810 -0
- package/.claude/skills/theme-detector/scripts/tests/test_heat_calculator.py +245 -0
- package/.claude/skills/theme-detector/scripts/tests/test_industry_ranker.py +256 -0
- package/.claude/skills/theme-detector/scripts/tests/test_lifecycle_calculator.py +301 -0
- package/.claude/skills/theme-detector/scripts/tests/test_report_generator.py +624 -0
- package/.claude/skills/theme-detector/scripts/tests/test_representative_stock_selector.py +898 -0
- package/.claude/skills/theme-detector/scripts/tests/test_scorer.py +185 -0
- package/.claude/skills/theme-detector/scripts/tests/test_theme_classifier.py +534 -0
- package/.claude/skills/theme-detector/scripts/tests/test_theme_detector_e2e.py +467 -0
- package/.claude/skills/theme-detector/scripts/tests/test_theme_discoverer.py +458 -0
- package/.claude/skills/theme-detector/scripts/tests/test_uptrend_client.py +76 -0
- package/.claude/skills/theme-detector/scripts/theme_detector.py +815 -0
- package/.claude/skills/theme-detector/scripts/themes.yaml +168 -0
- package/.claude/skills/theme-detector/scripts/uptrend_client.py +241 -0
- package/.claude/skills/uptrend-analyzer/SKILL.md +108 -0
- package/.claude/skills/uptrend-analyzer/references/uptrend_methodology.md +215 -0
- package/.claude/skills/uptrend-analyzer/scripts/calculators/__init__.py +1 -0
- package/.claude/skills/uptrend-analyzer/scripts/calculators/historical_context_calculator.py +122 -0
- package/.claude/skills/uptrend-analyzer/scripts/calculators/market_breadth_calculator.py +145 -0
- package/.claude/skills/uptrend-analyzer/scripts/calculators/momentum_calculator.py +183 -0
- package/.claude/skills/uptrend-analyzer/scripts/calculators/sector_participation_calculator.py +204 -0
- package/.claude/skills/uptrend-analyzer/scripts/calculators/sector_rotation_calculator.py +218 -0
- package/.claude/skills/uptrend-analyzer/scripts/data_fetcher.py +236 -0
- package/.claude/skills/uptrend-analyzer/scripts/report_generator.py +329 -0
- package/.claude/skills/uptrend-analyzer/scripts/scorer.py +276 -0
- package/.claude/skills/uptrend-analyzer/scripts/uptrend_analyzer.py +219 -0
- package/.claude/skills/us-market-bubble-detector/CHANGELOG.md +118 -0
- package/.claude/skills/us-market-bubble-detector/SKILL.md +545 -0
- package/.claude/skills/us-market-bubble-detector/references/bubble_framework.md +335 -0
- package/.claude/skills/us-market-bubble-detector/references/historical_cases.md +327 -0
- package/.claude/skills/us-market-bubble-detector/references/implementation_guide.md +473 -0
- package/.claude/skills/us-market-bubble-detector/references/quick_reference.md +354 -0
- package/.claude/skills/us-market-bubble-detector/references/quick_reference_en.md +342 -0
- package/.claude/skills/us-market-bubble-detector/scripts/bubble_scorer.py +309 -0
- package/.claude/skills/us-stock-analysis/SKILL.md +294 -0
- package/.claude/skills/us-stock-analysis/references/financial-metrics.md +172 -0
- package/.claude/skills/us-stock-analysis/references/fundamental-analysis.md +129 -0
- package/.claude/skills/us-stock-analysis/references/report-template.md +207 -0
- package/.claude/skills/us-stock-analysis/references/technical-analysis.md +93 -0
- package/.claude/skills/value-dividend-screener/SKILL.md +562 -0
- package/.claude/skills/value-dividend-screener/references/fmp_api_guide.md +348 -0
- package/.claude/skills/value-dividend-screener/references/screening_methodology.md +315 -0
- package/.claude/skills/value-dividend-screener/scripts/screen_dividend_stocks.py +1138 -0
- package/.claude/skills/vcp-screener/SKILL.md +79 -0
- package/.claude/skills/vcp-screener/references/fmp_api_endpoints.md +45 -0
- package/.claude/skills/vcp-screener/references/scoring_system.md +154 -0
- package/.claude/skills/vcp-screener/references/vcp_methodology.md +124 -0
- package/.claude/skills/vcp-screener/scripts/calculators/__init__.py +1 -0
- package/.claude/skills/vcp-screener/scripts/calculators/pivot_proximity_calculator.py +139 -0
- package/.claude/skills/vcp-screener/scripts/calculators/relative_strength_calculator.py +161 -0
- package/.claude/skills/vcp-screener/scripts/calculators/trend_template_calculator.py +228 -0
- package/.claude/skills/vcp-screener/scripts/calculators/vcp_pattern_calculator.py +322 -0
- package/.claude/skills/vcp-screener/scripts/calculators/volume_pattern_calculator.py +121 -0
- package/.claude/skills/vcp-screener/scripts/fmp_client.py +162 -0
- package/.claude/skills/vcp-screener/scripts/report_generator.py +317 -0
- package/.claude/skills/vcp-screener/scripts/scorer.py +155 -0
- package/.claude/skills/vcp-screener/scripts/screen_vcp.py +536 -0
- package/.claude/skills/vcp-screener/scripts/tests/__init__.py +0 -0
- package/.claude/skills/vcp-screener/scripts/tests/conftest.py +9 -0
- package/.claude/skills/vcp-screener/scripts/tests/test_vcp_screener.py +834 -0
- package/.claude/skills/weekly-trade-strategy/.claude/agents/druckenmiller-strategy-planner.md +300 -0
- package/.claude/skills/weekly-trade-strategy/.claude/agents/market-news-analyzer.md +239 -0
- package/.claude/skills/weekly-trade-strategy/.claude/agents/technical-market-analyst.md +187 -0
- package/.claude/skills/weekly-trade-strategy/.claude/agents/us-market-analyst.md +218 -0
- package/.claude/skills/weekly-trade-strategy/.claude/agents/weekly-trade-blog-writer.md +318 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/breadth-chart-analyst/SKILL.md +662 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/breadth-chart-analyst/assets/SP500_Breadth_Index_200MA_8MA.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/breadth-chart-analyst/assets/US_Stock_Market_Uptrend_Ratio.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/breadth-chart-analyst/assets/breadth_analysis_template.md +558 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/breadth-chart-analyst/references/breadth_chart_methodology.md +590 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/SKILL.md +721 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/assets/earnings_report_template.md +102 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/earnings_calendar_2025-11-02.md +447 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/references/fmp_api_guide.md +590 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/scripts/fetch_earnings_fmp.py +443 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/scripts/generate_report.py +366 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/economic-calendar-fetcher/SKILL.md +365 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/economic-calendar-fetcher/references/fmp_api_documentation.md +345 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/economic-calendar-fetcher/scripts/get_economic_calendar.py +267 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-environment-analysis/SKILL.md +139 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-environment-analysis/references/analysis_patterns.md +124 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-environment-analysis/references/indicators.md +99 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-environment-analysis/scripts/market_utils.py +127 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-news-analyst/SKILL.md +714 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-news-analyst/references/corporate_news_impact.md +446 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-news-analyst/references/geopolitical_commodity_correlations.md +499 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-news-analyst/references/market_event_patterns.md +393 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-news-analyst/references/trusted_news_sources.md +510 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/sector-analyst/SKILL.md +206 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/sector-analyst/assets/industory_performance_1.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/sector-analyst/assets/industory_performance_2.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/sector-analyst/assets/sector_performance.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/sector-analyst/references/sector_rotation.md +170 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/stanley-druckenmiller-investment/SKILL.md +84 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/stanley-druckenmiller-investment/references/case-studies.md +148 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/stanley-druckenmiller-investment/references/investment-philosophy.md +80 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/stanley-druckenmiller-investment/references/market-analysis-guide.md +146 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/technical-analyst/SKILL.md +238 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/technical-analyst/assets/analysis_template.md +183 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/technical-analyst/references/technical_analysis_framework.md +282 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/CHANGELOG.md +118 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/SKILL.md +545 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/references/bubble_framework.md +335 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/references/historical_cases.md +327 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/references/implementation_guide.md +473 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/references/quick_reference.md +354 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/references/quick_reference_en.md +342 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/scripts/bubble_scorer.py +309 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-stock-analysis/SKILL.md +294 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-stock-analysis/references/financial-metrics.md +172 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-stock-analysis/references/fundamental-analysis.md +129 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-stock-analysis/references/report-template.md +207 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-stock-analysis/references/technical-analysis.md +93 -0
- package/.claude/skills/weekly-trade-strategy/CLAUDE.md +454 -0
- package/.claude/skills/weekly-trade-strategy/README.md +287 -0
- package/.claude/skills/weekly-trade-strategy/blogs/.gitkeep +0 -0
- package/.claude/skills/weekly-trade-strategy/charts/.gitkeep +0 -0
- package/.claude/skills/weekly-trade-strategy/earnings_data.json +10054 -0
- package/.claude/skills/weekly-trade-strategy/skills/breadth-chart-analyst/SKILL.md +662 -0
- package/.claude/skills/weekly-trade-strategy/skills/breadth-chart-analyst/assets/SP500_Breadth_Index_200MA_8MA.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/skills/breadth-chart-analyst/assets/US_Stock_Market_Uptrend_Ratio.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/skills/breadth-chart-analyst/assets/breadth_analysis_template.md +558 -0
- package/.claude/skills/weekly-trade-strategy/skills/breadth-chart-analyst/references/breadth_chart_methodology.md +590 -0
- package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/SKILL.md +721 -0
- package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/assets/earnings_report_template.md +102 -0
- package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/earnings_calendar_2025-11-02.md +447 -0
- package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/references/fmp_api_guide.md +590 -0
- package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/scripts/fetch_earnings_fmp.py +443 -0
- package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/scripts/generate_report.py +366 -0
- package/.claude/skills/weekly-trade-strategy/skills/economic-calendar-fetcher/SKILL.md +365 -0
- package/.claude/skills/weekly-trade-strategy/skills/economic-calendar-fetcher/references/fmp_api_documentation.md +345 -0
- package/.claude/skills/weekly-trade-strategy/skills/economic-calendar-fetcher/scripts/get_economic_calendar.py +267 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-environment-analysis/SKILL.md +139 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-environment-analysis/references/analysis_patterns.md +124 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-environment-analysis/references/indicators.md +99 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-environment-analysis/scripts/market_utils.py +127 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-news-analyst/SKILL.md +714 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-news-analyst/references/corporate_news_impact.md +446 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-news-analyst/references/geopolitical_commodity_correlations.md +499 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-news-analyst/references/market_event_patterns.md +393 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-news-analyst/references/trusted_news_sources.md +510 -0
- package/.claude/skills/weekly-trade-strategy/skills/sector-analyst/SKILL.md +206 -0
- package/.claude/skills/weekly-trade-strategy/skills/sector-analyst/assets/industory_performance_1.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/skills/sector-analyst/assets/industory_performance_2.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/skills/sector-analyst/assets/sector_performance.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/skills/sector-analyst/references/sector_rotation.md +170 -0
- package/.claude/skills/weekly-trade-strategy/skills/stanley-druckenmiller-investment/SKILL.md +84 -0
- package/.claude/skills/weekly-trade-strategy/skills/stanley-druckenmiller-investment/references/case-studies.md +148 -0
- package/.claude/skills/weekly-trade-strategy/skills/stanley-druckenmiller-investment/references/investment-philosophy.md +80 -0
- package/.claude/skills/weekly-trade-strategy/skills/stanley-druckenmiller-investment/references/market-analysis-guide.md +146 -0
- package/.claude/skills/weekly-trade-strategy/skills/technical-analyst/SKILL.md +238 -0
- package/.claude/skills/weekly-trade-strategy/skills/technical-analyst/assets/analysis_template.md +183 -0
- package/.claude/skills/weekly-trade-strategy/skills/technical-analyst/references/technical_analysis_framework.md +282 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/CHANGELOG.md +118 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/SKILL.md +545 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/references/bubble_framework.md +335 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/references/historical_cases.md +327 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/references/implementation_guide.md +473 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/references/quick_reference.md +354 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/references/quick_reference_en.md +342 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/scripts/bubble_scorer.py +309 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-stock-analysis/SKILL.md +294 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-stock-analysis/references/financial-metrics.md +172 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-stock-analysis/references/fundamental-analysis.md +129 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-stock-analysis/references/report-template.md +207 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-stock-analysis/references/technical-analysis.md +93 -0
- package/.mcp.json +3 -0
- package/cli.mjs +16 -16
- package/package.json +4 -2
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Institutional Flow Tracker - Single Stock Deep Dive
|
|
4
|
+
|
|
5
|
+
Provides detailed analysis of institutional ownership for a specific stock,
|
|
6
|
+
including historical trends, top holders, and position changes.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python3 analyze_single_stock.py AAPL
|
|
10
|
+
python3 analyze_single_stock.py MSFT --quarters 12 --api-key YOUR_KEY
|
|
11
|
+
python3 analyze_single_stock.py TSLA --compare-to GM
|
|
12
|
+
|
|
13
|
+
Requirements:
|
|
14
|
+
- FMP API key (set FMP_API_KEY environment variable or pass --api-key)
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import argparse
|
|
18
|
+
import json
|
|
19
|
+
import os
|
|
20
|
+
import sys
|
|
21
|
+
from datetime import datetime
|
|
22
|
+
from typing import List, Dict, Optional
|
|
23
|
+
from collections import defaultdict
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
import requests
|
|
27
|
+
except ImportError:
|
|
28
|
+
print("Error: 'requests' library not installed. Install with: pip install requests")
|
|
29
|
+
sys.exit(1)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class SingleStockAnalyzer:
|
|
33
|
+
"""Analyze institutional ownership for a single stock"""
|
|
34
|
+
|
|
35
|
+
def __init__(self, api_key: str):
|
|
36
|
+
self.api_key = api_key
|
|
37
|
+
self.base_url = "https://financialmodelingprep.com/api/v3"
|
|
38
|
+
|
|
39
|
+
def get_institutional_holders(self, symbol: str) -> List[Dict]:
|
|
40
|
+
"""Get all institutional holders data for a stock"""
|
|
41
|
+
url = f"{self.base_url}/institutional-holder/{symbol}"
|
|
42
|
+
params = {"apikey": self.api_key}
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
response = requests.get(url, params=params, timeout=30)
|
|
46
|
+
response.raise_for_status()
|
|
47
|
+
data = response.json()
|
|
48
|
+
return data if isinstance(data, list) else []
|
|
49
|
+
except requests.exceptions.RequestException as e:
|
|
50
|
+
print(f"Error fetching institutional holders for {symbol}: {e}")
|
|
51
|
+
return []
|
|
52
|
+
|
|
53
|
+
def get_company_profile(self, symbol: str) -> Dict:
|
|
54
|
+
"""Get company profile information"""
|
|
55
|
+
url = f"{self.base_url}/profile/{symbol}"
|
|
56
|
+
params = {"apikey": self.api_key}
|
|
57
|
+
|
|
58
|
+
try:
|
|
59
|
+
response = requests.get(url, params=params, timeout=30)
|
|
60
|
+
response.raise_for_status()
|
|
61
|
+
data = response.json()
|
|
62
|
+
return data[0] if isinstance(data, list) and data else {}
|
|
63
|
+
except requests.exceptions.RequestException as e:
|
|
64
|
+
print(f"Error fetching company profile for {symbol}: {e}")
|
|
65
|
+
return {}
|
|
66
|
+
|
|
67
|
+
def analyze_stock(self, symbol: str, quarters: int = 8) -> Dict:
|
|
68
|
+
"""Perform comprehensive institutional analysis on a stock"""
|
|
69
|
+
|
|
70
|
+
print(f"Analyzing institutional ownership for {symbol}...")
|
|
71
|
+
|
|
72
|
+
# Get company profile
|
|
73
|
+
profile = self.get_company_profile(symbol)
|
|
74
|
+
company_name = profile.get('companyName', symbol)
|
|
75
|
+
sector = profile.get('sector', 'Unknown')
|
|
76
|
+
market_cap = profile.get('mktCap', 0)
|
|
77
|
+
|
|
78
|
+
print(f"Company: {company_name}")
|
|
79
|
+
print(f"Sector: {sector}")
|
|
80
|
+
print(f"Market Cap: ${market_cap:,}")
|
|
81
|
+
|
|
82
|
+
# Get institutional holders
|
|
83
|
+
holders = self.get_institutional_holders(symbol)
|
|
84
|
+
|
|
85
|
+
if not holders:
|
|
86
|
+
print(f"No institutional holder data available for {symbol}")
|
|
87
|
+
return {}
|
|
88
|
+
|
|
89
|
+
# Group by quarter
|
|
90
|
+
quarters_data = defaultdict(list)
|
|
91
|
+
for holder in holders:
|
|
92
|
+
date = holder.get('dateReported', '')
|
|
93
|
+
if date:
|
|
94
|
+
quarters_data[date].append(holder)
|
|
95
|
+
|
|
96
|
+
# Get most recent N quarters
|
|
97
|
+
sorted_quarters = sorted(quarters_data.keys(), reverse=True)[:quarters]
|
|
98
|
+
|
|
99
|
+
if len(sorted_quarters) < 2:
|
|
100
|
+
print(f"Insufficient data (need at least 2 quarters, found {len(sorted_quarters)})")
|
|
101
|
+
return {}
|
|
102
|
+
|
|
103
|
+
# Calculate quarterly metrics
|
|
104
|
+
quarterly_metrics = []
|
|
105
|
+
for q in sorted_quarters:
|
|
106
|
+
holders_q = quarters_data[q]
|
|
107
|
+
total_shares = sum(h.get('totalShares', 0) for h in holders_q)
|
|
108
|
+
total_value = sum(h.get('totalInvested', 0) for h in holders_q)
|
|
109
|
+
num_holders = len(holders_q)
|
|
110
|
+
|
|
111
|
+
quarterly_metrics.append({
|
|
112
|
+
'quarter': q,
|
|
113
|
+
'total_shares': total_shares,
|
|
114
|
+
'total_value': total_value,
|
|
115
|
+
'num_holders': num_holders,
|
|
116
|
+
'top_holders': sorted(holders_q, key=lambda x: x.get('totalShares', 0), reverse=True)[:20]
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
# Calculate trends
|
|
120
|
+
most_recent = quarterly_metrics[0]
|
|
121
|
+
oldest = quarterly_metrics[-1]
|
|
122
|
+
|
|
123
|
+
shares_trend = ((most_recent['total_shares'] - oldest['total_shares']) / oldest['total_shares'] * 100) if oldest['total_shares'] > 0 else 0
|
|
124
|
+
holders_trend = most_recent['num_holders'] - oldest['num_holders']
|
|
125
|
+
|
|
126
|
+
# Analyze position changes (recent quarter vs previous)
|
|
127
|
+
if len(quarterly_metrics) >= 2:
|
|
128
|
+
current_q = quarterly_metrics[0]
|
|
129
|
+
previous_q = quarterly_metrics[1]
|
|
130
|
+
|
|
131
|
+
# Create holder dictionaries for comparison
|
|
132
|
+
current_holders_map = {h.get('holder', ''): h for h in current_q['top_holders']}
|
|
133
|
+
previous_holders_map = {h.get('holder', ''): h for h in previous_q['top_holders']}
|
|
134
|
+
|
|
135
|
+
# Categorize changes
|
|
136
|
+
new_positions = []
|
|
137
|
+
increased_positions = []
|
|
138
|
+
decreased_positions = []
|
|
139
|
+
closed_positions = []
|
|
140
|
+
|
|
141
|
+
# Check current holders
|
|
142
|
+
for name, holder in current_holders_map.items():
|
|
143
|
+
current_shares = holder.get('totalShares', 0)
|
|
144
|
+
if name in previous_holders_map:
|
|
145
|
+
previous_shares = previous_holders_map[name].get('totalShares', 0)
|
|
146
|
+
change = current_shares - previous_shares
|
|
147
|
+
pct_change = (change / previous_shares * 100) if previous_shares > 0 else 0
|
|
148
|
+
|
|
149
|
+
if change > 0:
|
|
150
|
+
increased_positions.append({
|
|
151
|
+
'name': name,
|
|
152
|
+
'current_shares': current_shares,
|
|
153
|
+
'change': change,
|
|
154
|
+
'pct_change': pct_change
|
|
155
|
+
})
|
|
156
|
+
elif change < 0:
|
|
157
|
+
decreased_positions.append({
|
|
158
|
+
'name': name,
|
|
159
|
+
'current_shares': current_shares,
|
|
160
|
+
'change': change,
|
|
161
|
+
'pct_change': pct_change
|
|
162
|
+
})
|
|
163
|
+
else:
|
|
164
|
+
new_positions.append({
|
|
165
|
+
'name': name,
|
|
166
|
+
'shares': current_shares
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
# Check for closed positions
|
|
170
|
+
for name, holder in previous_holders_map.items():
|
|
171
|
+
if name not in current_holders_map:
|
|
172
|
+
closed_positions.append({
|
|
173
|
+
'name': name,
|
|
174
|
+
'previous_shares': holder.get('totalShares', 0)
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
# Sort by magnitude
|
|
178
|
+
increased_positions.sort(key=lambda x: x['change'], reverse=True)
|
|
179
|
+
decreased_positions.sort(key=lambda x: x['change'])
|
|
180
|
+
|
|
181
|
+
else:
|
|
182
|
+
new_positions = []
|
|
183
|
+
increased_positions = []
|
|
184
|
+
decreased_positions = []
|
|
185
|
+
closed_positions = []
|
|
186
|
+
|
|
187
|
+
return {
|
|
188
|
+
'symbol': symbol,
|
|
189
|
+
'company_name': company_name,
|
|
190
|
+
'sector': sector,
|
|
191
|
+
'market_cap': market_cap,
|
|
192
|
+
'quarterly_metrics': quarterly_metrics,
|
|
193
|
+
'shares_trend': shares_trend,
|
|
194
|
+
'holders_trend': holders_trend,
|
|
195
|
+
'new_positions': new_positions,
|
|
196
|
+
'increased_positions': increased_positions,
|
|
197
|
+
'decreased_positions': decreased_positions,
|
|
198
|
+
'closed_positions': closed_positions
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
def generate_report(self, analysis: Dict, output_file: Optional[str] = None):
|
|
202
|
+
"""Generate detailed markdown report"""
|
|
203
|
+
|
|
204
|
+
if not analysis:
|
|
205
|
+
print("No analysis data available")
|
|
206
|
+
return
|
|
207
|
+
|
|
208
|
+
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
209
|
+
symbol = analysis['symbol']
|
|
210
|
+
|
|
211
|
+
report = f"""# Institutional Ownership Analysis: {symbol}
|
|
212
|
+
|
|
213
|
+
**Company:** {analysis['company_name']}
|
|
214
|
+
**Sector:** {analysis['sector']}
|
|
215
|
+
**Market Cap:** ${analysis['market_cap']:,}
|
|
216
|
+
**Analysis Date:** {timestamp}
|
|
217
|
+
|
|
218
|
+
## Executive Summary
|
|
219
|
+
|
|
220
|
+
"""
|
|
221
|
+
|
|
222
|
+
# Determine overall signal
|
|
223
|
+
shares_trend = analysis['shares_trend']
|
|
224
|
+
holders_trend = analysis['holders_trend']
|
|
225
|
+
|
|
226
|
+
if shares_trend > 15 and holders_trend > 5:
|
|
227
|
+
signal = "🟢 **STRONG ACCUMULATION**"
|
|
228
|
+
interpretation = "Strong institutional buying with increasing participation. Positive signal."
|
|
229
|
+
elif shares_trend > 7 and holders_trend > 0:
|
|
230
|
+
signal = "🟢 **MODERATE ACCUMULATION**"
|
|
231
|
+
interpretation = "Steady institutional buying. Moderately positive signal."
|
|
232
|
+
elif shares_trend < -15 or holders_trend < -5:
|
|
233
|
+
signal = "🔴 **STRONG DISTRIBUTION**"
|
|
234
|
+
interpretation = "Significant institutional selling. Warning sign - investigate further."
|
|
235
|
+
elif shares_trend < -7:
|
|
236
|
+
signal = "🔴 **MODERATE DISTRIBUTION**"
|
|
237
|
+
interpretation = "Institutional selling detected. Monitor closely."
|
|
238
|
+
else:
|
|
239
|
+
signal = "⚪ **NEUTRAL**"
|
|
240
|
+
interpretation = "No significant institutional flow changes. Stable ownership."
|
|
241
|
+
|
|
242
|
+
report += f"""**Signal:** {signal}
|
|
243
|
+
|
|
244
|
+
**Interpretation:** {interpretation}
|
|
245
|
+
|
|
246
|
+
**Trend ({len(analysis['quarterly_metrics'])} Quarters):**
|
|
247
|
+
- Institutional Shares: {shares_trend:+.2f}%
|
|
248
|
+
- Number of Institutions: {holders_trend:+d}
|
|
249
|
+
|
|
250
|
+
## Historical Institutional Ownership Trend
|
|
251
|
+
|
|
252
|
+
| Quarter | Total Shares Held | Total Value | Number of Institutions | QoQ Change |
|
|
253
|
+
|---------|-------------------|-------------|----------------------|------------|
|
|
254
|
+
"""
|
|
255
|
+
|
|
256
|
+
# Add quarterly data
|
|
257
|
+
metrics = analysis['quarterly_metrics']
|
|
258
|
+
for i, q in enumerate(metrics):
|
|
259
|
+
if i < len(metrics) - 1:
|
|
260
|
+
prev_shares = metrics[i+1]['total_shares']
|
|
261
|
+
qoq_change = ((q['total_shares'] - prev_shares) / prev_shares * 100) if prev_shares > 0 else 0
|
|
262
|
+
qoq_str = f"{qoq_change:+.2f}%"
|
|
263
|
+
else:
|
|
264
|
+
qoq_str = "N/A"
|
|
265
|
+
|
|
266
|
+
report += f"| {q['quarter']} | {q['total_shares']:,} | ${q['total_value']:,} | {q['num_holders']} | {qoq_str} |\n"
|
|
267
|
+
|
|
268
|
+
# Recent changes
|
|
269
|
+
report += f"""
|
|
270
|
+
## Recent Quarter Changes ({metrics[0]['quarter']} vs {metrics[1]['quarter']})
|
|
271
|
+
|
|
272
|
+
### New Positions (Institutions that newly initiated)
|
|
273
|
+
|
|
274
|
+
"""
|
|
275
|
+
if analysis['new_positions']:
|
|
276
|
+
report += "| Institution | Shares Acquired |\n"
|
|
277
|
+
report += "|-------------|----------------|\n"
|
|
278
|
+
for pos in analysis['new_positions'][:10]:
|
|
279
|
+
report += f"| {pos['name']} | {pos['shares']:,} |\n"
|
|
280
|
+
else:
|
|
281
|
+
report += "No new institutional positions detected.\n"
|
|
282
|
+
|
|
283
|
+
report += "\n### Increased Positions (Top 10)\n\n"
|
|
284
|
+
if analysis['increased_positions']:
|
|
285
|
+
report += "| Institution | Current Shares | Change | % Change |\n"
|
|
286
|
+
report += "|-------------|----------------|--------|----------|\n"
|
|
287
|
+
for pos in analysis['increased_positions'][:10]:
|
|
288
|
+
report += f"| {pos['name']} | {pos['current_shares']:,} | {pos['change']:+,} | {pos['pct_change']:+.2f}% |\n"
|
|
289
|
+
else:
|
|
290
|
+
report += "No significant position increases detected.\n"
|
|
291
|
+
|
|
292
|
+
report += "\n### Decreased Positions (Top 10)\n\n"
|
|
293
|
+
if analysis['decreased_positions']:
|
|
294
|
+
report += "| Institution | Current Shares | Change | % Change |\n"
|
|
295
|
+
report += "|-------------|----------------|--------|----------|\n"
|
|
296
|
+
for pos in analysis['decreased_positions'][:10]:
|
|
297
|
+
report += f"| {pos['name']} | {pos['current_shares']:,} | {pos['change']:,} | {pos['pct_change']:.2f}% |\n"
|
|
298
|
+
else:
|
|
299
|
+
report += "No significant position decreases detected.\n"
|
|
300
|
+
|
|
301
|
+
report += "\n### Closed Positions (Institutions that exited)\n\n"
|
|
302
|
+
if analysis['closed_positions']:
|
|
303
|
+
report += "| Institution | Previous Shares |\n"
|
|
304
|
+
report += "|-------------|-----------------|\n"
|
|
305
|
+
for pos in analysis['closed_positions'][:10]:
|
|
306
|
+
report += f"| {pos['name']} | {pos['previous_shares']:,} |\n"
|
|
307
|
+
else:
|
|
308
|
+
report += "No institutional exits detected.\n"
|
|
309
|
+
|
|
310
|
+
# Top current holders
|
|
311
|
+
report += f"\n## Top 20 Current Institutional Holders ({metrics[0]['quarter']})\n\n"
|
|
312
|
+
report += "| Rank | Institution | Shares Held | % of Institutional | Latest Change |\n"
|
|
313
|
+
report += "|------|-------------|-------------|-------------------|---------------|\n"
|
|
314
|
+
|
|
315
|
+
total_inst_shares = metrics[0]['total_shares']
|
|
316
|
+
for i, holder in enumerate(metrics[0]['top_holders'], 1):
|
|
317
|
+
shares = holder.get('totalShares', 0)
|
|
318
|
+
pct_of_inst = (shares / total_inst_shares * 100) if total_inst_shares > 0 else 0
|
|
319
|
+
change = holder.get('change', 0)
|
|
320
|
+
report += f"| {i} | {holder.get('holder', 'Unknown')} | {shares:,} | {pct_of_inst:.2f}% | {change:+,} |\n"
|
|
321
|
+
|
|
322
|
+
# Concentration analysis
|
|
323
|
+
if len(metrics[0]['top_holders']) >= 10:
|
|
324
|
+
top_10_shares = sum(h.get('totalShares', 0) for h in metrics[0]['top_holders'][:10])
|
|
325
|
+
concentration = (top_10_shares / total_inst_shares * 100) if total_inst_shares > 0 else 0
|
|
326
|
+
|
|
327
|
+
report += f"""
|
|
328
|
+
## Concentration Analysis
|
|
329
|
+
|
|
330
|
+
**Top 10 Holders Concentration:** {concentration:.2f}%
|
|
331
|
+
|
|
332
|
+
**Interpretation:**
|
|
333
|
+
"""
|
|
334
|
+
if concentration > 60:
|
|
335
|
+
report += "- **High Concentration** - Top 10 institutions control majority of institutional ownership\n"
|
|
336
|
+
report += "- **Risk:** Significant price impact if top holders sell\n"
|
|
337
|
+
report += "- **Opportunity:** May indicate high conviction by quality investors\n"
|
|
338
|
+
elif concentration > 40:
|
|
339
|
+
report += "- **Moderate Concentration** - Balanced institutional ownership\n"
|
|
340
|
+
report += "- **Risk:** Moderate concentration risk\n"
|
|
341
|
+
else:
|
|
342
|
+
report += "- **Low Concentration** - Widely distributed institutional ownership\n"
|
|
343
|
+
report += "- **Risk:** Lower concentration risk, more stable ownership\n"
|
|
344
|
+
|
|
345
|
+
report += """
|
|
346
|
+
## Interpretation Guide
|
|
347
|
+
|
|
348
|
+
**For detailed interpretation framework, see:**
|
|
349
|
+
`institutional-flow-tracker/references/interpretation_framework.md`
|
|
350
|
+
|
|
351
|
+
**Next Steps:**
|
|
352
|
+
1. Validate institutional signal with fundamental analysis
|
|
353
|
+
2. Check technical setup for entry timing
|
|
354
|
+
3. Review sector-wide institutional trends
|
|
355
|
+
4. Monitor quarterly for trend continuation/reversal
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
**Data Source:** FMP API (13F SEC Filings)
|
|
360
|
+
**Data Lag:** ~45 days after quarter end
|
|
361
|
+
**Note:** Use as confirming indicator alongside fundamental and technical analysis
|
|
362
|
+
"""
|
|
363
|
+
|
|
364
|
+
# Save report
|
|
365
|
+
if output_file:
|
|
366
|
+
output_path = output_file if output_file.endswith('.md') else f"{output_file}.md"
|
|
367
|
+
else:
|
|
368
|
+
output_path = f"institutional_analysis_{symbol}_{datetime.now().strftime('%Y%m%d')}.md"
|
|
369
|
+
|
|
370
|
+
with open(output_path, 'w') as f:
|
|
371
|
+
f.write(report)
|
|
372
|
+
|
|
373
|
+
print(f"\n✅ Report saved to: {output_path}")
|
|
374
|
+
return report
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
def main():
|
|
378
|
+
parser = argparse.ArgumentParser(
|
|
379
|
+
description='Analyze institutional ownership for a specific stock',
|
|
380
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
381
|
+
epilog="""
|
|
382
|
+
Examples:
|
|
383
|
+
# Basic analysis
|
|
384
|
+
python3 analyze_single_stock.py AAPL
|
|
385
|
+
|
|
386
|
+
# Extended history (12 quarters)
|
|
387
|
+
python3 analyze_single_stock.py MSFT --quarters 12
|
|
388
|
+
|
|
389
|
+
# With custom output
|
|
390
|
+
python3 analyze_single_stock.py TSLA --output tesla_analysis.md
|
|
391
|
+
"""
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
parser.add_argument(
|
|
395
|
+
'symbol',
|
|
396
|
+
type=str,
|
|
397
|
+
help='Stock ticker symbol to analyze'
|
|
398
|
+
)
|
|
399
|
+
parser.add_argument(
|
|
400
|
+
'--api-key',
|
|
401
|
+
type=str,
|
|
402
|
+
default=os.getenv('FMP_API_KEY'),
|
|
403
|
+
help='FMP API key (or set FMP_API_KEY environment variable)'
|
|
404
|
+
)
|
|
405
|
+
parser.add_argument(
|
|
406
|
+
'--quarters',
|
|
407
|
+
type=int,
|
|
408
|
+
default=8,
|
|
409
|
+
help='Number of quarters to analyze (default: 8, i.e., 2 years)'
|
|
410
|
+
)
|
|
411
|
+
parser.add_argument(
|
|
412
|
+
'--output',
|
|
413
|
+
type=str,
|
|
414
|
+
help='Output file path for markdown report'
|
|
415
|
+
)
|
|
416
|
+
parser.add_argument(
|
|
417
|
+
'--compare-to',
|
|
418
|
+
type=str,
|
|
419
|
+
help='Compare to another stock (optional, future feature)'
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
args = parser.parse_args()
|
|
423
|
+
|
|
424
|
+
# Validate API key
|
|
425
|
+
if not args.api_key:
|
|
426
|
+
print("Error: FMP API key required")
|
|
427
|
+
print("Set FMP_API_KEY environment variable or pass --api-key argument")
|
|
428
|
+
print("Get free API key at: https://financialmodelingprep.com/developer/docs")
|
|
429
|
+
sys.exit(1)
|
|
430
|
+
|
|
431
|
+
# Initialize analyzer
|
|
432
|
+
analyzer = SingleStockAnalyzer(args.api_key)
|
|
433
|
+
|
|
434
|
+
# Run analysis
|
|
435
|
+
analysis = analyzer.analyze_stock(args.symbol.upper(), quarters=args.quarters)
|
|
436
|
+
|
|
437
|
+
if not analysis:
|
|
438
|
+
print(f"Unable to complete analysis for {args.symbol}")
|
|
439
|
+
sys.exit(1)
|
|
440
|
+
|
|
441
|
+
# Generate report
|
|
442
|
+
analyzer.generate_report(analysis, output_file=args.output)
|
|
443
|
+
|
|
444
|
+
# Print summary
|
|
445
|
+
print("\n" + "="*80)
|
|
446
|
+
print(f"INSTITUTIONAL OWNERSHIP SUMMARY: {args.symbol}")
|
|
447
|
+
print("="*80)
|
|
448
|
+
print(f"Trend ({args.quarters} quarters): {analysis['shares_trend']:+.2f}% shares, {analysis['holders_trend']:+d} institutions")
|
|
449
|
+
print(f"Recent Activity:")
|
|
450
|
+
print(f" - New Positions: {len(analysis['new_positions'])}")
|
|
451
|
+
print(f" - Increased: {len(analysis['increased_positions'])}")
|
|
452
|
+
print(f" - Decreased: {len(analysis['decreased_positions'])}")
|
|
453
|
+
print(f" - Exited: {len(analysis['closed_positions'])}")
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
if __name__ == '__main__':
|
|
457
|
+
main()
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Institutional Flow Tracker - Portfolio Tracking
|
|
4
|
+
|
|
5
|
+
Track portfolio changes of specific institutional investors (hedge funds, mutual funds)
|
|
6
|
+
by analyzing their 13F filings over time. Follow superinvestors like Warren Buffett.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python3 track_institution_portfolio.py --cik 0001067983 --name "Berkshire Hathaway"
|
|
10
|
+
python3 track_institution_portfolio.py --cik 0001579982 --name "ARK Investment"
|
|
11
|
+
|
|
12
|
+
Note: This is a simplified version. For full portfolio tracking, use WhaleWisdom or
|
|
13
|
+
SEC EDGAR directly, as FMP API has limited institution-specific endpoints.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import argparse
|
|
17
|
+
import os
|
|
18
|
+
import sys
|
|
19
|
+
from datetime import datetime
|
|
20
|
+
|
|
21
|
+
print("""
|
|
22
|
+
================================================================================
|
|
23
|
+
TRACK INSTITUTION PORTFOLIO - SIMPLIFIED VERSION
|
|
24
|
+
================================================================================
|
|
25
|
+
|
|
26
|
+
This is a placeholder script. For comprehensive institution portfolio tracking:
|
|
27
|
+
|
|
28
|
+
1. Use WhaleWisdom (free tier available): https://whalewisdom.com
|
|
29
|
+
2. Use SEC EDGAR directly: https://www.sec.gov/cgi-bin/browse-edgar
|
|
30
|
+
3. Use DataRoma for superinvestors: https://www.dataroma.com
|
|
31
|
+
|
|
32
|
+
FMP API has limited institution-specific portfolio endpoints. The institutional
|
|
33
|
+
holder data is organized by stock (not by institution), making it difficult to
|
|
34
|
+
efficiently reconstruct an institution's full portfolio.
|
|
35
|
+
|
|
36
|
+
Recommended Workflow:
|
|
37
|
+
--------------------
|
|
38
|
+
1. Visit WhaleWisdom or DataRoma
|
|
39
|
+
2. Search for your target institution by name or CIK
|
|
40
|
+
3. View their current portfolio and quarterly changes
|
|
41
|
+
4. Use this skill's other scripts to analyze specific stocks they hold
|
|
42
|
+
|
|
43
|
+
Notable Institutions to Track:
|
|
44
|
+
-----------------------------
|
|
45
|
+
- Berkshire Hathaway (CIK: 0001067983) - Warren Buffett
|
|
46
|
+
- Baupost Group (CIK: 0001061768) - Seth Klarman
|
|
47
|
+
- Pershing Square (CIK: 0001336528) - Bill Ackman
|
|
48
|
+
- Appaloosa Management (CIK: 0001079114) - David Tepper
|
|
49
|
+
- Third Point (CIK: 0001040273) - Dan Loeb
|
|
50
|
+
- ARK Investment (CIK: 0001579982) - Cathie Wood
|
|
51
|
+
- Fidelity Management (CIK: 0000315066)
|
|
52
|
+
- T. Rowe Price (CIK: 0001113169)
|
|
53
|
+
- Dodge & Cox (CIK: 0000922614)
|
|
54
|
+
|
|
55
|
+
Alternative Approach:
|
|
56
|
+
-------------------
|
|
57
|
+
If you know the top holdings of an institution, you can use the
|
|
58
|
+
analyze_single_stock.py script to see if they've changed their positions:
|
|
59
|
+
|
|
60
|
+
Example for Berkshire's top holdings:
|
|
61
|
+
python3 analyze_single_stock.py AAPL # Check if Berkshire changed position
|
|
62
|
+
python3 analyze_single_stock.py KO # Coca-Cola
|
|
63
|
+
python3 analyze_single_stock.py BAC # Bank of America
|
|
64
|
+
|
|
65
|
+
================================================================================
|
|
66
|
+
""")
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def main():
|
|
70
|
+
parser = argparse.ArgumentParser(
|
|
71
|
+
description='Track institutional investor portfolio changes (simplified)'
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
parser.add_argument(
|
|
75
|
+
'--cik',
|
|
76
|
+
type=str,
|
|
77
|
+
required=True,
|
|
78
|
+
help='Central Index Key of the institution'
|
|
79
|
+
)
|
|
80
|
+
parser.add_argument(
|
|
81
|
+
'--name',
|
|
82
|
+
type=str,
|
|
83
|
+
required=True,
|
|
84
|
+
help='Institution name'
|
|
85
|
+
)
|
|
86
|
+
parser.add_argument(
|
|
87
|
+
'--api-key',
|
|
88
|
+
type=str,
|
|
89
|
+
default=os.getenv('FMP_API_KEY'),
|
|
90
|
+
help='FMP API key (currently not used in simplified version)'
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
args = parser.parse_args()
|
|
94
|
+
|
|
95
|
+
print(f"Institution: {args.name}")
|
|
96
|
+
print(f"CIK: {args.cik}")
|
|
97
|
+
print()
|
|
98
|
+
print("For detailed portfolio tracking, please use:")
|
|
99
|
+
print(f"1. WhaleWisdom: https://whalewisdom.com/filer/{args.name.lower().replace(' ', '-')}")
|
|
100
|
+
print(f"2. SEC EDGAR: https://www.sec.gov/cgi-bin/browse-edgar?action=getcompany&CIK={args.cik}&type=13F")
|
|
101
|
+
print(f"3. DataRoma: https://www.dataroma.com (if superinvestor)")
|
|
102
|
+
print()
|
|
103
|
+
|
|
104
|
+
return 0
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
if __name__ == '__main__':
|
|
108
|
+
sys.exit(main())
|