-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgetGoldData.js
134 lines (118 loc) · 3.45 KB
/
getGoldData.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
const fs = require("fs").promises;
const path = require("path");
const { v4: uuidv4 } = require("uuid");
const fetch = require("node-fetch");
// 配置常量
const KLINE_TYPE_LABELS = {
1: "分钟",
5: "小时",
8: "日",
9: "周",
10: "月",
};
const QUERY_KLINE_NUM_BY_KLINE_TYPE = {
1: 1000,
5: 1000,
8: 1000,
9: 500,
10: 100,
};
const REQUEST_INTERVAL_MS = 11000;
const directoryPath = path.join(__dirname, "outputs");
async function request(klineType) {
const API_URL = "https://quote.alltick.io/quote-b-api/kline";
const query = {
trace: uuidv4(),
data: {
kline_type: klineType,
code: "GOLD",
kline_timestamp_end: 0,
query_kline_num: QUERY_KLINE_NUM_BY_KLINE_TYPE[klineType],
adjust_type: 0,
},
};
try {
const response = await fetch(
`${API_URL}?${new URLSearchParams({
token: process.env.API_TOKEN,
query: JSON.stringify(query),
})}`
);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const filename = `${KLINE_TYPE_LABELS[klineType]}K数据.json`;
const filePath = path.join(directoryPath, filename);
await fs.writeFile(filePath, await response.text());
console.log(`✅ ${filename} 已保存`);
return true;
} catch (err) {
throw new Error(
`${KLINE_TYPE_LABELS[klineType]}K数据请求失败: ${err.message}`
);
}
}
async function fetchKlinesSequentially() {
const klineTypes = Object.keys(KLINE_TYPE_LABELS).sort((a, b) => b - a);
for (const [index, klineType] of klineTypes.entries()) {
try {
console.log(`开始请求${KLINE_TYPE_LABELS[klineType]}K数据`);
await request(klineType);
if (index !== klineTypes.length - 1) {
console.log(`${REQUEST_INTERVAL_MS / 1000}秒后请求下一个`);
await new Promise((resolve) =>
setTimeout(resolve, REQUEST_INTERVAL_MS)
);
}
} catch (error) {
throw error; // 错误处理交给上层
}
}
console.log("全部请求结束");
}
// 清空输出目录
async function clearOutputDirectory() {
try {
// 首先读取目录的内容
const entries = await fs.readdir(directoryPath, { withFileTypes: true });
// 对于每一个条目,构建完整路径并删除
const deletePromises = entries.map(async (entry) => {
const fullPath = `${directoryPath}/${entry.name}`;
if (entry.isDirectory()) {
// 如果是子目录,递归删除
return fs.rm(fullPath, { recursive: true, force: true });
} else {
// 如果是文件,则直接删除
return fs.unlink(fullPath);
}
});
// 等待所有删除操作完成
await Promise.all(deletePromises);
console.log(`已清空输出目录下的内容: ${directoryPath}`);
} catch (err) {
throw new Error(`目录内容清理失败: ${err.message}`);
}
}
// 检查目录存在性
async function checkDirectoryExists() {
try {
await fs.access(directoryPath);
return true;
} catch {
return false;
}
}
exports.getGoldData = async function main() {
try {
if (!(await checkDirectoryExists())) {
await fs.mkdir(directoryPath, { recursive: true });
console.log("已创建目录:", directoryPath);
}
await clearOutputDirectory();
await fetchKlinesSequentially();
console.log("✅ 所有数据获取完成");
} catch (error) {
console.error("❌ 程序异常终止:", error.message);
throw error;
}
};