microsoft/qlib · warning · ValueError
The fund contains 每*份收益
Error message
The fund contains 每*份收益
What it means
Raised by FundCollector.get_data_from_remote when the fund's SYType field (from eastmoney's LSJZ NAV payload) is one of {'每万份收益','每百份收益','每百万份收益'} — per-10000/100/1M-share yield funds (money-market style) that do not publish net asset value per unit, so NAV normalization is impossible. Like 578, it is caught by the outer handler: logged as a warning and the method returns None.
Source
Thrown at scripts/data_collector/fund/collector.py:120
def get_data_from_remote(symbol, interval, start, end):
error_msg = f"{symbol}-{interval}-{start}-{end}"
try:
# TODO: numberOfHistoricalDaysToCrawl should be bigger enough
url = INDEX_BENCH_URL.format(
index_code=symbol, numberOfHistoricalDaysToCrawl=10000, startDate=start, endDate=end
)
resp = requests.get(url, headers={"referer": "http://fund.eastmoney.com/110022.html"}, timeout=None)
if resp.status_code != 200:
raise ValueError("request error")
data = json.loads(resp.text.split("(")[-1].split(")")[0])
# Some funds don't show the net value, example: http://fundf10.eastmoney.com/jjjz_010288.html
SYType = data["Data"]["SYType"]
if SYType in {"每万份收益", "每百份收益", "每百万份收益"}:
raise ValueError("The fund contains 每*份收益")
# TODO: should we sort the value by datetime?
_resp = pd.DataFrame(data["Data"]["LSJZList"])
if isinstance(_resp, pd.DataFrame):
return _resp.reset_index()
except Exception as e:
logger.warning(f"{error_msg}:{e}")
def get_data(
self, symbol: str, interval: str, start_datetime: pd.Timestamp, end_datetime: pd.Timestamp
) -> [pd.DataFrame]:
def _get_simple(start_, end_):
self.sleep()
_remote_interval = interval
return self.get_data_from_remote(
symbol,
interval=_remote_interval,View on GitHub (pinned to 79633dd950)
Solutions
- Exclude money-market funds from the collection list (filter codes known to be MMFs) — the collector deliberately skips them.
- If you need their returns, collect 万份收益 series from eastmoney separately and convert, rather than expecting the NAV pipeline to handle them.
- Treat the logged warning as expected skip behavior when it appears for MMF codes; no code fix needed for regular funds.
Example fix
# before # collecting all fund codes including MMFs run download_data --source_dir ... # after # filter out money market funds (SYType 每*份收益) from instrument list first funds = [f for f in funds if not is_money_market_fund(f)]
Defensive patterns
Strategy: fallback
Validate before calling
# pre-filter money market funds from the instrument list before collecting
SY_YIELD_TYPES = {"每万份收益", "每百份收益", "每百万份收益"}
def is_nav_fund(symbol) -> bool:
# probe SYType once; MMFs are excluded from collection
... Try / catch
try:
df = FundCollector.get_data_from_remote(symbol, interval, start, end)
except ValueError as e:
if "每*份收益" in str(e):
logger.info(f"{symbol}: money-market fund, skipped")
df = None
else:
raise Prevention
- Curate the fund list: exclude money-market/wealth-management funds (they quote per-lot yield, not NAV).
- Expect logged skips for MMF codes; monitor warnings rather than treating them as failures.
- If MMF returns are needed, collect the 万份收益 series with a dedicated pipeline.
When it happens
Trigger: Collecting data for a money-market/wealth-management fund code (e.g. 010288-style codes referenced in the code comment) whose eastmoney page shows 每*份收益 instead of unit NAV.
Common situations: Batch-collecting an instrument list that includes money market funds (货币基金) alongside regular funds; users unaware that MMFs quote yield-per-lot rather than NAV.
Related errors
- request error
- interval error: {self.interval}
- source_dir and target_dir cannot be None
- response status: {_status}, url={url}
- Unsupported freq: {freq}
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/1a0b96f5f0d4bc65.
Report an issue: GitHub.