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

  1. Exclude money-market funds from the collection list (filter codes known to be MMFs) — the collector deliberately skips them.
  2. If you need their returns, collect 万份收益 series from eastmoney separately and convert, rather than expecting the NAV pipeline to handle them.
  3. 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

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


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/1a0b96f5f0d4bc65. Report an issue: GitHub.