HKUDS/Vibe-Trading · error · RuntimeError

tushare not installed

Error message

tushare not installed: {exc}

What it means

The csi300 loader imports tushare lazily; if the package is not installed in the active environment, this RuntimeError wraps the ImportError with the underlying message.

Solutions

  1. pip install tushare into the environment running the agent
  2. Verify with: python -c 'import tushare' using the same interpreter
  3. Pin the dependency in requirements/pyproject if csi300 support is needed

Example fix

# before: ImportError wrapped as RuntimeError
# after
pip install tushare
Defensive patterns

Strategy: fallback

Validate before calling

try:
    import tushare  # noqa
    ok = True
except ImportError:
    ok = False

Try / catch

try:
    _load_csi300_panel(s, e)
except RuntimeError as e:
    if 'tushare not installed' in str(e):
        subprocess.run([sys.executable, '-m', 'pip', 'install', 'tushare'], check=True)

Prevention

When it happens

Trigger: Calling the csi300 universe path in an environment where 'import tushare' fails (package not installed or wrong virtualenv/interpreter).

Common situations: Running the agent in a venv created from a partial requirements file; deploying with a slimmed dependency set that omitted tushare; multiple interpreters where the tool runs under a different one.

Understand the failure class

Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/f42c4235c71467f8. Report an issue: GitHub.

Appendix: source

Thrown at agent/src/tools/alpha_bench_tool.py:325


def _load_csi300_panel(start: str, end: str) -> dict[str, pd.DataFrame]:
    """CSI 300 panel via Tushare. Includes ``amount`` (required by gtja191).

    Constituents are taken from the most recent ``index_weight`` snapshot in
    the requested window; if that call fails we degrade to a 30-name
    blue-chip fallback so the bench still runs.
    """
    token = get_env_config().data.tushare_token.strip()
    if not token or token == "your-tushare-token":
        raise RuntimeError(
            "TUSHARE_TOKEN not in agent/.env or environment; required for csi300 universe"
        )

    try:
        import tushare as ts
    except ImportError as exc:
        raise RuntimeError(f"tushare not installed: {exc}") from exc

    pro = ts.pro_api(token)
    sd = start.replace("-", "")
    ed = end.replace("-", "")

    codes: list[str] = []
    constituent_source = "tushare index_weight"
    constituent_source_date: str | None = None
    membership: pd.DataFrame | None = None
    try:
        # Reach back before ``start`` so the snapshot that was in force on the
        # first requested day is included; Tushare publishes month-end rosters.
        lookback = (pd.Timestamp(start) - pd.Timedelta(days=60)).strftime("%Y%m%d")
        weights = pro.index_weight(
            index_code="399300.SZ", start_date=lookback, end_date=ed
        )
        if weights is not None and not weights.empty:
            frame = weights.copy()

View on GitHub (pinned to 80ffdda44c)