Spaces:
Sleeping
Sleeping
| """ | |
| Swing Quant Engine β Central Configuration | |
| All tunable parameters, universe definitions, and thresholds. | |
| """ | |
| import os | |
| from pathlib import Path | |
| from dotenv import load_dotenv | |
| # ββ Paths ββ | |
| BASE_DIR = Path(__file__).parent | |
| DATA_DIR = BASE_DIR / "data" | |
| PARQUET_DIR = DATA_DIR / "parquet" | |
| DB_PATH = DATA_DIR / "quant.db" | |
| # Ensure dirs exist | |
| DATA_DIR.mkdir(exist_ok=True) | |
| PARQUET_DIR.mkdir(exist_ok=True) | |
| # Load env from portfolio_website if local .env doesn't exist | |
| _local_env = BASE_DIR / ".env" | |
| _portfolio_env = BASE_DIR.parent / "portfolio_website" / ".env" | |
| if _local_env.exists(): | |
| load_dotenv(_local_env) | |
| elif _portfolio_env.exists(): | |
| load_dotenv(_portfolio_env) | |
| # ββ API Keys ββ | |
| OPENAI_API_KEY = os.getenv("OPENAI_API_KEY", "") | |
| OPENAI_MODEL = os.getenv("OPENAI_MODEL", "gpt-4o-mini") | |
| PERPLEXITY_API_KEY = os.getenv("PERPLEXITY_API_KEY", "") | |
| FINNHUB_API_KEY = os.getenv("FINNHUB_API_KEY", "") | |
| # ββ Stock Universe ββ | |
| # Indian blue-chips (NSE) β top Nifty 50 + select mid-caps | |
| INDIA_UNIVERSE = [ | |
| "RELIANCE.NS", "TCS.NS", "HDFCBANK.NS", "INFY.NS", "ICICIBANK.NS", | |
| "HINDUNILVR.NS", "BHARTIARTL.NS", "SBIN.NS", "ITC.NS", "KOTAKBANK.NS", | |
| "LT.NS", "AXISBANK.NS", "BAJFINANCE.NS", "ASIANPAINT.NS", "MARUTI.NS", | |
| "HCLTECH.NS", "WIPRO.NS", "SUNPHARMA.NS", "TITAN.NS", "ULTRACEMCO.NS", | |
| "ONGC.NS", "NTPC.NS", "POWERGRID.NS", "TATAMOTORS.NS", "TATASTEEL.NS", | |
| "ADANIENT.NS", "ADANIPORTS.NS", "COALINDIA.NS", "JSWSTEEL.NS", "M&M.NS", | |
| "BAJAJ-AUTO.NS", "TECHM.NS", "HEROMOTOCO.NS", "DRREDDY.NS", "CIPLA.NS", | |
| "DIVISLAB.NS", "APOLLOHOSP.NS", "EICHERMOT.NS", "BPCL.NS", "GRASIM.NS", | |
| "TATACONSUM.NS", "NESTLEIND.NS", "BRITANNIA.NS", "INDUSINDBK.NS", | |
| "HINDALCO.NS", "SBILIFE.NS", "HDFCLIFE.NS", "BAJAJFINSV.NS", | |
| "SHREECEM.NS", "PIDILITIND.NS", | |
| ] | |
| # US blue-chips β S&P 100 subset | |
| US_UNIVERSE = [ | |
| "AAPL", "MSFT", "GOOGL", "AMZN", "NVDA", "META", "TSLA", "BRK-B", | |
| "UNH", "JNJ", "V", "XOM", "JPM", "PG", "MA", "HD", "CVX", "MRK", | |
| "ABBV", "LLY", "PEP", "KO", "COST", "AVGO", "WMT", "MCD", "CSCO", | |
| "ACN", "TMO", "ABT", "DHR", "NEE", "LIN", "PM", "TXN", "UNP", | |
| "RTX", "HON", "LOW", "AMGN", "COP", "QCOM", "ORCL", "GS", "BAC", | |
| "CAT", "SBUX", "AXP", "PFE", "AMD", | |
| ] | |
| # Combined default universe | |
| DEFAULT_UNIVERSE = INDIA_UNIVERSE + US_UNIVERSE | |
| # ββ Technical Signal Thresholds ββ | |
| SIGNAL_PARAMS = { | |
| # RSI | |
| "rsi_oversold": 30, | |
| "rsi_overbought": 75, | |
| "rsi_bullish_zone": (45, 76), # Tightened momentum sweet spot | |
| # MACD | |
| "macd_fast": 12, | |
| "macd_slow": 26, | |
| "macd_signal": 9, | |
| # Bollinger Bands | |
| "bb_period": 20, | |
| "bb_std": 2.0, | |
| # Moving Averages | |
| "sma_short": 20, | |
| "sma_medium": 50, | |
| "sma_long": 200, | |
| "ema_fast": 9, | |
| "ema_slow": 21, | |
| # Volume | |
| "volume_spike_threshold": 2.0, # Increased to 2.0x avg volume for higher conviction | |
| "volume_sma_period": 20, | |
| # ADX (trend strength) | |
| "adx_trending": 25, # ADX > 25 = trending market | |
| # ATR | |
| "atr_period": 14, | |
| # Breakout | |
| "breakout_lookback": 20, # days to look for resistance | |
| "breakout_volume_confirm": 1.3, # min volume multiplier for confirmation | |
| } | |
| # ββ Risk Parameters ββ | |
| RISK_PARAMS = { | |
| "max_position_pct": 5.0, # Max 5% of portfolio in one position | |
| "max_sector_pct": 15.0, # Reduced to 15% for better diversification | |
| "max_drawdown_pct": 15.0, # Kill switch at 15% portfolio drawdown | |
| "min_liquidity_inr": 5_00_00_000, # βΉ5Cr daily volume for India | |
| "min_liquidity_usd": 10_000_000, # $10M daily volume for US | |
| "max_atr_pct": 5.0, # Skip stocks with ATR% > 5% | |
| "max_correlation": 0.85, # Reject if corr > 0.85 with existing | |
| "kelly_fraction": 0.25, # Use 25% of Kelly optimal (conservative) | |
| } | |
| # ββ Alpha Scoring Weights ββ | |
| ALPHA_WEIGHTS = { | |
| "momentum": 0.35, | |
| "volume_breakout": 0.20, | |
| "sentiment": 0.20, | |
| "regime_fit": 0.15, | |
| "fundamental": 0.10, | |
| } | |
| # ββ Scan Schedule ββ | |
| SCAN_INTERVAL_HOURS = 4 # Re-scan every 4 hours during market hours | |
| # ββ Market Hours (for scheduling) ββ | |
| MARKET_HOURS = { | |
| "india": {"open": "09:15", "close": "15:30", "tz": "Asia/Kolkata"}, | |
| "us": {"open": "09:30", "close": "16:00", "tz": "America/New_York"}, | |
| } | |
| # ββ Backtest Defaults ββ | |
| BACKTEST_PARAMS = { | |
| "in_sample_months": 12,#6 | |
| "out_sample_months": 3,#1 | |
| "commission_india_pct": 0.1, | |
| "commission_us_pct": 0.05, | |
| "slippage_pct": 0.05, | |
| "initial_capital": 10_00_000, # βΉ10L or $10K equivalent | |
| } | |
| # ββ Logging ββ | |
| import logging | |
| LOG_FORMAT = "%(asctime)s [%(levelname)s] %(name)s: %(message)s" | |
| logging.basicConfig(level=logging.INFO, format=LOG_FORMAT) | |