""" TradeSense AI — Canonical Market Data Normalizer Transforms raw provider CanonicalBar collections into standardized Pandas DataFrames. """ from typing import List import pandas as pd from backend.data.providers.base import CanonicalBar class CanonicalNormalizer: """Standardizes bar structures into canonical DataFrame representations.""" @staticmethod def to_dataframe(bars: List[CanonicalBar]) -> pd.DataFrame: """Converts list of CanonicalBar objects to a sorted, cleaned DataFrame.""" if not bars: return pd.DataFrame(columns=["session", "Open", "High", "Low", "Close", "Volume", "VWAP"]) records = [ { "session": b.session, "Open": b.open, "High": b.high, "Low": b.low, "Close": b.close, "Volume": b.volume, "VWAP": b.vwap if b.vwap is not None else b.close, } for b in bars ] df = pd.DataFrame(records) # Ensure correct datatypes df["Open"] = df["Open"].astype(float) df["High"] = df["High"].astype(float) df["Low"] = df["Low"].astype(float) df["Close"] = df["Close"].astype(float) df["Volume"] = df["Volume"].astype(float) df["VWAP"] = df["VWAP"].astype(float) # Drop duplicates by session and sort ascending df = df.drop_duplicates(subset=["session"]).sort_values("session").reset_index(drop=True) return df