quantwise 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/README.md +80 -0
- package/.claude/skills/backtest-expert/SKILL.md +206 -0
- package/.claude/skills/backtest-expert/references/failed_tests.md +236 -0
- package/.claude/skills/backtest-expert/references/methodology.md +227 -0
- package/.claude/skills/breadth-chart-analyst/SKILL.md +583 -0
- package/.claude/skills/breadth-chart-analyst/assets/SP500_Breadth_Index_200MA_8MA.jpeg +0 -0
- package/.claude/skills/breadth-chart-analyst/assets/US_Stock_Market_Uptrend_Ratio.jpeg +0 -0
- package/.claude/skills/breadth-chart-analyst/assets/breadth_analysis_template.md +558 -0
- package/.claude/skills/breadth-chart-analyst/references/breadth_chart_methodology.md +590 -0
- package/.claude/skills/canslim-screener/SKILL.md +599 -0
- package/.claude/skills/canslim-screener/references/canslim_methodology.md +606 -0
- package/.claude/skills/canslim-screener/references/fmp_api_endpoints.md +707 -0
- package/.claude/skills/canslim-screener/references/interpretation_guide.md +516 -0
- package/.claude/skills/canslim-screener/references/scoring_system.md +597 -0
- package/.claude/skills/canslim-screener/scripts/calculators/earnings_calculator.py +343 -0
- package/.claude/skills/canslim-screener/scripts/calculators/growth_calculator.py +334 -0
- package/.claude/skills/canslim-screener/scripts/calculators/institutional_calculator.py +347 -0
- package/.claude/skills/canslim-screener/scripts/calculators/leadership_calculator.py +380 -0
- package/.claude/skills/canslim-screener/scripts/calculators/market_calculator.py +244 -0
- package/.claude/skills/canslim-screener/scripts/calculators/new_highs_calculator.py +194 -0
- package/.claude/skills/canslim-screener/scripts/calculators/supply_demand_calculator.py +221 -0
- package/.claude/skills/canslim-screener/scripts/finviz_stock_client.py +227 -0
- package/.claude/skills/canslim-screener/scripts/fmp_client.py +393 -0
- package/.claude/skills/canslim-screener/scripts/report_generator.py +405 -0
- package/.claude/skills/canslim-screener/scripts/scorer.py +625 -0
- package/.claude/skills/canslim-screener/scripts/screen_canslim.py +361 -0
- package/.claude/skills/canslim-screener/scripts/test_institutional_endpoint.py +109 -0
- package/.claude/skills/chart/SKILL.md +20 -0
- package/.claude/skills/dividend-growth-pullback-screener/SKILL.md +322 -0
- package/.claude/skills/dividend-growth-pullback-screener/references/dividend_growth_compounding.md +400 -0
- package/.claude/skills/dividend-growth-pullback-screener/references/fmp_api_guide.md +642 -0
- package/.claude/skills/dividend-growth-pullback-screener/references/rsi_oversold_strategy.md +333 -0
- package/.claude/skills/dividend-growth-pullback-screener/scripts/screen_dividend_growth_rsi.py +1155 -0
- package/.claude/skills/earnings-calendar/SKILL.md +721 -0
- package/.claude/skills/earnings-calendar/assets/earnings_report_template.md +102 -0
- package/.claude/skills/earnings-calendar/references/fmp_api_guide.md +590 -0
- package/.claude/skills/earnings-calendar/scripts/fetch_earnings_fmp.py +443 -0
- package/.claude/skills/earnings-calendar/scripts/generate_report.py +366 -0
- package/.claude/skills/economic-calendar-fetcher/SKILL.md +365 -0
- package/.claude/skills/economic-calendar-fetcher/references/fmp_api_documentation.md +345 -0
- package/.claude/skills/economic-calendar-fetcher/scripts/get_economic_calendar.py +267 -0
- package/.claude/skills/ftd-detector/SKILL.md +147 -0
- package/.claude/skills/ftd-detector/references/ftd_methodology.md +188 -0
- package/.claude/skills/ftd-detector/references/post_ftd_guide.md +185 -0
- package/.claude/skills/ftd-detector/scripts/fmp_client.py +158 -0
- package/.claude/skills/ftd-detector/scripts/ftd_detector.py +280 -0
- package/.claude/skills/ftd-detector/scripts/post_ftd_monitor.py +404 -0
- package/.claude/skills/ftd-detector/scripts/rally_tracker.py +508 -0
- package/.claude/skills/ftd-detector/scripts/report_generator.py +341 -0
- package/.claude/skills/ftd-detector/scripts/tests/conftest.py +9 -0
- package/.claude/skills/ftd-detector/scripts/tests/helpers.py +107 -0
- package/.claude/skills/ftd-detector/scripts/tests/test_post_ftd_monitor.py +311 -0
- package/.claude/skills/ftd-detector/scripts/tests/test_rally_tracker.py +302 -0
- package/.claude/skills/institutional-flow-tracker/README.md +362 -0
- package/.claude/skills/institutional-flow-tracker/SKILL.md +357 -0
- package/.claude/skills/institutional-flow-tracker/references/13f_filings_guide.md +383 -0
- package/.claude/skills/institutional-flow-tracker/references/institutional_investor_types.md +580 -0
- package/.claude/skills/institutional-flow-tracker/references/interpretation_framework.md +573 -0
- package/.claude/skills/institutional-flow-tracker/scripts/analyze_single_stock.py +457 -0
- package/.claude/skills/institutional-flow-tracker/scripts/track_institution_portfolio.py +108 -0
- package/.claude/skills/institutional-flow-tracker/scripts/track_institutional_flow.py +450 -0
- package/.claude/skills/macro-regime-detector/SKILL.md +86 -0
- package/.claude/skills/macro-regime-detector/references/historical_regimes.md +124 -0
- package/.claude/skills/macro-regime-detector/references/indicator_interpretation_guide.md +144 -0
- package/.claude/skills/macro-regime-detector/references/regime_detection_methodology.md +138 -0
- package/.claude/skills/macro-regime-detector/scripts/calculators/__init__.py +1 -0
- package/.claude/skills/macro-regime-detector/scripts/calculators/concentration_calculator.py +165 -0
- package/.claude/skills/macro-regime-detector/scripts/calculators/credit_conditions_calculator.py +124 -0
- package/.claude/skills/macro-regime-detector/scripts/calculators/equity_bond_calculator.py +198 -0
- package/.claude/skills/macro-regime-detector/scripts/calculators/sector_rotation_calculator.py +123 -0
- package/.claude/skills/macro-regime-detector/scripts/calculators/size_factor_calculator.py +131 -0
- package/.claude/skills/macro-regime-detector/scripts/calculators/utils.py +347 -0
- package/.claude/skills/macro-regime-detector/scripts/calculators/yield_curve_calculator.py +279 -0
- package/.claude/skills/macro-regime-detector/scripts/fmp_client.py +134 -0
- package/.claude/skills/macro-regime-detector/scripts/macro_regime_detector.py +278 -0
- package/.claude/skills/macro-regime-detector/scripts/report_generator.py +327 -0
- package/.claude/skills/macro-regime-detector/scripts/scorer.py +574 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/conftest.py +9 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_concentration.py +78 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_credit_conditions.py +59 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_equity_bond.py +74 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_helpers.py +90 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_scorer.py +439 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_sector_rotation.py +78 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_size_factor.py +59 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_utils.py +126 -0
- package/.claude/skills/macro-regime-detector/scripts/tests/test_yield_curve.py +64 -0
- package/.claude/skills/market-breadth-analyzer/SKILL.md +121 -0
- package/.claude/skills/market-breadth-analyzer/references/breadth_analysis_methodology.md +168 -0
- package/.claude/skills/market-breadth-analyzer/scripts/calculators/__init__.py +1 -0
- package/.claude/skills/market-breadth-analyzer/scripts/calculators/bearish_signal_calculator.py +150 -0
- package/.claude/skills/market-breadth-analyzer/scripts/calculators/cycle_calculator.py +168 -0
- package/.claude/skills/market-breadth-analyzer/scripts/calculators/divergence_calculator.py +119 -0
- package/.claude/skills/market-breadth-analyzer/scripts/calculators/historical_context_calculator.py +120 -0
- package/.claude/skills/market-breadth-analyzer/scripts/calculators/ma_crossover_calculator.py +115 -0
- package/.claude/skills/market-breadth-analyzer/scripts/calculators/trend_level_calculator.py +103 -0
- package/.claude/skills/market-breadth-analyzer/scripts/csv_client.py +225 -0
- package/.claude/skills/market-breadth-analyzer/scripts/market_breadth_analyzer.py +307 -0
- package/.claude/skills/market-breadth-analyzer/scripts/report_generator.py +330 -0
- package/.claude/skills/market-breadth-analyzer/scripts/scorer.py +271 -0
- package/.claude/skills/market-environment-analysis/SKILL.md +139 -0
- package/.claude/skills/market-environment-analysis/references/analysis_patterns.md +124 -0
- package/.claude/skills/market-environment-analysis/references/indicators.md +99 -0
- package/.claude/skills/market-environment-analysis/scripts/market_utils.py +127 -0
- package/.claude/skills/market-news-analyst/SKILL.md +714 -0
- package/.claude/skills/market-news-analyst/references/corporate_news_impact.md +446 -0
- package/.claude/skills/market-news-analyst/references/geopolitical_commodity_correlations.md +499 -0
- package/.claude/skills/market-news-analyst/references/market_event_patterns.md +393 -0
- package/.claude/skills/market-news-analyst/references/trusted_news_sources.md +510 -0
- package/.claude/skills/market-top-detector/SKILL.md +159 -0
- package/.claude/skills/market-top-detector/references/distribution_day_guide.md +100 -0
- package/.claude/skills/market-top-detector/references/historical_tops.md +142 -0
- package/.claude/skills/market-top-detector/references/market_top_methodology.md +167 -0
- package/.claude/skills/market-top-detector/scripts/calculators/__init__.py +17 -0
- package/.claude/skills/market-top-detector/scripts/calculators/breadth_calculator.py +116 -0
- package/.claude/skills/market-top-detector/scripts/calculators/defensive_rotation_calculator.py +127 -0
- package/.claude/skills/market-top-detector/scripts/calculators/distribution_day_calculator.py +161 -0
- package/.claude/skills/market-top-detector/scripts/calculators/index_technical_calculator.py +254 -0
- package/.claude/skills/market-top-detector/scripts/calculators/leading_stock_calculator.py +198 -0
- package/.claude/skills/market-top-detector/scripts/calculators/sentiment_calculator.py +213 -0
- package/.claude/skills/market-top-detector/scripts/fmp_client.py +158 -0
- package/.claude/skills/market-top-detector/scripts/market_top_detector.py +349 -0
- package/.claude/skills/market-top-detector/scripts/report_generator.py +314 -0
- package/.claude/skills/market-top-detector/scripts/scorer.py +473 -0
- package/.claude/skills/market-top-detector/scripts/tests/conftest.py +9 -0
- package/.claude/skills/market-top-detector/scripts/tests/helpers.py +49 -0
- package/.claude/skills/market-top-detector/scripts/tests/test_breadth.py +62 -0
- package/.claude/skills/market-top-detector/scripts/tests/test_defensive_rotation.py +56 -0
- package/.claude/skills/market-top-detector/scripts/tests/test_distribution_day.py +92 -0
- package/.claude/skills/market-top-detector/scripts/tests/test_index_technical.py +73 -0
- package/.claude/skills/market-top-detector/scripts/tests/test_leading_stock.py +57 -0
- package/.claude/skills/market-top-detector/scripts/tests/test_scorer.py +180 -0
- package/.claude/skills/market-top-detector/scripts/tests/test_sentiment.py +64 -0
- package/.claude/skills/options-strategy-advisor/README.md +469 -0
- package/.claude/skills/options-strategy-advisor/SKILL.md +959 -0
- package/.claude/skills/options-strategy-advisor/scripts/black_scholes.py +495 -0
- package/.claude/skills/pair-trade-screener/README.md +389 -0
- package/.claude/skills/pair-trade-screener/SKILL.md +622 -0
- package/.claude/skills/pair-trade-screener/references/cointegration_guide.md +745 -0
- package/.claude/skills/pair-trade-screener/references/methodology.md +853 -0
- package/.claude/skills/pair-trade-screener/scripts/analyze_spread.py +394 -0
- package/.claude/skills/pair-trade-screener/scripts/find_pairs.py +535 -0
- package/.claude/skills/portfolio-manager/README.md +394 -0
- package/.claude/skills/portfolio-manager/SKILL.md +750 -0
- package/.claude/skills/portfolio-manager/references/alpaca-mcp-setup.md +367 -0
- package/.claude/skills/portfolio-manager/references/asset-allocation.md +502 -0
- package/.claude/skills/portfolio-manager/references/diversification-principles.md +553 -0
- package/.claude/skills/portfolio-manager/references/portfolio-risk-metrics.md +603 -0
- package/.claude/skills/portfolio-manager/references/position-evaluation.md +477 -0
- package/.claude/skills/portfolio-manager/references/rebalancing-strategies.md +715 -0
- package/.claude/skills/portfolio-manager/references/risk-profile-questionnaire.md +608 -0
- package/.claude/skills/portfolio-manager/references/target-allocations.md +558 -0
- package/.claude/skills/portfolio-manager/scripts/test_alpaca_connection.py +286 -0
- package/.claude/skills/scenario-analyzer/SKILL.md +317 -0
- package/.claude/skills/scenario-analyzer/references/headline_event_patterns.md +264 -0
- package/.claude/skills/scenario-analyzer/references/scenario_playbooks.md +320 -0
- package/.claude/skills/scenario-analyzer/references/sector_sensitivity_matrix.md +217 -0
- package/.claude/skills/sector-analyst/SKILL.md +206 -0
- package/.claude/skills/sector-analyst/assets/industory_performance_1.jpeg +0 -0
- package/.claude/skills/sector-analyst/assets/industory_performance_2.jpeg +0 -0
- package/.claude/skills/sector-analyst/assets/sector_performance.jpeg +0 -0
- package/.claude/skills/sector-analyst/references/sector_rotation.md +170 -0
- package/.claude/skills/stanley-druckenmiller-investment/SKILL.md +84 -0
- package/.claude/skills/stanley-druckenmiller-investment/references/case-studies.md +148 -0
- package/.claude/skills/stanley-druckenmiller-investment/references/investment-philosophy.md +80 -0
- package/.claude/skills/stanley-druckenmiller-investment/references/market-analysis-guide.md +146 -0
- package/.claude/skills/stock/NOTION_SETUP.md +33 -0
- package/.claude/skills/stock/SKILL.md +38 -0
- package/.claude/skills/technical-analyst/SKILL.md +238 -0
- package/.claude/skills/technical-analyst/assets/analysis_template.md +183 -0
- package/.claude/skills/technical-analyst/references/technical_analysis_framework.md +282 -0
- package/.claude/skills/theme-detector/SKILL.md +320 -0
- package/.claude/skills/theme-detector/assets/report_template.md +155 -0
- package/.claude/skills/theme-detector/references/cross_sector_themes.md +252 -0
- package/.claude/skills/theme-detector/references/finviz_industry_codes.md +403 -0
- package/.claude/skills/theme-detector/references/thematic_etf_catalog.md +333 -0
- package/.claude/skills/theme-detector/references/theme_detection_methodology.md +430 -0
- package/.claude/skills/theme-detector/scripts/calculators/__init__.py +1 -0
- package/.claude/skills/theme-detector/scripts/calculators/heat_calculator.py +123 -0
- package/.claude/skills/theme-detector/scripts/calculators/industry_ranker.py +98 -0
- package/.claude/skills/theme-detector/scripts/calculators/lifecycle_calculator.py +172 -0
- package/.claude/skills/theme-detector/scripts/calculators/theme_classifier.py +195 -0
- package/.claude/skills/theme-detector/scripts/calculators/theme_discoverer.py +280 -0
- package/.claude/skills/theme-detector/scripts/config_loader.py +142 -0
- package/.claude/skills/theme-detector/scripts/default_theme_config.py +254 -0
- package/.claude/skills/theme-detector/scripts/etf_scanner.py +609 -0
- package/.claude/skills/theme-detector/scripts/finviz_performance_client.py +131 -0
- package/.claude/skills/theme-detector/scripts/report_generator.py +490 -0
- package/.claude/skills/theme-detector/scripts/representative_stock_selector.py +673 -0
- package/.claude/skills/theme-detector/scripts/scorer.py +87 -0
- package/.claude/skills/theme-detector/scripts/tests/README.md +21 -0
- package/.claude/skills/theme-detector/scripts/tests/conftest.py +9 -0
- package/.claude/skills/theme-detector/scripts/tests/test_config_loader.py +239 -0
- package/.claude/skills/theme-detector/scripts/tests/test_etf_scanner.py +810 -0
- package/.claude/skills/theme-detector/scripts/tests/test_heat_calculator.py +245 -0
- package/.claude/skills/theme-detector/scripts/tests/test_industry_ranker.py +256 -0
- package/.claude/skills/theme-detector/scripts/tests/test_lifecycle_calculator.py +301 -0
- package/.claude/skills/theme-detector/scripts/tests/test_report_generator.py +624 -0
- package/.claude/skills/theme-detector/scripts/tests/test_representative_stock_selector.py +898 -0
- package/.claude/skills/theme-detector/scripts/tests/test_scorer.py +185 -0
- package/.claude/skills/theme-detector/scripts/tests/test_theme_classifier.py +534 -0
- package/.claude/skills/theme-detector/scripts/tests/test_theme_detector_e2e.py +467 -0
- package/.claude/skills/theme-detector/scripts/tests/test_theme_discoverer.py +458 -0
- package/.claude/skills/theme-detector/scripts/tests/test_uptrend_client.py +76 -0
- package/.claude/skills/theme-detector/scripts/theme_detector.py +815 -0
- package/.claude/skills/theme-detector/scripts/themes.yaml +168 -0
- package/.claude/skills/theme-detector/scripts/uptrend_client.py +241 -0
- package/.claude/skills/uptrend-analyzer/SKILL.md +108 -0
- package/.claude/skills/uptrend-analyzer/references/uptrend_methodology.md +215 -0
- package/.claude/skills/uptrend-analyzer/scripts/calculators/__init__.py +1 -0
- package/.claude/skills/uptrend-analyzer/scripts/calculators/historical_context_calculator.py +122 -0
- package/.claude/skills/uptrend-analyzer/scripts/calculators/market_breadth_calculator.py +145 -0
- package/.claude/skills/uptrend-analyzer/scripts/calculators/momentum_calculator.py +183 -0
- package/.claude/skills/uptrend-analyzer/scripts/calculators/sector_participation_calculator.py +204 -0
- package/.claude/skills/uptrend-analyzer/scripts/calculators/sector_rotation_calculator.py +218 -0
- package/.claude/skills/uptrend-analyzer/scripts/data_fetcher.py +236 -0
- package/.claude/skills/uptrend-analyzer/scripts/report_generator.py +329 -0
- package/.claude/skills/uptrend-analyzer/scripts/scorer.py +276 -0
- package/.claude/skills/uptrend-analyzer/scripts/uptrend_analyzer.py +219 -0
- package/.claude/skills/us-market-bubble-detector/CHANGELOG.md +118 -0
- package/.claude/skills/us-market-bubble-detector/SKILL.md +545 -0
- package/.claude/skills/us-market-bubble-detector/references/bubble_framework.md +335 -0
- package/.claude/skills/us-market-bubble-detector/references/historical_cases.md +327 -0
- package/.claude/skills/us-market-bubble-detector/references/implementation_guide.md +473 -0
- package/.claude/skills/us-market-bubble-detector/references/quick_reference.md +354 -0
- package/.claude/skills/us-market-bubble-detector/references/quick_reference_en.md +342 -0
- package/.claude/skills/us-market-bubble-detector/scripts/bubble_scorer.py +309 -0
- package/.claude/skills/us-stock-analysis/SKILL.md +294 -0
- package/.claude/skills/us-stock-analysis/references/financial-metrics.md +172 -0
- package/.claude/skills/us-stock-analysis/references/fundamental-analysis.md +129 -0
- package/.claude/skills/us-stock-analysis/references/report-template.md +207 -0
- package/.claude/skills/us-stock-analysis/references/technical-analysis.md +93 -0
- package/.claude/skills/value-dividend-screener/SKILL.md +562 -0
- package/.claude/skills/value-dividend-screener/references/fmp_api_guide.md +348 -0
- package/.claude/skills/value-dividend-screener/references/screening_methodology.md +315 -0
- package/.claude/skills/value-dividend-screener/scripts/screen_dividend_stocks.py +1138 -0
- package/.claude/skills/vcp-screener/SKILL.md +79 -0
- package/.claude/skills/vcp-screener/references/fmp_api_endpoints.md +45 -0
- package/.claude/skills/vcp-screener/references/scoring_system.md +154 -0
- package/.claude/skills/vcp-screener/references/vcp_methodology.md +124 -0
- package/.claude/skills/vcp-screener/scripts/calculators/__init__.py +1 -0
- package/.claude/skills/vcp-screener/scripts/calculators/pivot_proximity_calculator.py +139 -0
- package/.claude/skills/vcp-screener/scripts/calculators/relative_strength_calculator.py +161 -0
- package/.claude/skills/vcp-screener/scripts/calculators/trend_template_calculator.py +228 -0
- package/.claude/skills/vcp-screener/scripts/calculators/vcp_pattern_calculator.py +322 -0
- package/.claude/skills/vcp-screener/scripts/calculators/volume_pattern_calculator.py +121 -0
- package/.claude/skills/vcp-screener/scripts/fmp_client.py +162 -0
- package/.claude/skills/vcp-screener/scripts/report_generator.py +317 -0
- package/.claude/skills/vcp-screener/scripts/scorer.py +155 -0
- package/.claude/skills/vcp-screener/scripts/screen_vcp.py +536 -0
- package/.claude/skills/vcp-screener/scripts/tests/__init__.py +0 -0
- package/.claude/skills/vcp-screener/scripts/tests/conftest.py +9 -0
- package/.claude/skills/vcp-screener/scripts/tests/test_vcp_screener.py +834 -0
- package/.claude/skills/weekly-trade-strategy/.claude/agents/druckenmiller-strategy-planner.md +300 -0
- package/.claude/skills/weekly-trade-strategy/.claude/agents/market-news-analyzer.md +239 -0
- package/.claude/skills/weekly-trade-strategy/.claude/agents/technical-market-analyst.md +187 -0
- package/.claude/skills/weekly-trade-strategy/.claude/agents/us-market-analyst.md +218 -0
- package/.claude/skills/weekly-trade-strategy/.claude/agents/weekly-trade-blog-writer.md +318 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/breadth-chart-analyst/SKILL.md +662 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/breadth-chart-analyst/assets/SP500_Breadth_Index_200MA_8MA.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/breadth-chart-analyst/assets/US_Stock_Market_Uptrend_Ratio.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/breadth-chart-analyst/assets/breadth_analysis_template.md +558 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/breadth-chart-analyst/references/breadth_chart_methodology.md +590 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/SKILL.md +721 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/assets/earnings_report_template.md +102 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/earnings_calendar_2025-11-02.md +447 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/references/fmp_api_guide.md +590 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/scripts/fetch_earnings_fmp.py +443 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/earnings-calendar/scripts/generate_report.py +366 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/economic-calendar-fetcher/SKILL.md +365 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/economic-calendar-fetcher/references/fmp_api_documentation.md +345 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/economic-calendar-fetcher/scripts/get_economic_calendar.py +267 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-environment-analysis/SKILL.md +139 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-environment-analysis/references/analysis_patterns.md +124 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-environment-analysis/references/indicators.md +99 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-environment-analysis/scripts/market_utils.py +127 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-news-analyst/SKILL.md +714 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-news-analyst/references/corporate_news_impact.md +446 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-news-analyst/references/geopolitical_commodity_correlations.md +499 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-news-analyst/references/market_event_patterns.md +393 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/market-news-analyst/references/trusted_news_sources.md +510 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/sector-analyst/SKILL.md +206 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/sector-analyst/assets/industory_performance_1.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/sector-analyst/assets/industory_performance_2.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/sector-analyst/assets/sector_performance.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/sector-analyst/references/sector_rotation.md +170 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/stanley-druckenmiller-investment/SKILL.md +84 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/stanley-druckenmiller-investment/references/case-studies.md +148 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/stanley-druckenmiller-investment/references/investment-philosophy.md +80 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/stanley-druckenmiller-investment/references/market-analysis-guide.md +146 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/technical-analyst/SKILL.md +238 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/technical-analyst/assets/analysis_template.md +183 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/technical-analyst/references/technical_analysis_framework.md +282 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/CHANGELOG.md +118 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/SKILL.md +545 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/references/bubble_framework.md +335 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/references/historical_cases.md +327 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/references/implementation_guide.md +473 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/references/quick_reference.md +354 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/references/quick_reference_en.md +342 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-market-bubble-detector/scripts/bubble_scorer.py +309 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-stock-analysis/SKILL.md +294 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-stock-analysis/references/financial-metrics.md +172 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-stock-analysis/references/fundamental-analysis.md +129 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-stock-analysis/references/report-template.md +207 -0
- package/.claude/skills/weekly-trade-strategy/.claude/skills/us-stock-analysis/references/technical-analysis.md +93 -0
- package/.claude/skills/weekly-trade-strategy/CLAUDE.md +454 -0
- package/.claude/skills/weekly-trade-strategy/README.md +287 -0
- package/.claude/skills/weekly-trade-strategy/blogs/.gitkeep +0 -0
- package/.claude/skills/weekly-trade-strategy/charts/.gitkeep +0 -0
- package/.claude/skills/weekly-trade-strategy/earnings_data.json +10054 -0
- package/.claude/skills/weekly-trade-strategy/skills/breadth-chart-analyst/SKILL.md +662 -0
- package/.claude/skills/weekly-trade-strategy/skills/breadth-chart-analyst/assets/SP500_Breadth_Index_200MA_8MA.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/skills/breadth-chart-analyst/assets/US_Stock_Market_Uptrend_Ratio.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/skills/breadth-chart-analyst/assets/breadth_analysis_template.md +558 -0
- package/.claude/skills/weekly-trade-strategy/skills/breadth-chart-analyst/references/breadth_chart_methodology.md +590 -0
- package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/SKILL.md +721 -0
- package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/assets/earnings_report_template.md +102 -0
- package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/earnings_calendar_2025-11-02.md +447 -0
- package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/references/fmp_api_guide.md +590 -0
- package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/scripts/fetch_earnings_fmp.py +443 -0
- package/.claude/skills/weekly-trade-strategy/skills/earnings-calendar/scripts/generate_report.py +366 -0
- package/.claude/skills/weekly-trade-strategy/skills/economic-calendar-fetcher/SKILL.md +365 -0
- package/.claude/skills/weekly-trade-strategy/skills/economic-calendar-fetcher/references/fmp_api_documentation.md +345 -0
- package/.claude/skills/weekly-trade-strategy/skills/economic-calendar-fetcher/scripts/get_economic_calendar.py +267 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-environment-analysis/SKILL.md +139 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-environment-analysis/references/analysis_patterns.md +124 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-environment-analysis/references/indicators.md +99 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-environment-analysis/scripts/market_utils.py +127 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-news-analyst/SKILL.md +714 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-news-analyst/references/corporate_news_impact.md +446 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-news-analyst/references/geopolitical_commodity_correlations.md +499 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-news-analyst/references/market_event_patterns.md +393 -0
- package/.claude/skills/weekly-trade-strategy/skills/market-news-analyst/references/trusted_news_sources.md +510 -0
- package/.claude/skills/weekly-trade-strategy/skills/sector-analyst/SKILL.md +206 -0
- package/.claude/skills/weekly-trade-strategy/skills/sector-analyst/assets/industory_performance_1.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/skills/sector-analyst/assets/industory_performance_2.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/skills/sector-analyst/assets/sector_performance.jpeg +0 -0
- package/.claude/skills/weekly-trade-strategy/skills/sector-analyst/references/sector_rotation.md +170 -0
- package/.claude/skills/weekly-trade-strategy/skills/stanley-druckenmiller-investment/SKILL.md +84 -0
- package/.claude/skills/weekly-trade-strategy/skills/stanley-druckenmiller-investment/references/case-studies.md +148 -0
- package/.claude/skills/weekly-trade-strategy/skills/stanley-druckenmiller-investment/references/investment-philosophy.md +80 -0
- package/.claude/skills/weekly-trade-strategy/skills/stanley-druckenmiller-investment/references/market-analysis-guide.md +146 -0
- package/.claude/skills/weekly-trade-strategy/skills/technical-analyst/SKILL.md +238 -0
- package/.claude/skills/weekly-trade-strategy/skills/technical-analyst/assets/analysis_template.md +183 -0
- package/.claude/skills/weekly-trade-strategy/skills/technical-analyst/references/technical_analysis_framework.md +282 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/CHANGELOG.md +118 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/SKILL.md +545 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/references/bubble_framework.md +335 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/references/historical_cases.md +327 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/references/implementation_guide.md +473 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/references/quick_reference.md +354 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/references/quick_reference_en.md +342 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-market-bubble-detector/scripts/bubble_scorer.py +309 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-stock-analysis/SKILL.md +294 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-stock-analysis/references/financial-metrics.md +172 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-stock-analysis/references/fundamental-analysis.md +129 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-stock-analysis/references/report-template.md +207 -0
- package/.claude/skills/weekly-trade-strategy/skills/us-stock-analysis/references/technical-analysis.md +93 -0
- package/.mcp.json +3 -0
- package/cli.mjs +16 -16
- package/package.json +4 -2
|
@@ -0,0 +1,853 @@
|
|
|
1
|
+
# Statistical Arbitrage and Pair Trading Methodology
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
1. [Introduction to Pair Trading](#introduction-to-pair-trading)
|
|
6
|
+
2. [Theoretical Foundation](#theoretical-foundation)
|
|
7
|
+
3. [Pair Selection Process](#pair-selection-process)
|
|
8
|
+
4. [Statistical Tests](#statistical-tests)
|
|
9
|
+
5. [Spread Construction and Analysis](#spread-construction-and-analysis)
|
|
10
|
+
6. [Entry and Exit Rules](#entry-and-exit-rules)
|
|
11
|
+
7. [Risk Management](#risk-management)
|
|
12
|
+
8. [Common Pitfalls](#common-pitfalls)
|
|
13
|
+
9. [Advanced Topics](#advanced-topics)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Introduction to Pair Trading
|
|
18
|
+
|
|
19
|
+
### What is Pair Trading?
|
|
20
|
+
|
|
21
|
+
Pair trading is a market-neutral trading strategy that involves simultaneously buying and selling two highly correlated securities. The strategy profits from the convergence of prices when the relationship between the two stocks temporarily diverges from its historical equilibrium.
|
|
22
|
+
|
|
23
|
+
**Key Characteristics:**
|
|
24
|
+
- **Market Neutral**: Long one stock, short another → net beta ≈ 0
|
|
25
|
+
- **Mean Reverting**: Relies on temporary deviations from equilibrium
|
|
26
|
+
- **Statistical Foundation**: Based on mathematical relationships, not discretion
|
|
27
|
+
- **Relative Value**: Profits from relative performance, not absolute direction
|
|
28
|
+
|
|
29
|
+
### Historical Context
|
|
30
|
+
|
|
31
|
+
Pair trading was pioneered by **Gerry Bamberger** and later developed by **Nunzio Tartaglia** at Morgan Stanley in the 1980s. The quantitative team identified pairs of stocks whose prices historically moved together and profited when temporary divergences occurred.
|
|
32
|
+
|
|
33
|
+
**Evolution:**
|
|
34
|
+
- 1980s: Manual pair selection, simple spread tracking
|
|
35
|
+
- 1990s: Statistical models (cointegration, Kalman filters)
|
|
36
|
+
- 2000s: High-frequency pair trading, algorithmic execution
|
|
37
|
+
- 2010s+: Machine learning, regime detection, multi-asset pairs
|
|
38
|
+
|
|
39
|
+
### Why Pair Trading Works
|
|
40
|
+
|
|
41
|
+
**Economic Rationale:**
|
|
42
|
+
1. **Sector/Industry Linkages**: Companies in same sector share common drivers (demand, regulation, input costs)
|
|
43
|
+
2. **Temporary Mispricing**: Information asymmetry, behavioral biases, technical flows create temporary price divergences
|
|
44
|
+
3. **Mean Reversion**: Economic forces pull prices back to equilibrium (arbitrage, fundamentals)
|
|
45
|
+
4. **Supply Chain Relationships**: Suppliers and customers often move together
|
|
46
|
+
|
|
47
|
+
**Statistical Rationale:**
|
|
48
|
+
- Cointegration ensures long-run equilibrium relationship
|
|
49
|
+
- Short-term deviations are statistically predictable
|
|
50
|
+
- Z-score framework provides objective entry/exit rules
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Theoretical Foundation
|
|
55
|
+
|
|
56
|
+
### Cointegration vs Correlation
|
|
57
|
+
|
|
58
|
+
**Correlation:**
|
|
59
|
+
- Measures short-term co-movement of returns
|
|
60
|
+
- Range: -1 to +1
|
|
61
|
+
- Can be unstable over time
|
|
62
|
+
- Does not imply mean reversion
|
|
63
|
+
|
|
64
|
+
**Cointegration:**
|
|
65
|
+
- Measures long-term equilibrium relationship between price levels
|
|
66
|
+
- Ensures spread is stationary (mean-reverting)
|
|
67
|
+
- More stable foundation for pair trading
|
|
68
|
+
- Implies prices won't drift apart indefinitely
|
|
69
|
+
|
|
70
|
+
**Mathematical Definition:**
|
|
71
|
+
|
|
72
|
+
Two time series `P_A(t)` and `P_B(t)` are cointegrated if:
|
|
73
|
+
```
|
|
74
|
+
Spread(t) = P_A(t) - β * P_B(t)
|
|
75
|
+
```
|
|
76
|
+
is stationary (mean-reverting), where β is the cointegration coefficient.
|
|
77
|
+
|
|
78
|
+
### Stationarity
|
|
79
|
+
|
|
80
|
+
A time series is **stationary** if:
|
|
81
|
+
1. Constant mean over time
|
|
82
|
+
2. Constant variance over time
|
|
83
|
+
3. Autocorrelation depends only on time lag, not time itself
|
|
84
|
+
|
|
85
|
+
**Why Stationarity Matters for Pair Trading:**
|
|
86
|
+
- Non-stationary spread → prices can diverge forever → no mean reversion
|
|
87
|
+
- Stationary spread → prices revert to mean → profitable trade opportunities
|
|
88
|
+
- Cointegration ensures spread stationarity
|
|
89
|
+
|
|
90
|
+
### Mean Reversion
|
|
91
|
+
|
|
92
|
+
The spread follows an **Ornstein-Uhlenbeck (OU) process**:
|
|
93
|
+
```
|
|
94
|
+
dS(t) = θ(μ - S(t))dt + σdW(t)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Where:
|
|
98
|
+
- `S(t)`: Spread at time t
|
|
99
|
+
- `θ`: Mean reversion speed (higher = faster reversion)
|
|
100
|
+
- `μ`: Long-term mean of spread
|
|
101
|
+
- `σ`: Volatility of spread
|
|
102
|
+
- `dW(t)`: Brownian motion (random noise)
|
|
103
|
+
|
|
104
|
+
**Half-Life:**
|
|
105
|
+
|
|
106
|
+
Time for spread to revert halfway to its mean:
|
|
107
|
+
```
|
|
108
|
+
Half-Life = ln(2) / θ
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Interpretation:**
|
|
112
|
+
- Half-life = 10 days: Very fast mean reversion (suitable for day trading)
|
|
113
|
+
- Half-life = 30 days: Standard speed (typical pair trades)
|
|
114
|
+
- Half-life = 60+ days: Slow reversion (requires patience, longer holding)
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Pair Selection Process
|
|
119
|
+
|
|
120
|
+
### Step 1: Universe Definition
|
|
121
|
+
|
|
122
|
+
**Sector-Based Approach (Recommended):**
|
|
123
|
+
- Focus on stocks within same sector (e.g., Technology, Financials)
|
|
124
|
+
- Common drivers increase likelihood of cointegration
|
|
125
|
+
- Examples:
|
|
126
|
+
- Tech: AAPL/MSFT, GOOGL/META, NVDA/AMD
|
|
127
|
+
- Financials: JPM/BAC, GS/MS, WFC/USB
|
|
128
|
+
- Energy: XOM/CVX, COP/EOG
|
|
129
|
+
|
|
130
|
+
**Industry-Specific Approach:**
|
|
131
|
+
- Narrow to specific industry (e.g., "Software" within Tech, "Regional Banks" within Financials)
|
|
132
|
+
- Stronger fundamental linkages
|
|
133
|
+
- Fewer pairs but higher quality
|
|
134
|
+
|
|
135
|
+
**Custom Approach:**
|
|
136
|
+
- User-specified list of stocks
|
|
137
|
+
- Allows testing hypotheses (e.g., supply chain pairs, competitor pairs)
|
|
138
|
+
|
|
139
|
+
**Filtering Criteria:**
|
|
140
|
+
- Market cap ≥ $2B (liquidity and stability)
|
|
141
|
+
- Average volume ≥ 1M shares/day (execution feasibility)
|
|
142
|
+
- Same exchange preferred (NYSE/NYSE, NASDAQ/NASDAQ)
|
|
143
|
+
- Exclude recent IPOs (<2 years) and distressed stocks
|
|
144
|
+
|
|
145
|
+
### Step 2: Correlation Screening
|
|
146
|
+
|
|
147
|
+
**Calculate Pearson Correlation:**
|
|
148
|
+
```python
|
|
149
|
+
import pandas as pd
|
|
150
|
+
import numpy as np
|
|
151
|
+
|
|
152
|
+
# Returns-based correlation
|
|
153
|
+
correlation = returns_A.corr(returns_B)
|
|
154
|
+
|
|
155
|
+
# Price-based correlation (for reference)
|
|
156
|
+
price_correlation = prices_A.corr(prices_B)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Thresholds:**
|
|
160
|
+
- **Excellent (ρ ≥ 0.85)**: Very strong co-movement, best candidates
|
|
161
|
+
- **Good (ρ 0.70-0.85)**: Strong relationship, acceptable
|
|
162
|
+
- **Marginal (ρ 0.50-0.70)**: Moderate, requires strong cointegration
|
|
163
|
+
- **Poor (ρ < 0.50)**: Weak, likely not cointegrated
|
|
164
|
+
|
|
165
|
+
**Correlation Stability:**
|
|
166
|
+
|
|
167
|
+
Test correlation over multiple periods:
|
|
168
|
+
```python
|
|
169
|
+
# 6-month rolling correlation
|
|
170
|
+
rolling_corr = returns_A.rolling(126).corr(returns_B)
|
|
171
|
+
|
|
172
|
+
# Stability metric: std deviation of rolling correlation
|
|
173
|
+
stability = rolling_corr.std()
|
|
174
|
+
|
|
175
|
+
# Prefer pairs with low stability (<0.10)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Red Flags:**
|
|
179
|
+
- Correlation declining sharply in recent period
|
|
180
|
+
- High correlation volatility (correlation jumps around)
|
|
181
|
+
- Correlation approaching zero or turning negative
|
|
182
|
+
|
|
183
|
+
### Step 3: Beta Estimation (Hedge Ratio)
|
|
184
|
+
|
|
185
|
+
**Ordinary Least Squares (OLS) Regression:**
|
|
186
|
+
```python
|
|
187
|
+
from scipy import stats
|
|
188
|
+
|
|
189
|
+
# Regress Price_A on Price_B
|
|
190
|
+
slope, intercept, r_value, p_value, std_err = stats.linregress(prices_B, prices_A)
|
|
191
|
+
|
|
192
|
+
beta = slope # Hedge ratio
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Interpretation:**
|
|
196
|
+
- Beta = 1.0: Equal dollar hedge ($1 long A, $1 short B)
|
|
197
|
+
- Beta = 1.5: $1 long A, $1.50 short B
|
|
198
|
+
- Beta = 0.8: $1 long A, $0.80 short B
|
|
199
|
+
|
|
200
|
+
**Alternative Methods:**
|
|
201
|
+
- **Total Least Squares (TLS)**: Accounts for error in both variables
|
|
202
|
+
- **Kalman Filter**: Time-varying beta (advanced)
|
|
203
|
+
- **Rolling OLS**: Adaptive beta over time
|
|
204
|
+
|
|
205
|
+
### Step 4: Cointegration Testing
|
|
206
|
+
|
|
207
|
+
**Augmented Dickey-Fuller (ADF) Test:**
|
|
208
|
+
|
|
209
|
+
Tests null hypothesis: "Spread has unit root (non-stationary)"
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
from statsmodels.tsa.stattools import adfuller
|
|
213
|
+
|
|
214
|
+
# Calculate spread
|
|
215
|
+
spread = prices_A - (beta * prices_B)
|
|
216
|
+
|
|
217
|
+
# ADF test
|
|
218
|
+
result = adfuller(spread, maxlag=1, regression='c')
|
|
219
|
+
adf_statistic = result[0]
|
|
220
|
+
p_value = result[1]
|
|
221
|
+
critical_values = result[4]
|
|
222
|
+
|
|
223
|
+
# Interpret
|
|
224
|
+
is_cointegrated = p_value < 0.05
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Interpretation:**
|
|
228
|
+
- **p < 0.01**: Very strong cointegration (reject null at 99% confidence)
|
|
229
|
+
- **p 0.01-0.05**: Moderate cointegration (reject null at 95% confidence)
|
|
230
|
+
- **p > 0.05**: No cointegration (fail to reject null)
|
|
231
|
+
|
|
232
|
+
**Critical Values:**
|
|
233
|
+
- ADF stat < critical value (1%) → Very strong evidence
|
|
234
|
+
- ADF stat < critical value (5%) → Moderate evidence
|
|
235
|
+
- ADF stat > critical value (10%) → Weak evidence
|
|
236
|
+
|
|
237
|
+
**Alternative Cointegration Tests:**
|
|
238
|
+
- **Engle-Granger Two-Step**: Similar to ADF
|
|
239
|
+
- **Johansen Test**: Multi-variate cointegration (for >2 stocks)
|
|
240
|
+
- **Phillips-Ouliaris Test**: More robust to structural breaks
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Statistical Tests
|
|
245
|
+
|
|
246
|
+
### Stationarity Tests
|
|
247
|
+
|
|
248
|
+
**Augmented Dickey-Fuller (ADF):**
|
|
249
|
+
- Most common stationarity test
|
|
250
|
+
- Tests for unit root in time series
|
|
251
|
+
- Null hypothesis: Series has unit root (non-stationary)
|
|
252
|
+
|
|
253
|
+
**Kwiatkowski-Phillips-Schmidt-Shin (KPSS):**
|
|
254
|
+
- Complementary to ADF
|
|
255
|
+
- Null hypothesis: Series is stationary
|
|
256
|
+
- Use both tests for robustness:
|
|
257
|
+
- ADF rejects + KPSS fails to reject → Stationary
|
|
258
|
+
- ADF fails to reject + KPSS rejects → Non-stationary
|
|
259
|
+
|
|
260
|
+
**Phillips-Perron (PP) Test:**
|
|
261
|
+
- Non-parametric alternative to ADF
|
|
262
|
+
- More robust to heteroskedasticity and serial correlation
|
|
263
|
+
|
|
264
|
+
### Half-Life Estimation
|
|
265
|
+
|
|
266
|
+
**AR(1) Model Approach:**
|
|
267
|
+
|
|
268
|
+
Model spread as first-order autoregressive process:
|
|
269
|
+
```
|
|
270
|
+
S(t) = α + φ * S(t-1) + ε(t)
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Where:
|
|
274
|
+
- φ: Autocorrelation coefficient
|
|
275
|
+
- Mean reversion speed: θ = -ln(φ)
|
|
276
|
+
- Half-life: HL = ln(2) / θ
|
|
277
|
+
|
|
278
|
+
**Python Implementation:**
|
|
279
|
+
```python
|
|
280
|
+
from statsmodels.tsa.ar_model import AutoReg
|
|
281
|
+
|
|
282
|
+
# Fit AR(1) model
|
|
283
|
+
model = AutoReg(spread, lags=1)
|
|
284
|
+
result = model.fit()
|
|
285
|
+
phi = result.params[1]
|
|
286
|
+
|
|
287
|
+
# Calculate half-life
|
|
288
|
+
theta = -np.log(phi)
|
|
289
|
+
half_life = np.log(2) / theta
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**Interpretation:**
|
|
293
|
+
- HL < 20 days: Very fast mean reversion
|
|
294
|
+
- HL 20-40 days: Fast mean reversion (ideal for pair trading)
|
|
295
|
+
- HL 40-60 days: Moderate mean reversion
|
|
296
|
+
- HL > 60 days: Slow mean reversion (less attractive)
|
|
297
|
+
|
|
298
|
+
### Structural Break Detection
|
|
299
|
+
|
|
300
|
+
**Chow Test:**
|
|
301
|
+
|
|
302
|
+
Tests for structural break at known date (e.g., major corporate event):
|
|
303
|
+
```python
|
|
304
|
+
from statsmodels.stats.diagnostic import breaks_cusumolsresid
|
|
305
|
+
|
|
306
|
+
# Test for breaks
|
|
307
|
+
stat, pvalue = breaks_cusumolsresid(ols_residuals)
|
|
308
|
+
|
|
309
|
+
# Interpret
|
|
310
|
+
has_structural_break = pvalue < 0.05
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**CUSUM Test:**
|
|
314
|
+
- Detects unknown breakpoints
|
|
315
|
+
- Plots cumulative sum of residuals
|
|
316
|
+
- Sharp changes indicate structural breaks
|
|
317
|
+
|
|
318
|
+
**Practical Implication:**
|
|
319
|
+
- If structural break detected → Re-estimate cointegration relationship
|
|
320
|
+
- If break persists → Abandon pair (relationship broken)
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## Spread Construction and Analysis
|
|
325
|
+
|
|
326
|
+
### Spread Definitions
|
|
327
|
+
|
|
328
|
+
**Price Difference (Additive):**
|
|
329
|
+
```
|
|
330
|
+
Spread(t) = P_A(t) - β * P_B(t)
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
**Advantages:**
|
|
334
|
+
- Simpler interpretation
|
|
335
|
+
- Stationary under cointegration
|
|
336
|
+
|
|
337
|
+
**Disadvantages:**
|
|
338
|
+
- Units depend on price levels
|
|
339
|
+
- Not suitable for stocks with very different prices
|
|
340
|
+
|
|
341
|
+
**Price Ratio (Multiplicative):**
|
|
342
|
+
```
|
|
343
|
+
Spread(t) = P_A(t) / P_B(t)
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
**Advantages:**
|
|
347
|
+
- Unit-free (ratio has no units)
|
|
348
|
+
- Better for stocks with different price levels
|
|
349
|
+
- Percentage-based interpretation
|
|
350
|
+
|
|
351
|
+
**Disadvantages:**
|
|
352
|
+
- Log transformation often needed for stationarity
|
|
353
|
+
- More complex statistics
|
|
354
|
+
|
|
355
|
+
**Log Price Ratio:**
|
|
356
|
+
```
|
|
357
|
+
Spread(t) = ln(P_A(t)) - ln(P_B(t))
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
**Advantages:**
|
|
361
|
+
- Ensures stationarity
|
|
362
|
+
- Returns-like interpretation
|
|
363
|
+
- Symmetric around zero
|
|
364
|
+
|
|
365
|
+
### Z-Score Calculation
|
|
366
|
+
|
|
367
|
+
**Definition:**
|
|
368
|
+
```
|
|
369
|
+
Z(t) = [Spread(t) - μ] / σ
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
Where:
|
|
373
|
+
- μ: Mean of spread over lookback period
|
|
374
|
+
- σ: Standard deviation of spread over lookback period
|
|
375
|
+
|
|
376
|
+
**Lookback Period:**
|
|
377
|
+
- **90 days (short-term)**: Responsive to recent changes, noisier
|
|
378
|
+
- **180 days (medium-term)**: Balanced approach (recommended)
|
|
379
|
+
- **252 days (long-term)**: Stable parameters, slower to adapt
|
|
380
|
+
|
|
381
|
+
**Rolling vs Expanding Window:**
|
|
382
|
+
|
|
383
|
+
**Rolling Window:**
|
|
384
|
+
```python
|
|
385
|
+
rolling_mean = spread.rolling(90).mean()
|
|
386
|
+
rolling_std = spread.rolling(90).std()
|
|
387
|
+
zscore = (spread - rolling_mean) / rolling_std
|
|
388
|
+
```
|
|
389
|
+
- Adapts to changing spread dynamics
|
|
390
|
+
- Can miss long-term trends
|
|
391
|
+
|
|
392
|
+
**Expanding Window:**
|
|
393
|
+
```python
|
|
394
|
+
expanding_mean = spread.expanding().mean()
|
|
395
|
+
expanding_std = spread.expanding().std()
|
|
396
|
+
zscore = (spread - expanding_mean) / expanding_std
|
|
397
|
+
```
|
|
398
|
+
- Uses all historical data
|
|
399
|
+
- More stable but less adaptive
|
|
400
|
+
|
|
401
|
+
### Spread Distribution Analysis
|
|
402
|
+
|
|
403
|
+
**Normality Test:**
|
|
404
|
+
```python
|
|
405
|
+
from scipy.stats import normaltest
|
|
406
|
+
|
|
407
|
+
# Test if spread is normally distributed
|
|
408
|
+
stat, pvalue = normaltest(spread)
|
|
409
|
+
is_normal = pvalue > 0.05
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
**If spread is NOT normal:**
|
|
413
|
+
- Use percentile-based thresholds instead of z-scores
|
|
414
|
+
- Example: Enter at 95th percentile instead of z > 2.0
|
|
415
|
+
|
|
416
|
+
**Skewness and Kurtosis:**
|
|
417
|
+
- Skewness ≠ 0: Asymmetric distribution (adjust thresholds)
|
|
418
|
+
- Kurtosis > 3: Fat tails (extreme values more common)
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## Entry and Exit Rules
|
|
423
|
+
|
|
424
|
+
### Entry Conditions
|
|
425
|
+
|
|
426
|
+
**Conservative Strategy (Z ≥ ±2.0):**
|
|
427
|
+
|
|
428
|
+
**LONG Spread (Long A, Short B):**
|
|
429
|
+
```
|
|
430
|
+
Conditions:
|
|
431
|
+
1. Z-score < -2.0 (spread 2+ std devs below mean)
|
|
432
|
+
2. Cointegration p-value < 0.05
|
|
433
|
+
3. Correlation > 0.70
|
|
434
|
+
4. Half-life < 60 days
|
|
435
|
+
5. No structural breaks in recent 6 months
|
|
436
|
+
|
|
437
|
+
Action:
|
|
438
|
+
- Buy Stock A: $5,000
|
|
439
|
+
- Sell Stock B: $5,000 × β
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
**SHORT Spread (Short A, Long B):**
|
|
443
|
+
```
|
|
444
|
+
Conditions:
|
|
445
|
+
1. Z-score > +2.0 (spread 2+ std devs above mean)
|
|
446
|
+
2. [Same conditions 2-5 as above]
|
|
447
|
+
|
|
448
|
+
Action:
|
|
449
|
+
- Sell Stock A: $5,000
|
|
450
|
+
- Buy Stock B: $5,000 × β
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
**Aggressive Strategy (Z ≥ ±1.5):**
|
|
454
|
+
- Lower threshold → More frequent trades
|
|
455
|
+
- Higher win rate but smaller profits per trade
|
|
456
|
+
- Requires more active monitoring
|
|
457
|
+
|
|
458
|
+
**Very Aggressive (Z ≥ ±1.0):**
|
|
459
|
+
- Very frequent trades
|
|
460
|
+
- Transaction costs become significant
|
|
461
|
+
- Only viable with low commissions/rebates
|
|
462
|
+
|
|
463
|
+
### Exit Conditions
|
|
464
|
+
|
|
465
|
+
**Primary Exit: Mean Reversion**
|
|
466
|
+
```
|
|
467
|
+
Exit when Z-score crosses zero
|
|
468
|
+
→ Spread has reverted to mean
|
|
469
|
+
→ Close both legs simultaneously
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
**Partial Profit Taking:**
|
|
473
|
+
```
|
|
474
|
+
Stage 1: Exit 50% at Z-score = ±1.0
|
|
475
|
+
Stage 2: Exit remaining 50% at Z-score = 0
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
**Stop Loss:**
|
|
479
|
+
```
|
|
480
|
+
Hard Stop: Z-score > ±3.0
|
|
481
|
+
- Spread has diverged to extreme levels
|
|
482
|
+
- Possible structural break
|
|
483
|
+
→ Exit immediately to limit losses
|
|
484
|
+
|
|
485
|
+
Drawdown Stop: Total P/L < -5%
|
|
486
|
+
- Trade not working as expected
|
|
487
|
+
→ Exit to preserve capital
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
**Time-Based Exit:**
|
|
491
|
+
```
|
|
492
|
+
Maximum Holding Period: 90 days (or 3× half-life)
|
|
493
|
+
- If no mean reversion after expected timeframe
|
|
494
|
+
→ Exit to free up capital for better opportunities
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### Signal Confirmation
|
|
498
|
+
|
|
499
|
+
**Additional Filters (Optional):**
|
|
500
|
+
|
|
501
|
+
**Volume Confirmation:**
|
|
502
|
+
- Require above-average volume on spread widening
|
|
503
|
+
- Confirms divergence is meaningful, not noise
|
|
504
|
+
|
|
505
|
+
**Trend Filter:**
|
|
506
|
+
- Avoid entry if overall market (SPY) trending strongly
|
|
507
|
+
- Correlations break down during market crashes/rallies
|
|
508
|
+
|
|
509
|
+
**Volatility Filter:**
|
|
510
|
+
- Skip entry if VIX > 30 (high volatility environment)
|
|
511
|
+
- Pair relationships less stable during volatility spikes
|
|
512
|
+
|
|
513
|
+
---
|
|
514
|
+
|
|
515
|
+
## Risk Management
|
|
516
|
+
|
|
517
|
+
### Position Sizing
|
|
518
|
+
|
|
519
|
+
**Equal Dollar Allocation:**
|
|
520
|
+
```
|
|
521
|
+
For $10,000 total allocation to one pair:
|
|
522
|
+
- Long Leg: $5,000
|
|
523
|
+
- Short Leg: $5,000 × β
|
|
524
|
+
|
|
525
|
+
If β = 1.2:
|
|
526
|
+
- Long Stock A: $5,000
|
|
527
|
+
- Short Stock B: $6,000
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
**Volatility-Adjusted Sizing:**
|
|
531
|
+
|
|
532
|
+
Scale position size by inverse of spread volatility:
|
|
533
|
+
```
|
|
534
|
+
Position Size = Base Size / (Spread Volatility / Avg Spread Volatility)
|
|
535
|
+
```
|
|
536
|
+
- High volatility pair → Smaller position
|
|
537
|
+
- Low volatility pair → Larger position
|
|
538
|
+
|
|
539
|
+
### Portfolio-Level Risk
|
|
540
|
+
|
|
541
|
+
**Diversification:**
|
|
542
|
+
- **Minimum**: 5 pairs (reduce idiosyncratic risk)
|
|
543
|
+
- **Optimal**: 8-10 pairs (balance diversification and management)
|
|
544
|
+
- **Maximum**: 15 pairs (diminishing returns, management complexity)
|
|
545
|
+
|
|
546
|
+
**Correlation Across Pairs:**
|
|
547
|
+
- Avoid multiple pairs with overlapping stocks (e.g., AAPL/MSFT and AAPL/GOOGL)
|
|
548
|
+
- Limit exposure to single sector (<50% of pairs)
|
|
549
|
+
- Monitor portfolio beta (should be near zero)
|
|
550
|
+
|
|
551
|
+
**Maximum Risk Allocation:**
|
|
552
|
+
- Single pair: 10-15% of total portfolio
|
|
553
|
+
- All pairs combined: 60-80% of total portfolio (rest in cash/T-bills)
|
|
554
|
+
|
|
555
|
+
### Transaction Costs
|
|
556
|
+
|
|
557
|
+
**Components:**
|
|
558
|
+
- **Commissions**: $0 (most brokers) but check per-share fees
|
|
559
|
+
- **Spread**: Bid-ask spread cost (0.01-0.05% per leg)
|
|
560
|
+
- **Slippage**: Market impact (0.02-0.10% per leg)
|
|
561
|
+
- **Short Interest**: Borrow costs for short leg (0-50% annual)
|
|
562
|
+
- **Hard-to-Borrow Fees**: Additional fees for difficult shorts
|
|
563
|
+
|
|
564
|
+
**Total Round-Trip Cost Estimate:**
|
|
565
|
+
```
|
|
566
|
+
Conservative: 0.4% (0.1% per leg × 4 legs)
|
|
567
|
+
With Short Interest: 0.4% + (0.5% × days held / 365)
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
**Breakeven Z-Score:**
|
|
571
|
+
|
|
572
|
+
Minimum z-score to exceed transaction costs:
|
|
573
|
+
```
|
|
574
|
+
Z_min = Total Transaction Cost / Expected Profit per Std Dev
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
Example:
|
|
578
|
+
- Transaction cost: 0.4%
|
|
579
|
+
- Expected profit per std dev: 0.8%
|
|
580
|
+
- Z_min = 0.4% / 0.8% = 0.5
|
|
581
|
+
|
|
582
|
+
→ Only enter if |Z| > 2.0 (provides 2σ × 0.8% = 1.6% profit, well above 0.4% cost)
|
|
583
|
+
|
|
584
|
+
### Margin and Leverage
|
|
585
|
+
|
|
586
|
+
**Regulation T Requirements:**
|
|
587
|
+
- Long stock: 50% initial margin
|
|
588
|
+
- Short stock: 50% initial margin + 100% collateral
|
|
589
|
+
- Pair trade: Effectively 100% margin requirement
|
|
590
|
+
|
|
591
|
+
**Example:**
|
|
592
|
+
```
|
|
593
|
+
Long $10,000 Stock A:
|
|
594
|
+
- Margin required: $5,000
|
|
595
|
+
|
|
596
|
+
Short $10,000 Stock B:
|
|
597
|
+
- Margin required: $5,000
|
|
598
|
+
- Collateral required: $10,000
|
|
599
|
+
- Total tied up: $15,000
|
|
600
|
+
|
|
601
|
+
Total capital required: $20,000 for $20,000 exposure
|
|
602
|
+
→ No leverage in market-neutral pair trading
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
**Portfolio Margin (Advanced):**
|
|
606
|
+
- Recognizes offsetting risk of pair
|
|
607
|
+
- May reduce margin requirement to 50-70% of Reg T
|
|
608
|
+
- Requires $125K account minimum
|
|
609
|
+
|
|
610
|
+
---
|
|
611
|
+
|
|
612
|
+
## Common Pitfalls
|
|
613
|
+
|
|
614
|
+
### 1. Survivorship Bias
|
|
615
|
+
|
|
616
|
+
**Problem:**
|
|
617
|
+
- Screening only currently listed stocks
|
|
618
|
+
- Excludes delisted stocks (bankruptcies, acquisitions)
|
|
619
|
+
- Overstates historical performance
|
|
620
|
+
|
|
621
|
+
**Solution:**
|
|
622
|
+
- Use survivorship-bias-free databases
|
|
623
|
+
- Acknowledge backtest limitations
|
|
624
|
+
- Focus on forward testing
|
|
625
|
+
|
|
626
|
+
### 2. Look-Ahead Bias
|
|
627
|
+
|
|
628
|
+
**Problem:**
|
|
629
|
+
- Using future information in historical analysis
|
|
630
|
+
- Example: Calculating z-score with full-period mean/std dev
|
|
631
|
+
|
|
632
|
+
**Incorrect:**
|
|
633
|
+
```python
|
|
634
|
+
# Using entire dataset mean (look-ahead bias)
|
|
635
|
+
mean = spread.mean()
|
|
636
|
+
std = spread.std()
|
|
637
|
+
zscore = (spread - mean) / std
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
**Correct:**
|
|
641
|
+
```python
|
|
642
|
+
# Using rolling window (no look-ahead)
|
|
643
|
+
zscore = (spread - spread.rolling(90).mean()) / spread.rolling(90).std()
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
### 3. Overfitting
|
|
647
|
+
|
|
648
|
+
**Problem:**
|
|
649
|
+
- Optimizing parameters on same dataset used for testing
|
|
650
|
+
- Finding spurious relationships
|
|
651
|
+
|
|
652
|
+
**Solutions:**
|
|
653
|
+
- **Out-of-Sample Testing**: Train on 70%, test on 30%
|
|
654
|
+
- **Walk-Forward Analysis**: Roll optimization window forward
|
|
655
|
+
- **Simplicity**: Prefer simple rules (z=2.0) over complex optimization
|
|
656
|
+
- **Economic Rationale**: Require fundamental reason for pair relationship
|
|
657
|
+
|
|
658
|
+
### 4. Ignoring Structural Breaks
|
|
659
|
+
|
|
660
|
+
**Problem:**
|
|
661
|
+
- Corporate actions (mergers, spin-offs, restructuring)
|
|
662
|
+
- Business model changes
|
|
663
|
+
- Regulatory changes
|
|
664
|
+
|
|
665
|
+
**Examples:**
|
|
666
|
+
- Tech company pivots to cloud (changes growth profile)
|
|
667
|
+
- Bank undergoes merger (risk profile changes)
|
|
668
|
+
- Regulatory change affects one stock but not the other
|
|
669
|
+
|
|
670
|
+
**Detection:**
|
|
671
|
+
```python
|
|
672
|
+
# Check for sharp correlation drop
|
|
673
|
+
recent_corr = returns_A[-60:].corr(returns_B[-60:])
|
|
674
|
+
historical_corr = returns_A[:-60].corr(returns_B[:-60])
|
|
675
|
+
|
|
676
|
+
if recent_corr < historical_corr - 0.20:
|
|
677
|
+
print("WARNING: Correlation breakdown detected")
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
### 5. Insufficient Liquidity
|
|
681
|
+
|
|
682
|
+
**Problem:**
|
|
683
|
+
- Small cap stocks with low volume
|
|
684
|
+
- Wide bid-ask spreads
|
|
685
|
+
- Market impact on entry/exit
|
|
686
|
+
|
|
687
|
+
**Solutions:**
|
|
688
|
+
- Require minimum avg volume (1M shares/day)
|
|
689
|
+
- Check spread as % of mid-price (<0.1% acceptable)
|
|
690
|
+
- Size positions relative to daily volume (<5% of avg daily volume)
|
|
691
|
+
|
|
692
|
+
### 6. Correlation ≠ Causation
|
|
693
|
+
|
|
694
|
+
**Problem:**
|
|
695
|
+
- Pairs with high correlation but no economic linkage
|
|
696
|
+
- Correlation may be spurious or temporary
|
|
697
|
+
|
|
698
|
+
**Example:**
|
|
699
|
+
- Stock A and Bitcoin have 0.80 correlation over 6 months
|
|
700
|
+
- No fundamental reason for relationship
|
|
701
|
+
- Likely to break down
|
|
702
|
+
|
|
703
|
+
**Solution:**
|
|
704
|
+
- Prefer pairs with clear economic linkage
|
|
705
|
+
- Same sector, supply chain, competitor dynamics
|
|
706
|
+
|
|
707
|
+
### 7. Regime Changes
|
|
708
|
+
|
|
709
|
+
**Problem:**
|
|
710
|
+
- Market regimes affect pair relationships
|
|
711
|
+
- Crisis periods: Correlations → 1 (all stocks down)
|
|
712
|
+
- Low volatility: Mean reversion fast
|
|
713
|
+
- High volatility: Mean reversion slow or absent
|
|
714
|
+
|
|
715
|
+
**VIX-Based Regime Filter:**
|
|
716
|
+
```
|
|
717
|
+
If VIX < 15: Normal regime → Trade all pairs
|
|
718
|
+
If VIX 15-25: Elevated volatility → Trade only high-quality pairs
|
|
719
|
+
If VIX > 25: Crisis mode → Exit all pairs, wait for stabilization
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
---
|
|
723
|
+
|
|
724
|
+
## Advanced Topics
|
|
725
|
+
|
|
726
|
+
### Time-Varying Hedge Ratios
|
|
727
|
+
|
|
728
|
+
**Problem with Static Beta:**
|
|
729
|
+
- Relationship between stocks changes over time
|
|
730
|
+
- Fixed beta may become outdated
|
|
731
|
+
|
|
732
|
+
**Kalman Filter Approach:**
|
|
733
|
+
|
|
734
|
+
Dynamically update beta based on new observations:
|
|
735
|
+
```python
|
|
736
|
+
from pykalman import KalmanFilter
|
|
737
|
+
|
|
738
|
+
# Set up Kalman filter
|
|
739
|
+
kf = KalmanFilter(
|
|
740
|
+
transition_matrices=[1],
|
|
741
|
+
observation_matrices=[prices_B],
|
|
742
|
+
initial_state_mean=initial_beta,
|
|
743
|
+
initial_state_covariance=1,
|
|
744
|
+
observation_covariance=1,
|
|
745
|
+
transition_covariance=0.01
|
|
746
|
+
)
|
|
747
|
+
|
|
748
|
+
# Estimate time-varying beta
|
|
749
|
+
state_means, state_covs = kf.filter(prices_A)
|
|
750
|
+
dynamic_beta = state_means.flatten()
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
**Advantages:**
|
|
754
|
+
- Adapts to changing relationship
|
|
755
|
+
- Reduces spread variance
|
|
756
|
+
|
|
757
|
+
**Disadvantages:**
|
|
758
|
+
- More complex implementation
|
|
759
|
+
- Risk of overfitting
|
|
760
|
+
|
|
761
|
+
### Multi-Pair Portfolios
|
|
762
|
+
|
|
763
|
+
**Basket Pair Trading:**
|
|
764
|
+
|
|
765
|
+
Instead of pairwise trades, construct baskets:
|
|
766
|
+
```
|
|
767
|
+
Long Basket: Equal-weight portfolio of Stock A, C, E
|
|
768
|
+
Short Basket: Equal-weight portfolio of Stock B, D, F
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
**Advantages:**
|
|
772
|
+
- Reduced idiosyncratic risk
|
|
773
|
+
- More stable spread
|
|
774
|
+
- Lower impact from single stock events
|
|
775
|
+
|
|
776
|
+
**Statistical Arbitrage Portfolios:**
|
|
777
|
+
- Screen entire universe for mispriced stocks
|
|
778
|
+
- Long top decile (undervalued)
|
|
779
|
+
- Short bottom decile (overvalued)
|
|
780
|
+
- Continuously rebalance
|
|
781
|
+
|
|
782
|
+
### Machine Learning Enhancements
|
|
783
|
+
|
|
784
|
+
**Cointegration Regime Classification:**
|
|
785
|
+
|
|
786
|
+
Use ML to predict when pairs are likely to mean-revert:
|
|
787
|
+
```python
|
|
788
|
+
from sklearn.ensemble import RandomForestClassifier
|
|
789
|
+
|
|
790
|
+
# Features: VIX, correlation stability, spread volatility, etc.
|
|
791
|
+
# Label: Did spread mean-revert within 30 days?
|
|
792
|
+
|
|
793
|
+
model = RandomForestClassifier()
|
|
794
|
+
model.fit(features, labels)
|
|
795
|
+
|
|
796
|
+
# Predict for current pair
|
|
797
|
+
will_revert = model.predict(current_features)
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
**Signal Enhancement:**
|
|
801
|
+
- Combine z-score with ML probability
|
|
802
|
+
- Only enter if z < -2.0 AND ML_prob > 0.70
|
|
803
|
+
|
|
804
|
+
**Caution:**
|
|
805
|
+
- Risk of overfitting
|
|
806
|
+
- Requires substantial out-of-sample testing
|
|
807
|
+
|
|
808
|
+
### Intraday Pair Trading
|
|
809
|
+
|
|
810
|
+
**High-Frequency Approach:**
|
|
811
|
+
- Use minute or tick data
|
|
812
|
+
- Faster mean reversion (half-life in hours/minutes)
|
|
813
|
+
- Requires low-latency execution
|
|
814
|
+
|
|
815
|
+
**Challenges:**
|
|
816
|
+
- Transaction costs dominate at high frequency
|
|
817
|
+
- Need for co-location, direct market access
|
|
818
|
+
- Market microstructure noise
|
|
819
|
+
|
|
820
|
+
**Recommendation:**
|
|
821
|
+
- Retail traders: Stick to daily/weekly pair trading
|
|
822
|
+
- Institutional: Intraday feasible with infrastructure
|
|
823
|
+
|
|
824
|
+
---
|
|
825
|
+
|
|
826
|
+
## Conclusion
|
|
827
|
+
|
|
828
|
+
Pair trading is a powerful market-neutral strategy with strong statistical and economic foundations. Success requires:
|
|
829
|
+
|
|
830
|
+
1. **Rigorous pair selection** (cointegration, not just correlation)
|
|
831
|
+
2. **Robust statistical testing** (ADF, half-life, structural breaks)
|
|
832
|
+
3. **Disciplined risk management** (position sizing, stop losses)
|
|
833
|
+
4. **Realistic cost modeling** (transaction costs, short interest)
|
|
834
|
+
5. **Continuous monitoring** (regime changes, correlation breakdowns)
|
|
835
|
+
|
|
836
|
+
**Key Takeaways:**
|
|
837
|
+
- Cointegration > Correlation
|
|
838
|
+
- Z-score provides objective framework
|
|
839
|
+
- Mean reversion is not guaranteed (use stop losses)
|
|
840
|
+
- Economic linkage strengthens statistical relationship
|
|
841
|
+
- Simplicity and robustness > complexity and optimization
|
|
842
|
+
|
|
843
|
+
**Further Reading:**
|
|
844
|
+
- Engle & Granger (1987): "Co-Integration and Error Correction: Representation, Estimation, and Testing"
|
|
845
|
+
- Gatev, Goetzmann, Rouwenhorst (2006): "Pairs Trading: Performance of a Relative-Value Arbitrage Rule"
|
|
846
|
+
- Vidyamurthy (2004): "Pairs Trading: Quantitative Methods and Analysis"
|
|
847
|
+
- Chan (2013): "Algorithmic Trading: Winning Strategies and Their Rationale" (Chapter 7)
|
|
848
|
+
|
|
849
|
+
---
|
|
850
|
+
|
|
851
|
+
**Document Version**: 1.0
|
|
852
|
+
**Last Updated**: 2025-11-08
|
|
853
|
+
**Author**: Claude Trading Skills - Pair Trade Screener
|