插件目录 / Developer / dsh-ths-holdings
dsh-ths-holdings
未验证 PM25000
功能简介
DSH 持仓盈亏悬浮卡片(同花顺投资账本)— 自动同步真实持仓数据,显示今日盈亏、上证指数和当日走势图,无需手动添加股票。
未验证 — 尚未实测
DSH 持仓盈亏悬浮卡片(同花顺投资账本)— 自动同步真实持仓数据,显示今日盈亏、上证指数和当日走势图,无需手动添加股票。 尚未验证——请自行安装测试。
「未验证」表示我们的自动化 CI 尚未安装过该插件。功能描述与版本兼容性均为作者声明。这不是安全审计,也不代表对第三方代码的背书。
README
dsh-ths-holdings
English | 中文
A floating position P&L card for the DeepSeek Harness (DSH) web GUI. It automatically syncs your real portfolio data from the Tonghuashun investment-ledger (同花顺投资账本) — no manual stock picking. Displays 今日盈亏 (today's P&L), 上证指数 (Shanghai Composite Index), and an intraday mini chart, all in the A-share red-up/green-down convention.
Unlike watchlist tools, this plugin reads your actual positions and shows your real profit & loss — both as a percentage and as a yuan amount — updating every 20 seconds.
Screenshots

Installation
dsh plugin --profile web add dsh-ths-holdings
Installation is pnpm add inside your web profile: the package's dsh.bundle.patch is applied to the profile layer automatically. Then restart dsh web — a floating card appears at the bottom-right corner.
To install manually (without dsh plugin), edit $DSH_HOME/profiles/web/package.json:
{
"dependencies": {
"dsh-ths-holdings": "^0.1.0"
},
"dsh": {
"profile": {
"bundles": [
// ...existing bundles,
"dsh-ths-holdings"
]
}
}
}
then cd $DSH_HOME/profiles/web && pnpm install and restart dsh web. The plugin row itself comes from the package's cordis.patch.yml — you don't write it by hand.
Usage
Recommended — auto-acquire:
- Open the DSH web GUI — click ⚙ on the card.
- Click 🖥 自动获取 Cookie(推荐) — a system browser window opens (Edge / Chrome — the first installed one wins).
- Sign in to the Tonghuashun investment ledger in that window (QR code / account).
- When the sign-in succeeds the window closes itself, the Cookie is saved automatically, and the card refreshes with your portfolio.
- The plugin auto-discovers your portfolio — if you have several, pick one from the dropdown. Done.
The auto-acquired Edge window ships anti-automation camouflage (hides
navigator.webdriver, disables the AutomationControlled Blink feature) to pass the Tonghuashun WAF. If a specific network/time still shows Nginx forbidden, pressF5in the popped window or open https://tzzb.10jqka.com.cn manually, then click 「我已登录,继续 →」 on the card; only10jqka-domain cookies are kept, never stored as raw plaintext.
Manual (backup):
- Open https://tzzb.10jqka.com.cn and log in.
- Press F12 → Console and run:
copy(document.cookie) - The cookie is now in your clipboard.
- Open the DSH web GUI — click ⚙ on the card, paste the cookie into STOCK_PNL_COOKIE → save.
- The card validates the saved cookie immediately — it shows ✓ valid or ✗ invalid (with the reason/hint).
The session cookie expires eventually — when it does, the card shows a Token 已过期 banner; re-open ⚙ and click auto-acquire (or repeat manual steps 1–4) with a fresh cookie (the v anti-bot token is handled automatically).
💡 After completing a new trade, re-upload your data from the investment-ledger app to the web version so your holdings stay consistent between the two.
Features
- 📊 Real-time position P&L — polls every 20 s (configurable) from your actual portfolio
- ¥ / % toggle — show today's P&L as a yuan amount, a percentage, or both
- 📈 Intraday chart — mini polyline with a zero axis, red-up/green-down
- 🇨🇳 Shanghai Composite Index — displayed alongside your P&L
- 🔄 Auto-discovery —
fund_keyis discovered from the portfolio list; multi-account selection via dropdown - 🖥 Auto-acquire Cookie — one click pops the Edge sign-in window; the cookie is saved automatically, no F12 needed
- ✓ Validate on save — the stored cookie is checked against the ledger right after paste or auto-acquire
- ↕ Draggable — drag the title bar vertically along the right edge (position persists in localStorage)
- ⚙ In-place settings — paste Cookie and select portfolio from the card itself
- 🔒 Credential-safe — the Cookie never leaves the host process
How it works
┌─────────────── Web browser ───────────────┐
│ lib/client.js (browser module) │
│ · shell.overlay slot → floating card │
│ · React + CSS Modules │
│ · config in localStorage │
│ │ fetch (same-origin) │
└──────────┼─────────────────────────────────┘
▼
┌─────────────── DSH Host (lib/index.js) ───┐
│ cordis plugin: webServer routes │
│ · GET /api/stock-pnl snapshot │
│ · GET /api/stock-pnl/portfolios accounts │
│ · GET /api/stock-pnl/verify cookie ok?│
│ · POST /api/stock-pnl/acquire* sign-in │
│ resolves Cookie via ctx.credentials │
│ auto-discovers user_id + fund_key │
│ POSTs Tonghuashun ledger APIs │
└───────────────────────────────────────────┘
The node half reads the login Cookie per request through the credential-reference seam (ctx.credentials) — it never reaches the browser. Credential-bearing requests never follow a redirect. The v anti-bot token is minted per request from the User-Agent; the stored Cookie only needs its session fields.
Auto-acquire runs an in-host state machine (acquire.ts): click the button → an anti-automation Edge window opens the ledger → once the sign-in is detected (userid cookie), the host collects that domain's cookies, commits them through the credential seam, and closes the window. Timeout, an early user window-close, or a WAF interception all surface as actionable notices on the card.
Config
| Key | Default | Meaning |
|---|---|---|
cookieEnv |
STOCK_PNL_COOKIE |
Credential reference holding the ledger Cookie. |
fundKeyEnv |
STOCK_PNL_FUND_KEY |
Credential reference holding the ledger fund key (saved from the card's ⚙ form). |
user_id |
the Cookie's userid |
The ledger user id, included in every form payload; an empty value falls back to the Cookie's own userid. |
fund_key |
auto-discovered | The ledger fund key selecting the managed portfolio; overridden by the fundKeyEnv credential when set, auto-discovered from the account list when empty. |
pnlUrl |
Tonghuashun time_share endpoint |
P&L endpoint override (tests point at a scripted server). |
indexUrl |
Tonghuashun getQuotes endpoint |
Index endpoint override (tests point at a scripted server). |
pollMs |
20000 |
Poll interval (ms) the card uses; reported to the browser in each response's poll_ms. |
Directory structure
dsh-ths-holdings/
├── src/
│ ├── index.ts # node half: webServer routes + credential resolution
│ ├── fetch.ts # Tonghuashun ledger API calls + auto-discovery + cookie verify
│ ├── acquire.ts # auto-acquire cookie (playwright-core drives Edge)
│ └── client/
│ ├── index.ts # browser half: shell.overlay registration
│ └── StockPnlCard.tsx
├── lib/ # built artifacts (index.js + client.js)
├── cordis.patch.yml # dsh.bundle patch layer
├── package.json # dsh.bundle + dsh.client manifests
├── tests/ # ledger / verify / acquire unit tests
└── README.md
FAQ / Troubleshooting
| Symptom | Cause & fix |
|---|---|
Card shows 请配置 Cookie |
STOCK_PNL_COOKIE is empty — click auto-acquire in the ⚙ panel, or paste manually. |
Card shows Token 已过期 |
The session Cookie expired — click auto-acquire in the ⚙ panel to re-sign-in, or re-run copy(document.cookie) and paste. |
| Auto-acquire reports missing playwright-core | playwright-core did not ship with the install (typically a legacy install or a manually pruned dependency tree) — re-pnpm add dsh-ths-holdings (or npm i playwright-core), restart dsh web, retry. |
Popped window shows Nginx forbidden |
The Tonghuashun WAF intermittently refuses automation — F5 in the window or open the ledger URL manually, then click 「我已登录,继续 →」. |
| No portfolio in the dropdown | The account list needs a valid Cookie first; save the Cookie, then click ↻ to refresh. |
| Multiple portfolios | Select the one you want from the dropdown — the choice is saved as STOCK_PNL_FUND_KEY. |
| Cookie pasted with line breaks | The plugin strips whitespace on save, so wrapped lines are fine. |
Model Experience
None — the card is a browser-side overlay over a host data route and registers nothing model-facing.
KV Cache effect
None — the plugin contributes no prompt, schema, or result.
Known Limitations
- The ledger API is an undocumented, login-gated endpoint — its response format can change and the Cookie expires; the plugin surfaces both as errors rather than retrying or caching.
- The portfolio list endpoint (
account_list) requires the Cookie to be saved first — the portfolio selector appears after you paste a valid Cookie. - Auto-acquire reuses a system browser — it drives the bundled playwright-core dependency against whichever of Edge / Chrome is installed (first found wins); with neither present auto-acquire is unavailable (manual paste still works) and the card says so explicitly.
- No server-side polling — the route fetches on each request and the card polls at the configured
pollMsinterval; there is no shared cache or push channel.
License
安装
装一次目录插件,之后本站所有插件都能让 DeepSeek Harness 自动找、自动装:
dsh plugin add dshbase-catalog 然后对 agent 说「帮我装 dsh-ths-holdings」,它会在目录里找到并自动安装。文档:dshbase-catalog · 已验证场景包。
该插件是 GitHub 源码(未发 npm)——直接从仓库装:
Web profile:
dsh plugin --profile web add github:PM25000/dsh-ths-holdings Headless(CLI)profile:
dsh plugin --profile headless add github:PM25000/dsh-ths-holdings 实测报告
尚未 L3 验证——若已跑过,见下方失败备注。
