DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-tradewatcher

t

dsh-tradewatcher

Manifest valid★ 3

DeepSeek Harness (DSH) Web Plugin: "Monitoring" Market Dashboard Sidebar Tab — Three quote strips with hover intraday charts, watchlist with industry alpha, ledger-driven portfolio P&L, A-share boards & detail drawer, host-side Eastmoney relay + read-only agent tools.

UI (client)hasBundlePatchMachine translated

dsh-tradewatcher(盯盘)

一个 DeepSeek Harness Web 插件:在 betterSidebar(ctx.betterSidebar 服务)注册一个「盯盘」页签,提供 A股/国际/商品行情条 + 悬浮分时图、内嵌大盘云图(52etf.site)、分组自选、流水驱动的分组持仓账本(市值/浮动盈亏/当日盈亏/已实现),并把持仓记录以只读模型工具 + 明文 JSON 双通道开放给 dsh 会话分析。

界面与数据组织参考浏览器插件「爱盯盘」(52etf.site);行情为免费公开接口的延迟行情(非 L2),仅作盯盘参考,不构成投资建议。

功能

  • 顶部行情条(三行,每 10s 自动刷新 + 手动刷新,暂停于页签隐藏时)
    1. A股指数:上证指数、深证成指、创业板指、科创50、沪深300、中证500
    2. 国际市场:韩国KOSPI200、法国CAC40、英国富时100、欧洲斯托克50、标普500、纳斯达克、德国DAX30、日经225、恒生指数
    3. 大宗商品:生猪主连、焦煤主连、豆粕主连、螺纹钢主连、布伦特原油当月、COMEX铜、COMEX白银、伦敦金现
    • 每卡片:名称 / 现价 / 当日涨跌值 / 涨跌幅(红涨绿跌,浅色/深色/跟随系统主题可切换)
    • hover 悬浮卡:当天分时图(源缺失自动回退近 5 日收盘走势),附昨收基准虚线、最后行情时间与成交额
  • 大盘云图:内嵌 iframe https://52etf.site/(行业热力图、缩放钻取、约 8s 刷新;可重新加载/新窗口打开)
  • 内部页签:
    • 自选:分组的新建/改名/备注/删除(删除=归档,可恢复)+ 组内添加(名称/代码搜索补全)/移除/移动分组(搜索池:A股/港股/美股/ETF/基金/指数/期货主连,如 688825、02155);A股行展示所属行业板块名、板块当日涨幅及个股相对板块 alpha(个股涨跌幅 − 板块涨跌幅)(行业归属 10 分钟缓存,板块涨幅随行情轮询同步刷新);排序:默认顺序 / 当日涨跌 / 总市值(组内生效,选择记忆在 prefs.json,同键再点切换升降序)—— 行内会显示 市值 xx亿,无该字段的标的(国际指数/商品/新浪备用源)在按市值排序时沉底
    • 分时缩略线与明细抽屉:自选/持仓每行带当日分时缩略曲线,点击弹出右侧抽屉:固定信息头(名称/代码/现价/涨跌幅/所属行业板块及板块涨跌幅/今开/昨收/换手率/最高/最低/成交量/成交额/市盈率/总市值),图表为三窗格专业图:主图 + 成交量(红绿柱、最大量标注)+ MACD(HIST 柱 + DIF/DEA 线,12/26/9,HIST=(DIF−DEA)×2),主图与子图均带纵轴刻度线(1/2/5×10ⁿ 步长);K 线叠加 MA5/10/30/60(橙/蓝/紫/灰,附当前值图例,均线在全量序列上计算后再截取可视区间);K 线下方为日期宽度缩放窗(双滑块缩放/平移 + 近1月/3月/6月/1年/全部 快捷键 + 当前区间与根数),图表内滚轮可以光标为中心缩放(最少 8 根)。分时主图另叠加均价线;五日图为 5 个交易日连续拼接(午休/隔夜已折叠,交易日之间画分隔线)。注意东财 trends2 的 ndays 参数会被上游忽略(只回当日),因此五日视图改用5 分钟 K 线拼接:新浪为主源(A股/ETF/指数,一次可取 6–8 个交易日)、腾讯 5 分钟 K 线兜底;港股等无多日分钟源的市场自动退回当日分时,图下注脚会如实显示交易日数量。 图上按持仓流水标注 B/S 买卖点(悬停显示「数量 @ 价格 · 分组/持仓」;周/月/年 K 把同周期多笔归并为 B2/S3),下方以 tab 切换 分时 / 五日 / 日K / 周K / 月K / 年K
    • 持仓:分组 CRUD(同上归档语义)+ 组内证券的「买入/卖出/调整/编辑/移动/明细/移除」;每分组与总览显示总市值、浮动盈亏、当日盈亏、累计已实现;每行明细含 浮动盈亏率与当日盈亏率(口径见下);排序:默认顺序 / 市值 / 持仓盈亏(随所选口径:摊薄=持仓盈亏,均价=浮动盈亏)/ 当日盈亏 / 仓位占比(组内生效,记忆在 prefs.json)
    • A股大盘:六大指数 + 沪深两市涨跌家数/成交额统计;行业/概念板块涨跌排行与主力资金排行;ETF 排行;个股/基金搜索 + 详情卡(分时大图、换手/量比/市盈率/市值等)
    • 护盘信号(A股大盘页内):识别「符合国家队历史行为模式」的宽基 ETF 护盘行为——常驻状态条(等级/评分/归因)+ 六通道标的卡 + 因子明细表 + 分时量能图 + 今日信号时间线与近 60 日历史回看。信号达「疑似护盘」时面板自动展开
      • 监测通道:默认核心 6 只宽基(沪深300ETF华泰柏瑞 510300 / 上证50ETF华夏 510050 / 中证500ETF南方 510500 / 中证1000ETF华夏 512100 / 科创50ETF华夏 588000 / 创业板ETF易方达 159915),可在设置里追加 510310 / 510330 / 159919 / 588080;共振按指数去重
      • 六因子加权(权重:量能 0.22 / 超大单 0.26 / 脉冲 0.18 / 持续性 0.12 / 量价背离 0.14 / 共振 0.08),乘时点系数(早盘 0.4 → 尾盘 1.1)得 0–100 评分;等级:≥75 强护盘信号 / 55–74 疑似护盘 / 35–54 资金异动 / <35 平静
      • 口径修订(v0.12.0,针对早期误报):
        • 时点系数真正接入评分(此前只用于展示,运行时恒为 1 → 早盘噪音最大的时段拿到满权重;实测同一盘面 09:48 由 62 分降为 25 分)
        • F2 以核心通道(沪深300/上证50)为主:仅外围通道净流入时打 0.7 折;核心通道超大单净流出达成交额 −15% 时封顶为「资金异动」(与托底特征相反)
        • F3 区分盘中与尾盘:14:30 前为「盘中脉冲」并打 0.6 折(大单对倒易造假),14:30 后为「尾盘突袭」满分权重;命中线为该时段 P90,锚点按时段分档标定(早盘 1.23/1.73/2.03x、尾盘 1.26/1.91/2.43x,不再是单一 1.5/2.5/4x——旧口径下 14–20% 的 5 分钟窗口天然越线)
        • F4 由「连续递增次数」改为「时间 + 幅度」:最近 5 分钟超大单净增 ÷ 该窗口成交额(锚点 5%/12%/25%),窗口内单次回撤超净增 50% 时打 0.6 折;不再随采样间隔漂移
        • F6 共振列出标的名并分层:核心 0 只时不得给「强护盘信号」(外围单买不足以认定系统性护盘);面板显示「系统性 / 局部」
        • 通道自身触发要求有净流入:只有量能或脉冲、没有超大单净流入不再计入共振
      • 底部位置 / 形态 / 概率(v0.15.0):回答"当前位置是否具备底部特征",与护盘行为识别并列展示(不进入护盘评分,避免把两件事混成一个数)
        • 位置:距 60/250 日最高回撤、近 60 日收盘分位、距 60 日最低、连续下跌天数、是否创 60 日新低 → 位置分(0–100,低位高分)
        • 日内形态:现价相对当日最低的回升幅度、下影线占振幅比例、当日最低点出现的时刻、是否"跌破前 20 日低后收回"、是否"创 60 日新低后收回" → 形态分
        • 底部概率(历史频率):把当前状态与历史同类日类比——近 60 日收盘分位 ≤ 25% 且 当日量能 ≥ 前 20 日均量 × 1——统计其后 5 日内最高价达到当日收盘 ×(1+目标) 的频率,同时给出无条件基线与样本量。实测(2026-09-28,6 通道合并):目标 +1% 同类 74.3% vs 基线 72.5%(+1.8pp,几乎无优势);目标 +2% 同类 61.4% vs 基线 50.8%(+10.6pp);前向 5 日收盘收益中位数 +1.0%、期间最大回撤中位数 −2.0%;同类样本 N=140、基线 N=1536
        • 诚实边界:① 概率是历史同类情形的频率,不是预测,必须与 N 和基线一起读,样本不足时不给结论;② 日内形态不进入概率——没有可回算的历史分钟数据,混进去就是伪精确,它只作实时修正参考;③ 位置低 ≠ 见底,护盘也可能发生在下跌半程,需结合资金流与量价背离
        • 实现记录:校准必须逐通道判定特征与前向收益、只合并统计结果——曾把多通道日线合并后按日期排序,导致"前 60 根"跨品种、前向窗口落到别的品种上,得出"前向收益中位数 +105%"的荒唐值;该场景已写成回归断言
      • 口径修订(v0.13.0,消除「重启后因子断档」):
        • 冷启动回填:采样环在内存里,进程重启后「脉冲」与「持续性」都需要 ≥5 分钟历史才可算;若重启发生在收盘前 5 分钟内,当天就再也算不出来(实测 9/24 14:44 重启即整日显示 —)。现首轮采样即用当日分钟数据回填(东财 trends2 每分钟成交额 + fflow klt=1 每分钟累计超大单/主力,约 240 点),实测重启后立刻得到「尾盘突袭 1.86x / 持续性 −2.0%」,6/6 通道可用
        • 阶段语义:区分「尾盘时段」与「已收盘」——收盘后不再把脉冲因子叫「尾盘突袭」(改为「脉冲(盘后)」,面板显示「已收盘」),避免误读为刚发生尾盘动作
        • 因子完整度如实标注:快照带 completeness,缺因子时状态条显示「因子 N/6」并在归因里注明「评分偏保守」(缺因子按 0 计入,方向偏保守,不做归一化放大)
        • 资金方向可见:通道卡新增「吸纳/撤离」标记(超大单占成交额 ±15%),避免把「大额净流出」误读成「哑火」
        • 旧口径留痕:新事件写入引擎版本,面板对早期记录标「旧口径」——升级前后评分逻辑不同,不能直接比较
        • 板块 / 资金 / ETF 的备用源与 last-known-good(v0.15.1):这一栏此前"一直不可用"。原因是它只在打开面板或切换 scope/sort 时才请求,属冷连接请求——东财行情 CDN(push2 系列)对本机新连接的封锁期间,行情与护盘因为持续轮询还养着旧连接与缓存,而这一栏每次都必然失败;而它既没有备用源也没有 last-known-good,于是直接显示"不可用"。现补三层:① 行业/概念 → 腾讯板块排行(mktHs/rank,含涨跌幅、领涨股、5/20 日);② ETF 排行 → 新浪(etf_hq_fund,含成交额与换手率);③ board-lkg.json 兜底:全部上游不可用时显示上次成功结果并标注时间。面板会注明数据来自哪个备用源,并说明**「主力净流入」仅东财提供**(备用源下显示 —)。另修正 ETF 榜的「换手」列(此前错映射到 f128,现取 f8/新浪 turnoverratio)
        • 搜索的熔断隔离与腾讯备用源(v0.14.2):现象是"自选/持仓搜不出任何标的"。两个原因:① 熔断器范围过宽 —— 最初所有东财请求共用一个熔断器,行情主机(push2 系列)被限流时,走 searchapi.eastmoney.com 的搜索被一起拦下(而该主机当时完全正常)。现改为按主机隔离(breakerFor(host) + hostsAllowed()),并在 selftest 里锁死"行情熔断不得影响搜索";② 搜索接入腾讯智慧搜索备用源(smartbox.gtimg.cn,响应是带 \uXXXX 转义的 JS 字面量,需还原;类型词表已对齐东财口径),覆盖沪/深/港股
        • 行情链路的腾讯备用源(v0.14.1):此前备用源只接了护盘模块,自选/持仓的行情仍在走东财——东财被限流时它们只能吃 last-known-good,价格冻在旧值(表现为"无法加载最新数据")。现把腾讯接进主链路:EM 拿不到的标的(或价格为空)由腾讯补齐,行上带 source: 'tencent',顶栏显示「备用源 N」;分时序列同样增加腾讯分钟线兜底(含当日均价 VWAP)。覆盖沪/深/港股;美股、国际指数、商品无腾讯映射,如实回落到 last-known-good
        • 腾讯备用源(v0.14.0):东财行情主机(push2 系列与 push2his)对本机 IP 限流/封锁时,改用腾讯免费接口保住「量能、脉冲、价格」:批量快照 qt.gtimg.cn/q=(1 次请求覆盖全部通道)与当日分钟线 web.ifzq.gtimg.cn/appstock/minute(每行 HHmm 价 累计量 累计额,第 4 字段是累计成交额)。「超大单净流入」只有东财提供,无替代——备用源下该字段为 null、面板如实标注,并在评分上封顶为「资金异动」(没有资金证据就不能说"有资金在托底"),flowSource 字段标出本次快照来源
        • 通道卡片与自定义通道(v0.14.0):通道统一以卡片呈现(上游不可用时按当日峰值合成「复盘」态卡片,而不是退回表格);设置里可添加自定义通道(通常为板块 ETF,如 1.512480 半导体ETF、1.512000 券商ETF),代码取东财 secid 前缀(沪市 1. / 深市 0.),名称与板块备注可填。自定义通道只做量能与脉冲观察,不进入护盘评分与共振——板块异动与「国家队托底」不是一回事,混入会污染口径;缺少 20 日均额基准时会后台自动补算,不必等到次日
        • 上游封禁/限流时的熔断与复盘兜底(v0.13.2):东财行情主机(push2*/push2his)在请求量偏大时会升级为持续不可达(实测失败率一天内从 25% 爬到 100%,而东财数据中心与腾讯/新浪仍正常 → 属针对本机 IP 的限流)。此时「重试 12 次」只会火上浇油,因此:① 进程级熔断(连续 3 次调用失败即停手,冷却 2→4→8→上限 15 分钟,半开试探成功即复位),行情中继与护盘采样器共用;② 重试轮数由 3×2 降到 2×2(最多 8 次尝试);③ 路由不再抛错(trend 返回 null),客户端自行降级,日志不再刷「route error」;④ 面板显示熔断层(含剩余时间与最后错误),并用当日复盘数据兜底:优先用各通道最后一次成功采样还原卡片,否则渲染「当日通道峰值」表——不再出现整块空白
        • 复盘表的渲染修复(v0.13.3):v0.13.2 的兜底数据在服务端已正确返回(实测接口带了 6 行峰值),但客户端从未渲染——上轮改客户端时用脚本替换且未加断言校验,插入复盘表的那处因缩进不匹配静默失败(同期横幅代码却插入了,导致"有横幅、无表格"的假象)。现已用精确编辑修正,并在构建后校验产物确实包含该段文案;同时不再用 etfs.length > 0 守卫整个展开块(否则无卡片时会连分时图/时间线/历史回看一起隐藏)
        • 快照 last-known-good + 无数据自动补采:采样循环只在交易时段内 tick,因此收盘后重启的进程不会产生任何快照 → 前端拿到空快照,标的卡与因子明细会整块消失(8/24 盘后实测)。现三层防护:① 每次成功采样把轻量快照落盘(rescue-log.json.lastSnapshot),本会话无数据时回落到它并标记 stale(面板显示「上次数据 HH:mm」与原因);② 路由在无新鲜数据时按 20 秒冷却自动补采一次;③ 客户端收到空快照时不覆盖已有数据
        • 盘后按「当日最后 5 分钟」评估:非交易时段不写入新样本,改以采样环内最后一个盘中样本为评估时点,否则「最近 5 分钟」会错配成「收盘到现在」这一整段空窗;面板显示「已收盘」而不沿用「尾盘突袭」
      • 阈值来源全部标注:量能倍数用历史分位数标定(腾讯日K 500 根 × 6 只 = 2886 个样本,P75/P90/P95 = 1.20/1.63/1.98x,对应 40/70/100 分);日内进度曲线用新浪 5 分钟线 126 个交易日标定(10:00 已占全天 29.6%、11:30 60.9%、14:30 86.0%),因此「同时点量能倍数」天然按时间进度归一,尾盘集合竞价的自然放量不会误判为脉冲;超大单强度因免费源已无日频资金流历史(东财 fflow 只回当日 1 行)暂用经验锚点,host 采样器自建样本满 20 个交易日后自动改用自建分位数(面板显示当前来源与样本天数)
      • 防误报约束(每条都写进归因,不做静默降级):指数明显上涨时封顶(+1.0% 以上最多「资金异动」,「+0.3%」以上不得为「强护盘」,因为放量上涨更可能是追涨);「强护盘」要求超大单强度达高门槛;无有效超大单且无脉冲时最多「资金异动」
      • 采样:host 侧常驻采样器,仅工作日 09:25–11:35 / 12:55–15:05 活跃,常态 30s、尾盘(默认 14:30 起)自动切 15s(间隔与尾盘时刻可在面板设置里改),每次采样 1 个批量请求(约 2 请求/分钟),页面关闭也持续记录
      • 数据:rescue-log.json(60 天滚动)保存每日信号事件、5 分钟抽样、20 日均额基准、自建样本;⚠ 免费源无 ETF 资金流历史,因此历史回看只能从本模块上线日起算
      • 会话工具 tradewatcher_rescue 可读取当前信号、六因子明细、各通道实测值与近 30 日历史
    • 大盘云图:见上
    • 日历:财经日历模块。月历网格按重要性三色标记事件(红=高 / 橙=中 / 蓝=低),格子里只显示事件名,点日期弹出当天事件详情卡(公布时刻、类别、重要度、来源、关联标的、备注),支持手动事件的增/删/改与自动事件的隐藏。数据来源:
      • 自动同步(东财数据中心,6 小时缓存):
        • 新股申购/上市日历(全市场);
        • 自选 + 持仓标的的财报预约披露日期、分红除权除息/股权登记日;
        • 国际 / 国内宏观:东财 H5 财经日历 emdatah5.eastmoney.com/dc/CJRL/GetIndexData,覆盖窗口 过去 7 天 ~ 未来 92 天(分页 50 条/页、4 并发,约 1–2 秒),含美联储议息会议、联邦基金利率目标、各国央行利率决议、非农、失业率、PCE、PPI、GDP、ISM、零售、初请失业金,以及中国 CPI/PPI/社融/进出口等;每条带北京时间公布时刻(time 字段,00:00 视为未定时刻不显示)。
        • 事件归类与重要度由名称启发式推导(数据源本身不含重要度字段):国家前缀 → 中国/中国香港/中国台湾/中国澳门 归国内宏观,其余核心经济体归国际宏观,无前缀的会议/行业事件归其他;非核心经济体(泰国、土耳其等)不入库。重要度:议息/利率决议/联邦基金利率/LPR/非农/CPI/PCE/GDP/两会/关税 → 高;PPI/PMI/零售/社融/失业金/库存等 → 中;其余 → 低(港口/保税区高频库存分项降为低)。
      • 手动维护:源里没有的事件(美国 CPI(BLS)不在东财免费源内,可从 + 事件 选「国际宏观」补录)、未上市公司 IPO 与上市日期(如长鑫、长存、DeepSeek、SpaceX)、自定义提醒——可在页面新增,也可以直接让会话里的 agent 用 tradewatcher_calendar_add 写入。 事件库落在 ~/.dsh/dsh-tradewatcher/calendar.json;会话工具 tradewatcher_calendar 可读取任意区间。

安装

前置:插件依赖宿主已挂载 dsh-better-sidebar(本机 web profile 一般已随其他聚合插件提供;ctx.betterSidebar 缺失时「盯盘」页签不会出现)。

# 1) 构建(lib/index.js + lib/client.js)
cd dsh-tradewatcher && npm install && npm run build   # 或 npm run selftest

# 2) 注册进 web profile(默认 ~/.dsh/profiles/web,可用 DSH_PROFILE_DIR 覆盖)
bash scripts/install.sh

# 3) 重启 dsh web 进程(必须:客户端 bundle 在启动时装载)
#    重启后打开 betterSidebar「+」菜单 → 大盘概览

卸载:bash scripts/uninstall.sh,然后同样重启 web。

插件为「双面」结构:主机半区(quote 中继、文件存储、/tradewatcher/* 路由、agent 工具)+ 浏览器半区(Tab UI),通过 dsh.bundle.patch(cordis.patch.yml 的 insert 行)随 bundle 自动挂载,无需手改 profile 的 cordis 配置。

数据与接口

数据文件(DSH_HOME 默认 ~/.dsh)

文件内容
~/.dsh/dsh-tradewatcher/watch.json自选:{ groups: [{id,name,order,archived?,note?}], items: [{id,groupId,secid,name,note?,createdAt}] }
~/.dsh/dsh-tradewatcher/positions.json持仓:{ groups:[…], items:[{id,groupId,secid,name,note?,createdAt}] } —— 数量/成本不落盘,全部由流水推导
~/.dsh/dsh-tradewatcher/ledger.json逐笔流水/审计(append-only):{v, entries:[{id,ts,actor,verb,groupId?,posId?,secid?,qty?,price?,fee?,note?,meta?}]}
~/.dsh/dsh-tradewatcher/prefs.json主题/刷新间隔/配色偏好
~/.dsh/dsh-tradewatcher/quotes-lkg.json行情 last-known-good 快照(每只证券最近一次有效读数,进程重启后仍可兜底,非账本数据)
~/.dsh/dsh-tradewatcher/klines/<secid>_<周期>.jsonK 线本地缓存:首次查看一次性拉全量(日 800 / 周 400 / 月 240 根),之后每次只增量拉最新几根并合并;上游不可用时直接回退缓存
  • verb:buy买入 / sell卖出 / adjust调整 / add新建持仓 / remove移除持仓 / gcreate新建分组 / grename改名 / gdelete归档 / grestore还原 / gmove移动或编辑 / pnote备注
  • 成本口径:买入按移动加权(费用计入摊薄成本);卖出确认已实现盈亏(费用于卖出时扣除);当日盈亏 = 隔夜 (现价−昨收)×数量 + 当日每笔买卖差额 − 当日费用;昨收取行情接口 昨收(期货主连按接口口径的昨结基准,见免责)
  • 盈亏率口径:浮动盈亏率 = 浮动盈亏 ÷(摊薄成本×数量);当日盈亏率 = 当日盈亏 ÷(期初数量×昨收 + 当日买入金额);无法估值(无昨收等)时显示 —
  • 成本口径可切换(持仓总览面板右上角分段开关,偏好存 prefs.json):
    • 摊薄口径(默认,与多数券商 App 一致):摊薄成本 = (累计买入含费 − 累计卖出净额) ÷ 剩余数量;持仓盈亏 = (现价 − 摊薄成本) × 数量,已实现盈亏已折进剩余持仓成本;卖出亏损会抬高摊薄成本,卖出盈利会压低(可能为负)。
    • 均价口径:买入移动加权均价(卖出不改成本);浮动盈亏单独显示,已实现盈亏另列。
    • 两者恒等关系:摊薄持仓盈亏 = 均价浮动盈亏 + 累计已实现。
  • 价格与成本保留 4 位小数(ETF/基金等低价标的 0.948 不会被四舍五入成 0.95)。
  • secid 为东财代码,格式 市场.代码:1.600519(沪A)、1.688825(科创板)、0.300750(深A)、1.510300(沪ETF)、116.02155/116.00700(港股)、100.KOSPI200(全球指数)、114.lhm(生猪主连)等

会话内分析(双通道)

  1. 模型工具(只读,重启后对所有会话可见)
    • tradewatcher_portfolio — 分组汇总 + 每只持仓(数量/成本/现价/市值/浮盈/当日/已实现)
    • tradewatcher_ledger — 逐笔流水,可按 posId/groupId 过滤(追溯完整交易过程)
    • tradewatcher_watchlist / tradewatcher_quotes / tradewatcher_search — 自选、实时行情、证券搜索(cn/intl/commodity/all 预设组)
    • 系统提示词已注册引导段落(插件在会话工具列表即显形,如出现工具名即说明挂载成功)
  2. 明文 JSON 文件:上述数据文件路径固定、格式如上,任何会话可用文件工具直接读取做离线分析/回溯校验

HTTP 路由(同源,浏览器信任围栏保护,POST 校验 Origin)

GET /tradewatcher/health|quotes?ids=|trend?secid=|kline?secid=|detail?secid=|suggest?q=|board?scope=&sort=&pn=&pz=、GET|POST /tradewatcher/watch|portfolio|prefs|calendar、GET /tradewatcher/ledger、GET /tradewatcher/trades?secid=、GET /tradewatcher/industry|industries

开发

src/
  index.ts            # 主机半区入口(路由 + 工具注册)
  host/em.ts          # 东财行情中继(push2delay/push2/push2his 多主机回退 + TTL 缓存)
  host/store.ts       # 文件存储 + 校验 + append-only 流水(纯函数可测)
  host/portfolio.ts   # 流水重放 → 持仓/分组/总览核算(纯函数)
  host/routes.ts      # /tradewatcher/* HTTP
  host/tools.ts       # tradewatcher_* agent 工具 + 提示词段落
  host/selftest.ts    # npm run selftest(核算断言 + 实时接口冒烟,网络项 soft)
  client/index.tsx    # 浏览器半区:ctx.betterSidebar.registerTab + 装配
  client/*.tsx        # TopBar/自选/持仓/A股大盘/云图 + SVG 分时图 + 悬浮卡
  shared/model.ts     # 两端共享类型 + 23 个固定代码
  • 构建:npm run build(esbuild → lib/index.js ESM、lib/client.js CJS + __ModuleLoader__ 工厂)
  • 门禁:npm run check = typecheck → test → selftest → build
    • typecheck:tsc --noEmit;build.mjs 构建前会先跑它,失败即中断(可用 TW_SKIP_TYPECHECK=1 临时跳过)
    • test:node --test --experimental-strip-types,当前覆盖客户端纯函数(指标计算与格式化)
    • selftest:host 侧集成自测(纯函数断言为硬失败,真实网络探针为 soft);会把 DSH_HOME 指向临时目录,不再写用户真实数据目录
    • 版本号单源:package.json.version 经 esbuild define 注入客户端(__TW_VERSION__),构建期校验产物确实含该版本号
  • 客户端在浏览器中的 react/react-dom/cordis 由 web shell 模块表提供(externals);其余全部内联

时间口径(v0.17.0 起统一)

全插件的时间标签只有一套口径:Asia/Shanghai(src/host/time.ts)。此前 rescue.ts / calendar.ts 用宿主本地时间、而 portfolio.ts 用 Asia/Shanghai,两套并存——实测在 TZ=UTC(Docker / 云主机 / CI 的默认值)下,北京时间 10:00 会被判成"盘前",护盘采样一次都不触发,且时点系数、阶段语义、 脉冲锚点全部错位(晚间盘面按"早盘"给 0.4 折)。现在 hhmmOf / dayOf / weekdayOf / calToday / shanghaiDayStart 全部来自同一实现,并在 4 个时区(Asia/Shanghai、UTC、America/New_York、 Australia/Sydney)下断言一致;npm test 会把这套断言跑两遍(宿主 TZ 与 TZ=UTC), 因为只有显式切 TZ 才锁得住时区回归。

注意:inTradingWindow 里的星期也必须按北京时间——北京时间周一 10:00 在 TZ=America/New_York 下是周日 22:00,用宿主星期会把真实交易日判成休市。

明确不做的项(附理由,避免反复评估)

外部代码评审(v0.15.1 基线)还提出若干结构性优化,经实测后明确不做或推迟,理由如下:

  • 账务单遍分组(O(P×N) → O(N)):实测本机账本为 103 条流水 × 10 只持仓 = 1030 次遍历,/portfolio 响应 0.28s 且主要耗时在上游行情等待。此规模下优化遍历无收益。
  • 流水改 JSONL 追加写、模块级缓存加 LRU、上游加令牌桶限流:单用户单进程、标的不满百;上游全挂的主要风险已由按主机熔断覆盖。
  • 拆分 em.ts / rescue.ts / tools.ts 为多文件、把模块级单例改工厂注入:功能仍在演进期,拆分与并行开发的冲突成本大于收益;新增模块按 bottom.ts 的方式办(纯函数、单主题、有断言)。
  • 引入 vitest / husky / CI 供应商:改用零依赖的 node --test;本机单机项目不引入 CI 服务。
  • 信任边界的完整加固(CSRF token 等):实测服务只监听 127.0.0.1,局域网不可达;仅保留 Content-Type 断言与本文档说明。

数据诚实性(v0.18.0 落地)

前一轮复核提出的五项"数据新鲜度/错误语义"问题已全部实施,口径如下:

  • /quotes 回传真实 asOf / stale:asOf 是数据被观测到的时刻(每行 at,来自东财/腾讯/新浪各自拿到读数的瞬间;兜底行保留其原始观测时刻),stale 表示至少一行是 last-known-good 或已超过 90s。TopBar 因此显示「数据 HH:MM:SS」并给出「滞后 N」标记与来源明细(em/tencent/sina/lkg 逐项计数)。此前显示的是响应生成时刻 —— 上游全挂、整屏都是几小时前的旧值时,界面依然写「更新 14:32:05」。
  • tick() 重入守卫:定时循环、前端 ?force=1、路由 ensureFresh() 三条路径统一经 SingleFlight 合并 —— 同时只跑一份采样,后续调用等待同一份结果。此前会并发跑两份全量采样:上游请求翻倍、today.samples 重复计数、两份快照互相覆盖(样本数可能"回退")。
  • buildBottom 保留上次视图:日线未到、校准冷却中或校准失败时返回上一次成功结果并标 stale + computedAt(面板显示「上次结果 · HH:MM」),不再整块消失。位置/形态/概率是慢变量,旧结论仍可参考,但必须标明不是本次计算。
  • 错误语义分级(src/host/http.ts):400 请求本身有问题(secid/scope/sort 非法、JSON 解析失败)· 413 请求体过大 · 503 上游不可用(熔断中/连接被关闭/超时/上游 4xx-5xx/上游返回非 JSON)· 500 未归类(本插件 bug),503 附带 retry-after(取最早恢复时刻)。此前一律 400,把"上游被限流"报成"你的请求写错了"。
  • 熔断状态聚合:/rescue 与 /health 返回 breakerSummary(逐主机明细 + minutesLeft 最早可重试 + allMinutesLeft 全部恢复 + 最近失败原因),面板横幅按「N/M 台熔断」展示。minutesToRecover 取最小值(最早恢复即可重试),此前取最大值会把"还有 1 分钟可试"显示成"约 14 分钟后重试"。
  • 回测/标定路径同样清洗日线:sanitizeBars 现在覆盖 laneOutcomeStats / calibratePooled / computePosition / buildBottomLane,前向极值改单遍求值。此前只有展示路径清洗,一根 NaN 日线会让 Math.max(...fwd) 变 NaN 并污染概率、中位数与回撤中位数,却仍被当作有效样本。
  • 构建期的类型门禁区分两种失败:tsc 未能启动(依赖没装)退出码 2 并提示 npm i;被信号杀死退出码 3;类型错误退出码 1 —— 不再把"没装 typescript"报成"类型检查不通过"。

排序(v0.19.0)

自选与持仓都支持组内排序,键与口径如下(选择存进 prefs.json,同键再点一次切换升降序):

  • 自选:默认顺序(= 添加顺序)/ 当日涨跌(pct)/ 总市值。市值来源:东财 f20(全部标的)→ 腾讯 f45(沪/深/港股,原始单位亿元,已 ×1e8 转元);新浪备用源不提供市值(int_/nf_/hf_ 行情里没有该字段),因此国际指数、商品、期货经新浪兜底时没有市值 → 排序时沉底,界面上也不显示这一栏(不编造)。
  • 持仓:默认顺序(= 建仓顺序)/ 市值 / 持仓盈亏 / 当日盈亏 / 仓位占比(个股市值 ÷ 组合总市值,含全部未归档分组)。盈亏键跟随当前成本口径(摊薄口径排的是「持仓盈亏」,均价口径排的是「浮动盈亏」)—— 排序用的数与表格里显示的那一列必须是同一个,否则"按盈亏排序"看到的顺序会和列对不上。
  • 两条硬约定(都在 src/client/sort.ts,并有 8 组断言锁死):
    1. 无效值恒沉底:无行情、无市值、无盈亏、NaN/Infinity 一律排在最后 —— 升序也不许跑到最前(null 参与数值比较会退化成 0,正是这类功能最常见的错误)。
    2. 稳定且可预期:同值条目保持原顺序,排序不会在每次行情轮询后重新洗牌。
  • prefs 边界:watchSort / portSort 走主机侧白名单校验(非法键、非布尔方向抛错,界面能提示出来);明文文件被手改成非法值时装载即回退默认(启动不因一个坏偏好失败),但同一文件里合法的排序偏好保留。
  • 排序记忆跨重启保留,且不影响默认顺序本身(选「默认」即回到自定义顺序)。

护盘面板的状态表述(v0.19.1)

东财行情主机对本机的封锁可能持续整天(见「上游连接抖动」),而面板此时往往仍有可用数据——因为采样器会自动回落到腾讯备用源。此前面板顶部会因此常驻一整行红字:「上游行情部分主机暂不可用(3/3 台熔断)……期间不发起请求以免加重封锁,面板显示当日复盘数据」——这句话在备用源兜底成功的场景下与事实相反(面板显示的正是当日实时/收盘数据),且把"东财链路熔断"这个次要信息喊得比「平静」状态还响。现改为:

  • 一行短句 + tooltip 明细:东财行情主机 3/3 台熔断(全部) · 下次开盘自动重试 —— 当前快照已由腾讯备用源兜底:价格、量能、脉冲、背离可用;超大单强度与持续性无法计算(该源无分单资金流)。逐主机剩余时间、连续熔断次数、最后错误收进 tooltip。
  • 按时段分场景:交易时段说「最早约 N 分钟可重试」(取最早恢复的那台),收盘后说「下次开盘自动重试」——收盘后没有采样需求,"N 分钟后可重试"没有可操作性。
  • 因子缺失的原因分开写:flowSource === 'tencent' 时明确「该源不含分单资金流,不是等几分钟就能补齐」;只有东财源下的缺因子才是「冷启动/采样满 5 分钟自动补齐」。此前一律承诺"5 分钟后自动补齐",在备用源场景下是空头承诺。
  • 数据时刻与失败时刻分离:ts/lastSampleTs 表示"这份数据是几点拿到的",lastFailTs 表示"最近一次采样失败在几点"。此前失败分支会把 ts 改写成当前时间 —— 收盘后手动点一次「立即采样」而上游不可用时,顶部的「已收盘 · 21:34:43」会变成失败时刻,看起来像刚采到数据。现在失败只置 gap 与 lastFailTs,改写在自检里被断言锁死。
  • 口径:本会话未采样 ≠ 采样缺口。收盘后重启时面板用持久化的上次快照(红标「上次数据」+ note 说明),此时不再误报"采样缺口"——gap 只反映当日真实失败。
  • 来源与失败时刻落盘(flowSource / lastFailTs 进 rescue-log.json),收盘后重启的面板仍能说明数据来自哪个源。

已知边界与免责

  • K 线数据源:腾讯历史 K 线为主(A股/港股/美股,稳定且快),东财 push2his 兜底(指数/期货等腾讯不覆盖的标的),两源统一不复权口径避免混源污染缓存;东财 klt=104 实际是季K,本插件的「年K」由月K本地重采样;历史接口的「200 + 空数组」按失败处理并切换数据源
  • 行情来自东方财富免费公开接口(push2delay 主、push2/push2his 备;历史接口偶发限流会自动重试/降级);延迟数据,盘中偶有缺口;国际指数与商品按源时区展示
  • 待复核:100.KOSPI200 的数值水平。本机 quotes-lkg.json 里东财返回的 100.KOSPI200(名为「韩国KOSPI200」)为 1088.15,而同一批其它国际指数的水平与公开行情一致(CAC40 8078 / FTSE 9284 / 恒生 24523 / 日经 44946 / 标普 6643)。KOSPI200 长期在数百点区间,1088 与之不符 —— 怀疑东财该 secid 指向的不是 KOSPI200 指数本身(或其口径不同)。新浪无 int_kospi200、腾讯无对应映射,因此两个备用源都无法交叉验证;东财行情主机对本机不可达时也无法复核。在验证清楚之前,不要把该数值当作决策依据;东财可达时可用 tradewatcher_quotes 100.KOSPI200 与其它公开源对照
  • 国际指数/商品的备用源缺口:东财不可达时的兜底覆盖为 20/23(腾讯 6 个 A股指数 + 新浪 14 个:7 国际指数、4 国内期货、3 外盘商品)。缺 韩国KOSPI200 / 法国CAC40 / 欧洲斯托克50 —— 三家免费源(hq.sinajs.cn、qt.gtimg.cn、smartbox 搜索)都没有对应符号,只能等东财恢复;此时它们会带 source: lkg 与滞后标记,而不是显示假数据
  • 上游连接抖动:本机到东财主机的连接会随机被立刻关闭(实测瞬时失败率 20–75%,与响应大小、IPv4/IPv6 选择无关,表现为 UND_ERR_SOCKET,几十毫秒即返回)。因此上游请求统一走 fetchAny:「2 轮 × 每主机 2 次」(最多 8 次尝试)+ 抖动退避(并发 worker 不同步重试)+ 9 秒总截止;实测分时接口的冷启动成功率从 3/12 提升到 12/12、板块接口从 1/3 提升到 6/6,且正常时首次尝试即成功(240–500ms),重试不增加常态延迟。行情主路径(/quotes 批量)此前是例外——它每主机只试 1 次且失败静默,现已对齐同一骨架,并补上失败日志与熔断
  • 分时序列兜底:ttlCache 此前只写不读(TTL 形同虚设,每个请求都打上游),已修正为真正命中缓存;分时另加 last-known-good(trends-lkg.json,与行情 LKG 同思路)——上游失败时返回上一份好图并在 staleAt 标记快照时间,命中后写 20s 短缓存(显式 grace: 0,不被 peek 的 45s 宽限吞掉,真实陈旧窗口即 20s)避免断网期间按行重试形成风暴。客户端同样不再因一次失败抹掉缩略图(失败只短缓存 15s,保留上一份 good 数据继续显示)
  • 接口瞬时缺价/漏返(实测东财会出现几十秒级的丢码窗口)时,主机侧按 last-known-good 回退:每次返回路径(新拉取/TTL/peek 命中)都做字段级回填,快照持久化到 quotes-lkg.json 跨重启生效,且单批缺码会先换备机补拉;客户端再保留已拉取旧值、空样本不回写——价格不会在“数字 / —”间闪烁;停牌等真实无价标的仍显示 —
  • 分时图对没有当日分时的标的回退近 5 日日线;push2his 限流时悬停图可能短暂显示占位
  • 期货主连「昨收/昨结」等口径字段随接口语义展示,若做精确期货结算对账请以结算单为准
  • 持仓记账支持任意可报价标的;跨市场标的盈亏按接口币种金额展示,未做汇率折算(人民币资产无影响)
  • 删除分组 = 归档(保留持仓与全部流水);「移除持仓」要求数量为 0(先卖后移),保证流水完整可追溯
  • 护盘信号:识别的只是「符合国家队护盘行为模式的放量 + 超大单净流入」,不能证明买入方是汇金/国新/诚通(它们不披露日内成交),回答与展示都按概率性信号处理;超大单为东财按单笔金额的分类口径(非席位数据);ETF 天量含做市双边报价与套利盘,故始终用超大单净额与量价背离交叉验证。另:免费源已无 ETF 资金流历史(东财 fflow 仅当日 1 行、push2his 常限流),故 F2 初期为经验锚点、历史回看自上线日起
  • 财经日历:宏观自动源为东财 H5 财经日历(免费公开接口),它不含美国 CPI/BLS 数据(该源有 PCE、PPI、非农、失业率,但没有 CPI),也不含未上市公司 IPO 传闻;这类事件请用页面 + 事件 或 tradewatcher_calendar_add 手动补录。宏观重要度为名称启发式推导,非官方评级;公布值/预期值该源未提供
  • 本插件不构成投资建议

License

MIT

Comments

Loading…

Similar plugins

dsh-stock-watch

by Bob-Bo1

DeepSeek Harness (DSH) plugin for local A-share portfolio tracking. Reads a local holdings.json and shows quotes and P&L in the sidebar.

Just for FunTerminal & ClientsDevelopment & InfrastructureManifest valid

★ 3

↓ 32/wk

MIT

JavaScript

Aug 18, 2026

dsh plugin --profile web add stock-watch

by ZSeven-W

DeepSeek Harness (DSH) plugin: a read-only ledger for the plugins you already have installed — a capability inventory with file:line evidence, declared-vs-detected reconciliation, cross-profile versio

Security & AuditManifest valid

★ 24

↓ 58/wk

MIT

JavaScript

Oct 10, 2026

dsh plugin --profile web add @zseven-w/dsh-harbor

by f1426912008

Realtime stock watch mini-window for the DeepSeek Harness web GUI: an A-share watchlist panel with intraday curves, hover detail cards, and its own settings page. Zero runtime dependencies, no build step.

Terminal & ClientsManifest valid

★ 0

MIT

JavaScript

Sep 30, 2026

dsh plugin --profile web add dsh-stock-ticker

by hutao562

DeepSeek Harness plugin: a sidebar tab that takes over the whole page with another DSH instance's Web GUI, plus a remote session-state badge. 在侧边栏顶部加一个「远程」标签,整页切到另一台主机上的 DSH。

Tools & CapabilitiesTerminal & ClientsDevelopment & InfrastructureManifest valid

★ 0

↓ 289/wk

MIT

JavaScript

Sep 11, 2026

dsh plugin --profile web add dsh-remote-dsh

A-share market dashboard for DeepSeek Harness: realtime market indices, stock screener with 13 technical signals and multi-strategy intersection, 7×24 multi-source news aggregation, watchlist with gro

Tools & CapabilitiesManifest valid

★ 0

dsh plugin --profile web add @czf1995/dsh-waste-market

by fashionmascherine-svg

DeepSeek Harness plugin (dsh-plugin): complete Polymarket superpowers — 31 verified tools across Gamma/CLOB/Data-API/Perps/RFQ/Bridge, embedded knowhow skill, live WebSocket stream. Read-only by defau

Tools & CapabilitiesManifest valid

★ 3

JavaScript

Aug 23, 2026

dsh plugin --profile web add dsh-polymarket-knowhow