@dshtrading/connector-bybit 0.6.1 → 0.6.2
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.
- package/README.md +187 -25
- package/lib/dataplane.d.ts +2 -2
- package/lib/dataplane.js +5 -4
- package/lib/index.d.ts +9 -7
- package/lib/index.js +10 -29
- package/lib/rest.d.ts +2 -3
- package/lib/rest.js +0 -7
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,34 +1,196 @@
|
|
|
1
|
-
# @dshtrading/connector-
|
|
1
|
+
# @dshtrading/connector-bybit
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Bybit v5 加密货币连接器(crypto 市场):实现 `@dshtrading/api` 的 `MarketDataService`
|
|
4
|
+
(现货 ∪ 线性永续公共行情),并把一个 TradeService 占位实现注册进路由交易面——
|
|
5
|
+
三态闸门与私有账户读面的失败关闭语义保留,**私有账户面与真实下单均未实现**。
|
|
6
|
+
凭证走 BYOK:配置里只出现环境变量名,不出现值。
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
## 状态
|
|
9
|
+
|
|
10
|
+
**部分实证(上游可达性受出口地区限制)**。
|
|
11
|
+
|
|
12
|
+
- **2026-10-08 可达出口复验**(commit `25d18c7bbbc7191951b82fbc263b9deafe4d64e0`,
|
|
13
|
+
出口 SG `188.253.121.148`):20 条判据全过、探针退出码 0,含线性合约真值
|
|
14
|
+
(`TSLAUSDT-SWAP` 374.34/374.21、`BTCUSDT-SWAP` 82339.7)与 `crypto_get_ticker`
|
|
15
|
+
底层服务路径的真价。证据 [EVIDENCE-reverify-2026-10-08.md](../../spikes/impl-crypto-perp-tradfi/EVIDENCE-reverify-2026-10-08.md)。
|
|
16
|
+
- **同一 commit 记录的地域封锁**:本机默认出口(美国节点 `216.195.208.136`)对
|
|
17
|
+
`api.bybit.com` 全量 **HTTP 403**(`api.bytick.com` / `api-demo.bybit.com` /
|
|
18
|
+
`api.bybit.nl` 同样;经 `-x http://127.0.0.1:7890` 仍是同一出口 IP、仍 403),
|
|
19
|
+
响应体自证 `The Amazon CloudFront distribution is configured to block access from your country`;
|
|
20
|
+
换 SG/JP/HK/TW/DE/KR/GB 出口后同一端点全部 200。证据
|
|
21
|
+
[EVIDENCE-P3-bybit-ccxt.md](../../spikes/impl-crypto-perp-tradfi/EVIDENCE-P3-bybit-ccxt.md) 第 1 节,
|
|
22
|
+
原始响应 `bybit-egress-blocked-*.json` / `.headers` 同目录。
|
|
23
|
+
- **更早、当时本出口可达的实证**:2026-08-31 评审随测 bybit ticker `BTCUSDT` 77773、
|
|
24
|
+
5m K 线 8 根([verify-connectors-suite/EVIDENCE.md](../../spikes/verify-connectors-suite/EVIDENCE.md)
|
|
25
|
+
第 6/7 项);2026-09-02 盘口与逐笔
|
|
26
|
+
([impl-orderbook-ticks/EVIDENCE.md](../../spikes/impl-orderbook-ticks/EVIDENCE.md),
|
|
27
|
+
原始响应 `bybit-orderbook-raw.json`);2026-09-02 衍生品子查询
|
|
28
|
+
([impl-crypto-derivatives/EVIDENCE.md](../../spikes/impl-crypto-derivatives/EVIDENCE.md))。
|
|
29
|
+
- **未实证**:签名私有账户读面、真实下单与撤单——源码内没有对应实现(见「已知边界」)。
|
|
30
|
+
|
|
31
|
+
## 配置
|
|
32
|
+
|
|
33
|
+
| 字段 | 默认 | 说明 |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| `enabled` | `true` | 是否激活本连接器;`false` 时 `apply` 立即返回 |
|
|
36
|
+
| `dryRun` | `true` | 强制模拟下单:为 `true` 时即使 `liveTrading=true` 且请求 `dryRun=false`,也只回本地模拟回执 |
|
|
37
|
+
| `liveTrading` | `false` | 实盘开关的**非权威镜像**;真正授权由 `@dshtrading/authority` 的人工签署平面裁定 |
|
|
38
|
+
| `apiKeyRef` | `'BYBIT_API_KEY'` | API Key 的**环境变量名**(BYOK);`apply` 时 `process.env[apiKeyRef]` 取值 |
|
|
39
|
+
| `secretRef` | `'BYBIT_SECRET_KEY'` | Secret 的环境变量名;值只存进客户端字段,**不参与任何签名**(当前无签名路径)。设置页自 2026-10-15 起也不再挂凭据卡片——填了到不了请求,见「已知边界」第 3 条 |
|
|
40
|
+
|
|
41
|
+
依据:`src/index.ts:47-53`(schema 与默认值)、`src/index.ts:281-282`(环境变量读取)、
|
|
42
|
+
`src/rest.ts:205-210`(baseUrl 与凭证字段)、`src/rest.ts:215-217`(请求头只有 `Accept`)。
|
|
43
|
+
|
|
44
|
+
## 接线
|
|
45
|
+
|
|
46
|
+
- **数据面行**:`packages/crypto/cordis.patch.yml:32-34` → 行 id `dsh-trading-crypto-dataplane-bybit`,
|
|
47
|
+
模块 `@dshtrading/connector-bybit/dataplane`。该入口把 `(crypto, bybit)` 注册进
|
|
48
|
+
`tradingMarketDataRegistry`(`src/dataplane.ts:49`)与 `tradingTradeRegistry`(`src/dataplane.ts:55`),
|
|
49
|
+
**不注册任何工具**。
|
|
50
|
+
- **preset 行**:`packages/crypto/assets/preset/crypto-trader/agent.cordis.yml:65-77` → isolate 组
|
|
51
|
+
id `dsh-trading-crypto-connector-bybit-group`(isolate `tradingCryptoMarketData` 与
|
|
52
|
+
`tradingCryptoTrade`),内层行 id `dsh-trading-crypto-connector-bybit`(第 72-73 行),
|
|
53
|
+
行内只写 `enabled: true` / `dryRun: true` / `liveTrading: false`(schema 默认值由本模块导出的
|
|
54
|
+
`Config` 补全,见 `src/dataplane.ts:16`)。
|
|
55
|
+
- **服务键**:`tradingCryptoMarketData`(`src/index.ts:55`)、`tradingCryptoTrade`(`src/index.ts:56`)。
|
|
56
|
+
- **provider 词汇**:`packages/router/src/index.ts:65` 登记 `bybit`。
|
|
57
|
+
- **设置页显示名与提示**:`PROVIDER_LABELS` 的 `bybit` 条目
|
|
58
|
+
(`packages/client-ui-settings/src/client/trading-settings-controller.ts:45`:`type: 'public'`、
|
|
59
|
+
`env: 'BYBIT_API_KEY'`、`markets: ['crypto']`)与 `packages/client-ui-settings/src/client/locales.ts`
|
|
60
|
+
的 `'provider.bybit'` 条目(zh / en 都是 `Bybit`)。`env` 与「配置」表里 `apiKeyRef` 的 schema
|
|
61
|
+
默认名同名(`src/index.ts:52`)——设置页文案与连接器读取的环境变量名同源。**凭据卡片已撤**
|
|
62
|
+
(2026-10-15):本包只从 env 取值且没有任何签名出站路径,面板填的 key 到不了请求,
|
|
63
|
+
撤字段的理由与对照见[设置页凭据面收窄](../../.agents/notes/implemented/simplification/2026-10-15-settings-credential-surface-narrowed.md)。
|
|
64
|
+
- **profile overrides**:`node scripts/sync-profile-overrides.mjs --all --dsh-home ~/.dsh-trading`
|
|
65
|
+
(注意 `--dsh-home`;宿主会话继承的 `DSH_HOME` 指向别处会找错 profile 集)。
|
|
66
|
+
|
|
67
|
+
用户切换:设置 → 数据源 → crypto → Bybit。
|
|
68
|
+
|
|
69
|
+
## 上游端点
|
|
70
|
+
|
|
71
|
+
全部打在同一个 baseUrl(`src/rest.ts:206`,`https://api.bybit.com`)上;无模拟盘域名;
|
|
72
|
+
所有请求只带 `Accept: application/json`(`src/rest.ts:215-217`),不带签名头。
|
|
73
|
+
|
|
74
|
+
| 用途 | 端点 | 源码行 |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| 行情快照 | `GET /v5/market/tickers?category={spot 或 linear}&symbol=` | `src/rest.ts:251` |
|
|
77
|
+
| K 线 | `GET /v5/market/kline?category={spot 或 linear}&symbol=&interval=&limit=` | `src/rest.ts:287` |
|
|
78
|
+
| 标的名册 | `GET /v5/market/instruments-info?category={spot 或 linear}&limit=1000&cursor=`(游标翻页) | `src/rest.ts:312` |
|
|
79
|
+
| 线性合约快照(fundingRate / openInterest / openInterestValue / markPrice / indexPrice / nextFundingTime) | `GET /v5/market/tickers?category=linear&symbol=` | `src/rest.ts:387` |
|
|
80
|
+
| 多空账户人数比 | `GET /v5/market/account-ratio?category=linear&symbol=&period=1h&limit=1` | `src/rest.ts:417` |
|
|
81
|
+
| 资金费率历史 | `GET /v5/market/funding/history?category=linear&symbol=&limit=`(上限 100) | `src/rest.ts:441` |
|
|
82
|
+
| 持仓量历史 | `GET /v5/market/open-interest?category=linear&symbol=&intervalTime=1d&limit=`(上限 50) | `src/rest.ts:466` |
|
|
83
|
+
| 盘口(25 档) | `GET /v5/market/orderbook?category={spot 或 linear}&symbol=&limit=25` | `src/rest.ts:501` |
|
|
84
|
+
| 最近逐笔成交 | `GET /v5/market/recent-trade?category={spot 或 linear}&symbol=&limit=`(上限 60) | `src/rest.ts:537` |
|
|
9
85
|
|
|
10
|
-
|
|
11
|
-
(src/rest.ts 头部清单 7 项)实现 TODO。每个 TODO 的参照段都在 connector-okx
|
|
12
|
-
(packages/connector-okx/),它是本仓第一个真实 TradeService 连接器。
|
|
86
|
+
上表是源码里出现过的全部上游请求;本包没有 `api.bybit.com` 之外的任何主机。
|
|
13
87
|
|
|
14
|
-
##
|
|
88
|
+
## 周期与契约
|
|
15
89
|
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
- `
|
|
90
|
+
- **周期词汇**:`1m / 5m / 15m / 30m / 1h / 4h / 1d / 1w / 1M`(`src/rest.ts:38`),
|
|
91
|
+
映射到 Bybit 的 `1 / 5 / 15 / 30 / 60 / 240 / D / W / M`(`src/rest.ts:40-52`)。
|
|
92
|
+
词汇表外的值在类型层即不可表达,不做静默降级。
|
|
93
|
+
- **符号形态**:`parseCryptoSymbol`(`src/rest.ts:83-88`)去空白、转大写、剥掉整段 `-SWAP`、
|
|
94
|
+
删 `- _ /` 分隔符;形态由 `@dshtrading/api` 的 `instrumentFormOf` 裁决(连接器不自写后缀判断)。
|
|
95
|
+
规范输出:现货 `BTCUSDT`,永续 `BTCUSDT-SWAP`。空符号 → `TRADING_INVALID_ARGUMENT`(`src/rest.ts:86`)。
|
|
96
|
+
- **形态即 category**:`perp → linear`、`spot → spot`(`src/rest.ts:101-103`)。
|
|
97
|
+
ticker / klines / orderbook / recent-trade 四条路径共用这一处分岔,
|
|
98
|
+
**`-SWAP` 不会被静默打到现货端点**(回归由 `test/perp-market-data.test.ts` 按 URL 断言)。
|
|
99
|
+
- **错误映射**(`src/rest.ts:212-230`):非 2xx → `TRADING_UPSTREAM_ERROR`;fetch 抛错 →
|
|
100
|
+
`TRADING_NETWORK`。业务层:ticker 命中空列表或 `retCode≠0` → `TRADING_UNSUPPORTED_SYMBOL`
|
|
101
|
+
(`src/rest.ts:253-257`;Bybit 对不存在的标的回 `retCode:0` + 空列表);
|
|
102
|
+
名册 / 盘口 / 逐笔 / 费率历史 / OI 历史的响应形状异常 → `TRADING_EXCHANGE_ERROR`。
|
|
103
|
+
- **例外(已知缺口)**:K 线在 `retCode≠0` 或缺 `result.list` 时返回**空数组**而不是结构化错误
|
|
104
|
+
(`src/rest.ts:289-291`)。
|
|
105
|
+
- **缺省纪律**:上游空串不当 0(`src/rest.ts:106-112`);合约元数据字段缺失即缺省
|
|
106
|
+
(`src/rest.ts:119-136`);`assetClass` 只由交易所 `symbolType` 字面量裁决,
|
|
107
|
+
空串与未登记取值(`forex` / `mstocks`)一律留空,不按符号猜(`src/rest.ts:153-166`)。
|
|
108
|
+
- **名册口径**:现货 ∪ 线性永续,只收 `status=Trading`,线性侧还要求
|
|
109
|
+
`contractType=LinearPerpetual`(`src/rest.ts:347-364`);翻页带重复游标守卫(`src/rest.ts:326-341`)。
|
|
22
110
|
|
|
23
|
-
##
|
|
111
|
+
## 能力面
|
|
112
|
+
|
|
113
|
+
服务方法(`BybitMarketDataService` / `BybitTradeService`):
|
|
114
|
+
|
|
115
|
+
| 方法 | 有/缺席 | 说明 |
|
|
116
|
+
|---|---|---|
|
|
117
|
+
| `getTicker` | 有 | 现货与线性永续,输出规范形(`src/index.ts:70`) |
|
|
118
|
+
| `getKlines` | 有 | 同上形态分岔(`src/index.ts:74`) |
|
|
119
|
+
| `listInstruments` | 有 | 现货 ∪ 线性永续名册,带 `form` 与 `contract`(`src/index.ts:84`) |
|
|
120
|
+
| `subscribeTicker` | 有 | 快照轮询,最小 1000 ms、缺省 5000 ms(`src/index.ts:88-96`) |
|
|
121
|
+
| `getOrderbook` | 有 | 25 档(`src/index.ts:99`) |
|
|
122
|
+
| `getRecentTrades` | 有 | 时间升序,上限 60(`src/index.ts:104`) |
|
|
123
|
+
| `getDerivatives` | 有 | 单所聚合快照,子查询失败只降级对应字段(`src/index.ts:114`) |
|
|
124
|
+
| `getDerivativesHistory` | 有 | 费率 + OI 双序列,单序列失败即该字段缺省(`src/index.ts:160`) |
|
|
125
|
+
| `placeOrder` | 有(模拟) | 三态闸门;模拟回执由服务层本地合成(`src/index.ts:205-232`) |
|
|
126
|
+
| `cancelOrder` | 有(受限) | 未获实盘授权或 `dryRun=true` 时结构化拒绝(`src/index.ts:234-242`) |
|
|
127
|
+
| `getOrder` | 有(失败关闭) | 恒抛 `TRADING_NOT_IMPLEMENTED`(`src/index.ts:251-257`) |
|
|
128
|
+
| `getPositions` | 有(失败关闭) | 恒抛 `TRADING_NOT_IMPLEMENTED`(`src/index.ts:259-265`) |
|
|
129
|
+
| `getBalances` / `listOpenOrders` / `listTradeFills` | 缺席 | 可选方法未定义,消费方按「缺席」处理 |
|
|
130
|
+
| `setLeverage` | 缺席 | 未定义 |
|
|
131
|
+
|
|
132
|
+
工具(`apply` 内注册,duplicate-safe,`src/index.ts:294-317`):
|
|
133
|
+
|
|
134
|
+
| 工具 | 参数 | 说明 |
|
|
135
|
+
|---|---|---|
|
|
136
|
+
| `crypto_get_ticker` | `symbol`(必填) | 现货形取现货、`-SWAP` 形取线性永续 |
|
|
137
|
+
| `crypto_get_klines` | `symbol` / `interval`(枚举 = 周期词汇,缺省 `1d`)/ `limit`(缺省 100) | 同上形态分岔 |
|
|
138
|
+
|
|
139
|
+
**本包只注册这 2 个工具**:盘口、逐笔、名册、衍生品快照与历史只在服务面可达,
|
|
140
|
+
没有对应工具名;交易面同样没有注册任何工具(唯一可达面是动态包 `inject` 直调服务)。
|
|
141
|
+
|
|
142
|
+
## 已知边界
|
|
143
|
+
|
|
144
|
+
1. **live 下单路径仍是本地 sim stub**:闸门③放行后调用 `BybitRestClient.placeOrder`
|
|
145
|
+
(`src/rest.ts:546-559`),它不触网、返回 `sim-bybit-*` 回执且 `dryRun: true`;
|
|
146
|
+
`cancelOrder` 同理返回 `{orderId, status:'canceled'}`(`src/rest.ts:561-563`)。
|
|
147
|
+
当前没有 Bybit 下单工具、GUI 桥强制 `dryRun=true`,可达面只有动态包 `inject` 直调。
|
|
148
|
+
见 [fabricated-trade-surface-fail-closed.md](../../.agents/notes/implemented/simplification/2026-10-10-fabricated-trade-surface-fail-closed.md)。
|
|
149
|
+
2. **私有账户读面失败关闭**:`getOrder` / `getPositions` 抛 `TRADING_NOT_IMPLEMENTED`
|
|
150
|
+
(语义是「不可用」,不是「订单不存在」或「没有持仓」);`getBalances` / `listOpenOrders` /
|
|
151
|
+
`listTradeFills` 直接缺席。此前硬编码的 100000 余额与恒空数组已删除,见同一份 Note。
|
|
152
|
+
3. **凭证不参与签名(设置页凭据卡片已撤)**:`apiKeyRef` / `secretRef` 解析出的值只存进客户端字段
|
|
153
|
+
(`src/rest.ts:206-207`),全部请求走免密公共端点;本包没有任何签名实现,`placeOrder` 的
|
|
154
|
+
`_creds` 形参被忽略(`src/rest.ts:546`)。设置页原先挂的 `apiKey` / `apiSecret` 卡片因此与
|
|
155
|
+
ccxt / binance 同批撤下(2026-10-15)——面板写的键不落任何请求;`BYBIT_API_KEY` 环境变量仍是
|
|
156
|
+
连接器自己的取值面。理由与对照见[设置页凭据面收窄](../../.agents/notes/implemented/simplification/2026-10-15-settings-credential-surface-narrowed.md)。
|
|
157
|
+
4. **K 线错误静默为空数组**(`src/rest.ts:289-291`),不抛结构化错误。
|
|
158
|
+
5. **地域封锁(实测)**:默认出口对 `api.bybit.com` 全量 403,换出口地区才可达,
|
|
159
|
+
见「状态」段的证据与日期。这是上游按出口国家的拦截,不是本包可控项。
|
|
160
|
+
6. **类型存量债**:本包 `tsconfig.json` 有 12 条 tsc 错误记在
|
|
161
|
+
`scripts/typecheck-baseline.json:35`(棘轮基线内的旧债,本 README 不改动)。
|
|
162
|
+
|
|
163
|
+
## 合规记录
|
|
164
|
+
|
|
165
|
+
- Bybit 公共行情端点:公开、免密;本包不内置密钥,不把凭证值写进日志或回执。
|
|
166
|
+
- 凭证只以**环境变量名**(ref)形式出现在配置与仓库里;值在 `apply` 时读入进程内存,
|
|
167
|
+
只传给 REST 客户端字段,不参与签名、不外发(见「配置」与「已知边界」第 3 条)。
|
|
168
|
+
- 本仓不缓存、不再分发行情数据。
|
|
169
|
+
- 地域拦截由上游按出口国家实施(响应体自证 CloudFront);换出口属**用户侧环境选择**,
|
|
170
|
+
不是仓库配置的一部分(`EVIDENCE-reverify-2026-10-08.md` 第 2 节原文:出口地区是机器状态)。
|
|
171
|
+
- 许可:`PolyForm-Noncommercial-1.0.0`(`package.json`)。
|
|
172
|
+
- 本包是数据与执行通道的技术实现,不构成投资建议。
|
|
173
|
+
|
|
174
|
+
## 出网验证
|
|
175
|
+
|
|
176
|
+
```sh
|
|
177
|
+
node_modules/.bin/tsx spikes/impl-crypto-perp-tradfi/run-reverify-probe.ts # 20 条判据,需可达出口
|
|
178
|
+
node spikes/impl-crypto-derivatives/run-derivatives-probe.mjs # 衍生品子查询与解析
|
|
179
|
+
node spikes/impl-orderbook-ticks/run-orderbook-probe.mjs # 盘口与逐笔原始响应
|
|
180
|
+
pnpm --filter @dshtrading/connector-bybit test # 离线:闸门三态/名册/形态/账户读面
|
|
181
|
+
```
|
|
24
182
|
|
|
25
|
-
`bybit
|
|
26
|
-
|
|
27
|
-
|
|
183
|
+
- 前置:可达出口(默认出口对 `api.bybit.com` 返回 403)。`run-reverify-probe.ts`
|
|
184
|
+
经本机 mihomo 控制器切地域节点,探针自带还原 trap。
|
|
185
|
+
- **三态闸门与账户读面的证据是离线测试**(`test/trade-gate.test.ts` 6 例、
|
|
186
|
+
`test/account-read-surface.test.ts` 5 例),不含真实下单。
|
|
187
|
+
- 真实网络下的服务缝闸门验证只覆盖 okx(
|
|
188
|
+
[impl-service-seam-gate/NET-VERIFY.md](../../spikes/impl-service-seam-gate/NET-VERIFY.md));
|
|
189
|
+
Bybit 的服务缝行为由上述离线矩阵覆盖,未对 Bybit 做真实下单验证。
|
|
28
190
|
|
|
29
|
-
##
|
|
191
|
+
## 参见
|
|
30
192
|
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
193
|
+
- Owning Note:[crypto-perp-data-plane-bybit-ccxt.md](../../.agents/notes/implemented/feature/2026-10-08-crypto-perp-data-plane-bybit-ccxt.md)
|
|
194
|
+
- 设计与卡拆分:[crypto-perp-and-tradfi.md](../../docs/roadmap/crypto-perp-and-tradfi.md)(P3)
|
|
195
|
+
- 全仓当前状态与硬停:[docs/current-state.md](../../docs/current-state.md)
|
|
196
|
+
- 连接器横向对照:[connectors-guide.md](../../docs/guides/connectors-guide.md)
|
package/lib/dataplane.d.ts
CHANGED
|
@@ -2,6 +2,6 @@ import { Config } from "./index.js";
|
|
|
2
2
|
import { Context } from "@deepseek-ai/cordis";
|
|
3
3
|
//#region src/dataplane.d.ts
|
|
4
4
|
declare const inject: string[];
|
|
5
|
-
declare function apply(ctx: Context, config
|
|
5
|
+
declare function apply(ctx: Context, config?: Config): void;
|
|
6
6
|
//#endregion
|
|
7
|
-
export { apply, inject };
|
|
7
|
+
export { Config, apply, inject };
|
package/lib/dataplane.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { BybitMarketDataService, BybitTradeService, TRADING_CRYPTO_MARKET_DATA_KEY, TRADING_CRYPTO_TRADE_KEY } from "./index.js";
|
|
1
|
+
import { BybitMarketDataService, BybitTradeService, Config, ROUTER_PROVIDER, TRADING_CRYPTO_MARKET_DATA_KEY, TRADING_CRYPTO_TRADE_KEY } from "./index.js";
|
|
2
2
|
//#region src/dataplane.ts
|
|
3
3
|
const inject = [];
|
|
4
|
+
/** schema 的运行时可调用形态(校验即补默认值);手工构造 ctx 不传 config 时按 schema 默认值处理。 */
|
|
5
|
+
const withDefaults = (value) => Config(value);
|
|
4
6
|
function resolveMarketDataRegistry(ctx) {
|
|
5
7
|
const candidate = ctx.get?.("tradingMarketDataRegistry", false);
|
|
6
8
|
return candidate !== void 0 ? candidate : void 0;
|
|
@@ -9,9 +11,8 @@ function resolveTradeRegistry(ctx) {
|
|
|
9
11
|
const candidate = ctx.get?.("tradingTradeRegistry", false);
|
|
10
12
|
return candidate !== void 0 ? candidate : void 0;
|
|
11
13
|
}
|
|
12
|
-
const ROUTER_PROVIDER = "bybit";
|
|
13
14
|
const MARKET = "crypto";
|
|
14
|
-
function apply(ctx, config) {
|
|
15
|
+
function apply(ctx, config = withDefaults(void 0)) {
|
|
15
16
|
if (!config.enabled) return;
|
|
16
17
|
const apiKey = process.env[config.apiKeyRef];
|
|
17
18
|
const apiSecret = process.env[config.secretRef];
|
|
@@ -41,4 +42,4 @@ function apply(ctx, config) {
|
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
//#endregion
|
|
44
|
-
export { apply, inject };
|
|
45
|
+
export { Config, apply, inject };
|
package/lib/index.d.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { AccountBalance, BybitRestClient, BybitRestOptions, INTERVAL_VOCABULARY, Interval, Kline, Order, ParsedCryptoSymbol, Position, Ticker, TradingServiceError, bybitAssetClassOf, bybitCategory, normalizeCryptoSymbol, parseCryptoSymbol, parseIntervalMs, toBybitInterval } from "./rest.js";
|
|
2
2
|
import { Context, Service } from "@deepseek-ai/cordis";
|
|
3
3
|
import Schema from "@deepseek-ai/schemastery";
|
|
4
|
-
import {
|
|
4
|
+
import { DerivativesData, DerivativesHistory, Disposable, InstrumentRef, Interval as Interval$1, Kline as Kline$1, MarketDataService, Order as Order$1, OrderRequest, Orderbook, Position as Position$1, Ticker as Ticker$1, TradeService, TradeTick } from "@dshtrading/api";
|
|
5
5
|
//#region src/index.d.ts
|
|
6
6
|
declare const name = "dsh-trading-crypto-connector-bybit";
|
|
7
7
|
interface Config {
|
|
8
8
|
enabled: boolean;
|
|
9
|
-
env: 'demo' | 'live';
|
|
10
9
|
dryRun: boolean;
|
|
11
10
|
liveTrading: boolean;
|
|
12
11
|
apiKeyRef: string;
|
|
@@ -55,14 +54,17 @@ declare class BybitTradeService extends Service implements TradeService {
|
|
|
55
54
|
constructor(ctx: Context, options: BybitRestOptions & {
|
|
56
55
|
config: Config;
|
|
57
56
|
}, serviceName?: string);
|
|
58
|
-
getBalance(): Promise<AccountBalance$1>;
|
|
59
|
-
getBalances(): Promise<AccountBalance$1[]>;
|
|
60
57
|
placeOrder(order: OrderRequest): Promise<Order$1>;
|
|
61
58
|
cancelOrder(orderId: string, _symbol?: string): Promise<void>;
|
|
62
|
-
|
|
59
|
+
/**
|
|
60
|
+
* 私有账户读面未实现(连接器没有签名读路径):必须显式拒绝。base 的账户工具
|
|
61
|
+
* 与 GUI 桥把同一注册面当「交易所账户真值」消费——返回编造订单或空数组会被
|
|
62
|
+
* 读成「订单存在」「没有持仓」,而契约语义是 TRADING_NOT_IMPLEMENTED(不可用)。
|
|
63
|
+
* 可选方法 getBalances/listOpenOrders/listTradeFills 直接缺席,由消费方按
|
|
64
|
+
* 「可选方法缺席」处理(见 packages/api/src/index.ts 的 TradeService 注释)。
|
|
65
|
+
*/
|
|
66
|
+
getOrder(_symbol: string, _id: string): Promise<Order$1>;
|
|
63
67
|
getPositions(): Promise<Position$1[]>;
|
|
64
|
-
listOpenOrders(_symbol?: string): Promise<Order$1[]>;
|
|
65
|
-
listTradeFills(_symbol?: string, _limit?: number): Promise<TradeFill[]>;
|
|
66
68
|
}
|
|
67
69
|
declare const ROUTER_PROVIDER = "bybit";
|
|
68
70
|
declare function routeAllows(ctx: Context, config: Config, market: string): boolean;
|
package/lib/index.js
CHANGED
|
@@ -11,7 +11,6 @@ import Schema from "@deepseek-ai/schemastery";
|
|
|
11
11
|
const name = "dsh-trading-crypto-connector-bybit";
|
|
12
12
|
const Config = Schema.object({
|
|
13
13
|
enabled: Schema.boolean().default(true).description("是否激活 Bybit 连接器"),
|
|
14
|
-
env: Schema.union(["demo", "live"]).default("demo").description("运行环境"),
|
|
15
14
|
dryRun: Schema.boolean().default(true).description("默认模拟下单"),
|
|
16
15
|
liveTrading: Schema.boolean().default(false).description("是否允许实盘交易"),
|
|
17
16
|
apiKeyRef: Schema.string().default("BYBIT_API_KEY").description("Bybit API Key 环境变量名 (BYOK)"),
|
|
@@ -118,16 +117,6 @@ var BybitTradeService = class extends Service {
|
|
|
118
117
|
this.client = new BybitRestClient(options);
|
|
119
118
|
this.config = options.config;
|
|
120
119
|
}
|
|
121
|
-
async getBalance() {
|
|
122
|
-
return this.client.getBalance();
|
|
123
|
-
}
|
|
124
|
-
async getBalances() {
|
|
125
|
-
try {
|
|
126
|
-
return [await this.client.getBalance()];
|
|
127
|
-
} catch {
|
|
128
|
-
return [];
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
120
|
async placeOrder(order) {
|
|
132
121
|
const requestedDryRun = order.dryRun ?? true;
|
|
133
122
|
if (!requestedDryRun && !liveTradingEnabled(this.config.liveTrading)) throw new TradingServiceError("TRADING_LIVE_TRADING_DISABLED", `Bybit TradeService.placeOrder rejected: the request asks for real execution (dryRun=${String(order.dryRun)}) but the signed live-trading authority does not grant real execution (see @dshtrading/authority) — keep dryRun=true for a simulated fill.`);
|
|
@@ -148,26 +137,18 @@ var BybitTradeService = class extends Service {
|
|
|
148
137
|
if (!liveTradingEnabled(this.config.liveTrading) || this.config.dryRun) throw new TradingServiceError("TRADING_LIVE_TRADING_DISABLED", "Bybit TradeService.cancelOrder rejected at the service seam: cancel is a live action and requires a signed live-trading grant (see @dshtrading/authority) with dryRun=false.");
|
|
149
138
|
return this.client.cancelOrder(void 0, orderId);
|
|
150
139
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
timestamp: Date.now()
|
|
161
|
-
};
|
|
140
|
+
/**
|
|
141
|
+
* 私有账户读面未实现(连接器没有签名读路径):必须显式拒绝。base 的账户工具
|
|
142
|
+
* 与 GUI 桥把同一注册面当「交易所账户真值」消费——返回编造订单或空数组会被
|
|
143
|
+
* 读成「订单存在」「没有持仓」,而契约语义是 TRADING_NOT_IMPLEMENTED(不可用)。
|
|
144
|
+
* 可选方法 getBalances/listOpenOrders/listTradeFills 直接缺席,由消费方按
|
|
145
|
+
* 「可选方法缺席」处理(见 packages/api/src/index.ts 的 TradeService 注释)。
|
|
146
|
+
*/
|
|
147
|
+
async getOrder(_symbol, _id) {
|
|
148
|
+
throw new TradingServiceError("TRADING_NOT_IMPLEMENTED", "Bybit TradeService.getOrder is not implemented: this connector has no signed private-account read path. That means \"not available\", NOT \"order not found\".");
|
|
162
149
|
}
|
|
163
150
|
async getPositions() {
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
async listOpenOrders(_symbol) {
|
|
167
|
-
return [];
|
|
168
|
-
}
|
|
169
|
-
async listTradeFills(_symbol, _limit) {
|
|
170
|
-
return [];
|
|
151
|
+
throw new TradingServiceError("TRADING_NOT_IMPLEMENTED", "Bybit TradeService.getPositions is not implemented: this connector has no signed private-account read path. That means \"not available\", NOT \"no positions\".");
|
|
171
152
|
}
|
|
172
153
|
};
|
|
173
154
|
const ROUTER_PROVIDER = "bybit";
|
package/lib/rest.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AccountBalance
|
|
1
|
+
import { AccountBalance, DerivativesPoint, InstrumentAssetClass, InstrumentForm, InstrumentRef, Interval as Interval$1, Kline as Kline$1, Order as Order$1, OrderRequest, Orderbook, Position as Position$1, Ticker as Ticker$1, TradeTick, TradingErrorCode } from "@dshtrading/api";
|
|
2
2
|
//#region src/rest.d.ts
|
|
3
3
|
declare class TradingServiceError extends Error {
|
|
4
4
|
readonly code: TradingErrorCode;
|
|
@@ -94,7 +94,6 @@ declare class BybitRestClient {
|
|
|
94
94
|
getOrderbook(symbol: string): Promise<Orderbook>;
|
|
95
95
|
/** 最近逐笔成交:GET /v5/market/recent-trade?category=spot(响应新→旧 → 反转升序)。 */
|
|
96
96
|
getRecentTrades(symbol: string, limit?: number): Promise<TradeTick[]>;
|
|
97
|
-
getBalance(): Promise<AccountBalance$1>;
|
|
98
97
|
placeOrder(_creds: unknown, req: OrderRequest): Promise<Order$1>;
|
|
99
98
|
cancelOrder(_creds: unknown, orderId: string): Promise<{
|
|
100
99
|
orderId: string;
|
|
@@ -102,4 +101,4 @@ declare class BybitRestClient {
|
|
|
102
101
|
}>;
|
|
103
102
|
}
|
|
104
103
|
//#endregion
|
|
105
|
-
export { type AccountBalance
|
|
104
|
+
export { type AccountBalance, BybitRestClient, BybitRestOptions, INTERVAL_VOCABULARY, type Interval$1 as Interval, type Kline$1 as Kline, type Order$1 as Order, ParsedCryptoSymbol, type Position$1 as Position, type Ticker$1 as Ticker, TradingServiceError, bybitAssetClassOf, bybitCategory, normalizeCryptoSymbol, parseCryptoSymbol, parseIntervalMs, toBybitInterval };
|
package/lib/rest.js
CHANGED
|
@@ -394,13 +394,6 @@ var BybitRestClient = class {
|
|
|
394
394
|
if (data.retCode !== 0 || !data.result?.list) throw new TradingServiceError("TRADING_EXCHANGE_ERROR", `Bybit trades for ${canonical}: unexpected response shape`);
|
|
395
395
|
return data.result.list.map((row) => this.#parseTradeRow(row, canonical)).reverse();
|
|
396
396
|
}
|
|
397
|
-
async getBalance() {
|
|
398
|
-
return {
|
|
399
|
-
currency: "USDT",
|
|
400
|
-
available: 1e5,
|
|
401
|
-
total: 1e5
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
397
|
async placeOrder(_creds, req) {
|
|
405
398
|
const sym = normalizeCryptoSymbol(req.symbol);
|
|
406
399
|
return {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dshtrading/connector-bybit",
|
|
3
|
-
"description": "
|
|
4
|
-
"version": "0.6.
|
|
3
|
+
"description": "Bybit v5 加密货币连接器:现货 ∪ 线性永续公共行情(ticker/K线/盘口/逐笔/名册/衍生品快照与历史)+ 保留三态闸门的交易占位服务(私有账户读面与真实下单未实现)。凭证走 BYOK 环境变量 ref。",
|
|
4
|
+
"version": "0.6.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"types": "./lib/index.d.ts",
|
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
],
|
|
22
22
|
"license": "PolyForm-Noncommercial-1.0.0",
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@dshtrading/authority": "^0.6.
|
|
25
|
-
"@dshtrading/api": "^0.6.
|
|
24
|
+
"@dshtrading/authority": "^0.6.2",
|
|
25
|
+
"@dshtrading/api": "^0.6.2"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"@deepseek-ai/cordis": ">=4.0.0",
|
|
29
|
-
"@deepseek-ai/dsh-tools": ">=0.2.
|
|
29
|
+
"@deepseek-ai/dsh-tools": ">=0.2.1-rc.2",
|
|
30
30
|
"@deepseek-ai/schemastery": ">=3.18.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|