pengpengyi92/dsh-quant

pengpengyi92/dsh-quant

面向 DeepSeek Harness 的量化研发工具箱,59 个工具覆盖行情、指标、因子评价、滚动样本外机器学习验证、风险(VaR/CVaR/回撤/Beta 与 Kupiec POF)、期权、债券、FICC 和基金模拟,并提供端到端 PDAT→PET 研究管线。

工具与能力ai-agentsalgorithmic-tradingbacktesting

🐳 dsh-quant — The Everything-Plugin Quant OS

📣 Announcement archive: 2026-09-01 X open-source launch copy

🌐 Site: https://dsh-quant-site.pages.dev · ✅ Listed in awesome-dsh-plugin (one-click install via dsh-market)

AI-native & DSH-native quant toolkit for every quant aspect — 59 tools · 6 domains
(data / alpha / ML / risk / execution / ecosystem) · one end-to-end PDAT→PET
research pipeline. Methods open, secrets internal.

🧩 Core Philosophy: Everything is a Plugin (quant edition)

dsh's philosophy is everything is a plugin; dsh-quant brings it to quant — open-sourcing the internal five-team paradigm (PDAT → PAAT → PCPT → PRT → PET) as five pluggable modules:

data plugin   dsh-data      market data / sources / quality  ← plug in Binance or your own data
alpha plugin  dsh-alpha     indicators / factors / eval      ← write your own alpha (internal alpha stays private)
model plugin  dsh-ml        backtests / ML/DL/RL framework   ← train your own models (internal research stays private)
risk plugin   dsh-risk      VaR / drawdown / options / bonds ← set your own risk limits
exec plugin   dsh-execution sim execution / fund / report    ← build your own trading system (paper or live)
  • What's open is the paradigm: how modules compose, how contracts are defined

(null alignment / no look-ahead / hand-computed tests), how results are validated — not the internal secrets

  • You fill it in: product power = UI + strategies + data interfaces + DL/RL

models + trading-system building, all self-assembled, all pluginized

  • Infinite self-evolution: fill the framework with your modules → run paper/live

→ feed the ecosystem back — that's dsh-quant

Plugin call for proposals: Issue #27 (five modules × many plugins) — PDAT plugins, PET plugins, anything you can imagine 🐋

🤖 AI-Native Is Deliberate (design statement)

dsh-quant's primary consumer is the agent (the model), not the human — a deliberate choice from day one:

  • Tool schemas are injected into the system prompt — every contract (args /

outputs / alignment rules) is written from the model's perspective

  • Equal-length null alignment — outputs match input length; leading window

positions are null, so the model aligns by index and never pads

  • Canonical JSON + render separation — machines read structure, humans read prose
  • All isConcurrencySafe — pure functions, no shared state; agents can call all

59 tools in parallel without interference

  • Skill layer — skill/quant-research lets the model load the workflow itself

Full statement: Issue #14 "AI-native is deliberate".

🐍 Why Almost No Python?

A common question: a quant project without .py files? Answer: 0 Python files, 21 TypeScript source files, zero runtime dependencies — deliberate:

  • dsh-quant is a dsh plugin running inside the harness's Node runtime: same

process as the agent, composable by the Loader, reversible registration (HMR-safe) — TypeScript is the only natural choice

  • Where Python is needed (akshare / tushare / baostock), use the **channel knowledge

base** (quant_data_guide, 15 channels): dsh ships shell / subprocess capabilities, so the agent decides whether to spawn Python — dsh-quant carries no runtime

  • All numerical methods (indicators / backtests / options / bonds) are **pure

functions with hand-computed baselines**: zero deps, offline-verifiable, npm test green anywhere

One goal: build the most usable AI-native quant repo 🐋

**59 quant_* tools · 6 domains · 298 tests · zero runtime deps**. Full positioning: pinned Issue #9.

🤖 For visiting agents

Agents landing on this repo: start at AGENTS.md (root-level, auto-read by Copilot / Claude Code / dsh), then the closed-loop example plugin/CASE_STUDY.md or Discussion #38, and the one-glance contract mcp/AGENT_GUIDE.md.

Compatibility release status

The 0.91.1 release candidate includes DSH 0.2.1-rc.2 compatibility, with 0.1.0-rc.6 / 0.2.0-rc.2 / 0.2.1-alpha.3 coverage retained. npm was still at 0.90.0 when this candidate was prepared on 2026-10-18. Check the delivery record and npm view dsh-quant version before treating the fix as published. Original compatibility contribution: @hufeide (#136); user reports: @ziladan (#139 / #140).

The v0.91.1 tag is fixed to the reviewed source. Its first authenticated publisher attempt failed with npm E404, so the tag is not evidence of npm availability. See delivery attempt. Maintainers can manually run release acceptance with source=candidate to reproduce the Linux package, or source=registry after publication to verify four clean real-Loader consumers. The workflow never publishes.

Quick Install (dsh users)

npm i dsh-quant

Add one line to your cordis.yml:

- name: 'dsh-quant'

59 tools auto-register — indicators / backtests / factors / risk / fund simulation / ecosystem metrics out of the box. One quant_research_pipeline runs the whole PDAT→PET chain. ML/DL knowledge: docs/ML_GUIDE.md; executable demo: npx tsx demos/ml-workflow.ts.

🚀 Product Experience: Three Minutes to a Full Quant Pipeline

Right after install, experience the complete PDAT→PET flow (BTC public data + simple strategy + backtest + paper trading):

data(quant_market_fetch) → quality(quant_data_quality) → factors(quant_factor_evaluate)
→ backtest(quant_backtest) → metrics(quant_metrics) → risk(quant_risk)
→ drawdown(quant_drawdown) → paper sim(quant_execute_sim) → fund sim(quant_fund)
→ report(quant_report)

One-liner: quant_research_pipeline(symbol=BTCUSDT, limit=120) returns everything in one call.

Then plug your own plugins into each module (data sources / alpha / models / risk / execution — everything is a plugin, proposals at Issue #27).

Five-step walkthrough with commentary: docs/ONBOARDING.md · Agent one-glance guide: mcp/AGENT_GUIDE.md

🖥️ UI Workbench (dsh-quant-ui)

dsh-quant-ui: candlesticks + MA overlays + trade markers, equity curves, fund NAV / management-fee / performance-fee cards, metric selector — plus a swimming chibi whale 🐋 (click the title 3 times).

Live demo: https://dsh-quant-ui.pages.dev

⌨️ CLI (dsh-quant terminal)

Zero-dependency readable terminal (pure Node + ANSI, same philosophy as the P-Research CLI). Browse the research columns and live market data without a browser:

node cli/main.mjs repo                      # 59 tools · 6 domains
node cli/main.mjs history                   # 53 firm archives index
node cli/main.mjs history citadel           # one firm's archive (rendered)
node cli/main.mjs history --reports         # ANALYSIS / TIMELINE / LINEAGE / BANK_LINEAGE
node cli/main.mjs history --search 高频      # cross-archive search
node cli/main.mjs kline BTCUSDT --limit 20  # colored OHLC table + stats
node cli/main.mjs browse                   # interactive TUI: arrow-key firm browser

After npm install -g ., the commands shorten to dsh-quant repo, dsh-quant history citadel, etc.

Tools

Tool · Parameters · Canonical output · First valid index quant_data_compare · dataType (e.g. "financials"/"daily bars") · { dataType, channels: [{ name, cost, covers, bestFor }] } (covering first) · — quant_data_advice · dataType + budget (free/low/institutional) + purpose (research/backtest/official) · { recommendations: [{ rank, name, reason }] } (decision-tree ranked) · — quant_series_stats · values: number[] · { count, mean, std, min, max, median, skew, kurtosis, autocorr1, annualizedVol, totalReturnPct } · — (first step after fetching) quant_var_backtest · returns + varSeries + confidence=0.95 · { failures, expected, lrStat, pValue, passed, periods } (Kupiec POF test) · — (the ground truth for VaR models) quant_option · spot + strike + timeToMaturity + riskFreeRate + type + exactly one of volatility/price · { price, impliedVolatility, delta, gamma, vega, theta, rho, … } · — (Optiver-inspired: BS pricing + five greeks + IV solve) quant_volatility · close: number[] + annualization=252 · { annualized, perPeriod, n, logReturns(aligned) } · — (realized vol; the RV-vs-IV research entry) quant_bond · couponRate + periodsToMaturity + paymentsPerYear? + exactly one of ytm/price · { price, yieldToMaturity, macaulayDuration, modifiedDuration, convexity, dv01, … } · — (FICC link: pricing/duration/convexity/DV01, textbook discounting) quant_drawdown · equity: number[] · { underwater(aligned), maxDrawdownPct, currentDrawdownPct, periods(peak/trough/recovery/depth/duration), ongoing } · — (drawdown episode analysis) quant_resample · candles + period (week=7 bars/month=30 bars) · { candles } (OHLCV aggregation, 24/7 markets) · — quant_report · strategy/metrics/risk/factor/fund (module outputs) · { report } (Markdown research report) · — (R&D conclusion assembly) quant_repo_stats · owner + repo · { stars, forks, watchers, openIssues, openPullRequests, topics, latestRelease, … } (public GitHub API, no credentials) · — (ecosystem data) quant_npm_stats · pkg · { latest, weeklyDownloads, monthlyDownloads, description, … } (npm registry + downloads API) · — (ecosystem data) quant_oss_pulse · stars + downloadsWeekly? + starsPrevious? + openIssues? + openPullRequests? + daysSinceRelease? · { score(0-100), grade(A-D), components, suggestions, summary } · — (open-source influence score; missing inputs score neutral 50) quant_stress_test · weights + betas + assetVolsPct + correlation=0.6 · { weights, scenarioLossesPct, worstScenario, maxLossPct, portfolioVolPct, notes } · — (portfolio loss under crash/liquidity/vol scenarios) quant_risk · returns (decimal series) + benchmarkReturns? + confidence=0.95 · { var95, cvar95, downsideDeviation, maxDrawdownPct, beta, alpha, informationRatio, trackingError, periods } · — (core risk module) quant_fund · equityCurve + initialCapital=1e8 + managementFeeRate=0.02 + performanceFeeRate=0.2 · { initialCapital, finalNavNet, finalAum, peakNav, peakAum, gross/netReturnPct, fees, navNet } · — (quant hedge-fund sim: NAV 1.00 start, daily mgmt fee, 20% high-water-mark performance fee) quant_metrics · equityCurve + trades? · { totalReturnPct, maxDrawdownPct, sharpe, annualizedVol, calmar, sortino, winRate, profitFactor, avgPeriodReturnPct, tradeMetrics } (required trio: return/drawdown/sharpe) · — (METRIC_CATALOG for UI pickers) quant_chart · kind (candles/series/annotations) + matching data · structured chart data (dsh-chart protocol: candles+overlays+markers / multi-series / annotation views) · — (UI-route data plane) quant_execute_sim · close + orders[{index, side, quantity?/valueFraction?}] + initialCash? + feeRate? + slippageBps? + latencyBars? · { fills, equityCurve, finalEquity, totalReturnPct, totalFee, totalSlippageCost, tradeCount, unfilledCount, cash, position } · — (execution framework, no live trading) quant_trading_cost · quantity + price + commissionRate=0.001 + spreadBps=5 + annualVolPct=30 + dailyAdv? + participationRate=0.01 · { totalCostBps, commissionBps, slippageBps, impactBps, notional, notes } · — (commission + slippage + market impact) quant_trade_quality · fills (from quant_execute_sim) + unfilledOrders? + holdingPeriodBars? · { orders, fills, fillRate, totalSlippageCost, avgSlippageBps, avgHoldingBars, buys, sells, avgFillValue, notes } · — (execution quality: sim → live expectations) quant_research_pipeline · symbol? + interval? + limit? + provider? + candles? + strategy/fund params · { candles, quality, stats, metrics, risk, drawdown, fund, factor, report, charts } · — (one-call PDAT→PET research) quant_factor_evaluate · factorValues + forwardReturns (factor[i] predicts ret[i+1]) + quantiles=5 + window=20 + decayHorizons=5 · { ic, rankIc, icDecay, icir, icSeries, quantileReturns, longShort, turnover, autocorr1, n } (alphalens set + RankIC/IC decay) · — quant_factor_neutralize · factorValues + groups? + styleFactors? + method? · { values(standardized), method, groupCount, styleCount, rSquared } · — (group z-score / OLS residual neutralization) quant_walk_forward · returns + features[][] + trainWindow + testWindow + step? · { predictions(null-aligned), oosIc, oosRankIc, oosCount, windows, trainR2Mean } · — (rolling train / out-of-sample, no look-ahead) quant_rebalance_schedule · driftPerPeriod + costPerRebalance + maxFrequency=60 · { frequencies, totalCosts, bestFrequency, bestCost, costBreakdown, notes } · — (drift vs cost: optimal rebalance frequency) quant_parameter_sensitivity · baseValue + range=0.2 + steps=9 + metricValues? · { paramName, values, metricValues, baseValue, robustness, bestValue, bestMetric, worstMetric, notes } · — (grid robustness: plateau vs needle-sharp) quant_linear_model · X(samples×features) + y + lambda? + predictX? + yTest? · { intercept, weights, lambda, trainR2, n, predictions?, testR2?, testIc? } · — (standalone OLS/Ridge fit & predict) quant_factor_correlation · factors (equal length) + factorNames? + threshold=0.7 · { factorNames, correlationMatrix, highCorrelationPairs, meanAbsCorrelation, effectiveFactorCount, notes } · — (factor redundancy: dedupe before combine) quant_factor_combine · factors: number[][] (equal length) + weights? · { signal(rank 0..1), effectiveWeights, factorCount } · — (z-score weighting + cross-sectional ranking) quant_ic_decay · factor + returns (same length) + maxHorizon=10 · { horizons, icByHorizon, halfLife, bestHorizon, peakIc, peakHorizon, signalType, notes } · — (IC decay: signal shelf-life → rebalance frequency) quant_layered_backtest · factor + returns (time×asset matrices) + layers=5 + horizon=5 + feeRate=0.001 · { layers, topEquity, bottomEquity, longShortEquity, topReturnPct, bottomReturnPct, longShortReturnPct, rebalances, layerMeanReturnPct, notes } · — (quantile-layer backtest: factor → strategy sketch) quant_series_quality · values: number[], jumpThreshold=0.2 · { count, missingCount, zOutliers, jumps, longestConstantRun, healthy } · — (series-level quality) quant_data_annotate · values: number[], jumpThreshold=0.2 · { count, annotations: [{index, label, severity, detail}], summary } · — (point-level labeling, a tribute to Scale AI) quant_data_quality · candles (quant_market_fetch output) · { count, highBelowLow, nonPositive, timeNotIncreasing, timeGaps, extremeMoves, healthy } · — (pre-analysis health check) quant_deflated_sharpe · observedSharpe + numPeriods + numTrials=1 + skewness? + kurtosis? · { observedSharpe, minSignificantSharpe, deflatedSharpe, significant, pValue, notes } · — (Bailey & López de Prado overfitting-adjusted Sharpe) quant_data_pit · values: (number\ · null)[] + channels? · { healthScore, pit{pass, lookAheadIndices, notes}, survivorship{continuous, gaps, tailTruncated}, channels[] } · — (AI-infra quality: point-in-time / survivorship / channel reliability) quant_channel_guide · channel (e.g. "akshare") + check? + hasCredentials? · { channel, displayName, steps[], prerequisites[], example, fallback, readiness? } · — (agent-ready channel access guide + readiness check) quant_data_guide · query (channel name/data type, e.g. "tushare"/"financials") or channel (exact name) · { query, results: [{ name, url, cost, dataTypes, setup, tutorialUrls, bestFor, … }] } · — (built-in 15-channel data knowledge base: A-shares/US/bonds + dsh ecosystem data plugins) quant_market_fetch · symbol: string (e.g. BTCUSDT / sh600000 / AAPL), interval: 1m…1M, limit: 1-1000, provider: binance/okx/bybit/sina/tencent/yahoo · { symbol, interval, provider, candles: [{openTime, open, high, low, close, volume}] } · — quant_sma · values: number[], window: integer · { values: (number\ · null)[], window } · index window-1 quant_ema · values: number[], window: integer · { values: (number\ · null)[], window } · index window-1 (seed = first-window mean, alpha = 2/(w+1)) quant_rsi · values: number[], window: integer = 14 · { values: (number\ · null)[], window } · index window (Wilder smoothing) quant_macd · values: number[], fast=12, slow=26, signal=9 · { macd, signal, histogram } (equal length) · macd: slow-1; signal/histogram: slow+signal-2 quant_bollinger · values: number[], window=20, multiplier=2 · { upper, middle, lower, window, multiplier } · index window-1 (population std) quant_atr · high/low/close: number[], window=14 · { values: (number\ · null)[], window } · index window (Wilder smoothing) quant_kdj · high/low/close: number[], window=9 · { k, d, j } (equal length) · index window-1 (RSV method, K/D seeded at 50) quant_williams_r · high/low/close: number[], window=14 · { values: (number\ · null)[], window } · index window-1 (range -100..0) quant_cci · high/low/close: number[], window=20 · { values: (number\ · null)[], window } · index window-1 (±100 overbought/oversold) quant_obv · close/volume: number[] · { values: number[] } · everywhere (first value 0, no nulls) quant_adx · high/low/close: number[], window=14 · { adx, plusDi, minusDi, window } · ±DI: index window; ADX: index 2*window-1 quant_roc · values: number[], window=12 · { values: (number\ · null)[], window } · index window quant_backtest · close: number[], fast=10, slow=30, feeRate=0.001, stopLoss?, takeProfit? · { totalReturnPct, maxDrawdownPct, sharpe, position, equityCurve, trades(with exitReason) } · first trade one bar after first confirmed cross quant_backtest_bollinger · close: number[], window=20, multiplier=2, feeRate=0.001, stopLoss?, takeProfit? · same (buy on upper-band breakout, sell on mid-band cross-down) · one bar after first confirmed breakout quant_backtest_rsi · close: number[], rsiWindow=14, buyBelow=30, sellAbove=70, feeRate=0.001, stopLoss?, takeProfit? · same (buy on RSI cross-up through buyBelow, sell on cross-down through sellAbove) · one bar after first confirmed signal quant_backtest_portfolio · assets: [{name, close}], weights?, rebalanceEvery?, feeRate=0.001 · { totalReturnPct, maxDrawdownPct, sharpe, equityCurve, assetNames, finalWeights, rebalances } · — (multi-asset portfolio) quant_portfolio_optimize · returns (time×asset matrix) + method=maxSharpe\ · minVar\ · riskParity + iterations? · { method, weights, annualReturnPct, annualVolPct, sharpe, assetSharpe, concentration } · — (weight optimizer; feed result to quant_backtest_portfolio) quant_attribution · returns (time×asset) + weights (sum 1) + factorExposures? [time][asset][factor] · { totalReturnPct, assetContributionsPct, assetContribShares, factorContributionsPct, residualPct, factorR2, notes } · — (portfolio attribution: where did the return come from) quant_backtest_grid · close: number[], fastMin=3, fastMax=10, slowMin=10, slowMax=30, feeRate=0.001 · { results(sorted by return desc), best, fastRange, slowRange, feeRate } · — (grid search; skips fast >= slow)

Typical chain (model's view)

quant_market_fetch(symbol: BTCUSDT, interval: 1d, limit: 100)
  → take close → quant_sma / quant_ema / quant_rsi / quant_macd / … → quant_backtest

Verified live: real Binance daily bars → indicators → backtest (fast 5 / slow 20) end to end.

Backtest contract

  • Dual-MA crossover: buy all-in when fast SMA crosses above slow SMA, liquidate when

it crosses below; signals confirm on bar i and fill at bar i+1 close (no look-ahead).

  • Fees are charged on both sides of notional (feeRate per side).
  • Open tail position: the last trade's exitIndex/exitPrice/returnPct are null.
  • position and equityCurve match input length; equity is normalized (starts at 1);

Sharpe is annualized assuming daily frequency (√365).

Alignment conventions

  • All outputs are equal-length with inputs; leading unwindowed positions are

null — the model aligns by index, no padding needed.

  • Empty series or window > series length is a legal result (all null),

not an error.

  • Non-finite numbers (NaN/Infinity) are rejected at the registry's lossless-JSON

argument snapshot layer (the model's JSON boundary) and never reach execute.

  • Constraints (window ≥ 1 integer, macd fast < slow, atr arrays equal length,

multiplier > 0) are hand-checked in execute; thrown errors become isError results via the registry.

Contract (defineTool)

  • Arguments use the unified schema DSL, validated by defineTool before execute