{"record":{"id":"512f0868a06a8204","repo":"HKUDS/Vibe-Trading","slug":"vwap-equity-cn-requires-panel-amount-and-panel","errorCode":null,"errorMessage":"vwap(equity_cn) requires panel['amount'] and panel['volume']","messagePattern":"vwap\\(equity_cn\\) requires panel\\['amount'\\] and panel\\['volume'\\]","errorType":"validation","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"agent/src/factors/base.py","lineNumber":348,"sourceCode":"      suspended bars.\n    - ``equity_us`` / ``equity_hk`` / ``equity_in`` / ``equity_kr`` /\n      ``futures``: typical price ``(H + L + C + O) / 4`` when ``panel[\"vwap\"]``\n      is absent. India (NSE/BSE) bars from Yahoo and Korea (KRX) bars from\n      pykrx carry raw price/volume (no Tushare 千元/手 scaling), so the\n      typical-price form applies unchanged.\n    - ``crypto``: prefer ``panel[\"vwap\"]`` if provided, else typical price.\n\n    Any missing required column → NaN propagation; never silent zero.\n    \"\"\"\n    if isinstance(market, str):\n        market = Market(market)\n\n    if \"vwap\" in panel:\n        return panel[\"vwap\"]\n\n    if market is Market.EQUITY_CN:\n        if \"amount\" not in panel or \"volume\" not in panel:\n            raise KeyError(\"vwap(equity_cn) requires panel['amount'] and panel['volume']\")\n        return safe_div(panel[\"amount\"] * 1000.0, panel[\"volume\"] * 100.0 + 1.0)\n\n    required = (\"open\", \"high\", \"low\", \"close\")\n    missing = [k for k in required if k not in panel]\n    if missing:\n        raise KeyError(f\"vwap({market.value}) requires panel keys {required}; missing {missing}\")\n    return (panel[\"open\"] + panel[\"high\"] + panel[\"low\"] + panel[\"close\"]) / 4.0\n","sourceCodeStart":330,"sourceCodeEnd":356,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/factors/base.py#L330-L356","documentation":"For Market.EQUITY_CN, vwap is computed as (amount * 1000) / (volume * 100 + 1) from CNY amount and share volume. If the panel lacks either 'amount' or 'volume' columns (and no precomputed 'vwap' column exists), KeyError is raised.","triggerScenarios":"Calling vwap on an equity_cn panel missing panel['amount'] or panel['volume'], e.g. only OHLC bars were loaded.","commonSituations":"Data loaders that only fetch OHLCV close/volume but not CNY amount, switching market from US to CN without changing the data pipeline, or a precomputed 'vwap' column being dropped during preprocessing.","solutions":["Include 'amount' and 'volume' columns in the CN panel","Or supply a precomputed panel['vwap'] column which is returned as-is","Ensure your data source (e.g. CN exchange feed) provides CNY amount"],"exampleFix":"# before\npanel = load_ohlc(codes)  # no amount\nvwap(panel, Market.EQUITY_CN)\n# after\npanel = load_ohlc_with_amount(codes)\nvwap(panel, Market.EQUITY_CN)","handlingStrategy":"validation","validationCode":"required = {'amount', 'volume'}\nmissing = required - set(panel.keys())\nassert not missing, f'equity_cn panel missing: {missing}'","typeGuard":"def has_cn_vwap_inputs(panel: dict) -> bool:\n    return 'vwap' in panel or ({'amount', 'volume'} <= set(panel.keys()))","tryCatchPattern":"try:\n    v = vwap(panel, Market.EQUITY_CN)\nexcept KeyError as e:\n    log.warning(f'vwap unavailable: {e}'); v = None  # or fallback factor","preventionTips":["Assert required panel columns right after data loading","Centralize per-market column requirements in the data pipeline"],"tags":["vwap","missing-column","equity-cn","data-pipeline"],"backgroundTag":"missing-required-column","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}