import os, yaml, requests, re, yfinance as yf from datetime import datetime, timezone, timedelta from telegram import Bot # ── load secrets ───────────────────────────────────────────────────────── GNEWS_KEY = os.getenv("GNEWS_KEY") TG_BOT = Bot(os.getenv("TELEGRAM_TOKEN")) CHAT_ID = os.getenv("TELEGRAM_CHAT_ID") # ── helper constants ────────────────────────────────────────────────────── BASE_MAP = "sector_map.yaml" DYN_MAP = "sector_map_dynamic.yaml" # ── time helper ──────────────────────────────────────────────────────────── def ist_now(): return datetime.now(timezone.utc) + timedelta(hours=5, minutes=30) # ── yaml loaders ────────────────────────────────────────────────────────── def load_yaml(path): if not os.path.exists(path): return {} with open(path) as f: return yaml.safe_load(f) or {} SECTOR = load_yaml(BASE_MAP) DYN = load_yaml(DYN_MAP) def save_dynamic(store): with open(DYN_MAP, "w") as f: yaml.safe_dump(store, f) # ── news & keyword helpers ───────────────────────────────────────────────── def fetch_news(max_items=250): today = datetime.utcnow().strftime("%Y-%m-%d") url = ( f"https://gnews.io/api/v4/search" f"?q=India&lang=en&from={today}&token={GNEWS_KEY}&max={max_items}" ) return requests.get(url, timeout=20).json().get("articles", []) def keyword_hit(text, keywords): txt = text.lower() return any(k.lower() in txt for k in keywords) # ── ticker validation ────────────────────────────────────────────────────── def validate_ticker(tkr, cutoff=5e12): if not tkr.endswith(".NS"): tkr += ".NS" try: info = yf.Ticker(tkr).info cap = info.get("marketCap") or 0 return tkr if cap > cutoff else None except: return None # ── telegram sender ──────────────────────────────────────────────────────── def send_tg(md): TG_BOT.send_message(chat_id=CHAT_ID, text=md, parse_mode="MarkdownV2")