@dshtrading/kit-hk 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1,25 @@
1
- ../../../packages/kit-hk/assets/skills/hk-risk-checklist.md
1
+ ---
2
+ name: hk-risk-checklist
3
+ description: 港股交易风控检查清单:开仓前逐项核对 T+0 回转与无涨跌幅限制、碎股( board lot)与手数、供股/配股摊薄、窝轮牛熊证杠杆与强制收回、港元汇率与港股通差异。
4
+ ---
5
+
6
+ # 港股风控检查清单(hk-risk-checklist)
7
+
8
+ 开仓前逐项核对,任何一项不过则不建仓:
9
+
10
+ **依据闸门(先过)**:每条开仓理由必须能指回锚点(工具名 + 参数 + 数值 + 数据时间 / 公告或章节 / facts 条目 / 知识卡 id + updatedAt)。只有 C/D/E 级来源、或写不出锚点的理由,按证据不足处理(insufficient),不得作为入场依据。
11
+
12
+ 1. **T+0 回转与无涨跌幅**:港股当日可无限次回转买卖(T+0),且**没有涨跌停板**——个股单日可以 ±30% 甚至更多,停牌复牌跳空无限制。止损单不能保证按止损价成交,隔夜仓必须有明确的仓位上限与最坏情景预算。T+0 不等于必须高频:无涨跌幅市场里频繁回转的交易成本(佣金+印花税+买卖价差)会迅速吞噬收益。
13
+ 2. **碎股与手数(board lot)**:港股每只股票有各自的每手股数(如腾讯 100 股/手,部分仙股 2000/10000 股/手),下单数量必须是每手的整数倍;**非整手为碎股(odd lot)**,碎股只能经碎股市场议价卖出,成交价通常折让、买入通常溢价。下单前核对该股 board lot(本插件 hk 行情不含手数,需自行查询),数量取整手。
14
+ 3. **供股 / 配股摊薄**:港股再融资门槛低、节奏快——供股(rights issue,向全体股东按比例折价配售,除净后正股价同步折价)与配股(placement,向特定投资者)都可能在无预警下公告。停牌一两天的配股公告、深度折价供股会直接打穿止损位;持有高负债、频繁再融资的公司必须预设摊薄情景。收到供股权利:供(继续投钱)、卖(-rights 权证)、放任(被摊薄)三选一,不作为也是决策。
15
+ 4. **窝轮(权证)/牛熊证警示**:Warrant(窝轮)与 CBBC(牛熊证)是发行商创设的杠杆衍生品,**不是正股**:有时间价值损耗(窝轮每日衰减)、发行商买卖价差宽、牛熊证触及收回价(call price)即**强制收回、剩余价值可能为零**。核清单:识别代码形态(窝轮 5 位数字、牛熊证带特殊编号)与到期日;不懂止损机制与街货比就不碰;严禁把衍生品仓位当作正股持仓过夜。
16
+ 5. **港元汇率与港股通差异**:港股以 HKD 计价,人民币投资者的最终损益叠加 CNH/HKD 汇率波动。经港股通持有:股息红利税 20%(H股 28% 口径另有规定)、交易汇率按结算汇兑比率每日浮动、不可参与融资融券与部分公司行为(如港股通标的供股需另行申报,逾期视同放弃)。碎股不可经港股通卖出(须自行处理)。
17
+ 6. **基本面估值与新闻**:调用 `hk_get_fundamentals` 核对总市值、市盈率 PE(TTM)、市净率 PB、股息率与 52 周区间;调用 `hk_get_news` 检查港股相关快讯(降级源),排查供配股、回购与财报公告;不做无基本面支撑的长尾仙股。
18
+ 7. **流动性与仙股**:港股头部流动性集中于恒指成分,长尾中小票日成交额极低、买卖价差可达百分之几,仙股(股价 < 1 HKD)有单日腰斩与庄股崩盘史。仓位上限按「占该股日均成交额的比例」设定,小票降低上限;不做无基本面的低价股博弈。
19
+ 8. **对手侧情景**:价格反向运行到止损位后,是否接受该笔亏损并继续执行原计划(无涨跌幅市场跳空会直接穿越止损);连续两笔止损即当日停手复盘(T+0 允许报复性交易,纪律上必须自我设限)。
20
+
21
+ 退出纪律:
22
+ - 达到目标位或止损位按计划执行;移动止损只朝有利方向。
23
+ - 财报、供股公告窗口前重估隔夜仓:停牌期间无法止损,不确定就减仓。
24
+
25
+ > 本清单是方法论,不构成投资建议。行情与下单工具均为 dry-run 起步,实盘需显式开关与审批(dsh-trading 铁律 #3);行情数据来自腾讯公共端点(无官方授权),个人使用边界以腾讯服务条款为准。
@@ -30,6 +30,8 @@ description: 财经观点沉淀与知识库策展指南:基于 Content Insight
30
30
  - `medium`:核心逻辑有参考价值,但部分数据存在滞后或口误出入;
31
31
  - `low`:存在重大关键事实失准或关键数据无法核实。
32
32
 
33
+ > **分层说明(勿混用)**:卡片 `factCheck` 三桶是**素材级**核查记录(这条声称被核实到什么程度);结论级证据契约的 `supported` / `contradicted` / `mixed` / `insufficient` 四态是**结论级**判定(这条结论能否成立)。卡片字段不因四态改名;引用卡片时按证据契约归入 C/D 级线索,不得单独支撑 `supported` 结论。
34
+
33
35
  ---
34
36
 
35
37
  ## 3. 标准策展 SOP
@@ -584,6 +584,10 @@ declare module '@deepseek-ai/cordis' {
584
584
  tradingCnMarketData: MarketDataService;
585
585
  /** hk 市场行情服务(由腾讯连接器同包双实例提供,config.market 分流;cn+hk 切片 2026-08-31 补齐)。 */
586
586
  tradingHkMarketData: MarketDataService;
587
+ /** futures 市场行情服务(由同花顺期货连接器提供,issue #97;日K + 当日分时聚合)。 */
588
+ tradingFuturesMarketData: MarketDataService;
589
+ /** 全球品种行情(global 市场:大宗/外汇/海外指数;@dshtrading/connector-jin10 dataplane 行提供)。 */
590
+ tradingGlobalMarketData: MarketDataService;
587
591
  /**
588
592
  * crypto 市场交易服务(R3 2026-08-29 补齐,crypto 市场第一个真实 TradeService):
589
593
  * 由 connector-okx 实现(签名 demo/live 下单),与 connector-binance 经
@@ -614,6 +618,10 @@ declare module '@deepseek-ai/cordis' {
614
618
  * 各市场 Kit apply 时注册 aggregateNews 纯函数,GUI 行情桥按市场获取。
615
619
  */
616
620
  tradingNewsRegistry: TradingNewsRegistry;
621
+ /** 跨市场快讯源(@dshtrading/connector-jin10 提供;缺席 = 未安装快讯连接器)。 */
622
+ tradingFlashFeed: FlashFeedService;
623
+ /** 宏观/利率源(@dshtrading/connector-jin10 提供;缺席 = 未安装金十连接器)。 */
624
+ tradingMacroFeed: MacroFeedService;
617
625
  }
618
626
  }
619
627
  /**
@@ -689,6 +697,8 @@ interface NewsItem {
689
697
  readonly publishedAt: string;
690
698
  /** 关联标的代码(可选,格式随源不同)。 */
691
699
  readonly relatedCodes?: readonly string[];
700
+ /** 热度等级(可选;金十快讯网页版 火/热/沸/爆,其他源不填)。 */
701
+ readonly hot?: string;
692
702
  }
693
703
  /** 新闻聚合请求选项。 */
694
704
  interface AggregateNewsOptions {
@@ -700,6 +710,11 @@ interface AggregateNewsOptions {
700
710
  symbol?: string | undefined;
701
711
  /** CryptoPanic API token(仅 crypto 市场使用,可选)。 */
702
712
  cryptoPanicKey?: string | undefined;
713
+ /**
714
+ * 启用的新闻/公告源 id 列表(issue #96 源配置化;各 kit 的 NewsSource 词汇)。
715
+ * 缺省 = 该市场全部默认源;空数组 = 显式关闭(返回空结果)。
716
+ */
717
+ sources?: readonly string[] | undefined;
703
718
  }
704
719
  /** 新闻聚合结果。 */
705
720
  interface AggregateNewsResult {
@@ -710,6 +725,73 @@ interface AggregateNewsResult {
710
725
  }
711
726
  /** 新闻聚合器函数签名(各 Kit 导出的 aggregateNews 符合此形状)。 */
712
727
  type NewsAggregator = (options?: AggregateNewsOptions) => Promise<AggregateNewsResult>;
728
+ /**
729
+ * 跨市场快讯源契约(2026-09-13 金十接入):host 平面由快讯连接器 provide
730
+ * tradingFlashFeed,GUI 快讯面板(桥 /dshtrading/api/flash)与 agent 快讯工具
731
+ * 共用同一取数实现;服务缺席 = 未安装/未启用该数据源 → 消费方报
732
+ * TRADING_NOT_IMPLEMENTED,绝不把「没有数据源」伪装成「没有快讯」。
733
+ */
734
+ interface FlashFeedService {
735
+ /**
736
+ * 最新快讯流(cursor 翻页);条目只含元数据(标题/时间/链接)。
737
+ * `hot` 非空时按热度等级服务端过滤(金十网页版 火/热/沸/爆)。
738
+ */
739
+ listFlash(options?: {
740
+ cursor?: string | undefined;
741
+ limit?: number | undefined;
742
+ hot?: readonly string[] | undefined;
743
+ }): Promise<{
744
+ readonly items: readonly NewsItem[];
745
+ readonly nextCursor?: string | undefined;
746
+ readonly hasMore: boolean;
747
+ }>;
748
+ /** 关键词搜快讯(上游一次性返回、不支持翻页)。 */
749
+ searchFlash(keyword: string, limit?: number | undefined): Promise<readonly NewsItem[]>;
750
+ }
751
+ /**
752
+ * 宏观经济日历条目(金十当周经济数据,2026-09-15):数值均为上游快照原样字符串,
753
+ * `actual` 缺省 = 未公布。
754
+ */
755
+ interface MacroCalendarEntry {
756
+ /** ISO 8601 公布时间(东八区解释,同 NewsItem 口径)。 */
757
+ readonly publishedAt: string;
758
+ /** 重要度(上游 star,0–5)。 */
759
+ readonly star: number;
760
+ /** 地区(标题前缀推断,如 美国/日本/中国;未识别 = 空串)。 */
761
+ readonly region: string;
762
+ readonly title: string;
763
+ readonly previous?: string;
764
+ readonly consensus?: string;
765
+ readonly actual?: string;
766
+ readonly revised?: string;
767
+ /** 上游公布影响词(利多/利空/影响较小…;原样透传)。 */
768
+ readonly affect?: string;
769
+ }
770
+ /** 央行最新利率条目(金十网页版,2026-09-15)。 */
771
+ interface MacroRateEntry {
772
+ /** 地区(flag 名推断,如 美国/日本/中国;未识别 = 空串)。 */
773
+ readonly region: string;
774
+ readonly bankName: string;
775
+ /** 最新利率(上游原样字符串,如 "3.75"/"0")。 */
776
+ readonly rate: string;
777
+ /** 公布日(上游原样 YYYY-MM-DD)。 */
778
+ readonly publishedAt: string;
779
+ /** 所属指标名(如「美联储利率决定(上限)」;部分央行缺省)。 */
780
+ readonly indicatorName?: string;
781
+ }
782
+ /**
783
+ * 宏观/利率源契约(2026-09-15 金十接入):host 平面由金十连接器 provide
784
+ * tradingMacroFeed,GUI 宏观面板(桥 /dshtrading/api/macro/*)消费;服务缺席 =
785
+ * 未安装/未启用该数据源 → 消费方报 TRADING_NOT_IMPLEMENTED,绝不把「没有数据源」
786
+ * 伪装成「没有数据」。日历走官方 MCP(list_calendar),利率走网页版公开接口
787
+ * (spikes/impl-jin10-macro-rates/EVIDENCE.md)。
788
+ */
789
+ interface MacroFeedService {
790
+ /** 当周经济日历(周一~周日,北京时间;limit 截尾,缺省全周)。 */
791
+ listCalendar(limit?: number | undefined): Promise<readonly MacroCalendarEntry[]>;
792
+ /** 央行最新利率(全量,客户端按地区过滤)。 */
793
+ listRates(): Promise<readonly MacroRateEntry[]>;
794
+ }
713
795
  /** 新闻聚合器注册表契约(Issue #37,router 插件提供)。 */
714
796
  interface TradingNewsRegistry {
715
797
  register(market: string, aggregator: NewsAggregator): () => void;
@@ -717,4 +799,4 @@ interface TradingNewsRegistry {
717
799
  markets(): string[];
718
800
  }
719
801
  //#endregion
720
- export { AccountBalance, AggregateNewsOptions, AggregateNewsResult, AuctionSnapshot, BuybackItem, CompanyProfile, CryptoFundamentals, DerivativesData, DerivativesHistory, DerivativesPoint, Disposable, DividendItem, DragonTigerItem, FinancialCell, FinancialIndicatorRow, FinancialReportGroup, FinancialReportMatrix, ForecastSummary, FundamentalsPackage, HolderNumSummary, InsiderTradeItem, InstitutionalHoldingItem, Interval, Kline, LimitUpPoolItem, MainOperationSegment, MarketDataRegistration, MarketDataRegistry, MarketDataService, MarketRouterService, NewsAggregator, NewsItem, OperatingEfficiency, Order, OrderRequest, OrderSide, OrderStatus, OrderType, Orderbook, OrderbookLevel, Position, PositionSide, ResearchReportItem, ShareholderItem, SplitItem, StockFundamentals, Ticker, TradeFill, TradeRegistration, TradeRegistry, TradeService, TradeTick, TradingNewsRegistry };
802
+ export { AccountBalance, AggregateNewsOptions, AggregateNewsResult, AuctionSnapshot, BuybackItem, CompanyProfile, CryptoFundamentals, DerivativesData, DerivativesHistory, DerivativesPoint, Disposable, DividendItem, DragonTigerItem, FinancialCell, FinancialIndicatorRow, FinancialReportGroup, FinancialReportMatrix, FlashFeedService, ForecastSummary, FundamentalsPackage, HolderNumSummary, InsiderTradeItem, InstitutionalHoldingItem, Interval, Kline, LimitUpPoolItem, MacroCalendarEntry, MacroFeedService, MacroRateEntry, MainOperationSegment, MarketDataRegistration, MarketDataRegistry, MarketDataService, MarketRouterService, NewsAggregator, NewsItem, OperatingEfficiency, Order, OrderRequest, OrderSide, OrderStatus, OrderType, Orderbook, OrderbookLevel, Position, PositionSide, ResearchReportItem, ShareholderItem, SplitItem, StockFundamentals, Ticker, TradeFill, TradeRegistration, TradeRegistry, TradeService, TradeTick, TradingNewsRegistry };
package/lib/index.d.ts CHANGED
@@ -8,16 +8,18 @@ declare const provider: SkillProvider;
8
8
  interface Config {
9
9
  dryRun: boolean;
10
10
  liveTrading: boolean;
11
- /** 角色预设按需收窄技能面;缺省保持全量捆绑目录。 */
12
- skills?: string[];
11
+ /** 角色预设按需收窄技能面;字段缺席保持全量捆绑目录,显式空数组才表示不下发任何技能。 */
12
+ skills?: string[] | null;
13
13
  }
14
14
  declare const Config: Schema<Config>;
15
15
  declare const inject: string[];
16
16
  declare const name = "dsh-trading-hk-kit";
17
17
  /** 白名单视图:未知名 fail-fast 不静默缩面;白名单外的 get 拒绝分发。 */
18
- declare function providerForSkills(allowed?: readonly string[]): SkillProvider;
18
+ declare function providerForSkills(allowed?: readonly string[] | null): SkillProvider;
19
19
  declare function apply(ctx: Context, config: Config): void;
20
- declare function createGetNewsTool(): import("@deepseek-ai/dsh-tools").ToolDefinition;
20
+ declare function createGetNewsTool(toolOptions?: {
21
+ getSources?: () => readonly string[] | undefined;
22
+ }): import("@deepseek-ai/dsh-tools").ToolDefinition;
21
23
  declare function createGetFundamentalsTool(options?: {
22
24
  fetch?: typeof globalThis.fetch;
23
25
  }): import("@deepseek-ai/dsh-tools").ToolDefinition;
package/lib/index.js CHANGED
@@ -115,7 +115,7 @@ const provider = {
115
115
  const Config = Schema.object({
116
116
  dryRun: Schema.boolean().default(true),
117
117
  liveTrading: Schema.boolean().default(false),
118
- skills: Schema.array(Schema.string())
118
+ skills: Schema.union([Schema.array(Schema.string()), Schema.const(null)]).default(null)
119
119
  });
120
120
  const inject = ["skills", "tools"];
121
121
  const name = "dsh-trading-hk-kit";
@@ -136,7 +136,9 @@ function providerForSkills(allowed) {
136
136
  }
137
137
  function apply(ctx, config) {
138
138
  ctx.skills.registerProvider(() => providerForSkills(config.skills));
139
- const newsTool = createGetNewsTool();
139
+ const routerCtx = ctx;
140
+ const readNewsSources = () => (routerCtx.get?.("tradingMarketRouter", false))?.newsSources?.("hk");
141
+ const newsTool = createGetNewsTool({ getSources: readNewsSources });
140
142
  const fundamentalsTool = createGetFundamentalsTool();
141
143
  const tools = ctx.tools;
142
144
  const registerOnce = (tool) => {
@@ -165,7 +167,7 @@ const DEFAULT_NEWS_LIMIT = 20;
165
167
  function renderNewsItem(item) {
166
168
  return `[${item.source}] ${item.publishedAt} ${item.title}\n ${item.url}`;
167
169
  }
168
- function createGetNewsTool() {
170
+ function createGetNewsTool(toolOptions = {}) {
169
171
  return defineTool({
170
172
  name: "hk_get_news",
171
173
  description: "Get recent Hong Kong stock market news, derived from Eastmoney financial fast-news (HK column) filtered to HK-relevant items (HKEX-listed marketId=116 codes or HK keywords). DEGRADED SOURCE — Eastmoney is a unified CN financial feed; HK coverage is PARTIAL (HK news without an HK-listed code or HK keyword is not captured; not a dedicated HK news source). Each item carries source name (东方财富), publish time and a link for traceability; fetches metadata only, never redistributes article bodies. Optionally filter by symbol (HK code, e.g. 00700 / 00700.HK) and by a time window. No credentials required.",
@@ -197,7 +199,8 @@ function createGetNewsTool() {
197
199
  const options = {
198
200
  symbol: typeof args.symbol === "string" ? args.symbol : void 0,
199
201
  windowHours: typeof args.windowHours === "number" ? args.windowHours : void 0,
200
- limit: typeof args.limit === "number" ? args.limit : void 0
202
+ limit: typeof args.limit === "number" ? args.limit : void 0,
203
+ sources: toolOptions.getSources?.()
201
204
  };
202
205
  const { items, unavailable } = await aggregateNews(options);
203
206
  if (items.length === 0 && unavailable.length === 0) return "hk_get_news: no news items found within the requested window (degraded source: Eastmoney HK column may have no HK-relevant items in-window).";
package/lib/news.d.ts CHANGED
@@ -31,6 +31,8 @@ interface AggregateNewsOptions {
31
31
  now?: number | undefined;
32
32
  /** CryptoPanic API token(桥面透传,hk 聚合器忽略;对齐 api 契约形状)。 */
33
33
  cryptoPanicKey?: string | undefined;
34
+ /** 启用源 id 列表(issue #96 源配置化);缺省 = 全部默认源,空数组 = 显式关闭。 */
35
+ sources?: readonly string[] | undefined;
34
36
  }
35
37
  interface AggregateNewsResult {
36
38
  items: NewsItem[];
package/lib/news.js CHANGED
@@ -459,10 +459,13 @@ async function aggregateNews(options = {}) {
459
459
  const now = options.now ?? Date.now();
460
460
  const windowMs = clampNumber(options.windowHours, DEFAULT_WINDOW_HOURS, 1, 168) * 36e5;
461
461
  const limit = clampNumber(options.limit, DEFAULT_LIMIT, 1, MAX_LIMIT);
462
- const fetchers = [fetchEastmoneyHk(fetchImpl, limit)];
462
+ const enabled = options.sources;
463
+ const isEnabled = (id) => enabled === void 0 || enabled.includes(id);
464
+ const fetchers = [];
465
+ if (isEnabled("eastmoney")) fetchers.push(fetchEastmoneyHk(fetchImpl, limit));
463
466
  if (options.symbol && options.symbol.trim()) {
464
- fetchers.push(fetchEastmoneyHkAnnouncements(fetchImpl, options.symbol, limit));
465
- fetchers.push(fetchHkexAnnouncements(fetchImpl, options.symbol, limit, now));
467
+ if (isEnabled("eastmoney-announcement")) fetchers.push(fetchEastmoneyHkAnnouncements(fetchImpl, options.symbol, limit));
468
+ if (isEnabled("hkex-announcement")) fetchers.push(fetchHkexAnnouncements(fetchImpl, options.symbol, limit, now));
466
469
  }
467
470
  const results = await Promise.allSettled(fetchers);
468
471
  const items = [];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dshtrading/kit-hk",
3
3
  "description": "Hong Kong market toolkit plugin for dsh-trading: HK risk checklist skill provider and HK fast-news (degraded) / fundamentals tools; runs as an hk-trader preset row (session-scoped)",
4
- "version": "0.2.1",
4
+ "version": "0.4.0",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "types": "./lib/index.d.ts",
@@ -18,8 +18,8 @@
18
18
  ],
19
19
  "license": "PolyForm-Noncommercial-1.0.0",
20
20
  "dependencies": {
21
- "@dshtrading/knowledge": "0.2.1",
22
- "@dshtrading/indicators": "0.2.1"
21
+ "@dshtrading/indicators": "0.4.0",
22
+ "@dshtrading/knowledge": "0.4.0"
23
23
  },
24
24
  "peerDependencies": {
25
25
  "@deepseek-ai/cordis": ">=4.0.0",
@@ -30,7 +30,7 @@
30
30
  "devDependencies": {
31
31
  "tsdown": "^0.22.0",
32
32
  "vitest": "^3.0.0",
33
- "@dshtrading/api": "0.2.1"
33
+ "@dshtrading/api": "0.4.0"
34
34
  },
35
35
  "scripts": {
36
36
  "build": "tsdown",