import pandas as pd from . import nsepythonmodified as ns from . import persist from datetime import datetime as dt def build_bhavcopy_html(date_str): key = f"bhavcopy_{date_str}" # ------------------------------------------------------- # 0) Use cached HTML if present # ------------------------------------------------------- if persist.exists(key, "html"): cached = persist.load(key, "html") if cached is not False: print( f"[{dt.now().strftime('%Y-%m-%d %H:%M:%S')}] " f"Using cached bhavcopy for {date_str}" ) return cached try: # ------------------------------------------------------- # 1) Validate Date (DD-MM-YYYY) # ------------------------------------------------------- try: dt.strptime(date_str, "%d-%m-%Y") except ValueError: html = "

Invalid date format. Use DD-MM-YYYY.

" persist.save(key, html, "html") return html # ------------------------------------------------------- # 2) Fetch Bhavcopy (nsepython expects DD-MM-YYYY) # ------------------------------------------------------- try: df = ns.nse_bhavcopy(date_str) df.columns = df.columns.str.strip() except Exception: html = f"

No Bhavcopy found for {date_str}.

" persist.save(key, html, "html") return html # ------------------------------------------------------- # 3) Drop unwanted columns # ------------------------------------------------------- remove = ["DATE1", "LAST_PRICE", "AVG_PRICE"] df.drop(columns=[c for c in remove if c in df.columns], inplace=True) # ------------------------------------------------------- # 4) Convert numeric columns # ------------------------------------------------------- numeric_cols = [ "PREV_CLOSE", "OPEN_PRICE", "HIGH_PRICE", "LOW_PRICE", "CLOSE_PRICE", "TTL_TRD_QNTY", "TURNOVER_LACS", "NO_OF_TRADES", "DELIV_QTY", "DELIV_PER" ] for col in numeric_cols: if col in df.columns: df[col] = ( df[col] .astype(str) .str.replace(",", "", regex=False) .str.strip() ) df[col] = pd.to_numeric(df[col], errors="coerce").fillna(0) # ------------------------------------------------------- # 5) Filter & sort # ------------------------------------------------------- df = df[df["TURNOVER_LACS"] > 1000] df = df.sort_values("TURNOVER_LACS", ascending=False) # ------------------------------------------------------- # 6) Computed columns # ------------------------------------------------------- df["change"] = df["CLOSE_PRICE"] - df["PREV_CLOSE"] df["perchange"] = (df["change"] / df["PREV_CLOSE"].replace(0, 1)) * 100 df["pergap"] = ( (df["OPEN_PRICE"] - df["PREV_CLOSE"]) / df["PREV_CLOSE"].replace(0, 1) ) * 100 # ------------------------------------------------------- # 7) HTML Output # ------------------------------------------------------- main_html = f"""
{df.to_html(index=False, escape=False)}
""" metrics = ["perchange", "pergap", "TURNOVER_LACS", "NO_OF_TRADES", "DELIV_PER"] col_html = [] for m in metrics: if m in df.columns: temp = df[["SYMBOL", m]].sort_values(m, ascending=False) col_html.append( f"""

{m}

{temp.to_html(index=False, escape=False)}
""" ) grid_html = f"""
{''.join(col_html)}
""" css = """ """ html = ( css + "

Main Bhavcopy Table

" + main_html + "

Matrix/Grid Table

" + grid_html ) persist.save(key, html, "html") return html except Exception as e: print( f"[{dt.now().strftime('%Y-%m-%d %H:%M:%S')}] " f"Error build_bhavcopy_html: {e}" ) return f"

Error: {e}

"