{"record":{"id":"c2be5f04c967c42b","repo":"OpenBB-finance/OpenBB","slug":"no-close-column-found-in-dataframe","errorCode":null,"errorMessage":"No close column found in dataframe","messagePattern":"No close column found in dataframe","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"openbb_platform/obbject_extensions/charting/openbb_charting/core/plotly_ta/data_classes.py","lineNumber":276,"sourceCode":"        ma_mode: list[str] | None = None,\n    ):\n        \"\"\"Initialize.\"\"\"\n        # pylint: disable=import-outside-toplevel\n        from pandas import DataFrame, Series  # noqa\n        from openbb_charting.core.plotly_ta.ta_helpers import check_columns  # noqa\n\n        if isinstance(df_ta, Series):\n            df_ta = df_ta.to_frame()\n\n        if not isinstance(indicators, ChartIndicators):\n            indicators = ChartIndicators.from_dict(indicators)\n\n        self.df_ta: DataFrame = df_ta\n        self.indicators: ChartIndicators = indicators\n        self.ma_mode: list[str] = ma_mode or [\"sma\", \"ema\", \"wma\", \"hma\", \"zlma\", \"rma\"]\n        self.close_col = check_columns(df_ta)\n        if self.close_col is None:\n            raise ValueError(\"No close column found in dataframe\")\n\n        self.columns: dict[str, list[str]] = {\n            \"ad\": [\"high\", \"low\", self.close_col, \"volume\"],\n            \"adosc\": [\"high\", \"low\", self.close_col, \"volume\"],\n            \"adx\": [\"high\", \"low\", self.close_col],\n            \"aroon\": [\"high\", \"low\"],\n            \"atr\": [\"high\", \"low\", self.close_col],\n            \"cci\": [\"high\", \"low\", self.close_col],\n            \"donchian\": [\"high\", \"low\"],\n            \"fisher\": [\"high\", \"low\"],\n            \"kc\": [\"high\", \"low\", self.close_col],\n            \"obv\": [self.close_col, \"volume\"],\n            \"stoch\": [\"high\", \"low\", self.close_col],\n            \"vwap\": [\"high\", \"low\", self.close_col, \"volume\"],\n        }\n\n        self.has_volume = \"volume\" in df_ta.columns and bool(df_ta[\"volume\"].sum() > 0)\n","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/obbject_extensions/charting/openbb_charting/core/plotly_ta/data_classes.py#L258-L294","documentation":"PlotlyTA(data_classes.py:276) requires an identifiable close column: it calls check_columns(df_ta) (plotly_ta/ta_helpers.py) which searches for a column matching 'Adj Close', 'adj_close', or 'Close' case-insensitively. If none is found the constructor raises ValueError(\"No close column found in dataframe\") because nearly every technical indicator (ad, adosc, adx, atr, cci, kc, obv, ...) needs close prices.","triggerScenarios":"Constructing PlotlyTA (directly or via charting with indicators) on a DataFrame whose price column is named differently — e.g. 'last', 'price', '4. close', or a localized name — or one that only has volume.","commonSituations":"Feeding charting output from a custom provider whose Close field was renamed during transform_data; using intraday frames where the provider emits 'close' only after normalization that was skipped; passing symbol-keyed multi-level columns so str(columns) no longer matches the regex cleanly.","solutions":["Rename the price column before charting: df = df.rename(columns={\"last\": \"close\"}).","If columns are MultiIndex/tuples, flatten them to plain strings first (df.columns = df.columns.get_level_values(0)).","Pass a standard OHLC frame (open/high/low/close, volume) from the router instead of a hand-built one.","Disable indicators if you only want candles: indicators={}"],"exampleFix":"# before\nPlotlyTA(df_ta=df, indicators={\"sma\": {}})  # ValueError: No close column found in dataframe\n\n# after\ndf = df.rename(columns={\"last\": \"close\"})\nPlotlyTA(df_ta=df, indicators={\"sma\": {}})","handlingStrategy":"validation","validationCode":"import re\nCLOSE_RE = re.compile(r\"(Adj\\sClose|adj_close|Close)\", re.IGNORECASE)\n\ndef has_close_column(df) -> bool:\n    return any(CLOSE_RE.search(c) for c in map(str, df.columns))\n\nif not has_close_column(df):\n    df = df.rename(columns={\"last\": \"close\"})","typeGuard":"def ta_frame(df: pd.DataFrame) -> bool:\n    cols = {str(c).lower() for c in df.columns}\n    return bool(cols & {\"close\", \"adj close\", \"adj_close\"})","tryCatchPattern":"try:\n    ta = PlotlyTA(df_ta=df, indicators=indicators)\nexcept ValueError as e:\n    if \"close column\" in str(e):\n        raise ValueError(\"charting requires a close column; rename your price column\") from e\n    raise","preventionTips":["Standardize frames to lowercase open/high/low/close/volume before charting.","Flatten MultiIndex columns to plain strings.","When piping provider data, verify the close field survived transform_data."],"tags":["python","openbb","charting","technical-analysis","data-validation"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}