Skip to content
dsh.fish
Agent preset

dsh-factor-investing

A DeepSeek Harness (DSH) agent preset for institutional multi-factor stock-selection research: methodology knowledge base + zero-dependency factor statistics.

Source
Nzssm1
stars
4 stars
License
MIT
Updated
Updated 9 days ago

Readme

# dsh-factor-investing · Multi-Factor Stock-Selection Quant Researcher

A [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness) community **agent preset** for institutional multi-factor stock selection (A-share oriented). It turns the broker/hedge-fund multi-factor pipeline into a discipline-aware researcher: a methodology knowledge base covering the full pipeline, plus a **deterministic Rust core** for reproducible factor statistics.

> Community project — NOT an official DeepSeek preset and not endorsed by DeepSeek. See [Relationship with DeepSeek](#10-relationship-with-deepseek).

## 1. Introduction

- **preset id**: `dsh-factor-investing` (the directory name; must match `[a-z0-9][a-z0-9-]*`)
- **display name**: 多因子选股量化研究员 (Multi-Factor Stock-Selection Quant Researcher)
- **positioning**: institutional research assistant for data → factors → testing → synthesis → portfolio → backtest → monitoring
- **scenarios**: factor mining & testing (IC/IR, Fama-MacBeth, incremental alpha), factor preprocessing & synthesis, Barra risk models, portfolio optimization, backtesting & live monitoring, quant code reproduction
- **computation architecture**: all core numeric work is delegated to a Rust CLI (`scripts/factor-stats`); the Agent writes only factor definitions and glue code

## 2. Why this preset

A generic chat model reduces "multi-factor" to "sum a few factors" and treats "good backtest = valid factor". Institutional multi-factor is an **industrial pipeline**, and its real edge over retail practice is **statistical discipline**:

- A factor's IC looking good ≠ useful — a new factor must pass an **incremental-alpha test** (regress its returns on known factors; the intercept α must be significant) to be genuinely new information;
- skipping size neutralization = an implicit small-cap bet; skipping industry neutralization = a value factor that always picks banks;
- multiple-testing correction (t>3 for novel factors), out-of-sample discipline, and cost/fill-rate assumptions decide whether a backtest is believable at all.

This preset writes that discipline into the system prompt via the persona, ships the methodology as a skill for on-demand loading, and pins the numeric algorithms in Rust so the same data and version produce the same numbers every time.

## 3. How it works

Three parts, all shipped with the repo:

1. **persona (system prompt)** — `agent.cordis.yml` injects a quant-researcher identity through `@deepseek-ai/dsh-persona`, embedding the pipeline, core discipline, and the hard rule that the Agent only writes factor definitions/glue code while all core computations go through the Rust CLI.
2. **skill (on-demand methodology)** — `skills/factor-investing-pipeline/` is registered through `@deepseek-ai/dsh-skill-filesystem`'s `customSkillDirs`; the model loads the relevant chapter with the `skill` tool.
3. **Rust core engine** — `src/` + `Cargo.toml` implement winsorization (MAD/3σ/percentile), standardization, neutralization, IC/ICIR, two-stage Fama-MacBeth, Gram-Schmidt orthogonalization; `scripts/factor-stats` is the stable JSON-in/JSON-out CLI and the Agent's only computation entry point.

The toolset keeps the full `standard` coding capability; only the identity and knowledge change, so the tool catalog — and thus the request-prefix cache — stays stable.

## 4. Rust CLI usage

Every command reads one JSON object from stdin and writes JSON to stdout; `null` represents missing/NaN values in both directions. Errors go to stderr with a non-zero exit. See [`RUST_CORE.md`](RUST_CORE.md) for the full command list and JSON fields.

```sh
# First call auto-builds the release binary (later calls use target/release/factor-stats)
echo '{"values":[1,2,3,4,5]}' | scripts/factor-stats zscore
echo '{"values":[1,2,3,4,5,6,7,8,9,1000]}' | scripts/factor-stats winsorize-mad
echo '{"factor":[1,2,3,4,5,6,7,8],"exposures":[[1],[2],[3],[4],[5],[6],[7],[8]]}' | scripts/factor-stats neutralize
echo '{"factors":[[1,2,3,4],[1,2,3,4]],"returns":[[2,4,6,8],[1,2,3,4]]}' | scripts/factor-stats ic-series
echo '{"values":[0.05,0.06,0.04,0.05,0.07,0.03]}' | scripts/factor-stats icir
echo '{"exposures":[[[1],[2]],[[1],[2]]],"returns":[[0.5,0.9],[0.6,1.2]]}' | scripts/factor-stats fama-macbeth
```

Commands: `mean`, `std`, `median`, `mad`, `quantile`, `rank`, `corr`, `spearman`, `winsorize-mad`, `winsorize-sigma`, `winsorize-percentile`, `zscore`, `neutralize`, `ols`, `pearson-ic`, `spearman-rank-ic`, `ic-series`, `icir`, `ic-tstat`, `fama-macbeth`, `gram-schmidt`.

## 5. Layout

```
dsh-factor-investing/
├── preset.yml                    # display metadata (name + description)
├── agent.cordis.yml              # Cordis composition: persona + tools + skill
├── skills/factor-investing-pipeline/
│   ├── SKILL.md                  # core framework + chapter/topic index
│   ├── chapters/ch00…ch09.md     # ten pipeline stages
│   ├── glossary.md / patterns.md / cheatsheet.md
├── src/stats.rs / src/main.rs    # Rust core algorithms and CLI
├── Cargo.toml / Cargo.lock       # locked Rust dependencies (reproducible builds)
├── RUST_CORE.md                  # Rust core interface and read-only policy
├── scripts/factor-stats          # Rust CLI wrapper (bash / cmd)
├── package.json                  # npm test (cargo test --locked), build:rust
├── README.md / README.zh-CN.md
├── LICENSE (MIT) / NOTICE
├── .gitignore
└── .github/workflows/test.yml    # CI: Rust
```

## 6. Installation

DSH discovers local presets under `<dshHome>/.agent-presets/` (`dshHome` defaults to `~/.dsh`; `%USERPROFILE%\.dsh` on Windows). The preset `id` is the directory name, so clone the repo as that directory.

**Linux / macOS:**

```sh
mkdir -p ~/.dsh/.agent-presets
git clone https://github.com/Nzssm1/dsh-factor-investing.git \
  ~/.dsh/.agent-presets/dsh-factor-investing
```

**Windows (PowerShell):**

```powershell
New-Item -ItemType Directory -Force "$env:USERPROFILE\.dsh\.agent-presets"
git clone https://github.com/Nzssm1/dsh-factor-investing.git `
  "$env:USERPROFILE\.dsh\.agent-presets\dsh-factor-investing"
```

Restart DSH and pick 「多因子选股量化研究员」 for a new session. If your deployment configures custom preset roots, place the repo under that root instead (`dsh-agent-presets` `roots`).

Rust toolchain requirement: the first `scripts/factor-stats` call needs `cargo` (Rust stable). Install from <https://rustup.rs>.

## 7. Verification

1. **persona active** — the first system prompt of a new session carries the quant-researcher identity, pipeline/discipline, and the Rust-computation rule (including "Rust core is read-only").
2. **skill registered** — ask "list skills"; `factor-investing-pipeline` should appear, or ask it to "load chapter ch04 of factor-investing-pipeline".
3. **Rust core works** — run `cargo test --locked` (24 Rust tests pass) or `echo '{"values":[1,2,3,4]}' | scripts/factor-stats mean` → `2.5`.
4. **full tests** — `npm test` runs `cargo test --locked`.

## 8. Important behaviors

- The preset does **not** change the tool catalog; it keeps `standard`'s tools and only replaces the persona and registers the skill, so there is no bootstrap/full switching and the prefix cache stays stable.
- **Computation discipline**: all fixed computations are implemented in Rust, and the Agent's only computation entry point is `scripts/factor-stats`. The Agent must not re-implement these algorithms in Python/JS, and must not use pandas/numpy in place of Rust.
- **Rust core is read-only for the Agent**: `src/`, `Cargo.toml`, `Cargo.lock`, and `scripts/factor-stats*` are the fixed computation layer. The Agent must not create, modify, or delete them; if a new fixed computation is needed, the Agent must ask the user/maintainer to extend the Rust core instead of editing it.
- **Rust boundary**: the Rust core contains only generic mathematical/statistical primitives. Commission, slippage, fill-rate, T+1, stock universe, market rules, and portfolio parameters are user-specific and must stay in the Agent glue/config layer — never in Rust.
- Knowledge-base thresholds are **rough heuristics** (|IC|>0.03 keep, >0.05 usable, ICIR 0.2–0.5 common, 20–40bp cost), tied to stock-pool breadth, dispersion, and IC frequency — not universal targets; verify sample in/out-of-sample, cost, annualization, and multiple-testing before citing.
- Broker figures (e.g. 湘财 "59 → 22" factors, long-short Sharpe 2.92) are magnitude references from a single, unspecified-cost sample.
- The Rust CLI speaks JSON; `null` means missing/NaN. Glue code can convert between pandas/numpy DataFrames and this JSON interface.

## 9. Compatibility

- Built for **DeepSeek Harness 0.1.0-rc.6**: `preset.yml` (display metadata) + `agent.cordis.yml` (Cordis composition) + `@deepseek-ai/dsh-persona` (persona) + `@deepseek-ai/dsh-skill-filesystem` `customSkillDirs` (preset-local skill).
- This is a **domain-expert preset**, not the older (0.1.0-rc.5 / commit 47f9438) "two-stage tool catalog" pattern that hand-wrote a `system-prompt/assemble` listener. In the current version the system prompt comes from `@deepseek-ai/dsh-persona`, and "the catalog changes once" is satisfied by not changing it at all.
- **Manual confirmations**: ① repo name vs. preset id (rename the directory if they differ); ② the copyright holder in `LICENSE` (currently `Nzssm1`); ③ whether your deployment sets custom preset roots (default `~/.dsh/.agent-presets/`); ④ on a non-rc.6 deployment, field names for `customSkillDirs` / `dsh-persona` may differ — check that version's `dsh-agent-presets` / `dsh-persona` README.

## 10. Relationship with DeepSeek

- This is a **community project** by GitHub user `Nzssm1`;
- it is **not an official DeepSeek preset**, is not hosted in an official DeepSeek repo, and the official repo does not accept external PRs;
- it is **not endorsed or sponsored by DeepSeek**;
- `agent.cordis.yml` is adapted from the `standard` preset shipped with DeepSeek Harness (Copyright (c) 2026 DeepSeek, MIT) and the MIT notice is retained (see `NOTICE`); the methodology knowledge base is adapted from the author's own research report, whose cited broker research and 《因子投资:方法与实践》 remain the property of their respective authors/publishers.

## 11. Tests

```sh
# Rust core full test suite
npm test

# Rust tests / release build separately
npm run test:rust
npm run build:rust
```

## 12. Publishing checklist

1. Create the repo `Nzssm1/dsh-factor-investing` on GitHub;
2. push to `main` (commands below);
3. add the topic `dsh-plugin` under **Settings → Topics** (this is how community directories and the topic page discover it);
4. confirm the `test.yml` workflow passes in **Actions** (including Rust tests);
5. (optional) publish a release.

```sh
git init
git add .
git commit -m "feat: dsh-factor-investing preset with Rust core"
git branch -M main
git remote add origin https://github.com/Nzssm1/dsh-factor-investing.git
git push -u origin main
```

Adding topics: repo page → right-side **About** gear → **Topics** → `dsh-plugin` (suggest also `deepseek-harness`, `dsh`, `factor-investing`, `quant`, `rust`).

Install

# Copy the composition to $DSH_HOME/.agent-presets/dsh-factor-investing/agent.cordis.yml

Profile: web

Source