@openfinclaw/findoo-datahub-plugin 2026.3.2 → 2026.3.10
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/DESIGN.md +492 -151
- package/_vendor/claude-skills-finance/SKILL.md +192 -0
- package/_vendor/claude-skills-finance/assets/dcf_analysis_template.md +184 -0
- package/_vendor/claude-skills-finance/assets/expected_output.json +161 -0
- package/_vendor/claude-skills-finance/assets/forecast_report_template.md +177 -0
- package/_vendor/claude-skills-finance/assets/sample_financial_data.json +219 -0
- package/_vendor/claude-skills-finance/assets/variance_report_template.md +122 -0
- package/_vendor/claude-skills-finance/references/financial-ratios-guide.md +396 -0
- package/_vendor/claude-skills-finance/references/forecasting-best-practices.md +294 -0
- package/_vendor/claude-skills-finance/references/valuation-methodology.md +255 -0
- package/_vendor/claude-skills-finance/scripts/budget_variance_analyzer.py +406 -0
- package/_vendor/claude-skills-finance/scripts/dcf_valuation.py +449 -0
- package/_vendor/claude-skills-finance/scripts/forecast_builder.py +494 -0
- package/_vendor/claude-skills-finance/scripts/ratio_calculator.py +432 -0
- package/index.ts +332 -14
- package/openclaw.plugin.json +2 -2
- package/package.json +1 -1
- package/references/cn-market-specifics.md +165 -0
- package/references/crypto-analysis.md +635 -0
- package/references/financial-ratios-cn.md +452 -0
- package/references/hk-market-specifics.md +166 -0
- package/references/macro-cycle-cn.md +409 -0
- package/references/valuation-cn.md +427 -0
- package/skills/README.md +294 -0
- package/skills/a-concept-cycle/skill.md +200 -0
- package/skills/a-convertible-arb/skill.md +294 -0
- package/skills/a-dividend-king/skill.md +187 -0
- package/skills/a-earnings-season/skill.md +221 -0
- package/skills/a-index-timer/skill.md +192 -0
- package/skills/a-ipo-new/skill.md +297 -0
- package/skills/a-northbound-decoder/skill.md +185 -0
- package/skills/a-quant-board/skill.md +286 -0
- package/skills/a-share/skill.md +347 -0
- package/skills/a-share-radar/skill.md +185 -0
- package/skills/cross-asset/skill.md +202 -0
- package/skills/crypto/skill.md +269 -0
- package/skills/crypto-altseason/skill.md +208 -0
- package/skills/crypto-btc-cycle/skill.md +231 -0
- package/skills/crypto-defi-yield/skill.md +181 -0
- package/skills/crypto-funding-arb/skill.md +158 -0
- package/skills/crypto-stablecoin-flow/skill.md +149 -0
- package/skills/data-query/skill.md +124 -30
- package/skills/derivatives/skill.md +188 -35
- package/skills/etf-fund/skill.md +216 -0
- package/skills/factor-screen/skill.md +186 -0
- package/skills/hk-china-internet/skill.md +190 -0
- package/skills/hk-dividend-harvest/skill.md +192 -0
- package/skills/hk-hsi-pulse/skill.md +154 -0
- package/skills/hk-southbound-alpha/skill.md +163 -0
- package/skills/hk-stock/skill.md +295 -0
- package/skills/macro/skill.md +244 -53
- package/skills/risk-monitor/skill.md +171 -0
- package/skills/us-dividend/skill.md +162 -0
- package/skills/us-earnings/skill.md +149 -0
- package/skills/us-equity/skill.md +235 -0
- package/skills/us-etf/skill.md +261 -0
- package/skills/us-sector-rotation/skill.md +223 -0
- package/src/config.ts +4 -5
- package/src/datahub-client.test.ts +4 -7
- package/src/datahub-client.ts +6 -1
- package/src/register-tools.ts +720 -0
- package/src/tool-helpers.ts +89 -0
- package/test/e2e/l3-gateway-bootstrap.live.test.ts +339 -0
- package/test/e2e/l4-skill-tool-chain.live.test.ts +465 -0
- package/skills/crypto-defi/skill.md +0 -69
- package/skills/equity/skill.md +0 -64
- package/skills/market-radar/skill.md +0 -47
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fin-us-sector-rotation
|
|
3
|
+
description: "US sector rotation — GICS 11-sector ETF scoreboard (XLK/XLF/XLE/XLV/XLU/XLI/XLB/XLP/XLY/XLRE/XLC), economic cycle positioning, sector vs SPY relative strength, valuation by sector. Use when: user asks about sector rotation, which industry to buy, economic cycle stage, or sector ETF comparison. NOT for: individual US stocks (use fin-us-equity), US ETF portfolio/DCA (use fin-us-etf), A-share sectors (use fin-a-share), macro rates only (use fin-macro), crypto sectors (use fin-crypto-altseason)."
|
|
4
|
+
metadata: { "openclaw": { "emoji": "🏭", "requires": { "extensions": ["findoo-datahub-plugin"] } } }
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# US Sector Rotation
|
|
8
|
+
|
|
9
|
+
Economic cycle positioning + GICS sector momentum = systematic allocation framework. This skill turns "which sector should I buy" from gut feeling into data-driven rotation decisions.
|
|
10
|
+
|
|
11
|
+
> **Scope boundary:** This skill covers US sector-level analysis and rotation strategy. For individual US stock analysis, use `/fin-us-equity`. For ETF portfolio construction and DCA, use `/fin-us-etf`. For macro rates and yield curve, use `/fin-macro`.
|
|
12
|
+
|
|
13
|
+
## When to Use
|
|
14
|
+
|
|
15
|
+
- "现在该买哪个行业" / "Which sector should I buy now?"
|
|
16
|
+
- "科技股 vs 能源股" / "Tech vs Energy comparison"
|
|
17
|
+
- "经济周期在什么阶段" / "What stage of the economic cycle are we in?"
|
|
18
|
+
- "行业轮动到哪里了" / "Where is sector rotation heading?"
|
|
19
|
+
- "防御性板块是不是该配了" / "Should I add defensive sectors?"
|
|
20
|
+
- "XLK 和 XLV 哪个好" / "XLK vs XLV comparison"
|
|
21
|
+
- "哪个行业估值最低" / "Which sector has the lowest valuation?"
|
|
22
|
+
|
|
23
|
+
## When NOT to Use
|
|
24
|
+
|
|
25
|
+
- 美股个股深度分析 (AAPL, NVDA) → use `/fin-us-equity`
|
|
26
|
+
- ETF 组合配置 / 定投模拟 / ETF 对比 → use `/fin-us-etf`
|
|
27
|
+
- 宏观利率 / 国债收益率 / GDP/CPI → use `/fin-macro`
|
|
28
|
+
- A 股行业 / 板块分析 → use `/fin-a-share`
|
|
29
|
+
- 加密货币赛道轮动 → use `/fin-crypto-altseason`
|
|
30
|
+
- 美股期权策略 → use `/fin-us-equity` (options section)
|
|
31
|
+
|
|
32
|
+
## Tools & Parameters
|
|
33
|
+
|
|
34
|
+
### fin_stock (Sector ETF price + fundamentals)
|
|
35
|
+
|
|
36
|
+
| Parameter | Type | Required | Format | Default | Example |
|
|
37
|
+
| --------- | ------ | -------- | --------- | ------- | ---------------- |
|
|
38
|
+
| symbol | string | Yes | US ticker | — | XLK |
|
|
39
|
+
| endpoint | string | Yes | see below | — | price/historical |
|
|
40
|
+
| provider | string | No | yfinance | auto | yfinance |
|
|
41
|
+
| limit | number | No | 1-5000 | 250 | 250 |
|
|
42
|
+
|
|
43
|
+
> **Important:** For US ETFs, always use `provider="yfinance"` with `price/historical`. Default tushare provider returns 500 for US symbols.
|
|
44
|
+
|
|
45
|
+
#### Endpoints
|
|
46
|
+
|
|
47
|
+
| endpoint | Description | Example |
|
|
48
|
+
| ------------------------------- | ----------------------- | --------------------------------------------------------------------------- |
|
|
49
|
+
| `price/historical` | Sector ETF OHLCV | `fin_stock(symbol="XLK", endpoint="price/historical", provider="yfinance")` |
|
|
50
|
+
| `fundamental/ratios` | Sector ETF basic ratios | `fin_stock(symbol="XLK", endpoint="fundamental/ratios")` |
|
|
51
|
+
| `fundamental/earnings_forecast` | Earnings consensus | `fin_stock(symbol="XLK", endpoint="fundamental/earnings_forecast")` |
|
|
52
|
+
| `profile` | ETF description | `fin_stock(symbol="XLK", endpoint="profile")` |
|
|
53
|
+
|
|
54
|
+
### Auxiliary Tools
|
|
55
|
+
|
|
56
|
+
| tool | endpoint | use case |
|
|
57
|
+
| ----------------- | -------------- | -------------------------------------------- |
|
|
58
|
+
| `fin_macro` | `treasury_us` | Yield curve for economic cycle determination |
|
|
59
|
+
| `fin_ta` | `rsi/sma/macd` | Sector ETF technical momentum |
|
|
60
|
+
| `fin_data_regime` | — | SPY regime for macro overlay |
|
|
61
|
+
| `fin_data_ohlcv` | — | Sector ETF K-line data |
|
|
62
|
+
| `fin_index` | `daily_basic` | Index valuation (for cross-reference) |
|
|
63
|
+
|
|
64
|
+
## Sector ETF Reference
|
|
65
|
+
|
|
66
|
+
### SPDR Select Sector ETFs (11 GICS Sectors)
|
|
67
|
+
|
|
68
|
+
| Ticker | Sector | Expense | Cycle Phase | Rate Sensitivity |
|
|
69
|
+
| ------ | ------------------ | ------- | -------------------- | ---------------- |
|
|
70
|
+
| XLK | Technology | 0.09% | Early/Late Expansion | High (negative) |
|
|
71
|
+
| XLF | Financials | 0.09% | Early Recovery | High (positive) |
|
|
72
|
+
| XLE | Energy | 0.09% | Late Cycle/Inflation | Low |
|
|
73
|
+
| XLV | Healthcare | 0.09% | Defensive/Late Cycle | Low |
|
|
74
|
+
| XLU | Utilities | 0.09% | Recession/Defensive | High (negative) |
|
|
75
|
+
| XLI | Industrials | 0.09% | Early Recovery | Moderate |
|
|
76
|
+
| XLB | Materials | 0.09% | Mid Cycle/Inflation | Moderate |
|
|
77
|
+
| XLP | Consumer Staples | 0.09% | Recession/Defensive | Low |
|
|
78
|
+
| XLY | Consumer Discret. | 0.09% | Early Recovery | Moderate |
|
|
79
|
+
| XLRE | Real Estate | 0.09% | Rate Sensitive | Very High (neg) |
|
|
80
|
+
| XLC | Communication Svcs | 0.09% | Growth-oriented | High (negative) |
|
|
81
|
+
|
|
82
|
+
### SPY as Benchmark
|
|
83
|
+
|
|
84
|
+
| Ticker | Description | Use |
|
|
85
|
+
| ------ | ----------- | ------------------------------------------- |
|
|
86
|
+
| SPY | S&P 500 | Benchmark for relative strength calculation |
|
|
87
|
+
|
|
88
|
+
## Sector Rotation Analysis Pattern
|
|
89
|
+
|
|
90
|
+
### 1. Sector Scoreboard
|
|
91
|
+
|
|
92
|
+
1. **Pull price history for all 11 sectors + SPY** — `fin_stock(symbol="XLK", endpoint="price/historical", provider="yfinance", limit=250)` for each sector ETF + SPY
|
|
93
|
+
- Calculate for each: 1W return, 1M return, 3M return, YTD return
|
|
94
|
+
- Calculate relative return vs SPY for each period (sector return - SPY return)
|
|
95
|
+
- Rank by 3M relative return (primary momentum signal)
|
|
96
|
+
- ⚠️ If top sector 3M relative return > +10% AND RSI > 70 → overbought, potential mean reversion
|
|
97
|
+
- ⚠️ If bottom sector 3M relative return < -10% AND RSI < 30 → oversold, potential contrarian opportunity
|
|
98
|
+
- 💡 Sector leading for > 6 months with decelerating momentum = exhaustion risk
|
|
99
|
+
|
|
100
|
+
2. **Momentum quality check** — `fin_ta(indicator="rsi", symbol="XLK", market="equity")` for top/bottom sectors
|
|
101
|
+
- RSI > 70 on sector ETF = overbought → trim bias
|
|
102
|
+
- RSI < 30 on sector ETF = oversold → accumulate bias
|
|
103
|
+
- 💡 Divergence between price (new high) and RSI (lower high) = weakening momentum
|
|
104
|
+
|
|
105
|
+
### 2. Economic Cycle Positioning
|
|
106
|
+
|
|
107
|
+
1. **Yield curve assessment** — `fin_macro(endpoint="treasury_us")` → 2Y and 10Y yields
|
|
108
|
+
- Calculate 2Y-10Y spread
|
|
109
|
+
- ⚠️ If spread < 0 (inverted) → late cycle / recession warning → rotate to defensives (XLU, XLP, XLV)
|
|
110
|
+
- ⚠️ If spread steepening from inversion → early recovery signal → rotate to cyclicals (XLF, XLY, XLI)
|
|
111
|
+
- 💡 Cross-validate with `fin_data_regime(symbol="SPY", market="equity")` for regime confirmation
|
|
112
|
+
|
|
113
|
+
2. **Cycle phase determination** — Combine yield curve + SPY regime + sector leadership
|
|
114
|
+
|
|
115
|
+
| Cycle Phase | Yield Curve Signal | Sector Leaders | Sector Laggards |
|
|
116
|
+
| ---------------- | -------------------------- | ------------------- | --------------- |
|
|
117
|
+
| Early Recovery | Steepening from inversion | XLF, XLY, XLI, XLB | XLU, XLP |
|
|
118
|
+
| Mid Expansion | Normal slope, rates rising | XLK, XLC, XLI | XLU, XLRE |
|
|
119
|
+
| Late Expansion | Flattening, rates elevated | XLE, XLB, XLK | XLY, XLRE |
|
|
120
|
+
| Recession/Crisis | Inverting or steep-falling | XLU, XLP, XLV, cash | XLY, XLF, XLI |
|
|
121
|
+
|
|
122
|
+
- ⚠️ Cycle phases are not precise — use as directional bias, not timing tool
|
|
123
|
+
- 💡 If SPY regime = "bear" or "crisis" but yield curve suggests early recovery → possible inflection, watch for confirmation
|
|
124
|
+
|
|
125
|
+
### 3. Sector Valuation Assessment
|
|
126
|
+
|
|
127
|
+
1. **Relative valuation** — `fin_stock(symbol="XLK", endpoint="fundamental/ratios")` for each sector
|
|
128
|
+
- Compare P/E across sectors
|
|
129
|
+
- ⚠️ If sector P/E > 1.5x its 5-year median → expensive relative to history
|
|
130
|
+
- ⚠️ If sector P/E < 0.7x its 5-year median → cheap relative to history
|
|
131
|
+
- 💡 Low valuation + improving momentum = strongest rotation signal
|
|
132
|
+
- 💡 High valuation + weakening momentum = strongest sell signal
|
|
133
|
+
|
|
134
|
+
### Historical Sector P/E Reference (approximate 5Y medians)
|
|
135
|
+
|
|
136
|
+
| Sector | Ticker | Approx 5Y Median P/E | Notes |
|
|
137
|
+
| ------ | ------ | -------------------- | --------------------------- |
|
|
138
|
+
| Tech | XLK | 28-32x | Driven by AAPL/MSFT/NVDA |
|
|
139
|
+
| Financ | XLF | 12-15x | Rate cycle dependent |
|
|
140
|
+
| Energy | XLE | 12-18x | Commodity price dependent |
|
|
141
|
+
| Health | XLV | 16-20x | Defensive premium |
|
|
142
|
+
| Util | XLU | 17-21x | Bond proxy, rate sensitive |
|
|
143
|
+
| Indust | XLI | 18-22x | GDP growth correlated |
|
|
144
|
+
| Mater | XLB | 15-19x | Commodity/inflation linked |
|
|
145
|
+
| Staple | XLP | 20-24x | Defensive premium |
|
|
146
|
+
| Discr | XLY | 22-28x | AMZN/TSLA weight distortion |
|
|
147
|
+
| RE | XLRE | 35-45x | REIT accounting (use P/FFO) |
|
|
148
|
+
| Comms | XLC | 18-24x | META/GOOG weight dominates |
|
|
149
|
+
|
|
150
|
+
### 4. Rotation Decision Framework
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
Combine signals into rotation recommendation:
|
|
154
|
+
|
|
155
|
+
1. Momentum signal (Scoreboard 3M relative return ranking)
|
|
156
|
+
2. Cycle signal (Economic cycle phase → favored sectors)
|
|
157
|
+
3. Valuation signal (Current P/E vs historical median)
|
|
158
|
+
|
|
159
|
+
Strong BUY: Momentum top 3 + Cycle favored + Valuation below median
|
|
160
|
+
Strong SELL: Momentum bottom 3 + Cycle unfavored + Valuation above median
|
|
161
|
+
Hold/Neutral: Mixed signals across the three dimensions
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
- ⚠️ Never recommend >20% portfolio in a single sector (concentration risk)
|
|
165
|
+
- ⚠️ Rotation is gradual tilt adjustment (5-10% weight shift), not binary all-in/all-out
|
|
166
|
+
- 💡 If all three signals align → highest conviction rotation call
|
|
167
|
+
|
|
168
|
+
## Signal Quick-Reference
|
|
169
|
+
|
|
170
|
+
### Sector Rotation Playbook by Macro Regime
|
|
171
|
+
|
|
172
|
+
| Macro Signal | Recommended Sectors | Avoid Sectors |
|
|
173
|
+
| ------------------------------ | ------------------- | ---------------- |
|
|
174
|
+
| Rate cuts beginning | XLK, XLRE, XLU, XLY | XLE, XLF (mixed) |
|
|
175
|
+
| Rate hikes beginning | XLF, XLE | XLRE, XLU, XLK |
|
|
176
|
+
| Inflation rising (CPI > 4%) | XLE, XLB, XLI | XLU, XLP, XLRE |
|
|
177
|
+
| Recession fears (VIX > 25) | XLU, XLP, XLV | XLY, XLI, XLF |
|
|
178
|
+
| AI/tech narrative dominant | XLK, XLC | XLE, XLB |
|
|
179
|
+
| Dollar weakening (DXY falling) | XLE, XLB, Emerging | XLK (mixed) |
|
|
180
|
+
|
|
181
|
+
### Sector Correlation Clusters
|
|
182
|
+
|
|
183
|
+
Understanding which sectors move together helps diversification:
|
|
184
|
+
|
|
185
|
+
- **Cyclical cluster**: XLF + XLI + XLY + XLB (GDP-sensitive)
|
|
186
|
+
- **Defensive cluster**: XLU + XLP + XLV (recession-resistant)
|
|
187
|
+
- **Growth cluster**: XLK + XLC (duration-sensitive, rate-impacted)
|
|
188
|
+
- **Real assets cluster**: XLE + XLB + XLRE (inflation-linked)
|
|
189
|
+
|
|
190
|
+
## Data Notes
|
|
191
|
+
|
|
192
|
+
- **yfinance ETF data**: ~15min delay, covers price and basic fundamentals. Always specify `provider="yfinance"` for US ETFs.
|
|
193
|
+
- **Sector ETF P/E**: `fundamental/ratios` may return limited data for ETFs. The historical P/E medians in the reference table are approximate and should be cited as "approximate historical reference."
|
|
194
|
+
- **Economic cycle determination**: Based on yield curve shape + SPY regime. This is a simplified framework — professional cycle dating (NBER) lags by months.
|
|
195
|
+
- **Missing from DataHub**: Sector-level aggregate earnings growth, ETF fund flows, precise P/E percentiles. Use the hardcoded reference table for historical context.
|
|
196
|
+
- **Rotation lag**: Sector rotation signals are medium-term (1-3 months). Do not use for day-trading or short-term tactical moves.
|
|
197
|
+
|
|
198
|
+
## Response Guidelines
|
|
199
|
+
|
|
200
|
+
### Number Formats
|
|
201
|
+
|
|
202
|
+
- Sector ETF price: $185.40 (2 decimal places)
|
|
203
|
+
- Returns: +8.5% / -2.3% (always with +/- sign, 1 decimal)
|
|
204
|
+
- Relative return vs SPY: +3.2% / -1.8% (clearly labeled "vs SPY")
|
|
205
|
+
- P/E ratio: 28.5x (1 decimal, with "x" suffix)
|
|
206
|
+
- Yield curve spread: +45bp / -12bp (basis points)
|
|
207
|
+
- Expense ratio: 0.09% (2 decimal places)
|
|
208
|
+
|
|
209
|
+
### Must Include
|
|
210
|
+
|
|
211
|
+
- Data timestamp ("Data as of YYYY-MM-DD")
|
|
212
|
+
- Scoreboard table with all 11 sectors ranked
|
|
213
|
+
- Current economic cycle phase assessment with reasoning
|
|
214
|
+
- At least one ⚠️ risk signal (overbought/overvalued sector, or cycle transition warning)
|
|
215
|
+
- Relative returns vs SPY (not just absolute returns)
|
|
216
|
+
|
|
217
|
+
### Display Format
|
|
218
|
+
|
|
219
|
+
- Sector overview → 11-sector scoreboard table (ticker, sector, 1W, 1M, 3M, YTD, vs SPY, RSI)
|
|
220
|
+
- Cycle positioning → phase label + yield curve data + favored/avoid sectors
|
|
221
|
+
- Sector comparison → side-by-side table (return, P/E, cycle alignment, momentum)
|
|
222
|
+
- Single sector analysis → structured: Performance, Valuation, Cycle Fit, Momentum, Verdict
|
|
223
|
+
- Always include actionable rotation recommendation with conviction level (high/medium/low)
|
package/src/config.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
|
3
3
|
export type PluginConfig = {
|
|
4
4
|
datahubApiUrl: string;
|
|
5
5
|
datahubUsername: string;
|
|
6
|
-
|
|
6
|
+
datahubApiKey: string | undefined;
|
|
7
7
|
requestTimeoutMs: number;
|
|
8
8
|
};
|
|
9
9
|
|
|
@@ -15,10 +15,9 @@ function readEnv(keys: string[]): string | undefined {
|
|
|
15
15
|
return undefined;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
//
|
|
18
|
+
// Built-in DataHub URL — API key must be configured by the user
|
|
19
19
|
const DEFAULT_DATAHUB_URL = "http://43.134.61.136:8088";
|
|
20
20
|
const DEFAULT_DATAHUB_USERNAME = "admin";
|
|
21
|
-
const DEFAULT_DATAHUB_PASSWORD = "98ffa5c5-1ec6-4735-8e0c-715a5eca1a8d";
|
|
22
21
|
|
|
23
22
|
export function resolveConfig(api: OpenClawPluginApi): PluginConfig {
|
|
24
23
|
const raw = api.pluginConfig as Record<string, unknown> | undefined;
|
|
@@ -37,7 +36,7 @@ export function resolveConfig(api: OpenClawPluginApi): PluginConfig {
|
|
|
37
36
|
(typeof raw?.datahubPassword === "string" ? raw.datahubPassword : undefined) ??
|
|
38
37
|
(typeof raw?.datahubApiKey === "string" ? raw.datahubApiKey : undefined) ??
|
|
39
38
|
readEnv(["DATAHUB_PASSWORD", "OPENFINCLAW_DATAHUB_PASSWORD", "DATAHUB_API_KEY"]) ??
|
|
40
|
-
|
|
39
|
+
undefined;
|
|
41
40
|
|
|
42
41
|
const timeoutRaw = raw?.requestTimeoutMs ?? readEnv(["OPENFINCLAW_DATAHUB_TIMEOUT_MS"]);
|
|
43
42
|
const timeout = Number(timeoutRaw);
|
|
@@ -45,7 +44,7 @@ export function resolveConfig(api: OpenClawPluginApi): PluginConfig {
|
|
|
45
44
|
return {
|
|
46
45
|
datahubApiUrl: datahubApiUrl.replace(/\/+$/, ""),
|
|
47
46
|
datahubUsername,
|
|
48
|
-
datahubPassword,
|
|
47
|
+
datahubApiKey: datahubPassword,
|
|
49
48
|
requestTimeoutMs: Number.isFinite(timeout) && timeout >= 1000 ? Math.floor(timeout) : 30_000,
|
|
50
49
|
};
|
|
51
50
|
}
|
|
@@ -226,19 +226,16 @@ describe("DataHubClient construction", () => {
|
|
|
226
226
|
|
|
227
227
|
const DATAHUB_URL = process.env.DATAHUB_API_URL ?? "http://43.134.61.136:8088";
|
|
228
228
|
const DATAHUB_USERNAME = process.env.DATAHUB_USERNAME ?? "admin";
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
"98ffa5c5-1ec6-4735-8e0c-715a5eca1a8d";
|
|
233
|
-
// Live tests run by default (public DataHub has baked-in credentials)
|
|
234
|
-
// Set DATAHUB_SKIP_LIVE=1 to skip
|
|
229
|
+
const DEV_KEY = "98ffa5c5-1ec6-4735-8e0c-715a5eca1a8d";
|
|
230
|
+
const DATAHUB_API_KEY = process.env.DATAHUB_PASSWORD ?? process.env.DATAHUB_API_KEY ?? DEV_KEY;
|
|
231
|
+
// Live tests use built-in dev key by default. Set DATAHUB_SKIP_LIVE=1 to skip.
|
|
235
232
|
const SKIP_LIVE = process.env.DATAHUB_SKIP_LIVE === "1";
|
|
236
233
|
|
|
237
234
|
describe.skipIf(SKIP_LIVE)("Live DataHub E2E", () => {
|
|
238
235
|
let client: DataHubClient;
|
|
239
236
|
|
|
240
237
|
beforeAll(() => {
|
|
241
|
-
client = new DataHubClient(DATAHUB_URL, DATAHUB_USERNAME,
|
|
238
|
+
client = new DataHubClient(DATAHUB_URL, DATAHUB_USERNAME, DATAHUB_API_KEY, 30_000);
|
|
242
239
|
});
|
|
243
240
|
|
|
244
241
|
// --- Coverage / Meta ---
|
package/src/datahub-client.ts
CHANGED
|
@@ -102,6 +102,11 @@ export class DataHubClient {
|
|
|
102
102
|
return this.query(`coverage/${endpoint}`);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
/** /api/v1/ta/* — Technical Analysis indicators (sma, ema, rsi, macd, bbands) */
|
|
106
|
+
ta(indicator: string, params?: Record<string, string>): Promise<unknown[]> {
|
|
107
|
+
return this.query(`ta/${indicator}`, params);
|
|
108
|
+
}
|
|
109
|
+
|
|
105
110
|
/* ============================================================
|
|
106
111
|
* Typed convenience methods (OHLCV + Ticker)
|
|
107
112
|
* ============================================================ */
|
|
@@ -203,5 +208,5 @@ function detectEquityProvider(symbol: string): string {
|
|
|
203
208
|
) {
|
|
204
209
|
return "tushare";
|
|
205
210
|
}
|
|
206
|
-
return "
|
|
211
|
+
return "massive";
|
|
207
212
|
}
|