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.
Files changed (362) hide show
  1. package/.claude/skills/README.md +80 -0
  2. package/.claude/skills/backtest-expert/SKILL.md +206 -0
  3. package/.claude/skills/backtest-expert/references/failed_tests.md +236 -0
  4. package/.claude/skills/backtest-expert/references/methodology.md +227 -0
  5. package/.claude/skills/breadth-chart-analyst/SKILL.md +583 -0
  6. package/.claude/skills/breadth-chart-analyst/assets/SP500_Breadth_Index_200MA_8MA.jpeg +0 -0
  7. package/.claude/skills/breadth-chart-analyst/assets/US_Stock_Market_Uptrend_Ratio.jpeg +0 -0
  8. package/.claude/skills/breadth-chart-analyst/assets/breadth_analysis_template.md +558 -0
  9. package/.claude/skills/breadth-chart-analyst/references/breadth_chart_methodology.md +590 -0
  10. package/.claude/skills/canslim-screener/SKILL.md +599 -0
  11. package/.claude/skills/canslim-screener/references/canslim_methodology.md +606 -0
  12. package/.claude/skills/canslim-screener/references/fmp_api_endpoints.md +707 -0
  13. package/.claude/skills/canslim-screener/references/interpretation_guide.md +516 -0
  14. package/.claude/skills/canslim-screener/references/scoring_system.md +597 -0
  15. package/.claude/skills/canslim-screener/scripts/calculators/earnings_calculator.py +343 -0
  16. package/.claude/skills/canslim-screener/scripts/calculators/growth_calculator.py +334 -0
  17. package/.claude/skills/canslim-screener/scripts/calculators/institutional_calculator.py +347 -0
  18. package/.claude/skills/canslim-screener/scripts/calculators/leadership_calculator.py +380 -0
  19. package/.claude/skills/canslim-screener/scripts/calculators/market_calculator.py +244 -0
  20. package/.claude/skills/canslim-screener/scripts/calculators/new_highs_calculator.py +194 -0
  21. package/.claude/skills/canslim-screener/scripts/calculators/supply_demand_calculator.py +221 -0
  22. package/.claude/skills/canslim-screener/scripts/finviz_stock_client.py +227 -0
  23. package/.claude/skills/canslim-screener/scripts/fmp_client.py +393 -0
  24. package/.claude/skills/canslim-screener/scripts/report_generator.py +405 -0
  25. package/.claude/skills/canslim-screener/scripts/scorer.py +625 -0
  26. package/.claude/skills/canslim-screener/scripts/screen_canslim.py +361 -0
  27. package/.claude/skills/canslim-screener/scripts/test_institutional_endpoint.py +109 -0
  28. package/.claude/skills/chart/SKILL.md +20 -0
  29. package/.claude/skills/dividend-growth-pullback-screener/SKILL.md +322 -0
  30. package/.claude/skills/dividend-growth-pullback-screener/references/dividend_growth_compounding.md +400 -0
  31. package/.claude/skills/dividend-growth-pullback-screener/references/fmp_api_guide.md +642 -0
  32. package/.claude/skills/dividend-growth-pullback-screener/references/rsi_oversold_strategy.md +333 -0
  33. package/.claude/skills/dividend-growth-pullback-screener/scripts/screen_dividend_growth_rsi.py +1155 -0
  34. package/.claude/skills/earnings-calendar/SKILL.md +721 -0
  35. package/.claude/skills/earnings-calendar/assets/earnings_report_template.md +102 -0
  36. package/.claude/skills/earnings-calendar/references/fmp_api_guide.md +590 -0
  37. package/.claude/skills/earnings-calendar/scripts/fetch_earnings_fmp.py +443 -0
  38. package/.claude/skills/earnings-calendar/scripts/generate_report.py +366 -0
  39. package/.claude/skills/economic-calendar-fetcher/SKILL.md +365 -0
  40. package/.claude/skills/economic-calendar-fetcher/references/fmp_api_documentation.md +345 -0
  41. package/.claude/skills/economic-calendar-fetcher/scripts/get_economic_calendar.py +267 -0
  42. package/.claude/skills/ftd-detector/SKILL.md +147 -0
  43. package/.claude/skills/ftd-detector/references/ftd_methodology.md +188 -0
  44. package/.claude/skills/ftd-detector/references/post_ftd_guide.md +185 -0
  45. package/.claude/skills/ftd-detector/scripts/fmp_client.py +158 -0
  46. package/.claude/skills/ftd-detector/scripts/ftd_detector.py +280 -0
  47. package/.claude/skills/ftd-detector/scripts/post_ftd_monitor.py +404 -0
  48. package/.claude/skills/ftd-detector/scripts/rally_tracker.py +508 -0
  49. package/.claude/skills/ftd-detector/scripts/report_generator.py +341 -0
  50. package/.claude/skills/ftd-detector/scripts/tests/conftest.py +9 -0
  51. package/.claude/skills/ftd-detector/scripts/tests/helpers.py +107 -0
  52. package/.claude/skills/ftd-detector/scripts/tests/test_post_ftd_monitor.py +311 -0
  53. package/.claude/skills/ftd-detector/scripts/tests/test_rally_tracker.py +302 -0
  54. package/.claude/skills/institutional-flow-tracker/README.md +362 -0
  55. package/.claude/skills/institutional-flow-tracker/SKILL.md +357 -0
  56. package/.claude/skills/institutional-flow-tracker/references/13f_filings_guide.md +383 -0
  57. package/.claude/skills/institutional-flow-tracker/references/institutional_investor_types.md +580 -0
  58. package/.claude/skills/institutional-flow-tracker/references/interpretation_framework.md +573 -0
  59. package/.claude/skills/institutional-flow-tracker/scripts/analyze_single_stock.py +457 -0
  60. package/.claude/skills/institutional-flow-tracker/scripts/track_institution_portfolio.py +108 -0
  61. package/.claude/skills/institutional-flow-tracker/scripts/track_institutional_flow.py +450 -0
  62. package/.claude/skills/macro-regime-detector/SKILL.md +86 -0
  63. package/.claude/skills/macro-regime-detector/references/historical_regimes.md +124 -0
  64. package/.claude/skills/macro-regime-detector/references/indicator_interpretation_guide.md +144 -0
  65. package/.claude/skills/macro-regime-detector/references/regime_detection_methodology.md +138 -0
  66. package/.claude/skills/macro-regime-detector/scripts/calculators/__init__.py +1 -0
  67. package/.claude/skills/macro-regime-detector/scripts/calculators/concentration_calculator.py +165 -0
  68. package/.claude/skills/macro-regime-detector/scripts/calculators/credit_conditions_calculator.py +124 -0
  69. package/.claude/skills/macro-regime-detector/scripts/calculators/equity_bond_calculator.py +198 -0
  70. package/.claude/skills/macro-regime-detector/scripts/calculators/sector_rotation_calculator.py +123 -0
  71. package/.claude/skills/macro-regime-detector/scripts/calculators/size_factor_calculator.py +131 -0
  72. package/.claude/skills/macro-regime-detector/scripts/calculators/utils.py +347 -0
  73. package/.claude/skills/macro-regime-detector/scripts/calculators/yield_curve_calculator.py +279 -0
  74. package/.claude/skills/macro-regime-detector/scripts/fmp_client.py +134 -0
  75. package/.claude/skills/macro-regime-detector/scripts/macro_regime_detector.py +278 -0
  76. package/.claude/skills/macro-regime-detector/scripts/report_generator.py +327 -0
  77. package/.claude/skills/macro-regime-detector/scripts/scorer.py +574 -0
  78. package/.claude/skills/macro-regime-detector/scripts/tests/conftest.py +9 -0
  79. package/.claude/skills/macro-regime-detector/scripts/tests/test_concentration.py +78 -0
  80. package/.claude/skills/macro-regime-detector/scripts/tests/test_credit_conditions.py +59 -0
  81. package/.claude/skills/macro-regime-detector/scripts/tests/test_equity_bond.py +74 -0
  82. package/.claude/skills/macro-regime-detector/scripts/tests/test_helpers.py +90 -0
  83. package/.claude/skills/macro-regime-detector/scripts/tests/test_scorer.py +439 -0
  84. package/.claude/skills/macro-regime-detector/scripts/tests/test_sector_rotation.py +78 -0
  85. package/.claude/skills/macro-regime-detector/scripts/tests/test_size_factor.py +59 -0
  86. package/.claude/skills/macro-regime-detector/scripts/tests/test_utils.py +126 -0
  87. package/.claude/skills/macro-regime-detector/scripts/tests/test_yield_curve.py +64 -0
  88. package/.claude/skills/market-breadth-analyzer/SKILL.md +121 -0
  89. package/.claude/skills/market-breadth-analyzer/references/breadth_analysis_methodology.md +168 -0
  90. package/.claude/skills/market-breadth-analyzer/scripts/calculators/__init__.py +1 -0
  91. package/.claude/skills/market-breadth-analyzer/scripts/calculators/bearish_signal_calculator.py +150 -0
  92. package/.claude/skills/market-breadth-analyzer/scripts/calculators/cycle_calculator.py +168 -0
  93. package/.claude/skills/market-breadth-analyzer/scripts/calculators/divergence_calculator.py +119 -0
  94. package/.claude/skills/market-breadth-analyzer/scripts/calculators/historical_context_calculator.py +120 -0
  95. package/.claude/skills/market-breadth-analyzer/scripts/calculators/ma_crossover_calculator.py +115 -0
  96. package/.claude/skills/market-breadth-analyzer/scripts/calculators/trend_level_calculator.py +103 -0
  97. package/.claude/skills/market-breadth-analyzer/scripts/csv_client.py +225 -0
  98. package/.claude/skills/market-breadth-analyzer/scripts/market_breadth_analyzer.py +307 -0
  99. package/.claude/skills/market-breadth-analyzer/scripts/report_generator.py +330 -0
  100. package/.claude/skills/market-breadth-analyzer/scripts/scorer.py +271 -0
  101. package/.claude/skills/market-environment-analysis/SKILL.md +139 -0
  102. package/.claude/skills/market-environment-analysis/references/analysis_patterns.md +124 -0
  103. package/.claude/skills/market-environment-analysis/references/indicators.md +99 -0
  104. package/.claude/skills/market-environment-analysis/scripts/market_utils.py +127 -0
  105. package/.claude/skills/market-news-analyst/SKILL.md +714 -0
  106. package/.claude/skills/market-news-analyst/references/corporate_news_impact.md +446 -0
  107. package/.claude/skills/market-news-analyst/references/geopolitical_commodity_correlations.md +499 -0
  108. package/.claude/skills/market-news-analyst/references/market_event_patterns.md +393 -0
  109. package/.claude/skills/market-news-analyst/references/trusted_news_sources.md +510 -0
  110. package/.claude/skills/market-top-detector/SKILL.md +159 -0
  111. package/.claude/skills/market-top-detector/references/distribution_day_guide.md +100 -0
  112. package/.claude/skills/market-top-detector/references/historical_tops.md +142 -0
  113. package/.claude/skills/market-top-detector/references/market_top_methodology.md +167 -0
  114. package/.claude/skills/market-top-detector/scripts/calculators/__init__.py +17 -0
  115. package/.claude/skills/market-top-detector/scripts/calculators/breadth_calculator.py +116 -0
  116. package/.claude/skills/market-top-detector/scripts/calculators/defensive_rotation_calculator.py +127 -0
  117. package/.claude/skills/market-top-detector/scripts/calculators/distribution_day_calculator.py +161 -0
  118. package/.claude/skills/market-top-detector/scripts/calculators/index_technical_calculator.py +254 -0
  119. package/.claude/skills/market-top-detector/scripts/calculators/leading_stock_calculator.py +198 -0
  120. package/.claude/skills/market-top-detector/scripts/calculators/sentiment_calculator.py +213 -0
  121. package/.claude/skills/market-top-detector/scripts/fmp_client.py +158 -0
  122. package/.claude/skills/market-top-detector/scripts/market_top_detector.py +349 -0
  123. package/.claude/skills/market-top-detector/scripts/report_generator.py +314 -0
  124. package/.claude/skills/market-top-detector/scripts/scorer.py +473 -0
  125. package/.claude/skills/market-top-detector/scripts/tests/conftest.py +9 -0
  126. package/.claude/skills/market-top-detector/scripts/tests/helpers.py +49 -0
  127. package/.claude/skills/market-top-detector/scripts/tests/test_breadth.py +62 -0
  128. package/.claude/skills/market-top-detector/scripts/tests/test_defensive_rotation.py +56 -0
  129. package/.claude/skills/market-top-detector/scripts/tests/test_distribution_day.py +92 -0
  130. package/.claude/skills/market-top-detector/scripts/tests/test_index_technical.py +73 -0
  131. package/.claude/skills/market-top-detector/scripts/tests/test_leading_stock.py +57 -0
  132. package/.claude/skills/market-top-detector/scripts/tests/test_scorer.py +180 -0
  133. package/.claude/skills/market-top-detector/scripts/tests/test_sentiment.py +64 -0
  134. package/.claude/skills/options-strategy-advisor/README.md +469 -0
  135. package/.claude/skills/options-strategy-advisor/SKILL.md +959 -0
  136. package/.claude/skills/options-strategy-advisor/scripts/black_scholes.py +495 -0
  137. package/.claude/skills/pair-trade-screener/README.md +389 -0
  138. package/.claude/skills/pair-trade-screener/SKILL.md +622 -0
  139. package/.claude/skills/pair-trade-screener/references/cointegration_guide.md +745 -0
  140. package/.claude/skills/pair-trade-screener/references/methodology.md +853 -0
  141. package/.claude/skills/pair-trade-screener/scripts/analyze_spread.py +394 -0
  142. package/.claude/skills/pair-trade-screener/scripts/find_pairs.py +535 -0
  143. package/.claude/skills/portfolio-manager/README.md +394 -0
  144. package/.claude/skills/portfolio-manager/SKILL.md +750 -0
  145. package/.claude/skills/portfolio-manager/references/alpaca-mcp-setup.md +367 -0
  146. package/.claude/skills/portfolio-manager/references/asset-allocation.md +502 -0
  147. package/.claude/skills/portfolio-manager/references/diversification-principles.md +553 -0
  148. package/.claude/skills/portfolio-manager/references/portfolio-risk-metrics.md +603 -0
  149. package/.claude/skills/portfolio-manager/references/position-evaluation.md +477 -0
  150. package/.claude/skills/portfolio-manager/references/rebalancing-strategies.md +715 -0
  151. package/.claude/skills/portfolio-manager/references/risk-profile-questionnaire.md +608 -0
  152. package/.claude/skills/portfolio-manager/references/target-allocations.md +558 -0
  153. package/.claude/skills/portfolio-manager/scripts/test_alpaca_connection.py +286 -0
  154. package/.claude/skills/scenario-analyzer/SKILL.md +317 -0
  155. package/.claude/skills/scenario-analyzer/references/headline_event_patterns.md +264 -0
  156. package/.claude/skills/scenario-analyzer/references/scenario_playbooks.md +320 -0
  157. package/.claude/skills/scenario-analyzer/references/sector_sensitivity_matrix.md +217 -0
  158. package/.claude/skills/sector-analyst/SKILL.md +206 -0
  159. package/.claude/skills/sector-analyst/assets/industory_performance_1.jpeg +0 -0
  160. package/.claude/skills/sector-analyst/assets/industory_performance_2.jpeg +0 -0
  161. package/.claude/skills/sector-analyst/assets/sector_performance.jpeg +0 -0
  162. package/.claude/skills/sector-analyst/references/sector_rotation.md +170 -0
  163. package/.claude/skills/stanley-druckenmiller-investment/SKILL.md +84 -0
  164. package/.claude/skills/stanley-druckenmiller-investment/references/case-studies.md +148 -0
  165. package/.claude/skills/stanley-druckenmiller-investment/references/investment-philosophy.md +80 -0
  166. package/.claude/skills/stanley-druckenmiller-investment/references/market-analysis-guide.md +146 -0
  167. package/.claude/skills/stock/NOTION_SETUP.md +33 -0
  168. package/.claude/skills/stock/SKILL.md +38 -0
  169. package/.claude/skills/technical-analyst/SKILL.md +238 -0
  170. package/.claude/skills/technical-analyst/assets/analysis_template.md +183 -0
  171. package/.claude/skills/technical-analyst/references/technical_analysis_framework.md +282 -0
  172. package/.claude/skills/theme-detector/SKILL.md +320 -0
  173. package/.claude/skills/theme-detector/assets/report_template.md +155 -0
  174. package/.claude/skills/theme-detector/references/cross_sector_themes.md +252 -0
  175. package/.claude/skills/theme-detector/references/finviz_industry_codes.md +403 -0
  176. package/.claude/skills/theme-detector/references/thematic_etf_catalog.md +333 -0
  177. package/.claude/skills/theme-detector/references/theme_detection_methodology.md +430 -0
  178. package/.claude/skills/theme-detector/scripts/calculators/__init__.py +1 -0
  179. package/.claude/skills/theme-detector/scripts/calculators/heat_calculator.py +123 -0
  180. package/.claude/skills/theme-detector/scripts/calculators/industry_ranker.py +98 -0
  181. package/.claude/skills/theme-detector/scripts/calculators/lifecycle_calculator.py +172 -0
  182. package/.claude/skills/theme-detector/scripts/calculators/theme_classifier.py +195 -0
  183. package/.claude/skills/theme-detector/scripts/calculators/theme_discoverer.py +280 -0
  184. package/.claude/skills/theme-detector/scripts/config_loader.py +142 -0
  185. package/.claude/skills/theme-detector/scripts/default_theme_config.py +254 -0
  186. package/.claude/skills/theme-detector/scripts/etf_scanner.py +609 -0
  187. package/.claude/skills/theme-detector/scripts/finviz_performance_client.py +131 -0
  188. package/.claude/skills/theme-detector/scripts/report_generator.py +490 -0
  189. package/.claude/skills/theme-detector/scripts/representative_stock_selector.py +673 -0
  190. package/.claude/skills/theme-detector/scripts/scorer.py +87 -0
  191. package/.claude/skills/theme-detector/scripts/tests/README.md +21 -0
  192. package/.claude/skills/theme-detector/scripts/tests/conftest.py +9 -0
  193. package/.claude/skills/theme-detector/scripts/tests/test_config_loader.py +239 -0
  194. package/.claude/skills/theme-detector/scripts/tests/test_etf_scanner.py +810 -0
  195. package/.claude/skills/theme-detector/scripts/tests/test_heat_calculator.py +245 -0
  196. package/.claude/skills/theme-detector/scripts/tests/test_industry_ranker.py +256 -0
  197. package/.claude/skills/theme-detector/scripts/tests/test_lifecycle_calculator.py +301 -0
  198. package/.claude/skills/theme-detector/scripts/tests/test_report_generator.py +624 -0
  199. package/.claude/skills/theme-detector/scripts/tests/test_representative_stock_selector.py +898 -0
  200. package/.claude/skills/theme-detector/scripts/tests/test_scorer.py +185 -0
  201. package/.claude/skills/theme-detector/scripts/tests/test_theme_classifier.py +534 -0
  202. package/.claude/skills/theme-detector/scripts/tests/test_theme_detector_e2e.py +467 -0
  203. package/.claude/skills/theme-detector/scripts/tests/test_theme_discoverer.py +458 -0
  204. package/.claude/skills/theme-detector/scripts/tests/test_uptrend_client.py +76 -0
  205. package/.claude/skills/theme-detector/scripts/theme_detector.py +815 -0
  206. package/.claude/skills/theme-detector/scripts/themes.yaml +168 -0
  207. package/.claude/skills/theme-detector/scripts/uptrend_client.py +241 -0
  208. package/.claude/skills/uptrend-analyzer/SKILL.md +108 -0
  209. package/.claude/skills/uptrend-analyzer/references/uptrend_methodology.md +215 -0
  210. package/.claude/skills/uptrend-analyzer/scripts/calculators/__init__.py +1 -0
  211. package/.claude/skills/uptrend-analyzer/scripts/calculators/historical_context_calculator.py +122 -0
  212. package/.claude/skills/uptrend-analyzer/scripts/calculators/market_breadth_calculator.py +145 -0
  213. package/.claude/skills/uptrend-analyzer/scripts/calculators/momentum_calculator.py +183 -0
  214. package/.claude/skills/uptrend-analyzer/scripts/calculators/sector_participation_calculator.py +204 -0
  215. package/.claude/skills/uptrend-analyzer/scripts/calculators/sector_rotation_calculator.py +218 -0
  216. package/.claude/skills/uptrend-analyzer/scripts/data_fetcher.py +236 -0
  217. package/.claude/skills/uptrend-analyzer/scripts/report_generator.py +329 -0
  218. package/.claude/skills/uptrend-analyzer/scripts/scorer.py +276 -0
  219. package/.claude/skills/uptrend-analyzer/scripts/uptrend_analyzer.py +219 -0
  220. package/.claude/skills/us-market-bubble-detector/CHANGELOG.md +118 -0
  221. package/.claude/skills/us-market-bubble-detector/SKILL.md +545 -0
  222. package/.claude/skills/us-market-bubble-detector/references/bubble_framework.md +335 -0
  223. package/.claude/skills/us-market-bubble-detector/references/historical_cases.md +327 -0
  224. package/.claude/skills/us-market-bubble-detector/references/implementation_guide.md +473 -0
  225. package/.claude/skills/us-market-bubble-detector/references/quick_reference.md +354 -0
  226. package/.claude/skills/us-market-bubble-detector/references/quick_reference_en.md +342 -0
  227. package/.claude/skills/us-market-bubble-detector/scripts/bubble_scorer.py +309 -0
  228. package/.claude/skills/us-stock-analysis/SKILL.md +294 -0
  229. package/.claude/skills/us-stock-analysis/references/financial-metrics.md +172 -0
  230. package/.claude/skills/us-stock-analysis/references/fundamental-analysis.md +129 -0
  231. package/.claude/skills/us-stock-analysis/references/report-template.md +207 -0
  232. package/.claude/skills/us-stock-analysis/references/technical-analysis.md +93 -0
  233. package/.claude/skills/value-dividend-screener/SKILL.md +562 -0
  234. package/.claude/skills/value-dividend-screener/references/fmp_api_guide.md +348 -0
  235. package/.claude/skills/value-dividend-screener/references/screening_methodology.md +315 -0
  236. package/.claude/skills/value-dividend-screener/scripts/screen_dividend_stocks.py +1138 -0
  237. package/.claude/skills/vcp-screener/SKILL.md +79 -0
  238. package/.claude/skills/vcp-screener/references/fmp_api_endpoints.md +45 -0
  239. package/.claude/skills/vcp-screener/references/scoring_system.md +154 -0
  240. package/.claude/skills/vcp-screener/references/vcp_methodology.md +124 -0
  241. package/.claude/skills/vcp-screener/scripts/calculators/__init__.py +1 -0
  242. package/.claude/skills/vcp-screener/scripts/calculators/pivot_proximity_calculator.py +139 -0
  243. package/.claude/skills/vcp-screener/scripts/calculators/relative_strength_calculator.py +161 -0
  244. package/.claude/skills/vcp-screener/scripts/calculators/trend_template_calculator.py +228 -0
  245. package/.claude/skills/vcp-screener/scripts/calculators/vcp_pattern_calculator.py +322 -0
  246. package/.claude/skills/vcp-screener/scripts/calculators/volume_pattern_calculator.py +121 -0
  247. package/.claude/skills/vcp-screener/scripts/fmp_client.py +162 -0
  248. package/.claude/skills/vcp-screener/scripts/report_generator.py +317 -0
  249. package/.claude/skills/vcp-screener/scripts/scorer.py +155 -0
  250. package/.claude/skills/vcp-screener/scripts/screen_vcp.py +536 -0
  251. package/.claude/skills/vcp-screener/scripts/tests/__init__.py +0 -0
  252. package/.claude/skills/vcp-screener/scripts/tests/conftest.py +9 -0
  253. package/.claude/skills/vcp-screener/scripts/tests/test_vcp_screener.py +834 -0
  254. package/.claude/skills/weekly-trade-strategy/.claude/agents/druckenmiller-strategy-planner.md +300 -0
  255. package/.claude/skills/weekly-trade-strategy/.claude/agents/market-news-analyzer.md +239 -0
  256. package/.claude/skills/weekly-trade-strategy/.claude/agents/technical-market-analyst.md +187 -0
  257. package/.claude/skills/weekly-trade-strategy/.claude/agents/us-market-analyst.md +218 -0
  258. package/.claude/skills/weekly-trade-strategy/.claude/agents/weekly-trade-blog-writer.md +318 -0
  259. package/.claude/skills/weekly-trade-strategy/.claude/skills/breadth-chart-analyst/SKILL.md +662 -0
  260. package/.claude/skills/weekly-trade-strategy/.claude/skills/breadth-chart-analyst/assets/SP500_Breadth_Index_200MA_8MA.jpeg +0 -0
  261. package/.claude/skills/weekly-trade-strategy/.claude/skills/breadth-chart-analyst/assets/US_Stock_Market_Uptrend_Ratio.jpeg +0 -0
  262. package/.claude/skills/weekly-trade-strategy/.claude/skills/breadth-chart-analyst/assets/breadth_analysis_template.md +558 -0
  263. package/.claude/skills/weekly-trade-strategy/.claude/skills/breadth-chart-analyst/references/breadth_chart_methodology.md +590 -0
  264. package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/SKILL.md +721 -0
  265. package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/assets/earnings_report_template.md +102 -0
  266. package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/earnings_calendar_2025-11-02.md +447 -0
  267. package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/references/fmp_api_guide.md +590 -0
  268. package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/scripts/fetch_earnings_fmp.py +443 -0
  269. package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/scripts/generate_report.py +366 -0
  270. package/.claude/skills/weekly-trade-strategy/.claude/skills/economic-calendar-fetcher/SKILL.md +365 -0
  271. package/.claude/skills/weekly-trade-strategy/.claude/skills/economic-calendar-fetcher/references/fmp_api_documentation.md +345 -0
  272. package/.claude/skills/weekly-trade-strategy/.claude/skills/economic-calendar-fetcher/scripts/get_economic_calendar.py +267 -0
  273. package/.claude/skills/weekly-trade-strategy/.claude/skills/market-environment-analysis/SKILL.md +139 -0
  274. package/.claude/skills/weekly-trade-strategy/.claude/skills/market-environment-analysis/references/analysis_patterns.md +124 -0
  275. package/.claude/skills/weekly-trade-strategy/.claude/skills/market-environment-analysis/references/indicators.md +99 -0
  276. package/.claude/skills/weekly-trade-strategy/.claude/skills/market-environment-analysis/scripts/market_utils.py +127 -0
  277. package/.claude/skills/weekly-trade-strategy/.claude/skills/market-news-analyst/SKILL.md +714 -0
  278. package/.claude/skills/weekly-trade-strategy/.claude/skills/market-news-analyst/references/corporate_news_impact.md +446 -0
  279. package/.claude/skills/weekly-trade-strategy/.claude/skills/market-news-analyst/references/geopolitical_commodity_correlations.md +499 -0
  280. package/.claude/skills/weekly-trade-strategy/.claude/skills/market-news-analyst/references/market_event_patterns.md +393 -0
  281. package/.claude/skills/weekly-trade-strategy/.claude/skills/market-news-analyst/references/trusted_news_sources.md +510 -0
  282. package/.claude/skills/weekly-trade-strategy/.claude/skills/sector-analyst/SKILL.md +206 -0
  283. package/.claude/skills/weekly-trade-strategy/.claude/skills/sector-analyst/assets/industory_performance_1.jpeg +0 -0
  284. package/.claude/skills/weekly-trade-strategy/.claude/skills/sector-analyst/assets/industory_performance_2.jpeg +0 -0
  285. package/.claude/skills/weekly-trade-strategy/.claude/skills/sector-analyst/assets/sector_performance.jpeg +0 -0
  286. package/.claude/skills/weekly-trade-strategy/.claude/skills/sector-analyst/references/sector_rotation.md +170 -0
  287. package/.claude/skills/weekly-trade-strategy/.claude/skills/stanley-druckenmiller-investment/SKILL.md +84 -0
  288. package/.claude/skills/weekly-trade-strategy/.claude/skills/stanley-druckenmiller-investment/references/case-studies.md +148 -0
  289. package/.claude/skills/weekly-trade-strategy/.claude/skills/stanley-druckenmiller-investment/references/investment-philosophy.md +80 -0
  290. package/.claude/skills/weekly-trade-strategy/.claude/skills/stanley-druckenmiller-investment/references/market-analysis-guide.md +146 -0
  291. package/.claude/skills/weekly-trade-strategy/.claude/skills/technical-analyst/SKILL.md +238 -0
  292. package/.claude/skills/weekly-trade-strategy/.claude/skills/technical-analyst/assets/analysis_template.md +183 -0
  293. package/.claude/skills/weekly-trade-strategy/.claude/skills/technical-analyst/references/technical_analysis_framework.md +282 -0
  294. package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/CHANGELOG.md +118 -0
  295. package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/SKILL.md +545 -0
  296. package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/references/bubble_framework.md +335 -0
  297. package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/references/historical_cases.md +327 -0
  298. package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/references/implementation_guide.md +473 -0
  299. package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/references/quick_reference.md +354 -0
  300. package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/references/quick_reference_en.md +342 -0
  301. package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/scripts/bubble_scorer.py +309 -0
  302. package/.claude/skills/weekly-trade-strategy/.claude/skills/us-stock-analysis/SKILL.md +294 -0
  303. package/.claude/skills/weekly-trade-strategy/.claude/skills/us-stock-analysis/references/financial-metrics.md +172 -0
  304. package/.claude/skills/weekly-trade-strategy/.claude/skills/us-stock-analysis/references/fundamental-analysis.md +129 -0
  305. package/.claude/skills/weekly-trade-strategy/.claude/skills/us-stock-analysis/references/report-template.md +207 -0
  306. package/.claude/skills/weekly-trade-strategy/.claude/skills/us-stock-analysis/references/technical-analysis.md +93 -0
  307. package/.claude/skills/weekly-trade-strategy/CLAUDE.md +454 -0
  308. package/.claude/skills/weekly-trade-strategy/README.md +287 -0
  309. package/.claude/skills/weekly-trade-strategy/blogs/.gitkeep +0 -0
  310. package/.claude/skills/weekly-trade-strategy/charts/.gitkeep +0 -0
  311. package/.claude/skills/weekly-trade-strategy/earnings_data.json +10054 -0
  312. package/.claude/skills/weekly-trade-strategy/skills/breadth-chart-analyst/SKILL.md +662 -0
  313. package/.claude/skills/weekly-trade-strategy/skills/breadth-chart-analyst/assets/SP500_Breadth_Index_200MA_8MA.jpeg +0 -0
  314. package/.claude/skills/weekly-trade-strategy/skills/breadth-chart-analyst/assets/US_Stock_Market_Uptrend_Ratio.jpeg +0 -0
  315. package/.claude/skills/weekly-trade-strategy/skills/breadth-chart-analyst/assets/breadth_analysis_template.md +558 -0
  316. package/.claude/skills/weekly-trade-strategy/skills/breadth-chart-analyst/references/breadth_chart_methodology.md +590 -0
  317. package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/SKILL.md +721 -0
  318. package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/assets/earnings_report_template.md +102 -0
  319. package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/earnings_calendar_2025-11-02.md +447 -0
  320. package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/references/fmp_api_guide.md +590 -0
  321. package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/scripts/fetch_earnings_fmp.py +443 -0
  322. package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/scripts/generate_report.py +366 -0
  323. package/.claude/skills/weekly-trade-strategy/skills/economic-calendar-fetcher/SKILL.md +365 -0
  324. package/.claude/skills/weekly-trade-strategy/skills/economic-calendar-fetcher/references/fmp_api_documentation.md +345 -0
  325. package/.claude/skills/weekly-trade-strategy/skills/economic-calendar-fetcher/scripts/get_economic_calendar.py +267 -0
  326. package/.claude/skills/weekly-trade-strategy/skills/market-environment-analysis/SKILL.md +139 -0
  327. package/.claude/skills/weekly-trade-strategy/skills/market-environment-analysis/references/analysis_patterns.md +124 -0
  328. package/.claude/skills/weekly-trade-strategy/skills/market-environment-analysis/references/indicators.md +99 -0
  329. package/.claude/skills/weekly-trade-strategy/skills/market-environment-analysis/scripts/market_utils.py +127 -0
  330. package/.claude/skills/weekly-trade-strategy/skills/market-news-analyst/SKILL.md +714 -0
  331. package/.claude/skills/weekly-trade-strategy/skills/market-news-analyst/references/corporate_news_impact.md +446 -0
  332. package/.claude/skills/weekly-trade-strategy/skills/market-news-analyst/references/geopolitical_commodity_correlations.md +499 -0
  333. package/.claude/skills/weekly-trade-strategy/skills/market-news-analyst/references/market_event_patterns.md +393 -0
  334. package/.claude/skills/weekly-trade-strategy/skills/market-news-analyst/references/trusted_news_sources.md +510 -0
  335. package/.claude/skills/weekly-trade-strategy/skills/sector-analyst/SKILL.md +206 -0
  336. package/.claude/skills/weekly-trade-strategy/skills/sector-analyst/assets/industory_performance_1.jpeg +0 -0
  337. package/.claude/skills/weekly-trade-strategy/skills/sector-analyst/assets/industory_performance_2.jpeg +0 -0
  338. package/.claude/skills/weekly-trade-strategy/skills/sector-analyst/assets/sector_performance.jpeg +0 -0
  339. package/.claude/skills/weekly-trade-strategy/skills/sector-analyst/references/sector_rotation.md +170 -0
  340. package/.claude/skills/weekly-trade-strategy/skills/stanley-druckenmiller-investment/SKILL.md +84 -0
  341. package/.claude/skills/weekly-trade-strategy/skills/stanley-druckenmiller-investment/references/case-studies.md +148 -0
  342. package/.claude/skills/weekly-trade-strategy/skills/stanley-druckenmiller-investment/references/investment-philosophy.md +80 -0
  343. package/.claude/skills/weekly-trade-strategy/skills/stanley-druckenmiller-investment/references/market-analysis-guide.md +146 -0
  344. package/.claude/skills/weekly-trade-strategy/skills/technical-analyst/SKILL.md +238 -0
  345. package/.claude/skills/weekly-trade-strategy/skills/technical-analyst/assets/analysis_template.md +183 -0
  346. package/.claude/skills/weekly-trade-strategy/skills/technical-analyst/references/technical_analysis_framework.md +282 -0
  347. package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/CHANGELOG.md +118 -0
  348. package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/SKILL.md +545 -0
  349. package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/references/bubble_framework.md +335 -0
  350. package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/references/historical_cases.md +327 -0
  351. package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/references/implementation_guide.md +473 -0
  352. package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/references/quick_reference.md +354 -0
  353. package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/references/quick_reference_en.md +342 -0
  354. package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/scripts/bubble_scorer.py +309 -0
  355. package/.claude/skills/weekly-trade-strategy/skills/us-stock-analysis/SKILL.md +294 -0
  356. package/.claude/skills/weekly-trade-strategy/skills/us-stock-analysis/references/financial-metrics.md +172 -0
  357. package/.claude/skills/weekly-trade-strategy/skills/us-stock-analysis/references/fundamental-analysis.md +129 -0
  358. package/.claude/skills/weekly-trade-strategy/skills/us-stock-analysis/references/report-template.md +207 -0
  359. package/.claude/skills/weekly-trade-strategy/skills/us-stock-analysis/references/technical-analysis.md +93 -0
  360. package/.mcp.json +3 -0
  361. package/cli.mjs +16 -16
  362. package/package.json +4 -2
@@ -0,0 +1,361 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ CANSLIM Stock Screener - Phase 3 (Full CANSLIM)
4
+
5
+ Screens US stocks using William O'Neil's CANSLIM methodology.
6
+ Phase 3 implements all 7 components: C, A, N, S, L, I, M (100% coverage)
7
+
8
+ Usage:
9
+ python3 screen_canslim.py --api-key YOUR_KEY --max-candidates 40
10
+ python3 screen_canslim.py # Uses FMP_API_KEY environment variable
11
+
12
+ Output:
13
+ - JSON: canslim_screener_YYYY-MM-DD_HHMMSS.json
14
+ - Markdown: canslim_screener_YYYY-MM-DD_HHMMSS.md
15
+ """
16
+
17
+ import argparse
18
+ import os
19
+ import sys
20
+ from datetime import datetime
21
+ from typing import Dict, List, Optional
22
+
23
+ # Add calculators directory to path
24
+ sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'calculators'))
25
+
26
+ from fmp_client import FMPClient
27
+ from calculators.earnings_calculator import calculate_quarterly_growth
28
+ from calculators.growth_calculator import calculate_annual_growth
29
+ from calculators.new_highs_calculator import calculate_newness
30
+ from calculators.supply_demand_calculator import calculate_supply_demand
31
+ from calculators.leadership_calculator import calculate_leadership
32
+ from calculators.institutional_calculator import calculate_institutional_sponsorship
33
+ from calculators.market_calculator import calculate_market_direction
34
+ from scorer import (
35
+ calculate_composite_score, check_minimum_thresholds,
36
+ calculate_composite_score_phase2, check_minimum_thresholds_phase2,
37
+ calculate_composite_score_phase3, check_minimum_thresholds_phase3
38
+ )
39
+ from report_generator import generate_json_report, generate_markdown_report
40
+
41
+
42
+ # S&P 500 sample tickers (top 40 by market cap)
43
+ DEFAULT_UNIVERSE = [
44
+ "AAPL", "MSFT", "GOOGL", "AMZN", "NVDA", "META", "TSLA", "BRK.B", "UNH", "JNJ",
45
+ "XOM", "V", "PG", "JPM", "MA", "HD", "CVX", "MRK", "ABBV", "PEP",
46
+ "COST", "AVGO", "KO", "ADBE", "LLY", "TMO", "WMT", "MCD", "CSCO", "ACN",
47
+ "ORCL", "ABT", "NKE", "CRM", "DHR", "VZ", "TXN", "AMD", "QCOM", "INTC"
48
+ ]
49
+
50
+
51
+ def parse_arguments():
52
+ """Parse command line arguments"""
53
+ parser = argparse.ArgumentParser(
54
+ description="CANSLIM Stock Screener - Phase 1 MVP (C, A, N, M components)"
55
+ )
56
+
57
+ parser.add_argument(
58
+ "--api-key",
59
+ help="FMP API key (defaults to FMP_API_KEY environment variable)"
60
+ )
61
+
62
+ parser.add_argument(
63
+ "--max-candidates",
64
+ type=int,
65
+ default=40,
66
+ help="Maximum number of stocks to analyze (default: 40, stays within free tier)"
67
+ )
68
+
69
+ parser.add_argument(
70
+ "--top",
71
+ type=int,
72
+ default=20,
73
+ help="Number of top stocks to include in report (default: 20)"
74
+ )
75
+
76
+ parser.add_argument(
77
+ "--output-dir",
78
+ default=".",
79
+ help="Output directory for reports (default: current directory)"
80
+ )
81
+
82
+ parser.add_argument(
83
+ "--universe",
84
+ nargs="+",
85
+ help="Custom list of stock symbols to screen (overrides default S&P 500)"
86
+ )
87
+
88
+ return parser.parse_args()
89
+
90
+
91
+ def analyze_stock(symbol: str, client: FMPClient, market_data: Dict, sp500_historical: List[Dict] = None) -> Optional[Dict]:
92
+ """
93
+ Analyze a single stock using CANSLIM Phase 3 components (7 components: C, A, N, S, L, I, M)
94
+
95
+ Args:
96
+ symbol: Stock ticker
97
+ client: FMP API client
98
+ market_data: Pre-calculated market direction data
99
+ sp500_historical: S&P 500 historical prices for L component RS calculation
100
+
101
+ Returns:
102
+ Dict with analysis results, or None if analysis failed
103
+ """
104
+ print(f" Analyzing {symbol}...", end=" ", flush=True)
105
+
106
+ try:
107
+ # Get company profile
108
+ profile = client.get_profile(symbol)
109
+ if not profile:
110
+ print("✗ Profile unavailable")
111
+ return None
112
+
113
+ company_name = profile[0].get("companyName", symbol)
114
+ sector = profile[0].get("sector", "Unknown")
115
+ market_cap = profile[0].get("mktCap", 0)
116
+
117
+ # Get quote
118
+ quote = client.get_quote(symbol)
119
+ if not quote:
120
+ print("✗ Quote unavailable")
121
+ return None
122
+
123
+ price = quote[0].get("price", 0)
124
+
125
+ # C Component: Current Quarterly Earnings
126
+ quarterly_income = client.get_income_statement(symbol, period="quarter", limit=8)
127
+ c_result = calculate_quarterly_growth(quarterly_income) if quarterly_income else {
128
+ "score": 0, "error": "No quarterly data"
129
+ }
130
+
131
+ # A Component: Annual Growth
132
+ annual_income = client.get_income_statement(symbol, period="annual", limit=5)
133
+ a_result = calculate_annual_growth(annual_income) if annual_income else {
134
+ "score": 50, "error": "No annual data"
135
+ }
136
+
137
+ # N Component: Newness / New Highs
138
+ n_result = calculate_newness(quote[0])
139
+
140
+ # S Component: Supply/Demand (uses existing historical_prices data - no extra API call)
141
+ historical_prices = client.get_historical_prices(symbol, days=90)
142
+ s_result = calculate_supply_demand(historical_prices) if historical_prices else {
143
+ "score": 0, "error": "No price history data"
144
+ }
145
+
146
+ # L Component: Leadership / Relative Strength (52-week performance vs S&P 500)
147
+ # Use 365-day historical data for full year comparison
148
+ historical_prices_52w_data = client.get_historical_prices(symbol, days=365)
149
+ # Extract 'historical' list from FMP response format
150
+ historical_prices_52w = historical_prices_52w_data.get("historical", []) if historical_prices_52w_data else []
151
+ # Prepare S&P 500 historical list (extract from FMP response format)
152
+ sp500_historical_list = sp500_historical.get("historical", []) if sp500_historical else None
153
+ l_result = calculate_leadership(
154
+ historical_prices_52w,
155
+ sp500_historical=sp500_historical_list
156
+ ) if historical_prices_52w else {
157
+ "score": 0, "error": "No 52-week price history"
158
+ }
159
+
160
+ # I Component: Institutional Sponsorship (with Finviz fallback)
161
+ institutional_holders = client.get_institutional_holders(symbol)
162
+ i_result = calculate_institutional_sponsorship(
163
+ institutional_holders, profile[0], symbol=symbol, use_finviz_fallback=True
164
+ ) if institutional_holders else {
165
+ "score": 0, "error": "No institutional holder data"
166
+ }
167
+
168
+ # M Component: Market Direction (use pre-calculated)
169
+ m_result = market_data
170
+
171
+ # Calculate composite score (Phase 3: 7 components - FULL CANSLIM)
172
+ composite = calculate_composite_score_phase3(
173
+ c_score=c_result.get("score", 0),
174
+ a_score=a_result.get("score", 50),
175
+ n_score=n_result.get("score", 0),
176
+ s_score=s_result.get("score", 0),
177
+ l_score=l_result.get("score", 0),
178
+ i_score=i_result.get("score", 0),
179
+ m_score=m_result.get("score", 50)
180
+ )
181
+
182
+ # Check minimum thresholds (Phase 3)
183
+ threshold_check = check_minimum_thresholds_phase3(
184
+ c_score=c_result.get("score", 0),
185
+ a_score=a_result.get("score", 50),
186
+ n_score=n_result.get("score", 0),
187
+ s_score=s_result.get("score", 0),
188
+ l_score=l_result.get("score", 0),
189
+ i_score=i_result.get("score", 0),
190
+ m_score=m_result.get("score", 50)
191
+ )
192
+
193
+ print(f"✓ Score: {composite['composite_score']:.1f} ({composite['rating']})")
194
+
195
+ return {
196
+ "symbol": symbol,
197
+ "company_name": company_name,
198
+ "sector": sector,
199
+ "price": price,
200
+ "market_cap": market_cap,
201
+ "composite_score": composite["composite_score"],
202
+ "rating": composite["rating"],
203
+ "rating_description": composite["rating_description"],
204
+ "guidance": composite["guidance"],
205
+ "weakest_component": composite["weakest_component"],
206
+ "weakest_score": composite["weakest_score"],
207
+ "c_component": c_result,
208
+ "a_component": a_result,
209
+ "n_component": n_result,
210
+ "s_component": s_result,
211
+ "l_component": l_result, # NEW: Phase 3
212
+ "i_component": i_result,
213
+ "m_component": m_result,
214
+ "threshold_check": threshold_check
215
+ }
216
+
217
+ except Exception as e:
218
+ print(f"✗ Error: {e}")
219
+ return None
220
+
221
+
222
+ def main():
223
+ """Main screening workflow"""
224
+ args = parse_arguments()
225
+
226
+ print("=" * 60)
227
+ print("CANSLIM Stock Screener - Phase 3 (Full CANSLIM)")
228
+ print("Components: C (Earnings), A (Growth), N (Newness), S (Supply/Demand), L (Leadership), I (Institutional), M (Market)")
229
+ print("=" * 60)
230
+ print()
231
+
232
+ # Initialize FMP client
233
+ try:
234
+ client = FMPClient(api_key=args.api_key)
235
+ print("✓ FMP API client initialized")
236
+ except ValueError as e:
237
+ print(f"ERROR: {e}", file=sys.stderr)
238
+ sys.exit(1)
239
+
240
+ # Determine universe
241
+ if args.universe:
242
+ universe = args.universe[:args.max_candidates]
243
+ print(f"✓ Custom universe: {len(universe)} stocks")
244
+ else:
245
+ universe = DEFAULT_UNIVERSE[:args.max_candidates]
246
+ print(f"✓ Default universe (S&P 500 top {len(universe)}): {len(universe)} stocks")
247
+
248
+ print()
249
+
250
+ # Step 1: Calculate market direction (M component) once for all stocks
251
+ print("Step 1: Analyzing Market Direction (M Component)")
252
+ print("-" * 60)
253
+
254
+ sp500_quote = client.get_quote("^GSPC")
255
+ vix_quote = client.get_quote("^VIX")
256
+
257
+ if not sp500_quote:
258
+ print("ERROR: Unable to fetch S&P 500 data", file=sys.stderr)
259
+ sys.exit(1)
260
+
261
+ market_data = calculate_market_direction(
262
+ sp500_quote=sp500_quote[0],
263
+ vix_quote=vix_quote[0] if vix_quote else None
264
+ )
265
+
266
+ print(f"S&P 500: ${market_data['sp500_price']:.2f}")
267
+ print(f"Distance from 50-EMA: {market_data['distance_from_ema_pct']:+.2f}%")
268
+ print(f"Trend: {market_data['trend']}")
269
+ print(f"M Score: {market_data['score']}/100")
270
+ print(f"Interpretation: {market_data['interpretation']}")
271
+
272
+ if market_data.get('warning'):
273
+ print()
274
+ print(f"⚠️ WARNING: {market_data['warning']}")
275
+ print(" Consider raising cash allocation. CANSLIM doesn't work in bear markets.")
276
+
277
+ print()
278
+
279
+ # Fetch S&P 500 historical prices for L component (Relative Strength calculation)
280
+ print("Fetching S&P 500 52-week data for Leadership (L) component...")
281
+ sp500_historical = client.get_historical_prices("SPY", days=365) # Use SPY as S&P 500 proxy
282
+ if sp500_historical and sp500_historical.get("historical"):
283
+ sp500_days = len(sp500_historical.get("historical", []))
284
+ print(f"✓ S&P 500 historical data: {sp500_days} days")
285
+ else:
286
+ print("⚠️ S&P 500 historical data unavailable - L component will use absolute performance")
287
+ print()
288
+
289
+ # Step 2: Progressive filtering and analysis
290
+ print(f"Step 2: Analyzing {len(universe)} Stocks")
291
+ print("-" * 60)
292
+
293
+ results = []
294
+ for symbol in universe:
295
+ analysis = analyze_stock(symbol, client, market_data, sp500_historical)
296
+ if analysis:
297
+ results.append(analysis)
298
+
299
+ print()
300
+ print(f"✓ Successfully analyzed {len(results)} stocks")
301
+ print()
302
+
303
+ # Step 3: Rank by composite score
304
+ print("Step 3: Ranking Results")
305
+ print("-" * 60)
306
+
307
+ results.sort(key=lambda x: x['composite_score'], reverse=True)
308
+
309
+ # Display top 5
310
+ print("Top 5 Stocks:")
311
+ for i, stock in enumerate(results[:5], 1):
312
+ print(f" {i}. {stock['symbol']:6} - {stock['composite_score']:5.1f} ({stock['rating']})")
313
+
314
+ print()
315
+
316
+ # Step 4: Generate reports
317
+ print("Step 4: Generating Reports")
318
+ print("-" * 60)
319
+
320
+ timestamp = datetime.now().strftime("%Y-%m-%d_%H%M%S")
321
+ json_file = os.path.join(args.output_dir, f"canslim_screener_{timestamp}.json")
322
+ md_file = os.path.join(args.output_dir, f"canslim_screener_{timestamp}.md")
323
+
324
+ metadata = {
325
+ "generated_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S UTC"),
326
+ "phase": "3 (7 components - FULL CANSLIM)",
327
+ "components_included": ["C", "A", "N", "S", "L", "I", "M"],
328
+ "candidates_analyzed": len(results),
329
+ "universe_size": len(universe),
330
+ "market_condition": {
331
+ "trend": market_data['trend'],
332
+ "M_score": market_data['score'],
333
+ "warning": market_data.get('warning')
334
+ }
335
+ }
336
+
337
+ # Limit to top N for report
338
+ top_results = results[:args.top]
339
+
340
+ generate_json_report(top_results, metadata, json_file)
341
+ generate_markdown_report(top_results, metadata, md_file)
342
+
343
+ print()
344
+ print("=" * 60)
345
+ print("✓ CANSLIM Screening Complete")
346
+ print("=" * 60)
347
+ print(f" JSON Report: {json_file}")
348
+ print(f" Markdown Report: {md_file}")
349
+ print()
350
+
351
+ # API stats
352
+ api_stats = client.get_api_stats()
353
+ print(f"API Usage:")
354
+ print(f" Cache entries: {api_stats['cache_entries']}")
355
+ print(f" Estimated calls: ~{len(universe) * 6 + 4} (market data + S&P 500 history + {len(universe)} stocks × 6 API calls)")
356
+ print(f" Phase 3 includes all 7 CANSLIM components (C, A, N, S, L, I, M)")
357
+ print()
358
+
359
+
360
+ if __name__ == "__main__":
361
+ main()
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test FMP institutional-holder endpoint availability
4
+ Critical decision point for Phase 2 implementation
5
+ """
6
+
7
+ import os
8
+ import sys
9
+ import requests
10
+
11
+ def test_institutional_endpoint():
12
+ """
13
+ Test if institutional-holder endpoint is available with current API key
14
+
15
+ Returns:
16
+ bool: True if endpoint available (Full Implementation)
17
+ False if endpoint restricted (Fallback Implementation)
18
+ """
19
+ # Get API key
20
+ api_key = os.environ.get('FMP_API_KEY')
21
+
22
+ if not api_key:
23
+ print("ERROR: FMP_API_KEY environment variable not set")
24
+ print("Please set it with: export FMP_API_KEY=your_key")
25
+ return False
26
+
27
+ print(f"Testing institutional-holder endpoint with API key (length: {len(api_key)})...")
28
+ print()
29
+
30
+ # Test institutional-holder endpoint
31
+ test_symbol = "AAPL"
32
+ url = f"https://financialmodelingprep.com/api/v3/institutional-holder/{test_symbol}"
33
+ params = {"apikey": api_key}
34
+
35
+ try:
36
+ response = requests.get(url, params=params, timeout=10)
37
+
38
+ print(f"Status Code: {response.status_code}")
39
+ print(f"Response length: {len(response.text)} bytes")
40
+ print()
41
+
42
+ if response.status_code == 200:
43
+ # Parse JSON
44
+ data = response.json()
45
+
46
+ # Check if it's an error message
47
+ if isinstance(data, dict) and "Error Message" in data:
48
+ print("❌ RESULT: Endpoint RESTRICTED")
49
+ print(f" Error: {data['Error Message']}")
50
+ print()
51
+ print("DECISION: Use Fallback Implementation (Step 3B)")
52
+ print(" - I component will use Profile API institutionalOwnership field only")
53
+ print(" - Score capped at 70/100")
54
+ print(" - Quality warning will be added to all results")
55
+ return False
56
+
57
+ # Check if data is valid
58
+ if isinstance(data, list) and len(data) > 0:
59
+ print("✅ RESULT: Endpoint AVAILABLE")
60
+ print(f" Found {len(data)} institutional holders for {test_symbol}")
61
+ print()
62
+ print("Sample data:")
63
+ for i, holder in enumerate(data[:3]):
64
+ print(f" {i+1}. {holder.get('holder', 'N/A')}: "
65
+ f"{holder.get('shares', 0):,} shares")
66
+ print()
67
+ print("DECISION: Use Full Implementation (Step 3A)")
68
+ print(" - Full institutional analysis with holder count and ownership %")
69
+ print(" - Superinvestor detection")
70
+ print(" - Score range: 0-100")
71
+ return True
72
+ else:
73
+ print("⚠️ RESULT: Unexpected response format")
74
+ print(f" Data type: {type(data)}")
75
+ print(f" Data: {data}")
76
+ print()
77
+ print("DECISION: Use Fallback Implementation (Step 3B) as precaution")
78
+ return False
79
+
80
+ elif response.status_code == 401 or response.status_code == 403:
81
+ print("❌ RESULT: Endpoint RESTRICTED (401/403)")
82
+ print()
83
+ print("DECISION: Use Fallback Implementation (Step 3B)")
84
+ return False
85
+ else:
86
+ print(f"⚠️ RESULT: Unexpected status code {response.status_code}")
87
+ print()
88
+ print("DECISION: Use Fallback Implementation (Step 3B) as precaution")
89
+ return False
90
+
91
+ except requests.exceptions.RequestException as e:
92
+ print(f"❌ ERROR: Request failed - {e}")
93
+ print()
94
+ print("DECISION: Use Fallback Implementation (Step 3B)")
95
+ return False
96
+
97
+
98
+ if __name__ == "__main__":
99
+ print("=" * 70)
100
+ print("FMP Institutional-Holder Endpoint Availability Test")
101
+ print("=" * 70)
102
+ print()
103
+
104
+ result = test_institutional_endpoint()
105
+
106
+ print()
107
+ print("=" * 70)
108
+
109
+ sys.exit(0 if result else 1)
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: chart
3
+ description: "终端K线图。将股票数据渲染为终端candlestick图表。用法: /chart AAPL"
4
+ user-invocable: true
5
+ allowed-tools: [Bash, mcp__stock-analysis__get_stock_quote]
6
+ context: inline
7
+ argument-hint: "股票代码"
8
+ ---
9
+
10
+ ## 终端 K 线图渲染
11
+
12
+ 1. 调用 `mcp__stock-analysis__get_stock_quote` 获取 $ARGUMENTS 的 OHLCV 数据
13
+ 2. 将数据转换为 candlestick-cli JSON 格式:
14
+ ```json
15
+ [{"open": 150.0, "high": 155.0, "low": 149.0, "close": 153.0, "volume": 1000000, "timestamp": 1640995200000, "type": 1}]
16
+ ```
17
+ type: close >= open 则为 1(涨),否则为 0(跌)
18
+ 3. 写入 /tmp/chart_$ARGUMENTS.json
19
+ 4. 执行: `candlestick-cli -f /tmp/chart_$ARGUMENTS.json -t "$ARGUMENTS" --height 25`
20
+ 5. 展示图表输出