daxiapi-cli 1.2.0 → 2.0.1
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 +75 -67
- package/bin/index.js +15 -203
- package/commands/config.js +67 -0
- package/commands/kline.js +34 -0
- package/commands/market.js +96 -0
- package/commands/search.js +35 -0
- package/commands/secid.js +34 -0
- package/commands/sector.js +121 -0
- package/commands/stock.js +80 -0
- package/commands/zdt.js +39 -0
- package/lib/api.js +43 -201
- package/lib/config.js +0 -15
- package/lib/error.js +80 -0
- package/lib/output.js +3 -324
- package/package.json +7 -5
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# daxiapi-cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
大虾皮金融数据API命令行工具。需要注册 daxiapi.com 网站,并且获取API Token之后才能使用。
|
|
4
4
|
|
|
5
5
|
## 安装
|
|
6
6
|
|
|
@@ -45,116 +45,124 @@ daxiapi config delete token
|
|
|
45
45
|
### 市场数据
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
|
-
#
|
|
48
|
+
# 市场概览(主流指数)
|
|
49
49
|
daxiapi market
|
|
50
50
|
|
|
51
51
|
# 市场温度
|
|
52
|
-
daxiapi market
|
|
52
|
+
daxiapi market temp
|
|
53
53
|
|
|
54
|
-
#
|
|
55
|
-
daxiapi market
|
|
54
|
+
# 市场风格
|
|
55
|
+
daxiapi market style
|
|
56
56
|
|
|
57
|
-
#
|
|
58
|
-
daxiapi market
|
|
59
|
-
|
|
60
|
-
# 收盘新闻
|
|
61
|
-
daxiapi market -n
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### 指数K线
|
|
65
|
-
|
|
66
|
-
```bash
|
|
67
|
-
# 获取上证指数K线
|
|
68
|
-
daxiapi index
|
|
57
|
+
# 市场估值
|
|
58
|
+
daxiapi market value
|
|
69
59
|
```
|
|
70
60
|
|
|
71
61
|
### 板块数据
|
|
72
62
|
|
|
73
63
|
```bash
|
|
74
|
-
#
|
|
64
|
+
# 板块列表
|
|
75
65
|
daxiapi sector
|
|
76
66
|
|
|
77
|
-
#
|
|
78
|
-
daxiapi sector
|
|
67
|
+
# 指定排序和数量
|
|
68
|
+
daxiapi sector --order zdf --limit 10
|
|
69
|
+
|
|
70
|
+
# 行业板块数据
|
|
71
|
+
daxiapi sector bk
|
|
79
72
|
|
|
80
|
-
#
|
|
81
|
-
daxiapi sector
|
|
73
|
+
# 板块内个股排名
|
|
74
|
+
daxiapi sector stocks --code BK0477
|
|
82
75
|
|
|
83
|
-
#
|
|
84
|
-
daxiapi sector
|
|
76
|
+
# 热门股票
|
|
77
|
+
daxiapi sector top
|
|
78
|
+
|
|
79
|
+
# 热门概念
|
|
80
|
+
daxiapi sector gn
|
|
85
81
|
```
|
|
86
82
|
|
|
87
|
-
###
|
|
83
|
+
### 股票数据
|
|
88
84
|
|
|
89
85
|
```bash
|
|
86
|
+
# 搜索股票或板块
|
|
87
|
+
daxiapi search 平安
|
|
88
|
+
daxiapi search 锂电 --type bk
|
|
89
|
+
|
|
90
90
|
# 查询单个股票
|
|
91
91
|
daxiapi stock 000001
|
|
92
92
|
|
|
93
93
|
# 查询多个股票
|
|
94
94
|
daxiapi stock 000001 600031 300750
|
|
95
95
|
|
|
96
|
-
#
|
|
97
|
-
daxiapi stock
|
|
96
|
+
# 概念股查询
|
|
97
|
+
daxiapi stock gn GN1234
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### K线数据
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# 获取K线数据
|
|
104
|
+
daxiapi kline 000001
|
|
98
105
|
```
|
|
99
106
|
|
|
100
|
-
###
|
|
107
|
+
### 涨跌停
|
|
101
108
|
|
|
102
109
|
```bash
|
|
103
|
-
#
|
|
104
|
-
daxiapi
|
|
110
|
+
# 涨停池
|
|
111
|
+
daxiapi zdt
|
|
105
112
|
|
|
106
|
-
#
|
|
107
|
-
daxiapi
|
|
113
|
+
# 跌停池
|
|
114
|
+
daxiapi zdt --type dt
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### 工具
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# 代码转换
|
|
121
|
+
daxiapi secid 000001
|
|
108
122
|
```
|
|
109
123
|
|
|
110
124
|
> 💡 提示:`daxiapi` 命令也可以使用简写 `dxp`
|
|
111
125
|
|
|
112
|
-
##
|
|
126
|
+
## 全局选项
|
|
113
127
|
|
|
114
|
-
|
|
128
|
+
```bash
|
|
129
|
+
# 查看帮助
|
|
130
|
+
daxiapi --help
|
|
131
|
+
daxiapi market --help
|
|
115
132
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
主要指数:
|
|
120
|
-
┌─────────┬────────┬───────────┬───────┬─────────┬─────────┐
|
|
121
|
-
│ (index) │ 名称 │ 涨跌幅 │ CS │ 5日 │ 20日 │
|
|
122
|
-
├─────────┼────────┼───────────┼───────┼─────────┼─────────┤
|
|
123
|
-
│ 0 │ '上证' │ '0.50%' │ 5.23 │ '2.10%' │ '3.50%' │
|
|
124
|
-
│ 1 │ '深证' │ '0.80%' │ 6.45 │ '2.50%' │ '4.20%' │
|
|
125
|
-
│ 2 │ '创业' │ '1.20%' │ 8.12 │ '3.00%' │ '5.10%' │
|
|
126
|
-
└─────────┴────────┴───────────┴───────┴─────────┴─────────┘
|
|
133
|
+
# 查看版本
|
|
134
|
+
daxiapi --version
|
|
127
135
|
```
|
|
128
136
|
|
|
129
|
-
|
|
137
|
+
## 错误处理
|
|
138
|
+
|
|
139
|
+
CLI 工具提供详细的错误提示和解决建议:
|
|
140
|
+
|
|
141
|
+
### 认证错误 (401)
|
|
130
142
|
|
|
131
143
|
```
|
|
132
|
-
|
|
144
|
+
❌ 错误: API Token 无效或已过期
|
|
145
|
+
|
|
146
|
+
解决方法:
|
|
147
|
+
1. 检查 Token 是否正确配置:
|
|
148
|
+
daxiapi config set token YOUR_TOKEN
|
|
133
149
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
价格: 18.50 涨跌幅: 2.50%
|
|
150
|
+
2. 或设置环境变量:
|
|
151
|
+
export DAXIAPI_TOKEN=YOUR_TOKEN
|
|
137
152
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
153
|
+
3. Token 可在 daxiapi.com 用户中心获取
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### 限流错误 (429)
|
|
141
157
|
|
|
142
|
-
形态标签: Good, LPS
|
|
143
|
-
技术形态: VCP, SOS
|
|
144
158
|
```
|
|
159
|
+
❌ 错误: 请求频率超限
|
|
145
160
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
| SM | 中期动量,短期与中期均线乖离率。>0多头排列 |
|
|
152
|
-
| ML | 长期动量,中期与长期均线乖离率 |
|
|
153
|
-
| RPS | 欧奈尔相对强度,>80为强势股 |
|
|
154
|
-
| SCTR | 技术排名百分比,如60代表强于市场60%股票 |
|
|
155
|
-
| VCP | 马克米勒维尼波动收缩模式 |
|
|
156
|
-
| SOS | Wyckoff强势走势行为 |
|
|
157
|
-
| LPS | Wyckoff最后支撑点 |
|
|
161
|
+
解决方法:
|
|
162
|
+
1. 请稍后重试
|
|
163
|
+
2. 检查您的请求频率是否过高
|
|
164
|
+
3. 升级账户获取更高配额
|
|
165
|
+
```
|
|
158
166
|
|
|
159
167
|
## 限流规则
|
|
160
168
|
|
package/bin/index.js
CHANGED
|
@@ -1,209 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const {program} = require('commander');
|
|
4
|
-
const
|
|
5
|
-
const config = require('../lib/config');
|
|
6
|
-
const api = require('../lib/api');
|
|
7
|
-
const output = require('../lib/output');
|
|
8
|
-
|
|
9
|
-
// 显示欢迎信息
|
|
10
|
-
function showWelcome() {
|
|
11
|
-
console.log(chalk.cyan.bold('\n📊 大虾皮 CLI - A股量化数据工具\n'));
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// 检查Token配置
|
|
15
|
-
function checkToken() {
|
|
16
|
-
const token = config.getToken();
|
|
17
|
-
if (!token) {
|
|
18
|
-
console.log(chalk.yellow('⚠️ 未配置 API Token'));
|
|
19
|
-
console.log(chalk.gray(' 请先运行: daxiapi config set token YOUR_TOKEN'));
|
|
20
|
-
console.log(chalk.gray(' 或设置环境变量: DAXIAPI_TOKEN=YOUR_TOKEN\n'));
|
|
21
|
-
process.exit(1);
|
|
22
|
-
}
|
|
23
|
-
return token;
|
|
24
|
-
}
|
|
4
|
+
const package = require('../package.json');
|
|
25
5
|
|
|
26
6
|
program
|
|
27
7
|
.name('daxiapi')
|
|
28
|
-
.
|
|
29
|
-
.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
program
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
console.log(chalk.red('用法: daxiapi config set <key> <value>'));
|
|
43
|
-
console.log(chalk.gray('示例: daxiapi config set token abc123...'));
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
config.set(key, value);
|
|
47
|
-
console.log(chalk.green(`✓ 已设置 ${key}`));
|
|
48
|
-
break;
|
|
49
|
-
case 'get':
|
|
50
|
-
if (!key) {
|
|
51
|
-
const all = config.getAll();
|
|
52
|
-
console.log(JSON.stringify(all, null, 2));
|
|
53
|
-
} else {
|
|
54
|
-
console.log(config.get(key) || '');
|
|
55
|
-
}
|
|
56
|
-
break;
|
|
57
|
-
case 'delete':
|
|
58
|
-
config.delete(key);
|
|
59
|
-
console.log(chalk.green(`✓ 已删除 ${key}`));
|
|
60
|
-
break;
|
|
61
|
-
default:
|
|
62
|
-
console.log(chalk.red('未知操作:', action));
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
// ==================== 市场数据命令 ====================
|
|
67
|
-
program
|
|
68
|
-
.command('market')
|
|
69
|
-
.description('市场数据')
|
|
70
|
-
.option('-d, --degree', '获取市场温度')
|
|
71
|
-
.option('-s, --style', '获取大小盘风格')
|
|
72
|
-
.option('-v, --value', '获取指数估值')
|
|
73
|
-
.option('-n, --news', '获取收盘新闻')
|
|
74
|
-
.action(async options => {
|
|
75
|
-
showWelcome();
|
|
76
|
-
const token = checkToken();
|
|
77
|
-
|
|
78
|
-
try {
|
|
79
|
-
if (options.degree) {
|
|
80
|
-
const data = await api.getMarketDegree(token);
|
|
81
|
-
output.text(data);
|
|
82
|
-
} else if (options.style) {
|
|
83
|
-
const data = await api.getMarketStyle(token);
|
|
84
|
-
output.table(data);
|
|
85
|
-
} else if (options.value) {
|
|
86
|
-
const data = await api.getMarketValueData(token);
|
|
87
|
-
output.valueTable(data);
|
|
88
|
-
} else if (options.news) {
|
|
89
|
-
const data = await api.getMarketNews(token);
|
|
90
|
-
output.newsList(data);
|
|
91
|
-
} else {
|
|
92
|
-
// 默认获取市场概览
|
|
93
|
-
const data = await api.getMarketData(token);
|
|
94
|
-
output.marketOverview(data);
|
|
95
|
-
}
|
|
96
|
-
} catch (err) {
|
|
97
|
-
output.error(err);
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
// ==================== 指数K线命令 ====================
|
|
102
|
-
program
|
|
103
|
-
.command('index')
|
|
104
|
-
.description('获取上证指数K线数据')
|
|
105
|
-
.action(async () => {
|
|
106
|
-
showWelcome();
|
|
107
|
-
const token = checkToken();
|
|
108
|
-
|
|
109
|
-
try {
|
|
110
|
-
const data = await api.getIndexK(token);
|
|
111
|
-
output.klines(data);
|
|
112
|
-
} catch (err) {
|
|
113
|
-
output.error(err);
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
// ==================== 板块数据命令 ====================
|
|
118
|
-
program
|
|
119
|
-
.command('sector')
|
|
120
|
-
.description('板块数据')
|
|
121
|
-
.option('-c, --code <code>', '板块代码,获取板块内个股')
|
|
122
|
-
.option('-o, --order <field>', '排序字段', 'cs')
|
|
123
|
-
.option('-l, --limit <days>', '天数', '5')
|
|
124
|
-
.option('-g, --gn <gnId>', '概念代码,获取概念内个股')
|
|
125
|
-
.action(async options => {
|
|
126
|
-
showWelcome();
|
|
127
|
-
const token = checkToken();
|
|
128
|
-
|
|
129
|
-
try {
|
|
130
|
-
if (options.code) {
|
|
131
|
-
const data = await api.getSectorRankStock(token, options.code, options.order);
|
|
132
|
-
output.stockList(data);
|
|
133
|
-
} else if (options.gn) {
|
|
134
|
-
const data = await api.getGainianStock(token, options.gn);
|
|
135
|
-
output.stockList(data);
|
|
136
|
-
} else {
|
|
137
|
-
const data = await api.getSectorData(token, options.order, parseInt(options.limit));
|
|
138
|
-
output.sectorHeatmap(data);
|
|
139
|
-
}
|
|
140
|
-
} catch (err) {
|
|
141
|
-
output.error(err);
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
// ==================== 个股查询命令 ====================
|
|
146
|
-
program
|
|
147
|
-
.command('stock <codes...>')
|
|
148
|
-
.description('获取个股数据,支持多个股票代码')
|
|
149
|
-
.option('-j, --json', '输出JSON格式')
|
|
150
|
-
.action(async (codes, options) => {
|
|
151
|
-
showWelcome();
|
|
152
|
-
const token = checkToken();
|
|
153
|
-
|
|
154
|
-
try {
|
|
155
|
-
const data = await api.getStockData(token, codes.join(','));
|
|
156
|
-
if (options.json) {
|
|
157
|
-
console.log(JSON.stringify(data, null, 2));
|
|
158
|
-
} else {
|
|
159
|
-
output.stockDetail(data);
|
|
160
|
-
}
|
|
161
|
-
} catch (err) {
|
|
162
|
-
output.error(err);
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
// ==================== 搜索命令 ====================
|
|
167
|
-
program
|
|
168
|
-
.command('search <keyword>')
|
|
169
|
-
.description('搜索股票或行业')
|
|
170
|
-
.option('-t, --type <type>', '类型: stock/hy', 'stock')
|
|
171
|
-
.action(async (keyword, options) => {
|
|
172
|
-
showWelcome();
|
|
173
|
-
const token = checkToken();
|
|
174
|
-
|
|
175
|
-
try {
|
|
176
|
-
const data = await api.queryStock(token, keyword, options.type);
|
|
177
|
-
output.searchResult(data);
|
|
178
|
-
} catch (err) {
|
|
179
|
-
output.error(err);
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
// ==================== K线数据命令 ====================
|
|
184
|
-
program
|
|
185
|
-
.command('kline <code>')
|
|
186
|
-
.description('获取个股K线数据')
|
|
187
|
-
.option('-l, --limit <days>', '数据条数', '300')
|
|
188
|
-
.option('-t, --type <type>', 'K线类型: day/week/month', 'day')
|
|
189
|
-
.option('-j, --json', '输出JSON格式')
|
|
190
|
-
.option('-s, --simple', '简单输出格式')
|
|
191
|
-
.action(async (code, options) => {
|
|
192
|
-
showWelcome();
|
|
193
|
-
// K线数据不需要token,使用免费数据源
|
|
194
|
-
|
|
195
|
-
try {
|
|
196
|
-
const data = await api.getKline(code, parseInt(options.limit), options.type);
|
|
197
|
-
if (options.json) {
|
|
198
|
-
console.log(JSON.stringify(data, null, 2));
|
|
199
|
-
} else if (options.simple) {
|
|
200
|
-
output.klineSimple(data, 10);
|
|
201
|
-
} else {
|
|
202
|
-
output.klineData(data, 20);
|
|
203
|
-
}
|
|
204
|
-
} catch (err) {
|
|
205
|
-
output.error(err);
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
program.parse();
|
|
8
|
+
.alias('dxp')
|
|
9
|
+
.version(package.version)
|
|
10
|
+
.description('大虾皮金融数据API命令行工具');
|
|
11
|
+
|
|
12
|
+
require('../commands/config')(program);
|
|
13
|
+
require('../commands/market')(program);
|
|
14
|
+
require('../commands/sector')(program);
|
|
15
|
+
require('../commands/stock')(program);
|
|
16
|
+
require('../commands/kline')(program);
|
|
17
|
+
require('../commands/zdt')(program);
|
|
18
|
+
require('../commands/secid')(program);
|
|
19
|
+
require('../commands/search')(program);
|
|
20
|
+
|
|
21
|
+
program.parse(process.argv);
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const config = require('../lib/config');
|
|
2
|
+
const { handleError, createParameterError } = require('../lib/error');
|
|
3
|
+
|
|
4
|
+
module.exports = function(program) {
|
|
5
|
+
const configCmd = program.command('config');
|
|
6
|
+
|
|
7
|
+
configCmd
|
|
8
|
+
.command('set <key> <value>')
|
|
9
|
+
.description('设置配置项')
|
|
10
|
+
.action((key, value) => {
|
|
11
|
+
try {
|
|
12
|
+
if (!key || !value) {
|
|
13
|
+
throw createParameterError(
|
|
14
|
+
'参数无效',
|
|
15
|
+
[
|
|
16
|
+
"参数 'key' 不能为空",
|
|
17
|
+
"参数 'value' 不能为空"
|
|
18
|
+
],
|
|
19
|
+
[
|
|
20
|
+
'daxiapi config set token YOUR_TOKEN',
|
|
21
|
+
'daxiapi config set baseUrl https://daxiapi.com'
|
|
22
|
+
]
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
config.set(key, value);
|
|
27
|
+
console.log(`✓ ${key} 已设置`);
|
|
28
|
+
} catch (error) {
|
|
29
|
+
handleError(error);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
configCmd
|
|
35
|
+
.command('get')
|
|
36
|
+
.description('查看所有配置')
|
|
37
|
+
.action(() => {
|
|
38
|
+
try {
|
|
39
|
+
const allConfig = config.getAll();
|
|
40
|
+
console.log(JSON.stringify(allConfig, null, 2));
|
|
41
|
+
} catch (error) {
|
|
42
|
+
handleError(error);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
configCmd
|
|
48
|
+
.command('delete <key>')
|
|
49
|
+
.description('删除配置项')
|
|
50
|
+
.action((key) => {
|
|
51
|
+
try {
|
|
52
|
+
if (!key) {
|
|
53
|
+
throw createParameterError(
|
|
54
|
+
'参数无效',
|
|
55
|
+
["参数 'key' 不能为空"],
|
|
56
|
+
['daxiapi config delete token']
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
config.delete(key);
|
|
61
|
+
console.log(`✓ ${key} 已删除`);
|
|
62
|
+
} catch (error) {
|
|
63
|
+
handleError(error);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const config = require('../lib/config');
|
|
2
|
+
const api = require('../lib/api');
|
|
3
|
+
const {handleError, createParameterError} = require('../lib/error');
|
|
4
|
+
const {output} = require('../lib/output');
|
|
5
|
+
|
|
6
|
+
module.exports = function(program) {
|
|
7
|
+
program
|
|
8
|
+
.command('kline <code>')
|
|
9
|
+
.description('获取A股股票、指数、板块的K线数据,支持股票代码、指数代码、板块代码。默认返回上证指数(000001)的K线,可指定K线条数(1-500,默认60)。返回开盘价、收盘价、最高价、最低价、成交量等K线数据,可用于技术分析和趋势判断。')
|
|
10
|
+
.action(async (code) => {
|
|
11
|
+
try {
|
|
12
|
+
const token = config.getToken();
|
|
13
|
+
if (!token) {
|
|
14
|
+
const error = new Error('未配置 API Token');
|
|
15
|
+
error.response = {status: 401};
|
|
16
|
+
throw error;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (!code) {
|
|
20
|
+
throw createParameterError(
|
|
21
|
+
'参数无效',
|
|
22
|
+
['参数 \'code\' 不能为空'],
|
|
23
|
+
['daxiapi kline 000001']
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const data = await api.getKline(token, code);
|
|
28
|
+
output(data);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
handleError(error);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const config = require('../lib/config');
|
|
2
|
+
const api = require('../lib/api');
|
|
3
|
+
const {handleError} = require('../lib/error');
|
|
4
|
+
const {output} = require('../lib/output');
|
|
5
|
+
|
|
6
|
+
module.exports = function (program) {
|
|
7
|
+
const marketCmd = program.command('market');
|
|
8
|
+
|
|
9
|
+
marketCmd
|
|
10
|
+
.command('index')
|
|
11
|
+
.description(
|
|
12
|
+
'获取A股市场主流指数数据,包括上证指数、深证成指、沪深300、上证50、中证500、创业板指、科创50等指数的强度值和多日涨跌幅。可用于市场风格判断、趋势分析、强弱排名、板块轮动分析和投资决策辅助。'
|
|
13
|
+
)
|
|
14
|
+
.action(async () => {
|
|
15
|
+
try {
|
|
16
|
+
const token = config.getToken();
|
|
17
|
+
if (!token) {
|
|
18
|
+
const error = new Error('未配置 API Token');
|
|
19
|
+
error.response = {status: 401};
|
|
20
|
+
throw error;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const data = await api.getMarketData(token);
|
|
24
|
+
output(data);
|
|
25
|
+
} catch (error) {
|
|
26
|
+
handleError(error);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
marketCmd
|
|
32
|
+
.command('temp')
|
|
33
|
+
.description(
|
|
34
|
+
'获取A股市场温度数据,包括估值温度、恐贪指数、趋势温度、动量温度等核心指标。可用于判断市场整体情绪、风险水平、趋势强度和动量状态,为投资决策提供参考。'
|
|
35
|
+
)
|
|
36
|
+
.action(async () => {
|
|
37
|
+
try {
|
|
38
|
+
const token = config.getToken();
|
|
39
|
+
if (!token) {
|
|
40
|
+
const error = new Error('未配置 API Token');
|
|
41
|
+
error.response = {status: 401};
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const data = await api.getMarketTemp(token);
|
|
46
|
+
output(data);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
handleError(error);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
marketCmd
|
|
54
|
+
.command('style')
|
|
55
|
+
.description(
|
|
56
|
+
'获取A股市场风格数据,计算中证500(小盘)与沪深300(大盘)的涨跌幅差值。当差值为正时表示小盘强于大盘,为负时表示大盘强于小盘,可用于判断市场风格偏向和风格轮动趋势。'
|
|
57
|
+
)
|
|
58
|
+
.action(async () => {
|
|
59
|
+
try {
|
|
60
|
+
const token = config.getToken();
|
|
61
|
+
if (!token) {
|
|
62
|
+
const error = new Error('未配置 API Token');
|
|
63
|
+
error.response = {status: 401};
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const data = await api.getMarketStyle(token);
|
|
68
|
+
output(data);
|
|
69
|
+
} catch (error) {
|
|
70
|
+
handleError(error);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
marketCmd
|
|
76
|
+
.command('value')
|
|
77
|
+
.description(
|
|
78
|
+
'获取A股主要指数估值数据,包括市盈率(PE)、市净率(PB)、估值温度、PE百分位、PB百分位等核心估值指标。支持对红利类指数的特殊估值计算,可用于判断指数当前估值水平和投资价值。'
|
|
79
|
+
)
|
|
80
|
+
.action(async () => {
|
|
81
|
+
try {
|
|
82
|
+
const token = config.getToken();
|
|
83
|
+
if (!token) {
|
|
84
|
+
const error = new Error('未配置 API Token');
|
|
85
|
+
error.response = {status: 401};
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const data = await api.getMarketValueData(token);
|
|
90
|
+
output(data);
|
|
91
|
+
} catch (error) {
|
|
92
|
+
handleError(error);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const config = require('../lib/config');
|
|
2
|
+
const api = require('../lib/api');
|
|
3
|
+
const {handleError, createParameterError} = require('../lib/error');
|
|
4
|
+
const {output} = require('../lib/output');
|
|
5
|
+
|
|
6
|
+
module.exports = function (program) {
|
|
7
|
+
program
|
|
8
|
+
.command('search <keyword>')
|
|
9
|
+
.description('搜索A股股票或板块,支持关键词模糊查询(股票名称、拼音缩写等)。支持两种搜索类型:stock(股票)和bk(板块),默认搜索股票。从东方财富API获取数据,返回代码、名称、类型、拼音等信息,最多返回10条结果。可用于快速查找股票代码和板块信息。')
|
|
10
|
+
.option('-t, --type <type>', '搜索类型:stock(股票)或 bk(板块)', 'stock')
|
|
11
|
+
.action(async (keyword, options) => {
|
|
12
|
+
try {
|
|
13
|
+
const token = config.getToken();
|
|
14
|
+
if (!token) {
|
|
15
|
+
const error = new Error('未配置 API Token');
|
|
16
|
+
error.response = {status: 401};
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!keyword) {
|
|
21
|
+
throw createParameterError(
|
|
22
|
+
'参数无效',
|
|
23
|
+
["参数 'keyword' 不能为空"],
|
|
24
|
+
['daxiapi search 平安', 'daxiapi search 锂电 --type bk']
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const data = await api.queryStockData(token, keyword, options.type);
|
|
29
|
+
output(data);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
handleError(error);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const config = require('../lib/config');
|
|
2
|
+
const api = require('../lib/api');
|
|
3
|
+
const {handleError, createParameterError} = require('../lib/error');
|
|
4
|
+
const {output} = require('../lib/output');
|
|
5
|
+
|
|
6
|
+
module.exports = function(program) {
|
|
7
|
+
program
|
|
8
|
+
.command('secid <code>')
|
|
9
|
+
.description('将各种股票代码格式转换为标准secid格式,支持以下格式:6位数字股票代码(000001)、sh/sz前缀(sh000001)、BK开头板块代码(BK0428)、纯数字板块代码(428)。返回标准secid格式,如1.600000(沪市)、0.000001(深市)、90.BK0428(板块)。可用于统一代码格式和K线数据查询。')
|
|
10
|
+
.action(async (code) => {
|
|
11
|
+
try {
|
|
12
|
+
const token = config.getToken();
|
|
13
|
+
if (!token) {
|
|
14
|
+
const error = new Error('未配置 API Token');
|
|
15
|
+
error.response = {status: 401};
|
|
16
|
+
throw error;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (!code) {
|
|
20
|
+
throw createParameterError(
|
|
21
|
+
'参数无效',
|
|
22
|
+
["参数 'code' 不能为空"],
|
|
23
|
+
['daxiapi secid 000001']
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const data = await api.getSecId(token, code);
|
|
28
|
+
output(data);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
handleError(error);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
};
|