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,78 @@
1
+ """Tests for Sector Rotation Calculator (XLY/XLP)"""
2
+
3
+ from calculators.sector_rotation_calculator import calculate_sector_rotation
4
+ from test_helpers import make_monthly_history
5
+
6
+
7
+ class TestCalculateSectorRotation:
8
+ def test_insufficient_data_empty(self):
9
+ result = calculate_sector_rotation([], [])
10
+ assert result["score"] == 0
11
+ assert result["data_available"] is False
12
+
13
+ def test_stable_ratio_low_score(self):
14
+ xly = make_monthly_history([180] * 24, start_year=2024)
15
+ xlp = make_monthly_history([75] * 24, start_year=2024)
16
+ result = calculate_sector_rotation(xly, xlp)
17
+ assert result["data_available"] is True
18
+ assert result["score"] <= 30 # Small noise from daily variation is expected
19
+
20
+ def test_risk_on_rotation(self):
21
+ # XLY rising faster than XLP = risk-on
22
+ xly_closes = [180 + i * 3 for i in range(24)]
23
+ xlp_closes = [75] * 24
24
+ xly = make_monthly_history(xly_closes, start_year=2024)
25
+ xlp = make_monthly_history(xlp_closes, start_year=2024)
26
+ result = calculate_sector_rotation(xly, xlp)
27
+ assert result["data_available"] is True
28
+
29
+ def test_risk_off_rotation(self):
30
+ # XLY falling, XLP rising = risk-off
31
+ xly_closes = [200 - i * 2 for i in range(24)]
32
+ xlp_closes = [70 + i * 2 for i in range(24)]
33
+ xly = make_monthly_history(xly_closes, start_year=2024)
34
+ xlp = make_monthly_history(xlp_closes, start_year=2024)
35
+ result = calculate_sector_rotation(xly, xlp)
36
+ assert result["data_available"] is True
37
+
38
+ def test_output_structure(self):
39
+ xly = make_monthly_history([180 + i for i in range(24)], start_year=2024)
40
+ xlp = make_monthly_history([75] * 24, start_year=2024)
41
+ result = calculate_sector_rotation(xly, xlp)
42
+
43
+ required_keys = [
44
+ "score",
45
+ "signal",
46
+ "data_available",
47
+ "direction",
48
+ "current_ratio",
49
+ "sma_6m",
50
+ "sma_12m",
51
+ "roc_3m",
52
+ "roc_12m",
53
+ "percentile",
54
+ "crossover",
55
+ "monthly_points",
56
+ "momentum_qualifier",
57
+ ]
58
+ for key in required_keys:
59
+ assert key in result
60
+ assert 0 <= result["score"] <= 100
61
+
62
+ def test_stale_crossover_reversal(self):
63
+ """Stale golden cross with declining recent momentum → risk_off + reversing."""
64
+ # Build ratio that crosses up early then declines recently
65
+ # 24 months: rise for first 12, then decline for next 12
66
+ xly_closes = [180 + i * 3 for i in range(12)] + [215 - i * 5 for i in range(12)]
67
+ xlp_closes = [75] * 24
68
+ xly = make_monthly_history(xly_closes, start_year=2024)
69
+ xlp = make_monthly_history(xlp_closes, start_year=2024)
70
+ result = calculate_sector_rotation(xly, xlp)
71
+ # The crossover happened early (stale) and recent momentum is negative
72
+ if (result["crossover"]["type"] == "golden_cross"
73
+ and result["crossover"]["bars_ago"] is not None
74
+ and result["crossover"]["bars_ago"] >= 3
75
+ and result["roc_3m"] is not None
76
+ and result["roc_3m"] < 0):
77
+ assert result["direction"] == "risk_off"
78
+ assert result["momentum_qualifier"] == "reversing"
@@ -0,0 +1,59 @@
1
+ """Tests for Size Factor Calculator (IWM/SPY)"""
2
+
3
+ from calculators.size_factor_calculator import calculate_size_factor
4
+ from test_helpers import make_monthly_history
5
+
6
+
7
+ class TestCalculateSizeFactor:
8
+ def test_insufficient_data_empty(self):
9
+ result = calculate_size_factor([], [])
10
+ assert result["score"] == 0
11
+ assert result["data_available"] is False
12
+
13
+ def test_stable_ratio_low_score(self):
14
+ iwm = make_monthly_history([200] * 24, start_year=2024)
15
+ spy = make_monthly_history([500] * 24, start_year=2024)
16
+ result = calculate_size_factor(iwm, spy)
17
+ assert result["data_available"] is True
18
+ assert result["score"] <= 30 # Small noise from daily variation is expected
19
+
20
+ def test_small_cap_outperformance(self):
21
+ # IWM rising faster = small cap leading
22
+ iwm_closes = [200 + i * 3 for i in range(24)]
23
+ spy_closes = [500 + i * 1 for i in range(24)]
24
+ iwm = make_monthly_history(iwm_closes, start_year=2024)
25
+ spy = make_monthly_history(spy_closes, start_year=2024)
26
+ result = calculate_size_factor(iwm, spy)
27
+ assert result["data_available"] is True
28
+
29
+ def test_large_cap_outperformance(self):
30
+ # SPY rising faster = large cap leading
31
+ iwm_closes = [200 + i * 0.5 for i in range(24)]
32
+ spy_closes = [500 + i * 5 for i in range(24)]
33
+ iwm = make_monthly_history(iwm_closes, start_year=2024)
34
+ spy = make_monthly_history(spy_closes, start_year=2024)
35
+ result = calculate_size_factor(iwm, spy)
36
+ assert result["data_available"] is True
37
+
38
+ def test_output_structure(self):
39
+ iwm = make_monthly_history([200 + i for i in range(24)], start_year=2024)
40
+ spy = make_monthly_history([500] * 24, start_year=2024)
41
+ result = calculate_size_factor(iwm, spy)
42
+
43
+ required_keys = [
44
+ "score",
45
+ "signal",
46
+ "data_available",
47
+ "direction",
48
+ "current_ratio",
49
+ "sma_6m",
50
+ "sma_12m",
51
+ "roc_3m",
52
+ "roc_12m",
53
+ "percentile",
54
+ "crossover",
55
+ "monthly_points",
56
+ ]
57
+ for key in required_keys:
58
+ assert key in result
59
+ assert 0 <= result["score"] <= 100
@@ -0,0 +1,126 @@
1
+ """Tests for determine_direction utility function"""
2
+
3
+ from calculators.utils import determine_direction
4
+
5
+
6
+ class TestDetermineDirection:
7
+ def test_recent_golden_cross_confirmed(self):
8
+ """Recent golden cross with positive ROC → positive label, confirmed."""
9
+ crossover = {"type": "golden_cross", "bars_ago": 1}
10
+ direction, qualifier = determine_direction(
11
+ crossover, roc_3m=5.0,
12
+ positive_label="risk_on", negative_label="risk_off",
13
+ )
14
+ assert direction == "risk_on"
15
+ assert qualifier == "confirmed"
16
+
17
+ def test_recent_death_cross_confirmed(self):
18
+ """Recent death cross with negative ROC → negative label, confirmed."""
19
+ crossover = {"type": "death_cross", "bars_ago": 1}
20
+ direction, qualifier = determine_direction(
21
+ crossover, roc_3m=-3.0,
22
+ positive_label="risk_on", negative_label="risk_off",
23
+ )
24
+ assert direction == "risk_off"
25
+ assert qualifier == "confirmed"
26
+
27
+ def test_stale_golden_cross_reversing(self):
28
+ """5-month-old golden cross with negative ROC → momentum overrides to negative."""
29
+ crossover = {"type": "golden_cross", "bars_ago": 5}
30
+ direction, qualifier = determine_direction(
31
+ crossover, roc_3m=-13.0,
32
+ positive_label="risk_on", negative_label="risk_off",
33
+ )
34
+ assert direction == "risk_off"
35
+ assert qualifier == "reversing"
36
+
37
+ def test_stale_death_cross_reversing(self):
38
+ """Old death cross with positive ROC → momentum overrides to positive."""
39
+ crossover = {"type": "death_cross", "bars_ago": 4}
40
+ direction, qualifier = determine_direction(
41
+ crossover, roc_3m=5.0,
42
+ positive_label="easing", negative_label="tightening",
43
+ )
44
+ assert direction == "easing"
45
+ assert qualifier == "reversing"
46
+
47
+ def test_stale_golden_cross_confirmed(self):
48
+ """Old golden cross but still positive ROC → positive label, confirmed."""
49
+ crossover = {"type": "golden_cross", "bars_ago": 5}
50
+ direction, qualifier = determine_direction(
51
+ crossover, roc_3m=2.0,
52
+ positive_label="risk_on", negative_label="risk_off",
53
+ )
54
+ assert direction == "risk_on"
55
+ assert qualifier == "confirmed"
56
+
57
+ def test_recent_cross_fading(self):
58
+ """Recent golden cross but negative ROC (not stale) → positive, fading."""
59
+ crossover = {"type": "golden_cross", "bars_ago": 1}
60
+ direction, qualifier = determine_direction(
61
+ crossover, roc_3m=-2.0,
62
+ positive_label="risk_on", negative_label="risk_off",
63
+ )
64
+ assert direction == "risk_on"
65
+ assert qualifier == "fading"
66
+
67
+ def test_no_crossover_momentum_only(self):
68
+ """No crossover, positive ROC → positive from momentum."""
69
+ crossover = {"type": "none", "bars_ago": None}
70
+ direction, qualifier = determine_direction(
71
+ crossover, roc_3m=3.0,
72
+ positive_label="small_cap_leading", negative_label="large_cap_leading",
73
+ )
74
+ assert direction == "small_cap_leading"
75
+ assert qualifier == "N/A"
76
+
77
+ def test_no_crossover_no_roc_neutral(self):
78
+ """No crossover, no ROC → neutral."""
79
+ crossover = {"type": "none", "bars_ago": None}
80
+ direction, qualifier = determine_direction(
81
+ crossover, roc_3m=None,
82
+ positive_label="risk_on", negative_label="risk_off",
83
+ neutral_label="neutral",
84
+ )
85
+ assert direction == "neutral"
86
+ assert qualifier == "N/A"
87
+
88
+ def test_converging_with_momentum(self):
89
+ """Converging (not a cross) with positive momentum → positive from momentum."""
90
+ crossover = {"type": "converging", "bars_ago": None}
91
+ direction, qualifier = determine_direction(
92
+ crossover, roc_3m=4.0,
93
+ positive_label="risk_on", negative_label="risk_off",
94
+ )
95
+ assert direction == "risk_on"
96
+ assert qualifier == "N/A"
97
+
98
+ def test_custom_neutral_label(self):
99
+ """Custom neutral label returned when no signals."""
100
+ crossover = {"type": "none", "bars_ago": None}
101
+ direction, qualifier = determine_direction(
102
+ crossover, roc_3m=None,
103
+ positive_label="easing", negative_label="tightening",
104
+ neutral_label="stable",
105
+ )
106
+ assert direction == "stable"
107
+
108
+ def test_stale_threshold_boundary(self):
109
+ """bars_ago == 3 (exactly at threshold) is stale."""
110
+ crossover = {"type": "golden_cross", "bars_ago": 3}
111
+ direction, qualifier = determine_direction(
112
+ crossover, roc_3m=-5.0,
113
+ positive_label="risk_on", negative_label="risk_off",
114
+ )
115
+ assert direction == "risk_off"
116
+ assert qualifier == "reversing"
117
+
118
+ def test_bars_ago_just_below_threshold(self):
119
+ """bars_ago == 2 (below threshold) is NOT stale → recent cross wins."""
120
+ crossover = {"type": "golden_cross", "bars_ago": 2}
121
+ direction, qualifier = determine_direction(
122
+ crossover, roc_3m=-5.0,
123
+ positive_label="risk_on", negative_label="risk_off",
124
+ )
125
+ assert direction == "risk_on"
126
+ assert qualifier == "fading"
@@ -0,0 +1,64 @@
1
+ """Tests for Yield Curve Calculator"""
2
+
3
+ from calculators.yield_curve_calculator import calculate_yield_curve
4
+ from test_helpers import make_monthly_history, make_treasury_rates
5
+
6
+
7
+ class TestCalculateYieldCurve:
8
+ def test_insufficient_data_all_none(self):
9
+ result = calculate_yield_curve(None, None, None)
10
+ assert result["score"] == 0
11
+ assert result["data_available"] is False
12
+
13
+ def test_treasury_api_stable_spread(self):
14
+ # Stable spread = low transition signal
15
+ spreads = [1.0] * 24 # Constant 1% spread
16
+ rates = make_treasury_rates(spreads, start_year=2024)
17
+ result = calculate_yield_curve(treasury_rates=rates)
18
+ assert result["data_available"] is True
19
+ assert result["data_source"] == "treasury_api"
20
+ assert result["score"] <= 30 # Small noise from daily variation is expected
21
+
22
+ def test_treasury_api_steepening(self):
23
+ # Spread increasing from -0.5 to 1.5 = steepening transition
24
+ spreads = [-0.5 + i * (2.0 / 23) for i in range(24)]
25
+ rates = make_treasury_rates(spreads, start_year=2024)
26
+ result = calculate_yield_curve(treasury_rates=rates)
27
+ assert result["data_available"] is True
28
+ assert result["direction"] in ("steepening", "flattening", "stable")
29
+
30
+ def test_treasury_api_inverted(self):
31
+ # Negative spreads
32
+ spreads = [-0.5] * 24
33
+ rates = make_treasury_rates(spreads, start_year=2024)
34
+ result = calculate_yield_curve(treasury_rates=rates)
35
+ assert result["curve_state"] in (
36
+ "inverted",
37
+ "deeply_inverted",
38
+ "flat",
39
+ "normalizing",
40
+ "normal",
41
+ "steep",
42
+ )
43
+
44
+ def test_shy_tlt_fallback(self):
45
+ # When no treasury rates, use SHY/TLT proxy
46
+ shy = make_monthly_history([80 + i * 0.1 for i in range(24)], start_year=2024)
47
+ tlt = make_monthly_history([90 - i * 0.2 for i in range(24)], start_year=2024)
48
+ result = calculate_yield_curve(treasury_rates=None, shy_history=shy, tlt_history=tlt)
49
+ assert result["data_available"] is True
50
+ assert result["data_source"] == "shy_tlt_proxy"
51
+
52
+ def test_output_structure(self):
53
+ spreads = [1.0 + i * 0.05 for i in range(24)]
54
+ rates = make_treasury_rates(spreads, start_year=2024)
55
+ result = calculate_yield_curve(treasury_rates=rates)
56
+
57
+ assert "score" in result
58
+ assert "signal" in result
59
+ assert "data_available" in result
60
+ assert "data_source" in result
61
+ assert "direction" in result
62
+ assert "curve_state" in result
63
+ assert "crossover" in result
64
+ assert 0 <= result["score"] <= 100
@@ -0,0 +1,121 @@
1
+ ---
2
+ name: market-breadth-analyzer
3
+ description: 使用TraderMonty的公开CSV数据量化市场广度健康状况。生成0-100的综合评分,涵盖6个维度(100 = 健康)。无需API密钥。当用户询问市场广度、参与率、涨跌线健康状况、上涨是否广泛,或整体市场健康评估时使用。
4
+ ---
5
+
6
+ # 市场广度分析器技能
7
+
8
+ ## 目的
9
+
10
+ 使用数据驱动的6维度评分系统(0-100)量化市场广度健康状况。利用TraderMonty公开可用的CSV数据,衡量市场在上涨或下跌中的参与广度。
11
+
12
+ **评分方向:** 100 = 最大健康度(广泛参与),0 = 严重虚弱。
13
+
14
+ **无需API密钥** - 使用GitHub Pages上免费提供的CSV数据。
15
+
16
+ ## 何时使用本技能
17
+
18
+ **英文:**
19
+ - User asks "Is the market rally broad-based?" or "How healthy is market breadth?"
20
+ - User wants to assess market participation rate
21
+ - User asks about advance-decline indicators or breadth thrust
22
+ - User wants to know if the market is narrowing (fewer stocks participating)
23
+ - User asks about equity exposure levels based on breadth conditions
24
+
25
+ **中文:**
26
+ - "市场广度怎么样?""市场参与率如何?"
27
+ - "上涨范围广泛吗?""是不是只有少数股票在涨?"
28
+ - 基于广度指标判断仓位水平
29
+ - 希望用数据确认市场健康度
30
+
31
+ ## 与Breadth Chart Analyst的区别
32
+
33
+ | 方面 | Market Breadth Analyzer | Breadth Chart Analyst |
34
+ |------|------------------------|----------------------|
35
+ | 数据来源 | CSV(自动化) | 图表图像(手动) |
36
+ | 需要API | 无 | 无 |
37
+ | 输出 | 定量0-100评分 | 定性图表分析 |
38
+ | 维度 | 6个评分维度 | 视觉模式识别 |
39
+ | 可重复性 | 完全可重现 | 依赖分析师 |
40
+
41
+ ---
42
+
43
+ ## 执行工作流
44
+
45
+ ### 第一阶段:执行Python脚本
46
+
47
+ 运行分析脚本:
48
+
49
+ ```bash
50
+ python3 skills/market-breadth-analyzer/scripts/market_breadth_analyzer.py \
51
+ --detail-url "https://tradermonty.github.io/market-breadth-analysis/market_breadth_data.csv" \
52
+ --summary-url "https://tradermonty.github.io/market-breadth-analysis/market_breadth_summary.csv"
53
+ ```
54
+
55
+ 脚本将执行以下操作:
56
+ 1. 获取详细CSV(约2,500行,2016年至今)和摘要CSV(8项指标)
57
+ 2. 验证数据时效性(若超过5天则发出警告)
58
+ 3. 计算所有6个维度的评分
59
+ 4. 生成综合评分及区域分类
60
+ 5. 输出JSON和Markdown报告
61
+
62
+ ### 第二阶段:展示结果
63
+
64
+ 向用户展示生成的Markdown报告,重点说明:
65
+ - 综合评分和健康区域
66
+ - 最强和最弱的维度
67
+ - 建议的股票仓位水平
68
+ - 需要关注的关键广度水平
69
+ - 任何数据时效性警告
70
+
71
+ ---
72
+
73
+ ## 6维度评分系统
74
+
75
+ | # | 维度 | 权重 | 关键信号 |
76
+ |---|------|------|----------|
77
+ | 1 | 广度水平与趋势 | **25%** | 当前8MA水平 + 200MA趋势方向 |
78
+ | 2 | 8MA与200MA交叉 | **20%** | 通过MA差距和方向判断动量 |
79
+ | 3 | 峰谷周期 | **20%** | 在广度周期中的位置 |
80
+ | 4 | 看跌信号 | **15%** | 经回测验证的看跌信号标志 |
81
+ | 5 | 历史百分位 | **10%** | 当前值与完整历史分布的对比 |
82
+ | 6 | S&P 500背离 | **10%** | 价格与广度的方向一致性 |
83
+
84
+ ## 健康区域映射(100 = 健康)
85
+
86
+ | 评分 | 区域 | 股票仓位 | 行动 |
87
+ |------|------|----------|------|
88
+ | 80-100 | 强劲 | 90-100% | 满仓操作,偏向成长/动量 |
89
+ | 60-79 | 健康 | 75-90% | 正常操作 |
90
+ | 40-59 | 中性 | 60-75% | 精选持仓,收紧止损 |
91
+ | 20-39 | 转弱 | 40-60% | 获利了结,增加现金 |
92
+ | 0-19 | 危急 | 25-40% | 保存资本,关注谷底 |
93
+
94
+ ---
95
+
96
+ ## 数据来源
97
+
98
+ **详细CSV:** `market_breadth_data.csv`
99
+ - 约2,500行,从2016年2月至今
100
+ - 列:Date, S&P500_Price, Breadth_Index_Raw, Breadth_Index_200MA, Breadth_Index_8MA, Breadth_200MA_Trend, Bearish_Signal, Is_Peak, Is_Trough, Is_Trough_8MA_Below_04
101
+
102
+ **摘要CSV:** `market_breadth_summary.csv`
103
+ - 8项汇总指标(平均峰值、平均谷底、计数、分析期间)
104
+
105
+ 两者均托管在GitHub Pages上——无需认证。
106
+
107
+ ## 输出文件
108
+
109
+ - JSON: `market_breadth_YYYY-MM-DD_HHMMSS.json`
110
+ - Markdown: `market_breadth_YYYY-MM-DD_HHMMSS.md`
111
+
112
+ ## 参考文档
113
+
114
+ ### `references/breadth_analysis_methodology.md`
115
+ - 包含维度评分细节的完整方法论
116
+ - 阈值说明和区域定义
117
+ - 历史背景和解读指南
118
+
119
+ ### 何时加载参考文档
120
+ - **首次使用:** 加载方法论参考文档以理解框架
121
+ - **常规执行:** 无需参考文档——脚本会处理评分
@@ -0,0 +1,168 @@
1
+ # Market Breadth Analysis Methodology
2
+
3
+ ## Overview
4
+
5
+ Market breadth measures the degree of participation in a market move. A healthy advance is characterized by broad participation (many stocks rising), while a narrowing market (fewer stocks leading) often precedes corrections.
6
+
7
+ This methodology uses TraderMonty's breadth dataset to quantify market health across 6 dimensions, producing a composite score from 0 (critical) to 100 (maximum health).
8
+
9
+ ---
10
+
11
+ ## Data Description
12
+
13
+ ### Breadth Index
14
+ The breadth index (0-1) measures the proportion of S&P 500 stocks trading above their 200-day moving average. Key derivatives:
15
+ - **Raw:** Daily breadth value (percentage of stocks above 200DMA)
16
+ - **8-day EMA (8MA):** Short-term exponentially weighted moving average (fast signal)
17
+ - **200-day EMA (200MA):** Long-term exponentially weighted moving average (trend filter)
18
+
19
+ **Important:** Both moving averages use **EMA** (Exponential Moving Average), not SMA. The source repository calculates them as `ewm(span=N, adjust=False)`. EMA gives more weight to recent data points, making it more responsive to changes than SMA.
20
+
21
+ ### Key Thresholds
22
+ | Level | Interpretation |
23
+ |-------|---------------|
24
+ | 8MA > 0.70 | Very strong breadth - broad rally |
25
+ | 8MA > 0.60 | Healthy breadth - above average participation |
26
+ | 8MA > 0.50 | Neutral - about half of stocks participating |
27
+ | 8MA > 0.40 | Weakening - below average participation |
28
+ | 8MA < 0.40 | Extreme weakness - potential trough formation |
29
+ | 8MA < 0.20 | Crisis levels - rare, precedes major bottoms |
30
+
31
+ ### Signal Flags
32
+ - **Breadth_200MA_Trend:** 1 = 200MA rising (bullish regime), -1 = 200MA falling (bearish regime). Uses hysteresis with threshold=0.001 to prevent whipsaw signals.
33
+ - **Bearish_Signal:** Backtested signal combining trend and momentum deterioration
34
+ - **Is_Peak / Is_Trough:** Cyclical turning points detected using `scipy.signal.find_peaks` with `distance=50, prominence=0.015` on the 200MA. This ensures at least 50 trading days (~10 weeks) between consecutive peaks/troughs and a minimum prominence of 0.015.
35
+ - **Is_Trough_8MA_Below_04:** Extreme trough marker detected with `prominence=0.02` on inverted 8MA values below 0.4.
36
+
37
+ ### Pink Zone (Bearish Region)
38
+ The source repository's charts use a pink background to highlight the most dangerous market condition:
39
+
40
+ ```
41
+ Pink Zone = (Breadth_200MA_Trend == -1) AND (8MA < 200MA)
42
+ ```
43
+
44
+ This means the long-term trend is declining AND the short-term breadth has fallen below the long-term average. Historically, markets in the Pink Zone experience elevated volatility and downside risk. The Pink Zone is distinct from the Bearish_Signal flag - it is a structural condition that can persist for weeks or months.
45
+
46
+ ---
47
+
48
+ ## Component Details
49
+
50
+ ### C1: Current Breadth Level & Trend (25%)
51
+
52
+ **Rationale:** The most direct measure of current market health. Higher 8MA means more stocks participating; uptrend in 200MA means the long-term structure is supportive.
53
+
54
+ **Weighting within component:**
55
+ - 8MA Level: 70% - immediate health snapshot
56
+ - 200MA Trend: 30% - longer-term regime confirmation
57
+
58
+ **Key insight:** An 8MA of 0.65 in an uptrend (score ~80) is healthier than 0.65 in a downtrend (score ~62), because the downtrend context suggests the level may be transient.
59
+
60
+ ### C2: 8MA vs 200MA Crossover Dynamics (20%)
61
+
62
+ **Rationale:** The gap between fast and slow MAs reveals momentum. A wide positive gap means breadth is accelerating above trend; a negative gap means it's deteriorating below trend.
63
+
64
+ **Direction modifier:** When the 8MA is recovering (rising) while still below the 200MA, this early recovery signal adds +10. Conversely, when 8MA is falling while still above 200MA, this early deterioration signal subtracts -10.
65
+
66
+ **Key insight:** The crossover point (8MA crossing 200MA) is a significant signal. Bull markets maintain 8MA above 200MA; bear phases see 8MA below 200MA.
67
+
68
+ ### C3: Peak/Trough Cycle Position (20%)
69
+
70
+ **Rationale:** Breadth moves in cycles. Knowing whether we are in the early, middle, or late phase of a cycle helps calibrate expectations.
71
+
72
+ **Cycle phases:**
73
+ 1. **Trough → Early Recovery (0-20 days):** Highest potential for upside if 8MA is rising
74
+ 2. **Sustained Recovery (21-60 days):** Confirmed recovery with decreasing upside magnitude
75
+ 3. **Mature Recovery (60+ days):** Late-cycle, watch for next peak
76
+ 4. **Post-Peak Decline (0-20 days):** Highest risk period
77
+ 5. **Sustained Decline (21-60 days):** Deep correction territory
78
+ 6. **Prolonged Decline (60+ days):** Potential bottom formation if 8MA starts rising
79
+
80
+ **Extreme trough bonus:** When 8MA drops below 0.4 at a trough, history shows these are often excellent long-term entry points, warranting a +10 bonus.
81
+
82
+ ### C4: Bearish Signal Status (15%)
83
+
84
+ **Rationale:** The dataset includes a backtested bearish signal flag that combines multiple factors. Its value depends on context.
85
+
86
+ **Interpretation matrix:**
87
+ | Signal | Trend | Score | Meaning |
88
+ |--------|-------|-------|---------|
89
+ | Off | Up | 85 | All clear - no concerns |
90
+ | Off | Down | 50 | No immediate danger but bearish backdrop |
91
+ | On | Up | 30 | Warning in otherwise bullish environment |
92
+ | On | Down | 10 | Full bearish alignment |
93
+
94
+ **Context matters:** A bearish signal when 8MA is above 0.50 is less concerning (+15 adjustment) than one when 8MA is below 0.25 (-5 adjustment).
95
+
96
+ **Pink Zone integration:** When in the Pink Zone (200MA downtrend + 8MA below 200MA) but without an active bearish signal, a -10 penalty is applied to reflect structural weakness that the bearish flag alone may not capture.
97
+
98
+ ### C5: Historical Percentile (10%)
99
+
100
+ **Rationale:** Knowing where current breadth stands relative to the full 10-year history provides framing. Is this level normal, unusually high, or unusually low?
101
+
102
+ **Overheated/oversold adjustments:** When current 8MA approaches the average peak level, a -10 penalty reflects elevated risk of mean reversion. When near the average trough level, a +10 bonus reflects contrarian opportunity.
103
+
104
+ ### C6: S&P 500 vs Breadth Divergence (10%)
105
+
106
+ **Rationale:** The most dangerous market condition is when the index makes new highs but breadth is declining (fewer stocks participating). This divergence preceded major tops in 2000, 2007, and 2021.
107
+
108
+ **Key patterns:**
109
+ - **S&P up + Breadth up:** Healthy, sustainable rally (70)
110
+ - **S&P up + Breadth down:** Dangerous narrow market (10-25)
111
+ - **S&P down + Breadth up:** Bullish divergence, potential bottom (65-80)
112
+ - **S&P down + Breadth down:** Consistent decline, wait for stabilization (30)
113
+
114
+ ---
115
+
116
+ ## Composite Score Interpretation
117
+
118
+ ### Zone Thresholds
119
+
120
+ | Score | Zone | Exposure | Key Actions |
121
+ |-------|------|----------|-------------|
122
+ | 80-100 | **Strong** | 90-100% | Full position sizing; growth/momentum strategies; wide stops |
123
+ | 60-79 | **Healthy** | 75-90% | Normal operations; standard risk management |
124
+ | 40-59 | **Neutral** | 60-75% | Selective; tighter stops; avoid speculative names |
125
+ | 20-39 | **Weakening** | 40-60% | Profit-taking; raise cash; defensive rotation |
126
+ | 0-19 | **Critical** | 25-40% | Capital preservation; hedging; watch for trough |
127
+
128
+ ### Cross-Referencing with Other Skills
129
+
130
+ - **Market Top Detector:** If breadth is Weakening (20-39) AND top detector is Orange/Red, this is strong confirmation of topping conditions.
131
+ - **CANSLIM Screener:** In Strong/Healthy zones, CANSLIM stock selections have higher success rates.
132
+ - **Sector Analyst:** Weakening breadth often coincides with rotation from offensive to defensive sectors.
133
+
134
+ ---
135
+
136
+ ## Historical Context
137
+
138
+ ### Average Values (from Summary CSV)
139
+ - **Average Peak (200MA):** ~0.729 - breadth cycles typically top around this level
140
+ - **Average Trough (8MA < 0.4):** ~0.232 - extreme troughs average around this level
141
+ - **Peak Count:** ~5 over 10 years (roughly every 2 years)
142
+ - **Trough Count:** ~10 extreme troughs (roughly twice per year on average)
143
+
144
+ ### Notable Historical Patterns
145
+ - **COVID-19 (March 2020):** 8MA crashed to extreme lows, followed by one of the sharpest breadth recoveries in history
146
+ - **2022 Bear Market:** Sustained period of 8MA below 200MA with multiple bearish signals
147
+ - **2023 Recovery:** Gradual breadth improvement with 8MA crossing above 200MA
148
+
149
+ ---
150
+
151
+ ## Live Resources
152
+
153
+ - **Interactive Dashboard:** https://tradermonty.github.io/market-breadth-analysis/
154
+ - **Data CSV:** https://tradermonty.github.io/market-breadth-analysis/market_breadth_data.csv
155
+ - **Summary CSV:** https://tradermonty.github.io/market-breadth-analysis/market_breadth_summary.csv
156
+ - **Source Repository:** https://github.com/tradermonty/market-breadth-analysis
157
+
158
+ Data is automatically updated twice daily via GitHub Actions. CSV files are freely accessible without API keys.
159
+
160
+ ---
161
+
162
+ ## Limitations
163
+
164
+ 1. **Lagging indicator:** Breadth data reflects what has happened, not what will happen. Use alongside forward-looking indicators.
165
+ 2. **No sector granularity:** The breadth index is market-wide. A few large sectors can dominate the reading.
166
+ 3. **CSV update frequency:** Data depends on TraderMonty's update schedule. Check data freshness before analysis.
167
+ 4. **Single market:** Covers S&P 500 only. Does not reflect international markets, small caps, or other asset classes.
168
+ 5. **No volume context:** The breadth index is price-based and does not incorporate volume data.
@@ -0,0 +1 @@
1
+ # Market Breadth Analyzer - Calculator modules