heyunfei commited on
Commit
85653bc
·
verified ·
1 Parent(s): f6ed7e1

Upload 56 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .dockerignore +83 -0
  2. .gitattributes +4 -0
  3. .gitignore +7 -0
  4. BINANCE_INTEGRATION.md +119 -0
  5. DOCKER_README.md +222 -0
  6. Dockerfile +71 -0
  7. Kronos项目详细分析文档.md +850 -0
  8. LICENSE +21 -0
  9. README.md +333 -11
  10. docker-compose.yml +38 -0
  11. examples/data/XSHG_5min_600977.csv +0 -0
  12. examples/eth_usdt_realtime_prediction.py +524 -0
  13. examples/prediction_batch_example.py +72 -0
  14. examples/prediction_example.py +81 -0
  15. examples/prediction_wo_vol_example.py +69 -0
  16. figures/backtest_result_example.png +3 -0
  17. figures/logo.png +3 -0
  18. figures/overview.png +3 -0
  19. figures/prediction_example.png +3 -0
  20. finetune/__pycache__/config.cpython-313.pyc +0 -0
  21. finetune/config.py +131 -0
  22. finetune/dataset.py +145 -0
  23. finetune/qlib_data_preprocess.py +130 -0
  24. finetune/qlib_test.py +358 -0
  25. finetune/train_predictor.py +244 -0
  26. finetune/train_tokenizer.py +281 -0
  27. finetune/utils/__init__.py +0 -0
  28. finetune/utils/training_utils.py +118 -0
  29. model/__init__.py +17 -0
  30. model/__pycache__/__init__.cpython-313.pyc +0 -0
  31. model/__pycache__/kronos.cpython-313.pyc +0 -0
  32. model/__pycache__/module.cpython-313.pyc +0 -0
  33. model/kronos.py +626 -0
  34. model/module.py +577 -0
  35. requirements.txt +12 -0
  36. webui/README.md +135 -0
  37. webui/__pycache__/app.cpython-313.pyc +0 -0
  38. webui/__pycache__/technical_indicators.cpython-313.pyc +0 -0
  39. webui/app.py +863 -0
  40. webui/docker_start.sh +46 -0
  41. webui/prediction_results/prediction_20250828_184347.json +2243 -0
  42. webui/prediction_results/prediction_20250829_105733.json +1135 -0
  43. webui/prediction_results/prediction_20250829_121801.json +1135 -0
  44. webui/prediction_results/prediction_20250829_144119.json +2243 -0
  45. webui/prediction_results/prediction_20250829_144330.json +1135 -0
  46. webui/prediction_results/prediction_20250829_144445.json +1135 -0
  47. webui/prediction_results/prediction_20250829_144621.json +1135 -0
  48. webui/prediction_results/prediction_20250829_145631.json +1135 -0
  49. webui/prediction_results/prediction_20250829_150514.json +1135 -0
  50. webui/prediction_results/prediction_20250829_172152.json +1135 -0
.dockerignore ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Git
2
+ .git
3
+ .gitignore
4
+ .gitattributes
5
+
6
+ # Documentation
7
+ *.md
8
+ README.md
9
+ LICENSE
10
+
11
+ # Python
12
+ __pycache__/
13
+ *.py[cod]
14
+ *$py.class
15
+ *.so
16
+ .Python
17
+ build/
18
+ develop-eggs/
19
+ dist/
20
+ downloads/
21
+ eggs/
22
+ .eggs/
23
+ lib/
24
+ lib64/
25
+ parts/
26
+ sdist/
27
+ var/
28
+ wheels/
29
+ *.egg-info/
30
+ .installed.cfg
31
+ *.egg
32
+
33
+ # Virtual environments
34
+ venv/
35
+ env/
36
+ ENV/
37
+ env.bak/
38
+ venv.bak/
39
+
40
+ # IDE
41
+ .vscode/
42
+ .idea/
43
+ *.swp
44
+ *.swo
45
+ *~
46
+
47
+ # OS
48
+ .DS_Store
49
+ .DS_Store?
50
+ ._*
51
+ .Spotlight-V100
52
+ .Trashes
53
+ ehthumbs.db
54
+ Thumbs.db
55
+
56
+ # Logs
57
+ *.log
58
+ logs/
59
+
60
+ # Docker
61
+ Dockerfile*
62
+ docker-compose*
63
+ .dockerignore
64
+
65
+ # Temporary files
66
+ *.tmp
67
+ *.temp
68
+ temp/
69
+ tmp/
70
+
71
+ # Test files
72
+ test_*
73
+ *_test.py
74
+ tests/
75
+
76
+ # Examples (optional - remove if you want to include examples)
77
+ examples/
78
+
79
+ # Figures (optional - remove if you want to include figures)
80
+ figures/
81
+
82
+ # Finetune (optional - remove if you want to include finetune)
83
+ finetune/
.gitattributes CHANGED
@@ -33,3 +33,7 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ figures/backtest_result_example.png filter=lfs diff=lfs merge=lfs -text
37
+ figures/logo.png filter=lfs diff=lfs merge=lfs -text
38
+ figures/overview.png filter=lfs diff=lfs merge=lfs -text
39
+ figures/prediction_example.png filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ /.venv/
2
+ /.idea/Kronos.iml
3
+ /.idea/inspectionProfiles/profiles_settings.xml
4
+ /.idea/AugmentWebviewStateStore.xml
5
+ /examples/eth_usdt_prediction*
6
+ /.idea/misc.xml
7
+ /.idea/vcs.xml
BINANCE_INTEGRATION.md ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 币安实时数据集成完成报告
2
+
3
+ ## 🎯 项目目标
4
+ 将 Kronos WebUI 中的文件选择功能替换为币安实时数据获取,支持选择不同的交易品种和时间周期。
5
+
6
+ ## ✅ 完成的修改
7
+
8
+ ### 1. 后端修改 (webui/app.py)
9
+
10
+ #### 新增依赖
11
+ - 添加了 `python-binance` 库用于币安API集成
12
+ - 添加了 `requests` 库用于HTTP请求
13
+
14
+ #### 新增功能函数
15
+ - `get_available_symbols()`: 获取可用的交易对列表(前100个热门USDT交易对)
16
+ - `get_binance_klines()`: 从币安获取K线数据,支持网络失败时的模拟数据
17
+ - `generate_mock_klines()`: 生成模拟K线数据作为备用方案
18
+ - `get_timeframe_options()`: 获取可用的时间周期选项
19
+
20
+ #### 修改的API路由
21
+ - `/api/symbols`: 替换原来的 `/api/data-files`,返回交易对列表
22
+ - `/api/timeframes`: 新增API,返回时间周期选项
23
+ - `/api/load-data`: 修改为接收币安数据参数(symbol, interval, limit)
24
+ - `/api/predict`: 修改预测参数,使用币安数据参数替代文件路径
25
+
26
+ ### 2. 前端修改 (webui/templates/index.html)
27
+
28
+ #### 界面更新
29
+ - 将"选择数据文件"替换为"选择交易对"
30
+ - 添加"选择时间周期"下拉框
31
+ - 添加"数据数量"选择器
32
+ - 按钮文本改为"📈 获取币安数据"
33
+
34
+ #### JavaScript功能更新
35
+ - 全局变量:`currentDataFile` → `currentSymbol`, `currentInterval`, `currentLimit`
36
+ - 新增函数:`loadSymbols()`, `loadTimeframes()`
37
+ - 修改函数:`loadData()`, `startPrediction()`
38
+ - 更新API调用参数
39
+
40
+ ### 3. 支持的交易对
41
+ 包含100个热门USDT交易对,如:
42
+ - BTC/USDT, ETH/USDT, BNB/USDT
43
+ - ADA/USDT, SOL/USDT 等主流币种
44
+
45
+ ### 4. 支持的时间周期
46
+ - 1分钟, 5分钟, 15分钟, 30分钟
47
+ - 1小时, 4小时, 1天, 1周
48
+
49
+ ### 5. 容错机制
50
+ - 网络连接失败时自动切换到模拟数据
51
+ - 模拟数据基于真实价格范围生成随机游走数据
52
+ - 保持与原有预测功能的完全兼容性
53
+
54
+ ## 🧪 测试结果
55
+
56
+ ### API测试 (test_api.py)
57
+ ✅ 交易对列表API - 成功获取100个交易对
58
+ ✅ 时间周期列表API - 成功获取8个时间周期选项
59
+ ✅ 加载币安数据API - 成功获取BTCUSDT数据
60
+
61
+ ### 功能验证
62
+ - 应用程序正常启动在 http://127.0.0.1:7070
63
+ - 所有新API接口响应正常
64
+ - 数据格式与原有系统完全兼容
65
+
66
+ ## 🚀 使用方法
67
+
68
+ 1. 启动应用:
69
+ ```bash
70
+ cd webui
71
+ python app.py
72
+ ```
73
+
74
+ 2. 访问 http://127.0.0.1:7070
75
+
76
+ 3. 操作流程:
77
+ - 选择模型并加载
78
+ - 选择交易对(如 BTC/USDT)
79
+ - 选择时间周期(如 1小时)
80
+ - 选择数据数量(如 1000条)
81
+ - 点击"📈 获取币安数据"
82
+ - 设置预测参数
83
+ - 开始预测
84
+
85
+ ## 📋 技术特点
86
+
87
+ - **实时数据**: 直接从币安获取最新的K线数据
88
+ - **多品种支持**: 支持100+主流加密货币交易对
89
+ - **多时间周期**: 从1分钟到1周的8种时间周期
90
+ - **容错设计**: 网络问题时自动使用模拟数据
91
+ - **向后兼容**: 保持与原有预测模型的完全兼容
92
+ - **用户友好**: 中文界面,操作简单直观
93
+
94
+ ## 🔧 依赖要求
95
+
96
+ 新增依赖包:
97
+ - python-binance>=1.0.19
98
+ - requests>=2.25.0
99
+
100
+ 已在 `webui/requirements.txt` 中更新。
101
+
102
+ ## 📝 注意事项
103
+
104
+ 1. 首次使用需要安装新的依赖包
105
+ 2. 币安API使用公开接口,无需API密钥
106
+ 3. 网络连接问题时会自动使用模拟数据
107
+ 4. 模拟数据基于真实价格范围,适合测试和演示
108
+
109
+ ## 🎉 总结
110
+
111
+ 成功将文件选择功能替换为币安实时数据获取,实现了:
112
+ - ✅ 实时数据获取
113
+ - ✅ 多品种支持
114
+ - ✅ 多时间周期
115
+ - ✅ 容错机制
116
+ - ✅ 用户体验优化
117
+ - ✅ 完全向后兼容
118
+
119
+ 现在用户可以直接选择任意加密货币交易对进行实时数据分析和预测,无需手动准备数据文件。
DOCKER_README.md ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Kronos Web UI - Docker Deployment Guide
2
+
3
+ ## 概述
4
+
5
+ 这个文档提供了使用 Docker 部署 Kronos Web UI 的完整指南。
6
+
7
+ ## 快速开始
8
+
9
+ ### 使用 Docker Compose(推荐)
10
+
11
+ 1. **构建并启动服务**
12
+ ```bash
13
+ docker-compose up --build
14
+ ```
15
+
16
+ 2. **后台运行**
17
+ ```bash
18
+ docker-compose up -d --build
19
+ ```
20
+
21
+ 3. **停止服务**
22
+ ```bash
23
+ docker-compose down
24
+ ```
25
+
26
+ 4. **查看日志**
27
+ ```bash
28
+ docker-compose logs -f kronos-webui
29
+ ```
30
+
31
+ ### 使用 Docker 命令
32
+
33
+ 1. **构建镜像**
34
+ ```bash
35
+ docker build -t kronos-webui .
36
+ ```
37
+
38
+ 2. **运行容器**
39
+ ```bash
40
+ docker run -d \
41
+ --name kronos-webui \
42
+ -p 7070:7070 \
43
+ -v $(pwd)/webui/prediction_results:/app/webui/prediction_results \
44
+ kronos-webui
45
+ ```
46
+
47
+ 3. **查看日志**
48
+ ```bash
49
+ docker logs -f kronos-webui
50
+ ```
51
+
52
+ 4. **停止容器**
53
+ ```bash
54
+ docker stop kronos-webui
55
+ docker rm kronos-webui
56
+ ```
57
+
58
+ ## 访问应用
59
+
60
+ 启动成功后,通过以下地址访问:
61
+ - **Web UI**: http://localhost:7070
62
+ - **健康检查**: http://localhost:7070/
63
+
64
+ ## 配置说明
65
+
66
+ ### 环境变量
67
+
68
+ | 变量名 | 默认值 | 说明 |
69
+ |--------|--------|------|
70
+ | `PYTHONPATH` | `/app` | Python 路径 |
71
+ | `FLASK_APP` | `webui/app.py` | Flask 应用入口 |
72
+ | `FLASK_ENV` | `production` | Flask 环境 |
73
+ | `TZ` | `Asia/Shanghai` | 时区设置 |
74
+
75
+ ### 数据持久化
76
+
77
+ 以下目录会被持久化存储:
78
+ - `./webui/prediction_results` - 预测结果文件
79
+ - `./model/data` - 模型数据(如果存在)
80
+
81
+ ### 端口配置
82
+
83
+ - **容器内端口**: 7070
84
+ - **宿主机端口**: 7070(可在 docker-compose.yml 中修改)
85
+
86
+ ## 生产环境部署
87
+
88
+ ### 使用 Gunicorn
89
+
90
+ 容器会自动检测并使用 Gunicorn 作为生产环境的 WSGI 服务器:
91
+ - 工作进程数:2
92
+ - 超时时间:120秒
93
+ - 绑定地址:0.0.0.0:7070
94
+
95
+ ### 健康检查
96
+
97
+ 容器包含健康检查功能:
98
+ - 检查间隔:30秒
99
+ - 超时时间:10秒
100
+ - 重试次数:3次
101
+ - 启动等待时间:40秒
102
+
103
+ ### 安全配置
104
+
105
+ - 使用非 root 用户运行(UID: 1000)
106
+ - 最小化镜像大小(多阶段构建)
107
+ - 只安装必要的运行时依赖
108
+
109
+ ## 故障排除
110
+
111
+ ### 常见问题
112
+
113
+ 1. **端口冲突**
114
+ ```bash
115
+ # 修改 docker-compose.yml 中的端口映射
116
+ ports:
117
+ - "8080:7070" # 使用 8080 端口
118
+ ```
119
+
120
+ 2. **权限问题**
121
+ ```bash
122
+ # 确保预测结果目录有正确权限
123
+ chmod 755 webui/prediction_results
124
+ ```
125
+
126
+ 3. **模型加载失败**
127
+ - 检查网络连接(需要下载 Hugging Face 模型)
128
+ - 确保有足够的磁盘空间
129
+ - 查看容器日志了解详细错误信息
130
+
131
+ ### 日志查看
132
+
133
+ ```bash
134
+ # 查看实时日志
135
+ docker-compose logs -f
136
+
137
+ # 查看特定服务日志
138
+ docker-compose logs kronos-webui
139
+
140
+ # 查看容器日志
141
+ docker logs kronos-webui
142
+ ```
143
+
144
+ ### 进入容器调试
145
+
146
+ ```bash
147
+ # 进入运行中的容器
148
+ docker exec -it kronos-webui /bin/bash
149
+
150
+ # 或使用 docker-compose
151
+ docker-compose exec kronos-webui /bin/bash
152
+ ```
153
+
154
+ ## 性能优化
155
+
156
+ ### 资源限制
157
+
158
+ 在 docker-compose.yml 中添加资源限制:
159
+
160
+ ```yaml
161
+ services:
162
+ kronos-webui:
163
+ # ... 其他配置
164
+ deploy:
165
+ resources:
166
+ limits:
167
+ memory: 2G
168
+ cpus: '1.0'
169
+ reservations:
170
+ memory: 1G
171
+ cpus: '0.5'
172
+ ```
173
+
174
+ ### 缓存优化
175
+
176
+ - 使用 `.dockerignore` 排除不必要的文件
177
+ - 多阶段构建减少最终镜像大小
178
+ - 合理使用 Docker 层缓存
179
+
180
+ ## 更新和维护
181
+
182
+ ### 更新应用
183
+
184
+ ```bash
185
+ # 重新构建并启动
186
+ docker-compose up --build -d
187
+
188
+ # 清理旧镜像
189
+ docker image prune -f
190
+ ```
191
+
192
+ ### 备份数据
193
+
194
+ ```bash
195
+ # 备份预测结果
196
+ tar -czf prediction_results_backup.tar.gz webui/prediction_results/
197
+
198
+ # 备份模型数据(如果存在)
199
+ tar -czf model_data_backup.tar.gz model/data/
200
+ ```
201
+
202
+ ## 监控
203
+
204
+ ### 容器状态
205
+
206
+ ```bash
207
+ # 查看容器状态
208
+ docker-compose ps
209
+
210
+ # 查看资源使用情况
211
+ docker stats kronos-webui
212
+ ```
213
+
214
+ ### 健康检查
215
+
216
+ ```bash
217
+ # 手动健康检查
218
+ curl -f http://localhost:7070/
219
+
220
+ # 查看健康检查状态
221
+ docker inspect kronos-webui | grep -A 10 Health
222
+ ```
Dockerfile ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Multi-stage build for optimization
2
+ FROM python:3.9-slim as builder
3
+
4
+ # Install system dependencies for building
5
+ RUN apt-get update && apt-get install -y \
6
+ build-essential \
7
+ gcc \
8
+ g++ \
9
+ && rm -rf /var/lib/apt/lists/*
10
+
11
+ # Create virtual environment
12
+ RUN python -m venv /opt/venv
13
+ ENV PATH="/opt/venv/bin:$PATH"
14
+
15
+ # Copy and install requirements
16
+ COPY requirements.txt /tmp/requirements.txt
17
+ COPY webui/requirements.txt /tmp/webui_requirements.txt
18
+
19
+ # Install main project dependencies
20
+ RUN pip install --no-cache-dir --upgrade pip && \
21
+ pip install --no-cache-dir -r /tmp/requirements.txt
22
+
23
+ # Install webui dependencies
24
+ RUN pip install --no-cache-dir -r /tmp/webui_requirements.txt
25
+
26
+ # Install production WSGI server
27
+ RUN pip install --no-cache-dir gunicorn
28
+
29
+ # Production stage
30
+ FROM python:3.9-slim
31
+
32
+ # Install runtime dependencies
33
+ RUN apt-get update && apt-get install -y \
34
+ curl \
35
+ && rm -rf /var/lib/apt/lists/*
36
+
37
+ # Create non-root user
38
+ RUN useradd -m -u 1000 user && \
39
+ mkdir -p /app && \
40
+ chown -R user:user /app
41
+
42
+ # Copy virtual environment from builder stage
43
+ COPY --from=builder /opt/venv /opt/venv
44
+ ENV PATH="/opt/venv/bin:$PATH"
45
+
46
+ # Set working directory
47
+ WORKDIR /app
48
+
49
+ # Copy application code
50
+ COPY --chown=user:user . /app
51
+
52
+ # Make startup script executable
53
+ RUN chmod +x /app/webui/docker_start.sh
54
+
55
+ # Switch to non-root user
56
+ USER user
57
+
58
+ # Expose the correct port (Flask app runs on 7070)
59
+ EXPOSE 7860
60
+
61
+ # Add health check
62
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
63
+ CMD curl -f http://localhost:7860/ || exit 1
64
+
65
+ # Set environment variables
66
+ ENV PYTHONPATH=/app
67
+ ENV FLASK_APP=webui/app.py
68
+ ENV FLASK_ENV=production
69
+
70
+ # Use the startup script
71
+ CMD ["/app/webui/docker_start.sh"]
Kronos项目详细分析文档.md ADDED
@@ -0,0 +1,850 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Kronos项目详细分析文档
2
+
3
+ ## 项目概述
4
+
5
+ **Kronos** 是一个专门为金融市场"语言"(K线序列)设计的解码器专用基础模型家族。与通用时间序列预测模型不同,Kronos专门处理金融数据的独特高噪声特征,采用创新的两阶段框架:
6
+
7
+ 1. **专用分词器**:将连续的多维K线数据(OHLCV)量化为分层离散token
8
+ 2. **大型自回归Transformer**:在这些token上进行预训练,作为多种量化任务的统一模型
9
+
10
+ ## 项目结构
11
+
12
+ ```
13
+ E:/Kronos/
14
+ ├── LICENSE # MIT许可证
15
+ ├── README.md # 项目说明文档
16
+ ├── requirements.txt # Python依赖包列表
17
+ ├── examples/ # 示例代码目录
18
+ │ ├── data/ # 示例数据
19
+ │ │ └── XSHG_5min_600977.csv
20
+ │ ├── prediction_example.py # 完整预测示例(包含成交量)
21
+ │ └── prediction_wo_vol_example.py # 无成交量预测示例
22
+ ├── figures/ # 图片资源
23
+ │ ├── logo.png
24
+ │ ├── overview.png
25
+ │ ├── prediction_example.png
26
+ │ └── backtest_result_example.png
27
+ ├── model/ # 核心模型代码
28
+ │ ├── __init__.py # 模型导入接口
29
+ │ ├── kronos.py # 主要模型类定义
30
+ │ └── module.py # 核心模块组件
31
+ └── finetune/ # 微调训练代码
32
+ ├── config.py # 配置文件
33
+ ├── dataset.py # 数据集处理
34
+ ├── train_tokenizer.py # 分词器训练
35
+ ├── train_predictor.py # 预测器训练
36
+ ├── qlib_data_preprocess.py # Qlib数据预处理
37
+ ├── qlib_test.py # Qlib测试
38
+ └── utils/ # 训练工具函数
39
+ ```
40
+
41
+ ## 核心架构
42
+
43
+ ### 1. 两阶段框架
44
+
45
+ #### 阶段一:KronosTokenizer(分词器)
46
+ - **功能**:将连续的OHLCV数据转换为离散token
47
+ - **核心技术**:Binary Spherical Quantization (BSQ)
48
+ - **架构**:编码器-解码器结构 + BSQuantizer
49
+
50
+ #### 阶段二:Kronos(预测模型)
51
+ - **功能**:基于token序列进行自回归预测
52
+ - **架构**:Transformer解码器 + 分层嵌入 + 依赖感知层
53
+
54
+ ### 2. 关键技术组件
55
+
56
+ #### Binary Spherical Quantization (BSQ)
57
+ ```python
58
+ class BSQuantizer(nn.Module):
59
+ def __init__(self, s1_bits, s2_bits, beta, gamma0, gamma, zeta, group_size):
60
+ # s1_bits: 第一级量化位数
61
+ # s2_bits: 第二级量化位数
62
+ # beta: 提交损失权重
63
+ # gamma0, gamma, zeta: 熵惩罚权重
64
+ ```
65
+
66
+ **特点**:
67
+ - 分层量化:将数据分为两个层次(s1和s2)
68
+ - 球面约束:在单位球面上进行量化
69
+ - 熵正则化:防止码本坍塌
70
+
71
+ #### 分层嵌入 (HierarchicalEmbedding)
72
+ ```python
73
+ class HierarchicalEmbedding(nn.Module):
74
+ def __init__(self, s1_bits, s2_bits, d_model=256):
75
+ self.emb_s1 = nn.Embedding(2**s1_bits, d_model) # 第一级嵌入
76
+ self.emb_s2 = nn.Embedding(2**s2_bits, d_model) # 第二级嵌入
77
+ self.fusion_proj = nn.Linear(d_model * 2, d_model) # 融合投影
78
+ ```
79
+
80
+ #### 依赖感知层 (DependencyAwareLayer)
81
+ ```python
82
+ class DependencyAwareLayer(nn.Module):
83
+ def __init__(self, d_model, n_heads=4):
84
+ self.cross_attn = MultiHeadCrossAttentionWithRoPE(d_model, n_heads)
85
+ self.norm = RMSNorm(d_model)
86
+ ```
87
+
88
+ **功能**:处理s1和s2 token之间的依赖关系
89
+
90
+ #### 旋转位置编码 (RoPE)
91
+ - 所有注意力机制都使用RoPE进行位置编码
92
+ - 支持更好的长序列建模能力
93
+
94
+ ### 3. 模型规格
95
+
96
+ #### 可用模型
97
+ - **Kronos-small**: 小型模型,适合快速推理
98
+ - **Kronos-base**: 基础模型,平衡性能和效率
99
+ - **最大上下文长度**: 512个时间步
100
+
101
+ #### 分词器规格
102
+ - **Kronos-Tokenizer-base**: 基础分词器
103
+ - 支持OHLCV数据的分层量化
104
+
105
+ ## 数据处理流程
106
+
107
+ ### 1. 输入数据格式
108
+ ```python
109
+ # 必需列
110
+ price_cols = ['open', 'high', 'low', 'close']
111
+ # 可选列
112
+ vol_col = 'volume'
113
+ amt_col = 'amount'
114
+ # 时间戳
115
+ timestamp_col = 'timestamps'
116
+ ```
117
+
118
+ ### 2. 数据预处理
119
+ ```python
120
+ # 标准化
121
+ x_mean, x_std = np.mean(x, axis=0), np.std(x, axis=0)
122
+ x = (x - x_mean) / (x_std + 1e-5)
123
+ # 裁剪异常值
124
+ x = np.clip(x, -clip_value, clip_value)
125
+ ```
126
+
127
+ ### 3. 时间特征工程
128
+ ```python
129
+ def calc_time_stamps(timestamps):
130
+ # 提取时间特征:分钟、小时、星期、日、月
131
+ return pd.DataFrame({
132
+ 'minute': timestamps.dt.minute,
133
+ 'hour': timestamps.dt.hour,
134
+ 'weekday': timestamps.dt.weekday,
135
+ 'day': timestamps.dt.day,
136
+ 'month': timestamps.dt.month
137
+ })
138
+ ```
139
+
140
+ ## 训练流程
141
+
142
+ ### 1. 分词器训练 (train_tokenizer.py)
143
+ ```python
144
+ # 损失函数
145
+ recon_loss_pre = F.mse_loss(z_pre, batch_x) # 重构损失(s1)
146
+ recon_loss_all = F.mse_loss(z, batch_x) # 重构损失(全部)
147
+ recon_loss = recon_loss_pre + recon_loss_all
148
+ loss = (recon_loss + bsq_loss) / 2
149
+ ```
150
+
151
+ **训练目标**:
152
+ - 最小化重构误差
153
+ - 优化量化码本
154
+ - 平衡压缩率和重构质量
155
+
156
+ ### 2. 预测器训练 (train_predictor.py)
157
+ ```python
158
+ # 分层预测损失
159
+ s1_loss = F.cross_entropy(s1_logits.view(-1, s1_vocab_size), s1_targets.view(-1))
160
+ s2_loss = F.cross_entropy(s2_logits.view(-1, s2_vocab_size), s2_targets.view(-1))
161
+ loss = s1_loss + s2_loss
162
+ ```
163
+
164
+ **训练目标**:
165
+ - 学习token序列的自回归模式
166
+ - 优化分层预测准确性
167
+
168
+ ### 3. 配置参数 (config.py)
169
+ ```python
170
+ # 数据参数
171
+ lookback_window = 90 # 历史窗口长度
172
+ predict_window = 10 # 预测窗口长度
173
+ max_context = 512 # 最大上下文长度
174
+
175
+ # 训练参数
176
+ epochs = 30
177
+ batch_size = 50
178
+ tokenizer_learning_rate = 2e-4
179
+ predictor_learning_rate = 4e-5
180
+ clip = 5.0 # 数据裁剪阈值
181
+ ```
182
+
183
+ ## 推理流程
184
+
185
+ ### 1. 模型加载
186
+ ```python
187
+ from model import Kronos, KronosTokenizer, KronosPredictor
188
+
189
+ # 从Hugging Face Hub加载
190
+ tokenizer = KronosTokenizer.from_pretrained("NeoQuasar/Kronos-Tokenizer-base")
191
+ model = Kronos.from_pretrained("NeoQuasar/Kronos-small")
192
+
193
+ # 创建预测器
194
+ predictor = KronosPredictor(model, tokenizer, device="cpu", max_context=512)
195
+ ```
196
+
197
+ ### 2. 数据准备
198
+ ```python
199
+ # 历史数据
200
+ x_df = df.loc[:lookback-1, ['open', 'high', 'low', 'close', 'volume', 'amount']]
201
+ x_timestamp = df.loc[:lookback-1, 'timestamps']
202
+ # 预测时间戳
203
+ y_timestamp = df.loc[lookback:lookback+pred_len-1, 'timestamps']
204
+ ```
205
+
206
+ ### 3. 生成预测
207
+ ```python
208
+ pred_df = predictor.predict(
209
+ df=x_df,
210
+ x_timestamp=x_timestamp,
211
+ y_timestamp=y_timestamp,
212
+ pred_len=pred_len,
213
+ T=1.0, # 采样温度
214
+ top_p=0.9, # 核采样概率
215
+ sample_count=1 # 采样路径数量
216
+ )
217
+ ```
218
+
219
+ ### 4. 采样策略
220
+ - **温度采样 (T)**: 控制预测的随机性
221
+ - **核采样 (top_p)**: 只从累积概率前p%的token中采样
222
+ - **多路径采样**: 生成多个预测路径并平均
223
+
224
+ ## 技术特色
225
+
226
+ ### 1. 分层量化
227
+ - **优势**: 更好地捕获金融数据的多尺度特征
228
+ - **实现**: BSQ将连续数据映射到分层离散空间
229
+
230
+ ### 2. 依赖感知建模
231
+ - **问题**: 传统方法忽略token间的内在依赖
232
+ - **解决**: DependencyAwareLayer显式建模s1和s2的关系
233
+
234
+ ### 3. 时间感知
235
+ - **时间嵌入**: 显式编码时间信息(分钟、小时、日期等)
236
+ - **位置编码**: RoPE提供更好的序列位置感知
237
+
238
+ ### 4. 鲁棒性设计
239
+ - **数据裁剪**: 处理金融数据的极端异常值
240
+ - **实例标准化**: 每个样本独立标准化
241
+ - **梯度累积**: 支持大批次训练
242
+
243
+ ## 应用场景
244
+
245
+ ### 1. 价格预测
246
+ - 股票价格预测
247
+ - 外汇汇率预测
248
+ - 商品期货预测
249
+
250
+ ### 2. 风险管理
251
+ - 波动率预测
252
+ - VaR计算
253
+ - 压力测试
254
+
255
+ ### 3. 量化交易
256
+ - 信号生成
257
+ - 组合优化
258
+ - 回测分析
259
+
260
+ ## 性能特点
261
+
262
+ ### 1. 优势
263
+ - **专门优化**: 针对金融数据特点设计
264
+ - **统一框架**: 一个模型处理多种任务
265
+ - **可扩展性**: 支持不同规模的模型
266
+
267
+ ### 2. 限制
268
+ - **上下文长度**: 最大512个时间步
269
+ - **计算资源**: 需要足够的GPU/CPU资源
270
+ - **数据质量**: 对输入数据质量敏感
271
+
272
+ ## 依赖环境
273
+
274
+ ### Python包依赖
275
+ ```
276
+ numpy
277
+ pandas
278
+ torch
279
+ einops==0.8.1
280
+ huggingface_hub==0.33.1
281
+ matplotlib==3.9.3
282
+ tqdm==4.67.1
283
+ safetensors # 模型加载必需
284
+ ```
285
+
286
+ ### 硬件要求
287
+ - **CPU**: 支持CPU推理(较慢)
288
+ - **GPU**: 推荐CUDA兼容GPU(更快)
289
+ - **内存**: 至少8GB RAM
290
+ - **存储**: 模型文件约100MB
291
+
292
+ ## 许可证
293
+ MIT License - 允许商业和非商业使用
294
+
295
+ ## 详细代码分析
296
+
297
+ ### 1. KronosTokenizer类详解
298
+
299
+ #### 核心参数
300
+ ```python
301
+ def __init__(self, d_in, d_model, n_heads, ff_dim, n_enc_layers, n_dec_layers,
302
+ ffn_dropout_p, attn_dropout_p, resid_dropout_p, s1_bits, s2_bits,
303
+ beta, gamma0, gamma, zeta, group_size):
304
+ ```
305
+
306
+ **参数说明**:
307
+ - `d_in`: 输入维度(通常为6,对应OHLCVA)
308
+ - `d_model`: 模型隐藏维度
309
+ - `n_heads`: 注意力头数
310
+ - `ff_dim`: 前馈网络维度
311
+ - `n_enc_layers/n_dec_layers`: 编码器/解码器层数
312
+ - `s1_bits/s2_bits`: 分层量化位数
313
+ - `beta, gamma0, gamma, zeta`: BSQ损失权重
314
+
315
+ #### 前向传播流程
316
+ ```python
317
+ def forward(self, x):
318
+ # 1. 输入嵌入
319
+ z = self.embed(x) # [B, T, d_in] -> [B, T, d_model]
320
+
321
+ # 2. 编码器处理
322
+ for layer in self.encoder:
323
+ z = layer(z)
324
+
325
+ # 3. 量化准备
326
+ z = self.quant_embed(z) # [B, T, d_model] -> [B, T, codebook_dim]
327
+
328
+ # 4. BSQ量化
329
+ bsq_loss, quantized, z_indices = self.tokenizer(z)
330
+
331
+ # 5. 分层解码
332
+ quantized_pre = quantized[:, :, :self.s1_bits] # s1部分
333
+ z_pre = self.post_quant_embed_pre(quantized_pre)
334
+ z = self.post_quant_embed(quantized) # 完整量化
335
+
336
+ # 6. 解码器重构
337
+ for layer in self.decoder:
338
+ z_pre = layer(z_pre)
339
+ z = layer(z)
340
+
341
+ z_pre = self.head(z_pre) # s1重构
342
+ z = self.head(z) # 完整重构
343
+
344
+ return (z_pre, z), bsq_loss, quantized, z_indices
345
+ ```
346
+
347
+ ### 2. Kronos预测模型详解
348
+
349
+ #### 模型初始化
350
+ ```python
351
+ def __init__(self, d_model, n_heads, ff_dim, n_layers, s1_bits, s2_bits,
352
+ ffn_dropout_p, attn_dropout_p, resid_dropout_p, token_dropout_p, learn_te):
353
+ ```
354
+
355
+ #### 关键组件
356
+ 1. **分层嵌入层**: 处理s1和s2 token的嵌入
357
+ 2. **时间嵌入层**: 编码时间特征
358
+ 3. **Transformer层**: 多层自注意力机制
359
+ 4. **依赖感知层**: 处理token间依赖
360
+ 5. **双头输出**: 分别预测s1和s2
361
+
362
+ #### 生成过程
363
+ ```python
364
+ def generate(self, x, x_stamp, y_stamp, pred_len, T=1.0, top_k=0, top_p=0.9,
365
+ sample_count=1, verbose=True):
366
+ # 1. 编码历史数据
367
+ s1_ids, s2_ids = self.tokenizer.encode(x, half=True)
368
+
369
+ # 2. 自回归生成
370
+ for i in range(pred_len):
371
+ # 获取当前上下文
372
+ context_s1 = s1_ids[:, -self.max_context:]
373
+ context_s2 = s2_ids[:, -self.max_context:]
374
+
375
+ # 预测下一个token
376
+ s1_logits, s2_logits = self.forward(context_s1, context_s2, ...)
377
+
378
+ # 采样策略
379
+ next_s1 = self.sample_token(s1_logits[:, -1], T, top_k, top_p)
380
+ next_s2 = self.sample_token(s2_logits[:, -1], T, top_k, top_p)
381
+
382
+ # 更新序列
383
+ s1_ids = torch.cat([s1_ids, next_s1.unsqueeze(1)], dim=1)
384
+ s2_ids = torch.cat([s2_ids, next_s2.unsqueeze(1)], dim=1)
385
+
386
+ # 3. 解码为原始数据
387
+ pred_tokens = torch.cat([s1_ids[:, -pred_len:], s2_ids[:, -pred_len:]], dim=-1)
388
+ predictions = self.tokenizer.decode(pred_tokens)
389
+
390
+ return predictions
391
+ ```
392
+
393
+ ### 3. BSQ量化算法详解
394
+
395
+ #### 核心思想
396
+ Binary Spherical Quantization将连续向量量化到单位球面上的二进制点:
397
+
398
+ ```python
399
+ def quantize(self, z):
400
+ # 1. 球面归一化
401
+ z = F.normalize(z, dim=-1)
402
+
403
+ # 2. 二进制量化
404
+ zhat = torch.where(z > 0,
405
+ torch.tensor(1, dtype=z.dtype, device=z.device),
406
+ torch.tensor(-1, dtype=z.dtype, device=z.device))
407
+
408
+ # 3. 直通估计器
409
+ return z + (zhat - z).detach()
410
+ ```
411
+
412
+ #### 损失函数组成
413
+ ```python
414
+ def forward(self, z):
415
+ # 1. 量化
416
+ zq = self.quantize(z)
417
+
418
+ # 2. 提交损失(commitment loss)
419
+ commit_loss = self.beta * torch.mean(((zq.detach() - z) ** 2).sum(dim=-1))
420
+
421
+ # 3. 熵正则化
422
+ entropy_penalty = self.compute_entropy_penalty(z)
423
+
424
+ # 4. 总损失
425
+ total_loss = commit_loss + self.zeta * entropy_penalty / self.inv_temperature
426
+
427
+ return zq, total_loss, metrics
428
+ ```
429
+
430
+ ### 4. 数据集处理详解
431
+
432
+ #### QlibDataset类
433
+ ```python
434
+ class QlibDataset(Dataset):
435
+ def __init__(self, data_type='train'):
436
+ # 加载预处理数据
437
+ with open(self.data_path, 'rb') as f:
438
+ self.data = pickle.load(f)
439
+
440
+ # 预计算所有可能的起始索引
441
+ self.valid_start_indices = []
442
+ for symbol_data in self.data:
443
+ seq_len = len(symbol_data['feature'])
444
+ max_start = seq_len - self.config.lookback_window - self.config.predict_window
445
+ if max_start > 0:
446
+ self.valid_start_indices.extend([
447
+ (symbol_idx, start_idx)
448
+ for start_idx in range(max_start)
449
+ ])
450
+ ```
451
+
452
+ #### 数据采样策略
453
+ ```python
454
+ def __getitem__(self, index):
455
+ # 随机选择起始位置
456
+ symbol_idx, start_idx = self.py_rng.choice(self.valid_start_indices)
457
+
458
+ # 提取特征和时间戳
459
+ symbol_data = self.data[symbol_idx]
460
+ end_idx = start_idx + self.config.lookback_window
461
+
462
+ x = symbol_data['feature'][start_idx:end_idx]
463
+ x_stamp = symbol_data['time_feature'][start_idx:end_idx]
464
+
465
+ # 实例级标准化
466
+ x_mean, x_std = np.mean(x, axis=0), np.std(x, axis=0)
467
+ x = (x - x_mean) / (x_std + 1e-5)
468
+ x = np.clip(x, -self.config.clip, self.config.clip)
469
+
470
+ return torch.from_numpy(x), torch.from_numpy(x_stamp)
471
+ ```
472
+
473
+ ### 5. 训练优化策略
474
+
475
+ #### 梯度累积
476
+ ```python
477
+ for j in range(config['accumulation_steps']):
478
+ # 分批处理
479
+ start_idx = j * (batch_size // config['accumulation_steps'])
480
+ end_idx = (j + 1) * (batch_size // config['accumulation_steps'])
481
+ mini_batch = batch[start_idx:end_idx]
482
+
483
+ # 前向传播
484
+ loss = model(mini_batch)
485
+ loss_scaled = loss / config['accumulation_steps']
486
+
487
+ # 反向传播
488
+ loss_scaled.backward()
489
+
490
+ # 参数更新
491
+ optimizer.step()
492
+ optimizer.zero_grad()
493
+ ```
494
+
495
+ #### 学习率调度
496
+ ```python
497
+ scheduler = torch.optim.lr_scheduler.OneCycleLR(
498
+ optimizer=optimizer,
499
+ max_lr=config['learning_rate'],
500
+ steps_per_epoch=len(train_loader),
501
+ epochs=config['epochs'],
502
+ pct_start=0.03, # 3%的时间用于warm-up
503
+ div_factor=10 # 初始学习率 = max_lr / div_factor
504
+ )
505
+ ```
506
+
507
+ ### 6. 分布式训练支持
508
+
509
+ #### DDP设置
510
+ ```python
511
+ def setup_ddp(rank, world_size):
512
+ os.environ['MASTER_ADDR'] = 'localhost'
513
+ os.environ['MASTER_PORT'] = '12355'
514
+ dist.init_process_group("nccl", rank=rank, world_size=world_size)
515
+ torch.cuda.set_device(rank)
516
+
517
+ # 模型包装
518
+ model = DDP(model, device_ids=[local_rank], find_unused_parameters=False)
519
+
520
+ # 数据采样器
521
+ train_sampler = DistributedSampler(train_dataset, num_replicas=world_size, rank=rank)
522
+ ```
523
+
524
+ ### 7. 实验监控
525
+
526
+ #### Comet ML集成
527
+ ```python
528
+ if config.use_comet:
529
+ comet_logger = comet_ml.Experiment(
530
+ api_key=config.comet_config['api_key'],
531
+ project_name=config.comet_config['project_name'],
532
+ workspace=config.comet_config['workspace']
533
+ )
534
+ comet_logger.add_tag(config.comet_tag)
535
+ comet_logger.set_name(config.comet_name)
536
+ ```
537
+
538
+ #### 指标记录
539
+ ```python
540
+ # 训练指标
541
+ comet_logger.log_metric("train_loss", loss.item(), step=batch_idx_global_train)
542
+ comet_logger.log_metric("learning_rate", scheduler.get_last_lr()[0], step=batch_idx_global_train)
543
+
544
+ # 验证指标
545
+ comet_logger.log_metric("val_loss", val_loss, step=epoch_idx)
546
+ comet_logger.log_metric("val_recon_loss", val_recon_loss, step=epoch_idx)
547
+ ```
548
+
549
+ ### 8. 模型评估与回测
550
+
551
+ #### 预测质量评估
552
+ ```python
553
+ def evaluate_predictions(y_true, y_pred):
554
+ # 价格预测指标
555
+ mse = np.mean((y_true - y_pred) ** 2)
556
+ mae = np.mean(np.abs(y_true - y_pred))
557
+ mape = np.mean(np.abs((y_true - y_pred) / y_true)) * 100
558
+
559
+ # 方向准确率
560
+ direction_acc = np.mean(
561
+ np.sign(y_true[1:] - y_true[:-1]) ==
562
+ np.sign(y_pred[1:] - y_pred[:-1])
563
+ )
564
+
565
+ return {
566
+ 'MSE': mse,
567
+ 'MAE': mae,
568
+ 'MAPE': mape,
569
+ 'Direction_Accuracy': direction_acc
570
+ }
571
+ ```
572
+
573
+ #### 回测框架
574
+ ```python
575
+ class BacktestEngine:
576
+ def __init__(self, config):
577
+ self.n_symbol_hold = config.backtest_n_symbol_hold
578
+ self.n_symbol_drop = config.backtest_n_symbol_drop
579
+ self.hold_thresh = config.backtest_hold_thresh
580
+
581
+ def run_backtest(self, predictions, prices, timestamps):
582
+ # 1. 信号生成
583
+ signals = self.generate_signals(predictions)
584
+
585
+ # 2. 组合构建
586
+ portfolio = self.build_portfolio(signals)
587
+
588
+ # 3. 收益计算
589
+ returns = self.calculate_returns(portfolio, prices)
590
+
591
+ # 4. 风险指标
592
+ metrics = self.calculate_risk_metrics(returns)
593
+
594
+ return metrics
595
+ ```
596
+
597
+ ### 9. 部署与生产使用
598
+
599
+ #### 模型服务化
600
+ ```python
601
+ class KronosPredictor:
602
+ def __init__(self, model_path, tokenizer_path, device="cpu"):
603
+ self.device = device
604
+ self.tokenizer = KronosTokenizer.from_pretrained(tokenizer_path)
605
+ self.model = Kronos.from_pretrained(model_path)
606
+ self.tokenizer.eval().to(device)
607
+ self.model.eval().to(device)
608
+
609
+ @torch.no_grad()
610
+ def predict_batch(self, batch_data):
611
+ """批量预测接口"""
612
+ predictions = []
613
+ for data in batch_data:
614
+ pred = self.predict(
615
+ df=data['features'],
616
+ x_timestamp=data['timestamps'],
617
+ y_timestamp=data['target_timestamps'],
618
+ pred_len=data['pred_len']
619
+ )
620
+ predictions.append(pred)
621
+ return predictions
622
+ ```
623
+
624
+ #### API接口设计
625
+ ```python
626
+ from flask import Flask, request, jsonify
627
+
628
+ app = Flask(__name__)
629
+ predictor = KronosPredictor("model_path", "tokenizer_path")
630
+
631
+ @app.route('/predict', methods=['POST'])
632
+ def predict():
633
+ try:
634
+ data = request.json
635
+
636
+ # 数据验证
637
+ required_fields = ['features', 'timestamps', 'pred_len']
638
+ if not all(field in data for field in required_fields):
639
+ return jsonify({'error': 'Missing required fields'}), 400
640
+
641
+ # 预测
642
+ result = predictor.predict(
643
+ df=pd.DataFrame(data['features']),
644
+ x_timestamp=pd.to_datetime(data['timestamps']),
645
+ y_timestamp=pd.to_datetime(data['target_timestamps']),
646
+ pred_len=data['pred_len']
647
+ )
648
+
649
+ return jsonify({
650
+ 'predictions': result.to_dict('records'),
651
+ 'status': 'success'
652
+ })
653
+
654
+ except Exception as e:
655
+ return jsonify({'error': str(e)}), 500
656
+ ```
657
+
658
+ ### 10. 性能优化建议
659
+
660
+ #### 推理优化
661
+ ```python
662
+ # 1. 模型量化
663
+ model = torch.quantization.quantize_dynamic(
664
+ model, {torch.nn.Linear}, dtype=torch.qint8
665
+ )
666
+
667
+ # 2. 批处理优化
668
+ def batch_predict(self, batch_data, batch_size=32):
669
+ results = []
670
+ for i in range(0, len(batch_data), batch_size):
671
+ batch = batch_data[i:i+batch_size]
672
+ with torch.no_grad():
673
+ batch_results = self.model(batch)
674
+ results.extend(batch_results)
675
+ return results
676
+
677
+ # 3. 缓存机制
678
+ from functools import lru_cache
679
+
680
+ @lru_cache(maxsize=1000)
681
+ def cached_tokenize(self, data_hash):
682
+ return self.tokenizer.encode(data)
683
+ ```
684
+
685
+ #### 内存优化
686
+ ```python
687
+ # 1. 梯度检查点
688
+ model = torch.utils.checkpoint.checkpoint_sequential(model, segments=4)
689
+
690
+ # 2. 混合精度训练
691
+ from torch.cuda.amp import autocast, GradScaler
692
+
693
+ scaler = GradScaler()
694
+ with autocast():
695
+ loss = model(batch)
696
+ scaler.scale(loss).backward()
697
+ scaler.step(optimizer)
698
+ scaler.update()
699
+ ```
700
+
701
+ ### 11. 故障排除指南
702
+
703
+ #### 常见问题及解决方案
704
+
705
+ 1. **CUDA内存不足**
706
+ ```python
707
+ # 解决方案:减少批次大小或使用梯度累积
708
+ config['batch_size'] = 16 # 减小批次
709
+ config['accumulation_steps'] = 4 # 增加累积步数
710
+ ```
711
+
712
+ 2. **模型加载失败**
713
+ ```python
714
+ # 检查依赖
715
+ pip install safetensors huggingface_hub
716
+
717
+ # 检查模型路径
718
+ if not os.path.exists(model_path):
719
+ print(f"Model path {model_path} does not exist")
720
+ ```
721
+
722
+ 3. **数据格式错误**
723
+ ```python
724
+ # 确保时间戳格式正确
725
+ df['timestamps'] = pd.to_datetime(df['timestamps'])
726
+
727
+ # 检查必需列
728
+ required_cols = ['open', 'high', 'low', 'close']
729
+ missing_cols = [col for col in required_cols if col not in df.columns]
730
+ if missing_cols:
731
+ raise ValueError(f"Missing columns: {missing_cols}")
732
+ ```
733
+
734
+ 4. **预测结果异常**
735
+ ```python
736
+ # 检查输入数据范围
737
+ print(f"Data range: {df.min()} to {df.max()}")
738
+
739
+ # 检查标准化
740
+ if df.std().min() < 1e-6:
741
+ print("Warning: Very small standard deviation detected")
742
+ ```
743
+
744
+ ### 12. 扩展开发指南
745
+
746
+ #### 自定义损失函数
747
+ ```python
748
+ class CustomLoss(nn.Module):
749
+ def __init__(self, alpha=1.0, beta=1.0):
750
+ super().__init__()
751
+ self.alpha = alpha
752
+ self.beta = beta
753
+
754
+ def forward(self, pred, target):
755
+ # 价格损失
756
+ price_loss = F.mse_loss(pred[:, :, :4], target[:, :, :4])
757
+
758
+ # 成交量损失(可选权重)
759
+ volume_loss = F.mse_loss(pred[:, :, 4:], target[:, :, 4:])
760
+
761
+ return self.alpha * price_loss + self.beta * volume_loss
762
+ ```
763
+
764
+ #### 新增特征
765
+ ```python
766
+ def add_technical_indicators(df):
767
+ """添加技术指标特征"""
768
+ # 移动平均
769
+ df['ma_5'] = df['close'].rolling(5).mean()
770
+ df['ma_20'] = df['close'].rolling(20).mean()
771
+
772
+ # RSI
773
+ delta = df['close'].diff()
774
+ gain = (delta.where(delta > 0, 0)).rolling(14).mean()
775
+ loss = (-delta.where(delta < 0, 0)).rolling(14).mean()
776
+ df['rsi'] = 100 - (100 / (1 + gain / loss))
777
+
778
+ # MACD
779
+ exp1 = df['close'].ewm(span=12).mean()
780
+ exp2 = df['close'].ewm(span=26).mean()
781
+ df['macd'] = exp1 - exp2
782
+
783
+ return df
784
+ ```
785
+
786
+ ### 13. 最佳实践
787
+
788
+ #### 数据质量控制
789
+ ```python
790
+ def validate_data_quality(df):
791
+ """数据质量检查"""
792
+ issues = []
793
+
794
+ # 检查缺失值
795
+ if df.isnull().any().any():
796
+ issues.append("Contains missing values")
797
+
798
+ # 检查异常值
799
+ for col in ['open', 'high', 'low', 'close']:
800
+ if (df[col] <= 0).any():
801
+ issues.append(f"Non-positive values in {col}")
802
+
803
+ # 检查价格逻辑
804
+ if (df['high'] < df['low']).any():
805
+ issues.append("High price less than low price")
806
+
807
+ if (df['high'] < df['close']).any() or (df['low'] > df['close']).any():
808
+ issues.append("Close price outside high-low range")
809
+
810
+ return issues
811
+ ```
812
+
813
+ #### 模型版本管理
814
+ ```python
815
+ class ModelVersionManager:
816
+ def __init__(self, base_path):
817
+ self.base_path = base_path
818
+
819
+ def save_model(self, model, version, metadata):
820
+ """保存模型版本"""
821
+ version_path = os.path.join(self.base_path, f"v{version}")
822
+ os.makedirs(version_path, exist_ok=True)
823
+
824
+ # 保存模型
825
+ model.save_pretrained(version_path)
826
+
827
+ # 保存元数据
828
+ with open(os.path.join(version_path, "metadata.json"), 'w') as f:
829
+ json.dump(metadata, f, indent=2)
830
+
831
+ def load_model(self, version):
832
+ """加载指定版本模型"""
833
+ version_path = os.path.join(self.base_path, f"v{version}")
834
+ return Kronos.from_pretrained(version_path)
835
+ ```
836
+
837
+ ---
838
+
839
+ ## 总结
840
+
841
+ Kronos项目是一个专门为金融时间序列预测设计的先进深度学习框架,具有以下核心优势:
842
+
843
+ 1. **专业性**: 专门针对金融数据的特点进行优化
844
+ 2. **创新性**: 采用分层量化和依赖感知的新颖架构
845
+ 3. **实用性**: 提供完整的训练、推理和部署解决方案
846
+ 4. **可扩展性**: 支持自定义扩展和优化
847
+
848
+ 该项目为量化金融领域提供了一个强大的工具,可以应用于价格预测、风险管理、算法交易等多个场景。通过合理的配置和优化,可以在实际生产环境中获得良好的性能表现。
849
+
850
+ *本文档基于Kronos项目代码分析生成,详细技术实现请参考源代码。*
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2025 ShiYu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
README.md CHANGED
@@ -1,11 +1,333 @@
1
- ---
2
- title: Crypt
3
- emoji: 😻
4
- colorFrom: green
5
- colorTo: green
6
- sdk: docker
7
- pinned: false
8
- license: apache-2.0
9
- ---
10
-
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div align="center">
2
+ <h2><b>Kronos: A Foundation Model for the Language of Financial Markets </b></h2>
3
+ </div>
4
+
5
+
6
+ <div align="center">
7
+
8
+ </a>
9
+ <a href="https://huggingface.co/NeoQuasar">
10
+ <img src="https://img.shields.io/badge/🤗-Hugging_Face-yellow" alt="Hugging Face">
11
+ </a>
12
+ <a href="https://shiyu-coder.github.io/Kronos-demo/"> <img src="https://img.shields.io/badge/🚀-Live_Demo-brightgreen" alt="Live Demo"> </a>
13
+ <a href="https://github.com/shiyu-coder/Kronos/graphs/commit-activity">
14
+ <img src="https://img.shields.io/github/last-commit/shiyu-coder/Kronos?color=blue" alt="Last Commit">
15
+ </a>
16
+ <a href="https://github.com/shiyu-coder/Kronos/stargazers">
17
+ <img src="https://img.shields.io/github/stars/shiyu-coder/Kronos?color=lightblue" alt="GitHub Stars">
18
+ </a>
19
+ <a href="https://github.com/shiyu-coder/Kronos/network/members">
20
+ <img src="https://img.shields.io/github/forks/shiyu-coder/Kronos?color=yellow" alt="GitHub Forks">
21
+ </a>
22
+ <a href="./LICENSE">
23
+ <img src="https://img.shields.io/github/license/shiyu-coder/Kronos?color=green" alt="License">
24
+ </a>
25
+
26
+ </div>
27
+
28
+ <div align="center">
29
+ <!-- Keep these links. Translations will automatically update with the README. -->
30
+ <a href="https://zdoc.app/de/shiyu-coder/Kronos">Deutsch</a> |
31
+ <a href="https://zdoc.app/es/shiyu-coder/Kronos">Español</a> |
32
+ <a href="https://zdoc.app/fr/shiyu-coder/Kronos">français</a> |
33
+ <a href="https://zdoc.app/ja/shiyu-coder/Kronos">日本語</a> |
34
+ <a href="https://zdoc.app/ko/shiyu-coder/Kronos">한국어</a> |
35
+ <a href="https://zdoc.app/pt/shiyu-coder/Kronos">Português</a> |
36
+ <a href="https://zdoc.app/ru/shiyu-coder/Kronos">Русский</a> |
37
+ <a href="https://zdoc.app/zh/shiyu-coder/Kronos">中文</a>
38
+ </div>
39
+
40
+ <p align="center">
41
+
42
+ <img src="./figures/logo.png" width="100">
43
+
44
+ </p>
45
+
46
+ > Kronos is the **first open-source foundation model** for financial candlesticks (K-lines),
47
+ > trained on data from over **45 global exchanges**.
48
+
49
+
50
+ </div>
51
+
52
+ ## 📰 News
53
+ * 🚩 **[2025.08.17]** We have released the scripts for fine-tuning! Check them out to adapt Kronos to your own tasks.
54
+ * 🚩 **[2025.08.02]** Our paper is now available on [arXiv](https://arxiv.org/abs/2508.02739)!
55
+
56
+ <p align="center">
57
+
58
+ ## 📜 Introduction
59
+
60
+ **Kronos** is a family of decoder-only foundation models, pre-trained specifically for the "language" of financial markets—K-line sequences. Unlike general-purpose TSFMs, Kronos is designed to handle the unique, high-noise characteristics of financial data. It leverages a novel two-stage framework:
61
+ 1. A specialized tokenizer first quantizes continuous, multi-dimensional K-line data (OHLCV) into **hierarchical discrete tokens**.
62
+ 2. A large, autoregressive Transformer is then pre-trained on these tokens, enabling it to serve as a unified model for diverse quantitative tasks.
63
+
64
+ <p align="center">
65
+ <img src="figures/overview.png" alt="" align="center" width="700px" />
66
+ </p>
67
+
68
+ ## ✨ Live Demo
69
+ We have set up a live demo to visualize Kronos's forecasting results. The webpage showcases a forecast for the **BTC/USDT** trading pair over the next 24 hours.
70
+
71
+ **👉 [Access the Live Demo Here](https://shiyu-coder.github.io/Kronos-demo/)**
72
+
73
+ ## 📦 Model Zoo
74
+ We release a family of pre-trained models with varying capacities to suit different computational and application needs. All models are readily accessible from the Hugging Face Hub.
75
+
76
+ | Model | Tokenizer | Context length | Param | Open-source |
77
+ |--------------|---------------------------------------------------------------------------------| -------------- | ------ |---------------------------------------------------------------------------|
78
+ | Kronos-mini | [Kronos-Tokenizer-2k](https://huggingface.co/NeoQuasar/Kronos-Tokenizer-2k) | 2048 | 4.1M | ✅ [NeoQuasar/Kronos-mini](https://huggingface.co/NeoQuasar/Kronos-mini) |
79
+ | Kronos-small | [Kronos-Tokenizer-base](https://huggingface.co/NeoQuasar/Kronos-Tokenizer-base) | 512 | 24.7M | ✅ [NeoQuasar/Kronos-small](https://huggingface.co/NeoQuasar/Kronos-small) |
80
+ | Kronos-base | [Kronos-Tokenizer-base](https://huggingface.co/NeoQuasar/Kronos-Tokenizer-base) | 512 | 102.3M | ✅ [NeoQuasar/Kronos-base](https://huggingface.co/NeoQuasar/Kronos-base) |
81
+ | Kronos-large | [Kronos-Tokenizer-base](https://huggingface.co/NeoQuasar/Kronos-Tokenizer-base) | 512 | 499.2M | ❌ |
82
+
83
+
84
+ ## 🚀 Getting Started
85
+
86
+ ### Installation
87
+
88
+ 1. Install Python 3.10+, and then install the dependencies:
89
+
90
+ ```shell
91
+ pip install -r requirements.txt
92
+ ```
93
+
94
+ ### 📈 Making Forecasts
95
+
96
+ Forecasting with Kronos is straightforward using the `KronosPredictor` class. It handles data preprocessing, normalization, prediction, and inverse normalization, allowing you to get from raw data to forecasts in just a few lines of code.
97
+
98
+ **Important Note**: The `max_context` for `Kronos-small` and `Kronos-base` is **512**. This is the maximum sequence length the model can process. For optimal performance, it is recommended that your input data length (i.e., `lookback`) does not exceed this limit. The `KronosPredictor` will automatically handle truncation for longer contexts.
99
+
100
+ Here is a step-by-step guide to making your first forecast.
101
+
102
+ #### 1. Load the Tokenizer and Model
103
+
104
+ First, load a pre-trained Kronos model and its corresponding tokenizer from the Hugging Face Hub.
105
+
106
+ ```python
107
+ from model import Kronos, KronosTokenizer, KronosPredictor
108
+
109
+ # Load from Hugging Face Hub
110
+ tokenizer = KronosTokenizer.from_pretrained("NeoQuasar/Kronos-Tokenizer-base")
111
+ model = Kronos.from_pretrained("NeoQuasar/Kronos-small")
112
+ ```
113
+
114
+ #### 2. Instantiate the Predictor
115
+
116
+ Create an instance of `KronosPredictor`, passing the model, tokenizer, and desired device.
117
+
118
+ ```python
119
+ # Initialize the predictor
120
+ predictor = KronosPredictor(model, tokenizer, device="cuda:0", max_context=512)
121
+ ```
122
+
123
+ #### 3. Prepare Input Data
124
+
125
+ The `predict` method requires three main inputs:
126
+ - `df`: A pandas DataFrame containing the historical K-line data. It must include columns `['open', 'high', 'low', 'close']`. `volume` and `amount` are optional.
127
+ - `x_timestamp`: A pandas Series of timestamps corresponding to the historical data in `df`.
128
+ - `y_timestamp`: A pandas Series of timestamps for the future periods you want to predict.
129
+
130
+ ```python
131
+ import pandas as pd
132
+
133
+ # Load your data
134
+ df = pd.read_csv("./data/XSHG_5min_600977.csv")
135
+ df['timestamps'] = pd.to_datetime(df['timestamps'])
136
+
137
+ # Define context window and prediction length
138
+ lookback = 400
139
+ pred_len = 120
140
+
141
+ # Prepare inputs for the predictor
142
+ x_df = df.loc[:lookback-1, ['open', 'high', 'low', 'close', 'volume', 'amount']]
143
+ x_timestamp = df.loc[:lookback-1, 'timestamps']
144
+ y_timestamp = df.loc[lookback:lookback+pred_len-1, 'timestamps']
145
+ ```
146
+
147
+ #### 4. Generate Forecasts
148
+
149
+ Call the `predict` method to generate forecasts. You can control the sampling process with parameters like `T`, `top_p`, and `sample_count` for probabilistic forecasting.
150
+
151
+ ```python
152
+ # Generate predictions
153
+ pred_df = predictor.predict(
154
+ df=x_df,
155
+ x_timestamp=x_timestamp,
156
+ y_timestamp=y_timestamp,
157
+ pred_len=pred_len,
158
+ T=1.0, # Temperature for sampling
159
+ top_p=0.9, # Nucleus sampling probability
160
+ sample_count=1 # Number of forecast paths to generate and average
161
+ )
162
+
163
+ print("Forecasted Data Head:")
164
+ print(pred_df.head())
165
+ ```
166
+
167
+ The `predict` method returns a pandas DataFrame containing the forecasted values for `open`, `high`, `low`, `close`, `volume`, and `amount`, indexed by the `y_timestamp` you provided.
168
+
169
+ For efficient processing of multiple time series, Kronos provides a `predict_batch` method that enables parallel prediction on multiple datasets simultaneously. This is particularly useful when you need to forecast multiple assets or time periods at once.
170
+
171
+ ```python
172
+ # Prepare multiple datasets for batch prediction
173
+ df_list = [df1, df2, df3] # List of DataFrames
174
+ x_timestamp_list = [x_ts1, x_ts2, x_ts3] # List of historical timestamps
175
+ y_timestamp_list = [y_ts1, y_ts2, y_ts3] # List of future timestamps
176
+
177
+ # Generate batch predictions
178
+ pred_df_list = predictor.predict_batch(
179
+ df_list=df_list,
180
+ x_timestamp_list=x_timestamp_list,
181
+ y_timestamp_list=y_timestamp_list,
182
+ pred_len=pred_len,
183
+ T=1.0,
184
+ top_p=0.9,
185
+ sample_count=1,
186
+ verbose=True
187
+ )
188
+
189
+ # pred_df_list contains prediction results in the same order as input
190
+ for i, pred_df in enumerate(pred_df_list):
191
+ print(f"Predictions for series {i}:")
192
+ print(pred_df.head())
193
+ ```
194
+
195
+ **Important Requirements for Batch Prediction:**
196
+ - All series must have the same historical length (lookback window)
197
+ - All series must have the same prediction length (`pred_len`)
198
+ - Each DataFrame must contain the required columns: `['open', 'high', 'low', 'close']`
199
+ - `volume` and `amount` columns are optional and will be filled with zeros if missing
200
+
201
+ The `predict_batch` method leverages GPU parallelism for efficient processing and automatically handles normalization and denormalization for each series independently.
202
+
203
+ #### 5. Example and Visualization
204
+
205
+ For a complete, runnable script that includes data loading, prediction, and plotting, please see [`examples/prediction_example.py`](examples/prediction_example.py).
206
+
207
+ Running this script will generate a plot comparing the ground truth data against the model's forecast, similar to the one shown below:
208
+
209
+ <p align="center">
210
+ <img src="figures/prediction_example.png" alt="Forecast Example" align="center" width="600px" />
211
+ </p>
212
+
213
+ Additionally, we also provide a script that makes predictions without Volume and Amount data, which can be found in [`examples/prediction_wo_vol_example.py`](examples/prediction_wo_vol_example.py).
214
+
215
+
216
+ ## 🔧 Finetuning on Your Own Data (A-Share Market Example)
217
+
218
+ We provide a complete pipeline for finetuning Kronos on your own datasets. As an example, we demonstrate how to use [Qlib](https://github.com/microsoft/qlib) to prepare data from the Chinese A-share market and conduct a simple backtest.
219
+
220
+ > **Disclaimer:** This pipeline is intended as a demonstration to illustrate the finetuning process. It is a simplified example and not a production-ready quantitative trading system. A robust quantitative strategy requires more sophisticated techniques, such as portfolio optimization and risk factor neutralization, to achieve stable alpha.
221
+
222
+ The finetuning process is divided into four main steps:
223
+
224
+ 1. **Configuration**: Set up paths and hyperparameters.
225
+ 2. **Data Preparation**: Process and split your data using Qlib.
226
+ 3. **Model Finetuning**: Finetune the Tokenizer and the Predictor models.
227
+ 4. **Backtesting**: Evaluate the finetuned model's performance.
228
+
229
+ ### Prerequisites
230
+
231
+ 1. First, ensure you have all dependencies from `requirements.txt` installed.
232
+ 2. This pipeline relies on `qlib`. Please install it:
233
+ ```shell
234
+ pip install pyqlib
235
+ ```
236
+ 3. You will need to prepare your Qlib data. Follow the [official Qlib guide](https://github.com/microsoft/qlib) to download and set up your data locally. The example scripts assume you are using daily frequency data.
237
+
238
+ ### Step 1: Configure Your Experiment
239
+
240
+ All settings for data, training, and model paths are centralized in `finetune/config.py`. Before running any scripts, please **modify the following paths** according to your environment:
241
+
242
+ * `qlib_data_path`: Path to your local Qlib data directory.
243
+ * `dataset_path`: Directory where the processed train/validation/test pickle files will be saved.
244
+ * `save_path`: Base directory for saving model checkpoints.
245
+ * `backtest_result_path`: Directory for saving backtesting results.
246
+ * `pretrained_tokenizer_path` and `pretrained_predictor_path`: Paths to the pre-trained models you want to start from (can be local paths or Hugging Face model names).
247
+
248
+ You can also adjust other parameters like `instrument`, `train_time_range`, `epochs`, and `batch_size` to fit your specific task. If you don't use [Comet.ml](https://www.comet.com/), set `use_comet = False`.
249
+
250
+ ### Step 2: Prepare the Dataset
251
+
252
+ Run the data preprocessing script. This script will load raw market data from your Qlib directory, process it, split it into training, validation, and test sets, and save them as pickle files.
253
+
254
+ ```shell
255
+ python finetune/qlib_data_preprocess.py
256
+ ```
257
+
258
+ After running, you will find `train_data.pkl`, `val_data.pkl`, and `test_data.pkl` in the directory specified by `dataset_path` in your config.
259
+
260
+ ### Step 3: Run the Finetuning
261
+
262
+ The finetuning process consists of two stages: finetuning the tokenizer and then the predictor. Both training scripts are designed for multi-GPU training using `torchrun`.
263
+
264
+ #### 3.1 Finetune the Tokenizer
265
+
266
+ This step adjusts the tokenizer to the data distribution of your specific domain.
267
+
268
+ ```shell
269
+ # Replace NUM_GPUS with the number of GPUs you want to use (e.g., 2)
270
+ torchrun --standalone --nproc_per_node=NUM_GPUS finetune/train_tokenizer.py
271
+ ```
272
+
273
+ The best tokenizer checkpoint will be saved to the path configured in `config.py` (derived from `save_path` and `tokenizer_save_folder_name`).
274
+
275
+ #### 3.2 Finetune the Predictor
276
+
277
+ This step finetunes the main Kronos model for the forecasting task.
278
+
279
+ ```shell
280
+ # Replace NUM_GPUS with the number of GPUs you want to use (e.g., 2)
281
+ torchrun --standalone --nproc_per_node=NUM_GPUS finetune/train_predictor.py
282
+ ```
283
+
284
+ The best predictor checkpoint will be saved to the path configured in `config.py`.
285
+
286
+ ### Step 4: Evaluate with Backtesting
287
+
288
+ Finally, run the backtesting script to evaluate your finetuned model. This script loads the models, performs inference on the test set, generates prediction signals (e.g., forecasted price change), and runs a simple top-K strategy backtest.
289
+
290
+ ```shell
291
+ # Specify the GPU for inference
292
+ python finetune/qlib_test.py --device cuda:0
293
+ ```
294
+
295
+ The script will output a detailed performance analysis in your console and generate a plot showing the cumulative return curves of your strategy against the benchmark, similar to the one below:
296
+
297
+ <p align="center">
298
+ <img src="figures/backtest_result_example.png" alt="Backtest Example" align="center" width="700px" />
299
+ </p>
300
+
301
+ ### 💡 From Demo to Production: Important Considerations
302
+
303
+ * **Raw Signals vs. Pure Alpha**: The signals generated by the model in this demo are raw predictions. In a real-world quantitative workflow, these signals would typically be fed into a portfolio optimization model. This model would apply constraints to neutralize exposure to common risk factors (e.g., market beta, style factors like size and value), thereby isolating the **"pure alpha"** and improving the strategy's robustness.
304
+ * **Data Handling**: The provided `QlibDataset` is an example. For different data sources or formats, you will need to adapt the data loading and preprocessing logic.
305
+ * **Strategy and Backtesting Complexity**: The simple top-K strategy used here is a basic starting point. Production-level strategies often incorporate more complex logic for portfolio construction, dynamic position sizing, and risk management (e.g., stop-loss/take-profit rules). Furthermore, a high-fidelity backtest should meticulously model transaction costs, slippage, and market impact to provide a more accurate estimate of real-world performance.
306
+
307
+ > **📝 AI-Generated Comments**: Please note that many of the code comments within the `finetune/` directory were generated by an AI assistant (Gemini 2.5 Pro) for explanatory purposes. While they aim to be helpful, they may contain inaccuracies. We recommend treating the code itself as the definitive source of logic.
308
+
309
+ ## 📖 Citation
310
+
311
+ If you use Kronos in your research, we would appreciate a citation to our [paper](https://arxiv.org/abs/2508.02739):
312
+
313
+ ```
314
+ @misc{shi2025kronos,
315
+ title={Kronos: A Foundation Model for the Language of Financial Markets},
316
+ author={Yu Shi and Zongliang Fu and Shuo Chen and Bohan Zhao and Wei Xu and Changshui Zhang and Jian Li},
317
+ year={2025},
318
+ eprint={2508.02739},
319
+ archivePrefix={arXiv},
320
+ primaryClass={q-fin.ST},
321
+ url={https://arxiv.org/abs/2508.02739},
322
+ }
323
+ ```
324
+
325
+ ## 📜 License
326
+ This project is licensed under the [MIT License](./LICENSE).
327
+
328
+
329
+
330
+
331
+
332
+
333
+
docker-compose.yml ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version: '3.8'
2
+
3
+ services:
4
+ kronos-webui:
5
+ build:
6
+ context: .
7
+ dockerfile: Dockerfile
8
+ container_name: kronos-webui
9
+ ports:
10
+ - "7070:7070"
11
+ environment:
12
+ - PYTHONPATH=/app
13
+ - FLASK_APP=webui/app.py
14
+ - FLASK_ENV=production
15
+ - TZ=Asia/Shanghai
16
+ volumes:
17
+ # Mount prediction results directory for persistence
18
+ - ./webui/prediction_results:/app/webui/prediction_results
19
+ # Mount model data directory if you have local models
20
+ - ./model/data:/app/model/data
21
+ restart: unless-stopped
22
+ healthcheck:
23
+ test: ["CMD", "curl", "-f", "http://localhost:7070/"]
24
+ interval: 30s
25
+ timeout: 10s
26
+ retries: 3
27
+ start_period: 40s
28
+ networks:
29
+ - kronos-network
30
+
31
+ networks:
32
+ kronos-network:
33
+ driver: bridge
34
+
35
+ # Optional: Add a volume for persistent data
36
+ volumes:
37
+ kronos-data:
38
+ driver: local
examples/data/XSHG_5min_600977.csv ADDED
The diff for this file is too large to render. See raw diff
 
examples/eth_usdt_realtime_prediction.py ADDED
@@ -0,0 +1,524 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import time
4
+ import warnings
5
+ from datetime import datetime, timedelta
6
+
7
+ import matplotlib.dates as mdates
8
+ import matplotlib.pyplot as plt
9
+ import numpy as np
10
+ import pandas as pd
11
+ import requests
12
+
13
+ warnings.filterwarnings('ignore')
14
+
15
+ # 添加项目路径
16
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
17
+ from model import Kronos, KronosTokenizer, KronosPredictor
18
+
19
+
20
+ # ==================== 配置参数 ====================
21
+ class PredictionConfig:
22
+ """预测配置类"""
23
+
24
+ # 支持的时间间隔及其对应的分钟数
25
+ SUPPORTED_INTERVALS = {
26
+ '1m': 1, '3m': 3, '5m': 5, '15m': 15, '30m': 30,
27
+ '1h': 60, '2h': 120, '4h': 240, '6h': 360, '8h': 480, '12h': 720, '1d': 1440
28
+ }
29
+
30
+ def __init__(self, interval='15m', pred_len=24, lookback=400):
31
+ self.interval = interval
32
+ self.pred_len = pred_len
33
+ self.lookback = lookback
34
+ self.interval_minutes = self.SUPPORTED_INTERVALS.get(interval, 15)
35
+
36
+ # 验证参数
37
+ if interval not in self.SUPPORTED_INTERVALS:
38
+ raise ValueError(f"不支持的时间间隔: {interval}. 支持的间隔: {list(self.SUPPORTED_INTERVALS.keys())}")
39
+
40
+ def get_24h_periods(self):
41
+ """计算24小时对应的K线数量"""
42
+ return int(24 * 60 / self.interval_minutes)
43
+
44
+ def get_prediction_duration_hours(self):
45
+ """计算预测时长(小时)"""
46
+ return (self.pred_len * self.interval_minutes) / 60
47
+
48
+ def get_freq_string(self):
49
+ """获取pandas频率字符串"""
50
+ freq_map = {
51
+ '1m': '1T', '3m': '3T', '5m': '5T', '15m': '15T', '30m': '30T',
52
+ '1h': '1H', '2h': '2H', '4h': '4H', '6h': '6H', '8h': '8H', '12h': '12H', '1d': '1D'
53
+ }
54
+ return freq_map.get(self.interval, '15T')
55
+
56
+ def get_time_format(self):
57
+ """根据时间间隔获取最佳时间显示格式"""
58
+ if self.interval_minutes <= 60: # 小时内
59
+ return '%H:%M'
60
+ elif self.interval_minutes <= 1440: # 日内
61
+ return '%m-%d %H:%M'
62
+ else: # 日级别
63
+ return '%Y-%m-%d'
64
+
65
+ def get_prediction_time_points(self):
66
+ """Get prediction time point descriptions"""
67
+ duration_hours = self.get_prediction_duration_hours()
68
+
69
+ if duration_hours < 1:
70
+ return [
71
+ (int(self.pred_len * 0.25), f"{int(duration_hours * 0.25 * 60)}min later"),
72
+ (int(self.pred_len * 0.5), f"{int(duration_hours * 0.5 * 60)}min later"),
73
+ (self.pred_len - 1, f"{int(duration_hours * 60)}min later")
74
+ ]
75
+ elif duration_hours <= 24:
76
+ return [
77
+ (int(self.pred_len * 0.25), f"{duration_hours * 0.25:.1f}h later"),
78
+ (int(self.pred_len * 0.5), f"{duration_hours * 0.5:.1f}h later"),
79
+ (self.pred_len - 1, f"{duration_hours:.1f}h later")
80
+ ]
81
+ else:
82
+ days = duration_hours / 24
83
+ return [
84
+ (int(self.pred_len * 0.25), f"{days * 0.25:.1f}d later"),
85
+ (int(self.pred_len * 0.5), f"{days * 0.5:.1f}d later"),
86
+ (self.pred_len - 1, f"{days:.1f}d later")
87
+ ]
88
+
89
+
90
+ def get_user_config():
91
+ """获取用户配置(可扩展为交互式输入)"""
92
+
93
+ # 配置示例:
94
+ # 短期交易 (1分钟K线,预测30分钟)
95
+ # config = PredictionConfig(interval='1m', pred_len=30, lookback=400)
96
+
97
+ # 中期交易 (15分钟K线,预测6小时)
98
+ config = PredictionConfig(interval='15m', pred_len=24, lookback=512)
99
+
100
+ # 长期分析 (1小时K线,预测24小时)
101
+ # config = PredictionConfig(interval='1h', pred_len=24, lookback=400)
102
+
103
+ # 日线分析 (1天K线,预测7天)
104
+ # config = PredictionConfig(interval='1d', pred_len=7, lookback=200)
105
+
106
+ print("📋 当前预测配置:")
107
+ print(f" 时间间隔: {config.interval}")
108
+ print(f" 预测长度: {config.pred_len} 步")
109
+ print(f" 预测时长: {config.get_prediction_duration_hours():.1f} 小时")
110
+ print(f" 历史数据: {config.lookback} 个数据点")
111
+ print(f" 支持的间隔: {list(config.SUPPORTED_INTERVALS.keys())}")
112
+ print()
113
+
114
+ return config
115
+
116
+
117
+ class BinanceDataFetcher:
118
+ """币安数据获取器 - 中国可访问"""
119
+
120
+ def __init__(self):
121
+ self.base_url = "https://api.binance.com"
122
+ # 备用URL(如果主URL不可访问)
123
+ self.backup_urls = [
124
+ "https://api1.binance.com",
125
+ "https://api2.binance.com",
126
+ "https://api3.binance.com"
127
+ ]
128
+
129
+ def get_klines(self, symbol="ETHUSDT", interval="15m", limit=500):
130
+ """
131
+ 获取K线数据
132
+
133
+ Args:
134
+ symbol: 交易对符号 (如 ETHUSDT)
135
+ interval: 时间间隔 (1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M)
136
+ limit: 数据条数 (最大1000)
137
+ """
138
+ endpoint = "/api/v3/klines"
139
+ params = {
140
+ 'symbol': symbol,
141
+ 'interval': interval,
142
+ 'limit': limit
143
+ }
144
+
145
+ # 尝试多个URL
146
+ for url in [self.base_url] + self.backup_urls:
147
+ try:
148
+ response = requests.get(url + endpoint, params=params, timeout=10)
149
+ if response.status_code == 200:
150
+ data = response.json()
151
+ return self._parse_klines(data)
152
+ else:
153
+ print(f"API返回错误: {response.status_code}")
154
+ except Exception as e:
155
+ print(f"尝试URL {url} 失败: {e}")
156
+ continue
157
+
158
+ raise Exception("所有API URL都无法访问,请检查网络连接")
159
+
160
+ def _parse_klines(self, raw_data):
161
+ """解析K线数据"""
162
+ df = pd.DataFrame(raw_data, columns=[
163
+ 'timestamp', 'open', 'high', 'low', 'close', 'volume',
164
+ 'close_time', 'quote_asset_volume', 'number_of_trades',
165
+ 'taker_buy_base_asset_volume', 'taker_buy_quote_asset_volume', 'ignore'
166
+ ])
167
+
168
+ # 转换数据类型
169
+ df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
170
+ for col in ['open', 'high', 'low', 'close', 'volume', 'quote_asset_volume']:
171
+ df[col] = df[col].astype(float)
172
+
173
+ # 重命名列以匹配Kronos格式
174
+ df = df.rename(columns={
175
+ 'timestamp': 'timestamps',
176
+ 'quote_asset_volume': 'amount'
177
+ })
178
+
179
+ # 选择需要的列
180
+ df = df[['timestamps', 'open', 'high', 'low', 'close', 'volume', 'amount']]
181
+
182
+ return df.sort_values('timestamps').reset_index(drop=True)
183
+
184
+
185
+ def plot_prediction_with_realtime(historical_df, pred_df, config, symbol="ETH-USDT"):
186
+ """Plot professional financial chart style real-time prediction results"""
187
+
188
+ # Set font to avoid Chinese display issues
189
+ plt.rcParams['font.family'] = 'DejaVu Sans'
190
+ plt.rcParams['axes.unicode_minus'] = False
191
+
192
+ # 准备时间序列数据
193
+ hist_timestamps = pd.to_datetime(historical_df['timestamps'])
194
+ pred_timestamps = pd.to_datetime(pred_df.index) if hasattr(pred_df, 'index') else pd.date_range(
195
+ start=hist_timestamps.iloc[-1] + pd.Timedelta(minutes=config.interval_minutes),
196
+ periods=len(pred_df),
197
+ freq=config.get_freq_string()
198
+ )
199
+
200
+ # 准备数据
201
+ hist_close = historical_df['close'].values
202
+ pred_close = pred_df['close'].values
203
+ hist_volume = historical_df['volume'].values
204
+ pred_volume = pred_df['volume'].values
205
+
206
+ # 计算关键统计信息
207
+ current_price = hist_close[-1]
208
+ final_pred_price = pred_close[-1]
209
+ price_change = final_pred_price - current_price
210
+ price_change_pct = (price_change / current_price) * 100
211
+ max_pred_price = np.max(pred_close)
212
+ min_pred_price = np.min(pred_close)
213
+ volatility = ((max_pred_price - min_pred_price) / current_price) * 100
214
+
215
+ # 创建专业图表布局
216
+ fig = plt.figure(figsize=(16, 10))
217
+ gs = fig.add_gridspec(3, 4, height_ratios=[0.8, 2, 1], width_ratios=[1, 1, 1, 1],
218
+ hspace=0.3, wspace=0.2)
219
+
220
+ # 信息面板
221
+ ax_info = fig.add_subplot(gs[0, :])
222
+ ax_info.axis('off')
223
+
224
+ # 主价格图
225
+ ax_price = fig.add_subplot(gs[1, :])
226
+
227
+ # 成交量图
228
+ ax_volume = fig.add_subplot(gs[2, :], sharex=ax_price)
229
+
230
+ # === Information Panel ===
231
+ duration_text = f"{config.get_prediction_duration_hours():.1f}h" if config.get_prediction_duration_hours() >= 1 else f"{int(config.get_prediction_duration_hours() * 60)}min"
232
+ info_text = f"""
233
+ {symbol} {config.interval} Candlestick Prediction Analysis | {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
234
+ Config: {config.pred_len}-step prediction ({duration_text}) | Historical data: {config.lookback} points
235
+
236
+ Current Price: ${current_price:.2f} Predicted Price: ${final_pred_price:.2f} Change: {price_change:+.2f} ({price_change_pct:+.2f}%)
237
+ Predicted High: ${max_pred_price:.2f} Predicted Low: ${min_pred_price:.2f} Volatility: {volatility:.2f}%
238
+ """
239
+ ax_info.text(0.5, 0.5, info_text, transform=ax_info.transAxes,
240
+ fontsize=12, ha='center', va='center',
241
+ bbox=dict(boxstyle="round,pad=0.5", facecolor='lightblue', alpha=0.8))
242
+
243
+ # === 价格图绘制 ===
244
+ # 历史价格线
245
+ ax_price.plot(hist_timestamps, hist_close,
246
+ color='#1f77b4', linewidth=2, label='Historical Price', alpha=0.8)
247
+
248
+ # 预测价格线(虚线)
249
+ ax_price.plot(pred_timestamps, pred_close,
250
+ color='#ff7f0e', linewidth=2.5, linestyle='--',
251
+ label='Predicted Price', alpha=0.9)
252
+
253
+ # 预测区域背景高亮
254
+ y_min, y_max = ax_price.get_ylim()
255
+ pred_start = pred_timestamps[0]
256
+ pred_end = pred_timestamps[-1]
257
+ ax_price.axvspan(pred_start, pred_end, alpha=0.1, color='orange', label='Prediction Zone')
258
+
259
+ # 关键价格点标注
260
+ # 当前价格点
261
+ ax_price.scatter(hist_timestamps.iloc[-1], current_price,
262
+ color='blue', s=100, zorder=5, marker='o')
263
+ ax_price.annotate(f'Current: ${current_price:.2f}',
264
+ xy=(hist_timestamps.iloc[-1], current_price),
265
+ xytext=(10, 10), textcoords='offset points',
266
+ bbox=dict(boxstyle='round,pad=0.3', facecolor='lightblue'),
267
+ arrowprops=dict(arrowstyle='->', color='blue'))
268
+
269
+ # 最终预测价格点
270
+ ax_price.scatter(pred_timestamps[-1], final_pred_price,
271
+ color='red', s=100, zorder=5, marker='s')
272
+ ax_price.annotate(f'Predicted: ${final_pred_price:.2f}',
273
+ xy=(pred_timestamps[-1], final_pred_price),
274
+ xytext=(-80, 10), textcoords='offset points',
275
+ bbox=dict(boxstyle='round,pad=0.3', facecolor='lightyellow'),
276
+ arrowprops=dict(arrowstyle='->', color='red'))
277
+
278
+ # 最高最低价格标注
279
+ max_idx = np.argmax(pred_close)
280
+ min_idx = np.argmin(pred_close)
281
+
282
+ ax_price.scatter(pred_timestamps[max_idx], max_pred_price,
283
+ color='green', s=80, zorder=5, marker='^')
284
+ ax_price.annotate(f'High: ${max_pred_price:.2f}',
285
+ xy=(pred_timestamps[max_idx], max_pred_price),
286
+ xytext=(0, 15), textcoords='offset points',
287
+ ha='center', fontsize=9,
288
+ bbox=dict(boxstyle='round,pad=0.2', facecolor='lightgreen'))
289
+
290
+ ax_price.scatter(pred_timestamps[min_idx], min_pred_price,
291
+ color='red', s=80, zorder=5, marker='v')
292
+ ax_price.annotate(f'Low: ${min_pred_price:.2f}',
293
+ xy=(pred_timestamps[min_idx], min_pred_price),
294
+ xytext=(0, -20), textcoords='offset points',
295
+ ha='center', fontsize=9,
296
+ bbox=dict(boxstyle='round,pad=0.2', facecolor='lightcoral'))
297
+
298
+ # 趋势箭头
299
+ if price_change > 0:
300
+ ax_price.annotate('', xy=(pred_timestamps[-1], final_pred_price),
301
+ xytext=(pred_timestamps[0], pred_close[0]),
302
+ arrowprops=dict(arrowstyle='->', color='green', lw=2, alpha=0.6))
303
+ else:
304
+ ax_price.annotate('', xy=(pred_timestamps[-1], final_pred_price),
305
+ xytext=(pred_timestamps[0], pred_close[0]),
306
+ arrowprops=dict(arrowstyle='->', color='red', lw=2, alpha=0.6))
307
+
308
+ # === 成交量图绘制 ===
309
+ # 计算柱状图宽度(约为时间间隔的80%)
310
+ bar_width = pd.Timedelta(minutes=config.interval_minutes * 0.8)
311
+
312
+ # 历史成交量柱状图
313
+ ax_volume.bar(hist_timestamps, hist_volume,
314
+ width=bar_width, color='#1f77b4',
315
+ alpha=0.6, label='Historical Volume')
316
+
317
+ # 预测成交量柱状图
318
+ ax_volume.bar(pred_timestamps, pred_volume,
319
+ width=bar_width, color='#ff7f0e',
320
+ alpha=0.7, label='Predicted Volume')
321
+
322
+ # === 图表格式化 ===
323
+ # 价格图设置
324
+ ax_price.set_ylabel('Price (USDT)', fontsize=12, fontweight='bold')
325
+ ax_price.grid(True, alpha=0.3, linestyle='-', linewidth=0.5)
326
+ ax_price.legend(loc='upper left', frameon=True, fancybox=True, shadow=True)
327
+ ax_price.set_facecolor('#fafafa')
328
+
329
+ # 成交量图设置
330
+ ax_volume.set_ylabel('Volume (ETH)', fontsize=12, fontweight='bold')
331
+ ax_volume.set_xlabel('Time', fontsize=12, fontweight='bold')
332
+ ax_volume.grid(True, alpha=0.3, linestyle='-', linewidth=0.5)
333
+ ax_volume.legend(loc='upper left', frameon=True, fancybox=True, shadow=True)
334
+ ax_volume.set_facecolor('#fafafa')
335
+
336
+ # 时间轴格式化(基于配置参数)
337
+ time_format = config.get_time_format()
338
+ ax_volume.xaxis.set_major_formatter(mdates.DateFormatter(time_format))
339
+
340
+ # 根据时间间隔设置刻度间隔
341
+ if config.interval_minutes <= 5: # 1m, 3m, 5m
342
+ ax_volume.xaxis.set_major_locator(mdates.HourLocator(interval=1))
343
+ elif config.interval_minutes <= 30: # 15m, 30m
344
+ ax_volume.xaxis.set_major_locator(mdates.HourLocator(interval=2))
345
+ elif config.interval_minutes <= 240: # 1h, 2h, 4h
346
+ ax_volume.xaxis.set_major_locator(mdates.HourLocator(interval=6))
347
+ elif config.interval_minutes <= 720: # 6h, 8h, 12h
348
+ ax_volume.xaxis.set_major_locator(mdates.HourLocator(interval=12))
349
+ else: # 1d
350
+ ax_volume.xaxis.set_major_locator(mdates.DayLocator(interval=1))
351
+
352
+ # 旋转时间标签
353
+ plt.setp(ax_volume.xaxis.get_majorticklabels(), rotation=45, ha='right')
354
+
355
+ # 添加分割线(历史/预测边界)
356
+ boundary_time = pred_timestamps[0]
357
+ ax_price.axvline(x=boundary_time, color='gray', linestyle=':', linewidth=2, alpha=0.8)
358
+ ax_volume.axvline(x=boundary_time, color='gray', linestyle=':', linewidth=2, alpha=0.8)
359
+
360
+ # 添加分割线标签
361
+ ax_price.text(boundary_time, ax_price.get_ylim()[1] * 0.95, 'Prediction Start',
362
+ rotation=90, ha='right', va='top', fontsize=10,
363
+ bbox=dict(boxstyle='round,pad=0.2', facecolor='white', alpha=0.8))
364
+
365
+ # 整体布局优化
366
+ plt.tight_layout()
367
+
368
+ # Save chart
369
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
370
+ filename = f"eth_usdt_prediction_{timestamp}.png"
371
+ plt.savefig(filename, dpi=300, bbox_inches='tight', facecolor='white')
372
+ print(f"Prediction chart saved as: {filename}")
373
+
374
+ # Also save SVG format (vector graphics)
375
+ svg_filename = f"eth_usdt_prediction_{timestamp}.svg"
376
+ plt.savefig(svg_filename, format='svg', bbox_inches='tight', facecolor='white')
377
+ print(f"Vector chart saved as: {svg_filename}")
378
+
379
+ # plt.show() # Commented out to avoid GUI issues
380
+ print("📊 Chart generation completed!")
381
+
382
+
383
+ def main():
384
+ print("🚀 ETH-USDT 实时预测系统启动")
385
+ print("=" * 50)
386
+
387
+ # 0. 获取配置参数
388
+ config = get_user_config()
389
+
390
+ # 1. 初始化数据获取器
391
+ print("📡 初始化数据获取器...")
392
+ fetcher = BinanceDataFetcher()
393
+
394
+ # 2. 获取实时数据
395
+ print("📊 获取ETH-USDT实时数据...")
396
+ try:
397
+ df = fetcher.get_klines(symbol="ETHUSDT", interval=config.interval, limit=config.lookback)
398
+ print(f"✅ 成功获取 {len(df)} 条数据")
399
+ print(f"📅 数据时间范围: {df['timestamps'].min()} 到 {df['timestamps'].max()}")
400
+ print(f"💰 当前价格: ${df['close'].iloc[-1]:.2f}")
401
+
402
+ # 计算24小时涨跌(根据时间间隔调整)
403
+ periods_24h = config.get_24h_periods()
404
+ if len(df) >= periods_24h:
405
+ price_24h_ago = df['close'].iloc[-periods_24h]
406
+ change_24h = ((df['close'].iloc[-1] / price_24h_ago - 1) * 100)
407
+ print(f"📈 24h涨跌: {change_24h:.2f}%")
408
+ else:
409
+ print(f"📈 数据不足24小时,无法计算24h涨跌")
410
+ except Exception as e:
411
+ print(f"❌ 数据获取失败: {e}")
412
+ return
413
+
414
+ # 3. 加载模型
415
+ print("\n🤖 加载Kronos模型...")
416
+ try:
417
+ tokenizer = KronosTokenizer.from_pretrained("NeoQuasar/Kronos-Tokenizer-base")
418
+ model = Kronos.from_pretrained("NeoQuasar/Kronos-base")
419
+ predictor = KronosPredictor(model, tokenizer, device="cpu", max_context=512)
420
+ print("✅ 模型加载成功")
421
+ except Exception as e:
422
+ print(f"❌ 模型加载失败: {e}")
423
+ return
424
+
425
+ # 4. 准备预测数据
426
+ print("\n📋 准备预测数据...")
427
+
428
+ if len(df) < config.lookback:
429
+ print(f"❌ 数据不足,需要至少{config.lookback}条数据,当前只有{len(df)}条")
430
+ return
431
+
432
+ # 选择最近的数据
433
+ recent_df = df.tail(config.lookback + config.pred_len).copy()
434
+
435
+ # 历史数据
436
+ x_df = recent_df.iloc[:config.lookback][['open', 'high', 'low', 'close', 'volume', 'amount']]
437
+ x_timestamp = recent_df.iloc[:config.lookback]['timestamps']
438
+
439
+ # 生成未来时间戳(根据配置的时间间隔)
440
+ last_time = x_timestamp.iloc[-1]
441
+ future_timestamps = pd.date_range(
442
+ start=last_time + timedelta(minutes=config.interval_minutes),
443
+ periods=config.pred_len,
444
+ freq=config.get_freq_string()
445
+ )
446
+ # 转换为pandas Series以匹配模型期望的格式
447
+ future_timestamps = pd.Series(future_timestamps)
448
+
449
+ duration_hours = config.get_prediction_duration_hours()
450
+ duration_text = f"{duration_hours:.1f}小时" if duration_hours >= 1 else f"{int(duration_hours * 60)}分钟"
451
+
452
+ print(f"📊 使用 {len(x_df)} 条历史数据")
453
+ print(f"🔮 预测未来 {config.pred_len} 个时间点({duration_text})")
454
+ print(f"⏰ 预测时间范围: {future_timestamps.iloc[0]} 到 {future_timestamps.iloc[-1]}")
455
+
456
+ # 5. 执行预测
457
+ print("\n🔮 开始预测...")
458
+ start_time = time.time()
459
+
460
+ try:
461
+ pred_df = predictor.predict(
462
+ df=x_df,
463
+ x_timestamp=x_timestamp,
464
+ y_timestamp=future_timestamps,
465
+ pred_len=config.pred_len,
466
+ T=0.8, # 降低温度以获得更稳定的预测
467
+ top_p=0.9, # 核采样
468
+ sample_count=3, # 多次采样取平均
469
+ verbose=True
470
+ )
471
+
472
+ prediction_time = time.time() - start_time
473
+ print(f"✅ 预测完成,耗时: {prediction_time:.1f}秒")
474
+
475
+ except Exception as e:
476
+ print(f"❌ 预测失败: {e}")
477
+ return
478
+
479
+ # 6. 分析预测结果
480
+ print("\n📈 预测结果分析:")
481
+ print("=" * 30)
482
+
483
+ current_price = x_df['close'].iloc[-1]
484
+ pred_prices = pred_df['close']
485
+
486
+ print(f"当前价格: ${current_price:.2f}")
487
+
488
+ # 使用配置的时间点进行���析
489
+ time_points = config.get_prediction_time_points()
490
+ for idx, time_desc in time_points:
491
+ if idx < len(pred_prices):
492
+ price = pred_prices.iloc[idx]
493
+ change_pct = ((price / current_price - 1) * 100)
494
+ print(f"{time_desc}预测: ${price:.2f} ({change_pct:+.2f}%)")
495
+
496
+ # 价格趋势分析
497
+ price_trend = "上涨" if pred_prices.iloc[-1] > current_price else "下跌"
498
+ max_price = pred_prices.max()
499
+ min_price = pred_prices.min()
500
+
501
+ print(f"\n📊 趋势分析:")
502
+ print(f"整体趋势: {price_trend}")
503
+ print(f"预测最高价: ${max_price:.2f}")
504
+ print(f"预测最低价: ${min_price:.2f}")
505
+ print(f"价格波动范围: {((max_price - min_price) / current_price * 100):.2f}%")
506
+
507
+ # 7. 可视化结果
508
+ print("\n📊 生成预测图表...")
509
+ try:
510
+ plot_prediction_with_realtime(recent_df.iloc[:config.lookback], pred_df, config, "ETH-USDT")
511
+ except Exception as e:
512
+ print(f"⚠️ 图表生成失败: {e}")
513
+
514
+ # 8. 保存预测结果
515
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
516
+ result_file = f"eth_usdt_prediction_{config.interval}_{timestamp}.csv"
517
+ pred_df.to_csv(result_file)
518
+ print(f"💾 预测结果已保存为: {result_file}")
519
+
520
+ print("\n🎉 预测完成!")
521
+
522
+
523
+ if __name__ == "__main__":
524
+ main()
examples/prediction_batch_example.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import matplotlib.pyplot as plt
3
+ import sys
4
+ sys.path.append("../")
5
+ from model import Kronos, KronosTokenizer, KronosPredictor
6
+
7
+
8
+ def plot_prediction(kline_df, pred_df):
9
+ pred_df.index = kline_df.index[-pred_df.shape[0]:]
10
+ sr_close = kline_df['close']
11
+ sr_pred_close = pred_df['close']
12
+ sr_close.name = 'Ground Truth'
13
+ sr_pred_close.name = "Prediction"
14
+
15
+ sr_volume = kline_df['volume']
16
+ sr_pred_volume = pred_df['volume']
17
+ sr_volume.name = 'Ground Truth'
18
+ sr_pred_volume.name = "Prediction"
19
+
20
+ close_df = pd.concat([sr_close, sr_pred_close], axis=1)
21
+ volume_df = pd.concat([sr_volume, sr_pred_volume], axis=1)
22
+
23
+ fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(8, 6), sharex=True)
24
+
25
+ ax1.plot(close_df['Ground Truth'], label='Ground Truth', color='blue', linewidth=1.5)
26
+ ax1.plot(close_df['Prediction'], label='Prediction', color='red', linewidth=1.5)
27
+ ax1.set_ylabel('Close Price', fontsize=14)
28
+ ax1.legend(loc='lower left', fontsize=12)
29
+ ax1.grid(True)
30
+
31
+ ax2.plot(volume_df['Ground Truth'], label='Ground Truth', color='blue', linewidth=1.5)
32
+ ax2.plot(volume_df['Prediction'], label='Prediction', color='red', linewidth=1.5)
33
+ ax2.set_ylabel('Volume', fontsize=14)
34
+ ax2.legend(loc='upper left', fontsize=12)
35
+ ax2.grid(True)
36
+
37
+ plt.tight_layout()
38
+ plt.show()
39
+
40
+
41
+ # 1. Load Model and Tokenizer
42
+ tokenizer = KronosTokenizer.from_pretrained('/home/csc/huggingface/Kronos-Tokenizer-base/')
43
+ model = Kronos.from_pretrained("/home/csc/huggingface/Kronos-base/")
44
+
45
+ # 2. Instantiate Predictor
46
+ predictor = KronosPredictor(model, tokenizer, device="cuda:0", max_context=512)
47
+
48
+ # 3. Prepare Data
49
+ df = pd.read_csv("./data/XSHG_5min_600977.csv")
50
+ df['timestamps'] = pd.to_datetime(df['timestamps'])
51
+
52
+ lookback = 400
53
+ pred_len = 120
54
+
55
+ dfs = []
56
+ xtsp = []
57
+ ytsp = []
58
+ for i in range(5):
59
+ idf = df.loc[(i*400):(i*400+lookback-1), ['open', 'high', 'low', 'close', 'volume', 'amount']]
60
+ i_x_timestamp = df.loc[(i*400):(i*400+lookback-1), 'timestamps']
61
+ i_y_timestamp = df.loc[(i*400+lookback):(i*400+lookback+pred_len-1), 'timestamps']
62
+
63
+ dfs.append(idf)
64
+ xtsp.append(i_x_timestamp)
65
+ ytsp.append(i_y_timestamp)
66
+
67
+ pred_df = predictor.predict_batch(
68
+ df_list=dfs,
69
+ x_timestamp_list=xtsp,
70
+ y_timestamp_list=ytsp,
71
+ pred_len=pred_len,
72
+ )
examples/prediction_example.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import matplotlib.pyplot as plt
3
+ import sys
4
+ import os
5
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
6
+ from model import Kronos, KronosTokenizer, KronosPredictor
7
+
8
+
9
+ def plot_prediction(kline_df, pred_df):
10
+ pred_df.index = kline_df.index[-pred_df.shape[0]:]
11
+ sr_close = kline_df['close']
12
+ sr_pred_close = pred_df['close']
13
+ sr_close.name = 'Ground Truth'
14
+ sr_pred_close.name = "Prediction"
15
+
16
+ sr_volume = kline_df['volume']
17
+ sr_pred_volume = pred_df['volume']
18
+ sr_volume.name = 'Ground Truth'
19
+ sr_pred_volume.name = "Prediction"
20
+
21
+ close_df = pd.concat([sr_close, sr_pred_close], axis=1)
22
+ volume_df = pd.concat([sr_volume, sr_pred_volume], axis=1)
23
+
24
+ fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(8, 6), sharex=True)
25
+
26
+ ax1.plot(close_df['Ground Truth'], label='Ground Truth', color='blue', linewidth=1.5)
27
+ ax1.plot(close_df['Prediction'], label='Prediction', color='red', linewidth=1.5)
28
+ ax1.set_ylabel('Close Price', fontsize=14)
29
+ ax1.legend(loc='lower left', fontsize=12)
30
+ ax1.grid(True)
31
+
32
+ ax2.plot(volume_df['Ground Truth'], label='Ground Truth', color='blue', linewidth=1.5)
33
+ ax2.plot(volume_df['Prediction'], label='Prediction', color='red', linewidth=1.5)
34
+ ax2.set_ylabel('Volume', fontsize=14)
35
+ ax2.legend(loc='upper left', fontsize=12)
36
+ ax2.grid(True)
37
+
38
+ plt.tight_layout()
39
+ plt.show()
40
+
41
+
42
+ # 1. Load Model and Tokenizer
43
+ tokenizer = KronosTokenizer.from_pretrained("NeoQuasar/Kronos-Tokenizer-base")
44
+ model = Kronos.from_pretrained("NeoQuasar/Kronos-small")
45
+
46
+ # 2. Instantiate Predictor
47
+ predictor = KronosPredictor(model, tokenizer, device="cpu", max_context=512)
48
+
49
+ # 3. Prepare Data
50
+ df = pd.read_csv("./examples/data/XSHG_5min_600977.csv")
51
+ df['timestamps'] = pd.to_datetime(df['timestamps'])
52
+
53
+ lookback = 400
54
+ pred_len = 120
55
+
56
+ x_df = df.loc[:lookback-1, ['open', 'high', 'low', 'close', 'volume', 'amount']]
57
+ x_timestamp = df.loc[:lookback-1, 'timestamps']
58
+ y_timestamp = df.loc[lookback:lookback+pred_len-1, 'timestamps']
59
+
60
+ # 4. Make Prediction
61
+ pred_df = predictor.predict(
62
+ df=x_df,
63
+ x_timestamp=x_timestamp,
64
+ y_timestamp=y_timestamp,
65
+ pred_len=pred_len,
66
+ T=1.0,
67
+ top_p=0.9,
68
+ sample_count=1,
69
+ verbose=True
70
+ )
71
+
72
+ # 5. Visualize Results
73
+ print("Forecasted Data Head:")
74
+ print(pred_df.head())
75
+
76
+ # Combine historical and forecasted data for plotting
77
+ kline_df = df.loc[:lookback+pred_len-1]
78
+
79
+ # visualize
80
+ plot_prediction(kline_df, pred_df)
81
+
examples/prediction_wo_vol_example.py ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import matplotlib.pyplot as plt
3
+ import sys
4
+ import os
5
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
6
+ from model import Kronos, KronosTokenizer, KronosPredictor
7
+
8
+
9
+ def plot_prediction(kline_df, pred_df):
10
+ pred_df.index = kline_df.index[-pred_df.shape[0]:]
11
+ sr_close = kline_df['close']
12
+ sr_pred_close = pred_df['close']
13
+ sr_close.name = 'Ground Truth'
14
+ sr_pred_close.name = "Prediction"
15
+
16
+ close_df = pd.concat([sr_close, sr_pred_close], axis=1)
17
+
18
+ fig, ax = plt.subplots(1, 1, figsize=(8, 4))
19
+
20
+ ax.plot(close_df['Ground Truth'], label='Ground Truth', color='blue', linewidth=1.5)
21
+ ax.plot(close_df['Prediction'], label='Prediction', color='red', linewidth=1.5)
22
+ ax.set_ylabel('Close Price', fontsize=14)
23
+ ax.legend(loc='lower left', fontsize=12)
24
+ ax.grid(True)
25
+
26
+ plt.tight_layout()
27
+ plt.show()
28
+
29
+
30
+ # 1. Load Model and Tokenizer
31
+ tokenizer = KronosTokenizer.from_pretrained("NeoQuasar/Kronos-Tokenizer-base")
32
+ model = Kronos.from_pretrained("NeoQuasar/Kronos-base")
33
+
34
+ # 2. Instantiate Predictor
35
+ predictor = KronosPredictor(model, tokenizer, device="cpu", max_context=512)
36
+
37
+ # 3. Prepare Data
38
+ df = pd.read_csv("./examples/data/XSHG_5min_600977.csv")
39
+ df['timestamps'] = pd.to_datetime(df['timestamps'])
40
+
41
+ lookback = 400
42
+ pred_len = 120
43
+
44
+ x_df = df.loc[:lookback-1, ['open', 'high', 'low', 'close']]
45
+ x_timestamp = df.loc[:lookback-1, 'timestamps']
46
+ y_timestamp = df.loc[lookback:lookback+pred_len-1, 'timestamps']
47
+
48
+ # 4. Make Prediction
49
+ pred_df = predictor.predict(
50
+ df=x_df,
51
+ x_timestamp=x_timestamp,
52
+ y_timestamp=y_timestamp,
53
+ pred_len=pred_len,
54
+ T=1.0,
55
+ top_p=0.9,
56
+ sample_count=1,
57
+ verbose=True
58
+ )
59
+
60
+ # 5. Visualize Results
61
+ print("Forecasted Data Head:")
62
+ print(pred_df.head())
63
+
64
+ # Combine historical and forecasted data for plotting
65
+ kline_df = df.loc[:lookback+pred_len-1]
66
+
67
+ # visualize
68
+ plot_prediction(kline_df, pred_df)
69
+
figures/backtest_result_example.png ADDED

Git LFS Details

  • SHA256: 7b86fea2ac1a8d9a1c698039e64ae397d5453179557466a91da37431f331126c
  • Pointer size: 131 Bytes
  • Size of remote file: 499 kB
figures/logo.png ADDED

Git LFS Details

  • SHA256: b4a3bb66fed73a24f74b74f15f0798d5edf1b9729ee826a0cad8e5088dedda61
  • Pointer size: 131 Bytes
  • Size of remote file: 872 kB
figures/overview.png ADDED

Git LFS Details

  • SHA256: f5b4556a39883fdd82b35515a686899a4c94495f70ab8f3fc7a7ac1e3104cc50
  • Pointer size: 132 Bytes
  • Size of remote file: 1.25 MB
figures/prediction_example.png ADDED

Git LFS Details

  • SHA256: 24ddc86256158658582687fc7cef4761f1dbb130ab8161e04957c8d178d323f9
  • Pointer size: 131 Bytes
  • Size of remote file: 194 kB
finetune/__pycache__/config.cpython-313.pyc ADDED
Binary file (4.16 kB). View file
 
finetune/config.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ class Config:
4
+ """
5
+ Configuration class for the entire project.
6
+ """
7
+
8
+ def __init__(self):
9
+ # =================================================================
10
+ # Data & Feature Parameters
11
+ # =================================================================
12
+ # TODO: Update this path to your Qlib data directory.
13
+ self.qlib_data_path = "~/.qlib/qlib_data/cn_data"
14
+ self.instrument = 'csi300'
15
+
16
+ # Overall time range for data loading from Qlib.
17
+ self.dataset_begin_time = "2011-01-01"
18
+ self.dataset_end_time = '2025-06-05'
19
+
20
+ # Sliding window parameters for creating samples.
21
+ self.lookback_window = 90 # Number of past time steps for input.
22
+ self.predict_window = 10 # Number of future time steps for prediction.
23
+ self.max_context = 512 # Maximum context length for the model.
24
+
25
+ # Features to be used from the raw data.
26
+ self.feature_list = ['open', 'high', 'low', 'close', 'vol', 'amt']
27
+ # Time-based features to be generated.
28
+ self.time_feature_list = ['minute', 'hour', 'weekday', 'day', 'month']
29
+
30
+ # =================================================================
31
+ # Dataset Splitting & Paths
32
+ # =================================================================
33
+ # Note: The validation/test set starts earlier than the training/validation set ends
34
+ # to account for the `lookback_window`.
35
+ self.train_time_range = ["2011-01-01", "2022-12-31"]
36
+ self.val_time_range = ["2022-09-01", "2024-06-30"]
37
+ self.test_time_range = ["2024-04-01", "2025-06-05"]
38
+ self.backtest_time_range = ["2024-07-01", "2025-06-05"]
39
+
40
+ # TODO: Directory to save the processed, pickled datasets.
41
+ self.dataset_path = "./data/processed_datasets"
42
+
43
+ # =================================================================
44
+ # Training Hyperparameters
45
+ # =================================================================
46
+ self.clip = 5.0 # Clipping value for normalized data to prevent outliers.
47
+
48
+ self.epochs = 30
49
+ self.log_interval = 100 # Log training status every N batches.
50
+ self.batch_size = 50 # Batch size per GPU.
51
+
52
+ # Number of samples to draw for one "epoch" of training/validation.
53
+ # This is useful for large datasets where a true epoch is too long.
54
+ self.n_train_iter = 2000 * self.batch_size
55
+ self.n_val_iter = 400 * self.batch_size
56
+
57
+ # Learning rates for different model components.
58
+ self.tokenizer_learning_rate = 2e-4
59
+ self.predictor_learning_rate = 4e-5
60
+
61
+ # Gradient accumulation to simulate a larger batch size.
62
+ self.accumulation_steps = 1
63
+
64
+ # AdamW optimizer parameters.
65
+ self.adam_beta1 = 0.9
66
+ self.adam_beta2 = 0.95
67
+ self.adam_weight_decay = 0.1
68
+
69
+ # Miscellaneous
70
+ self.seed = 100 # Global random seed for reproducibility.
71
+
72
+ # =================================================================
73
+ # Experiment Logging & Saving
74
+ # =================================================================
75
+ self.use_comet = True # Set to False if you don't want to use Comet ML
76
+ self.comet_config = {
77
+ # It is highly recommended to load secrets from environment variables
78
+ # for security purposes. Example: os.getenv("COMET_API_KEY")
79
+ "api_key": "YOUR_COMET_API_KEY",
80
+ "project_name": "Kronos-Finetune-Demo",
81
+ "workspace": "your_comet_workspace" # TODO: Change to your Comet ML workspace name
82
+ }
83
+ self.comet_tag = 'finetune_demo'
84
+ self.comet_name = 'finetune_demo'
85
+
86
+ # Base directory for saving model checkpoints and results.
87
+ # Using a general 'outputs' directory is a common practice.
88
+ self.save_path = "./outputs/models"
89
+ self.tokenizer_save_folder_name = 'finetune_tokenizer_demo'
90
+ self.predictor_save_folder_name = 'finetune_predictor_demo'
91
+ self.backtest_save_folder_name = 'finetune_backtest_demo'
92
+
93
+ # Path for backtesting results.
94
+ self.backtest_result_path = "./outputs/backtest_results"
95
+
96
+ # =================================================================
97
+ # Model & Checkpoint Paths
98
+ # =================================================================
99
+ # TODO: Update these paths to your pretrained model locations.
100
+ # These can be local paths or Hugging Face Hub model identifiers.
101
+ self.pretrained_tokenizer_path = "path/to/your/Kronos-Tokenizer-base"
102
+ self.pretrained_predictor_path = "path/to/your/Kronos-small"
103
+
104
+ # Paths to the fine-tuned models, derived from the save_path.
105
+ # These will be generated automatically during training.
106
+ self.finetuned_tokenizer_path = f"{self.save_path}/{self.tokenizer_save_folder_name}/checkpoints/best_model"
107
+ self.finetuned_predictor_path = f"{self.save_path}/{self.predictor_save_folder_name}/checkpoints/best_model"
108
+
109
+ # =================================================================
110
+ # Backtesting Parameters
111
+ # =================================================================
112
+ self.backtest_n_symbol_hold = 50 # Number of symbols to hold in the portfolio.
113
+ self.backtest_n_symbol_drop = 5 # Number of symbols to drop from the pool.
114
+ self.backtest_hold_thresh = 5 # Minimum holding period for a stock.
115
+ self.inference_T = 0.6
116
+ self.inference_top_p = 0.9
117
+ self.inference_top_k = 0
118
+ self.inference_sample_count = 5
119
+ self.backtest_batch_size = 1000
120
+ self.backtest_benchmark = self._set_benchmark(self.instrument)
121
+
122
+ def _set_benchmark(self, instrument):
123
+ dt_benchmark = {
124
+ 'csi800': "SH000906",
125
+ 'csi1000': "SH000852",
126
+ 'csi300': "SH000300",
127
+ }
128
+ if instrument in dt_benchmark:
129
+ return dt_benchmark[instrument]
130
+ else:
131
+ raise ValueError(f"Benchmark not defined for instrument: {instrument}")
finetune/dataset.py ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pickle
2
+ import random
3
+ import numpy as np
4
+ import torch
5
+ from torch.utils.data import Dataset
6
+ from config import Config
7
+
8
+
9
+ class QlibDataset(Dataset):
10
+ """
11
+ A PyTorch Dataset for handling Qlib financial time series data.
12
+
13
+ This dataset pre-computes all possible start indices for sliding windows
14
+ and then randomly samples from them during training/validation.
15
+
16
+ Args:
17
+ data_type (str): The type of dataset to load, either 'train' or 'val'.
18
+
19
+ Raises:
20
+ ValueError: If `data_type` is not 'train' or 'val'.
21
+ """
22
+
23
+ def __init__(self, data_type: str = 'train'):
24
+ self.config = Config()
25
+ if data_type not in ['train', 'val']:
26
+ raise ValueError("data_type must be 'train' or 'val'")
27
+ self.data_type = data_type
28
+
29
+ # Use a dedicated random number generator for sampling to avoid
30
+ # interfering with other random processes (e.g., in model initialization).
31
+ self.py_rng = random.Random(self.config.seed)
32
+
33
+ # Set paths and number of samples based on the data type.
34
+ if data_type == 'train':
35
+ self.data_path = f"{self.config.dataset_path}/train_data.pkl"
36
+ self.n_samples = self.config.n_train_iter
37
+ else:
38
+ self.data_path = f"{self.config.dataset_path}/val_data.pkl"
39
+ self.n_samples = self.config.n_val_iter
40
+
41
+ with open(self.data_path, 'rb') as f:
42
+ self.data = pickle.load(f)
43
+
44
+ self.window = self.config.lookback_window + self.config.predict_window + 1
45
+
46
+ self.symbols = list(self.data.keys())
47
+ self.feature_list = self.config.feature_list
48
+ self.time_feature_list = self.config.time_feature_list
49
+
50
+ # Pre-compute all possible (symbol, start_index) pairs.
51
+ self.indices = []
52
+ print(f"[{data_type.upper()}] Pre-computing sample indices...")
53
+ for symbol in self.symbols:
54
+ df = self.data[symbol].reset_index()
55
+ series_len = len(df)
56
+ num_samples = series_len - self.window + 1
57
+
58
+ if num_samples > 0:
59
+ # Generate time features and store them directly in the dataframe.
60
+ df['minute'] = df['datetime'].dt.minute
61
+ df['hour'] = df['datetime'].dt.hour
62
+ df['weekday'] = df['datetime'].dt.weekday
63
+ df['day'] = df['datetime'].dt.day
64
+ df['month'] = df['datetime'].dt.month
65
+ # Keep only necessary columns to save memory.
66
+ self.data[symbol] = df[self.feature_list + self.time_feature_list]
67
+
68
+ # Add all valid starting indices for this symbol to the global list.
69
+ for i in range(num_samples):
70
+ self.indices.append((symbol, i))
71
+
72
+ # The effective dataset size is the minimum of the configured iterations
73
+ # and the total number of available samples.
74
+ self.n_samples = min(self.n_samples, len(self.indices))
75
+ print(f"[{data_type.upper()}] Found {len(self.indices)} possible samples. Using {self.n_samples} per epoch.")
76
+
77
+ def set_epoch_seed(self, epoch: int):
78
+ """
79
+ Sets a new seed for the random sampler for each epoch. This is crucial
80
+ for reproducibility in distributed training.
81
+
82
+ Args:
83
+ epoch (int): The current epoch number.
84
+ """
85
+ epoch_seed = self.config.seed + epoch
86
+ self.py_rng.seed(epoch_seed)
87
+
88
+ def __len__(self) -> int:
89
+ """Returns the number of samples per epoch."""
90
+ return self.n_samples
91
+
92
+ def __getitem__(self, idx: int) -> tuple[torch.Tensor, torch.Tensor]:
93
+ """
94
+ Retrieves a random sample from the dataset.
95
+
96
+ Note: The `idx` argument is ignored. Instead, a random index is drawn
97
+ from the pre-computed `self.indices` list using `self.py_rng`. This
98
+ ensures random sampling over the entire dataset for each call.
99
+
100
+ Args:
101
+ idx (int): Ignored.
102
+
103
+ Returns:
104
+ tuple[torch.Tensor, torch.Tensor]: A tuple containing:
105
+ - x_tensor (torch.Tensor): The normalized feature tensor.
106
+ - x_stamp_tensor (torch.Tensor): The time feature tensor.
107
+ """
108
+ # Select a random sample from the entire pool of indices.
109
+ random_idx = self.py_rng.randint(0, len(self.indices) - 1)
110
+ symbol, start_idx = self.indices[random_idx]
111
+
112
+ # Extract the sliding window from the dataframe.
113
+ df = self.data[symbol]
114
+ end_idx = start_idx + self.window
115
+ win_df = df.iloc[start_idx:end_idx]
116
+
117
+ # Separate main features and time features.
118
+ x = win_df[self.feature_list].values.astype(np.float32)
119
+ x_stamp = win_df[self.time_feature_list].values.astype(np.float32)
120
+
121
+ # Perform instance-level normalization.
122
+ x_mean, x_std = np.mean(x, axis=0), np.std(x, axis=0)
123
+ x = (x - x_mean) / (x_std + 1e-5)
124
+ x = np.clip(x, -self.config.clip, self.config.clip)
125
+
126
+ # Convert to PyTorch tensors.
127
+ x_tensor = torch.from_numpy(x)
128
+ x_stamp_tensor = torch.from_numpy(x_stamp)
129
+
130
+ return x_tensor, x_stamp_tensor
131
+
132
+
133
+ if __name__ == '__main__':
134
+ # Example usage and verification.
135
+ print("Creating training dataset instance...")
136
+ train_dataset = QlibDataset(data_type='train')
137
+
138
+ print(f"Dataset length: {len(train_dataset)}")
139
+
140
+ if len(train_dataset) > 0:
141
+ try_x, try_x_stamp = train_dataset[100] # Index 100 is ignored.
142
+ print(f"Sample feature shape: {try_x.shape}")
143
+ print(f"Sample time feature shape: {try_x_stamp.shape}")
144
+ else:
145
+ print("Dataset is empty.")
finetune/qlib_data_preprocess.py ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import pickle
3
+ import numpy as np
4
+ import pandas as pd
5
+ import qlib
6
+ from qlib.config import REG_CN
7
+ from qlib.data import D
8
+ from qlib.data.dataset.loader import QlibDataLoader
9
+ from tqdm import trange
10
+
11
+ from config import Config
12
+
13
+
14
+ class QlibDataPreprocessor:
15
+ """
16
+ A class to handle the loading, processing, and splitting of Qlib financial data.
17
+ """
18
+
19
+ def __init__(self):
20
+ """Initializes the preprocessor with configuration and data fields."""
21
+ self.config = Config()
22
+ self.data_fields = ['open', 'close', 'high', 'low', 'volume', 'vwap']
23
+ self.data = {} # A dictionary to store processed data for each symbol.
24
+
25
+ def initialize_qlib(self):
26
+ """Initializes the Qlib environment."""
27
+ print("Initializing Qlib...")
28
+ qlib.init(provider_uri=self.config.qlib_data_path, region=REG_CN)
29
+
30
+ def load_qlib_data(self):
31
+ """
32
+ Loads raw data from Qlib, processes it symbol by symbol, and stores
33
+ it in the `self.data` attribute.
34
+ """
35
+ print("Loading and processing data from Qlib...")
36
+ data_fields_qlib = ['$' + f for f in self.data_fields]
37
+ cal: np.ndarray = D.calendar()
38
+
39
+ # Determine the actual start and end times to load, including buffer for lookback and predict windows.
40
+ start_index = cal.searchsorted(pd.Timestamp(self.config.dataset_begin_time))
41
+ end_index = cal.searchsorted(pd.Timestamp(self.config.dataset_end_time))
42
+
43
+ # Check if start_index lookbackw_window will cause negative index
44
+ adjusted_start_index = max(start_index - self.config.lookback_window, 0)
45
+ real_start_time = cal[adjusted_start_index]
46
+
47
+ # Check if end_index exceeds the range of the array
48
+ if end_index >= len(cal):
49
+ end_index = len(cal) - 1
50
+ elif cal[end_index] != pd.Timestamp(self.config.dataset_end_time):
51
+ end_index -= 1
52
+
53
+ # Check if end_index+predictw_window will exceed the range of the array
54
+ adjusted_end_index = min(end_index + self.config.predict_window, len(cal) - 1)
55
+ real_end_time = cal[adjusted_end_index]
56
+
57
+ # Load data using Qlib's data loader.
58
+ data_df = QlibDataLoader(config=data_fields_qlib).load(
59
+ self.config.instrument, real_start_time, real_end_time
60
+ )
61
+ data_df = data_df.stack().unstack(level=1) # Reshape for easier access.
62
+
63
+ symbol_list = list(data_df.columns)
64
+ for i in trange(len(symbol_list), desc="Processing Symbols"):
65
+ symbol = symbol_list[i]
66
+ symbol_df = data_df[symbol]
67
+
68
+ # Pivot the table to have features as columns and datetime as index.
69
+ symbol_df = symbol_df.reset_index().rename(columns={'level_1': 'field'})
70
+ symbol_df = pd.pivot(symbol_df, index='datetime', columns='field', values=symbol)
71
+ symbol_df = symbol_df.rename(columns={f'${field}': field for field in self.data_fields})
72
+
73
+ # Calculate amount and select final features.
74
+ symbol_df['vol'] = symbol_df['volume']
75
+ symbol_df['amt'] = (symbol_df['open'] + symbol_df['high'] + symbol_df['low'] + symbol_df['close']) / 4 * symbol_df['vol']
76
+ symbol_df = symbol_df[self.config.feature_list]
77
+
78
+ # Filter out symbols with insufficient data.
79
+ symbol_df = symbol_df.dropna()
80
+ if len(symbol_df) < self.config.lookback_window + self.config.predict_window + 1:
81
+ continue
82
+
83
+ self.data[symbol] = symbol_df
84
+
85
+ def prepare_dataset(self):
86
+ """
87
+ Splits the loaded data into train, validation, and test sets and saves them to disk.
88
+ """
89
+ print("Splitting data into train, validation, and test sets...")
90
+ train_data, val_data, test_data = {}, {}, {}
91
+
92
+ symbol_list = list(self.data.keys())
93
+ for i in trange(len(symbol_list), desc="Preparing Datasets"):
94
+ symbol = symbol_list[i]
95
+ symbol_df = self.data[symbol]
96
+
97
+ # Define time ranges from config.
98
+ train_start, train_end = self.config.train_time_range
99
+ val_start, val_end = self.config.val_time_range
100
+ test_start, test_end = self.config.test_time_range
101
+
102
+ # Create boolean masks for each dataset split.
103
+ train_mask = (symbol_df.index >= train_start) & (symbol_df.index <= train_end)
104
+ val_mask = (symbol_df.index >= val_start) & (symbol_df.index <= val_end)
105
+ test_mask = (symbol_df.index >= test_start) & (symbol_df.index <= test_end)
106
+
107
+ # Apply masks to create the final datasets.
108
+ train_data[symbol] = symbol_df[train_mask]
109
+ val_data[symbol] = symbol_df[val_mask]
110
+ test_data[symbol] = symbol_df[test_mask]
111
+
112
+ # Save the datasets using pickle.
113
+ os.makedirs(self.config.dataset_path, exist_ok=True)
114
+ with open(f"{self.config.dataset_path}/train_data.pkl", 'wb') as f:
115
+ pickle.dump(train_data, f)
116
+ with open(f"{self.config.dataset_path}/val_data.pkl", 'wb') as f:
117
+ pickle.dump(val_data, f)
118
+ with open(f"{self.config.dataset_path}/test_data.pkl", 'wb') as f:
119
+ pickle.dump(test_data, f)
120
+
121
+ print("Datasets prepared and saved successfully.")
122
+
123
+
124
+ if __name__ == '__main__':
125
+ # This block allows the script to be run directly to perform data preprocessing.
126
+ preprocessor = QlibDataPreprocessor()
127
+ preprocessor.initialize_qlib()
128
+ preprocessor.load_qlib_data()
129
+ preprocessor.prepare_dataset()
130
+
finetune/qlib_test.py ADDED
@@ -0,0 +1,358 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import argparse
4
+ import pickle
5
+ from collections import defaultdict
6
+
7
+ import numpy as np
8
+ import pandas as pd
9
+ import torch
10
+ from torch.utils.data import Dataset, DataLoader
11
+ from tqdm import trange, tqdm
12
+ from matplotlib import pyplot as plt
13
+
14
+ import qlib
15
+ from qlib.config import REG_CN
16
+ from qlib.backtest import backtest, executor, CommonInfrastructure
17
+ from qlib.contrib.evaluate import risk_analysis
18
+ from qlib.contrib.strategy import TopkDropoutStrategy
19
+ from qlib.utils import flatten_dict
20
+ from qlib.utils.time import Freq
21
+
22
+ # Ensure project root is in the Python path
23
+ sys.path.append("../")
24
+ from config import Config
25
+ from model.kronos import Kronos, KronosTokenizer, auto_regressive_inference
26
+
27
+
28
+ # =================================================================================
29
+ # 1. Data Loading and Processing for Inference
30
+ # =================================================================================
31
+
32
+ class QlibTestDataset(Dataset):
33
+ """
34
+ PyTorch Dataset for handling Qlib test data, specifically for inference.
35
+
36
+ This dataset iterates through all possible sliding windows sequentially. It also
37
+ yields metadata like symbol and timestamp, which are crucial for mapping
38
+ predictions back to the original time series.
39
+ """
40
+
41
+ def __init__(self, data: dict, config: Config):
42
+ self.data = data
43
+ self.config = config
44
+ self.window_size = config.lookback_window + config.predict_window
45
+ self.symbols = list(self.data.keys())
46
+ self.feature_list = config.feature_list
47
+ self.time_feature_list = config.time_feature_list
48
+ self.indices = []
49
+
50
+ print("Preprocessing and building indices for test dataset...")
51
+ for symbol in self.symbols:
52
+ df = self.data[symbol].reset_index()
53
+ # Generate time features on-the-fly
54
+ df['minute'] = df['datetime'].dt.minute
55
+ df['hour'] = df['datetime'].dt.hour
56
+ df['weekday'] = df['datetime'].dt.weekday
57
+ df['day'] = df['datetime'].dt.day
58
+ df['month'] = df['datetime'].dt.month
59
+ self.data[symbol] = df # Store preprocessed dataframe
60
+
61
+ num_samples = len(df) - self.window_size + 1
62
+ if num_samples > 0:
63
+ for i in range(num_samples):
64
+ timestamp = df.iloc[i + self.config.lookback_window - 1]['datetime']
65
+ self.indices.append((symbol, i, timestamp))
66
+
67
+ def __len__(self) -> int:
68
+ return len(self.indices)
69
+
70
+ def __getitem__(self, idx: int):
71
+ symbol, start_idx, timestamp = self.indices[idx]
72
+ df = self.data[symbol]
73
+
74
+ context_end = start_idx + self.config.lookback_window
75
+ predict_end = context_end + self.config.predict_window
76
+
77
+ context_df = df.iloc[start_idx:context_end]
78
+ predict_df = df.iloc[context_end:predict_end]
79
+
80
+ x = context_df[self.feature_list].values.astype(np.float32)
81
+ x_stamp = context_df[self.time_feature_list].values.astype(np.float32)
82
+ y_stamp = predict_df[self.time_feature_list].values.astype(np.float32)
83
+
84
+ # Instance-level normalization, consistent with training
85
+ x_mean, x_std = np.mean(x, axis=0), np.std(x, axis=0)
86
+ x = (x - x_mean) / (x_std + 1e-5)
87
+ x = np.clip(x, -self.config.clip, self.config.clip)
88
+
89
+ return torch.from_numpy(x), torch.from_numpy(x_stamp), torch.from_numpy(y_stamp), symbol, timestamp
90
+
91
+
92
+ # =================================================================================
93
+ # 2. Backtesting Logic
94
+ # =================================================================================
95
+
96
+ class QlibBacktest:
97
+ """
98
+ A wrapper class for conducting backtesting experiments using Qlib.
99
+ """
100
+
101
+ def __init__(self, config: Config):
102
+ self.config = config
103
+ self.initialize_qlib()
104
+
105
+ def initialize_qlib(self):
106
+ """Initializes the Qlib environment."""
107
+ print("Initializing Qlib for backtesting...")
108
+ qlib.init(provider_uri=self.config.qlib_data_path, region=REG_CN)
109
+
110
+ def run_single_backtest(self, signal_series: pd.Series) -> pd.DataFrame:
111
+ """
112
+ Runs a single backtest for a given prediction signal.
113
+
114
+ Args:
115
+ signal_series (pd.Series): A pandas Series with a MultiIndex
116
+ (instrument, datetime) and prediction scores.
117
+ Returns:
118
+ pd.DataFrame: A DataFrame containing the performance report.
119
+ """
120
+ strategy = TopkDropoutStrategy(
121
+ topk=self.config.backtest_n_symbol_hold,
122
+ n_drop=self.config.backtest_n_symbol_drop,
123
+ hold_thresh=self.config.backtest_hold_thresh,
124
+ signal=signal_series,
125
+ )
126
+ executor_config = {
127
+ "time_per_step": "day",
128
+ "generate_portfolio_metrics": True,
129
+ "delay_execution": True,
130
+ }
131
+ backtest_config = {
132
+ "start_time": self.config.backtest_time_range[0],
133
+ "end_time": self.config.backtest_time_range[1],
134
+ "account": 100_000_000,
135
+ "benchmark": self.config.backtest_benchmark,
136
+ "exchange_kwargs": {
137
+ "freq": "day", "limit_threshold": 0.095, "deal_price": "open",
138
+ "open_cost": 0.001, "close_cost": 0.0015, "min_cost": 5,
139
+ },
140
+ "executor": executor.SimulatorExecutor(**executor_config),
141
+ }
142
+
143
+ portfolio_metric_dict, _ = backtest(strategy=strategy, **backtest_config)
144
+ analysis_freq = "{0}{1}".format(*Freq.parse("day"))
145
+ report, _ = portfolio_metric_dict.get(analysis_freq)
146
+
147
+ # --- Analysis and Reporting ---
148
+ analysis = {
149
+ "excess_return_without_cost": risk_analysis(report["return"] - report["bench"], freq=analysis_freq),
150
+ "excess_return_with_cost": risk_analysis(report["return"] - report["bench"] - report["cost"], freq=analysis_freq),
151
+ }
152
+ print("\n--- Backtest Analysis ---")
153
+ print("Benchmark Return:", risk_analysis(report["bench"], freq=analysis_freq), sep='\n')
154
+ print("\nExcess Return (w/o cost):", analysis["excess_return_without_cost"], sep='\n')
155
+ print("\nExcess Return (w/ cost):", analysis["excess_return_with_cost"], sep='\n')
156
+
157
+ report_df = pd.DataFrame({
158
+ "cum_bench": report["bench"].cumsum(),
159
+ "cum_return_w_cost": (report["return"] - report["cost"]).cumsum(),
160
+ "cum_ex_return_w_cost": (report["return"] - report["bench"] - report["cost"]).cumsum(),
161
+ })
162
+ return report_df
163
+
164
+ def run_and_plot_results(self, signals: dict[str, pd.DataFrame]):
165
+ """
166
+ Runs backtests for multiple signals and plots the cumulative return curves.
167
+
168
+ Args:
169
+ signals (dict[str, pd.DataFrame]): A dictionary where keys are signal names
170
+ and values are prediction DataFrames.
171
+ """
172
+ return_df, ex_return_df, bench_df = pd.DataFrame(), pd.DataFrame(), pd.DataFrame()
173
+
174
+ for signal_name, pred_df in signals.items():
175
+ print(f"\nBacktesting signal: {signal_name}...")
176
+ pred_series = pred_df.stack()
177
+ pred_series.index.names = ['datetime', 'instrument']
178
+ pred_series = pred_series.swaplevel().sort_index()
179
+ report_df = self.run_single_backtest(pred_series)
180
+
181
+ return_df[signal_name] = report_df['cum_return_w_cost']
182
+ ex_return_df[signal_name] = report_df['cum_ex_return_w_cost']
183
+ if 'return' not in bench_df:
184
+ bench_df['return'] = report_df['cum_bench']
185
+
186
+ # Plotting results
187
+ fig, axes = plt.subplots(2, 1, figsize=(12, 8), sharex=True)
188
+ return_df.plot(ax=axes[0], title='Cumulative Return with Cost', grid=True)
189
+ axes[0].plot(bench_df['return'], label=self.config.instrument.upper(), color='black', linestyle='--')
190
+ axes[0].legend()
191
+ axes[0].set_ylabel("Cumulative Return")
192
+
193
+ ex_return_df.plot(ax=axes[1], title='Cumulative Excess Return with Cost', grid=True)
194
+ axes[1].legend()
195
+ axes[1].set_xlabel("Date")
196
+ axes[1].set_ylabel("Cumulative Excess Return")
197
+
198
+ plt.tight_layout()
199
+ plt.savefig("../figures/backtest_result_example.png", dpi=200)
200
+ plt.show()
201
+
202
+
203
+ # =================================================================================
204
+ # 3. Inference Logic
205
+ # =================================================================================
206
+
207
+ def load_models(config: dict) -> tuple[KronosTokenizer, Kronos]:
208
+ """Loads the fine-tuned tokenizer and predictor model."""
209
+ device = torch.device(config['device'])
210
+ print(f"Loading models onto device: {device}...")
211
+ tokenizer = KronosTokenizer.from_pretrained(config['tokenizer_path']).to(device).eval()
212
+ model = Kronos.from_pretrained(config['model_path']).to(device).eval()
213
+ return tokenizer, model
214
+
215
+
216
+ def collate_fn_for_inference(batch):
217
+ """
218
+ Custom collate function to handle batches containing Tensors, strings, and Timestamps.
219
+
220
+ Args:
221
+ batch (list): A list of samples, where each sample is the tuple returned by
222
+ QlibTestDataset.__getitem__.
223
+
224
+ Returns:
225
+ A single tuple containing the batched data.
226
+ """
227
+ # Unzip the list of samples into separate lists for each data type
228
+ x, x_stamp, y_stamp, symbols, timestamps = zip(*batch)
229
+
230
+ # Stack the tensors to create a batch
231
+ x_batch = torch.stack(x, dim=0)
232
+ x_stamp_batch = torch.stack(x_stamp, dim=0)
233
+ y_stamp_batch = torch.stack(y_stamp, dim=0)
234
+
235
+ # Return the strings and timestamps as lists
236
+ return x_batch, x_stamp_batch, y_stamp_batch, list(symbols), list(timestamps)
237
+
238
+
239
+ def generate_predictions(config: dict, test_data: dict) -> dict[str, pd.DataFrame]:
240
+ """
241
+ Runs inference on the test dataset to generate prediction signals.
242
+
243
+ Args:
244
+ config (dict): A dictionary containing inference parameters.
245
+ test_data (dict): The raw test data loaded from a pickle file.
246
+
247
+ Returns:
248
+ A dictionary where keys are signal types (e.g., 'mean', 'last') and
249
+ values are DataFrames of predictions (datetime index, symbol columns).
250
+ """
251
+ tokenizer, model = load_models(config)
252
+ device = torch.device(config['device'])
253
+
254
+ # Use the Dataset and DataLoader for efficient batching and processing
255
+ dataset = QlibTestDataset(data=test_data, config=Config())
256
+ loader = DataLoader(
257
+ dataset,
258
+ batch_size=config['batch_size'] // config['sample_count'],
259
+ shuffle=False,
260
+ num_workers=os.cpu_count() // 2,
261
+ collate_fn=collate_fn_for_inference
262
+ )
263
+
264
+ results = defaultdict(list)
265
+ with torch.no_grad():
266
+ for x, x_stamp, y_stamp, symbols, timestamps in tqdm(loader, desc="Inference"):
267
+ preds = auto_regressive_inference(
268
+ tokenizer, model, x.to(device), x_stamp.to(device), y_stamp.to(device),
269
+ max_context=config['max_context'], pred_len=config['pred_len'], clip=config['clip'],
270
+ T=config['T'], top_k=config['top_k'], top_p=config['top_p'], sample_count=config['sample_count']
271
+ )
272
+
273
+ # The 'close' price is at index 3 in `feature_list`
274
+ last_day_close = x[:, -1, 3].numpy()
275
+ signals = {
276
+ 'last': preds[:, -1, 3] - last_day_close,
277
+ 'mean': np.mean(preds[:, :, 3], axis=1) - last_day_close,
278
+ 'max': np.max(preds[:, :, 3], axis=1) - last_day_close,
279
+ 'min': np.min(preds[:, :, 3], axis=1) - last_day_close,
280
+ }
281
+
282
+ for i in range(len(symbols)):
283
+ for sig_type, sig_values in signals.items():
284
+ results[sig_type].append((timestamps[i], symbols[i], sig_values[i]))
285
+
286
+ print("Post-processing predictions into DataFrames...")
287
+ prediction_dfs = {}
288
+ for sig_type, records in results.items():
289
+ df = pd.DataFrame(records, columns=['datetime', 'instrument', 'score'])
290
+ pivot_df = df.pivot_table(index='datetime', columns='instrument', values='score')
291
+ prediction_dfs[sig_type] = pivot_df.sort_index()
292
+
293
+ return prediction_dfs
294
+
295
+
296
+ # =================================================================================
297
+ # 4. Main Execution
298
+ # =================================================================================
299
+
300
+ def main():
301
+ """Main function to set up config, run inference, and execute backtesting."""
302
+ parser = argparse.ArgumentParser(description="Run Kronos Inference and Backtesting")
303
+ parser.add_argument("--device", type=str, default="cuda:1", help="Device for inference (e.g., 'cuda:0', 'cpu')")
304
+ args = parser.parse_args()
305
+
306
+ # --- 1. Configuration Setup ---
307
+ base_config = Config()
308
+
309
+ # Create a dedicated dictionary for this run's configuration
310
+ run_config = {
311
+ 'device': args.device,
312
+ 'data_path': base_config.dataset_path,
313
+ 'result_save_path': base_config.backtest_result_path,
314
+ 'result_name': base_config.backtest_save_folder_name,
315
+ 'tokenizer_path': base_config.finetuned_tokenizer_path,
316
+ 'model_path': base_config.finetuned_predictor_path,
317
+ 'max_context': base_config.max_context,
318
+ 'pred_len': base_config.predict_window,
319
+ 'clip': base_config.clip,
320
+ 'T': base_config.inference_T,
321
+ 'top_k': base_config.inference_top_k,
322
+ 'top_p': base_config.inference_top_p,
323
+ 'sample_count': base_config.inference_sample_count,
324
+ 'batch_size': base_config.backtest_batch_size,
325
+ }
326
+
327
+ print("--- Running with Configuration ---")
328
+ for key, val in run_config.items():
329
+ print(f"{key:>20}: {val}")
330
+ print("-" * 35)
331
+
332
+ # --- 2. Load Data ---
333
+ test_data_path = os.path.join(run_config['data_path'], "test_data.pkl")
334
+ print(f"Loading test data from {test_data_path}...")
335
+ with open(test_data_path, 'rb') as f:
336
+ test_data = pickle.load(f)
337
+ print(test_data)
338
+ # --- 3. Generate Predictions ---
339
+ model_preds = generate_predictions(run_config, test_data)
340
+
341
+ # --- 4. Save Predictions ---
342
+ save_dir = os.path.join(run_config['result_save_path'], run_config['result_name'])
343
+ os.makedirs(save_dir, exist_ok=True)
344
+ predictions_file = os.path.join(save_dir, "predictions.pkl")
345
+ print(f"Saving prediction signals to {predictions_file}...")
346
+ with open(predictions_file, 'wb') as f:
347
+ pickle.dump(model_preds, f)
348
+
349
+ # --- 5. Run Backtesting ---
350
+ with open(predictions_file, 'rb') as f:
351
+ model_preds = pickle.load(f)
352
+
353
+ backtester = QlibBacktest(base_config)
354
+ backtester.run_and_plot_results(model_preds)
355
+
356
+
357
+ if __name__ == '__main__':
358
+ main()
finetune/train_predictor.py ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import json
4
+ import time
5
+ from time import gmtime, strftime
6
+ import torch.distributed as dist
7
+ import torch
8
+ from torch.utils.data import DataLoader
9
+ from torch.utils.data.distributed import DistributedSampler
10
+ from torch.nn.parallel import DistributedDataParallel as DDP
11
+
12
+ import comet_ml
13
+
14
+ # Ensure project root is in path
15
+ sys.path.append('../')
16
+ from config import Config
17
+ from dataset import QlibDataset
18
+ from model.kronos import KronosTokenizer, Kronos
19
+ # Import shared utilities
20
+ from utils.training_utils import (
21
+ setup_ddp,
22
+ cleanup_ddp,
23
+ set_seed,
24
+ get_model_size,
25
+ format_time
26
+ )
27
+
28
+
29
+ def create_dataloaders(config: dict, rank: int, world_size: int):
30
+ """
31
+ Creates and returns distributed dataloaders for training and validation.
32
+
33
+ Args:
34
+ config (dict): A dictionary of configuration parameters.
35
+ rank (int): The global rank of the current process.
36
+ world_size (int): The total number of processes.
37
+
38
+ Returns:
39
+ tuple: (train_loader, val_loader, train_dataset, valid_dataset).
40
+ """
41
+ print(f"[Rank {rank}] Creating distributed dataloaders...")
42
+ train_dataset = QlibDataset('train')
43
+ valid_dataset = QlibDataset('val')
44
+ print(f"[Rank {rank}] Train dataset size: {len(train_dataset)}, Validation dataset size: {len(valid_dataset)}")
45
+
46
+ train_sampler = DistributedSampler(train_dataset, num_replicas=world_size, rank=rank, shuffle=True)
47
+ val_sampler = DistributedSampler(valid_dataset, num_replicas=world_size, rank=rank, shuffle=False)
48
+
49
+ train_loader = DataLoader(
50
+ train_dataset, batch_size=config['batch_size'], sampler=train_sampler,
51
+ num_workers=config.get('num_workers', 2), pin_memory=True, drop_last=True
52
+ )
53
+ val_loader = DataLoader(
54
+ valid_dataset, batch_size=config['batch_size'], sampler=val_sampler,
55
+ num_workers=config.get('num_workers', 2), pin_memory=True, drop_last=False
56
+ )
57
+ return train_loader, val_loader, train_dataset, valid_dataset
58
+
59
+
60
+ def train_model(model, tokenizer, device, config, save_dir, logger, rank, world_size):
61
+ """
62
+ The main training and validation loop for the predictor.
63
+ """
64
+ start_time = time.time()
65
+ if rank == 0:
66
+ effective_bs = config['batch_size'] * world_size
67
+ print(f"Effective BATCHSIZE per GPU: {config['batch_size']}, Total: {effective_bs}")
68
+
69
+ train_loader, val_loader, train_dataset, valid_dataset = create_dataloaders(config, rank, world_size)
70
+
71
+ optimizer = torch.optim.AdamW(
72
+ model.parameters(),
73
+ lr=config['predictor_learning_rate'],
74
+ betas=(config['adam_beta1'], config['adam_beta2']),
75
+ weight_decay=config['adam_weight_decay']
76
+ )
77
+ scheduler = torch.optim.lr_scheduler.OneCycleLR(
78
+ optimizer, max_lr=config['predictor_learning_rate'],
79
+ steps_per_epoch=len(train_loader), epochs=config['epochs'],
80
+ pct_start=0.03, div_factor=10
81
+ )
82
+
83
+ best_val_loss = float('inf')
84
+ dt_result = {}
85
+ batch_idx_global = 0
86
+
87
+ for epoch_idx in range(config['epochs']):
88
+ epoch_start_time = time.time()
89
+ model.train()
90
+ train_loader.sampler.set_epoch(epoch_idx)
91
+
92
+ train_dataset.set_epoch_seed(epoch_idx * 10000 + rank)
93
+ valid_dataset.set_epoch_seed(0)
94
+
95
+ for i, (batch_x, batch_x_stamp) in enumerate(train_loader):
96
+ batch_x = batch_x.squeeze(0).to(device, non_blocking=True)
97
+ batch_x_stamp = batch_x_stamp.squeeze(0).to(device, non_blocking=True)
98
+
99
+ # Tokenize input data on-the-fly
100
+ with torch.no_grad():
101
+ token_seq_0, token_seq_1 = tokenizer.encode(batch_x, half=True)
102
+
103
+ # Prepare inputs and targets for the language model
104
+ token_in = [token_seq_0[:, :-1], token_seq_1[:, :-1]]
105
+ token_out = [token_seq_0[:, 1:], token_seq_1[:, 1:]]
106
+
107
+ # Forward pass and loss calculation
108
+ logits = model(token_in[0], token_in[1], batch_x_stamp[:, :-1, :])
109
+ loss, s1_loss, s2_loss = model.module.head.compute_loss(logits[0], logits[1], token_out[0], token_out[1])
110
+
111
+ # Backward pass and optimization
112
+ optimizer.zero_grad()
113
+ loss.backward()
114
+ torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=3.0)
115
+ optimizer.step()
116
+ scheduler.step()
117
+
118
+ # Logging (Master Process Only)
119
+ if rank == 0 and (batch_idx_global + 1) % config['log_interval'] == 0:
120
+ lr = optimizer.param_groups[0]['lr']
121
+ print(
122
+ f"[Rank {rank}, Epoch {epoch_idx + 1}/{config['epochs']}, Step {i + 1}/{len(train_loader)}] "
123
+ f"LR {lr:.6f}, Loss: {loss.item():.4f}"
124
+ )
125
+ if rank == 0 and logger:
126
+ lr = optimizer.param_groups[0]['lr']
127
+ logger.log_metric('train_predictor_loss_batch', loss.item(), step=batch_idx_global)
128
+ logger.log_metric('train_S1_loss_each_batch', s1_loss.item(), step=batch_idx_global)
129
+ logger.log_metric('train_S2_loss_each_batch', s2_loss.item(), step=batch_idx_global)
130
+ logger.log_metric('predictor_learning_rate', lr, step=batch_idx_global)
131
+
132
+ batch_idx_global += 1
133
+
134
+ # --- Validation Loop ---
135
+ model.eval()
136
+ tot_val_loss_sum_rank = 0.0
137
+ val_batches_processed_rank = 0
138
+ with torch.no_grad():
139
+ for batch_x, batch_x_stamp in val_loader:
140
+ batch_x = batch_x.squeeze(0).to(device, non_blocking=True)
141
+ batch_x_stamp = batch_x_stamp.squeeze(0).to(device, non_blocking=True)
142
+
143
+ token_seq_0, token_seq_1 = tokenizer.encode(batch_x, half=True)
144
+ token_in = [token_seq_0[:, :-1], token_seq_1[:, :-1]]
145
+ token_out = [token_seq_0[:, 1:], token_seq_1[:, 1:]]
146
+
147
+ logits = model(token_in[0], token_in[1], batch_x_stamp[:, :-1, :])
148
+ val_loss, _, _ = model.module.head.compute_loss(logits[0], logits[1], token_out[0], token_out[1])
149
+
150
+ tot_val_loss_sum_rank += val_loss.item()
151
+ val_batches_processed_rank += 1
152
+
153
+ # Reduce validation metrics
154
+ val_loss_sum_tensor = torch.tensor(tot_val_loss_sum_rank, device=device)
155
+ val_batches_tensor = torch.tensor(val_batches_processed_rank, device=device)
156
+ dist.all_reduce(val_loss_sum_tensor, op=dist.ReduceOp.SUM)
157
+ dist.all_reduce(val_batches_tensor, op=dist.ReduceOp.SUM)
158
+
159
+ avg_val_loss = val_loss_sum_tensor.item() / val_batches_tensor.item() if val_batches_tensor.item() > 0 else 0
160
+
161
+ # --- End of Epoch Summary & Checkpointing (Master Process Only) ---
162
+ if rank == 0:
163
+ print(f"\n--- Epoch {epoch_idx + 1}/{config['epochs']} Summary ---")
164
+ print(f"Validation Loss: {avg_val_loss:.4f}")
165
+ print(f"Time This Epoch: {format_time(time.time() - epoch_start_time)}")
166
+ print(f"Total Time Elapsed: {format_time(time.time() - start_time)}\n")
167
+ if logger:
168
+ logger.log_metric('val_predictor_loss_epoch', avg_val_loss, epoch=epoch_idx)
169
+
170
+ if avg_val_loss < best_val_loss:
171
+ best_val_loss = avg_val_loss
172
+ save_path = f"{save_dir}/checkpoints/best_model"
173
+ model.module.save_pretrained(save_path)
174
+ print(f"Best model saved to {save_path} (Val Loss: {best_val_loss:.4f})")
175
+
176
+ dist.barrier()
177
+
178
+ dt_result['best_val_loss'] = best_val_loss
179
+ return dt_result
180
+
181
+
182
+ def main(config: dict):
183
+ """Main function to orchestrate the DDP training process."""
184
+ rank, world_size, local_rank = setup_ddp()
185
+ device = torch.device(f"cuda:{local_rank}")
186
+ set_seed(config['seed'], rank)
187
+
188
+ save_dir = os.path.join(config['save_path'], config['predictor_save_folder_name'])
189
+
190
+ # Logger and summary setup (master process only)
191
+ comet_logger, master_summary = None, {}
192
+ if rank == 0:
193
+ os.makedirs(os.path.join(save_dir, 'checkpoints'), exist_ok=True)
194
+ master_summary = {
195
+ 'start_time': strftime("%Y-%m-%dT%H-%M-%S", gmtime()),
196
+ 'save_directory': save_dir,
197
+ 'world_size': world_size,
198
+ }
199
+ if config['use_comet']:
200
+ comet_logger = comet_ml.Experiment(
201
+ api_key=config['comet_config']['api_key'],
202
+ project_name=config['comet_config']['project_name'],
203
+ workspace=config['comet_config']['workspace'],
204
+ )
205
+ comet_logger.add_tag(config['comet_tag'])
206
+ comet_logger.set_name(config['comet_name'])
207
+ comet_logger.log_parameters(config)
208
+ print("Comet Logger Initialized.")
209
+
210
+ dist.barrier()
211
+
212
+ # Model Initialization
213
+ tokenizer = KronosTokenizer.from_pretrained(config['finetuned_tokenizer_path'])
214
+ tokenizer.eval().to(device)
215
+
216
+ model = Kronos.from_pretrained(config['pretrained_predictor_path'])
217
+ model.to(device)
218
+ model = DDP(model, device_ids=[local_rank], find_unused_parameters=False)
219
+
220
+ if rank == 0:
221
+ print(f"Predictor Model Size: {get_model_size(model.module)}")
222
+
223
+ # Start Training
224
+ dt_result = train_model(
225
+ model, tokenizer, device, config, save_dir, comet_logger, rank, world_size
226
+ )
227
+
228
+ if rank == 0:
229
+ master_summary['final_result'] = dt_result
230
+ with open(os.path.join(save_dir, 'summary.json'), 'w') as f:
231
+ json.dump(master_summary, f, indent=4)
232
+ print('Training finished. Summary file saved.')
233
+ if comet_logger: comet_logger.end()
234
+
235
+ cleanup_ddp()
236
+
237
+
238
+ if __name__ == '__main__':
239
+ # Usage: torchrun --standalone --nproc_per_node=NUM_GPUS train_predictor.py
240
+ if "WORLD_SIZE" not in os.environ:
241
+ raise RuntimeError("This script must be launched with `torchrun`.")
242
+
243
+ config_instance = Config()
244
+ main(config_instance.__dict__)
finetune/train_tokenizer.py ADDED
@@ -0,0 +1,281 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import json
4
+ import time
5
+ from time import gmtime, strftime
6
+ import argparse
7
+ import datetime
8
+ import torch.distributed as dist
9
+ import torch
10
+ import torch.nn.functional as F
11
+ from torch.utils.data import DataLoader
12
+ from torch.utils.data.distributed import DistributedSampler
13
+ from torch.nn.parallel import DistributedDataParallel as DDP
14
+
15
+ import comet_ml
16
+
17
+ # Ensure project root is in path
18
+ sys.path.append("../")
19
+ from config import Config
20
+ from dataset import QlibDataset
21
+ from model.kronos import KronosTokenizer
22
+ # Import shared utilities
23
+ from utils.training_utils import (
24
+ setup_ddp,
25
+ cleanup_ddp,
26
+ set_seed,
27
+ get_model_size,
28
+ format_time,
29
+ )
30
+
31
+
32
+ def create_dataloaders(config: dict, rank: int, world_size: int):
33
+ """
34
+ Creates and returns distributed dataloaders for training and validation.
35
+
36
+ Args:
37
+ config (dict): A dictionary of configuration parameters.
38
+ rank (int): The global rank of the current process.
39
+ world_size (int): The total number of processes.
40
+
41
+ Returns:
42
+ tuple: A tuple containing (train_loader, val_loader, train_dataset, valid_dataset).
43
+ """
44
+ print(f"[Rank {rank}] Creating distributed dataloaders...")
45
+ train_dataset = QlibDataset('train')
46
+ valid_dataset = QlibDataset('val')
47
+ print(f"[Rank {rank}] Train dataset size: {len(train_dataset)}, Validation dataset size: {len(valid_dataset)}")
48
+
49
+ train_sampler = DistributedSampler(train_dataset, num_replicas=world_size, rank=rank, shuffle=True)
50
+ val_sampler = DistributedSampler(valid_dataset, num_replicas=world_size, rank=rank, shuffle=False)
51
+
52
+ train_loader = DataLoader(
53
+ train_dataset,
54
+ batch_size=config['batch_size'],
55
+ sampler=train_sampler,
56
+ shuffle=False, # Shuffle is handled by the sampler
57
+ num_workers=config.get('num_workers', 2),
58
+ pin_memory=True,
59
+ drop_last=True
60
+ )
61
+ val_loader = DataLoader(
62
+ valid_dataset,
63
+ batch_size=config['batch_size'],
64
+ sampler=val_sampler,
65
+ shuffle=False,
66
+ num_workers=config.get('num_workers', 2),
67
+ pin_memory=True,
68
+ drop_last=False
69
+ )
70
+ print(f"[Rank {rank}] Dataloaders created. Train steps/epoch: {len(train_loader)}, Val steps: {len(val_loader)}")
71
+ return train_loader, val_loader, train_dataset, valid_dataset
72
+
73
+
74
+ def train_model(model, device, config, save_dir, logger, rank, world_size):
75
+ """
76
+ The main training and validation loop for the tokenizer.
77
+
78
+ Args:
79
+ model (DDP): The DDP-wrapped model to train.
80
+ device (torch.device): The device for the current process.
81
+ config (dict): Configuration dictionary.
82
+ save_dir (str): Directory to save checkpoints.
83
+ logger (comet_ml.Experiment): Comet logger instance.
84
+ rank (int): Global rank of the process.
85
+ world_size (int): Total number of processes.
86
+
87
+ Returns:
88
+ tuple: A tuple containing the trained model and a dictionary of results.
89
+ """
90
+ start_time = time.time()
91
+ if rank == 0:
92
+ effective_bs = config['batch_size'] * world_size * config['accumulation_steps']
93
+ print(f"[Rank {rank}] BATCHSIZE (per GPU): {config['batch_size']}")
94
+ print(f"[Rank {rank}] Effective total batch size: {effective_bs}")
95
+
96
+ train_loader, val_loader, train_dataset, valid_dataset = create_dataloaders(config, rank, world_size)
97
+
98
+ optimizer = torch.optim.AdamW(
99
+ model.parameters(),
100
+ lr=config['tokenizer_learning_rate'],
101
+ weight_decay=config['adam_weight_decay']
102
+ )
103
+
104
+ scheduler = torch.optim.lr_scheduler.OneCycleLR(
105
+ optimizer=optimizer,
106
+ max_lr=config['tokenizer_learning_rate'],
107
+ steps_per_epoch=len(train_loader),
108
+ epochs=config['epochs'],
109
+ pct_start=0.03,
110
+ div_factor=10
111
+ )
112
+
113
+ best_val_loss = float('inf')
114
+ dt_result = {}
115
+ batch_idx_global_train = 0
116
+
117
+ for epoch_idx in range(config['epochs']):
118
+ epoch_start_time = time.time()
119
+ model.train()
120
+ train_loader.sampler.set_epoch(epoch_idx)
121
+
122
+ # Set dataset seeds for reproducible sampling
123
+ train_dataset.set_epoch_seed(epoch_idx * 10000 + rank)
124
+ valid_dataset.set_epoch_seed(0) # Keep validation sampling consistent
125
+
126
+ for i, (ori_batch_x, _) in enumerate(train_loader):
127
+ ori_batch_x = ori_batch_x.squeeze(0).to(device, non_blocking=True)
128
+
129
+ # --- Gradient Accumulation Loop ---
130
+ current_batch_total_loss = 0.0
131
+ for j in range(config['accumulation_steps']):
132
+ start_idx = j * (ori_batch_x.shape[0] // config['accumulation_steps'])
133
+ end_idx = (j + 1) * (ori_batch_x.shape[0] // config['accumulation_steps'])
134
+ batch_x = ori_batch_x[start_idx:end_idx]
135
+
136
+ # Forward pass
137
+ zs, bsq_loss, _, _ = model(batch_x)
138
+ z_pre, z = zs
139
+
140
+ # Loss calculation
141
+ recon_loss_pre = F.mse_loss(z_pre, batch_x)
142
+ recon_loss_all = F.mse_loss(z, batch_x)
143
+ recon_loss = recon_loss_pre + recon_loss_all
144
+ loss = (recon_loss + bsq_loss) / 2 # Assuming w_1=w_2=1
145
+
146
+ loss_scaled = loss / config['accumulation_steps']
147
+ current_batch_total_loss += loss.item()
148
+ loss_scaled.backward()
149
+
150
+ # --- Optimizer Step after Accumulation ---
151
+ torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=2.0)
152
+ optimizer.step()
153
+ scheduler.step()
154
+ optimizer.zero_grad()
155
+
156
+ # --- Logging (Master Process Only) ---
157
+ if rank == 0 and (batch_idx_global_train + 1) % config['log_interval'] == 0:
158
+ avg_loss = current_batch_total_loss / config['accumulation_steps']
159
+ print(
160
+ f"[Rank {rank}, Epoch {epoch_idx + 1}/{config['epochs']}, Step {i + 1}/{len(train_loader)}] "
161
+ f"LR {optimizer.param_groups[0]['lr']:.6f}, Loss: {avg_loss:.4f}"
162
+ )
163
+ if rank == 0 and logger:
164
+ avg_loss = current_batch_total_loss / config['accumulation_steps']
165
+ logger.log_metric('train_tokenizer_loss_batch', avg_loss, step=batch_idx_global_train)
166
+ logger.log_metric(f'train_vqvae_vq_loss_each_batch', bsq_loss.item(), step=batch_idx_global_train)
167
+ logger.log_metric(f'train_recon_loss_pre_each_batch', recon_loss_pre.item(), step=batch_idx_global_train)
168
+ logger.log_metric(f'train_recon_loss_each_batch', recon_loss_all.item(), step=batch_idx_global_train)
169
+ logger.log_metric('tokenizer_learning_rate', optimizer.param_groups[0]["lr"], step=batch_idx_global_train)
170
+
171
+ batch_idx_global_train += 1
172
+
173
+ # --- Validation Loop ---
174
+ model.eval()
175
+ tot_val_loss_sum_rank = 0.0
176
+ val_sample_count_rank = 0
177
+ with torch.no_grad():
178
+ for ori_batch_x, _ in val_loader:
179
+ ori_batch_x = ori_batch_x.squeeze(0).to(device, non_blocking=True)
180
+ zs, _, _, _ = model(ori_batch_x)
181
+ _, z = zs
182
+ val_loss_item = F.mse_loss(z, ori_batch_x)
183
+
184
+ tot_val_loss_sum_rank += val_loss_item.item() * ori_batch_x.size(0)
185
+ val_sample_count_rank += ori_batch_x.size(0)
186
+
187
+ # Reduce validation losses from all processes
188
+ val_loss_sum_tensor = torch.tensor(tot_val_loss_sum_rank, device=device)
189
+ val_count_tensor = torch.tensor(val_sample_count_rank, device=device)
190
+ dist.all_reduce(val_loss_sum_tensor, op=dist.ReduceOp.SUM)
191
+ dist.all_reduce(val_count_tensor, op=dist.ReduceOp.SUM)
192
+
193
+ avg_val_loss = val_loss_sum_tensor.item() / val_count_tensor.item() if val_count_tensor.item() > 0 else 0
194
+
195
+ # --- End of Epoch Summary & Checkpointing (Master Process Only) ---
196
+ if rank == 0:
197
+ print(f"\n--- Epoch {epoch_idx + 1}/{config['epochs']} Summary ---")
198
+ print(f"Validation Loss: {avg_val_loss:.4f}")
199
+ print(f"Time This Epoch: {format_time(time.time() - epoch_start_time)}")
200
+ print(f"Total Time Elapsed: {format_time(time.time() - start_time)}\n")
201
+ if logger:
202
+ logger.log_metric('val_tokenizer_loss_epoch', avg_val_loss, epoch=epoch_idx)
203
+
204
+ if avg_val_loss < best_val_loss:
205
+ best_val_loss = avg_val_loss
206
+ save_path = f"{save_dir}/checkpoints/best_model"
207
+ model.module.save_pretrained(save_path)
208
+ print(f"Best model saved to {save_path} (Val Loss: {best_val_loss:.4f})")
209
+ if logger:
210
+ logger.log_model("best_model", save_path)
211
+
212
+ dist.barrier() # Ensure all processes finish the epoch before starting the next one.
213
+
214
+ dt_result['best_val_loss'] = best_val_loss
215
+ return model, dt_result
216
+
217
+
218
+ def main(config: dict):
219
+ """
220
+ Main function to orchestrate the DDP training process.
221
+ """
222
+ rank, world_size, local_rank = setup_ddp()
223
+ device = torch.device(f"cuda:{local_rank}")
224
+ set_seed(config['seed'], rank)
225
+
226
+ save_dir = os.path.join(config['save_path'], config['tokenizer_save_folder_name'])
227
+
228
+ # Logger and summary setup (master process only)
229
+ comet_logger, master_summary = None, {}
230
+ if rank == 0:
231
+ os.makedirs(os.path.join(save_dir, 'checkpoints'), exist_ok=True)
232
+ master_summary = {
233
+ 'start_time': strftime("%Y-%m-%dT%H-%M-%S", gmtime()),
234
+ 'save_directory': save_dir,
235
+ 'world_size': world_size,
236
+ }
237
+ if config['use_comet']:
238
+ comet_logger = comet_ml.Experiment(
239
+ api_key=config['comet_config']['api_key'],
240
+ project_name=config['comet_config']['project_name'],
241
+ workspace=config['comet_config']['workspace'],
242
+ )
243
+ comet_logger.add_tag(config['comet_tag'])
244
+ comet_logger.set_name(config['comet_name'])
245
+ comet_logger.log_parameters(config)
246
+ print("Comet Logger Initialized.")
247
+
248
+ dist.barrier() # Ensure save directory is created before proceeding
249
+
250
+ # Model Initialization
251
+ model = KronosTokenizer.from_pretrained(config['pretrained_tokenizer_path'])
252
+ model.to(device)
253
+ model = DDP(model, device_ids=[local_rank], find_unused_parameters=False)
254
+
255
+ if rank == 0:
256
+ print(f"Model Size: {get_model_size(model.module)}")
257
+
258
+ # Start Training
259
+ _, dt_result = train_model(
260
+ model, device, config, save_dir, comet_logger, rank, world_size
261
+ )
262
+
263
+ # Finalize and save summary (master process only)
264
+ if rank == 0:
265
+ master_summary['final_result'] = dt_result
266
+ with open(os.path.join(save_dir, 'summary.json'), 'w') as f:
267
+ json.dump(master_summary, f, indent=4)
268
+ print('Training finished. Summary file saved.')
269
+ if comet_logger:
270
+ comet_logger.end()
271
+
272
+ cleanup_ddp()
273
+
274
+
275
+ if __name__ == '__main__':
276
+ # Usage: torchrun --standalone --nproc_per_node=NUM_GPUS train_tokenizer.py
277
+ if "WORLD_SIZE" not in os.environ:
278
+ raise RuntimeError("This script must be launched with `torchrun`.")
279
+
280
+ config_instance = Config()
281
+ main(config_instance.__dict__)
finetune/utils/__init__.py ADDED
File without changes
finetune/utils/training_utils.py ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import random
3
+ import datetime
4
+ import numpy as np
5
+ import torch
6
+ import torch.distributed as dist
7
+
8
+
9
+ def setup_ddp():
10
+ """
11
+ Initializes the distributed data parallel environment.
12
+
13
+ This function relies on environment variables set by `torchrun` or a similar
14
+ launcher. It initializes the process group and sets the CUDA device for the
15
+ current process.
16
+
17
+ Returns:
18
+ tuple: A tuple containing (rank, world_size, local_rank).
19
+ """
20
+ if not dist.is_available():
21
+ raise RuntimeError("torch.distributed is not available.")
22
+
23
+ dist.init_process_group(backend="nccl")
24
+ rank = int(os.environ["RANK"])
25
+ world_size = int(os.environ["WORLD_SIZE"])
26
+ local_rank = int(os.environ["LOCAL_RANK"])
27
+ torch.cuda.set_device(local_rank)
28
+ print(
29
+ f"[DDP Setup] Global Rank: {rank}/{world_size}, "
30
+ f"Local Rank (GPU): {local_rank} on device {torch.cuda.current_device()}"
31
+ )
32
+ return rank, world_size, local_rank
33
+
34
+
35
+ def cleanup_ddp():
36
+ """Cleans up the distributed process group."""
37
+ if dist.is_initialized():
38
+ dist.destroy_process_group()
39
+
40
+
41
+ def set_seed(seed: int, rank: int = 0):
42
+ """
43
+ Sets the random seed for reproducibility across all relevant libraries.
44
+
45
+ Args:
46
+ seed (int): The base seed value.
47
+ rank (int): The process rank, used to ensure different processes have
48
+ different seeds, which can be important for data loading.
49
+ """
50
+ actual_seed = seed + rank
51
+ random.seed(actual_seed)
52
+ np.random.seed(actual_seed)
53
+ torch.manual_seed(actual_seed)
54
+ if torch.cuda.is_available():
55
+ torch.cuda.manual_seed_all(actual_seed)
56
+ # The two lines below can impact performance, so they are often
57
+ # reserved for final experiments where reproducibility is critical.
58
+ torch.backends.cudnn.deterministic = True
59
+ torch.backends.cudnn.benchmark = False
60
+
61
+
62
+ def get_model_size(model: torch.nn.Module) -> str:
63
+ """
64
+ Calculates the number of trainable parameters in a PyTorch model and returns
65
+ it as a human-readable string.
66
+
67
+ Args:
68
+ model (torch.nn.Module): The PyTorch model.
69
+
70
+ Returns:
71
+ str: A string representing the model size (e.g., "175.0B", "7.1M", "50.5K").
72
+ """
73
+ total_params = sum(p.numel() for p in model.parameters() if p.requires_grad)
74
+
75
+ if total_params >= 1e9:
76
+ return f"{total_params / 1e9:.1f}B" # Billions
77
+ elif total_params >= 1e6:
78
+ return f"{total_params / 1e6:.1f}M" # Millions
79
+ else:
80
+ return f"{total_params / 1e3:.1f}K" # Thousands
81
+
82
+
83
+ def reduce_tensor(tensor: torch.Tensor, world_size: int, op=dist.ReduceOp.SUM) -> torch.Tensor:
84
+ """
85
+ Reduces a tensor's value across all processes in a distributed setup.
86
+
87
+ Args:
88
+ tensor (torch.Tensor): The tensor to be reduced.
89
+ world_size (int): The total number of processes.
90
+ op (dist.ReduceOp, optional): The reduction operation (SUM, AVG, etc.).
91
+ Defaults to dist.ReduceOp.SUM.
92
+
93
+ Returns:
94
+ torch.Tensor: The reduced tensor, which will be identical on all processes.
95
+ """
96
+ rt = tensor.clone()
97
+ dist.all_reduce(rt, op=op)
98
+ # Note: `dist.ReduceOp.AVG` is available in newer torch versions.
99
+ # For compatibility, manual division is sometimes used after a SUM.
100
+ if op == dist.ReduceOp.AVG:
101
+ rt /= world_size
102
+ return rt
103
+
104
+
105
+ def format_time(seconds: float) -> str:
106
+ """
107
+ Formats a duration in seconds into a human-readable H:M:S string.
108
+
109
+ Args:
110
+ seconds (float): The total seconds.
111
+
112
+ Returns:
113
+ str: The formatted time string (e.g., "0:15:32").
114
+ """
115
+ return str(datetime.timedelta(seconds=int(seconds)))
116
+
117
+
118
+
model/__init__.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .kronos import KronosTokenizer, Kronos, KronosPredictor
2
+
3
+ model_dict = {
4
+ 'kronos_tokenizer': KronosTokenizer,
5
+ 'kronos': Kronos,
6
+ 'kronos_predictor': KronosPredictor
7
+ }
8
+
9
+
10
+ def get_model_class(model_name):
11
+ if model_name in model_dict:
12
+ return model_dict[model_name]
13
+ else:
14
+ print(f"Model {model_name} not found in model_dict")
15
+ raise NotImplementedError
16
+
17
+
model/__pycache__/__init__.cpython-313.pyc ADDED
Binary file (606 Bytes). View file
 
model/__pycache__/kronos.cpython-313.pyc ADDED
Binary file (37 kB). View file
 
model/__pycache__/module.cpython-313.pyc ADDED
Binary file (37.5 kB). View file
 
model/kronos.py ADDED
@@ -0,0 +1,626 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import pandas as pd
3
+ import torch
4
+ from huggingface_hub import PyTorchModelHubMixin
5
+ import sys
6
+
7
+ from tqdm import trange
8
+
9
+ sys.path.append("../")
10
+ from model.module import *
11
+
12
+
13
+ class KronosTokenizer(nn.Module, PyTorchModelHubMixin):
14
+ """
15
+ KronosTokenizer module for tokenizing input data using a hybrid quantization approach.
16
+
17
+ This tokenizer utilizes a combination of encoder and decoder Transformer blocks
18
+ along with the Binary Spherical Quantization (BSQuantizer) to compress and decompress input data.
19
+
20
+ Args:
21
+ d_in (int): Input dimension.
22
+ d_model (int): Model dimension.
23
+ n_heads (int): Number of attention heads.
24
+ ff_dim (int): Feed-forward dimension.
25
+ n_enc_layers (int): Number of encoder layers.
26
+ n_dec_layers (int): Number of decoder layers.
27
+ ffn_dropout_p (float): Dropout probability for feed-forward networks.
28
+ attn_dropout_p (float): Dropout probability for attention mechanisms.
29
+ resid_dropout_p (float): Dropout probability for residual connections.
30
+ s1_bits (int): Number of bits for the pre token in BSQuantizer.
31
+ s2_bits (int): Number of bits for the post token in BSQuantizer.
32
+ beta (float): Beta parameter for BSQuantizer.
33
+ gamma0 (float): Gamma0 parameter for BSQuantizer.
34
+ gamma (float): Gamma parameter for BSQuantizer.
35
+ zeta (float): Zeta parameter for BSQuantizer.
36
+ group_size (int): Group size parameter for BSQuantizer.
37
+
38
+ """
39
+
40
+ def __init__(self, d_in, d_model, n_heads, ff_dim, n_enc_layers, n_dec_layers, ffn_dropout_p, attn_dropout_p, resid_dropout_p, s1_bits, s2_bits, beta, gamma0, gamma, zeta, group_size):
41
+
42
+ super().__init__()
43
+ self.d_in = d_in
44
+ self.d_model = d_model
45
+ self.n_heads = n_heads
46
+ self.ff_dim = ff_dim
47
+ self.enc_layers = n_enc_layers
48
+ self.dec_layers = n_dec_layers
49
+ self.ffn_dropout_p = ffn_dropout_p
50
+ self.attn_dropout_p = attn_dropout_p
51
+ self.resid_dropout_p = resid_dropout_p
52
+
53
+ self.s1_bits = s1_bits
54
+ self.s2_bits = s2_bits
55
+ self.codebook_dim = s1_bits + s2_bits # Total dimension of the codebook after quantization
56
+ self.embed = nn.Linear(self.d_in, self.d_model)
57
+ self.head = nn.Linear(self.d_model, self.d_in)
58
+
59
+ # Encoder Transformer Blocks
60
+ self.encoder = nn.ModuleList([
61
+ TransformerBlock(self.d_model, self.n_heads, self.ff_dim, self.ffn_dropout_p, self.attn_dropout_p, self.resid_dropout_p)
62
+ for _ in range(self.enc_layers - 1)
63
+ ])
64
+ # Decoder Transformer Blocks
65
+ self.decoder = nn.ModuleList([
66
+ TransformerBlock(self.d_model, self.n_heads, self.ff_dim, self.ffn_dropout_p, self.attn_dropout_p, self.resid_dropout_p)
67
+ for _ in range(self.dec_layers - 1)
68
+ ])
69
+ self.quant_embed = nn.Linear(in_features=self.d_model, out_features=self.codebook_dim) # Linear layer before quantization
70
+ self.post_quant_embed_pre = nn.Linear(in_features=self.s1_bits, out_features=self.d_model) # Linear layer after quantization (pre part - s1 bits)
71
+ self.post_quant_embed = nn.Linear(in_features=self.codebook_dim, out_features=self.d_model) # Linear layer after quantization (full codebook)
72
+ self.tokenizer = BSQuantizer(self.s1_bits, self.s2_bits, beta, gamma0, gamma, zeta, group_size) # BSQuantizer module
73
+
74
+ def forward(self, x):
75
+ """
76
+ Forward pass of the KronosTokenizer.
77
+
78
+ Args:
79
+ x (torch.Tensor): Input tensor of shape (batch_size, seq_len, d_in).
80
+
81
+ Returns:
82
+ tuple: A tuple containing:
83
+ - tuple: (z_pre, z) - Reconstructed outputs from decoder with s1_bits and full codebook respectively,
84
+ both of shape (batch_size, seq_len, d_in).
85
+ - torch.Tensor: bsq_loss - Loss from the BSQuantizer.
86
+ - torch.Tensor: quantized - Quantized representation from BSQuantizer.
87
+ - torch.Tensor: z_indices - Indices from the BSQuantizer.
88
+ """
89
+ z = self.embed(x)
90
+
91
+ for layer in self.encoder:
92
+ z = layer(z)
93
+
94
+ z = self.quant_embed(z) # (B, T, codebook)
95
+
96
+ bsq_loss, quantized, z_indices = self.tokenizer(z)
97
+
98
+ quantized_pre = quantized[:, :, :self.s1_bits] # Extract the first part of quantized representation (s1_bits)
99
+ z_pre = self.post_quant_embed_pre(quantized_pre)
100
+
101
+ z = self.post_quant_embed(quantized)
102
+
103
+ # Decoder layers (for pre part - s1 bits)
104
+ for layer in self.decoder:
105
+ z_pre = layer(z_pre)
106
+ z_pre = self.head(z_pre)
107
+
108
+ # Decoder layers (for full codebook)
109
+ for layer in self.decoder:
110
+ z = layer(z)
111
+ z = self.head(z)
112
+
113
+ return (z_pre, z), bsq_loss, quantized, z_indices
114
+
115
+ def indices_to_bits(self, x, half=False):
116
+ """
117
+ Converts indices to bit representations and scales them.
118
+
119
+ Args:
120
+ x (torch.Tensor): Indices tensor.
121
+ half (bool, optional): Whether to process only half of the codebook dimension. Defaults to False.
122
+
123
+ Returns:
124
+ torch.Tensor: Bit representation tensor.
125
+ """
126
+ if half:
127
+ x1 = x[0] # Assuming x is a tuple of indices if half is True
128
+ x2 = x[1]
129
+ mask = 2 ** torch.arange(self.codebook_dim//2, device=x1.device, dtype=torch.long) # Create a mask for bit extraction
130
+ x1 = (x1.unsqueeze(-1) & mask) != 0 # Extract bits for the first half
131
+ x2 = (x2.unsqueeze(-1) & mask) != 0 # Extract bits for the second half
132
+ x = torch.cat([x1, x2], dim=-1) # Concatenate the bit representations
133
+ else:
134
+ mask = 2 ** torch.arange(self.codebook_dim, device=x.device, dtype=torch.long) # Create a mask for bit extraction
135
+ x = (x.unsqueeze(-1) & mask) != 0 # Extract bits
136
+
137
+ x = x.float() * 2 - 1 # Convert boolean to bipolar (-1, 1)
138
+ q_scale = 1. / (self.codebook_dim ** 0.5) # Scaling factor
139
+ x = x * q_scale
140
+ return x
141
+
142
+ def encode(self, x, half=False):
143
+ """
144
+ Encodes the input data into quantized indices.
145
+
146
+ Args:
147
+ x (torch.Tensor): Input tensor of shape (batch_size, seq_len, d_in).
148
+ half (bool, optional): Whether to use half quantization in BSQuantizer. Defaults to False.
149
+
150
+ Returns:
151
+ torch.Tensor: Quantized indices from BSQuantizer.
152
+ """
153
+ z = self.embed(x)
154
+ for layer in self.encoder:
155
+ z = layer(z)
156
+ z = self.quant_embed(z)
157
+
158
+ bsq_loss, quantized, z_indices = self.tokenizer(z, half)
159
+ return z_indices
160
+
161
+ def decode(self, x, half=False):
162
+ """
163
+ Decodes quantized indices back to the input data space.
164
+
165
+ Args:
166
+ x (torch.Tensor): Quantized indices tensor.
167
+ half (bool, optional): Whether the indices were generated with half quantization. Defaults to False.
168
+
169
+ Returns:
170
+ torch.Tensor: Reconstructed output tensor of shape (batch_size, seq_len, d_in).
171
+ """
172
+ quantized = self.indices_to_bits(x, half)
173
+ z = self.post_quant_embed(quantized)
174
+ for layer in self.decoder:
175
+ z = layer(z)
176
+ z = self.head(z)
177
+ return z
178
+
179
+
180
+ class Kronos(nn.Module, PyTorchModelHubMixin):
181
+ """
182
+ Kronos Model.
183
+
184
+ Args:
185
+ s1_bits (int): Number of bits for pre tokens.
186
+ s2_bits (int): Number of bits for post tokens.
187
+ n_layers (int): Number of Transformer blocks.
188
+ d_model (int): Dimension of the model's embeddings and hidden states.
189
+ n_heads (int): Number of attention heads in the MultiheadAttention layers.
190
+ ff_dim (int): Dimension of the feedforward network in the Transformer blocks.
191
+ ffn_dropout_p (float): Dropout probability for the feedforward network.
192
+ attn_dropout_p (float): Dropout probability for the attention layers.
193
+ resid_dropout_p (float): Dropout probability for residual connections.
194
+ token_dropout_p (float): Dropout probability for token embeddings.
195
+ learn_te (bool): Whether to use learnable temporal embeddings.
196
+ """
197
+
198
+ def __init__(self, s1_bits, s2_bits, n_layers, d_model, n_heads, ff_dim, ffn_dropout_p, attn_dropout_p, resid_dropout_p, token_dropout_p, learn_te):
199
+ super().__init__()
200
+ self.s1_bits = s1_bits
201
+ self.s2_bits = s2_bits
202
+ self.n_layers = n_layers
203
+ self.d_model = d_model
204
+ self.n_heads = n_heads
205
+ self.learn_te = learn_te
206
+ self.ff_dim = ff_dim
207
+ self.ffn_dropout_p = ffn_dropout_p
208
+ self.attn_dropout_p = attn_dropout_p
209
+ self.resid_dropout_p = resid_dropout_p
210
+ self.token_dropout_p = token_dropout_p
211
+
212
+ self.s1_vocab_size = 2 ** self.s1_bits
213
+ self.token_drop = nn.Dropout(self.token_dropout_p)
214
+ self.embedding = HierarchicalEmbedding(self.s1_bits, self.s2_bits, self.d_model)
215
+ self.time_emb = TemporalEmbedding(self.d_model, self.learn_te)
216
+ self.transformer = nn.ModuleList([
217
+ TransformerBlock(self.d_model, self.n_heads, self.ff_dim, self.ffn_dropout_p, self.attn_dropout_p, self.resid_dropout_p)
218
+ for _ in range(self.n_layers)
219
+ ])
220
+ self.norm = RMSNorm(self.d_model)
221
+ self.dep_layer = DependencyAwareLayer(self.d_model)
222
+ self.head = DualHead(self.s1_bits, self.s2_bits, self.d_model)
223
+ self.apply(self._init_weights)
224
+
225
+ def _init_weights(self, module):
226
+
227
+ if isinstance(module, nn.Linear):
228
+ nn.init.xavier_normal_(module.weight)
229
+ if module.bias is not None:
230
+ nn.init.zeros_(module.bias)
231
+ elif isinstance(module, nn.Embedding):
232
+ nn.init.normal_(module.weight, mean=0, std=self.embedding.d_model ** -0.5)
233
+ elif isinstance(module, nn.LayerNorm):
234
+ nn.init.ones_(module.weight)
235
+ nn.init.zeros_(module.bias)
236
+ elif isinstance(module, RMSNorm):
237
+ nn.init.ones_(module.weight)
238
+
239
+ def forward(self, s1_ids, s2_ids, stamp=None, padding_mask=None, use_teacher_forcing=False, s1_targets=None):
240
+ """
241
+ Args:
242
+ s1_ids (torch.Tensor): Input tensor of s1 token IDs. Shape: [batch_size, seq_len]
243
+ s2_ids (torch.Tensor): Input tensor of s2 token IDs. Shape: [batch_size, seq_len]
244
+ stamp (torch.Tensor, optional): Temporal stamp tensor. Shape: [batch_size, seq_len]. Defaults to None.
245
+ padding_mask (torch.Tensor, optional): Mask for padding tokens. Shape: [batch_size, seq_len]. Defaults to None.
246
+ use_teacher_forcing (bool, optional): Whether to use teacher forcing for s1 decoding. Defaults to False.
247
+ s1_targets (torch.Tensor, optional): Target s1 token IDs for teacher forcing. Shape: [batch_size, seq_len]. Defaults to None.
248
+
249
+ Returns:
250
+ Tuple[torch.Tensor, torch.Tensor]:
251
+ - s1 logits: Logits for s1 token predictions. Shape: [batch_size, seq_len, s1_vocab_size]
252
+ - s2_logits: Logits for s2 token predictions, conditioned on s1. Shape: [batch_size, seq_len, s2_vocab_size]
253
+ """
254
+ x = self.embedding([s1_ids, s2_ids])
255
+ if stamp is not None:
256
+ time_embedding = self.time_emb(stamp)
257
+ x = x + time_embedding
258
+ x = self.token_drop(x)
259
+
260
+ for layer in self.transformer:
261
+ x = layer(x, key_padding_mask=padding_mask)
262
+
263
+ x = self.norm(x)
264
+
265
+ s1_logits = self.head(x)
266
+
267
+ if use_teacher_forcing:
268
+ sibling_embed = self.embedding.emb_s1(s1_targets)
269
+ else:
270
+ s1_probs = F.softmax(s1_logits.detach(), dim=-1)
271
+ sample_s1_ids = torch.multinomial(s1_probs.view(-1, self.s1_vocab_size), 1).view(s1_ids.shape)
272
+ sibling_embed = self.embedding.emb_s1(sample_s1_ids)
273
+
274
+ x2 = self.dep_layer(x, sibling_embed, key_padding_mask=padding_mask) # Dependency Aware Layer: Condition on s1 embeddings
275
+ s2_logits = self.head.cond_forward(x2)
276
+ return s1_logits, s2_logits
277
+
278
+ def decode_s1(self, s1_ids, s2_ids, stamp=None, padding_mask=None):
279
+ """
280
+ Decodes only the s1 tokens.
281
+
282
+ This method performs a forward pass to predict only s1 tokens. It returns the s1 logits
283
+ and the context representation from the Transformer, which can be used for subsequent s2 decoding.
284
+
285
+ Args:
286
+ s1_ids (torch.Tensor): Input tensor of s1 token IDs. Shape: [batch_size, seq_len]
287
+ s2_ids (torch.Tensor): Input tensor of s2 token IDs. Shape: [batch_size, seq_len]
288
+ stamp (torch.Tensor, optional): Temporal stamp tensor. Shape: [batch_size, seq_len]. Defaults to None.
289
+ padding_mask (torch.Tensor, optional): Mask for padding tokens. Shape: [batch_size, seq_len]. Defaults to None.
290
+
291
+ Returns:
292
+ Tuple[torch.Tensor, torch.Tensor]:
293
+ - s1 logits: Logits for s1 token predictions. Shape: [batch_size, seq_len, s1_vocab_size]
294
+ - context: Context representation from the Transformer. Shape: [batch_size, seq_len, d_model]
295
+ """
296
+ x = self.embedding([s1_ids, s2_ids])
297
+ if stamp is not None:
298
+ time_embedding = self.time_emb(stamp)
299
+ x = x + time_embedding
300
+ x = self.token_drop(x)
301
+
302
+ for layer in self.transformer:
303
+ x = layer(x, key_padding_mask=padding_mask)
304
+
305
+ x = self.norm(x)
306
+
307
+ s1_logits = self.head(x)
308
+ return s1_logits, x
309
+
310
+ def decode_s2(self, context, s1_ids, padding_mask=None):
311
+ """
312
+ Decodes the s2 tokens, conditioned on the context and s1 tokens.
313
+
314
+ This method decodes s2 tokens based on a pre-computed context representation (typically from `decode_s1`)
315
+ and the s1 token IDs. It uses the dependency-aware layer and the conditional s2 head to predict s2 tokens.
316
+
317
+ Args:
318
+ context (torch.Tensor): Context representation from the transformer (output of decode_s1).
319
+ Shape: [batch_size, seq_len, d_model]
320
+ s1_ids (torch.torch.Tensor): Input tensor of s1 token IDs. Shape: [batch_size, seq_len]
321
+ padding_mask (torch.Tensor, optional): Mask for padding tokens. Shape: [batch_size, seq_len]. Defaults to None.
322
+
323
+ Returns:
324
+ torch.Tensor: s2 logits. Shape: [batch_size, seq_len, s2_vocab_size]
325
+ """
326
+ sibling_embed = self.embedding.emb_s1(s1_ids)
327
+ x2 = self.dep_layer(context, sibling_embed, key_padding_mask=padding_mask)
328
+ return self.head.cond_forward(x2)
329
+
330
+
331
+ def top_k_top_p_filtering(
332
+ logits,
333
+ top_k: int = 0,
334
+ top_p: float = 1.0,
335
+ filter_value: float = -float("Inf"),
336
+ min_tokens_to_keep: int = 1,
337
+ ):
338
+ """Filter a distribution of logits using top-k and/or nucleus (top-p) filtering
339
+ Args:
340
+ logits: logits distribution shape (batch size, vocabulary size)
341
+ if top_k > 0: keep only top k tokens with highest probability (top-k filtering).
342
+ if top_p < 1.0: keep the top tokens with cumulative probability >= top_p (nucleus filtering).
343
+ Nucleus filtering is described in Holtzman et al. (http://arxiv.org/abs/1904.09751)
344
+ Make sure we keep at least min_tokens_to_keep per batch example in the output
345
+ From: https://gist.github.com/thomwolf/1a5a29f6962089e871b94cbd09daf317
346
+ """
347
+ if top_k > 0:
348
+ top_k = min(max(top_k, min_tokens_to_keep), logits.size(-1)) # Safety check
349
+ # Remove all tokens with a probability less than the last token of the top-k
350
+ indices_to_remove = logits < torch.topk(logits, top_k)[0][..., -1, None]
351
+ logits[indices_to_remove] = filter_value
352
+ return logits
353
+
354
+ if top_p < 1.0:
355
+ sorted_logits, sorted_indices = torch.sort(logits, descending=True)
356
+ cumulative_probs = torch.cumsum(F.softmax(sorted_logits, dim=-1), dim=-1)
357
+
358
+ # Remove tokens with cumulative probability above the threshold (token with 0 are kept)
359
+ sorted_indices_to_remove = cumulative_probs > top_p
360
+ if min_tokens_to_keep > 1:
361
+ # Keep at least min_tokens_to_keep (set to min_tokens_to_keep-1 because we add the first one below)
362
+ sorted_indices_to_remove[..., :min_tokens_to_keep] = 0
363
+ # Shift the indices to the right to keep also the first token above the threshold
364
+ sorted_indices_to_remove[..., 1:] = sorted_indices_to_remove[..., :-1].clone()
365
+ sorted_indices_to_remove[..., 0] = 0
366
+
367
+ # scatter sorted tensors to original indexing
368
+ indices_to_remove = sorted_indices_to_remove.scatter(1, sorted_indices, sorted_indices_to_remove)
369
+ logits[indices_to_remove] = filter_value
370
+ return logits
371
+
372
+
373
+ def sample_from_logits(logits, temperature=1.0, top_k=None, top_p=None, sample_logits=True):
374
+ logits = logits / temperature
375
+ if top_k is not None or top_p is not None:
376
+ if top_k > 0 or top_p < 1.0:
377
+ logits = top_k_top_p_filtering(logits, top_k=top_k, top_p=top_p)
378
+
379
+ probs = F.softmax(logits, dim=-1)
380
+
381
+ if not sample_logits:
382
+ _, x = top_k(probs, k=1, dim=-1)
383
+ else:
384
+ x = torch.multinomial(probs, num_samples=1)
385
+
386
+ return x
387
+
388
+
389
+ def auto_regressive_inference(tokenizer, model, x, x_stamp, y_stamp, max_context, pred_len, clip=5, T=1.0, top_k=0, top_p=0.99, sample_count=5, verbose=False):
390
+ with torch.no_grad():
391
+ batch_size = x.size(0)
392
+ initial_seq_len = x.size(1)
393
+ x = torch.clip(x, -clip, clip)
394
+
395
+ device = x.device
396
+ x = x.unsqueeze(1).repeat(1, sample_count, 1, 1).reshape(-1, x.size(1), x.size(2)).to(device)
397
+ x_stamp = x_stamp.unsqueeze(1).repeat(1, sample_count, 1, 1).reshape(-1, x_stamp.size(1), x_stamp.size(2)).to(device)
398
+ y_stamp = y_stamp.unsqueeze(1).repeat(1, sample_count, 1, 1).reshape(-1, y_stamp.size(1), y_stamp.size(2)).to(device)
399
+
400
+ x_token = tokenizer.encode(x, half=True)
401
+
402
+ def get_dynamic_stamp(x_stamp, y_stamp, current_seq_len, pred_step):
403
+
404
+ if current_seq_len <= max_context - pred_step:
405
+ return torch.cat([x_stamp, y_stamp[:, :pred_step, :]], dim=1)
406
+ else:
407
+ start_idx = max_context - pred_step
408
+ return torch.cat([x_stamp[:, -start_idx:, :], y_stamp[:, :pred_step, :]], dim=1)
409
+
410
+ if verbose:
411
+ ran = trange
412
+ else:
413
+ ran = range
414
+ for i in ran(pred_len):
415
+ current_seq_len = initial_seq_len + i
416
+
417
+ if current_seq_len <= max_context:
418
+ input_tokens = x_token
419
+ else:
420
+ input_tokens = [t[:, -max_context:].contiguous() for t in x_token]
421
+
422
+ current_stamp = get_dynamic_stamp(x_stamp, y_stamp, current_seq_len, i)
423
+
424
+ s1_logits, context = model.decode_s1(input_tokens[0], input_tokens[1], current_stamp)
425
+ s1_logits = s1_logits[:, -1, :]
426
+ sample_pre = sample_from_logits(s1_logits, temperature=T, top_k=top_k, top_p=top_p, sample_logits=True)
427
+
428
+ s2_logits = model.decode_s2(context, sample_pre)
429
+ s2_logits = s2_logits[:, -1, :]
430
+ sample_post = sample_from_logits(s2_logits, temperature=T, top_k=top_k, top_p=top_p, sample_logits=True)
431
+
432
+ x_token[0] = torch.cat([x_token[0], sample_pre], dim=1)
433
+ x_token[1] = torch.cat([x_token[1], sample_post], dim=1)
434
+
435
+ torch.cuda.empty_cache()
436
+
437
+ input_tokens = [t[:, -max_context:].contiguous() for t in x_token]
438
+ z = tokenizer.decode(input_tokens, half=True)
439
+ z = z.reshape(batch_size, sample_count, z.size(1), z.size(2))
440
+ preds = z.cpu().numpy()
441
+ preds = np.mean(preds, axis=1)
442
+
443
+ return preds
444
+
445
+
446
+ def calc_time_stamps(x_timestamp):
447
+ time_df = pd.DataFrame()
448
+ time_df['minute'] = x_timestamp.dt.minute
449
+ time_df['hour'] = x_timestamp.dt.hour
450
+ time_df['weekday'] = x_timestamp.dt.weekday
451
+ time_df['day'] = x_timestamp.dt.day
452
+ time_df['month'] = x_timestamp.dt.month
453
+ return time_df
454
+
455
+
456
+ class KronosPredictor:
457
+
458
+ def __init__(self, model, tokenizer, device="cuda:0", max_context=512, clip=5):
459
+ self.tokenizer = tokenizer
460
+ self.model = model
461
+ self.max_context = max_context
462
+ self.clip = clip
463
+ self.price_cols = ['open', 'high', 'low', 'close']
464
+ self.vol_col = 'volume'
465
+ self.amt_vol = 'amount'
466
+ self.time_cols = ['minute', 'hour', 'weekday', 'day', 'month']
467
+ self.device = device
468
+
469
+ self.tokenizer = self.tokenizer.to(self.device)
470
+ self.model = self.model.to(self.device)
471
+
472
+ def generate(self, x, x_stamp, y_stamp, pred_len, T, top_k, top_p, sample_count, verbose):
473
+
474
+ x_tensor = torch.from_numpy(np.array(x).astype(np.float32)).to(self.device)
475
+ x_stamp_tensor = torch.from_numpy(np.array(x_stamp).astype(np.float32)).to(self.device)
476
+ y_stamp_tensor = torch.from_numpy(np.array(y_stamp).astype(np.float32)).to(self.device)
477
+
478
+ preds = auto_regressive_inference(self.tokenizer, self.model, x_tensor, x_stamp_tensor, y_stamp_tensor, self.max_context, pred_len,
479
+ self.clip, T, top_k, top_p, sample_count, verbose)
480
+ preds = preds[:, -pred_len:, :]
481
+ return preds
482
+
483
+ def predict(self, df, x_timestamp, y_timestamp, pred_len, T=1.0, top_k=0, top_p=0.9, sample_count=1, verbose=True):
484
+
485
+ if not isinstance(df, pd.DataFrame):
486
+ raise ValueError("Input must be a pandas DataFrame.")
487
+
488
+ if not all(col in df.columns for col in self.price_cols):
489
+ raise ValueError(f"Price columns {self.price_cols} not found in DataFrame.")
490
+
491
+ df = df.copy()
492
+ if self.vol_col not in df.columns:
493
+ df[self.vol_col] = 0.0 # Fill missing volume with zeros
494
+ df[self.amt_vol] = 0.0 # Fill missing amount with zeros
495
+ if self.amt_vol not in df.columns and self.vol_col in df.columns:
496
+ df[self.amt_vol] = df[self.vol_col] * df[self.price_cols].mean(axis=1)
497
+
498
+ if df[self.price_cols + [self.vol_col, self.amt_vol]].isnull().values.any():
499
+ raise ValueError("Input DataFrame contains NaN values in price or volume columns.")
500
+
501
+ x_time_df = calc_time_stamps(x_timestamp)
502
+ y_time_df = calc_time_stamps(y_timestamp)
503
+
504
+ x = df[self.price_cols + [self.vol_col, self.amt_vol]].values.astype(np.float32)
505
+ x_stamp = x_time_df.values.astype(np.float32)
506
+ y_stamp = y_time_df.values.astype(np.float32)
507
+
508
+ x_mean, x_std = np.mean(x, axis=0), np.std(x, axis=0)
509
+
510
+ x = (x - x_mean) / (x_std + 1e-5)
511
+ x = np.clip(x, -self.clip, self.clip)
512
+
513
+ x = x[np.newaxis, :]
514
+ x_stamp = x_stamp[np.newaxis, :]
515
+ y_stamp = y_stamp[np.newaxis, :]
516
+
517
+ preds = self.generate(x, x_stamp, y_stamp, pred_len, T, top_k, top_p, sample_count, verbose)
518
+
519
+ preds = preds.squeeze(0)
520
+ preds = preds * (x_std + 1e-5) + x_mean
521
+
522
+ pred_df = pd.DataFrame(preds, columns=self.price_cols + [self.vol_col, self.amt_vol], index=y_timestamp)
523
+ return pred_df
524
+
525
+
526
+ def predict_batch(self, df_list, x_timestamp_list, y_timestamp_list, pred_len, T=1.0, top_k=0, top_p=0.9, sample_count=1, verbose=True):
527
+ """
528
+ Perform parallel (batch) prediction on multiple time series. All series must have the same historical length and prediction length (pred_len).
529
+
530
+ Args:
531
+ df_list (List[pd.DataFrame]): List of input DataFrames, each containing price columns and optional volume/amount columns.
532
+ x_timestamp_list (List[pd.DatetimeIndex or Series]): List of timestamps corresponding to historical data, length should match the number of rows in each DataFrame.
533
+ y_timestamp_list (List[pd.DatetimeIndex or Series]): List of future prediction timestamps, length should equal pred_len.
534
+ pred_len (int): Number of prediction steps.
535
+ T (float): Sampling temperature.
536
+ top_k (int): Top-k filtering threshold.
537
+ top_p (float): Top-p (nucleus sampling) threshold.
538
+ sample_count (int): Number of parallel samples per series, automatically averaged internally.
539
+ verbose (bool): Whether to display autoregressive progress.
540
+
541
+ Returns:
542
+ List[pd.DataFrame]: List of prediction results in the same order as input, each DataFrame contains
543
+ `open, high, low, close, volume, amount` columns, indexed by corresponding `y_timestamp`.
544
+ """
545
+ # Basic validation
546
+ if not isinstance(df_list, (list, tuple)) or not isinstance(x_timestamp_list, (list, tuple)) or not isinstance(y_timestamp_list, (list, tuple)):
547
+ raise ValueError("df_list, x_timestamp_list, y_timestamp_list must be list or tuple types.")
548
+ if not (len(df_list) == len(x_timestamp_list) == len(y_timestamp_list)):
549
+ raise ValueError("df_list, x_timestamp_list, y_timestamp_list must have consistent lengths.")
550
+
551
+ num_series = len(df_list)
552
+
553
+ x_list = []
554
+ x_stamp_list = []
555
+ y_stamp_list = []
556
+ means = []
557
+ stds = []
558
+ seq_lens = []
559
+ y_lens = []
560
+
561
+ for i in range(num_series):
562
+ df = df_list[i]
563
+ if not isinstance(df, pd.DataFrame):
564
+ raise ValueError(f"Input at index {i} is not a pandas DataFrame.")
565
+ if not all(col in df.columns for col in self.price_cols):
566
+ raise ValueError(f"DataFrame at index {i} is missing price columns {self.price_cols}.")
567
+
568
+ df = df.copy()
569
+ if self.vol_col not in df.columns:
570
+ df[self.vol_col] = 0.0
571
+ df[self.amt_vol] = 0.0
572
+ if self.amt_vol not in df.columns and self.vol_col in df.columns:
573
+ df[self.amt_vol] = df[self.vol_col] * df[self.price_cols].mean(axis=1)
574
+
575
+ if df[self.price_cols + [self.vol_col, self.amt_vol]].isnull().values.any():
576
+ raise ValueError(f"DataFrame at index {i} contains NaN values in price or volume columns.")
577
+
578
+ x_timestamp = x_timestamp_list[i]
579
+ y_timestamp = y_timestamp_list[i]
580
+
581
+ x_time_df = calc_time_stamps(x_timestamp)
582
+ y_time_df = calc_time_stamps(y_timestamp)
583
+
584
+ x = df[self.price_cols + [self.vol_col, self.amt_vol]].values.astype(np.float32)
585
+ x_stamp = x_time_df.values.astype(np.float32)
586
+ y_stamp = y_time_df.values.astype(np.float32)
587
+
588
+ if x.shape[0] != x_stamp.shape[0]:
589
+ raise ValueError(f"Inconsistent lengths at index {i}: x has {x.shape[0]} vs x_stamp has {x_stamp.shape[0]}.")
590
+ if y_stamp.shape[0] != pred_len:
591
+ raise ValueError(f"y_timestamp length at index {i} should equal pred_len={pred_len}, got {y_stamp.shape[0]}.")
592
+
593
+ x_mean, x_std = np.mean(x, axis=0), np.std(x, axis=0)
594
+ x_norm = (x - x_mean) / (x_std + 1e-5)
595
+ x_norm = np.clip(x_norm, -self.clip, self.clip)
596
+
597
+ x_list.append(x_norm)
598
+ x_stamp_list.append(x_stamp)
599
+ y_stamp_list.append(y_stamp)
600
+ means.append(x_mean)
601
+ stds.append(x_std)
602
+
603
+ seq_lens.append(x_norm.shape[0])
604
+ y_lens.append(y_stamp.shape[0])
605
+
606
+ # Require all series to have consistent historical and prediction lengths for batch processing
607
+ if len(set(seq_lens)) != 1:
608
+ raise ValueError(f"Parallel prediction requires all series to have consistent historical lengths, got: {seq_lens}")
609
+ if len(set(y_lens)) != 1:
610
+ raise ValueError(f"Parallel prediction requires all series to have consistent prediction lengths, got: {y_lens}")
611
+
612
+ x_batch = np.stack(x_list, axis=0).astype(np.float32) # (B, seq_len, feat)
613
+ x_stamp_batch = np.stack(x_stamp_list, axis=0).astype(np.float32) # (B, seq_len, time_feat)
614
+ y_stamp_batch = np.stack(y_stamp_list, axis=0).astype(np.float32) # (B, pred_len, time_feat)
615
+
616
+ preds = self.generate(x_batch, x_stamp_batch, y_stamp_batch, pred_len, T, top_k, top_p, sample_count, verbose)
617
+ # preds: (B, pred_len, feat)
618
+
619
+ pred_dfs = []
620
+ for i in range(num_series):
621
+ preds_i = preds[i] * (stds[i] + 1e-5) + means[i]
622
+ pred_df = pd.DataFrame(preds_i, columns=self.price_cols + [self.vol_col, self.amt_vol], index=y_timestamp_list[i])
623
+ pred_dfs.append(pred_df)
624
+
625
+ return pred_dfs
626
+
model/module.py ADDED
@@ -0,0 +1,577 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+
3
+ from einops import rearrange, reduce
4
+ import torch
5
+ import torch.nn as nn
6
+ from torch.autograd import Function
7
+ import torch.nn.functional as F
8
+
9
+
10
+ class DifferentiableEntropyFunction(Function):
11
+ @staticmethod
12
+ def forward(ctx, zq, basis, K, eps):
13
+ zb = (zq + 1) / 2
14
+ zi = ((zb * basis).sum(-1)).to(torch.int64)
15
+ cnt = torch.scatter_reduce(torch.zeros(2 ** K, device=zq.device, dtype=zq.dtype),
16
+ 0,
17
+ zi.flatten(),
18
+ torch.ones_like(zi.flatten()).to(zq.dtype),
19
+ 'sum')
20
+ prob = (cnt + eps) / (cnt + eps).sum()
21
+ H = -(prob * torch.log(prob)).sum()
22
+ ctx.save_for_backward(zq, zi, prob)
23
+ ctx.K = K
24
+ return H
25
+
26
+ @staticmethod
27
+ def backward(ctx, grad_output):
28
+ zq, zi, prob = ctx.saved_tensors
29
+ grad_array = -grad_output * (torch.log(prob) + 1) / zi.numel() / ctx.K
30
+ reord_grad = grad_array[zi.flatten()].reshape(zi.shape)
31
+ grad_input = reord_grad.unsqueeze(-1) * zq
32
+ return grad_input, None, None, None, None
33
+
34
+
35
+ def codebook_entropy(zq, basis, K, eps=1e-4):
36
+ return DifferentiableEntropyFunction.apply(zq, basis, K, eps)
37
+
38
+
39
+ class BinarySphericalQuantizer(nn.Module):
40
+ def __init__(self, embed_dim, beta, gamma0, gamma, zeta,
41
+ input_format='bchw',
42
+ soft_entropy=True, group_size=9,
43
+ persample_entropy_compute='analytical',
44
+ cb_entropy_compute='group',
45
+ l2_norm=True,
46
+ inv_temperature=1):
47
+ """
48
+ Paper link: https://arxiv.org/pdf/2406.07548.pdf
49
+ Here we use the official implementation of the BinarySphericalQuantizer.
50
+ """
51
+ super().__init__()
52
+ self.embed_dim = embed_dim
53
+ self.beta = beta # loss weight for commit loss
54
+ self.gamma0 = gamma0 # loss weight for entropy penalty
55
+ self.gamma = gamma # loss weight for entropy penalty
56
+ self.zeta = zeta # loss weight for entire entropy penalty
57
+ self.input_format = input_format
58
+ assert self.embed_dim % group_size == 0, "embed_dim must be divisible by group_size"
59
+ self.num_groups = self.embed_dim // group_size
60
+ self.group_size = group_size
61
+ assert persample_entropy_compute in ['group', 'analytical'], "persample_entropy_compute must be either 'group' or 'analytical'"
62
+ assert cb_entropy_compute in ['group', 'nce'], "cb_entropy_compute must be either 'group' or 'nce'"
63
+ self.persample_entropy_compute = persample_entropy_compute
64
+ self.cb_entropy_compute = cb_entropy_compute
65
+ self.l2_norm = l2_norm
66
+ self.inv_temperature = inv_temperature
67
+
68
+ self.register_buffer('basis', 2 ** torch.arange(embed_dim - 1, -1, -1))
69
+ self.register_buffer('group_basis', 2 ** torch.arange(group_size - 1, -1, -1))
70
+
71
+ self.num_dimensions = 2 ** embed_dim
72
+ self.bits_per_index = embed_dim
73
+
74
+ # we only need to keep the codebook portion up to the group size
75
+ # because we approximate the H loss with this subcode
76
+ group_codes = torch.arange(2 ** self.group_size)
77
+ group_codebook = self.indexes_to_codes(group_codes).float()[:, -group_size:]
78
+ self.register_buffer('group_codebook', group_codebook, persistent=False)
79
+
80
+ self.soft_entropy = soft_entropy # soft_entropy: Sec 3.2 of https://arxiv.org/pdf/1911.05894.pdf
81
+
82
+ def quantize(self, z):
83
+ assert z.shape[-1] == self.embed_dim, f"Expected {self.embed_dim} dimensions, got {z.shape[-1]}"
84
+
85
+ zhat = torch.where(z > 0,
86
+ torch.tensor(1, dtype=z.dtype, device=z.device),
87
+ torch.tensor(-1, dtype=z.dtype, device=z.device))
88
+ return z + (zhat - z).detach()
89
+
90
+ def forward(self, z):
91
+ # if self.input_format == 'bchw':
92
+ # z = rearrange(z, 'b c h w -> b h w c')
93
+ zq = self.quantize(z)
94
+
95
+ indices = self.codes_to_indexes(zq.detach())
96
+ group_indices = self.codes_to_group_indexes(zq.detach())
97
+ if not self.training:
98
+ used_codes = torch.unique(indices, return_counts=False)
99
+ else:
100
+ used_codes = None
101
+
102
+ q_scale = 1. / (self.embed_dim ** 0.5) if self.l2_norm else 1.
103
+
104
+ if self.soft_entropy:
105
+ persample_entropy, cb_entropy, avg_prob = self.soft_entropy_loss(z)
106
+ entropy_penalty = self.gamma0 * persample_entropy - self.gamma * cb_entropy
107
+ else:
108
+ zb_by_sample = ((zq + 1) / 2).reshape(z.shape[0], -1, z.shape[-1]).to(torch.float32)
109
+ persample_entropy = self.get_hard_per_sample_entropy(zb_by_sample)
110
+ cb_entropy = codebook_entropy(zq, self.basis, self.embed_dim)
111
+ entropy_penalty = self.gamma0 * persample_entropy - self.gamma * cb_entropy
112
+
113
+ zq = zq * q_scale
114
+
115
+ # commit loss
116
+ commit_loss = self.beta * torch.mean(((zq.detach() - z) ** 2).sum(dim=-1))
117
+
118
+ # if self.input_format == 'bchw':
119
+ # zq = rearrange(zq, 'b h w c -> b c h w')
120
+
121
+ return (
122
+ zq,
123
+ commit_loss + self.zeta * entropy_penalty / self.inv_temperature,
124
+ {"H": cb_entropy, "used_codes": used_codes, "indices": indices, "group_indices": group_indices,
125
+ "avg_prob": avg_prob}
126
+ )
127
+
128
+ def soft_entropy_loss(self, z):
129
+ # if we divide the code in subgroups of size group_size, the codebook will be of size 2 ** group_size
130
+ # the sub-code is the last group_size bits of the full code
131
+ group_code_book = self.group_codebook / (self.embed_dim ** 0.5 if self.l2_norm else 1)
132
+ divided_z = rearrange(z, '... (g c) -> ... g c', c=self.group_size)
133
+
134
+ # we calculate the distance between the divided_z and the codebook for each subgroup
135
+ distance = - 2 * torch.einsum('... g c, d c ->... g d', divided_z, group_code_book)
136
+ prob = (-distance * self.inv_temperature).softmax(dim=-1)
137
+ if self.persample_entropy_compute == 'analytical':
138
+ if self.l2_norm:
139
+ p = torch.sigmoid(-4 * z / (self.embed_dim ** 0.5) * self.inv_temperature)
140
+ else:
141
+ p = torch.sigmoid(-4 * z * self.inv_temperature)
142
+ prob = torch.stack([p, 1 - p], dim=-1)
143
+ per_sample_entropy = self.get_entropy(prob, dim=-1, normalize=False).sum(dim=-1).mean()
144
+ else:
145
+ per_sample_entropy = self.get_entropy(prob, dim=-1, normalize=False).sum(dim=-1).mean()
146
+
147
+ # macro average of the probability of each subgroup
148
+ avg_prob = reduce(prob, '... g d ->g d', 'mean')
149
+ codebook_entropy = self.get_entropy(avg_prob, dim=-1, normalize=False)
150
+
151
+ # the approximation of the entropy is the sum of the entropy of each subgroup
152
+ return per_sample_entropy, codebook_entropy.sum(), avg_prob
153
+
154
+ def get_hard_per_sample_entropy(self, zb_by_sample):
155
+ probs_per_dim = zb_by_sample.sum(1) / zb_by_sample.shape[1]
156
+ persample_entropy = - probs_per_dim * torch.log(probs_per_dim + 1e-8) - (1 - probs_per_dim) * torch.log(1 - probs_per_dim + 1e-8)
157
+ persample_entropy = persample_entropy.sum(-1)
158
+ return persample_entropy.mean()
159
+
160
+ def codes_to_indexes(self, zhat):
161
+ """Converts a `code` to an index in the codebook.
162
+ Args:
163
+ zhat: A tensor of shape (B, ..., C) containing the codes. must be in {-1, 1}
164
+ """
165
+ assert zhat.shape[-1] == self.embed_dim, f"Expected {self.embed_dim} dimensions, got {zhat.shape[-1]}"
166
+ return ((zhat + 1) / 2 * self.basis).sum(axis=-1).to(torch.int64)
167
+
168
+ def codes_to_group_indexes(self, zhat):
169
+ """Converts a `code` to a list of indexes (in groups) in the codebook.
170
+ Args:
171
+ zhat: A tensor of shape (B, ..., C) containing the codes. must be in {-1, 1}
172
+ """
173
+ zhat_in_group = rearrange(zhat, 'b ... (g c) -> b ... g c', c=self.group_size)
174
+ return ((zhat_in_group + 1) / 2 * self.group_basis).sum(axis=-1).to(torch.int64)
175
+
176
+ def indexes_to_codes(self, indices):
177
+ """Inverse of `indexes_to_codes`."""
178
+ indices = indices.unsqueeze(-1)
179
+ codes_non_centered = torch.remainder(
180
+ torch.floor_divide(indices, self.basis), 2
181
+ )
182
+ return codes_non_centered * 2 - 1
183
+
184
+ def group_indexes_to_codes(self, group_indices):
185
+ """Inverse of `group_indexes_to_codes`."""
186
+ group_indices = group_indices.unsqueeze(-1)
187
+ codes_non_centered = torch.remainder(
188
+ torch.floor_divide(group_indices, self.group_basis), 2
189
+ )
190
+ codes_non_centered = rearrange(codes_non_centered, 'b ... g c -> b ... (g c)')
191
+ return codes_non_centered * 2 - 1
192
+
193
+ def get_entropy(self, count, dim=-1, eps=1e-4, normalize=True):
194
+ if normalize:
195
+ probs = (count + eps) / (count + eps).sum(dim=dim, keepdim=True)
196
+ else:
197
+ probs = count
198
+ H = -(probs * torch.log(probs + 1e-8)).sum(dim=dim)
199
+ return H
200
+
201
+ def get_group_codebook_entry(self, group_indices):
202
+ z_q = self.group_indexes_to_codes(group_indices)
203
+ q_scale = 1. / (self.embed_dim ** 0.5) if self.l2_norm else 1.
204
+ z_q = z_q * q_scale
205
+ if self.input_format == 'bchw':
206
+ h, w = int(z_q.shape[1] ** 0.5)
207
+ assert h * w == z_q.shape[1], 'Invalid sequence length'
208
+ z_q = rearrange(z_q, 'b (h w) c -> b c h w', h=h)
209
+ return z_q
210
+
211
+ def get_codebook_entry(self, indices):
212
+ z_q = self.indexes_to_codes(indices)
213
+ q_scale = 1. / (self.embed_dim ** 0.5) if self.l2_norm else 1.
214
+ z_q = z_q * q_scale
215
+ if self.input_format == 'bchw':
216
+ h, w = int(z_q.shape[1] ** 0.5)
217
+ assert h * w == z_q.shape[1], 'Invalid sequence length'
218
+ z_q = rearrange(z_q, 'b (h w) c -> b c h w', h=h)
219
+ return z_q
220
+
221
+
222
+ class BSQuantizer(nn.Module):
223
+
224
+ def __init__(self, s1_bits, s2_bits, beta, gamma0, gamma, zeta, group_size):
225
+ super().__init__()
226
+ self.codebook_dim = s1_bits + s2_bits
227
+ self.s1_bits = s1_bits
228
+ self.s2_bits = s2_bits
229
+ self.bsq = BinarySphericalQuantizer(self.codebook_dim, beta, gamma0, gamma, zeta, group_size=group_size)
230
+
231
+ def bits_to_indices(self, bits):
232
+ bits = (bits >= 0).to(torch.long)
233
+ indices = 2 ** torch.arange(
234
+ 0,
235
+ bits.shape[-1],
236
+ 1,
237
+ dtype=torch.long,
238
+ device=bits.device,
239
+ )
240
+ return (bits * indices).sum(-1)
241
+
242
+ def forward(self, z, half=False):
243
+ z = F.normalize(z, dim=-1)
244
+ quantized, bsq_loss, metrics = self.bsq(z)
245
+ if half:
246
+ q_pre = quantized[:, :, :self.s1_bits]
247
+ q_post = quantized[:, :, self.s1_bits:]
248
+ z_indices = [self.bits_to_indices(q_pre), self.bits_to_indices(q_post)]
249
+ else:
250
+ z_indices = self.bits_to_indices(quantized)
251
+ return bsq_loss, quantized, z_indices
252
+
253
+
254
+ class RMSNorm(torch.nn.Module):
255
+ def __init__(self, dim: int, eps: float = 1e-5):
256
+ super().__init__()
257
+ self.eps = eps
258
+ self.weight = nn.Parameter(torch.ones(dim))
259
+
260
+ def _norm(self, x):
261
+ return x * torch.rsqrt(torch.mean(x * x, dim=-1, keepdim=True) + self.eps)
262
+
263
+ def forward(self, x):
264
+ output = self._norm(x.float()).type_as(x)
265
+ return output * self.weight
266
+
267
+
268
+ class FeedForward(nn.Module):
269
+ def __init__(self, d_model, ff_dim, ffn_dropout_p=0.0):
270
+ super().__init__()
271
+
272
+ self.w1 = nn.Linear(d_model, ff_dim, bias=False)
273
+ self.w3 = nn.Linear(d_model, ff_dim, bias=False)
274
+ self.w2 = nn.Linear(ff_dim, d_model, bias=False)
275
+ self.ffn_dropout = nn.Dropout(ffn_dropout_p)
276
+
277
+ def forward(self, x):
278
+ return self.ffn_dropout(self.w2(F.silu(self.w1(x)) * self.w3(x)))
279
+
280
+
281
+ class RotaryPositionalEmbedding(nn.Module):
282
+ def __init__(self, dim):
283
+ super().__init__()
284
+ inv_freq = 1.0 / (10000 ** (torch.arange(0, dim, 2).float() / dim))
285
+ self.register_buffer("inv_freq", inv_freq)
286
+ self.seq_len_cached = None
287
+ self.cos_cached = None
288
+ self.sin_cached = None
289
+
290
+ def _update_cos_sin_cache(self, x, seq_len):
291
+ if seq_len != self.seq_len_cached:
292
+ self.seq_len_cached = seq_len
293
+ t = torch.arange(seq_len, device=x.device).type_as(self.inv_freq)
294
+ freqs = torch.einsum('i,j->ij', t, self.inv_freq)
295
+ emb = torch.cat((freqs, freqs), dim=-1).to(x.device)
296
+ self.cos_cached = emb.cos()[None, None, :, :]
297
+ self.sin_cached = emb.sin()[None, None, :, :]
298
+ return self.cos_cached, self.sin_cached
299
+
300
+ def forward(self, q, k):
301
+ cos, sin = self._update_cos_sin_cache(q, q.shape[-2])
302
+ return (
303
+ (q * cos) + (self._rotate_half(q) * sin),
304
+ (k * cos) + (self._rotate_half(k) * sin),
305
+ )
306
+
307
+ def _rotate_half(self, x):
308
+ x1, x2 = x.chunk(2, dim=-1)
309
+ return torch.cat((-x2, x1), dim=-1)
310
+
311
+
312
+ def scaled_dot_product_attention(query, key, value, attn_mask=None, dropout_p=0.0, is_causal=False, scale=None) -> torch.Tensor:
313
+ L, S = query.size(-2), key.size(-2)
314
+ scale_factor = 1 / math.sqrt(query.size(-1)) if scale is None else scale
315
+ attn_bias = torch.zeros(L, S, dtype=query.dtype).to(query.device)
316
+
317
+ if is_causal:
318
+ assert attn_mask is None
319
+ temp_mask = torch.ones(L, S, dtype=torch.bool).tril(diagonal=0).to(query.device)
320
+ attn_bias.masked_fill_(temp_mask.logical_not(), float("-inf"))
321
+ attn_bias.to(query.dtype)
322
+
323
+ attn_weight = query @ key.transpose(-2, -1) * scale_factor
324
+ attn_weight += attn_bias
325
+
326
+ if attn_mask is not None:
327
+ attn_mask_bias = torch.zeros_like(attn_weight)
328
+ if attn_mask.dtype == torch.bool:
329
+ attn_mask_bias.masked_fill_(attn_mask, float("-inf"))
330
+ else:
331
+ attn_mask_bias += attn_mask
332
+ attn_weight += attn_mask_bias
333
+
334
+ attn_weight = torch.softmax(attn_weight, dim=-1)
335
+ attn_weight = torch.dropout(attn_weight, dropout_p, train=True)
336
+ return attn_weight @ value
337
+
338
+
339
+ class MultiHeadAttentionWithRoPE(nn.Module):
340
+ def __init__(self, d_model, n_heads, attn_dropout_p=0.0, resid_dropout_p=0.0):
341
+ super().__init__()
342
+ self.d_model = d_model
343
+ self.n_heads = n_heads
344
+ self.head_dim = d_model // n_heads
345
+
346
+ self.q_proj = nn.Linear(d_model, d_model)
347
+ self.k_proj = nn.Linear(d_model, d_model)
348
+ self.v_proj = nn.Linear(d_model, d_model)
349
+ self.out_proj = nn.Linear(d_model, d_model)
350
+ self.rotary = RotaryPositionalEmbedding(self.head_dim)
351
+ self.attn_dropout_p = attn_dropout_p
352
+ self.resid_dropout = nn.Dropout(resid_dropout_p)
353
+
354
+ def forward(self, x, key_padding_mask=None):
355
+ batch_size, seq_len, _ = x.shape
356
+
357
+ q = self.q_proj(x).view(batch_size, seq_len, self.n_heads, self.head_dim).transpose(1, 2)
358
+ k = self.k_proj(x).view(batch_size, seq_len, self.n_heads, self.head_dim).transpose(1, 2)
359
+ v = self.v_proj(x).view(batch_size, seq_len, self.n_heads, self.head_dim).transpose(1, 2)
360
+
361
+ q, k = self.rotary(q, k)
362
+
363
+ if key_padding_mask is not None:
364
+ attn_mask = key_padding_mask.unsqueeze(1).unsqueeze(2) # [batch, 1, 1, seq_len]
365
+ attn_mask = attn_mask.expand(-1, self.n_heads, seq_len, -1) # [batch, n_heads, q_len, k_len]
366
+ else:
367
+ attn_mask = None
368
+
369
+ attn_output = scaled_dot_product_attention(
370
+ q, k, v,
371
+ attn_mask=attn_mask,
372
+ dropout_p=self.attn_dropout_p,
373
+ is_causal=True
374
+ )
375
+
376
+ attn_output = attn_output.transpose(1, 2).contiguous().view(batch_size, seq_len, self.d_model)
377
+ return self.resid_dropout(self.out_proj(attn_output))
378
+
379
+
380
+ class MultiHeadCrossAttentionWithRoPE(nn.Module):
381
+ def __init__(self, d_model, n_heads, attn_dropout_p=0.0, resid_dropout=0.0):
382
+ super().__init__()
383
+ self.d_model = d_model
384
+ self.n_heads = n_heads
385
+ self.head_dim = d_model // n_heads
386
+
387
+ self.q_proj = nn.Linear(d_model, d_model)
388
+ self.k_proj = nn.Linear(d_model, d_model)
389
+ self.v_proj = nn.Linear(d_model, d_model)
390
+ self.out_proj = nn.Linear(d_model, d_model)
391
+ self.rotary = RotaryPositionalEmbedding(self.head_dim)
392
+ self.attn_dropout_p = attn_dropout_p
393
+ self.resid_dropout = nn.Dropout(resid_dropout)
394
+
395
+ def forward(self, query, key, value, key_padding_mask=None):
396
+ batch_size, q_len, _ = query.shape
397
+ _, seq_len, _ = key.shape
398
+
399
+ q = self.q_proj(query).view(batch_size, q_len, self.n_heads, self.head_dim).transpose(1, 2)
400
+ k = self.k_proj(key).view(batch_size, seq_len, self.n_heads, self.head_dim).transpose(1, 2)
401
+ v = self.v_proj(value).view(batch_size, seq_len, self.n_heads, self.head_dim).transpose(1, 2)
402
+
403
+ q, k = self.rotary(q, k)
404
+
405
+ if key_padding_mask is not None:
406
+ attn_mask = key_padding_mask.unsqueeze(1).unsqueeze(2)
407
+ attn_mask = attn_mask.expand(-1, self.n_heads, q_len, -1)
408
+ else:
409
+ attn_mask = None
410
+
411
+ is_causal_flag = self.training
412
+
413
+ attn_output = scaled_dot_product_attention(
414
+ q, k, v,
415
+ attn_mask=attn_mask,
416
+ dropout_p=self.attn_dropout_p,
417
+ is_causal=is_causal_flag
418
+ )
419
+
420
+ attn_output = attn_output.transpose(1, 2).contiguous().view(batch_size, q_len, self.d_model)
421
+ return self.resid_dropout(self.out_proj(attn_output))
422
+
423
+
424
+ class HierarchicalEmbedding(nn.Module):
425
+ def __init__(self, s1_bits, s2_bits, d_model=256):
426
+ super().__init__()
427
+ self.s1_bits = s1_bits
428
+ self.s2_bits = s2_bits
429
+
430
+ vocab_s1 = 2 ** s1_bits
431
+ vocab_s2 = 2 ** s2_bits
432
+
433
+ self.emb_s1 = nn.Embedding(vocab_s1, d_model)
434
+ self.emb_s2 = nn.Embedding(vocab_s2, d_model)
435
+ self.d_model = d_model
436
+ self.fusion_proj = nn.Linear(d_model * 2, d_model)
437
+
438
+ nn.init.normal_(self.emb_s1.weight, mean=0, std=d_model ** -0.5)
439
+ nn.init.normal_(self.emb_s2.weight, mean=0, std=d_model ** -0.5)
440
+
441
+ def forward(self, token_ids):
442
+ """Inputs:
443
+ token_ids: [batch_size, seq_len] token ID
444
+ Output: [batch_size, seq_len, d_model]
445
+ """
446
+ if isinstance(token_ids, tuple) or isinstance(token_ids, list):
447
+ s1_ids, s2_ids = token_ids
448
+ else:
449
+ s1_ids, s2_ids = self.split_token(token_ids, self.s2_bits)
450
+ s1_emb = self.emb_s1(s1_ids) * math.sqrt(self.d_model)
451
+ s2_emb = self.emb_s2(s2_ids) * math.sqrt(self.d_model)
452
+ return self.fusion_proj(torch.cat([s1_emb, s2_emb], dim=-1))
453
+
454
+
455
+ class DependencyAwareLayer(nn.Module):
456
+ def __init__(self, d_model, n_heads=4, attn_dropout_p=0.0, resid_dropout=0.0):
457
+ super().__init__()
458
+ self.cross_attn = MultiHeadCrossAttentionWithRoPE(d_model, n_heads, attn_dropout_p, resid_dropout)
459
+ self.norm = RMSNorm(d_model)
460
+
461
+ def forward(self, hidden_states, sibling_embed, key_padding_mask=None):
462
+ """hidden_states: [batch, seq_len, d_model]
463
+ sibling_embed: Embedding from another subtoken
464
+ """
465
+ attn_out = self.cross_attn(
466
+ query=sibling_embed,
467
+ key=hidden_states,
468
+ value=hidden_states,
469
+ key_padding_mask=key_padding_mask
470
+ )
471
+ return self.norm(hidden_states + attn_out)
472
+
473
+
474
+ class TransformerBlock(nn.Module):
475
+ def __init__(self, d_model, n_heads, ff_dim=1024, ffn_dropout_p=0.0, attn_dropout_p=0.0, resid_dropout_p=0.0):
476
+ super().__init__()
477
+ self.norm1 = RMSNorm(d_model)
478
+ self.self_attn = MultiHeadAttentionWithRoPE(d_model, n_heads, attn_dropout_p, resid_dropout_p)
479
+ self.norm2 = RMSNorm(d_model)
480
+ self.ffn = FeedForward(d_model, ff_dim, ffn_dropout_p)
481
+
482
+ def forward(self, x, key_padding_mask=None):
483
+ residual = x
484
+ x = self.norm1(x)
485
+ attn_out = self.self_attn(x, key_padding_mask=key_padding_mask)
486
+ x = residual + attn_out
487
+
488
+ residual = x
489
+ x = self.norm2(x)
490
+ ffn_out = self.ffn(x)
491
+ x = residual + ffn_out
492
+ return x
493
+
494
+
495
+ class DualHead(nn.Module):
496
+ def __init__(self, s1_bits, s2_bits, d_model):
497
+ super().__init__()
498
+ self.vocab_s1 = 2 ** s1_bits
499
+ self.vocab_s2 = 2 ** s2_bits
500
+ self.proj_s1 = nn.Linear(d_model, self.vocab_s1)
501
+ self.proj_s2 = nn.Linear(d_model, self.vocab_s2)
502
+
503
+ def compute_loss(self, s1_logits, s2_logits, s1_targets, s2_targets, padding_mask=None):
504
+ if padding_mask is not None:
505
+ valid_mask = (padding_mask == 0)
506
+ s1_logits = s1_logits[valid_mask]
507
+ s2_logits = s2_logits[valid_mask]
508
+ s1_targets = s1_targets[valid_mask]
509
+ s2_targets = s2_targets[valid_mask]
510
+ ce_s1 = F.cross_entropy(s1_logits, s1_targets)
511
+ ce_s2 = F.cross_entropy(s2_logits, s2_targets)
512
+ else:
513
+ ce_s1 = F.cross_entropy(s1_logits.reshape(-1, self.vocab_s1), s1_targets.reshape(-1))
514
+ ce_s2 = F.cross_entropy(s2_logits.reshape(-1, self.vocab_s2), s2_targets.reshape(-1))
515
+ ce_loss = (ce_s1 + ce_s2) / 2
516
+ return ce_loss, ce_s1, ce_s2
517
+
518
+ def forward(self, x):
519
+ return self.proj_s1(x)
520
+
521
+ def cond_forward(self, x2):
522
+ return self.proj_s2(x2)
523
+
524
+
525
+ class FixedEmbedding(nn.Module):
526
+ def __init__(self, c_in, d_model):
527
+ super(FixedEmbedding, self).__init__()
528
+
529
+ w = torch.zeros(c_in, d_model).float()
530
+ w.require_grad = False
531
+
532
+ position = torch.arange(0, c_in).float().unsqueeze(1)
533
+ div_term = (torch.arange(0, d_model, 2).float() * -(math.log(10000.0) / d_model)).exp()
534
+
535
+ w[:, 0::2] = torch.sin(position * div_term)
536
+ w[:, 1::2] = torch.cos(position * div_term)
537
+
538
+ self.emb = nn.Embedding(c_in, d_model)
539
+ self.emb.weight = nn.Parameter(w, requires_grad=False)
540
+
541
+ def forward(self, x):
542
+ return self.emb(x).detach()
543
+
544
+
545
+ class TemporalEmbedding(nn.Module):
546
+ def __init__(self, d_model, learn_pe):
547
+ super(TemporalEmbedding, self).__init__()
548
+
549
+ minute_size = 60
550
+ hour_size = 24
551
+ weekday_size = 7
552
+ day_size = 32
553
+ month_size = 13
554
+
555
+ Embed = FixedEmbedding if not learn_pe else nn.Embedding
556
+ self.minute_embed = Embed(minute_size, d_model)
557
+ self.hour_embed = Embed(hour_size, d_model)
558
+ self.weekday_embed = Embed(weekday_size, d_model)
559
+ self.day_embed = Embed(day_size, d_model)
560
+ self.month_embed = Embed(month_size, d_model)
561
+
562
+ def forward(self, x):
563
+ x = x.long()
564
+
565
+ minute_x = self.minute_embed(x[:, :, 0])
566
+ hour_x = self.hour_embed(x[:, :, 1])
567
+ weekday_x = self.weekday_embed(x[:, :, 2])
568
+ day_x = self.day_embed(x[:, :, 3])
569
+ month_x = self.month_embed(x[:, :, 4])
570
+
571
+ return hour_x + weekday_x + day_x + month_x + minute_x
572
+
573
+
574
+
575
+
576
+
577
+
requirements.txt ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ binance
2
+ requests
3
+ numpy
4
+ pandas
5
+ torch
6
+
7
+ einops==0.8.1
8
+ huggingface_hub==0.33.1
9
+ matplotlib==3.9.3
10
+ pandas==2.2.2
11
+ tqdm==4.67.1
12
+ safetensors==0.6.2
webui/README.md ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Kronos Web UI
2
+
3
+ Web user interface for Kronos financial prediction model, providing intuitive graphical operation interface.
4
+
5
+ ## ✨ Features
6
+
7
+ - **Multi-format data support**: Supports CSV, Feather and other financial data formats
8
+ - **Smart time window**: Fixed 400+120 data point time window slider selection
9
+ - **Real model prediction**: Integrated real Kronos model, supports multiple model sizes
10
+ - **Prediction quality control**: Adjustable temperature, nucleus sampling, sample count and other parameters
11
+ - **Multi-device support**: Supports CPU, CUDA, MPS and other computing devices
12
+ - **Comparison analysis**: Detailed comparison between prediction results and actual data
13
+ - **K-line chart display**: Professional financial K-line chart display
14
+
15
+ ## 🚀 Quick Start
16
+
17
+ ### Method 1: Start with Python script
18
+ ```bash
19
+ cd webui
20
+ python run.py
21
+ ```
22
+
23
+ ### Method 2: Start with Shell script
24
+ ```bash
25
+ cd webui
26
+ chmod +x start.sh
27
+ ./start.sh
28
+ ```
29
+
30
+ ### Method 3: Start Flask application directly
31
+ ```bash
32
+ cd webui
33
+ python app.py
34
+ ```
35
+
36
+ After successful startup, visit http://localhost:7070
37
+
38
+ ## 📋 Usage Steps
39
+
40
+ 1. **Load data**: Select financial data file from data directory
41
+ 2. **Load model**: Select Kronos model and computing device
42
+ 3. **Set parameters**: Adjust prediction quality parameters
43
+ 4. **Select time window**: Use slider to select 400+120 data point time range
44
+ 5. **Start prediction**: Click prediction button to generate results
45
+ 6. **View results**: View prediction results in charts and tables
46
+
47
+ ## 🔧 Prediction Quality Parameters
48
+
49
+ ### Temperature (T)
50
+ - **Range**: 0.1 - 2.0
51
+ - **Effect**: Controls prediction randomness
52
+ - **Recommendation**: 1.2-1.5 for better prediction quality
53
+
54
+ ### Nucleus Sampling (top_p)
55
+ - **Range**: 0.1 - 1.0
56
+ - **Effect**: Controls prediction diversity
57
+ - **Recommendation**: 0.95-1.0 to consider more possibilities
58
+
59
+ ### Sample Count
60
+ - **Range**: 1 - 5
61
+ - **Effect**: Generate multiple prediction samples
62
+ - **Recommendation**: 2-3 samples to improve quality
63
+
64
+ ## 📊 Supported Data Formats
65
+
66
+ ### Required Columns
67
+ - `open`: Opening price
68
+ - `high`: Highest price
69
+ - `low`: Lowest price
70
+ - `close`: Closing price
71
+
72
+ ### Optional Columns
73
+ - `volume`: Trading volume
74
+ - `amount`: Trading amount (not used for prediction)
75
+ - `timestamps`/`timestamp`/`date`: Timestamp
76
+
77
+ ## 🤖 Model Support
78
+
79
+ - **Kronos-mini**: 4.1M parameters, lightweight fast prediction
80
+ - **Kronos-small**: 24.7M parameters, balanced performance and speed
81
+ - **Kronos-base**: 102.3M parameters, high quality prediction
82
+
83
+ ## 🖥️ GPU Acceleration Support
84
+
85
+ - **CPU**: General computing, best compatibility
86
+ - **CUDA**: NVIDIA GPU acceleration, best performance
87
+ - **MPS**: Apple Silicon GPU acceleration, recommended for Mac users
88
+
89
+ ## ⚠️ Notes
90
+
91
+ - `amount` column is not used for prediction, only for display
92
+ - Time window is fixed at 400+120=520 data points
93
+ - Ensure data file contains sufficient historical data
94
+ - First model loading may require download, please be patient
95
+
96
+ ## 🔍 Comparison Analysis
97
+
98
+ The system automatically provides comparison analysis between prediction results and actual data, including:
99
+ - Price difference statistics
100
+ - Error analysis
101
+ - Prediction quality assessment
102
+
103
+ ## 🛠️ Technical Architecture
104
+
105
+ - **Backend**: Flask + Python
106
+ - **Frontend**: HTML + CSS + JavaScript
107
+ - **Charts**: Plotly.js
108
+ - **Data processing**: Pandas + NumPy
109
+ - **Model**: Hugging Face Transformers
110
+
111
+ ## 📝 Troubleshooting
112
+
113
+ ### Common Issues
114
+ 1. **Port occupied**: Modify port number in app.py
115
+ 2. **Missing dependencies**: Run `pip install -r requirements.txt`
116
+ 3. **Model loading failed**: Check network connection and model ID
117
+ 4. **Data format error**: Ensure data column names and format are correct
118
+
119
+ ### Log Viewing
120
+ Detailed runtime information will be displayed in the console at startup, including model status and error messages.
121
+
122
+ ## 📄 License
123
+
124
+ This project follows the license terms of the original Kronos project.
125
+
126
+ ## 🤝 Contributing
127
+
128
+ Welcome to submit Issues and Pull Requests to improve this Web UI!
129
+
130
+ ## 📞 Support
131
+
132
+ If you have questions, please check:
133
+ 1. Project documentation
134
+ 2. GitHub Issues
135
+ 3. Console error messages
webui/__pycache__/app.cpython-313.pyc ADDED
Binary file (34 kB). View file
 
webui/__pycache__/technical_indicators.cpython-313.pyc ADDED
Binary file (7.72 kB). View file
 
webui/app.py ADDED
@@ -0,0 +1,863 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import datetime
2
+ import json
3
+ import os
4
+ import sys
5
+ import warnings
6
+
7
+ import pandas as pd
8
+ import plotly.graph_objects as go
9
+ import plotly.utils
10
+ import pytz
11
+ from binance.client import Client
12
+ from flask import Flask, render_template, request, jsonify
13
+ from flask_cors import CORS
14
+ from sympy import false
15
+
16
+ try:
17
+ from technical_indicators import add_technical_indicators, get_available_indicators
18
+
19
+ TECHNICAL_INDICATORS_AVAILABLE = False
20
+ except ImportError as e:
21
+ print(f"⚠️ 技术指标模块导入失败: {e}")
22
+ TECHNICAL_INDICATORS_AVAILABLE = False
23
+
24
+
25
+ # 定义空的替代函数
26
+ def add_technical_indicators(df, indicators_config=None):
27
+ return df
28
+
29
+
30
+ def get_available_indicators():
31
+ return {'trend': [], 'momentum': [], 'volatility': [], 'volume': []}
32
+
33
+ warnings.filterwarnings('ignore')
34
+
35
+ # 设置东八区时区
36
+ BEIJING_TZ = pytz.timezone('Asia/Shanghai')
37
+
38
+ # Add project root directory to path
39
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
40
+
41
+ try:
42
+ from model import Kronos, KronosTokenizer, KronosPredictor
43
+
44
+ MODEL_AVAILABLE = True
45
+ except ImportError:
46
+ MODEL_AVAILABLE = False
47
+ print("Warning: Kronos model cannot be imported, will use simulated data for demonstration")
48
+
49
+ app = Flask(__name__)
50
+ CORS(app)
51
+
52
+ # Global variables to store models
53
+ tokenizer = None
54
+ model = None
55
+ predictor = None
56
+
57
+ # Available model configurations
58
+ AVAILABLE_MODELS = {
59
+ 'kronos-mini': {
60
+ 'name': 'Kronos-mini',
61
+ 'model_id': 'NeoQuasar/Kronos-mini',
62
+ 'tokenizer_id': 'NeoQuasar/Kronos-Tokenizer-2k',
63
+ 'context_length': 2048,
64
+ 'params': '4.1M',
65
+ 'description': 'Lightweight model, suitable for fast prediction'
66
+ },
67
+ 'kronos-small': {
68
+ 'name': 'Kronos-small',
69
+ 'model_id': 'NeoQuasar/Kronos-small',
70
+ 'tokenizer_id': 'NeoQuasar/Kronos-Tokenizer-base',
71
+ 'context_length': 512,
72
+ 'params': '24.7M',
73
+ 'description': 'Small model, balanced performance and speed'
74
+ },
75
+ 'kronos-base': {
76
+ 'name': 'Kronos-base',
77
+ 'model_id': 'NeoQuasar/Kronos-base',
78
+ 'tokenizer_id': 'NeoQuasar/Kronos-Tokenizer-base',
79
+ 'context_length': 512,
80
+ 'params': '102.3M',
81
+ 'description': 'Base model, provides better prediction quality'
82
+ }
83
+ }
84
+
85
+ # 币安客户端初始化(使用公开API,无需API密钥)
86
+ binance_client = Client("", "")
87
+
88
+
89
+ def get_available_symbols():
90
+ """获取固定的交易对列表"""
91
+ # 返回固定的主要交易对,不再从币安API获取
92
+ return [
93
+ {'symbol': 'BTCUSDT', 'baseAsset': 'BTC', 'quoteAsset': 'USDT', 'name': 'BTC/USDT'},
94
+ {'symbol': 'ETHUSDT', 'baseAsset': 'ETH', 'quoteAsset': 'USDT', 'name': 'ETH/USDT'},
95
+ {'symbol': 'SOLUSDT', 'baseAsset': 'SOL', 'quoteAsset': 'USDT', 'name': 'SOL/USDT'},
96
+ {'symbol': 'BNBUSDT', 'baseAsset': 'BNB', 'quoteAsset': 'USDT', 'name': 'BNB/USDT'}
97
+ ]
98
+
99
+
100
+
101
+ def get_binance_klines(symbol, interval='1h', limit=1000):
102
+ """从币安获取K线数据,如果失败则生成模拟数据"""
103
+ try:
104
+ # 尝试获取真实的币安数据
105
+ klines = binance_client.get_klines(
106
+ symbol=symbol,
107
+ interval=interval,
108
+ limit=limit
109
+ )
110
+
111
+ # 转换为DataFrame
112
+ df = pd.DataFrame(klines, columns=[
113
+ 'timestamp', 'open', 'high', 'low', 'close', 'volume',
114
+ 'close_time', 'quote_asset_volume', 'number_of_trades',
115
+ 'taker_buy_base_asset_volume', 'taker_buy_quote_asset_volume', 'ignore'
116
+ ])
117
+
118
+ # 数据类型转换,转换为东八区时间
119
+ df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms', utc=True)
120
+ df['timestamp'] = df['timestamp'].dt.tz_convert(BEIJING_TZ)
121
+ df['timestamps'] = df['timestamp'] # 保持兼容性
122
+
123
+ # 转换数值列
124
+ numeric_cols = ['open', 'high', 'low', 'close', 'volume', 'quote_asset_volume']
125
+ for col in numeric_cols:
126
+ df[col] = pd.to_numeric(df[col], errors='coerce')
127
+
128
+ # 添加amount列(成交额)
129
+ df['amount'] = df['quote_asset_volume']
130
+
131
+ # 只保留需要的列
132
+ df = df[['timestamp','timestamps', 'open', 'high', 'low', 'close', 'volume', 'amount']]
133
+
134
+ # 按时间排序
135
+ df = df.sort_values('timestamp').reset_index(drop=True)
136
+
137
+ # 添加技术指标(如果可用)
138
+ if TECHNICAL_INDICATORS_AVAILABLE:
139
+ try:
140
+ df = add_technical_indicators(df)
141
+ print(f"✅ 成功获取币安真实数据并计算技术指标: {symbol} {interval} {len(df)}条,{len(df.columns)}个特征")
142
+ except Exception as e:
143
+ print(f"⚠️ 技术指标计算失败,使用原始数据: {e}")
144
+ else:
145
+ print(f"✅ 成功获取��安真实数据: {symbol} {interval} {len(df)}条")
146
+
147
+ return df, None
148
+
149
+ except Exception as e:
150
+ print(f"⚠️ 币安API连接失败,使用模拟数据: {str(e)}")
151
+
152
+
153
+ def get_timeframe_options():
154
+ """获取可用的时间周期选项"""
155
+ return [
156
+ {'value': '1m', 'label': '1分钟', 'description': '1分钟K线'},
157
+ {'value': '5m', 'label': '5分钟', 'description': '5分钟K线'},
158
+ {'value': '15m', 'label': '15分钟', 'description': '15分钟K线'},
159
+ {'value': '30m', 'label': '30分钟', 'description': '30分钟K线'},
160
+ {'value': '1h', 'label': '1小时', 'description': '1小时K线'},
161
+ {'value': '4h', 'label': '4小时', 'description': '4小时K线'},
162
+ {'value': '1d', 'label': '1天', 'description': '日K线'},
163
+ {'value': '1w', 'label': '1周', 'description': '周K线'},
164
+ ]
165
+
166
+
167
+ def save_prediction_results(file_path, prediction_type, prediction_results, actual_data, input_data, prediction_params):
168
+ """Save prediction results to file"""
169
+ try:
170
+ # Create prediction results directory
171
+ results_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'prediction_results')
172
+ os.makedirs(results_dir, exist_ok=True)
173
+
174
+ # Generate filename
175
+ timestamp = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')
176
+ filename = f'prediction_{timestamp}.json'
177
+ filepath = os.path.join(results_dir, filename)
178
+
179
+ # Prepare data for saving
180
+ save_data = {
181
+ 'timestamp': datetime.datetime.now().isoformat(),
182
+ 'file_path': file_path,
183
+ 'prediction_type': prediction_type,
184
+ 'prediction_params': prediction_params,
185
+ 'input_data_summary': {
186
+ 'rows': len(input_data),
187
+ 'columns': list(input_data.columns),
188
+ 'price_range': {
189
+ 'open': {'min': float(input_data['open'].min()), 'max': float(input_data['open'].max())},
190
+ 'high': {'min': float(input_data['high'].min()), 'max': float(input_data['high'].max())},
191
+ 'low': {'min': float(input_data['low'].min()), 'max': float(input_data['low'].max())},
192
+ 'close': {'min': float(input_data['close'].min()), 'max': float(input_data['close'].max())}
193
+ },
194
+ 'last_values': {
195
+ 'open': float(input_data['open'].iloc[-1]),
196
+ 'high': float(input_data['high'].iloc[-1]),
197
+ 'low': float(input_data['low'].iloc[-1]),
198
+ 'close': float(input_data['close'].iloc[-1])
199
+ }
200
+ },
201
+ 'prediction_results': prediction_results,
202
+ 'actual_data': actual_data,
203
+ 'analysis': {}
204
+ }
205
+
206
+ # If actual data exists, perform comparison analysis
207
+ if actual_data and len(actual_data) > 0:
208
+ # Calculate continuity analysis
209
+ if len(prediction_results) > 0 and len(actual_data) > 0:
210
+ last_pred = prediction_results[0] # First prediction point
211
+ first_actual = actual_data[0] # First actual point
212
+
213
+ save_data['analysis']['continuity'] = {
214
+ 'last_prediction': {
215
+ 'open': last_pred['open'],
216
+ 'high': last_pred['high'],
217
+ 'low': last_pred['low'],
218
+ 'close': last_pred['close']
219
+ },
220
+ 'first_actual': {
221
+ 'open': first_actual['open'],
222
+ 'high': first_actual['high'],
223
+ 'low': first_actual['low'],
224
+ 'close': first_actual['close']
225
+ },
226
+ 'gaps': {
227
+ 'open_gap': abs(last_pred['open'] - first_actual['open']),
228
+ 'high_gap': abs(last_pred['high'] - first_actual['high']),
229
+ 'low_gap': abs(last_pred['low'] - first_actual['low']),
230
+ 'close_gap': abs(last_pred['close'] - first_actual['close'])
231
+ },
232
+ 'gap_percentages': {
233
+ 'open_gap_pct': (abs(last_pred['open'] - first_actual['open']) / first_actual['open']) * 100,
234
+ 'high_gap_pct': (abs(last_pred['high'] - first_actual['high']) / first_actual['high']) * 100,
235
+ 'low_gap_pct': (abs(last_pred['low'] - first_actual['low']) / first_actual['low']) * 100,
236
+ 'close_gap_pct': (abs(last_pred['close'] - first_actual['close']) / first_actual['close']) * 100
237
+ }
238
+ }
239
+
240
+ # Save to file
241
+ with open(filepath, 'w', encoding='utf-8') as f:
242
+ json.dump(save_data, f, indent=2, ensure_ascii=False)
243
+
244
+ print(f"Prediction results saved to: {filepath}")
245
+ return filepath
246
+
247
+ except Exception as e:
248
+ print(f"Failed to save prediction results: {e}")
249
+ return None
250
+
251
+
252
+ def create_prediction_chart(df, pred_df, lookback, pred_len, actual_df=None, historical_start_idx=0):
253
+ """Create prediction chart"""
254
+ # Use specified historical data start position, not always from the beginning of df
255
+ if historical_start_idx + lookback + pred_len <= len(df):
256
+ # Display lookback historical points + pred_len prediction points starting from specified position
257
+ historical_df = df.iloc[historical_start_idx:historical_start_idx + lookback]
258
+ prediction_range = range(historical_start_idx + lookback, historical_start_idx + lookback + pred_len)
259
+ else:
260
+ # If data is insufficient, adjust to maximum available range
261
+ available_lookback = min(lookback, len(df) - historical_start_idx)
262
+ available_pred_len = min(pred_len, max(0, len(df) - historical_start_idx - available_lookback))
263
+ historical_df = df.iloc[historical_start_idx:historical_start_idx + available_lookback]
264
+ prediction_range = range(historical_start_idx + available_lookback,
265
+ historical_start_idx + available_lookback + available_pred_len)
266
+
267
+ # Create chart
268
+ fig = go.Figure()
269
+
270
+ # Add historical data (candlestick chart)
271
+ fig.add_trace(go.Candlestick(
272
+ x=historical_df['timestamps'] if 'timestamps' in historical_df.columns else historical_df.index,
273
+ open=historical_df['open'],
274
+ high=historical_df['high'],
275
+ low=historical_df['low'],
276
+ close=historical_df['close'],
277
+ name='Historical Data (400 data points)',
278
+ increasing_line_color='#26A69A',
279
+ decreasing_line_color='#EF5350'
280
+ ))
281
+
282
+ # Add prediction data (candlestick chart)
283
+ if pred_df is not None and len(pred_df) > 0:
284
+ # Calculate prediction data timestamps - ensure continuity with historical data
285
+ if 'timestamps' in df.columns and len(historical_df) > 0:
286
+ # Start from the last timestamp of historical data, create prediction timestamps with the same time interval
287
+ last_timestamp = historical_df['timestamps'].iloc[-1]
288
+ time_diff = df['timestamps'].iloc[1] - df['timestamps'].iloc[0] if len(df) > 1 else pd.Timedelta(hours=1)
289
+
290
+ pred_timestamps = pd.date_range(
291
+ start=last_timestamp + time_diff,
292
+ periods=len(pred_df),
293
+ freq=time_diff
294
+ )
295
+ else:
296
+ # If no timestamps, use index
297
+ pred_timestamps = range(len(historical_df), len(historical_df) + len(pred_df))
298
+
299
+ fig.add_trace(go.Candlestick(
300
+ x=pred_timestamps,
301
+ open=pred_df['open'],
302
+ high=pred_df['high'],
303
+ low=pred_df['low'],
304
+ close=pred_df['close'],
305
+ name='Prediction Data (120 data points)',
306
+ increasing_line_color='#66BB6A',
307
+ decreasing_line_color='#FF7043'
308
+ ))
309
+
310
+ # Add actual data for comparison (if exists)
311
+ if actual_df is not None and len(actual_df) > 0:
312
+ # Actual data should be in the same time period as prediction data
313
+ if 'timestamps' in df.columns:
314
+ # Actual data should use the same timestamps as prediction data to ensure time alignment
315
+ if 'pred_timestamps' in locals():
316
+ actual_timestamps = pred_timestamps
317
+ else:
318
+ # If no prediction timestamps, calculate from the last timestamp of historical data
319
+ if len(historical_df) > 0:
320
+ last_timestamp = historical_df['timestamps'].iloc[-1]
321
+ time_diff = df['timestamps'].iloc[1] - df['timestamps'].iloc[0] if len(df) > 1 else pd.Timedelta(
322
+ hours=1)
323
+ actual_timestamps = pd.date_range(
324
+ start=last_timestamp + time_diff,
325
+ periods=len(actual_df),
326
+ freq=time_diff
327
+ )
328
+ else:
329
+ actual_timestamps = range(len(historical_df), len(historical_df) + len(actual_df))
330
+ else:
331
+ actual_timestamps = range(len(historical_df), len(historical_df) + len(actual_df))
332
+
333
+ fig.add_trace(go.Candlestick(
334
+ x=actual_timestamps,
335
+ open=actual_df['open'],
336
+ high=actual_df['high'],
337
+ low=actual_df['low'],
338
+ close=actual_df['close'],
339
+ name='Actual Data (120 data points)',
340
+ increasing_line_color='#FF9800',
341
+ decreasing_line_color='#F44336'
342
+ ))
343
+
344
+ # Update layout
345
+ fig.update_layout(
346
+ title='Kronos Financial Prediction Results - 400 Historical Points + 120 Prediction Points vs 120 Actual Points',
347
+ xaxis_title='Time',
348
+ yaxis_title='Price',
349
+ template='plotly_white',
350
+ height=600,
351
+ showlegend=True
352
+ )
353
+
354
+ # Ensure x-axis time continuity
355
+ if 'timestamps' in historical_df.columns:
356
+ # Get all timestamps and sort them
357
+ all_timestamps = []
358
+ if len(historical_df) > 0:
359
+ all_timestamps.extend(historical_df['timestamps'])
360
+ if 'pred_timestamps' in locals():
361
+ all_timestamps.extend(pred_timestamps)
362
+ if 'actual_timestamps' in locals():
363
+ all_timestamps.extend(actual_timestamps)
364
+
365
+ if all_timestamps:
366
+ all_timestamps = sorted(all_timestamps)
367
+ fig.update_xaxes(
368
+ range=[all_timestamps[0], all_timestamps[-1]],
369
+ rangeslider_visible=False,
370
+ type='date'
371
+ )
372
+
373
+ return json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
374
+
375
+
376
+ @app.route('/')
377
+ def index():
378
+ """Home page"""
379
+ return render_template('index.html')
380
+
381
+
382
+ @app.route('/api/symbols')
383
+ def get_symbols():
384
+ """获取可用的交易对列表"""
385
+ symbols = get_available_symbols()
386
+ return jsonify(symbols)
387
+
388
+
389
+ @app.route('/api/timeframes')
390
+ def get_timeframes():
391
+ """获取可用的时间周期列表"""
392
+ timeframes = get_timeframe_options()
393
+ return jsonify(timeframes)
394
+
395
+
396
+ @app.route('/api/technical-indicators')
397
+ def get_technical_indicators():
398
+ """获取可用的技术指标列表"""
399
+ indicators = get_available_indicators()
400
+ return jsonify(indicators)
401
+
402
+
403
+ @app.route('/api/load-data', methods=['POST'])
404
+ def load_data():
405
+ """加载币安数据"""
406
+ try:
407
+ data = request.get_json()
408
+ symbol = data.get('symbol')
409
+ interval = data.get('interval', '1h')
410
+ limit = int(data.get('limit', 1000))
411
+
412
+ if not symbol:
413
+ return jsonify({'error': '交易对不能为空'}), 400
414
+
415
+ df, error = get_binance_klines(symbol, interval, limit)
416
+ if error:
417
+ return jsonify({'error': error}), 400
418
+
419
+ # Detect data time frequency
420
+ def detect_timeframe(df):
421
+ if len(df) < 2:
422
+ return "Unknown"
423
+
424
+ time_diffs = []
425
+ for i in range(1, min(10, len(df))): # Check first 10 time differences
426
+ diff = df['timestamps'].iloc[i] - df['timestamps'].iloc[i - 1]
427
+ time_diffs.append(diff)
428
+
429
+ if not time_diffs:
430
+ return "Unknown"
431
+
432
+ # Calculate average time difference
433
+ avg_diff = sum(time_diffs, pd.Timedelta(0)) / len(time_diffs)
434
+
435
+ # Convert to readable format
436
+ if avg_diff < pd.Timedelta(minutes=1):
437
+ return f"{avg_diff.total_seconds():.0f} seconds"
438
+ elif avg_diff < pd.Timedelta(hours=1):
439
+ return f"{avg_diff.total_seconds() / 60:.0f} minutes"
440
+ elif avg_diff < pd.Timedelta(days=1):
441
+ return f"{avg_diff.total_seconds() / 3600:.0f} hours"
442
+ else:
443
+ return f"{avg_diff.days} days"
444
+
445
+ # Return data information with formatted time
446
+ def format_beijing_time(timestamp):
447
+ """格式化东八区时间为 yyyy-MM-dd HH:mm:ss"""
448
+ if pd.isna(timestamp):
449
+ return 'N/A'
450
+ # 确保时间戳有时区信息
451
+ if timestamp.tz is None:
452
+ timestamp = timestamp.tz_localize(BEIJING_TZ)
453
+ elif timestamp.tz != BEIJING_TZ:
454
+ timestamp = timestamp.tz_convert(BEIJING_TZ)
455
+ return timestamp.strftime('%Y-%m-%d %H:%M:%S')
456
+
457
+ data_info = {
458
+ 'rows': len(df),
459
+ 'columns': list(df.columns),
460
+ 'start_date': format_beijing_time(df['timestamps'].min()) if 'timestamps' in df.columns else 'N/A',
461
+ 'end_date': format_beijing_time(df['timestamps'].max()) if 'timestamps' in df.columns else 'N/A',
462
+ 'price_range': {
463
+ 'min': float(df[['open', 'high', 'low', 'close']].min().min()),
464
+ 'max': float(df[['open', 'high', 'low', 'close']].max().max())
465
+ },
466
+ 'prediction_columns': ['open', 'high', 'low', 'close'] + (['volume'] if 'volume' in df.columns else []),
467
+ 'timeframe': detect_timeframe(df)
468
+ }
469
+
470
+ return jsonify({
471
+ 'success': True,
472
+ 'data_info': data_info,
473
+ 'message': f'Successfully loaded data, total {len(df)} rows'
474
+ })
475
+
476
+ except Exception as e:
477
+ return jsonify({'error': f'Failed to load data: {str(e)}'}), 500
478
+
479
+
480
+ @app.route('/api/predict', methods=['POST'])
481
+ def predict():
482
+ """Perform prediction"""
483
+ try:
484
+ data = request.get_json()
485
+ symbol = data.get('symbol')
486
+ interval = data.get('interval', '1h')
487
+ limit = int(data.get('limit', 1000))
488
+ lookback = int(data.get('lookback', 400))
489
+ pred_len = int(data.get('pred_len', 120))
490
+
491
+ # Get prediction quality parameters
492
+ temperature = float(data.get('temperature', 1.0))
493
+ top_p = float(data.get('top_p', 0.9))
494
+ sample_count = int(data.get('sample_count', 1))
495
+
496
+ if not symbol:
497
+ return jsonify({'error': '交易对不能为空'}), 400
498
+
499
+ # Load data from Binance
500
+ df, error = get_binance_klines(symbol, interval, limit)
501
+ if error:
502
+ return jsonify({'error': error}), 400
503
+
504
+ if len(df) < lookback:
505
+ return jsonify({'error': f'Insufficient data length, need at least {lookback} rows'}), 400
506
+
507
+ # Perform prediction
508
+ if MODEL_AVAILABLE:
509
+ try:
510
+ # Use real Kronos model
511
+ # Only use necessary columns: OHLCVA (6 features required by Kronos model)
512
+ required_cols = ['open', 'high', 'low', 'close']
513
+ if 'volume' in df.columns:
514
+ required_cols.append('volume')
515
+ if 'amount' in df.columns:
516
+ required_cols.append('amount')
517
+
518
+ print(f"🔍 Using features for prediction: {required_cols}")
519
+ print(f" Available columns in data: {list(df.columns)}")
520
+ print(f" Data shape: {df.shape}")
521
+
522
+ # Check if required columns exist
523
+ missing_cols = [col for col in required_cols if col not in df.columns]
524
+ if missing_cols:
525
+ return jsonify({'error': f'Missing required columns: {missing_cols}'}), 400
526
+
527
+ # Process time period selection
528
+ start_date = data.get('start_date')
529
+
530
+ if start_date:
531
+ # Custom time period - fix logic: use data within selected window
532
+ start_dt = pd.to_datetime(start_date)
533
+
534
+ # Find data after start time
535
+ mask = df['timestamps'] >= start_dt
536
+ time_range_df = df[mask]
537
+
538
+ # Ensure sufficient data: lookback + pred_len
539
+ if len(time_range_df) < lookback + pred_len:
540
+ return jsonify({
541
+ 'error': f'Insufficient data from start time {start_dt.strftime("%Y-%m-%d %H:%M")}, need at least {lookback + pred_len} data points, currently only {len(time_range_df)} available'}), 400
542
+
543
+ # Use first lookback data points within selected window for prediction
544
+ x_df = time_range_df.iloc[:lookback][required_cols]
545
+ x_timestamp = time_range_df.iloc[:lookback]['timestamps']
546
+
547
+ print(f"🔍 Custom time period - x_df shape: {x_df.shape}")
548
+ print(f" x_timestamp length: {len(x_timestamp)}")
549
+ print(f" x_df columns: {list(x_df.columns)}")
550
+ print(f" x_df sample:\n{x_df.head()}")
551
+
552
+ # Generate future timestamps for prediction instead of using existing data
553
+ # Calculate time difference from the data
554
+ if len(time_range_df) >= 2:
555
+ time_diff = time_range_df['timestamps'].iloc[1] - time_range_df['timestamps'].iloc[0]
556
+ else:
557
+ time_diff = pd.Timedelta(hours=1) # Default to 1 hour
558
+
559
+ # Generate future timestamps starting from the last timestamp of input data
560
+ last_timestamp = time_range_df['timestamps'].iloc[lookback - 1]
561
+ y_timestamp = pd.date_range(
562
+ start=last_timestamp + time_diff,
563
+ periods=pred_len,
564
+ freq=time_diff
565
+ )
566
+
567
+ # Calculate actual time period length
568
+ start_timestamp = time_range_df['timestamps'].iloc[0]
569
+ end_timestamp = y_timestamp[-1] # Use the last generated timestamp
570
+ time_span = end_timestamp - start_timestamp
571
+
572
+ prediction_type = f"Kronos model prediction (within selected window: first {lookback} data points for prediction, {pred_len} future predictions, time span: {time_span})"
573
+ else:
574
+ # Use latest data
575
+ x_df = df.iloc[:lookback][required_cols]
576
+ x_timestamp = df.iloc[:lookback]['timestamps']
577
+
578
+ # Generate future timestamps for prediction instead of using existing data
579
+ # Calculate time difference from the data
580
+ if len(df) >= 2:
581
+ time_diff = df['timestamps'].iloc[1] - df['timestamps'].iloc[0]
582
+ else:
583
+ time_diff = pd.Timedelta(hours=1) # Default to 1 hour
584
+
585
+ # Generate future timestamps starting from the last timestamp of input data
586
+ last_timestamp = df['timestamps'].iloc[lookback - 1]
587
+ y_timestamp = pd.date_range(
588
+ start=last_timestamp + time_diff,
589
+ periods=pred_len,
590
+ freq=time_diff
591
+ )
592
+ prediction_type = "Kronos model prediction (latest data)"
593
+
594
+ print(f"🔍 Latest data - x_df shape: {x_df.shape}")
595
+ print(f" x_timestamp length: {len(x_timestamp)}")
596
+ print(f" y_timestamp length: {len(y_timestamp)}")
597
+ print(f" x_df columns: {list(x_df.columns)}")
598
+ print(f" x_df sample:\n{x_df.head()}")
599
+
600
+ # Check if data is empty
601
+ if x_df.empty or len(x_df) == 0:
602
+ return jsonify({'error': 'Input data is empty after processing'}), 400
603
+
604
+ if len(x_timestamp) == 0:
605
+ return jsonify({'error': 'Input timestamps are empty'}), 400
606
+
607
+ if len(y_timestamp) == 0:
608
+ return jsonify({'error': 'Target timestamps are empty'}), 400
609
+
610
+ # Ensure timestamps are Series format, not DatetimeIndex, to avoid .dt attribute error in Kronos model
611
+ if isinstance(x_timestamp, pd.DatetimeIndex):
612
+ x_timestamp = pd.Series(x_timestamp, name='timestamps')
613
+ if isinstance(y_timestamp, pd.DatetimeIndex):
614
+ y_timestamp = pd.Series(y_timestamp, name='timestamps')
615
+
616
+ pred_df = predictor.predict(
617
+ df=x_df,
618
+ x_timestamp=x_timestamp,
619
+ y_timestamp=y_timestamp,
620
+ pred_len=pred_len,
621
+ T=temperature,
622
+ top_p=top_p,
623
+ sample_count=sample_count
624
+ )
625
+
626
+ except Exception as e:
627
+ return jsonify({'error': f'Kronos model prediction failed: {str(e)}'}), 500
628
+ else:
629
+ return jsonify({'error': 'Kronos model not loaded, please load model first'}), 400
630
+
631
+ # Prepare actual data for comparison (if exists)
632
+ actual_data = []
633
+ actual_df = None
634
+
635
+ if start_date: # Custom time period
636
+ # Fix logic: use data within selected window
637
+ # Prediction uses first 400 data points within selected window
638
+ # Actual data should be last 120 data points within selected window
639
+ start_dt = pd.to_datetime(start_date)
640
+ # 确保时区一致性
641
+ if start_dt.tz is None:
642
+ start_dt = start_dt.tz_localize(BEIJING_TZ)
643
+
644
+ # Find data starting from start_date
645
+ mask = df['timestamps'] >= start_dt
646
+ time_range_df = df[mask]
647
+
648
+ if len(time_range_df) >= lookback + pred_len:
649
+ # Get last 120 data points within selected window as actual values
650
+ actual_df = time_range_df.iloc[lookback:lookback + pred_len]
651
+
652
+ for i, (_, row) in enumerate(actual_df.iterrows()):
653
+ actual_data.append({
654
+ 'timestamp': row['timestamps'].isoformat(),
655
+ 'open': float(row['open']),
656
+ 'high': float(row['high']),
657
+ 'low': float(row['low']),
658
+ 'close': float(row['close']),
659
+ 'volume': float(row['volume']) if 'volume' in row else 0,
660
+ 'amount': float(row['amount']) if 'amount' in row else 0
661
+ })
662
+ else: # Latest data
663
+ # Prediction uses first 400 data points
664
+ # Actual data should be 120 data points after first 400 data points
665
+ if len(df) >= lookback + pred_len:
666
+ actual_df = df.iloc[lookback:lookback + pred_len]
667
+ for i, (_, row) in enumerate(actual_df.iterrows()):
668
+ actual_data.append({
669
+ 'timestamp': row['timestamps'].isoformat(),
670
+ 'open': float(row['open']),
671
+ 'high': float(row['high']),
672
+ 'low': float(row['low']),
673
+ 'close': float(row['close']),
674
+ 'volume': float(row['volume']) if 'volume' in row else 0,
675
+ 'amount': float(row['amount']) if 'amount' in row else 0
676
+ })
677
+
678
+ # Create chart - pass historical data start position
679
+ if start_date:
680
+ # Custom time period: find starting position of historical data in original df
681
+ start_dt = pd.to_datetime(start_date)
682
+ # 确保时区一致性
683
+ if start_dt.tz is None:
684
+ start_dt = start_dt.tz_localize(BEIJING_TZ)
685
+ mask = df['timestamps'] >= start_dt
686
+ historical_start_idx = df[mask].index[0] if len(df[mask]) > 0 else 0
687
+ else:
688
+ # Latest data: start from beginning
689
+ historical_start_idx = 0
690
+
691
+ chart_json = create_prediction_chart(df, pred_df, lookback, pred_len, actual_df, historical_start_idx)
692
+
693
+ # Prepare prediction result data - fix timestamp calculation logic
694
+ if 'timestamps' in df.columns:
695
+ if start_date:
696
+ # Custom time period: use selected window data to calculate timestamps
697
+ start_dt = pd.to_datetime(start_date)
698
+ # 确保时区一致性
699
+ if start_dt.tz is None:
700
+ start_dt = start_dt.tz_localize(BEIJING_TZ)
701
+ mask = df['timestamps'] >= start_dt
702
+ time_range_df = df[mask]
703
+
704
+ if len(time_range_df) >= lookback:
705
+ # Calculate prediction timestamps starting from last time point of selected window
706
+ last_timestamp = time_range_df['timestamps'].iloc[lookback - 1]
707
+ time_diff = df['timestamps'].iloc[1] - df['timestamps'].iloc[0]
708
+ future_timestamps = pd.date_range(
709
+ start=last_timestamp + time_diff,
710
+ periods=pred_len,
711
+ freq=time_diff
712
+ )
713
+ else:
714
+ future_timestamps = []
715
+ else:
716
+ # Latest data: calculate from last time point of entire data file
717
+ last_timestamp = df['timestamps'].iloc[-1]
718
+ time_diff = df['timestamps'].iloc[1] - df['timestamps'].iloc[0]
719
+ future_timestamps = pd.date_range(
720
+ start=last_timestamp + time_diff,
721
+ periods=pred_len,
722
+ freq=time_diff
723
+ )
724
+ else:
725
+ future_timestamps = range(len(df), len(df) + pred_len)
726
+
727
+ prediction_results = []
728
+ for i, (_, row) in enumerate(pred_df.iterrows()):
729
+ prediction_results.append({
730
+ 'timestamp': future_timestamps[i].isoformat() if i < len(future_timestamps) else f"T{i}",
731
+ 'open': float(row['open']),
732
+ 'high': float(row['high']),
733
+ 'low': float(row['low']),
734
+ 'close': float(row['close']),
735
+ 'volume': float(row['volume']) if 'volume' in row else 0,
736
+ 'amount': float(row['amount']) if 'amount' in row else 0
737
+ })
738
+
739
+ # Save prediction results to file
740
+ try:
741
+ data_source = f"{symbol}_{interval}"
742
+ save_prediction_results(
743
+ file_path=data_source,
744
+ prediction_type=prediction_type,
745
+ prediction_results=prediction_results,
746
+ actual_data=actual_data,
747
+ input_data=x_df,
748
+ prediction_params={
749
+ 'symbol': symbol,
750
+ 'interval': interval,
751
+ 'limit': limit,
752
+ 'lookback': lookback,
753
+ 'pred_len': pred_len,
754
+ 'temperature': temperature,
755
+ 'top_p': top_p,
756
+ 'sample_count': sample_count,
757
+ 'start_date': start_date if start_date else 'latest'
758
+ }
759
+ )
760
+ except Exception as e:
761
+ print(f"Failed to save prediction results: {e}")
762
+
763
+ return jsonify({
764
+ 'success': True,
765
+ 'prediction_type': prediction_type,
766
+ 'chart': chart_json,
767
+ 'prediction_results': prediction_results,
768
+ 'actual_data': actual_data,
769
+ 'has_comparison': len(actual_data) > 0,
770
+ 'message': f'Prediction completed, generated {pred_len} prediction points' + (
771
+ f', including {len(actual_data)} actual data points for comparison' if len(actual_data) > 0 else '')
772
+ })
773
+
774
+ except Exception as e:
775
+ return jsonify({'error': f'Prediction failed: {str(e)}'}), 500
776
+
777
+
778
+ @app.route('/api/load-model', methods=['POST'])
779
+ def load_model():
780
+ """Load Kronos model"""
781
+ global tokenizer, model, predictor
782
+
783
+ try:
784
+ if not MODEL_AVAILABLE:
785
+ return jsonify({'error': 'Kronos model library not available'}), 400
786
+
787
+ data = request.get_json()
788
+ model_key = data.get('model_key', 'kronos-small')
789
+ device = data.get('device', 'cpu')
790
+
791
+ if model_key not in AVAILABLE_MODELS:
792
+ return jsonify({'error': f'Unsupported model: {model_key}'}), 400
793
+
794
+ model_config = AVAILABLE_MODELS[model_key]
795
+
796
+ # Load tokenizer and model
797
+ tokenizer = KronosTokenizer.from_pretrained(model_config['tokenizer_id'])
798
+ model = Kronos.from_pretrained(model_config['model_id'])
799
+
800
+ # Create predictor
801
+ predictor = KronosPredictor(model, tokenizer, device=device, max_context=model_config['context_length'])
802
+
803
+ return jsonify({
804
+ 'success': True,
805
+ 'message': f'Model loaded successfully: {model_config["name"]} ({model_config["params"]}) on {device}',
806
+ 'model_info': {
807
+ 'name': model_config['name'],
808
+ 'params': model_config['params'],
809
+ 'context_length': model_config['context_length'],
810
+ 'description': model_config['description']
811
+ }
812
+ })
813
+
814
+ except Exception as e:
815
+ return jsonify({'error': f'Model loading failed: {str(e)}'}), 500
816
+
817
+
818
+ @app.route('/api/available-models')
819
+ def get_available_models():
820
+ """Get available model list"""
821
+ return jsonify({
822
+ 'models': AVAILABLE_MODELS,
823
+ 'model_available': MODEL_AVAILABLE
824
+ })
825
+
826
+
827
+ @app.route('/api/model-status')
828
+ def get_model_status():
829
+ """Get model status"""
830
+ if MODEL_AVAILABLE:
831
+ if predictor is not None:
832
+ return jsonify({
833
+ 'available': True,
834
+ 'loaded': True,
835
+ 'message': 'Kronos model loaded and available',
836
+ 'current_model': {
837
+ 'name': predictor.model.__class__.__name__,
838
+ 'device': str(next(predictor.model.parameters()).device)
839
+ }
840
+ })
841
+ else:
842
+ return jsonify({
843
+ 'available': True,
844
+ 'loaded': False,
845
+ 'message': 'Kronos model available but not loaded'
846
+ })
847
+ else:
848
+ return jsonify({
849
+ 'available': False,
850
+ 'loaded': False,
851
+ 'message': 'Kronos model library not available, please install related dependencies'
852
+ })
853
+
854
+
855
+ if __name__ == '__main__':
856
+ print("Starting Kronos Web UI...")
857
+ print(f"Model availability: {MODEL_AVAILABLE}")
858
+ if MODEL_AVAILABLE:
859
+ print("Tip: You can load Kronos model through /api/load-model endpoint")
860
+ else:
861
+ print("Tip: Will use simulated data for demonstration")
862
+
863
+ app.run(debug=True, host='0.0.0.0', port=7070)
webui/docker_start.sh ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # Kronos Web UI Docker startup script
4
+
5
+ echo "🚀 Starting Kronos Web UI in Docker..."
6
+ echo "======================================"
7
+
8
+ # Check if we're in the correct directory
9
+ if [ ! -f "app.py" ]; then
10
+ echo "❌ app.py not found, please check the working directory"
11
+ exit 1
12
+ fi
13
+
14
+ # Set environment variables
15
+ export PYTHONPATH=/app
16
+ export FLASK_APP=webui/app.py
17
+ export FLASK_ENV=production
18
+
19
+ # Create necessary directories
20
+ mkdir -p prediction_results
21
+ mkdir -p model/data
22
+
23
+ # Check if model is available
24
+ python3 -c "
25
+ try:
26
+ from model import Kronos, KronosTokenizer, KronosPredictor
27
+ print('✅ Kronos model library available')
28
+ except ImportError as e:
29
+ print(f'⚠️ Kronos model library not available: {e}')
30
+ print(' Will use simulated data for demonstration')
31
+ "
32
+
33
+ # Start the Flask application
34
+ echo "🌐 Starting Flask server on port 7860..."
35
+ echo "Access URL: http://localhost:7860"
36
+ echo "Press Ctrl+C to stop server"
37
+ echo ""
38
+
39
+ # Use gunicorn for production if available, otherwise use Flask dev server
40
+ if command -v gunicorn &> /dev/null; then
41
+ echo "Using Gunicorn for production..."
42
+ exec gunicorn --bind 0.0.0.0:7860 --workers 2 --timeout 120 --access-logfile - --error-logfile - app:app
43
+ else
44
+ echo "Using Flask development server..."
45
+ exec python3 app.py
46
+ fi
webui/prediction_results/prediction_20250828_184347.json ADDED
@@ -0,0 +1,2243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "timestamp": "2025-08-28T18:43:47.791765",
3
+ "file_path": "ETHUSDT_1h",
4
+ "prediction_type": "Kronos model prediction (latest data)",
5
+ "prediction_params": {
6
+ "symbol": "ETHUSDT",
7
+ "interval": "1h",
8
+ "limit": 1000,
9
+ "lookback": 400,
10
+ "pred_len": 120,
11
+ "temperature": 1.0,
12
+ "top_p": 0.9,
13
+ "sample_count": 1,
14
+ "start_date": "latest"
15
+ },
16
+ "input_data_summary": {
17
+ "rows": 400,
18
+ "columns": [
19
+ "open",
20
+ "high",
21
+ "low",
22
+ "close",
23
+ "volume",
24
+ "amount"
25
+ ],
26
+ "price_range": {
27
+ "open": {
28
+ "min": 3383.2,
29
+ "max": 3929.79
30
+ },
31
+ "high": {
32
+ "min": 3412.59,
33
+ "max": 3941.0
34
+ },
35
+ "low": {
36
+ "min": 3354.28,
37
+ "max": 3909.72
38
+ },
39
+ "close": {
40
+ "min": 3383.2,
41
+ "max": 3929.8
42
+ }
43
+ },
44
+ "last_values": {
45
+ "open": 3466.26,
46
+ "high": 3488.0,
47
+ "low": 3465.21,
48
+ "close": 3484.94
49
+ }
50
+ },
51
+ "prediction_results": [
52
+ {
53
+ "timestamp": "2025-08-28T19:00:00+08:00",
54
+ "open": 3468.14892578125,
55
+ "high": 3476.130126953125,
56
+ "low": 3447.22314453125,
57
+ "close": 3457.6015625,
58
+ "volume": 11822.2060546875,
59
+ "amount": 41490972.0
60
+ },
61
+ {
62
+ "timestamp": "2025-08-28T20:00:00+08:00",
63
+ "open": 3461.814208984375,
64
+ "high": 3499.876953125,
65
+ "low": 3450.8935546875,
66
+ "close": 3488.62548828125,
67
+ "volume": 14990.9091796875,
68
+ "amount": 51411228.0
69
+ },
70
+ {
71
+ "timestamp": "2025-08-28T21:00:00+08:00",
72
+ "open": 3483.72119140625,
73
+ "high": 3499.249267578125,
74
+ "low": 3466.6474609375,
75
+ "close": 3483.294677734375,
76
+ "volume": 13611.0146484375,
77
+ "amount": 47573660.0
78
+ },
79
+ {
80
+ "timestamp": "2025-08-28T22:00:00+08:00",
81
+ "open": 3503.0693359375,
82
+ "high": 3514.906005859375,
83
+ "low": 3452.087890625,
84
+ "close": 3461.633544921875,
85
+ "volume": 23598.255859375,
86
+ "amount": 80013608.0
87
+ },
88
+ {
89
+ "timestamp": "2025-08-28T23:00:00+08:00",
90
+ "open": 3472.73681640625,
91
+ "high": 3483.671875,
92
+ "low": 3452.955322265625,
93
+ "close": 3466.7421875,
94
+ "volume": 13364.9931640625,
95
+ "amount": 45953844.0
96
+ },
97
+ {
98
+ "timestamp": "2025-08-29T00:00:00+08:00",
99
+ "open": 3471.701171875,
100
+ "high": 3507.112548828125,
101
+ "low": 3455.1953125,
102
+ "close": 3490.139404296875,
103
+ "volume": 29673.27734375,
104
+ "amount": 98473200.0
105
+ },
106
+ {
107
+ "timestamp": "2025-08-29T01:00:00+08:00",
108
+ "open": 3510.8427734375,
109
+ "high": 3544.874267578125,
110
+ "low": 3489.832763671875,
111
+ "close": 3517.6767578125,
112
+ "volume": 29258.44140625,
113
+ "amount": 99728368.0
114
+ },
115
+ {
116
+ "timestamp": "2025-08-29T02:00:00+08:00",
117
+ "open": 3514.7841796875,
118
+ "high": 3528.6025390625,
119
+ "low": 3489.89697265625,
120
+ "close": 3508.23583984375,
121
+ "volume": 22397.392578125,
122
+ "amount": 76663296.0
123
+ },
124
+ {
125
+ "timestamp": "2025-08-29T03:00:00+08:00",
126
+ "open": 3513.5546875,
127
+ "high": 3519.365234375,
128
+ "low": 3463.162841796875,
129
+ "close": 3474.033203125,
130
+ "volume": 28335.953125,
131
+ "amount": 95009912.0
132
+ },
133
+ {
134
+ "timestamp": "2025-08-29T04:00:00+08:00",
135
+ "open": 3475.752197265625,
136
+ "high": 3498.843017578125,
137
+ "low": 3455.8115234375,
138
+ "close": 3478.194091796875,
139
+ "volume": 23878.3984375,
140
+ "amount": 79594720.0
141
+ },
142
+ {
143
+ "timestamp": "2025-08-29T05:00:00+08:00",
144
+ "open": 3467.24853515625,
145
+ "high": 3482.260498046875,
146
+ "low": 3427.906982421875,
147
+ "close": 3448.40478515625,
148
+ "volume": 29498.138671875,
149
+ "amount": 96328576.0
150
+ },
151
+ {
152
+ "timestamp": "2025-08-29T06:00:00+08:00",
153
+ "open": 3439.564208984375,
154
+ "high": 3473.7197265625,
155
+ "low": 3407.775146484375,
156
+ "close": 3447.84375,
157
+ "volume": 38097.359375,
158
+ "amount": 123009160.0
159
+ },
160
+ {
161
+ "timestamp": "2025-08-29T07:00:00+08:00",
162
+ "open": 3433.309326171875,
163
+ "high": 3447.677001953125,
164
+ "low": 3393.175048828125,
165
+ "close": 3410.229248046875,
166
+ "volume": 26765.513671875,
167
+ "amount": 85481504.0
168
+ },
169
+ {
170
+ "timestamp": "2025-08-29T08:00:00+08:00",
171
+ "open": 3416.614990234375,
172
+ "high": 3460.13720703125,
173
+ "low": 3399.771484375,
174
+ "close": 3439.709228515625,
175
+ "volume": 26403.80859375,
176
+ "amount": 84065496.0
177
+ },
178
+ {
179
+ "timestamp": "2025-08-29T09:00:00+08:00",
180
+ "open": 3451.199951171875,
181
+ "high": 3469.704833984375,
182
+ "low": 3417.040771484375,
183
+ "close": 3436.0166015625,
184
+ "volume": 31116.67578125,
185
+ "amount": 101487776.0
186
+ },
187
+ {
188
+ "timestamp": "2025-08-29T10:00:00+08:00",
189
+ "open": 3432.70458984375,
190
+ "high": 3472.6015625,
191
+ "low": 3415.297607421875,
192
+ "close": 3454.004638671875,
193
+ "volume": 25828.935546875,
194
+ "amount": 84078160.0
195
+ },
196
+ {
197
+ "timestamp": "2025-08-29T11:00:00+08:00",
198
+ "open": 3440.9443359375,
199
+ "high": 3465.64013671875,
200
+ "low": 3416.551025390625,
201
+ "close": 3442.333984375,
202
+ "volume": 33883.79296875,
203
+ "amount": 108258472.0
204
+ },
205
+ {
206
+ "timestamp": "2025-08-29T12:00:00+08:00",
207
+ "open": 3439.764404296875,
208
+ "high": 3449.08349609375,
209
+ "low": 3417.070556640625,
210
+ "close": 3428.1455078125,
211
+ "volume": 13853.611328125,
212
+ "amount": 46947156.0
213
+ },
214
+ {
215
+ "timestamp": "2025-08-29T13:00:00+08:00",
216
+ "open": 3449.460693359375,
217
+ "high": 3472.006591796875,
218
+ "low": 3415.291015625,
219
+ "close": 3436.240966796875,
220
+ "volume": 31302.556640625,
221
+ "amount": 98996696.0
222
+ },
223
+ {
224
+ "timestamp": "2025-08-29T14:00:00+08:00",
225
+ "open": 3431.794677734375,
226
+ "high": 3449.3583984375,
227
+ "low": 3410.71484375,
228
+ "close": 3425.410888671875,
229
+ "volume": 21295.623046875,
230
+ "amount": 69638944.0
231
+ },
232
+ {
233
+ "timestamp": "2025-08-29T15:00:00+08:00",
234
+ "open": 3405.3408203125,
235
+ "high": 3429.2470703125,
236
+ "low": 3361.233642578125,
237
+ "close": 3385.927734375,
238
+ "volume": 34861.234375,
239
+ "amount": 109210472.0
240
+ },
241
+ {
242
+ "timestamp": "2025-08-29T16:00:00+08:00",
243
+ "open": 3381.72900390625,
244
+ "high": 3446.140625,
245
+ "low": 3362.82666015625,
246
+ "close": 3425.9697265625,
247
+ "volume": 33529.0546875,
248
+ "amount": 106655240.0
249
+ },
250
+ {
251
+ "timestamp": "2025-08-29T17:00:00+08:00",
252
+ "open": 3425.0419921875,
253
+ "high": 3453.053466796875,
254
+ "low": 3406.19677734375,
255
+ "close": 3431.833251953125,
256
+ "volume": 27149.974609375,
257
+ "amount": 87418696.0
258
+ },
259
+ {
260
+ "timestamp": "2025-08-29T18:00:00+08:00",
261
+ "open": 3442.406982421875,
262
+ "high": 3482.64990234375,
263
+ "low": 3425.232666015625,
264
+ "close": 3463.140625,
265
+ "volume": 33164.15234375,
266
+ "amount": 110002776.0
267
+ },
268
+ {
269
+ "timestamp": "2025-08-29T19:00:00+08:00",
270
+ "open": 3465.9921875,
271
+ "high": 3506.56591796875,
272
+ "low": 3448.1884765625,
273
+ "close": 3489.350341796875,
274
+ "volume": 31491.951171875,
275
+ "amount": 105813880.0
276
+ },
277
+ {
278
+ "timestamp": "2025-08-29T20:00:00+08:00",
279
+ "open": 3483.676025390625,
280
+ "high": 3503.85205078125,
281
+ "low": 3467.48291015625,
282
+ "close": 3488.96875,
283
+ "volume": 16379.38671875,
284
+ "amount": 56624872.0
285
+ },
286
+ {
287
+ "timestamp": "2025-08-29T21:00:00+08:00",
288
+ "open": 3488.94091796875,
289
+ "high": 3510.781005859375,
290
+ "low": 3463.559814453125,
291
+ "close": 3489.7548828125,
292
+ "volume": 26487.48828125,
293
+ "amount": 89625680.0
294
+ },
295
+ {
296
+ "timestamp": "2025-08-29T22:00:00+08:00",
297
+ "open": 3481.56591796875,
298
+ "high": 3492.911376953125,
299
+ "low": 3458.482177734375,
300
+ "close": 3470.540283203125,
301
+ "volume": 17526.03125,
302
+ "amount": 60344644.0
303
+ },
304
+ {
305
+ "timestamp": "2025-08-29T23:00:00+08:00",
306
+ "open": 3469.722900390625,
307
+ "high": 3486.805419921875,
308
+ "low": 3455.75244140625,
309
+ "close": 3471.106689453125,
310
+ "volume": 14491.2421875,
311
+ "amount": 50355272.0
312
+ },
313
+ {
314
+ "timestamp": "2025-08-30T00:00:00+08:00",
315
+ "open": 3468.894775390625,
316
+ "high": 3487.218017578125,
317
+ "low": 3446.548583984375,
318
+ "close": 3466.410888671875,
319
+ "volume": 21765.0390625,
320
+ "amount": 73304280.0
321
+ },
322
+ {
323
+ "timestamp": "2025-08-30T01:00:00+08:00",
324
+ "open": 3466.30908203125,
325
+ "high": 3485.128173828125,
326
+ "low": 3444.802734375,
327
+ "close": 3464.304443359375,
328
+ "volume": 23290.185546875,
329
+ "amount": 77930928.0
330
+ },
331
+ {
332
+ "timestamp": "2025-08-30T02:00:00+08:00",
333
+ "open": 3475.242431640625,
334
+ "high": 3492.35400390625,
335
+ "low": 3437.67626953125,
336
+ "close": 3455.584228515625,
337
+ "volume": 32366.541015625,
338
+ "amount": 104928336.0
339
+ },
340
+ {
341
+ "timestamp": "2025-08-30T03:00:00+08:00",
342
+ "open": 3439.1904296875,
343
+ "high": 3458.9365234375,
344
+ "low": 3411.313232421875,
345
+ "close": 3432.90478515625,
346
+ "volume": 23476.369140625,
347
+ "amount": 78507928.0
348
+ },
349
+ {
350
+ "timestamp": "2025-08-30T04:00:00+08:00",
351
+ "open": 3430.857177734375,
352
+ "high": 3473.16015625,
353
+ "low": 3412.4482421875,
354
+ "close": 3455.3232421875,
355
+ "volume": 24322.662109375,
356
+ "amount": 79716152.0
357
+ },
358
+ {
359
+ "timestamp": "2025-08-30T05:00:00+08:00",
360
+ "open": 3460.14306640625,
361
+ "high": 3505.022705078125,
362
+ "low": 3445.50048828125,
363
+ "close": 3487.989501953125,
364
+ "volume": 25433.70703125,
365
+ "amount": 85826544.0
366
+ },
367
+ {
368
+ "timestamp": "2025-08-30T06:00:00+08:00",
369
+ "open": 3481.59619140625,
370
+ "high": 3498.063720703125,
371
+ "low": 3460.976806640625,
372
+ "close": 3478.622314453125,
373
+ "volume": 19458.09765625,
374
+ "amount": 66888076.0
375
+ },
376
+ {
377
+ "timestamp": "2025-08-30T07:00:00+08:00",
378
+ "open": 3472.95947265625,
379
+ "high": 3497.14892578125,
380
+ "low": 3441.0693359375,
381
+ "close": 3475.32275390625,
382
+ "volume": 22292.001953125,
383
+ "amount": 71040912.0
384
+ },
385
+ {
386
+ "timestamp": "2025-08-30T08:00:00+08:00",
387
+ "open": 3482.1015625,
388
+ "high": 3509.3486328125,
389
+ "low": 3465.51025390625,
390
+ "close": 3494.0234375,
391
+ "volume": 21343.0625,
392
+ "amount": 71492904.0
393
+ },
394
+ {
395
+ "timestamp": "2025-08-30T09:00:00+08:00",
396
+ "open": 3493.76025390625,
397
+ "high": 3509.20556640625,
398
+ "low": 3470.673828125,
399
+ "close": 3493.825927734375,
400
+ "volume": 18176.375,
401
+ "amount": 61656444.0
402
+ },
403
+ {
404
+ "timestamp": "2025-08-30T10:00:00+08:00",
405
+ "open": 3497.45166015625,
406
+ "high": 3511.575927734375,
407
+ "low": 3476.6875,
408
+ "close": 3493.53662109375,
409
+ "volume": 15902.19140625,
410
+ "amount": 55375516.0
411
+ },
412
+ {
413
+ "timestamp": "2025-08-30T11:00:00+08:00",
414
+ "open": 3495.31982421875,
415
+ "high": 3522.240478515625,
416
+ "low": 3477.999755859375,
417
+ "close": 3513.140380859375,
418
+ "volume": 15443.646484375,
419
+ "amount": 54717752.0
420
+ },
421
+ {
422
+ "timestamp": "2025-08-30T12:00:00+08:00",
423
+ "open": 3513.2119140625,
424
+ "high": 3533.237060546875,
425
+ "low": 3485.8349609375,
426
+ "close": 3515.5625,
427
+ "volume": 16526.314453125,
428
+ "amount": 57483684.0
429
+ },
430
+ {
431
+ "timestamp": "2025-08-30T13:00:00+08:00",
432
+ "open": 3513.151123046875,
433
+ "high": 3533.728515625,
434
+ "low": 3488.749755859375,
435
+ "close": 3511.3828125,
436
+ "volume": 29275.87890625,
437
+ "amount": 99888296.0
438
+ },
439
+ {
440
+ "timestamp": "2025-08-30T14:00:00+08:00",
441
+ "open": 3506.642578125,
442
+ "high": 3531.968505859375,
443
+ "low": 3486.180908203125,
444
+ "close": 3517.985595703125,
445
+ "volume": 23027.29296875,
446
+ "amount": 78585664.0
447
+ },
448
+ {
449
+ "timestamp": "2025-08-30T15:00:00+08:00",
450
+ "open": 3531.1796875,
451
+ "high": 3539.64892578125,
452
+ "low": 3492.451416015625,
453
+ "close": 3501.460205078125,
454
+ "volume": 20179.0859375,
455
+ "amount": 70712592.0
456
+ },
457
+ {
458
+ "timestamp": "2025-08-30T16:00:00+08:00",
459
+ "open": 3505.10400390625,
460
+ "high": 3523.694580078125,
461
+ "low": 3487.6943359375,
462
+ "close": 3506.3369140625,
463
+ "volume": 18263.3359375,
464
+ "amount": 63227472.0
465
+ },
466
+ {
467
+ "timestamp": "2025-08-30T17:00:00+08:00",
468
+ "open": 3507.10693359375,
469
+ "high": 3524.10888671875,
470
+ "low": 3481.83154296875,
471
+ "close": 3502.443115234375,
472
+ "volume": 28682.345703125,
473
+ "amount": 99056448.0
474
+ },
475
+ {
476
+ "timestamp": "2025-08-30T18:00:00+08:00",
477
+ "open": 3500.263671875,
478
+ "high": 3512.617431640625,
479
+ "low": 3480.970458984375,
480
+ "close": 3494.75537109375,
481
+ "volume": 13585.0888671875,
482
+ "amount": 47761664.0
483
+ },
484
+ {
485
+ "timestamp": "2025-08-30T19:00:00+08:00",
486
+ "open": 3494.47412109375,
487
+ "high": 3523.316650390625,
488
+ "low": 3482.838623046875,
489
+ "close": 3511.900634765625,
490
+ "volume": 16062.4951171875,
491
+ "amount": 56453180.0
492
+ },
493
+ {
494
+ "timestamp": "2025-08-30T20:00:00+08:00",
495
+ "open": 3508.79150390625,
496
+ "high": 3521.7294921875,
497
+ "low": 3489.431396484375,
498
+ "close": 3505.088623046875,
499
+ "volume": 15340.181640625,
500
+ "amount": 54304496.0
501
+ },
502
+ {
503
+ "timestamp": "2025-08-30T21:00:00+08:00",
504
+ "open": 3514.0986328125,
505
+ "high": 3548.181884765625,
506
+ "low": 3497.149169921875,
507
+ "close": 3537.88623046875,
508
+ "volume": 19336.25,
509
+ "amount": 68097016.0
510
+ },
511
+ {
512
+ "timestamp": "2025-08-30T22:00:00+08:00",
513
+ "open": 3536.456298828125,
514
+ "high": 3581.998291015625,
515
+ "low": 3505.706787109375,
516
+ "close": 3551.600830078125,
517
+ "volume": 37870.69921875,
518
+ "amount": 130169344.0
519
+ },
520
+ {
521
+ "timestamp": "2025-08-30T23:00:00+08:00",
522
+ "open": 3554.302001953125,
523
+ "high": 3572.1083984375,
524
+ "low": 3537.70068359375,
525
+ "close": 3556.613525390625,
526
+ "volume": 16178.5693359375,
527
+ "amount": 57691016.0
528
+ },
529
+ {
530
+ "timestamp": "2025-08-31T00:00:00+08:00",
531
+ "open": 3544.907470703125,
532
+ "high": 3555.91650390625,
533
+ "low": 3509.399658203125,
534
+ "close": 3527.784912109375,
535
+ "volume": 25012.73046875,
536
+ "amount": 86259992.0
537
+ },
538
+ {
539
+ "timestamp": "2025-08-31T01:00:00+08:00",
540
+ "open": 3530.232177734375,
541
+ "high": 3566.323486328125,
542
+ "low": 3511.997314453125,
543
+ "close": 3550.9853515625,
544
+ "volume": 34384.98828125,
545
+ "amount": 118960032.0
546
+ },
547
+ {
548
+ "timestamp": "2025-08-31T02:00:00+08:00",
549
+ "open": 3546.08544921875,
550
+ "high": 3567.689697265625,
551
+ "low": 3520.6572265625,
552
+ "close": 3553.1845703125,
553
+ "volume": 17046.0703125,
554
+ "amount": 61672976.0
555
+ },
556
+ {
557
+ "timestamp": "2025-08-31T03:00:00+08:00",
558
+ "open": 3555.565673828125,
559
+ "high": 3553.3115234375,
560
+ "low": 3496.5009765625,
561
+ "close": 3504.778076171875,
562
+ "volume": 25209.626953125,
563
+ "amount": 90606552.0
564
+ },
565
+ {
566
+ "timestamp": "2025-08-31T04:00:00+08:00",
567
+ "open": 3514.896728515625,
568
+ "high": 3538.239990234375,
569
+ "low": 3497.66064453125,
570
+ "close": 3519.965576171875,
571
+ "volume": 19448.58984375,
572
+ "amount": 67944240.0
573
+ },
574
+ {
575
+ "timestamp": "2025-08-31T05:00:00+08:00",
576
+ "open": 3516.385986328125,
577
+ "high": 3549.198974609375,
578
+ "low": 3496.19873046875,
579
+ "close": 3531.891357421875,
580
+ "volume": 39729.296875,
581
+ "amount": 137073632.0
582
+ },
583
+ {
584
+ "timestamp": "2025-08-31T06:00:00+08:00",
585
+ "open": 3524.895263671875,
586
+ "high": 3558.8916015625,
587
+ "low": 3500.920654296875,
588
+ "close": 3542.42578125,
589
+ "volume": 21010.33984375,
590
+ "amount": 73549496.0
591
+ },
592
+ {
593
+ "timestamp": "2025-08-31T07:00:00+08:00",
594
+ "open": 3540.580078125,
595
+ "high": 3562.463623046875,
596
+ "low": 3520.479736328125,
597
+ "close": 3544.3935546875,
598
+ "volume": 25887.041015625,
599
+ "amount": 89431272.0
600
+ },
601
+ {
602
+ "timestamp": "2025-08-31T08:00:00+08:00",
603
+ "open": 3543.780517578125,
604
+ "high": 3578.470947265625,
605
+ "low": 3531.41943359375,
606
+ "close": 3566.87548828125,
607
+ "volume": 39538.43359375,
608
+ "amount": 137115232.0
609
+ },
610
+ {
611
+ "timestamp": "2025-08-31T09:00:00+08:00",
612
+ "open": 3574.94482421875,
613
+ "high": 3591.615234375,
614
+ "low": 3552.0703125,
615
+ "close": 3571.47021484375,
616
+ "volume": 23257.1328125,
617
+ "amount": 82802704.0
618
+ },
619
+ {
620
+ "timestamp": "2025-08-31T10:00:00+08:00",
621
+ "open": 3570.832763671875,
622
+ "high": 3582.4814453125,
623
+ "low": 3544.106201171875,
624
+ "close": 3561.2314453125,
625
+ "volume": 27277.099609375,
626
+ "amount": 95787896.0
627
+ },
628
+ {
629
+ "timestamp": "2025-08-31T11:00:00+08:00",
630
+ "open": 3561.4560546875,
631
+ "high": 3581.984130859375,
632
+ "low": 3543.4755859375,
633
+ "close": 3568.34716796875,
634
+ "volume": 28733.494140625,
635
+ "amount": 101161608.0
636
+ },
637
+ {
638
+ "timestamp": "2025-08-31T12:00:00+08:00",
639
+ "open": 3573.066650390625,
640
+ "high": 3595.313232421875,
641
+ "low": 3560.29345703125,
642
+ "close": 3581.3408203125,
643
+ "volume": 19071.9765625,
644
+ "amount": 67863536.0
645
+ },
646
+ {
647
+ "timestamp": "2025-08-31T13:00:00+08:00",
648
+ "open": 3583.27001953125,
649
+ "high": 3605.70068359375,
650
+ "low": 3566.567626953125,
651
+ "close": 3588.767578125,
652
+ "volume": 29999.08984375,
653
+ "amount": 106010232.0
654
+ },
655
+ {
656
+ "timestamp": "2025-08-31T14:00:00+08:00",
657
+ "open": 3609.24462890625,
658
+ "high": 3642.2978515625,
659
+ "low": 3576.64013671875,
660
+ "close": 3603.13916015625,
661
+ "volume": 26337.767578125,
662
+ "amount": 94407848.0
663
+ },
664
+ {
665
+ "timestamp": "2025-08-31T15:00:00+08:00",
666
+ "open": 3610.994873046875,
667
+ "high": 3631.838623046875,
668
+ "low": 3588.931640625,
669
+ "close": 3611.744384765625,
670
+ "volume": 28535.8984375,
671
+ "amount": 101900192.0
672
+ },
673
+ {
674
+ "timestamp": "2025-08-31T16:00:00+08:00",
675
+ "open": 3601.09033203125,
676
+ "high": 3619.553955078125,
677
+ "low": 3572.877685546875,
678
+ "close": 3597.489990234375,
679
+ "volume": 35363.2109375,
680
+ "amount": 125741016.0
681
+ },
682
+ {
683
+ "timestamp": "2025-08-31T17:00:00+08:00",
684
+ "open": 3603.489013671875,
685
+ "high": 3626.448486328125,
686
+ "low": 3571.823486328125,
687
+ "close": 3592.206298828125,
688
+ "volume": 34616.64453125,
689
+ "amount": 123871432.0
690
+ },
691
+ {
692
+ "timestamp": "2025-08-31T18:00:00+08:00",
693
+ "open": 3591.42822265625,
694
+ "high": 3614.21142578125,
695
+ "low": 3574.286376953125,
696
+ "close": 3598.65673828125,
697
+ "volume": 43010.1015625,
698
+ "amount": 152287072.0
699
+ },
700
+ {
701
+ "timestamp": "2025-08-31T19:00:00+08:00",
702
+ "open": 3609.3896484375,
703
+ "high": 3631.5693359375,
704
+ "low": 3567.523681640625,
705
+ "close": 3586.775634765625,
706
+ "volume": 46034.44921875,
707
+ "amount": 164477792.0
708
+ },
709
+ {
710
+ "timestamp": "2025-08-31T20:00:00+08:00",
711
+ "open": 3601.6044921875,
712
+ "high": 3631.02685546875,
713
+ "low": 3585.49755859375,
714
+ "close": 3618.29931640625,
715
+ "volume": 34731.8828125,
716
+ "amount": 124306624.0
717
+ },
718
+ {
719
+ "timestamp": "2025-08-31T21:00:00+08:00",
720
+ "open": 3627.4541015625,
721
+ "high": 3645.651123046875,
722
+ "low": 3588.77197265625,
723
+ "close": 3604.88427734375,
724
+ "volume": 33821.76953125,
725
+ "amount": 121511600.0
726
+ },
727
+ {
728
+ "timestamp": "2025-08-31T22:00:00+08:00",
729
+ "open": 3609.21630859375,
730
+ "high": 3624.7626953125,
731
+ "low": 3589.6396484375,
732
+ "close": 3608.43701171875,
733
+ "volume": 19986.55078125,
734
+ "amount": 71930064.0
735
+ },
736
+ {
737
+ "timestamp": "2025-08-31T23:00:00+08:00",
738
+ "open": 3605.911376953125,
739
+ "high": 3622.1708984375,
740
+ "low": 3583.413818359375,
741
+ "close": 3605.765380859375,
742
+ "volume": 36891.55078125,
743
+ "amount": 131533088.0
744
+ },
745
+ {
746
+ "timestamp": "2025-09-01T00:00:00+08:00",
747
+ "open": 3603.644775390625,
748
+ "high": 3618.170166015625,
749
+ "low": 3588.930908203125,
750
+ "close": 3606.161376953125,
751
+ "volume": 13745.3837890625,
752
+ "amount": 50117124.0
753
+ },
754
+ {
755
+ "timestamp": "2025-09-01T01:00:00+08:00",
756
+ "open": 3618.791015625,
757
+ "high": 3615.46728515625,
758
+ "low": 3586.7783203125,
759
+ "close": 3594.759521484375,
760
+ "volume": 22564.8671875,
761
+ "amount": 81858480.0
762
+ },
763
+ {
764
+ "timestamp": "2025-09-01T02:00:00+08:00",
765
+ "open": 3609.00244140625,
766
+ "high": 3645.954345703125,
767
+ "low": 3594.9208984375,
768
+ "close": 3632.624755859375,
769
+ "volume": 40672.64453125,
770
+ "amount": 145219552.0
771
+ },
772
+ {
773
+ "timestamp": "2025-09-01T03:00:00+08:00",
774
+ "open": 3634.521240234375,
775
+ "high": 3658.514892578125,
776
+ "low": 3616.27490234375,
777
+ "close": 3639.481689453125,
778
+ "volume": 30849.6875,
779
+ "amount": 112328224.0
780
+ },
781
+ {
782
+ "timestamp": "2025-09-01T04:00:00+08:00",
783
+ "open": 3637.838134765625,
784
+ "high": 3653.825439453125,
785
+ "low": 3615.41064453125,
786
+ "close": 3632.104248046875,
787
+ "volume": 27218.19921875,
788
+ "amount": 98525912.0
789
+ },
790
+ {
791
+ "timestamp": "2025-09-01T05:00:00+08:00",
792
+ "open": 3633.328369140625,
793
+ "high": 3647.701416015625,
794
+ "low": 3618.96826171875,
795
+ "close": 3636.32568359375,
796
+ "volume": 12220.6640625,
797
+ "amount": 44403348.0
798
+ },
799
+ {
800
+ "timestamp": "2025-09-01T06:00:00+08:00",
801
+ "open": 3655.7119140625,
802
+ "high": 3677.554443359375,
803
+ "low": 3599.05517578125,
804
+ "close": 3620.9833984375,
805
+ "volume": 29162.8828125,
806
+ "amount": 110434336.0
807
+ },
808
+ {
809
+ "timestamp": "2025-09-01T07:00:00+08:00",
810
+ "open": 3635.944580078125,
811
+ "high": 3657.149169921875,
812
+ "low": 3617.201904296875,
813
+ "close": 3638.95751953125,
814
+ "volume": 27112.767578125,
815
+ "amount": 98672976.0
816
+ },
817
+ {
818
+ "timestamp": "2025-09-01T08:00:00+08:00",
819
+ "open": 3706.15478515625,
820
+ "high": 3768.969482421875,
821
+ "low": 3599.4306640625,
822
+ "close": 3641.33056640625,
823
+ "volume": 26431.27734375,
824
+ "amount": 98242376.0
825
+ },
826
+ {
827
+ "timestamp": "2025-09-01T09:00:00+08:00",
828
+ "open": 3650.827880859375,
829
+ "high": 3666.99609375,
830
+ "low": 3626.406494140625,
831
+ "close": 3645.767333984375,
832
+ "volume": 21349.005859375,
833
+ "amount": 77676432.0
834
+ },
835
+ {
836
+ "timestamp": "2025-09-01T10:00:00+08:00",
837
+ "open": 3647.571044921875,
838
+ "high": 3666.177001953125,
839
+ "low": 3625.84130859375,
840
+ "close": 3646.537841796875,
841
+ "volume": 31924.48046875,
842
+ "amount": 115758112.0
843
+ },
844
+ {
845
+ "timestamp": "2025-09-01T11:00:00+08:00",
846
+ "open": 3647.4833984375,
847
+ "high": 3668.267822265625,
848
+ "low": 3628.75537109375,
849
+ "close": 3652.542236328125,
850
+ "volume": 35726.5546875,
851
+ "amount": 129920816.0
852
+ },
853
+ {
854
+ "timestamp": "2025-09-01T12:00:00+08:00",
855
+ "open": 3700.94970703125,
856
+ "high": 3712.095947265625,
857
+ "low": 3630.115478515625,
858
+ "close": 3645.3837890625,
859
+ "volume": 33909.453125,
860
+ "amount": 129076672.0
861
+ },
862
+ {
863
+ "timestamp": "2025-09-01T13:00:00+08:00",
864
+ "open": 3659.6240234375,
865
+ "high": 3683.8955078125,
866
+ "low": 3642.53369140625,
867
+ "close": 3673.70263671875,
868
+ "volume": 22655.662109375,
869
+ "amount": 84269184.0
870
+ },
871
+ {
872
+ "timestamp": "2025-09-01T14:00:00+08:00",
873
+ "open": 3671.739013671875,
874
+ "high": 3689.649169921875,
875
+ "low": 3654.13671875,
876
+ "close": 3676.41064453125,
877
+ "volume": 19736.21875,
878
+ "amount": 73153760.0
879
+ },
880
+ {
881
+ "timestamp": "2025-09-01T15:00:00+08:00",
882
+ "open": 3668.830322265625,
883
+ "high": 3677.822021484375,
884
+ "low": 3632.979248046875,
885
+ "close": 3645.85400390625,
886
+ "volume": 32829.375,
887
+ "amount": 120742400.0
888
+ },
889
+ {
890
+ "timestamp": "2025-09-01T16:00:00+08:00",
891
+ "open": 3644.898193359375,
892
+ "high": 3661.139404296875,
893
+ "low": 3623.921630859375,
894
+ "close": 3642.707763671875,
895
+ "volume": 22472.23046875,
896
+ "amount": 82116160.0
897
+ },
898
+ {
899
+ "timestamp": "2025-09-01T17:00:00+08:00",
900
+ "open": 3642.300048828125,
901
+ "high": 3663.891357421875,
902
+ "low": 3627.124755859375,
903
+ "close": 3651.3369140625,
904
+ "volume": 25698.533203125,
905
+ "amount": 93891680.0
906
+ },
907
+ {
908
+ "timestamp": "2025-09-01T18:00:00+08:00",
909
+ "open": 3647.7666015625,
910
+ "high": 3659.95458984375,
911
+ "low": 3623.6650390625,
912
+ "close": 3645.59423828125,
913
+ "volume": 29862.859375,
914
+ "amount": 109192208.0
915
+ },
916
+ {
917
+ "timestamp": "2025-09-01T19:00:00+08:00",
918
+ "open": 3639.471435546875,
919
+ "high": 3652.29248046875,
920
+ "low": 3620.84765625,
921
+ "close": 3643.015380859375,
922
+ "volume": 38507.26171875,
923
+ "amount": 139202304.0
924
+ },
925
+ {
926
+ "timestamp": "2025-09-01T20:00:00+08:00",
927
+ "open": 3650.572021484375,
928
+ "high": 3645.328857421875,
929
+ "low": 3617.303466796875,
930
+ "close": 3620.720947265625,
931
+ "volume": 24788.48046875,
932
+ "amount": 91357856.0
933
+ },
934
+ {
935
+ "timestamp": "2025-09-01T21:00:00+08:00",
936
+ "open": 3623.6982421875,
937
+ "high": 3630.431396484375,
938
+ "low": 3596.617431640625,
939
+ "close": 3608.395751953125,
940
+ "volume": 19434.51953125,
941
+ "amount": 70918184.0
942
+ },
943
+ {
944
+ "timestamp": "2025-09-01T22:00:00+08:00",
945
+ "open": 3612.80810546875,
946
+ "high": 3631.20166015625,
947
+ "low": 3597.616943359375,
948
+ "close": 3618.6123046875,
949
+ "volume": 18826.673828125,
950
+ "amount": 67608392.0
951
+ },
952
+ {
953
+ "timestamp": "2025-09-01T23:00:00+08:00",
954
+ "open": 3621.827392578125,
955
+ "high": 3639.676025390625,
956
+ "low": 3606.2109375,
957
+ "close": 3626.62890625,
958
+ "volume": 20204.71484375,
959
+ "amount": 72770960.0
960
+ },
961
+ {
962
+ "timestamp": "2025-09-02T00:00:00+08:00",
963
+ "open": 3628.596435546875,
964
+ "high": 3641.76708984375,
965
+ "low": 3600.493896484375,
966
+ "close": 3614.9853515625,
967
+ "volume": 33523.3984375,
968
+ "amount": 121069280.0
969
+ },
970
+ {
971
+ "timestamp": "2025-09-02T01:00:00+08:00",
972
+ "open": 3625.431884765625,
973
+ "high": 3668.158447265625,
974
+ "low": 3613.774169921875,
975
+ "close": 3663.7353515625,
976
+ "volume": 26953.91015625,
977
+ "amount": 97312840.0
978
+ },
979
+ {
980
+ "timestamp": "2025-09-02T02:00:00+08:00",
981
+ "open": 3659.55322265625,
982
+ "high": 3670.4306640625,
983
+ "low": 3627.720703125,
984
+ "close": 3647.45947265625,
985
+ "volume": 26681.921875,
986
+ "amount": 96963112.0
987
+ },
988
+ {
989
+ "timestamp": "2025-09-02T03:00:00+08:00",
990
+ "open": 3643.05078125,
991
+ "high": 3651.91552734375,
992
+ "low": 3611.958251953125,
993
+ "close": 3625.541259765625,
994
+ "volume": 18680.94140625,
995
+ "amount": 68299552.0
996
+ },
997
+ {
998
+ "timestamp": "2025-09-02T04:00:00+08:00",
999
+ "open": 3627.533203125,
1000
+ "high": 3650.206787109375,
1001
+ "low": 3608.2587890625,
1002
+ "close": 3632.515869140625,
1003
+ "volume": 20985.216796875,
1004
+ "amount": 76285968.0
1005
+ },
1006
+ {
1007
+ "timestamp": "2025-09-02T05:00:00+08:00",
1008
+ "open": 3642.9619140625,
1009
+ "high": 3673.5244140625,
1010
+ "low": 3614.7392578125,
1011
+ "close": 3638.457763671875,
1012
+ "volume": 29110.40625,
1013
+ "amount": 106286984.0
1014
+ },
1015
+ {
1016
+ "timestamp": "2025-09-02T06:00:00+08:00",
1017
+ "open": 3649.281982421875,
1018
+ "high": 3673.47119140625,
1019
+ "low": 3625.91162109375,
1020
+ "close": 3647.77001953125,
1021
+ "volume": 32140.509765625,
1022
+ "amount": 117109824.0
1023
+ },
1024
+ {
1025
+ "timestamp": "2025-09-02T07:00:00+08:00",
1026
+ "open": 3648.700439453125,
1027
+ "high": 3664.75537109375,
1028
+ "low": 3629.885498046875,
1029
+ "close": 3647.60693359375,
1030
+ "volume": 20344.96875,
1031
+ "amount": 74699992.0
1032
+ },
1033
+ {
1034
+ "timestamp": "2025-09-02T08:00:00+08:00",
1035
+ "open": 3647.435302734375,
1036
+ "high": 3659.057373046875,
1037
+ "low": 3626.186279296875,
1038
+ "close": 3641.026611328125,
1039
+ "volume": 16247.140625,
1040
+ "amount": 59863400.0
1041
+ },
1042
+ {
1043
+ "timestamp": "2025-09-02T09:00:00+08:00",
1044
+ "open": 3642.234130859375,
1045
+ "high": 3661.250244140625,
1046
+ "low": 3628.173583984375,
1047
+ "close": 3651.25,
1048
+ "volume": 20856.9453125,
1049
+ "amount": 75970800.0
1050
+ },
1051
+ {
1052
+ "timestamp": "2025-09-02T10:00:00+08:00",
1053
+ "open": 3664.116455078125,
1054
+ "high": 3740.093017578125,
1055
+ "low": 3563.56982421875,
1056
+ "close": 3627.733154296875,
1057
+ "volume": 28155.84765625,
1058
+ "amount": 103703080.0
1059
+ },
1060
+ {
1061
+ "timestamp": "2025-09-02T11:00:00+08:00",
1062
+ "open": 3653.74658203125,
1063
+ "high": 3681.43896484375,
1064
+ "low": 3622.62451171875,
1065
+ "close": 3642.622314453125,
1066
+ "volume": 26403.95703125,
1067
+ "amount": 95644768.0
1068
+ },
1069
+ {
1070
+ "timestamp": "2025-09-02T12:00:00+08:00",
1071
+ "open": 3651.860107421875,
1072
+ "high": 3674.969970703125,
1073
+ "low": 3634.89599609375,
1074
+ "close": 3660.502197265625,
1075
+ "volume": 20447.05078125,
1076
+ "amount": 75581792.0
1077
+ },
1078
+ {
1079
+ "timestamp": "2025-09-02T13:00:00+08:00",
1080
+ "open": 3657.2568359375,
1081
+ "high": 3671.539306640625,
1082
+ "low": 3642.1376953125,
1083
+ "close": 3658.734619140625,
1084
+ "volume": 14799.5439453125,
1085
+ "amount": 54890104.0
1086
+ },
1087
+ {
1088
+ "timestamp": "2025-09-02T14:00:00+08:00",
1089
+ "open": 3659.761474609375,
1090
+ "high": 3672.185791015625,
1091
+ "low": 3643.5595703125,
1092
+ "close": 3659.8720703125,
1093
+ "volume": 13889.8310546875,
1094
+ "amount": 51610440.0
1095
+ },
1096
+ {
1097
+ "timestamp": "2025-09-02T15:00:00+08:00",
1098
+ "open": 3647.686279296875,
1099
+ "high": 3666.09814453125,
1100
+ "low": 3629.409423828125,
1101
+ "close": 3654.3515625,
1102
+ "volume": 21850.337890625,
1103
+ "amount": 80185176.0
1104
+ },
1105
+ {
1106
+ "timestamp": "2025-09-02T16:00:00+08:00",
1107
+ "open": 3657.072021484375,
1108
+ "high": 3669.529541015625,
1109
+ "low": 3631.63720703125,
1110
+ "close": 3647.35546875,
1111
+ "volume": 18260.533203125,
1112
+ "amount": 67864896.0
1113
+ },
1114
+ {
1115
+ "timestamp": "2025-09-02T17:00:00+08:00",
1116
+ "open": 3660.329345703125,
1117
+ "high": 3683.8974609375,
1118
+ "low": 3625.788818359375,
1119
+ "close": 3642.968017578125,
1120
+ "volume": 25198.13671875,
1121
+ "amount": 91833328.0
1122
+ },
1123
+ {
1124
+ "timestamp": "2025-09-02T18:00:00+08:00",
1125
+ "open": 3648.4814453125,
1126
+ "high": 3673.598876953125,
1127
+ "low": 3632.00390625,
1128
+ "close": 3657.188232421875,
1129
+ "volume": 24749.943359375,
1130
+ "amount": 90996184.0
1131
+ }
1132
+ ],
1133
+ "actual_data": [
1134
+ {
1135
+ "timestamp": "2025-08-03T19:00:00+08:00",
1136
+ "open": 3484.94,
1137
+ "high": 3516.31,
1138
+ "low": 3484.5,
1139
+ "close": 3485.46,
1140
+ "volume": 24185.4187,
1141
+ "amount": 84639993.916648
1142
+ },
1143
+ {
1144
+ "timestamp": "2025-08-03T20:00:00+08:00",
1145
+ "open": 3485.45,
1146
+ "high": 3504.27,
1147
+ "low": 3475.63,
1148
+ "close": 3489.66,
1149
+ "volume": 13322.4888,
1150
+ "amount": 46468415.705146
1151
+ },
1152
+ {
1153
+ "timestamp": "2025-08-03T21:00:00+08:00",
1154
+ "open": 3489.67,
1155
+ "high": 3499.16,
1156
+ "low": 3483.98,
1157
+ "close": 3492.15,
1158
+ "volume": 8257.0432,
1159
+ "amount": 28827905.47964
1160
+ },
1161
+ {
1162
+ "timestamp": "2025-08-03T22:00:00+08:00",
1163
+ "open": 3492.15,
1164
+ "high": 3494.44,
1165
+ "low": 3463.91,
1166
+ "close": 3472.08,
1167
+ "volume": 15904.9333,
1168
+ "amount": 55285842.543492
1169
+ },
1170
+ {
1171
+ "timestamp": "2025-08-03T23:00:00+08:00",
1172
+ "open": 3472.08,
1173
+ "high": 3479.02,
1174
+ "low": 3454.34,
1175
+ "close": 3476.49,
1176
+ "volume": 13775.3339,
1177
+ "amount": 47740813.852397
1178
+ },
1179
+ {
1180
+ "timestamp": "2025-08-04T00:00:00+08:00",
1181
+ "open": 3476.49,
1182
+ "high": 3496.68,
1183
+ "low": 3467.85,
1184
+ "close": 3495.03,
1185
+ "volume": 13016.2107,
1186
+ "amount": 45314415.974091
1187
+ },
1188
+ {
1189
+ "timestamp": "2025-08-04T01:00:00+08:00",
1190
+ "open": 3495.03,
1191
+ "high": 3499.66,
1192
+ "low": 3480.1,
1193
+ "close": 3489.81,
1194
+ "volume": 8693.7508,
1195
+ "amount": 30341439.229837
1196
+ },
1197
+ {
1198
+ "timestamp": "2025-08-04T02:00:00+08:00",
1199
+ "open": 3489.82,
1200
+ "high": 3498.0,
1201
+ "low": 3481.54,
1202
+ "close": 3496.47,
1203
+ "volume": 7343.8967,
1204
+ "amount": 25636455.496089
1205
+ },
1206
+ {
1207
+ "timestamp": "2025-08-04T03:00:00+08:00",
1208
+ "open": 3496.48,
1209
+ "high": 3515.0,
1210
+ "low": 3488.73,
1211
+ "close": 3496.74,
1212
+ "volume": 17761.4273,
1213
+ "amount": 62246145.787179
1214
+ },
1215
+ {
1216
+ "timestamp": "2025-08-04T04:00:00+08:00",
1217
+ "open": 3496.75,
1218
+ "high": 3497.93,
1219
+ "low": 3484.0,
1220
+ "close": 3492.63,
1221
+ "volume": 7579.8708,
1222
+ "amount": 26455230.032259
1223
+ },
1224
+ {
1225
+ "timestamp": "2025-08-04T05:00:00+08:00",
1226
+ "open": 3492.64,
1227
+ "high": 3508.71,
1228
+ "low": 3489.14,
1229
+ "close": 3502.44,
1230
+ "volume": 8030.1638,
1231
+ "amount": 28102767.867
1232
+ },
1233
+ {
1234
+ "timestamp": "2025-08-04T06:00:00+08:00",
1235
+ "open": 3502.44,
1236
+ "high": 3515.49,
1237
+ "low": 3483.5,
1238
+ "close": 3503.41,
1239
+ "volume": 8560.7602,
1240
+ "amount": 29928851.451857
1241
+ },
1242
+ {
1243
+ "timestamp": "2025-08-04T07:00:00+08:00",
1244
+ "open": 3503.41,
1245
+ "high": 3521.79,
1246
+ "low": 3495.19,
1247
+ "close": 3496.74,
1248
+ "volume": 12735.8513,
1249
+ "amount": 44681690.785297
1250
+ },
1251
+ {
1252
+ "timestamp": "2025-08-04T08:00:00+08:00",
1253
+ "open": 3496.75,
1254
+ "high": 3551.98,
1255
+ "low": 3490.73,
1256
+ "close": 3546.17,
1257
+ "volume": 20294.4593,
1258
+ "amount": 71590998.494384
1259
+ },
1260
+ {
1261
+ "timestamp": "2025-08-04T09:00:00+08:00",
1262
+ "open": 3546.16,
1263
+ "high": 3568.32,
1264
+ "low": 3533.84,
1265
+ "close": 3537.84,
1266
+ "volume": 21871.3514,
1267
+ "amount": 77564293.248077
1268
+ },
1269
+ {
1270
+ "timestamp": "2025-08-04T10:00:00+08:00",
1271
+ "open": 3537.85,
1272
+ "high": 3571.88,
1273
+ "low": 3523.66,
1274
+ "close": 3571.66,
1275
+ "volume": 23300.425,
1276
+ "amount": 82627745.273626
1277
+ },
1278
+ {
1279
+ "timestamp": "2025-08-04T11:00:00+08:00",
1280
+ "open": 3571.66,
1281
+ "high": 3576.07,
1282
+ "low": 3555.16,
1283
+ "close": 3556.8,
1284
+ "volume": 10075.0921,
1285
+ "amount": 35901236.309885
1286
+ },
1287
+ {
1288
+ "timestamp": "2025-08-04T12:00:00+08:00",
1289
+ "open": 3556.79,
1290
+ "high": 3565.67,
1291
+ "low": 3536.08,
1292
+ "close": 3539.56,
1293
+ "volume": 14816.6168,
1294
+ "amount": 52589350.405797
1295
+ },
1296
+ {
1297
+ "timestamp": "2025-08-04T13:00:00+08:00",
1298
+ "open": 3539.56,
1299
+ "high": 3541.3,
1300
+ "low": 3524.14,
1301
+ "close": 3533.46,
1302
+ "volume": 10448.7895,
1303
+ "amount": 36896475.237576
1304
+ },
1305
+ {
1306
+ "timestamp": "2025-08-04T14:00:00+08:00",
1307
+ "open": 3533.46,
1308
+ "high": 3541.49,
1309
+ "low": 3520.69,
1310
+ "close": 3538.95,
1311
+ "volume": 11440.8843,
1312
+ "amount": 40408805.963704
1313
+ },
1314
+ {
1315
+ "timestamp": "2025-08-04T15:00:00+08:00",
1316
+ "open": 3538.94,
1317
+ "high": 3554.21,
1318
+ "low": 3536.58,
1319
+ "close": 3551.99,
1320
+ "volume": 10991.9173,
1321
+ "amount": 38974289.242651
1322
+ },
1323
+ {
1324
+ "timestamp": "2025-08-04T16:00:00+08:00",
1325
+ "open": 3552.0,
1326
+ "high": 3564.7,
1327
+ "low": 3542.25,
1328
+ "close": 3550.5,
1329
+ "volume": 16866.3252,
1330
+ "amount": 59951468.933939
1331
+ },
1332
+ {
1333
+ "timestamp": "2025-08-04T17:00:00+08:00",
1334
+ "open": 3550.5,
1335
+ "high": 3563.6,
1336
+ "low": 3545.24,
1337
+ "close": 3547.19,
1338
+ "volume": 9126.3226,
1339
+ "amount": 32443511.665887
1340
+ },
1341
+ {
1342
+ "timestamp": "2025-08-04T18:00:00+08:00",
1343
+ "open": 3547.2,
1344
+ "high": 3574.47,
1345
+ "low": 3545.0,
1346
+ "close": 3554.9,
1347
+ "volume": 11163.6158,
1348
+ "amount": 39746261.004546
1349
+ },
1350
+ {
1351
+ "timestamp": "2025-08-04T19:00:00+08:00",
1352
+ "open": 3554.9,
1353
+ "high": 3566.12,
1354
+ "low": 3549.6,
1355
+ "close": 3555.7,
1356
+ "volume": 8543.0119,
1357
+ "amount": 30386240.888326
1358
+ },
1359
+ {
1360
+ "timestamp": "2025-08-04T20:00:00+08:00",
1361
+ "open": 3555.71,
1362
+ "high": 3573.0,
1363
+ "low": 3551.1,
1364
+ "close": 3570.17,
1365
+ "volume": 8758.9984,
1366
+ "amount": 31196643.68114
1367
+ },
1368
+ {
1369
+ "timestamp": "2025-08-04T21:00:00+08:00",
1370
+ "open": 3570.18,
1371
+ "high": 3621.2,
1372
+ "low": 3560.48,
1373
+ "close": 3621.18,
1374
+ "volume": 39973.0102,
1375
+ "amount": 143630982.008284
1376
+ },
1377
+ {
1378
+ "timestamp": "2025-08-04T22:00:00+08:00",
1379
+ "open": 3621.19,
1380
+ "high": 3665.6,
1381
+ "low": 3618.51,
1382
+ "close": 3639.04,
1383
+ "volume": 62527.0339,
1384
+ "amount": 227846837.110381
1385
+ },
1386
+ {
1387
+ "timestamp": "2025-08-04T23:00:00+08:00",
1388
+ "open": 3639.05,
1389
+ "high": 3657.46,
1390
+ "low": 3634.56,
1391
+ "close": 3648.89,
1392
+ "volume": 24071.5376,
1393
+ "amount": 87751241.502379
1394
+ },
1395
+ {
1396
+ "timestamp": "2025-08-05T00:00:00+08:00",
1397
+ "open": 3648.89,
1398
+ "high": 3698.86,
1399
+ "low": 3648.85,
1400
+ "close": 3685.61,
1401
+ "volume": 31790.7909,
1402
+ "amount": 116832883.158396
1403
+ },
1404
+ {
1405
+ "timestamp": "2025-08-05T01:00:00+08:00",
1406
+ "open": 3685.62,
1407
+ "high": 3718.54,
1408
+ "low": 3678.44,
1409
+ "close": 3681.5,
1410
+ "volume": 29492.6576,
1411
+ "amount": 109099443.74252
1412
+ },
1413
+ {
1414
+ "timestamp": "2025-08-05T02:00:00+08:00",
1415
+ "open": 3681.5,
1416
+ "high": 3693.4,
1417
+ "low": 3671.26,
1418
+ "close": 3676.28,
1419
+ "volume": 11484.4418,
1420
+ "amount": 42275283.151899
1421
+ },
1422
+ {
1423
+ "timestamp": "2025-08-05T03:00:00+08:00",
1424
+ "open": 3676.28,
1425
+ "high": 3688.46,
1426
+ "low": 3666.22,
1427
+ "close": 3669.73,
1428
+ "volume": 12455.6091,
1429
+ "amount": 45797047.636022
1430
+ },
1431
+ {
1432
+ "timestamp": "2025-08-05T04:00:00+08:00",
1433
+ "open": 3669.73,
1434
+ "high": 3713.04,
1435
+ "low": 3661.21,
1436
+ "close": 3700.47,
1437
+ "volume": 17101.3931,
1438
+ "amount": 63093481.917354
1439
+ },
1440
+ {
1441
+ "timestamp": "2025-08-05T05:00:00+08:00",
1442
+ "open": 3700.46,
1443
+ "high": 3732.0,
1444
+ "low": 3699.1,
1445
+ "close": 3710.02,
1446
+ "volume": 18804.2053,
1447
+ "amount": 69861928.66363
1448
+ },
1449
+ {
1450
+ "timestamp": "2025-08-05T06:00:00+08:00",
1451
+ "open": 3710.02,
1452
+ "high": 3736.73,
1453
+ "low": 3710.02,
1454
+ "close": 3732.52,
1455
+ "volume": 23577.2217,
1456
+ "amount": 87873069.64921
1457
+ },
1458
+ {
1459
+ "timestamp": "2025-08-05T07:00:00+08:00",
1460
+ "open": 3732.51,
1461
+ "high": 3733.74,
1462
+ "low": 3709.31,
1463
+ "close": 3720.99,
1464
+ "volume": 14374.2753,
1465
+ "amount": 53479794.443385
1466
+ },
1467
+ {
1468
+ "timestamp": "2025-08-05T08:00:00+08:00",
1469
+ "open": 3720.99,
1470
+ "high": 3722.24,
1471
+ "low": 3693.66,
1472
+ "close": 3697.52,
1473
+ "volume": 18166.7583,
1474
+ "amount": 67297897.954748
1475
+ },
1476
+ {
1477
+ "timestamp": "2025-08-05T09:00:00+08:00",
1478
+ "open": 3697.53,
1479
+ "high": 3707.43,
1480
+ "low": 3678.56,
1481
+ "close": 3680.38,
1482
+ "volume": 13461.5777,
1483
+ "amount": 49706801.158639
1484
+ },
1485
+ {
1486
+ "timestamp": "2025-08-05T10:00:00+08:00",
1487
+ "open": 3680.38,
1488
+ "high": 3688.07,
1489
+ "low": 3672.5,
1490
+ "close": 3680.09,
1491
+ "volume": 20551.5013,
1492
+ "amount": 75582923.838953
1493
+ },
1494
+ {
1495
+ "timestamp": "2025-08-05T11:00:00+08:00",
1496
+ "open": 3680.1,
1497
+ "high": 3681.16,
1498
+ "low": 3648.24,
1499
+ "close": 3651.94,
1500
+ "volume": 22939.5826,
1501
+ "amount": 83967337.074924
1502
+ },
1503
+ {
1504
+ "timestamp": "2025-08-05T12:00:00+08:00",
1505
+ "open": 3651.94,
1506
+ "high": 3667.84,
1507
+ "low": 3635.0,
1508
+ "close": 3649.02,
1509
+ "volume": 14185.1342,
1510
+ "amount": 51808130.057304
1511
+ },
1512
+ {
1513
+ "timestamp": "2025-08-05T13:00:00+08:00",
1514
+ "open": 3649.03,
1515
+ "high": 3668.37,
1516
+ "low": 3646.91,
1517
+ "close": 3664.4,
1518
+ "volume": 11672.3515,
1519
+ "amount": 42721624.244208
1520
+ },
1521
+ {
1522
+ "timestamp": "2025-08-05T14:00:00+08:00",
1523
+ "open": 3664.4,
1524
+ "high": 3679.69,
1525
+ "low": 3635.04,
1526
+ "close": 3650.85,
1527
+ "volume": 17109.5981,
1528
+ "amount": 62641621.966935
1529
+ },
1530
+ {
1531
+ "timestamp": "2025-08-05T15:00:00+08:00",
1532
+ "open": 3650.85,
1533
+ "high": 3656.5,
1534
+ "low": 3601.53,
1535
+ "close": 3613.49,
1536
+ "volume": 27886.6748,
1537
+ "amount": 101066192.319664
1538
+ },
1539
+ {
1540
+ "timestamp": "2025-08-05T16:00:00+08:00",
1541
+ "open": 3613.49,
1542
+ "high": 3637.5,
1543
+ "low": 3608.1,
1544
+ "close": 3634.81,
1545
+ "volume": 18459.413,
1546
+ "amount": 66897128.8631
1547
+ },
1548
+ {
1549
+ "timestamp": "2025-08-05T17:00:00+08:00",
1550
+ "open": 3634.81,
1551
+ "high": 3666.55,
1552
+ "low": 3633.58,
1553
+ "close": 3660.56,
1554
+ "volume": 14570.1279,
1555
+ "amount": 53166877.929179
1556
+ },
1557
+ {
1558
+ "timestamp": "2025-08-05T18:00:00+08:00",
1559
+ "open": 3660.56,
1560
+ "high": 3694.06,
1561
+ "low": 3654.0,
1562
+ "close": 3682.55,
1563
+ "volume": 17429.1474,
1564
+ "amount": 64100752.55806
1565
+ },
1566
+ {
1567
+ "timestamp": "2025-08-05T19:00:00+08:00",
1568
+ "open": 3682.56,
1569
+ "high": 3686.3,
1570
+ "low": 3662.03,
1571
+ "close": 3673.79,
1572
+ "volume": 16969.2144,
1573
+ "amount": 62348030.824123
1574
+ },
1575
+ {
1576
+ "timestamp": "2025-08-05T20:00:00+08:00",
1577
+ "open": 3673.8,
1578
+ "high": 3680.58,
1579
+ "low": 3609.73,
1580
+ "close": 3628.43,
1581
+ "volume": 29620.7096,
1582
+ "amount": 107886418.725765
1583
+ },
1584
+ {
1585
+ "timestamp": "2025-08-05T21:00:00+08:00",
1586
+ "open": 3628.43,
1587
+ "high": 3659.4,
1588
+ "low": 3618.63,
1589
+ "close": 3646.86,
1590
+ "volume": 22651.8476,
1591
+ "amount": 82382659.00909
1592
+ },
1593
+ {
1594
+ "timestamp": "2025-08-05T22:00:00+08:00",
1595
+ "open": 3646.85,
1596
+ "high": 3647.63,
1597
+ "low": 3559.82,
1598
+ "close": 3577.85,
1599
+ "volume": 76416.0033,
1600
+ "amount": 274185452.294548
1601
+ },
1602
+ {
1603
+ "timestamp": "2025-08-05T23:00:00+08:00",
1604
+ "open": 3577.85,
1605
+ "high": 3598.21,
1606
+ "low": 3555.0,
1607
+ "close": 3570.43,
1608
+ "volume": 36957.393,
1609
+ "amount": 132100040.780566
1610
+ },
1611
+ {
1612
+ "timestamp": "2025-08-06T00:00:00+08:00",
1613
+ "open": 3570.43,
1614
+ "high": 3594.4,
1615
+ "low": 3563.07,
1616
+ "close": 3577.67,
1617
+ "volume": 22068.0117,
1618
+ "amount": 78984997.570765
1619
+ },
1620
+ {
1621
+ "timestamp": "2025-08-06T01:00:00+08:00",
1622
+ "open": 3577.67,
1623
+ "high": 3609.08,
1624
+ "low": 3576.53,
1625
+ "close": 3605.53,
1626
+ "volume": 15739.6251,
1627
+ "amount": 56576963.229153
1628
+ },
1629
+ {
1630
+ "timestamp": "2025-08-06T02:00:00+08:00",
1631
+ "open": 3605.53,
1632
+ "high": 3612.26,
1633
+ "low": 3567.81,
1634
+ "close": 3587.69,
1635
+ "volume": 15577.0193,
1636
+ "amount": 55882352.293388
1637
+ },
1638
+ {
1639
+ "timestamp": "2025-08-06T03:00:00+08:00",
1640
+ "open": 3587.7,
1641
+ "high": 3594.9,
1642
+ "low": 3559.71,
1643
+ "close": 3571.66,
1644
+ "volume": 11272.0649,
1645
+ "amount": 40327392.257818
1646
+ },
1647
+ {
1648
+ "timestamp": "2025-08-06T04:00:00+08:00",
1649
+ "open": 3571.65,
1650
+ "high": 3597.7,
1651
+ "low": 3571.65,
1652
+ "close": 3576.5,
1653
+ "volume": 8946.206,
1654
+ "amount": 32064012.977547
1655
+ },
1656
+ {
1657
+ "timestamp": "2025-08-06T05:00:00+08:00",
1658
+ "open": 3576.49,
1659
+ "high": 3590.91,
1660
+ "low": 3570.0,
1661
+ "close": 3575.62,
1662
+ "volume": 8287.7314,
1663
+ "amount": 29684124.219502
1664
+ },
1665
+ {
1666
+ "timestamp": "2025-08-06T06:00:00+08:00",
1667
+ "open": 3575.61,
1668
+ "high": 3598.96,
1669
+ "low": 3546.0,
1670
+ "close": 3597.01,
1671
+ "volume": 15588.6108,
1672
+ "amount": 55611816.749148
1673
+ },
1674
+ {
1675
+ "timestamp": "2025-08-06T07:00:00+08:00",
1676
+ "open": 3597.02,
1677
+ "high": 3624.56,
1678
+ "low": 3593.82,
1679
+ "close": 3612.0,
1680
+ "volume": 12544.655,
1681
+ "amount": 45318178.743317
1682
+ },
1683
+ {
1684
+ "timestamp": "2025-08-06T08:00:00+08:00",
1685
+ "open": 3612.01,
1686
+ "high": 3614.0,
1687
+ "low": 3570.97,
1688
+ "close": 3576.17,
1689
+ "volume": 14701.3921,
1690
+ "amount": 52804179.285012
1691
+ },
1692
+ {
1693
+ "timestamp": "2025-08-06T09:00:00+08:00",
1694
+ "open": 3576.29,
1695
+ "high": 3593.93,
1696
+ "low": 3564.19,
1697
+ "close": 3592.31,
1698
+ "volume": 13311.2163,
1699
+ "amount": 47656767.779134
1700
+ },
1701
+ {
1702
+ "timestamp": "2025-08-06T10:00:00+08:00",
1703
+ "open": 3592.3,
1704
+ "high": 3596.05,
1705
+ "low": 3573.91,
1706
+ "close": 3592.34,
1707
+ "volume": 6947.3673,
1708
+ "amount": 24917823.086425
1709
+ },
1710
+ {
1711
+ "timestamp": "2025-08-06T11:00:00+08:00",
1712
+ "open": 3592.35,
1713
+ "high": 3594.46,
1714
+ "low": 3572.05,
1715
+ "close": 3583.66,
1716
+ "volume": 6443.6362,
1717
+ "amount": 23084846.550522
1718
+ },
1719
+ {
1720
+ "timestamp": "2025-08-06T12:00:00+08:00",
1721
+ "open": 3583.67,
1722
+ "high": 3584.89,
1723
+ "low": 3570.2,
1724
+ "close": 3573.51,
1725
+ "volume": 6999.9054,
1726
+ "amount": 25031420.258159
1727
+ },
1728
+ {
1729
+ "timestamp": "2025-08-06T13:00:00+08:00",
1730
+ "open": 3573.5,
1731
+ "high": 3662.0,
1732
+ "low": 3569.28,
1733
+ "close": 3638.51,
1734
+ "volume": 36791.5623,
1735
+ "amount": 133683042.516564
1736
+ },
1737
+ {
1738
+ "timestamp": "2025-08-06T14:00:00+08:00",
1739
+ "open": 3638.52,
1740
+ "high": 3643.94,
1741
+ "low": 3616.95,
1742
+ "close": 3632.23,
1743
+ "volume": 14135.6883,
1744
+ "amount": 51302216.069645
1745
+ },
1746
+ {
1747
+ "timestamp": "2025-08-06T15:00:00+08:00",
1748
+ "open": 3632.23,
1749
+ "high": 3649.17,
1750
+ "low": 3625.0,
1751
+ "close": 3639.82,
1752
+ "volume": 13062.1164,
1753
+ "amount": 47533535.32585
1754
+ },
1755
+ {
1756
+ "timestamp": "2025-08-06T16:00:00+08:00",
1757
+ "open": 3639.81,
1758
+ "high": 3643.04,
1759
+ "low": 3607.54,
1760
+ "close": 3622.15,
1761
+ "volume": 17163.5719,
1762
+ "amount": 62187556.059639
1763
+ },
1764
+ {
1765
+ "timestamp": "2025-08-06T17:00:00+08:00",
1766
+ "open": 3622.14,
1767
+ "high": 3644.6,
1768
+ "low": 3616.54,
1769
+ "close": 3627.05,
1770
+ "volume": 11538.5576,
1771
+ "amount": 41865931.907236
1772
+ },
1773
+ {
1774
+ "timestamp": "2025-08-06T18:00:00+08:00",
1775
+ "open": 3627.06,
1776
+ "high": 3634.91,
1777
+ "low": 3611.54,
1778
+ "close": 3616.3,
1779
+ "volume": 12126.8385,
1780
+ "amount": 43909457.401443
1781
+ },
1782
+ {
1783
+ "timestamp": "2025-08-06T19:00:00+08:00",
1784
+ "open": 3616.3,
1785
+ "high": 3630.55,
1786
+ "low": 3609.93,
1787
+ "close": 3619.64,
1788
+ "volume": 7406.9453,
1789
+ "amount": 26814863.031456
1790
+ },
1791
+ {
1792
+ "timestamp": "2025-08-06T20:00:00+08:00",
1793
+ "open": 3619.63,
1794
+ "high": 3623.31,
1795
+ "low": 3579.38,
1796
+ "close": 3584.01,
1797
+ "volume": 21252.4327,
1798
+ "amount": 76407389.282446
1799
+ },
1800
+ {
1801
+ "timestamp": "2025-08-06T21:00:00+08:00",
1802
+ "open": 3584.02,
1803
+ "high": 3604.7,
1804
+ "low": 3574.05,
1805
+ "close": 3602.75,
1806
+ "volume": 23925.4513,
1807
+ "amount": 85928233.551377
1808
+ },
1809
+ {
1810
+ "timestamp": "2025-08-06T22:00:00+08:00",
1811
+ "open": 3602.76,
1812
+ "high": 3637.17,
1813
+ "low": 3587.97,
1814
+ "close": 3637.17,
1815
+ "volume": 27369.5503,
1816
+ "amount": 98891239.718361
1817
+ },
1818
+ {
1819
+ "timestamp": "2025-08-06T23:00:00+08:00",
1820
+ "open": 3637.16,
1821
+ "high": 3669.38,
1822
+ "low": 3620.31,
1823
+ "close": 3664.69,
1824
+ "volume": 29992.1527,
1825
+ "amount": 109196193.698316
1826
+ },
1827
+ {
1828
+ "timestamp": "2025-08-07T00:00:00+08:00",
1829
+ "open": 3664.7,
1830
+ "high": 3674.78,
1831
+ "low": 3640.16,
1832
+ "close": 3645.42,
1833
+ "volume": 21273.1646,
1834
+ "amount": 77768093.564447
1835
+ },
1836
+ {
1837
+ "timestamp": "2025-08-07T01:00:00+08:00",
1838
+ "open": 3645.42,
1839
+ "high": 3684.26,
1840
+ "low": 3638.56,
1841
+ "close": 3682.32,
1842
+ "volume": 14136.3406,
1843
+ "amount": 51788514.602329
1844
+ },
1845
+ {
1846
+ "timestamp": "2025-08-07T02:00:00+08:00",
1847
+ "open": 3682.31,
1848
+ "high": 3698.6,
1849
+ "low": 3672.44,
1850
+ "close": 3677.09,
1851
+ "volume": 17679.717,
1852
+ "amount": 65178320.683334
1853
+ },
1854
+ {
1855
+ "timestamp": "2025-08-07T03:00:00+08:00",
1856
+ "open": 3677.08,
1857
+ "high": 3686.15,
1858
+ "low": 3669.11,
1859
+ "close": 3683.65,
1860
+ "volume": 10806.3655,
1861
+ "amount": 39735017.421117
1862
+ },
1863
+ {
1864
+ "timestamp": "2025-08-07T04:00:00+08:00",
1865
+ "open": 3683.66,
1866
+ "high": 3683.66,
1867
+ "low": 3666.89,
1868
+ "close": 3674.54,
1869
+ "volume": 9692.9289,
1870
+ "amount": 35615297.522507
1871
+ },
1872
+ {
1873
+ "timestamp": "2025-08-07T05:00:00+08:00",
1874
+ "open": 3674.53,
1875
+ "high": 3684.97,
1876
+ "low": 3652.38,
1877
+ "close": 3669.9,
1878
+ "volume": 12537.5208,
1879
+ "amount": 45979271.294903
1880
+ },
1881
+ {
1882
+ "timestamp": "2025-08-07T06:00:00+08:00",
1883
+ "open": 3669.91,
1884
+ "high": 3682.82,
1885
+ "low": 3666.03,
1886
+ "close": 3682.15,
1887
+ "volume": 7461.3455,
1888
+ "amount": 27431497.758384
1889
+ },
1890
+ {
1891
+ "timestamp": "2025-08-07T07:00:00+08:00",
1892
+ "open": 3682.15,
1893
+ "high": 3686.17,
1894
+ "low": 3674.0,
1895
+ "close": 3683.31,
1896
+ "volume": 8554.153,
1897
+ "amount": 31492787.933534
1898
+ },
1899
+ {
1900
+ "timestamp": "2025-08-07T08:00:00+08:00",
1901
+ "open": 3683.31,
1902
+ "high": 3683.31,
1903
+ "low": 3663.76,
1904
+ "close": 3673.93,
1905
+ "volume": 8821.4226,
1906
+ "amount": 32404533.256647
1907
+ },
1908
+ {
1909
+ "timestamp": "2025-08-07T09:00:00+08:00",
1910
+ "open": 3673.93,
1911
+ "high": 3716.61,
1912
+ "low": 3666.68,
1913
+ "close": 3667.55,
1914
+ "volume": 29195.1749,
1915
+ "amount": 107834273.699961
1916
+ },
1917
+ {
1918
+ "timestamp": "2025-08-07T10:00:00+08:00",
1919
+ "open": 3667.55,
1920
+ "high": 3677.84,
1921
+ "low": 3650.4,
1922
+ "close": 3659.03,
1923
+ "volume": 10793.6538,
1924
+ "amount": 39552520.069412
1925
+ },
1926
+ {
1927
+ "timestamp": "2025-08-07T11:00:00+08:00",
1928
+ "open": 3659.02,
1929
+ "high": 3664.7,
1930
+ "low": 3647.63,
1931
+ "close": 3656.78,
1932
+ "volume": 7312.4733,
1933
+ "amount": 26741858.457292
1934
+ },
1935
+ {
1936
+ "timestamp": "2025-08-07T12:00:00+08:00",
1937
+ "open": 3656.78,
1938
+ "high": 3670.91,
1939
+ "low": 3655.09,
1940
+ "close": 3662.27,
1941
+ "volume": 7952.4262,
1942
+ "amount": 29135827.987942
1943
+ },
1944
+ {
1945
+ "timestamp": "2025-08-07T13:00:00+08:00",
1946
+ "open": 3662.27,
1947
+ "high": 3688.66,
1948
+ "low": 3659.33,
1949
+ "close": 3688.0,
1950
+ "volume": 7630.6906,
1951
+ "amount": 28041966.204968
1952
+ },
1953
+ {
1954
+ "timestamp": "2025-08-07T14:00:00+08:00",
1955
+ "open": 3688.0,
1956
+ "high": 3711.0,
1957
+ "low": 3686.58,
1958
+ "close": 3695.14,
1959
+ "volume": 19795.4181,
1960
+ "amount": 73185873.377086
1961
+ },
1962
+ {
1963
+ "timestamp": "2025-08-07T15:00:00+08:00",
1964
+ "open": 3695.15,
1965
+ "high": 3710.0,
1966
+ "low": 3694.22,
1967
+ "close": 3702.4,
1968
+ "volume": 10977.7521,
1969
+ "amount": 40641263.624024
1970
+ },
1971
+ {
1972
+ "timestamp": "2025-08-07T16:00:00+08:00",
1973
+ "open": 3702.41,
1974
+ "high": 3727.88,
1975
+ "low": 3702.41,
1976
+ "close": 3721.25,
1977
+ "volume": 21846.6884,
1978
+ "amount": 81267478.788996
1979
+ },
1980
+ {
1981
+ "timestamp": "2025-08-07T17:00:00+08:00",
1982
+ "open": 3721.26,
1983
+ "high": 3737.0,
1984
+ "low": 3715.03,
1985
+ "close": 3732.41,
1986
+ "volume": 19907.7895,
1987
+ "amount": 74188765.645104
1988
+ },
1989
+ {
1990
+ "timestamp": "2025-08-07T18:00:00+08:00",
1991
+ "open": 3732.4,
1992
+ "high": 3826.5,
1993
+ "low": 3730.63,
1994
+ "close": 3821.48,
1995
+ "volume": 98363.4913,
1996
+ "amount": 372895872.014478
1997
+ },
1998
+ {
1999
+ "timestamp": "2025-08-07T19:00:00+08:00",
2000
+ "open": 3821.47,
2001
+ "high": 3843.66,
2002
+ "low": 3806.82,
2003
+ "close": 3827.0,
2004
+ "volume": 43599.3277,
2005
+ "amount": 166673838.734013
2006
+ },
2007
+ {
2008
+ "timestamp": "2025-08-07T20:00:00+08:00",
2009
+ "open": 3827.01,
2010
+ "high": 3851.0,
2011
+ "low": 3823.64,
2012
+ "close": 3849.68,
2013
+ "volume": 43328.6642,
2014
+ "amount": 166353380.895278
2015
+ },
2016
+ {
2017
+ "timestamp": "2025-08-07T21:00:00+08:00",
2018
+ "open": 3849.68,
2019
+ "high": 3865.64,
2020
+ "low": 3826.3,
2021
+ "close": 3857.69,
2022
+ "volume": 40189.986,
2023
+ "amount": 154591439.45392
2024
+ },
2025
+ {
2026
+ "timestamp": "2025-08-07T22:00:00+08:00",
2027
+ "open": 3857.69,
2028
+ "high": 3858.24,
2029
+ "low": 3804.27,
2030
+ "close": 3820.33,
2031
+ "volume": 42348.8701,
2032
+ "amount": 161944829.376416
2033
+ },
2034
+ {
2035
+ "timestamp": "2025-08-07T23:00:00+08:00",
2036
+ "open": 3820.33,
2037
+ "high": 3841.0,
2038
+ "low": 3815.13,
2039
+ "close": 3837.01,
2040
+ "volume": 25338.4874,
2041
+ "amount": 96995371.730342
2042
+ },
2043
+ {
2044
+ "timestamp": "2025-08-08T00:00:00+08:00",
2045
+ "open": 3837.01,
2046
+ "high": 3843.79,
2047
+ "low": 3780.54,
2048
+ "close": 3815.29,
2049
+ "volume": 36988.8399,
2050
+ "amount": 141175705.196292
2051
+ },
2052
+ {
2053
+ "timestamp": "2025-08-08T01:00:00+08:00",
2054
+ "open": 3815.29,
2055
+ "high": 3834.33,
2056
+ "low": 3805.04,
2057
+ "close": 3830.2,
2058
+ "volume": 15044.9344,
2059
+ "amount": 57466303.469954
2060
+ },
2061
+ {
2062
+ "timestamp": "2025-08-08T02:00:00+08:00",
2063
+ "open": 3830.19,
2064
+ "high": 3831.39,
2065
+ "low": 3808.34,
2066
+ "close": 3827.7,
2067
+ "volume": 12739.6187,
2068
+ "amount": 48652770.698461
2069
+ },
2070
+ {
2071
+ "timestamp": "2025-08-08T03:00:00+08:00",
2072
+ "open": 3827.7,
2073
+ "high": 3876.44,
2074
+ "low": 3822.08,
2075
+ "close": 3867.6,
2076
+ "volume": 29003.2856,
2077
+ "amount": 111764391.130891
2078
+ },
2079
+ {
2080
+ "timestamp": "2025-08-08T04:00:00+08:00",
2081
+ "open": 3867.6,
2082
+ "high": 3880.0,
2083
+ "low": 3851.22,
2084
+ "close": 3874.14,
2085
+ "volume": 20732.7113,
2086
+ "amount": 80143395.809151
2087
+ },
2088
+ {
2089
+ "timestamp": "2025-08-08T05:00:00+08:00",
2090
+ "open": 3874.15,
2091
+ "high": 3885.95,
2092
+ "low": 3858.72,
2093
+ "close": 3871.53,
2094
+ "volume": 16520.2261,
2095
+ "amount": 63942410.903693
2096
+ },
2097
+ {
2098
+ "timestamp": "2025-08-08T06:00:00+08:00",
2099
+ "open": 3871.53,
2100
+ "high": 3927.77,
2101
+ "low": 3868.64,
2102
+ "close": 3916.8,
2103
+ "volume": 43175.8358,
2104
+ "amount": 168327605.61928
2105
+ },
2106
+ {
2107
+ "timestamp": "2025-08-08T07:00:00+08:00",
2108
+ "open": 3916.8,
2109
+ "high": 3917.5,
2110
+ "low": 3889.51,
2111
+ "close": 3910.31,
2112
+ "volume": 20071.2192,
2113
+ "amount": 78331295.28814
2114
+ },
2115
+ {
2116
+ "timestamp": "2025-08-08T08:00:00+08:00",
2117
+ "open": 3910.3,
2118
+ "high": 3937.0,
2119
+ "low": 3882.29,
2120
+ "close": 3900.16,
2121
+ "volume": 40356.648,
2122
+ "amount": 157758571.63297
2123
+ },
2124
+ {
2125
+ "timestamp": "2025-08-08T09:00:00+08:00",
2126
+ "open": 3900.15,
2127
+ "high": 3918.0,
2128
+ "low": 3880.0,
2129
+ "close": 3887.36,
2130
+ "volume": 24134.8488,
2131
+ "amount": 94035327.531122
2132
+ },
2133
+ {
2134
+ "timestamp": "2025-08-08T10:00:00+08:00",
2135
+ "open": 3887.35,
2136
+ "high": 3906.58,
2137
+ "low": 3880.0,
2138
+ "close": 3893.68,
2139
+ "volume": 13375.9968,
2140
+ "amount": 52067053.074899
2141
+ },
2142
+ {
2143
+ "timestamp": "2025-08-08T11:00:00+08:00",
2144
+ "open": 3893.67,
2145
+ "high": 3969.06,
2146
+ "low": 3892.6,
2147
+ "close": 3939.18,
2148
+ "volume": 52679.7141,
2149
+ "amount": 207679512.656005
2150
+ },
2151
+ {
2152
+ "timestamp": "2025-08-08T12:00:00+08:00",
2153
+ "open": 3939.19,
2154
+ "high": 3939.34,
2155
+ "low": 3916.0,
2156
+ "close": 3920.5,
2157
+ "volume": 13674.9861,
2158
+ "amount": 53684917.681459
2159
+ },
2160
+ {
2161
+ "timestamp": "2025-08-08T13:00:00+08:00",
2162
+ "open": 3920.51,
2163
+ "high": 3920.87,
2164
+ "low": 3894.56,
2165
+ "close": 3901.5,
2166
+ "volume": 15809.6234,
2167
+ "amount": 61737223.473883
2168
+ },
2169
+ {
2170
+ "timestamp": "2025-08-08T14:00:00+08:00",
2171
+ "open": 3901.5,
2172
+ "high": 3920.32,
2173
+ "low": 3892.47,
2174
+ "close": 3915.01,
2175
+ "volume": 14818.3957,
2176
+ "amount": 57921469.932196
2177
+ },
2178
+ {
2179
+ "timestamp": "2025-08-08T15:00:00+08:00",
2180
+ "open": 3915.01,
2181
+ "high": 3928.29,
2182
+ "low": 3900.4,
2183
+ "close": 3915.97,
2184
+ "volume": 22590.2051,
2185
+ "amount": 88472627.9492
2186
+ },
2187
+ {
2188
+ "timestamp": "2025-08-08T16:00:00+08:00",
2189
+ "open": 3915.98,
2190
+ "high": 3927.54,
2191
+ "low": 3885.29,
2192
+ "close": 3898.46,
2193
+ "volume": 23335.7904,
2194
+ "amount": 91096066.228158
2195
+ },
2196
+ {
2197
+ "timestamp": "2025-08-08T17:00:00+08:00",
2198
+ "open": 3898.46,
2199
+ "high": 3902.0,
2200
+ "low": 3884.44,
2201
+ "close": 3900.03,
2202
+ "volume": 11907.3276,
2203
+ "amount": 46364175.009127
2204
+ },
2205
+ {
2206
+ "timestamp": "2025-08-08T18:00:00+08:00",
2207
+ "open": 3900.03,
2208
+ "high": 3908.37,
2209
+ "low": 3886.59,
2210
+ "close": 3897.41,
2211
+ "volume": 9849.5187,
2212
+ "amount": 38395026.767345
2213
+ }
2214
+ ],
2215
+ "analysis": {
2216
+ "continuity": {
2217
+ "last_prediction": {
2218
+ "open": 3468.14892578125,
2219
+ "high": 3476.130126953125,
2220
+ "low": 3447.22314453125,
2221
+ "close": 3457.6015625
2222
+ },
2223
+ "first_actual": {
2224
+ "open": 3484.94,
2225
+ "high": 3516.31,
2226
+ "low": 3484.5,
2227
+ "close": 3485.46
2228
+ },
2229
+ "gaps": {
2230
+ "open_gap": 16.791074218750055,
2231
+ "high_gap": 40.179873046874945,
2232
+ "low_gap": 37.27685546875,
2233
+ "close_gap": 27.858437500000036
2234
+ },
2235
+ "gap_percentages": {
2236
+ "open_gap_pct": 0.4818181724434296,
2237
+ "high_gap_pct": 1.1426715234684925,
2238
+ "low_gap_pct": 1.0697906577342517,
2239
+ "close_gap_pct": 0.7992757770853784
2240
+ }
2241
+ }
2242
+ }
2243
+ }
webui/prediction_results/prediction_20250829_105733.json ADDED
@@ -0,0 +1,1135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "timestamp": "2025-08-29T10:57:33.720609",
3
+ "file_path": "ETHUSDT_1h",
4
+ "prediction_type": "Kronos model prediction (latest data)",
5
+ "prediction_params": {
6
+ "symbol": "ETHUSDT",
7
+ "interval": "1h",
8
+ "limit": 400,
9
+ "lookback": 400,
10
+ "pred_len": 120,
11
+ "temperature": 1.2,
12
+ "top_p": 0.9,
13
+ "sample_count": 28,
14
+ "start_date": "latest"
15
+ },
16
+ "input_data_summary": {
17
+ "rows": 400,
18
+ "columns": [
19
+ "open",
20
+ "high",
21
+ "low",
22
+ "close",
23
+ "volume",
24
+ "amount"
25
+ ],
26
+ "price_range": {
27
+ "open": {
28
+ "min": 4075.58,
29
+ "max": 4935.01
30
+ },
31
+ "high": {
32
+ "min": 4115.51,
33
+ "max": 4956.78
34
+ },
35
+ "low": {
36
+ "min": 4060.0,
37
+ "max": 4897.31
38
+ },
39
+ "close": {
40
+ "min": 4075.59,
41
+ "max": 4935.0
42
+ }
43
+ },
44
+ "last_values": {
45
+ "open": 4481.62,
46
+ "high": 4490.7,
47
+ "low": 4434.79,
48
+ "close": 4460.62
49
+ }
50
+ },
51
+ "prediction_results": [
52
+ {
53
+ "timestamp": "2025-08-29T10:00:00+08:00",
54
+ "open": 4450.8359375,
55
+ "high": 4494.50830078125,
56
+ "low": 4427.478515625,
57
+ "close": 4463.5849609375,
58
+ "volume": 19731.15625,
59
+ "amount": 89868512.0
60
+ },
61
+ {
62
+ "timestamp": "2025-08-29T11:00:00+08:00",
63
+ "open": 4459.93994140625,
64
+ "high": 4493.154296875,
65
+ "low": 4427.376953125,
66
+ "close": 4459.12255859375,
67
+ "volume": 20277.904296875,
68
+ "amount": 92300304.0
69
+ },
70
+ {
71
+ "timestamp": "2025-08-29T12:00:00+08:00",
72
+ "open": 4453.43896484375,
73
+ "high": 4488.71728515625,
74
+ "low": 4416.20458984375,
75
+ "close": 4460.4091796875,
76
+ "volume": 22137.80859375,
77
+ "amount": 100495416.0
78
+ },
79
+ {
80
+ "timestamp": "2025-08-29T13:00:00+08:00",
81
+ "open": 4452.81640625,
82
+ "high": 4488.9931640625,
83
+ "low": 4419.21875,
84
+ "close": 4457.8291015625,
85
+ "volume": 21303.05859375,
86
+ "amount": 96756680.0
87
+ },
88
+ {
89
+ "timestamp": "2025-08-29T14:00:00+08:00",
90
+ "open": 4453.10888671875,
91
+ "high": 4498.98046875,
92
+ "low": 4425.1357421875,
93
+ "close": 4460.93798828125,
94
+ "volume": 25089.302734375,
95
+ "amount": 114732928.0
96
+ },
97
+ {
98
+ "timestamp": "2025-08-29T15:00:00+08:00",
99
+ "open": 4462.42822265625,
100
+ "high": 4498.001953125,
101
+ "low": 4418.0537109375,
102
+ "close": 4464.234375,
103
+ "volume": 30212.841796875,
104
+ "amount": 136533104.0
105
+ },
106
+ {
107
+ "timestamp": "2025-08-29T16:00:00+08:00",
108
+ "open": 4457.75048828125,
109
+ "high": 4501.37646484375,
110
+ "low": 4426.861328125,
111
+ "close": 4468.7001953125,
112
+ "volume": 29965.708984375,
113
+ "amount": 134467024.0
114
+ },
115
+ {
116
+ "timestamp": "2025-08-29T17:00:00+08:00",
117
+ "open": 4464.234375,
118
+ "high": 4502.5986328125,
119
+ "low": 4430.35400390625,
120
+ "close": 4470.16650390625,
121
+ "volume": 29753.06640625,
122
+ "amount": 135085440.0
123
+ },
124
+ {
125
+ "timestamp": "2025-08-29T18:00:00+08:00",
126
+ "open": 4470.16259765625,
127
+ "high": 4505.154296875,
128
+ "low": 4440.8515625,
129
+ "close": 4479.41943359375,
130
+ "volume": 30642.41796875,
131
+ "amount": 138297552.0
132
+ },
133
+ {
134
+ "timestamp": "2025-08-29T19:00:00+08:00",
135
+ "open": 4481.640625,
136
+ "high": 4520.38916015625,
137
+ "low": 4450.97216796875,
138
+ "close": 4490.08935546875,
139
+ "volume": 29416.107421875,
140
+ "amount": 133158272.0
141
+ },
142
+ {
143
+ "timestamp": "2025-08-29T20:00:00+08:00",
144
+ "open": 4479.46728515625,
145
+ "high": 4532.5166015625,
146
+ "low": 4447.89794921875,
147
+ "close": 4497.046875,
148
+ "volume": 33504.37890625,
149
+ "amount": 152929152.0
150
+ },
151
+ {
152
+ "timestamp": "2025-08-29T21:00:00+08:00",
153
+ "open": 4493.11279296875,
154
+ "high": 4540.783203125,
155
+ "low": 4460.349609375,
156
+ "close": 4506.4287109375,
157
+ "volume": 37279.5546875,
158
+ "amount": 169164432.0
159
+ },
160
+ {
161
+ "timestamp": "2025-08-29T22:00:00+08:00",
162
+ "open": 4511.74853515625,
163
+ "high": 4550.04736328125,
164
+ "low": 4478.97314453125,
165
+ "close": 4509.96435546875,
166
+ "volume": 32651.22265625,
167
+ "amount": 147927248.0
168
+ },
169
+ {
170
+ "timestamp": "2025-08-29T23:00:00+08:00",
171
+ "open": 4511.28857421875,
172
+ "high": 4548.7861328125,
173
+ "low": 4483.978515625,
174
+ "close": 4514.49267578125,
175
+ "volume": 37645.71875,
176
+ "amount": 170708288.0
177
+ },
178
+ {
179
+ "timestamp": "2025-08-30T00:00:00+08:00",
180
+ "open": 4512.9609375,
181
+ "high": 4548.849609375,
182
+ "low": 4471.10595703125,
183
+ "close": 4511.14306640625,
184
+ "volume": 30429.859375,
185
+ "amount": 137106608.0
186
+ },
187
+ {
188
+ "timestamp": "2025-08-30T01:00:00+08:00",
189
+ "open": 4505.650390625,
190
+ "high": 4547.44140625,
191
+ "low": 4478.6416015625,
192
+ "close": 4516.3759765625,
193
+ "volume": 29940.6796875,
194
+ "amount": 134529568.0
195
+ },
196
+ {
197
+ "timestamp": "2025-08-30T02:00:00+08:00",
198
+ "open": 4509.92919921875,
199
+ "high": 4550.62255859375,
200
+ "low": 4481.5302734375,
201
+ "close": 4520.822265625,
202
+ "volume": 29082.5234375,
203
+ "amount": 131279064.0
204
+ },
205
+ {
206
+ "timestamp": "2025-08-30T03:00:00+08:00",
207
+ "open": 4516.47802734375,
208
+ "high": 4555.31005859375,
209
+ "low": 4487.1640625,
210
+ "close": 4523.4306640625,
211
+ "volume": 32992.02734375,
212
+ "amount": 146586528.0
213
+ },
214
+ {
215
+ "timestamp": "2025-08-30T04:00:00+08:00",
216
+ "open": 4518.392578125,
217
+ "high": 4564.9658203125,
218
+ "low": 4497.18310546875,
219
+ "close": 4540.0302734375,
220
+ "volume": 28643.2109375,
221
+ "amount": 128580496.0
222
+ },
223
+ {
224
+ "timestamp": "2025-08-30T05:00:00+08:00",
225
+ "open": 4530.82177734375,
226
+ "high": 4559.23583984375,
227
+ "low": 4501.7939453125,
228
+ "close": 4532.138671875,
229
+ "volume": 26202.1953125,
230
+ "amount": 118504600.0
231
+ },
232
+ {
233
+ "timestamp": "2025-08-30T06:00:00+08:00",
234
+ "open": 4526.82373046875,
235
+ "high": 4562.5791015625,
236
+ "low": 4500.203125,
237
+ "close": 4532.30712890625,
238
+ "volume": 28922.1015625,
239
+ "amount": 130380640.0
240
+ },
241
+ {
242
+ "timestamp": "2025-08-30T07:00:00+08:00",
243
+ "open": 4534.630859375,
244
+ "high": 4568.8115234375,
245
+ "low": 4512.154296875,
246
+ "close": 4539.01611328125,
247
+ "volume": 25019.025390625,
248
+ "amount": 113397968.0
249
+ },
250
+ {
251
+ "timestamp": "2025-08-30T08:00:00+08:00",
252
+ "open": 4535.39306640625,
253
+ "high": 4566.35888671875,
254
+ "low": 4508.9755859375,
255
+ "close": 4531.33642578125,
256
+ "volume": 25840.5546875,
257
+ "amount": 116813872.0
258
+ },
259
+ {
260
+ "timestamp": "2025-08-30T09:00:00+08:00",
261
+ "open": 4521.49169921875,
262
+ "high": 4552.07666015625,
263
+ "low": 4489.42578125,
264
+ "close": 4519.38818359375,
265
+ "volume": 31191.93359375,
266
+ "amount": 139978240.0
267
+ },
268
+ {
269
+ "timestamp": "2025-08-30T10:00:00+08:00",
270
+ "open": 4508.76953125,
271
+ "high": 4539.025390625,
272
+ "low": 4473.35302734375,
273
+ "close": 4509.77294921875,
274
+ "volume": 29320.80859375,
275
+ "amount": 132001056.0
276
+ },
277
+ {
278
+ "timestamp": "2025-08-30T11:00:00+08:00",
279
+ "open": 4508.013671875,
280
+ "high": 4537.02880859375,
281
+ "low": 4461.837890625,
282
+ "close": 4505.21875,
283
+ "volume": 27340.513671875,
284
+ "amount": 123927256.0
285
+ },
286
+ {
287
+ "timestamp": "2025-08-30T12:00:00+08:00",
288
+ "open": 4497.7177734375,
289
+ "high": 4540.33154296875,
290
+ "low": 4471.88232421875,
291
+ "close": 4511.08984375,
292
+ "volume": 29142.4609375,
293
+ "amount": 132103040.0
294
+ },
295
+ {
296
+ "timestamp": "2025-08-30T13:00:00+08:00",
297
+ "open": 4500.7177734375,
298
+ "high": 4546.02490234375,
299
+ "low": 4459.09228515625,
300
+ "close": 4502.54638671875,
301
+ "volume": 35493.7109375,
302
+ "amount": 159789952.0
303
+ },
304
+ {
305
+ "timestamp": "2025-08-30T14:00:00+08:00",
306
+ "open": 4493.02734375,
307
+ "high": 4533.30517578125,
308
+ "low": 4453.9111328125,
309
+ "close": 4500.021484375,
310
+ "volume": 32821.66796875,
311
+ "amount": 146583088.0
312
+ },
313
+ {
314
+ "timestamp": "2025-08-30T15:00:00+08:00",
315
+ "open": 4477.076171875,
316
+ "high": 4537.36865234375,
317
+ "low": 4428.81884765625,
318
+ "close": 4497.0966796875,
319
+ "volume": 41439.2265625,
320
+ "amount": 185322080.0
321
+ },
322
+ {
323
+ "timestamp": "2025-08-30T16:00:00+08:00",
324
+ "open": 4486.07666015625,
325
+ "high": 4526.85400390625,
326
+ "low": 4444.513671875,
327
+ "close": 4496.07470703125,
328
+ "volume": 32475.9140625,
329
+ "amount": 145825488.0
330
+ },
331
+ {
332
+ "timestamp": "2025-08-30T17:00:00+08:00",
333
+ "open": 4481.4931640625,
334
+ "high": 4536.28369140625,
335
+ "low": 4447.109375,
336
+ "close": 4500.2939453125,
337
+ "volume": 40199.81640625,
338
+ "amount": 180964448.0
339
+ },
340
+ {
341
+ "timestamp": "2025-08-30T18:00:00+08:00",
342
+ "open": 4488.0673828125,
343
+ "high": 4537.7578125,
344
+ "low": 4449.1435546875,
345
+ "close": 4501.94677734375,
346
+ "volume": 40515.2734375,
347
+ "amount": 182693888.0
348
+ },
349
+ {
350
+ "timestamp": "2025-08-30T19:00:00+08:00",
351
+ "open": 4487.50341796875,
352
+ "high": 4536.515625,
353
+ "low": 4427.98193359375,
354
+ "close": 4493.09912109375,
355
+ "volume": 48395.421875,
356
+ "amount": 216889600.0
357
+ },
358
+ {
359
+ "timestamp": "2025-08-30T20:00:00+08:00",
360
+ "open": 4482.77734375,
361
+ "high": 4523.8505859375,
362
+ "low": 4433.978515625,
363
+ "close": 4480.380859375,
364
+ "volume": 39964.015625,
365
+ "amount": 180851792.0
366
+ },
367
+ {
368
+ "timestamp": "2025-08-30T21:00:00+08:00",
369
+ "open": 4474.68359375,
370
+ "high": 4513.74755859375,
371
+ "low": 4434.42236328125,
372
+ "close": 4480.46923828125,
373
+ "volume": 35719.953125,
374
+ "amount": 161377408.0
375
+ },
376
+ {
377
+ "timestamp": "2025-08-30T22:00:00+08:00",
378
+ "open": 4472.40380859375,
379
+ "high": 4516.482421875,
380
+ "low": 4429.94091796875,
381
+ "close": 4482.6728515625,
382
+ "volume": 34478.453125,
383
+ "amount": 155292304.0
384
+ },
385
+ {
386
+ "timestamp": "2025-08-30T23:00:00+08:00",
387
+ "open": 4474.7255859375,
388
+ "high": 4511.2392578125,
389
+ "low": 4434.8154296875,
390
+ "close": 4478.13671875,
391
+ "volume": 38205.8828125,
392
+ "amount": 171659504.0
393
+ },
394
+ {
395
+ "timestamp": "2025-08-31T00:00:00+08:00",
396
+ "open": 4483.43798828125,
397
+ "high": 4514.7763671875,
398
+ "low": 4447.97021484375,
399
+ "close": 4480.90673828125,
400
+ "volume": 30044.4296875,
401
+ "amount": 135494272.0
402
+ },
403
+ {
404
+ "timestamp": "2025-08-31T01:00:00+08:00",
405
+ "open": 4478.654296875,
406
+ "high": 4514.06396484375,
407
+ "low": 4449.1953125,
408
+ "close": 4480.10986328125,
409
+ "volume": 28165.23046875,
410
+ "amount": 127759216.0
411
+ },
412
+ {
413
+ "timestamp": "2025-08-31T02:00:00+08:00",
414
+ "open": 4473.78125,
415
+ "high": 4514.228515625,
416
+ "low": 4445.8505859375,
417
+ "close": 4482.70556640625,
418
+ "volume": 27063.619140625,
419
+ "amount": 122650752.0
420
+ },
421
+ {
422
+ "timestamp": "2025-08-31T03:00:00+08:00",
423
+ "open": 4480.15087890625,
424
+ "high": 4504.80126953125,
425
+ "low": 4439.88525390625,
426
+ "close": 4469.64404296875,
427
+ "volume": 25218.947265625,
428
+ "amount": 114438584.0
429
+ },
430
+ {
431
+ "timestamp": "2025-08-31T04:00:00+08:00",
432
+ "open": 4460.44921875,
433
+ "high": 4496.0146484375,
434
+ "low": 4421.23388671875,
435
+ "close": 4467.8115234375,
436
+ "volume": 27878.4921875,
437
+ "amount": 125946912.0
438
+ },
439
+ {
440
+ "timestamp": "2025-08-31T05:00:00+08:00",
441
+ "open": 4457.68359375,
442
+ "high": 4508.80615234375,
443
+ "low": 4423.09814453125,
444
+ "close": 4473.8330078125,
445
+ "volume": 31408.904296875,
446
+ "amount": 141321280.0
447
+ },
448
+ {
449
+ "timestamp": "2025-08-31T06:00:00+08:00",
450
+ "open": 4462.6728515625,
451
+ "high": 4502.55322265625,
452
+ "low": 4427.08984375,
453
+ "close": 4464.8515625,
454
+ "volume": 30178.615234375,
455
+ "amount": 137053360.0
456
+ },
457
+ {
458
+ "timestamp": "2025-08-31T07:00:00+08:00",
459
+ "open": 4457.85986328125,
460
+ "high": 4495.55908203125,
461
+ "low": 4415.52685546875,
462
+ "close": 4465.9853515625,
463
+ "volume": 31197.201171875,
464
+ "amount": 140450048.0
465
+ },
466
+ {
467
+ "timestamp": "2025-08-31T08:00:00+08:00",
468
+ "open": 4459.98828125,
469
+ "high": 4496.1435546875,
470
+ "low": 4429.2705078125,
471
+ "close": 4460.576171875,
472
+ "volume": 30786.2421875,
473
+ "amount": 139296304.0
474
+ },
475
+ {
476
+ "timestamp": "2025-08-31T09:00:00+08:00",
477
+ "open": 4462.32421875,
478
+ "high": 4501.80908203125,
479
+ "low": 4426.9814453125,
480
+ "close": 4474.70751953125,
481
+ "volume": 29207.87890625,
482
+ "amount": 132301560.0
483
+ },
484
+ {
485
+ "timestamp": "2025-08-31T10:00:00+08:00",
486
+ "open": 4470.01416015625,
487
+ "high": 4515.68310546875,
488
+ "low": 4431.60302734375,
489
+ "close": 4479.33154296875,
490
+ "volume": 34050.01171875,
491
+ "amount": 152495920.0
492
+ },
493
+ {
494
+ "timestamp": "2025-08-31T11:00:00+08:00",
495
+ "open": 4472.5400390625,
496
+ "high": 4520.5712890625,
497
+ "low": 4438.35693359375,
498
+ "close": 4483.72119140625,
499
+ "volume": 38330.17578125,
500
+ "amount": 172849568.0
501
+ },
502
+ {
503
+ "timestamp": "2025-08-31T12:00:00+08:00",
504
+ "open": 4481.42236328125,
505
+ "high": 4513.62060546875,
506
+ "low": 4443.89111328125,
507
+ "close": 4481.28759765625,
508
+ "volume": 35882.328125,
509
+ "amount": 161331104.0
510
+ },
511
+ {
512
+ "timestamp": "2025-08-31T13:00:00+08:00",
513
+ "open": 4477.16015625,
514
+ "high": 4519.8837890625,
515
+ "low": 4438.07177734375,
516
+ "close": 4483.29443359375,
517
+ "volume": 34176.1796875,
518
+ "amount": 153926832.0
519
+ },
520
+ {
521
+ "timestamp": "2025-08-31T14:00:00+08:00",
522
+ "open": 4479.00439453125,
523
+ "high": 4513.7646484375,
524
+ "low": 4436.97509765625,
525
+ "close": 4486.51220703125,
526
+ "volume": 32291.1328125,
527
+ "amount": 144562304.0
528
+ },
529
+ {
530
+ "timestamp": "2025-08-31T15:00:00+08:00",
531
+ "open": 4479.67919921875,
532
+ "high": 4515.6171875,
533
+ "low": 4448.310546875,
534
+ "close": 4486.01123046875,
535
+ "volume": 33435.0078125,
536
+ "amount": 151168656.0
537
+ },
538
+ {
539
+ "timestamp": "2025-08-31T16:00:00+08:00",
540
+ "open": 4487.38623046875,
541
+ "high": 4525.0166015625,
542
+ "low": 4456.3505859375,
543
+ "close": 4496.7744140625,
544
+ "volume": 31492.712890625,
545
+ "amount": 141909072.0
546
+ },
547
+ {
548
+ "timestamp": "2025-08-31T17:00:00+08:00",
549
+ "open": 4490.2138671875,
550
+ "high": 4547.57421875,
551
+ "low": 4454.83642578125,
552
+ "close": 4506.9951171875,
553
+ "volume": 38174.625,
554
+ "amount": 170458400.0
555
+ },
556
+ {
557
+ "timestamp": "2025-08-31T18:00:00+08:00",
558
+ "open": 4501.44921875,
559
+ "high": 4539.72412109375,
560
+ "low": 4456.2265625,
561
+ "close": 4515.705078125,
562
+ "volume": 35388.4140625,
563
+ "amount": 159776400.0
564
+ },
565
+ {
566
+ "timestamp": "2025-08-31T19:00:00+08:00",
567
+ "open": 4509.02783203125,
568
+ "high": 4557.29345703125,
569
+ "low": 4478.16796875,
570
+ "close": 4511.64599609375,
571
+ "volume": 31070.486328125,
572
+ "amount": 142651296.0
573
+ },
574
+ {
575
+ "timestamp": "2025-08-31T20:00:00+08:00",
576
+ "open": 4511.42236328125,
577
+ "high": 4543.98681640625,
578
+ "low": 4474.60791015625,
579
+ "close": 4513.00927734375,
580
+ "volume": 33355.8671875,
581
+ "amount": 150990352.0
582
+ },
583
+ {
584
+ "timestamp": "2025-08-31T21:00:00+08:00",
585
+ "open": 4510.88037109375,
586
+ "high": 4555.1796875,
587
+ "low": 4475.1455078125,
588
+ "close": 4513.15380859375,
589
+ "volume": 33064.078125,
590
+ "amount": 148064768.0
591
+ },
592
+ {
593
+ "timestamp": "2025-08-31T22:00:00+08:00",
594
+ "open": 4507.35986328125,
595
+ "high": 4546.740234375,
596
+ "low": 4456.5390625,
597
+ "close": 4511.0244140625,
598
+ "volume": 41013.0390625,
599
+ "amount": 185423952.0
600
+ },
601
+ {
602
+ "timestamp": "2025-08-31T23:00:00+08:00",
603
+ "open": 4506.08984375,
604
+ "high": 4553.21484375,
605
+ "low": 4479.30224609375,
606
+ "close": 4519.13330078125,
607
+ "volume": 35694.73046875,
608
+ "amount": 161016528.0
609
+ },
610
+ {
611
+ "timestamp": "2025-09-01T00:00:00+08:00",
612
+ "open": 4515.09423828125,
613
+ "high": 4571.60986328125,
614
+ "low": 4475.12646484375,
615
+ "close": 4531.5927734375,
616
+ "volume": 50190.98046875,
617
+ "amount": 224669856.0
618
+ },
619
+ {
620
+ "timestamp": "2025-09-01T01:00:00+08:00",
621
+ "open": 4520.98193359375,
622
+ "high": 4571.2705078125,
623
+ "low": 4492.3857421875,
624
+ "close": 4536.96142578125,
625
+ "volume": 43183.2734375,
626
+ "amount": 194699456.0
627
+ },
628
+ {
629
+ "timestamp": "2025-09-01T02:00:00+08:00",
630
+ "open": 4527.15234375,
631
+ "high": 4584.31103515625,
632
+ "low": 4499.2080078125,
633
+ "close": 4543.89599609375,
634
+ "volume": 42264.5390625,
635
+ "amount": 192231104.0
636
+ },
637
+ {
638
+ "timestamp": "2025-09-01T03:00:00+08:00",
639
+ "open": 4543.2080078125,
640
+ "high": 4581.86279296875,
641
+ "low": 4515.0869140625,
642
+ "close": 4550.6015625,
643
+ "volume": 35673.5,
644
+ "amount": 162637792.0
645
+ },
646
+ {
647
+ "timestamp": "2025-09-01T04:00:00+08:00",
648
+ "open": 4550.373046875,
649
+ "high": 4585.73681640625,
650
+ "low": 4519.7255859375,
651
+ "close": 4546.40576171875,
652
+ "volume": 30567.98046875,
653
+ "amount": 139016640.0
654
+ },
655
+ {
656
+ "timestamp": "2025-09-01T05:00:00+08:00",
657
+ "open": 4534.3642578125,
658
+ "high": 4581.50537109375,
659
+ "low": 4489.97216796875,
660
+ "close": 4546.67041015625,
661
+ "volume": 33954.3828125,
662
+ "amount": 153468688.0
663
+ },
664
+ {
665
+ "timestamp": "2025-09-01T06:00:00+08:00",
666
+ "open": 4529.3857421875,
667
+ "high": 4570.0,
668
+ "low": 4492.39306640625,
669
+ "close": 4543.60791015625,
670
+ "volume": 38178.34765625,
671
+ "amount": 172492160.0
672
+ },
673
+ {
674
+ "timestamp": "2025-09-01T07:00:00+08:00",
675
+ "open": 4536.6728515625,
676
+ "high": 4578.05908203125,
677
+ "low": 4505.8515625,
678
+ "close": 4547.5517578125,
679
+ "volume": 37513.44140625,
680
+ "amount": 169059376.0
681
+ },
682
+ {
683
+ "timestamp": "2025-09-01T08:00:00+08:00",
684
+ "open": 4537.17333984375,
685
+ "high": 4579.54638671875,
686
+ "low": 4505.5595703125,
687
+ "close": 4542.337890625,
688
+ "volume": 37342.78125,
689
+ "amount": 168504400.0
690
+ },
691
+ {
692
+ "timestamp": "2025-09-01T09:00:00+08:00",
693
+ "open": 4542.44775390625,
694
+ "high": 4588.03955078125,
695
+ "low": 4512.2275390625,
696
+ "close": 4555.419921875,
697
+ "volume": 33891.13671875,
698
+ "amount": 153160720.0
699
+ },
700
+ {
701
+ "timestamp": "2025-09-01T10:00:00+08:00",
702
+ "open": 4555.69091796875,
703
+ "high": 4593.60205078125,
704
+ "low": 4519.77734375,
705
+ "close": 4554.9326171875,
706
+ "volume": 32961.81640625,
707
+ "amount": 149232912.0
708
+ },
709
+ {
710
+ "timestamp": "2025-09-01T11:00:00+08:00",
711
+ "open": 4551.8701171875,
712
+ "high": 4595.939453125,
713
+ "low": 4526.4951171875,
714
+ "close": 4567.53857421875,
715
+ "volume": 34340.46484375,
716
+ "amount": 154740672.0
717
+ },
718
+ {
719
+ "timestamp": "2025-09-01T12:00:00+08:00",
720
+ "open": 4551.22021484375,
721
+ "high": 4590.642578125,
722
+ "low": 4512.958984375,
723
+ "close": 4558.58251953125,
724
+ "volume": 31490.224609375,
725
+ "amount": 142267904.0
726
+ },
727
+ {
728
+ "timestamp": "2025-09-01T13:00:00+08:00",
729
+ "open": 4556.5498046875,
730
+ "high": 4597.73779296875,
731
+ "low": 4521.79736328125,
732
+ "close": 4563.30029296875,
733
+ "volume": 37523.03515625,
734
+ "amount": 168086096.0
735
+ },
736
+ {
737
+ "timestamp": "2025-09-01T14:00:00+08:00",
738
+ "open": 4547.9365234375,
739
+ "high": 4605.7509765625,
740
+ "low": 4512.25732421875,
741
+ "close": 4560.18017578125,
742
+ "volume": 40796.53125,
743
+ "amount": 184486400.0
744
+ },
745
+ {
746
+ "timestamp": "2025-09-01T15:00:00+08:00",
747
+ "open": 4551.7548828125,
748
+ "high": 4595.08203125,
749
+ "low": 4517.673828125,
750
+ "close": 4559.6455078125,
751
+ "volume": 40180.01171875,
752
+ "amount": 181325856.0
753
+ },
754
+ {
755
+ "timestamp": "2025-09-01T16:00:00+08:00",
756
+ "open": 4541.392578125,
757
+ "high": 4598.98291015625,
758
+ "low": 4504.27001953125,
759
+ "close": 4558.1953125,
760
+ "volume": 46832.625,
761
+ "amount": 209827136.0
762
+ },
763
+ {
764
+ "timestamp": "2025-09-01T17:00:00+08:00",
765
+ "open": 4537.3212890625,
766
+ "high": 4594.482421875,
767
+ "low": 4511.13330078125,
768
+ "close": 4558.16552734375,
769
+ "volume": 40158.1875,
770
+ "amount": 181835472.0
771
+ },
772
+ {
773
+ "timestamp": "2025-09-01T18:00:00+08:00",
774
+ "open": 4546.46044921875,
775
+ "high": 4598.70654296875,
776
+ "low": 4512.66943359375,
777
+ "close": 4566.07470703125,
778
+ "volume": 48231.7890625,
779
+ "amount": 216870304.0
780
+ },
781
+ {
782
+ "timestamp": "2025-09-01T19:00:00+08:00",
783
+ "open": 4564.17138671875,
784
+ "high": 4605.62255859375,
785
+ "low": 4527.1689453125,
786
+ "close": 4567.36376953125,
787
+ "volume": 44911.62109375,
788
+ "amount": 202784528.0
789
+ },
790
+ {
791
+ "timestamp": "2025-09-01T20:00:00+08:00",
792
+ "open": 4568.35400390625,
793
+ "high": 4608.775390625,
794
+ "low": 4530.666015625,
795
+ "close": 4572.20556640625,
796
+ "volume": 49538.671875,
797
+ "amount": 223670128.0
798
+ },
799
+ {
800
+ "timestamp": "2025-09-01T21:00:00+08:00",
801
+ "open": 4563.20166015625,
802
+ "high": 4604.4912109375,
803
+ "low": 4534.18212890625,
804
+ "close": 4578.16552734375,
805
+ "volume": 49131.1015625,
806
+ "amount": 219783520.0
807
+ },
808
+ {
809
+ "timestamp": "2025-09-01T22:00:00+08:00",
810
+ "open": 4562.595703125,
811
+ "high": 4601.8984375,
812
+ "low": 4534.12939453125,
813
+ "close": 4576.1748046875,
814
+ "volume": 40698.40234375,
815
+ "amount": 182535312.0
816
+ },
817
+ {
818
+ "timestamp": "2025-09-01T23:00:00+08:00",
819
+ "open": 4569.4189453125,
820
+ "high": 4614.7001953125,
821
+ "low": 4538.5859375,
822
+ "close": 4590.91455078125,
823
+ "volume": 45643.28125,
824
+ "amount": 204557808.0
825
+ },
826
+ {
827
+ "timestamp": "2025-09-02T00:00:00+08:00",
828
+ "open": 4578.15234375,
829
+ "high": 4619.27685546875,
830
+ "low": 4544.9169921875,
831
+ "close": 4587.79150390625,
832
+ "volume": 51975.890625,
833
+ "amount": 234901408.0
834
+ },
835
+ {
836
+ "timestamp": "2025-09-02T01:00:00+08:00",
837
+ "open": 4577.390625,
838
+ "high": 4631.59423828125,
839
+ "low": 4545.03125,
840
+ "close": 4585.9189453125,
841
+ "volume": 51274.875,
842
+ "amount": 230496544.0
843
+ },
844
+ {
845
+ "timestamp": "2025-09-02T02:00:00+08:00",
846
+ "open": 4573.42236328125,
847
+ "high": 4613.76318359375,
848
+ "low": 4528.8759765625,
849
+ "close": 4591.5029296875,
850
+ "volume": 43442.48828125,
851
+ "amount": 194660128.0
852
+ },
853
+ {
854
+ "timestamp": "2025-09-02T03:00:00+08:00",
855
+ "open": 4586.62841796875,
856
+ "high": 4624.18310546875,
857
+ "low": 4549.8232421875,
858
+ "close": 4587.60205078125,
859
+ "volume": 38606.8984375,
860
+ "amount": 173501440.0
861
+ },
862
+ {
863
+ "timestamp": "2025-09-02T04:00:00+08:00",
864
+ "open": 4585.529296875,
865
+ "high": 4624.11474609375,
866
+ "low": 4553.10400390625,
867
+ "close": 4596.857421875,
868
+ "volume": 38522.11328125,
869
+ "amount": 173502480.0
870
+ },
871
+ {
872
+ "timestamp": "2025-09-02T05:00:00+08:00",
873
+ "open": 4580.89501953125,
874
+ "high": 4630.5234375,
875
+ "low": 4539.7060546875,
876
+ "close": 4586.83935546875,
877
+ "volume": 42720.11328125,
878
+ "amount": 193021648.0
879
+ },
880
+ {
881
+ "timestamp": "2025-09-02T06:00:00+08:00",
882
+ "open": 4571.10107421875,
883
+ "high": 4617.46533203125,
884
+ "low": 4533.0322265625,
885
+ "close": 4578.92919921875,
886
+ "volume": 43508.734375,
887
+ "amount": 196595456.0
888
+ },
889
+ {
890
+ "timestamp": "2025-09-02T07:00:00+08:00",
891
+ "open": 4573.62548828125,
892
+ "high": 4611.6513671875,
893
+ "low": 4531.03515625,
894
+ "close": 4574.15771484375,
895
+ "volume": 42145.03125,
896
+ "amount": 189896544.0
897
+ },
898
+ {
899
+ "timestamp": "2025-09-02T08:00:00+08:00",
900
+ "open": 4573.3837890625,
901
+ "high": 4598.72802734375,
902
+ "low": 4536.0673828125,
903
+ "close": 4564.84228515625,
904
+ "volume": 34268.640625,
905
+ "amount": 154832912.0
906
+ },
907
+ {
908
+ "timestamp": "2025-09-02T09:00:00+08:00",
909
+ "open": 4557.5595703125,
910
+ "high": 4593.67431640625,
911
+ "low": 4520.9833984375,
912
+ "close": 4561.54150390625,
913
+ "volume": 39207.77734375,
914
+ "amount": 176473856.0
915
+ },
916
+ {
917
+ "timestamp": "2025-09-02T10:00:00+08:00",
918
+ "open": 4545.6884765625,
919
+ "high": 4589.771484375,
920
+ "low": 4508.16455078125,
921
+ "close": 4556.0419921875,
922
+ "volume": 40883.828125,
923
+ "amount": 183683680.0
924
+ },
925
+ {
926
+ "timestamp": "2025-09-02T11:00:00+08:00",
927
+ "open": 4544.94384765625,
928
+ "high": 4583.875,
929
+ "low": 4492.998046875,
930
+ "close": 4550.53857421875,
931
+ "volume": 40838.2109375,
932
+ "amount": 184617152.0
933
+ },
934
+ {
935
+ "timestamp": "2025-09-02T12:00:00+08:00",
936
+ "open": 4529.3046875,
937
+ "high": 4578.46484375,
938
+ "low": 4482.02197265625,
939
+ "close": 4535.69482421875,
940
+ "volume": 44927.51953125,
941
+ "amount": 202664016.0
942
+ },
943
+ {
944
+ "timestamp": "2025-09-02T13:00:00+08:00",
945
+ "open": 4532.599609375,
946
+ "high": 4572.65087890625,
947
+ "low": 4501.83447265625,
948
+ "close": 4543.251953125,
949
+ "volume": 39039.8125,
950
+ "amount": 175099296.0
951
+ },
952
+ {
953
+ "timestamp": "2025-09-02T14:00:00+08:00",
954
+ "open": 4534.67236328125,
955
+ "high": 4574.8134765625,
956
+ "low": 4495.57958984375,
957
+ "close": 4544.16552734375,
958
+ "volume": 40128.22265625,
959
+ "amount": 179932976.0
960
+ },
961
+ {
962
+ "timestamp": "2025-09-02T15:00:00+08:00",
963
+ "open": 4526.42822265625,
964
+ "high": 4581.20556640625,
965
+ "low": 4495.72021484375,
966
+ "close": 4545.689453125,
967
+ "volume": 45521.45703125,
968
+ "amount": 205629088.0
969
+ },
970
+ {
971
+ "timestamp": "2025-09-02T16:00:00+08:00",
972
+ "open": 4538.80908203125,
973
+ "high": 4583.529296875,
974
+ "low": 4509.79541015625,
975
+ "close": 4556.81591796875,
976
+ "volume": 38849.3828125,
977
+ "amount": 175604992.0
978
+ },
979
+ {
980
+ "timestamp": "2025-09-02T17:00:00+08:00",
981
+ "open": 4547.2919921875,
982
+ "high": 4591.7880859375,
983
+ "low": 4507.6572265625,
984
+ "close": 4550.9033203125,
985
+ "volume": 42733.4609375,
986
+ "amount": 193856672.0
987
+ },
988
+ {
989
+ "timestamp": "2025-09-02T18:00:00+08:00",
990
+ "open": 4537.7236328125,
991
+ "high": 4593.67041015625,
992
+ "low": 4491.9482421875,
993
+ "close": 4554.923828125,
994
+ "volume": 55684.0859375,
995
+ "amount": 249526496.0
996
+ },
997
+ {
998
+ "timestamp": "2025-09-02T19:00:00+08:00",
999
+ "open": 4550.138671875,
1000
+ "high": 4607.232421875,
1001
+ "low": 4510.49462890625,
1002
+ "close": 4559.1455078125,
1003
+ "volume": 53416.7578125,
1004
+ "amount": 239459168.0
1005
+ },
1006
+ {
1007
+ "timestamp": "2025-09-02T20:00:00+08:00",
1008
+ "open": 4546.7890625,
1009
+ "high": 4605.263671875,
1010
+ "low": 4510.28369140625,
1011
+ "close": 4563.14111328125,
1012
+ "volume": 45000.546875,
1013
+ "amount": 203496160.0
1014
+ },
1015
+ {
1016
+ "timestamp": "2025-09-02T21:00:00+08:00",
1017
+ "open": 4545.60302734375,
1018
+ "high": 4589.77001953125,
1019
+ "low": 4495.37060546875,
1020
+ "close": 4555.21484375,
1021
+ "volume": 45539.390625,
1022
+ "amount": 205006336.0
1023
+ },
1024
+ {
1025
+ "timestamp": "2025-09-02T22:00:00+08:00",
1026
+ "open": 4546.20458984375,
1027
+ "high": 4593.9287109375,
1028
+ "low": 4513.806640625,
1029
+ "close": 4561.802734375,
1030
+ "volume": 39585.1484375,
1031
+ "amount": 178231856.0
1032
+ },
1033
+ {
1034
+ "timestamp": "2025-09-02T23:00:00+08:00",
1035
+ "open": 4559.8203125,
1036
+ "high": 4596.2900390625,
1037
+ "low": 4524.34814453125,
1038
+ "close": 4560.80419921875,
1039
+ "volume": 40244.0390625,
1040
+ "amount": 180489472.0
1041
+ },
1042
+ {
1043
+ "timestamp": "2025-09-03T00:00:00+08:00",
1044
+ "open": 4549.5927734375,
1045
+ "high": 4597.9208984375,
1046
+ "low": 4520.5087890625,
1047
+ "close": 4563.94384765625,
1048
+ "volume": 38034.07421875,
1049
+ "amount": 171380160.0
1050
+ },
1051
+ {
1052
+ "timestamp": "2025-09-03T01:00:00+08:00",
1053
+ "open": 4558.900390625,
1054
+ "high": 4607.0771484375,
1055
+ "low": 4525.36865234375,
1056
+ "close": 4572.4052734375,
1057
+ "volume": 42806.9765625,
1058
+ "amount": 191927728.0
1059
+ },
1060
+ {
1061
+ "timestamp": "2025-09-03T02:00:00+08:00",
1062
+ "open": 4569.9013671875,
1063
+ "high": 4612.73583984375,
1064
+ "low": 4535.84228515625,
1065
+ "close": 4576.216796875,
1066
+ "volume": 42280.65625,
1067
+ "amount": 192226768.0
1068
+ },
1069
+ {
1070
+ "timestamp": "2025-09-03T03:00:00+08:00",
1071
+ "open": 4570.88134765625,
1072
+ "high": 4606.115234375,
1073
+ "low": 4536.02734375,
1074
+ "close": 4574.78564453125,
1075
+ "volume": 38558.3046875,
1076
+ "amount": 174409024.0
1077
+ },
1078
+ {
1079
+ "timestamp": "2025-09-03T04:00:00+08:00",
1080
+ "open": 4562.32177734375,
1081
+ "high": 4593.474609375,
1082
+ "low": 4526.6728515625,
1083
+ "close": 4564.43310546875,
1084
+ "volume": 37037.171875,
1085
+ "amount": 166321456.0
1086
+ },
1087
+ {
1088
+ "timestamp": "2025-09-03T05:00:00+08:00",
1089
+ "open": 4559.52734375,
1090
+ "high": 4591.86083984375,
1091
+ "low": 4521.20263671875,
1092
+ "close": 4560.76611328125,
1093
+ "volume": 38661.72265625,
1094
+ "amount": 174025728.0
1095
+ },
1096
+ {
1097
+ "timestamp": "2025-09-03T06:00:00+08:00",
1098
+ "open": 4550.4130859375,
1099
+ "high": 4602.3818359375,
1100
+ "low": 4507.49951171875,
1101
+ "close": 4562.0517578125,
1102
+ "volume": 39403.13671875,
1103
+ "amount": 176418672.0
1104
+ },
1105
+ {
1106
+ "timestamp": "2025-09-03T07:00:00+08:00",
1107
+ "open": 4555.890625,
1108
+ "high": 4612.65576171875,
1109
+ "low": 4530.1845703125,
1110
+ "close": 4575.11669921875,
1111
+ "volume": 38585.37109375,
1112
+ "amount": 175562176.0
1113
+ },
1114
+ {
1115
+ "timestamp": "2025-09-03T08:00:00+08:00",
1116
+ "open": 4567.9541015625,
1117
+ "high": 4604.32373046875,
1118
+ "low": 4522.24072265625,
1119
+ "close": 4564.3603515625,
1120
+ "volume": 41344.58984375,
1121
+ "amount": 186778160.0
1122
+ },
1123
+ {
1124
+ "timestamp": "2025-09-03T09:00:00+08:00",
1125
+ "open": 4560.51171875,
1126
+ "high": 4601.98291015625,
1127
+ "low": 4505.90380859375,
1128
+ "close": 4555.81787109375,
1129
+ "volume": 52268.02734375,
1130
+ "amount": 233733104.0
1131
+ }
1132
+ ],
1133
+ "actual_data": [],
1134
+ "analysis": {}
1135
+ }
webui/prediction_results/prediction_20250829_121801.json ADDED
@@ -0,0 +1,1135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "timestamp": "2025-08-29T12:18:01.979611",
3
+ "file_path": "BTCUSDT_1h",
4
+ "prediction_type": "Kronos model prediction (latest data)",
5
+ "prediction_params": {
6
+ "symbol": "BTCUSDT",
7
+ "interval": "1h",
8
+ "limit": 400,
9
+ "lookback": 400,
10
+ "pred_len": 120,
11
+ "temperature": 1.2,
12
+ "top_p": 0.9,
13
+ "sample_count": 28,
14
+ "start_date": "latest"
15
+ },
16
+ "input_data_summary": {
17
+ "rows": 400,
18
+ "columns": [
19
+ "open",
20
+ "high",
21
+ "low",
22
+ "close",
23
+ "volume",
24
+ "amount"
25
+ ],
26
+ "price_range": {
27
+ "open": {
28
+ "min": 109100.24,
29
+ "max": 123847.82
30
+ },
31
+ "high": {
32
+ "min": 109910.68,
33
+ "max": 124474.0
34
+ },
35
+ "low": {
36
+ "min": 108666.66,
37
+ "max": 123337.66
38
+ },
39
+ "close": {
40
+ "min": 109100.23,
41
+ "max": 123847.83
42
+ }
43
+ },
44
+ "last_values": {
45
+ "open": 111419.98,
46
+ "high": 111606.6,
47
+ "low": 111302.27,
48
+ "close": 111571.88
49
+ }
50
+ },
51
+ "prediction_results": [
52
+ {
53
+ "timestamp": "2025-08-29T12:00:00+08:00",
54
+ "open": 111678.046875,
55
+ "high": 112058.6484375,
56
+ "low": 111368.4765625,
57
+ "close": 111744.7734375,
58
+ "volume": 405.9655456542969,
59
+ "amount": 47038224.0
60
+ },
61
+ {
62
+ "timestamp": "2025-08-29T13:00:00+08:00",
63
+ "open": 111796.3828125,
64
+ "high": 112146.296875,
65
+ "low": 111461.4765625,
66
+ "close": 111780.171875,
67
+ "volume": 432.43914794921875,
68
+ "amount": 49848024.0
69
+ },
70
+ {
71
+ "timestamp": "2025-08-29T14:00:00+08:00",
72
+ "open": 111791.625,
73
+ "high": 112208.390625,
74
+ "low": 111419.890625,
75
+ "close": 111882.1484375,
76
+ "volume": 540.7537841796875,
77
+ "amount": 61842488.0
78
+ },
79
+ {
80
+ "timestamp": "2025-08-29T15:00:00+08:00",
81
+ "open": 111769.8671875,
82
+ "high": 112259.59375,
83
+ "low": 111382.8125,
84
+ "close": 111854.5,
85
+ "volume": 554.3189086914062,
86
+ "amount": 62870188.0
87
+ },
88
+ {
89
+ "timestamp": "2025-08-29T16:00:00+08:00",
90
+ "open": 111927.046875,
91
+ "high": 112388.6796875,
92
+ "low": 111471.046875,
93
+ "close": 111938.5078125,
94
+ "volume": 557.777099609375,
95
+ "amount": 63840504.0
96
+ },
97
+ {
98
+ "timestamp": "2025-08-29T17:00:00+08:00",
99
+ "open": 111790.3203125,
100
+ "high": 112544.296875,
101
+ "low": 111308.9765625,
102
+ "close": 112095.5703125,
103
+ "volume": 734.0645141601562,
104
+ "amount": 83315408.0
105
+ },
106
+ {
107
+ "timestamp": "2025-08-29T18:00:00+08:00",
108
+ "open": 112104.0703125,
109
+ "high": 112711.390625,
110
+ "low": 111511.2734375,
111
+ "close": 112256.734375,
112
+ "volume": 813.0852661132812,
113
+ "amount": 91869640.0
114
+ },
115
+ {
116
+ "timestamp": "2025-08-29T19:00:00+08:00",
117
+ "open": 112036.8203125,
118
+ "high": 112828.796875,
119
+ "low": 111500.0390625,
120
+ "close": 112430.0625,
121
+ "volume": 814.6621704101562,
122
+ "amount": 93057072.0
123
+ },
124
+ {
125
+ "timestamp": "2025-08-29T20:00:00+08:00",
126
+ "open": 112277.0390625,
127
+ "high": 113020.4453125,
128
+ "low": 111647.8203125,
129
+ "close": 112538.7109375,
130
+ "volume": 808.9354248046875,
131
+ "amount": 91927912.0
132
+ },
133
+ {
134
+ "timestamp": "2025-08-29T21:00:00+08:00",
135
+ "open": 112360.5703125,
136
+ "high": 113118.484375,
137
+ "low": 111740.078125,
138
+ "close": 112733.21875,
139
+ "volume": 848.8428955078125,
140
+ "amount": 95803144.0
141
+ },
142
+ {
143
+ "timestamp": "2025-08-29T22:00:00+08:00",
144
+ "open": 112677.671875,
145
+ "high": 113365.2421875,
146
+ "low": 112083.640625,
147
+ "close": 112972.515625,
148
+ "volume": 918.8619995117188,
149
+ "amount": 103425584.0
150
+ },
151
+ {
152
+ "timestamp": "2025-08-29T23:00:00+08:00",
153
+ "open": 112883.890625,
154
+ "high": 113497.1484375,
155
+ "low": 112433.7421875,
156
+ "close": 113059.265625,
157
+ "volume": 894.2817993164062,
158
+ "amount": 101721584.0
159
+ },
160
+ {
161
+ "timestamp": "2025-08-30T00:00:00+08:00",
162
+ "open": 112990.3203125,
163
+ "high": 113604.203125,
164
+ "low": 112319.265625,
165
+ "close": 113162.2578125,
166
+ "volume": 795.2791748046875,
167
+ "amount": 90507440.0
168
+ },
169
+ {
170
+ "timestamp": "2025-08-30T01:00:00+08:00",
171
+ "open": 113053.015625,
172
+ "high": 113701.5703125,
173
+ "low": 112730.328125,
174
+ "close": 113401.4296875,
175
+ "volume": 835.3759155273438,
176
+ "amount": 95571496.0
177
+ },
178
+ {
179
+ "timestamp": "2025-08-30T02:00:00+08:00",
180
+ "open": 113313.8515625,
181
+ "high": 113946.765625,
182
+ "low": 112822.28125,
183
+ "close": 113557.015625,
184
+ "volume": 908.225830078125,
185
+ "amount": 104284352.0
186
+ },
187
+ {
188
+ "timestamp": "2025-08-30T03:00:00+08:00",
189
+ "open": 113491.3671875,
190
+ "high": 114152.734375,
191
+ "low": 112822.0625,
192
+ "close": 113787.734375,
193
+ "volume": 805.0210571289062,
194
+ "amount": 93016096.0
195
+ },
196
+ {
197
+ "timestamp": "2025-08-30T04:00:00+08:00",
198
+ "open": 113709.828125,
199
+ "high": 114362.234375,
200
+ "low": 113255.1640625,
201
+ "close": 113878.640625,
202
+ "volume": 843.4304809570312,
203
+ "amount": 97360744.0
204
+ },
205
+ {
206
+ "timestamp": "2025-08-30T05:00:00+08:00",
207
+ "open": 113846.5625,
208
+ "high": 114394.2578125,
209
+ "low": 113421.1484375,
210
+ "close": 114012.2734375,
211
+ "volume": 730.8413696289062,
212
+ "amount": 84390816.0
213
+ },
214
+ {
215
+ "timestamp": "2025-08-30T06:00:00+08:00",
216
+ "open": 113922.25,
217
+ "high": 114599.1875,
218
+ "low": 113537.1875,
219
+ "close": 114216.015625,
220
+ "volume": 800.009521484375,
221
+ "amount": 91974744.0
222
+ },
223
+ {
224
+ "timestamp": "2025-08-30T07:00:00+08:00",
225
+ "open": 114085.484375,
226
+ "high": 114788.0078125,
227
+ "low": 113634.375,
228
+ "close": 114381.109375,
229
+ "volume": 798.4268188476562,
230
+ "amount": 92166744.0
231
+ },
232
+ {
233
+ "timestamp": "2025-08-30T08:00:00+08:00",
234
+ "open": 114266.0390625,
235
+ "high": 114902.3671875,
236
+ "low": 113825.8125,
237
+ "close": 114427.5078125,
238
+ "volume": 781.154541015625,
239
+ "amount": 90198160.0
240
+ },
241
+ {
242
+ "timestamp": "2025-08-30T09:00:00+08:00",
243
+ "open": 114198.859375,
244
+ "high": 114718.0859375,
245
+ "low": 113719.09375,
246
+ "close": 114445.15625,
247
+ "volume": 727.2125854492188,
248
+ "amount": 84094280.0
249
+ },
250
+ {
251
+ "timestamp": "2025-08-30T10:00:00+08:00",
252
+ "open": 114254.078125,
253
+ "high": 115053.984375,
254
+ "low": 113719.296875,
255
+ "close": 114578.6640625,
256
+ "volume": 787.0217895507812,
257
+ "amount": 90583872.0
258
+ },
259
+ {
260
+ "timestamp": "2025-08-30T11:00:00+08:00",
261
+ "open": 114370.4765625,
262
+ "high": 114978.4375,
263
+ "low": 113954.0,
264
+ "close": 114610.1640625,
265
+ "volume": 698.4326171875,
266
+ "amount": 80562704.0
267
+ },
268
+ {
269
+ "timestamp": "2025-08-30T12:00:00+08:00",
270
+ "open": 114524.578125,
271
+ "high": 114983.5234375,
272
+ "low": 114071.0390625,
273
+ "close": 114640.3984375,
274
+ "volume": 711.9177856445312,
275
+ "amount": 82456848.0
276
+ },
277
+ {
278
+ "timestamp": "2025-08-30T13:00:00+08:00",
279
+ "open": 114473.9375,
280
+ "high": 115008.3671875,
281
+ "low": 113770.96875,
282
+ "close": 114655.96875,
283
+ "volume": 641.5777587890625,
284
+ "amount": 74140864.0
285
+ },
286
+ {
287
+ "timestamp": "2025-08-30T14:00:00+08:00",
288
+ "open": 114599.3359375,
289
+ "high": 114959.15625,
290
+ "low": 114203.4140625,
291
+ "close": 114578.296875,
292
+ "volume": 603.5386352539062,
293
+ "amount": 69634744.0
294
+ },
295
+ {
296
+ "timestamp": "2025-08-30T15:00:00+08:00",
297
+ "open": 114565.4453125,
298
+ "high": 115189.7265625,
299
+ "low": 114228.171875,
300
+ "close": 114749.9921875,
301
+ "volume": 824.3392944335938,
302
+ "amount": 94645616.0
303
+ },
304
+ {
305
+ "timestamp": "2025-08-30T16:00:00+08:00",
306
+ "open": 114666.6953125,
307
+ "high": 115140.3828125,
308
+ "low": 114342.3359375,
309
+ "close": 114742.46875,
310
+ "volume": 706.1392211914062,
311
+ "amount": 81438368.0
312
+ },
313
+ {
314
+ "timestamp": "2025-08-30T17:00:00+08:00",
315
+ "open": 114636.4453125,
316
+ "high": 115071.3515625,
317
+ "low": 114165.953125,
318
+ "close": 114799.7109375,
319
+ "volume": 603.8955078125,
320
+ "amount": 69889120.0
321
+ },
322
+ {
323
+ "timestamp": "2025-08-30T18:00:00+08:00",
324
+ "open": 114637.8203125,
325
+ "high": 115285.8671875,
326
+ "low": 114242.046875,
327
+ "close": 114799.8125,
328
+ "volume": 709.6212158203125,
329
+ "amount": 82033984.0
330
+ },
331
+ {
332
+ "timestamp": "2025-08-30T19:00:00+08:00",
333
+ "open": 114650.3359375,
334
+ "high": 115288.828125,
335
+ "low": 114052.4296875,
336
+ "close": 114782.5625,
337
+ "volume": 702.4822998046875,
338
+ "amount": 81290800.0
339
+ },
340
+ {
341
+ "timestamp": "2025-08-30T20:00:00+08:00",
342
+ "open": 114726.6640625,
343
+ "high": 115218.671875,
344
+ "low": 114385.2265625,
345
+ "close": 114810.65625,
346
+ "volume": 642.02294921875,
347
+ "amount": 74575360.0
348
+ },
349
+ {
350
+ "timestamp": "2025-08-30T21:00:00+08:00",
351
+ "open": 114892.1875,
352
+ "high": 115429.2265625,
353
+ "low": 114520.5859375,
354
+ "close": 114968.1875,
355
+ "volume": 581.2764892578125,
356
+ "amount": 67660224.0
357
+ },
358
+ {
359
+ "timestamp": "2025-08-30T22:00:00+08:00",
360
+ "open": 114778.40625,
361
+ "high": 115230.03125,
362
+ "low": 114373.734375,
363
+ "close": 114951.84375,
364
+ "volume": 664.252197265625,
365
+ "amount": 76671360.0
366
+ },
367
+ {
368
+ "timestamp": "2025-08-30T23:00:00+08:00",
369
+ "open": 114792.9375,
370
+ "high": 115302.5703125,
371
+ "low": 114358.7734375,
372
+ "close": 114915.8828125,
373
+ "volume": 614.5665283203125,
374
+ "amount": 71216488.0
375
+ },
376
+ {
377
+ "timestamp": "2025-08-31T00:00:00+08:00",
378
+ "open": 114701.2421875,
379
+ "high": 115293.90625,
380
+ "low": 114356.75,
381
+ "close": 114886.0,
382
+ "volume": 758.6578979492188,
383
+ "amount": 87556176.0
384
+ },
385
+ {
386
+ "timestamp": "2025-08-31T01:00:00+08:00",
387
+ "open": 114800.234375,
388
+ "high": 115376.8203125,
389
+ "low": 114549.1953125,
390
+ "close": 114942.9453125,
391
+ "volume": 660.4749755859375,
392
+ "amount": 76325336.0
393
+ },
394
+ {
395
+ "timestamp": "2025-08-31T02:00:00+08:00",
396
+ "open": 114899.90625,
397
+ "high": 115435.015625,
398
+ "low": 114550.4140625,
399
+ "close": 115096.53125,
400
+ "volume": 677.5713500976562,
401
+ "amount": 78511792.0
402
+ },
403
+ {
404
+ "timestamp": "2025-08-31T03:00:00+08:00",
405
+ "open": 115009.75,
406
+ "high": 115614.5625,
407
+ "low": 114704.109375,
408
+ "close": 115275.328125,
409
+ "volume": 627.1311645507812,
410
+ "amount": 72788048.0
411
+ },
412
+ {
413
+ "timestamp": "2025-08-31T04:00:00+08:00",
414
+ "open": 115312.7265625,
415
+ "high": 115785.8828125,
416
+ "low": 114951.515625,
417
+ "close": 115352.828125,
418
+ "volume": 684.791259765625,
419
+ "amount": 79607792.0
420
+ },
421
+ {
422
+ "timestamp": "2025-08-31T05:00:00+08:00",
423
+ "open": 115360.7890625,
424
+ "high": 115944.265625,
425
+ "low": 114984.9296875,
426
+ "close": 115551.5390625,
427
+ "volume": 759.218017578125,
428
+ "amount": 88073592.0
429
+ },
430
+ {
431
+ "timestamp": "2025-08-31T06:00:00+08:00",
432
+ "open": 115514.921875,
433
+ "high": 115978.9609375,
434
+ "low": 115180.875,
435
+ "close": 115584.578125,
436
+ "volume": 731.6386108398438,
437
+ "amount": 84956176.0
438
+ },
439
+ {
440
+ "timestamp": "2025-08-31T07:00:00+08:00",
441
+ "open": 115572.9765625,
442
+ "high": 116045.5859375,
443
+ "low": 115320.328125,
444
+ "close": 115734.9375,
445
+ "volume": 672.762451171875,
446
+ "amount": 78672560.0
447
+ },
448
+ {
449
+ "timestamp": "2025-08-31T08:00:00+08:00",
450
+ "open": 115623.4453125,
451
+ "high": 116154.1875,
452
+ "low": 115299.625,
453
+ "close": 115679.859375,
454
+ "volume": 678.5626831054688,
455
+ "amount": 79602008.0
456
+ },
457
+ {
458
+ "timestamp": "2025-08-31T09:00:00+08:00",
459
+ "open": 115533.9140625,
460
+ "high": 116118.5234375,
461
+ "low": 115244.1015625,
462
+ "close": 115750.1484375,
463
+ "volume": 656.5803833007812,
464
+ "amount": 76637552.0
465
+ },
466
+ {
467
+ "timestamp": "2025-08-31T10:00:00+08:00",
468
+ "open": 115534.28125,
469
+ "high": 116049.2265625,
470
+ "low": 115140.5234375,
471
+ "close": 115718.9765625,
472
+ "volume": 673.4630737304688,
473
+ "amount": 78149592.0
474
+ },
475
+ {
476
+ "timestamp": "2025-08-31T11:00:00+08:00",
477
+ "open": 115686.109375,
478
+ "high": 116227.015625,
479
+ "low": 115103.0078125,
480
+ "close": 115691.7265625,
481
+ "volume": 730.6686401367188,
482
+ "amount": 85101936.0
483
+ },
484
+ {
485
+ "timestamp": "2025-08-31T12:00:00+08:00",
486
+ "open": 115557.546875,
487
+ "high": 116038.984375,
488
+ "low": 115196.140625,
489
+ "close": 115637.84375,
490
+ "volume": 616.0569458007812,
491
+ "amount": 71511352.0
492
+ },
493
+ {
494
+ "timestamp": "2025-08-31T13:00:00+08:00",
495
+ "open": 115577.7578125,
496
+ "high": 116125.296875,
497
+ "low": 115175.7734375,
498
+ "close": 115594.984375,
499
+ "volume": 715.7029418945312,
500
+ "amount": 83584912.0
501
+ },
502
+ {
503
+ "timestamp": "2025-08-31T14:00:00+08:00",
504
+ "open": 115540.7734375,
505
+ "high": 115974.453125,
506
+ "low": 115086.125,
507
+ "close": 115500.296875,
508
+ "volume": 668.9669799804688,
509
+ "amount": 77617560.0
510
+ },
511
+ {
512
+ "timestamp": "2025-08-31T15:00:00+08:00",
513
+ "open": 115392.5703125,
514
+ "high": 115996.546875,
515
+ "low": 115064.015625,
516
+ "close": 115569.5546875,
517
+ "volume": 799.4886474609375,
518
+ "amount": 92742384.0
519
+ },
520
+ {
521
+ "timestamp": "2025-08-31T16:00:00+08:00",
522
+ "open": 115492.515625,
523
+ "high": 116025.59375,
524
+ "low": 115198.1640625,
525
+ "close": 115712.5703125,
526
+ "volume": 608.7568359375,
527
+ "amount": 70650136.0
528
+ },
529
+ {
530
+ "timestamp": "2025-08-31T17:00:00+08:00",
531
+ "open": 115824.375,
532
+ "high": 116295.296875,
533
+ "low": 115440.90625,
534
+ "close": 115886.5546875,
535
+ "volume": 655.3104248046875,
536
+ "amount": 75839392.0
537
+ },
538
+ {
539
+ "timestamp": "2025-08-31T18:00:00+08:00",
540
+ "open": 115781.7421875,
541
+ "high": 116216.75,
542
+ "low": 115292.1875,
543
+ "close": 115914.1015625,
544
+ "volume": 737.2243041992188,
545
+ "amount": 85503688.0
546
+ },
547
+ {
548
+ "timestamp": "2025-08-31T19:00:00+08:00",
549
+ "open": 115817.6796875,
550
+ "high": 116349.8828125,
551
+ "low": 115472.5234375,
552
+ "close": 115940.0078125,
553
+ "volume": 702.83349609375,
554
+ "amount": 81555112.0
555
+ },
556
+ {
557
+ "timestamp": "2025-08-31T20:00:00+08:00",
558
+ "open": 115901.71875,
559
+ "high": 116512.8125,
560
+ "low": 115638.859375,
561
+ "close": 116140.46875,
562
+ "volume": 659.1805419921875,
563
+ "amount": 76850248.0
564
+ },
565
+ {
566
+ "timestamp": "2025-08-31T21:00:00+08:00",
567
+ "open": 116034.828125,
568
+ "high": 116533.2265625,
569
+ "low": 115556.8984375,
570
+ "close": 115999.234375,
571
+ "volume": 703.81787109375,
572
+ "amount": 80180824.0
573
+ },
574
+ {
575
+ "timestamp": "2025-08-31T22:00:00+08:00",
576
+ "open": 116069.2890625,
577
+ "high": 116596.6953125,
578
+ "low": 115546.0390625,
579
+ "close": 116206.28125,
580
+ "volume": 803.7196044921875,
581
+ "amount": 92996728.0
582
+ },
583
+ {
584
+ "timestamp": "2025-08-31T23:00:00+08:00",
585
+ "open": 116168.6015625,
586
+ "high": 116798.75,
587
+ "low": 115866.921875,
588
+ "close": 116420.046875,
589
+ "volume": 798.1824340820312,
590
+ "amount": 92726352.0
591
+ },
592
+ {
593
+ "timestamp": "2025-09-01T00:00:00+08:00",
594
+ "open": 116389.359375,
595
+ "high": 116927.6171875,
596
+ "low": 116036.3203125,
597
+ "close": 116534.2890625,
598
+ "volume": 874.3668823242188,
599
+ "amount": 102158488.0
600
+ },
601
+ {
602
+ "timestamp": "2025-09-01T01:00:00+08:00",
603
+ "open": 116445.0546875,
604
+ "high": 117008.7265625,
605
+ "low": 115990.6328125,
606
+ "close": 116543.7890625,
607
+ "volume": 883.1549682617188,
608
+ "amount": 102974064.0
609
+ },
610
+ {
611
+ "timestamp": "2025-09-01T02:00:00+08:00",
612
+ "open": 116323.375,
613
+ "high": 116852.796875,
614
+ "low": 115945.9921875,
615
+ "close": 116528.578125,
616
+ "volume": 842.6671142578125,
617
+ "amount": 97626464.0
618
+ },
619
+ {
620
+ "timestamp": "2025-09-01T03:00:00+08:00",
621
+ "open": 116487.3203125,
622
+ "high": 116942.203125,
623
+ "low": 116169.2890625,
624
+ "close": 116584.1484375,
625
+ "volume": 651.710693359375,
626
+ "amount": 76004512.0
627
+ },
628
+ {
629
+ "timestamp": "2025-09-01T04:00:00+08:00",
630
+ "open": 116594.375,
631
+ "high": 116920.8359375,
632
+ "low": 116259.4765625,
633
+ "close": 116554.0625,
634
+ "volume": 561.9791870117188,
635
+ "amount": 65773012.0
636
+ },
637
+ {
638
+ "timestamp": "2025-09-01T05:00:00+08:00",
639
+ "open": 116431.3125,
640
+ "high": 116817.296875,
641
+ "low": 116082.171875,
642
+ "close": 116428.109375,
643
+ "volume": 576.2901000976562,
644
+ "amount": 67000744.0
645
+ },
646
+ {
647
+ "timestamp": "2025-09-01T06:00:00+08:00",
648
+ "open": 116441.5859375,
649
+ "high": 116920.515625,
650
+ "low": 116157.0234375,
651
+ "close": 116459.3203125,
652
+ "volume": 598.8751831054688,
653
+ "amount": 69953344.0
654
+ },
655
+ {
656
+ "timestamp": "2025-09-01T07:00:00+08:00",
657
+ "open": 116404.265625,
658
+ "high": 116829.828125,
659
+ "low": 116023.109375,
660
+ "close": 116423.4453125,
661
+ "volume": 596.3116455078125,
662
+ "amount": 69609616.0
663
+ },
664
+ {
665
+ "timestamp": "2025-09-01T08:00:00+08:00",
666
+ "open": 116430.609375,
667
+ "high": 116915.65625,
668
+ "low": 116025.4453125,
669
+ "close": 116406.953125,
670
+ "volume": 673.6424560546875,
671
+ "amount": 78286288.0
672
+ },
673
+ {
674
+ "timestamp": "2025-09-01T09:00:00+08:00",
675
+ "open": 116380.3984375,
676
+ "high": 116850.671875,
677
+ "low": 116046.046875,
678
+ "close": 116446.421875,
679
+ "volume": 589.7572631835938,
680
+ "amount": 68686032.0
681
+ },
682
+ {
683
+ "timestamp": "2025-09-01T10:00:00+08:00",
684
+ "open": 116416.1640625,
685
+ "high": 116779.859375,
686
+ "low": 116009.5078125,
687
+ "close": 116385.1953125,
688
+ "volume": 618.2947387695312,
689
+ "amount": 72080168.0
690
+ },
691
+ {
692
+ "timestamp": "2025-09-01T11:00:00+08:00",
693
+ "open": 116316.421875,
694
+ "high": 116879.671875,
695
+ "low": 115941.8125,
696
+ "close": 116481.2265625,
697
+ "volume": 678.6925659179688,
698
+ "amount": 79048768.0
699
+ },
700
+ {
701
+ "timestamp": "2025-09-01T12:00:00+08:00",
702
+ "open": 116406.1875,
703
+ "high": 116958.2734375,
704
+ "low": 116042.8515625,
705
+ "close": 116494.7890625,
706
+ "volume": 633.0341796875,
707
+ "amount": 73585200.0
708
+ },
709
+ {
710
+ "timestamp": "2025-09-01T13:00:00+08:00",
711
+ "open": 116524.4375,
712
+ "high": 116815.578125,
713
+ "low": 116129.515625,
714
+ "close": 116458.8125,
715
+ "volume": 773.78173828125,
716
+ "amount": 89548216.0
717
+ },
718
+ {
719
+ "timestamp": "2025-09-01T14:00:00+08:00",
720
+ "open": 116257.9765625,
721
+ "high": 117002.4609375,
722
+ "low": 115768.4609375,
723
+ "close": 116466.953125,
724
+ "volume": 730.5646362304688,
725
+ "amount": 85442800.0
726
+ },
727
+ {
728
+ "timestamp": "2025-09-01T15:00:00+08:00",
729
+ "open": 116394.4375,
730
+ "high": 117111.53125,
731
+ "low": 115888.4609375,
732
+ "close": 116620.1328125,
733
+ "volume": 750.8353881835938,
734
+ "amount": 87240464.0
735
+ },
736
+ {
737
+ "timestamp": "2025-09-01T16:00:00+08:00",
738
+ "open": 116480.3046875,
739
+ "high": 117249.8828125,
740
+ "low": 116091.0859375,
741
+ "close": 116582.828125,
742
+ "volume": 719.80810546875,
743
+ "amount": 83425224.0
744
+ },
745
+ {
746
+ "timestamp": "2025-09-01T17:00:00+08:00",
747
+ "open": 116625.28125,
748
+ "high": 117148.9140625,
749
+ "low": 116169.171875,
750
+ "close": 116616.453125,
751
+ "volume": 748.014892578125,
752
+ "amount": 86873928.0
753
+ },
754
+ {
755
+ "timestamp": "2025-09-01T18:00:00+08:00",
756
+ "open": 116465.78125,
757
+ "high": 117228.6875,
758
+ "low": 116200.203125,
759
+ "close": 116746.9609375,
760
+ "volume": 723.50634765625,
761
+ "amount": 84327800.0
762
+ },
763
+ {
764
+ "timestamp": "2025-09-01T19:00:00+08:00",
765
+ "open": 116727.921875,
766
+ "high": 117215.734375,
767
+ "low": 116388.9765625,
768
+ "close": 116691.78125,
769
+ "volume": 711.3038330078125,
770
+ "amount": 83376272.0
771
+ },
772
+ {
773
+ "timestamp": "2025-09-01T20:00:00+08:00",
774
+ "open": 116661.4296875,
775
+ "high": 117299.2734375,
776
+ "low": 116213.953125,
777
+ "close": 116756.6953125,
778
+ "volume": 849.3621826171875,
779
+ "amount": 99181008.0
780
+ },
781
+ {
782
+ "timestamp": "2025-09-01T21:00:00+08:00",
783
+ "open": 116673.796875,
784
+ "high": 117209.4609375,
785
+ "low": 116284.578125,
786
+ "close": 116691.109375,
787
+ "volume": 773.4111938476562,
788
+ "amount": 89430880.0
789
+ },
790
+ {
791
+ "timestamp": "2025-09-01T22:00:00+08:00",
792
+ "open": 116553.0546875,
793
+ "high": 117246.6796875,
794
+ "low": 116192.1484375,
795
+ "close": 116739.421875,
796
+ "volume": 808.733642578125,
797
+ "amount": 93944392.0
798
+ },
799
+ {
800
+ "timestamp": "2025-09-01T23:00:00+08:00",
801
+ "open": 116491.140625,
802
+ "high": 117103.796875,
803
+ "low": 116092.3515625,
804
+ "close": 116613.71875,
805
+ "volume": 920.4912109375,
806
+ "amount": 106971280.0
807
+ },
808
+ {
809
+ "timestamp": "2025-09-02T00:00:00+08:00",
810
+ "open": 116399.4453125,
811
+ "high": 117119.078125,
812
+ "low": 115873.90625,
813
+ "close": 116414.9140625,
814
+ "volume": 793.8433227539062,
815
+ "amount": 92618888.0
816
+ },
817
+ {
818
+ "timestamp": "2025-09-02T01:00:00+08:00",
819
+ "open": 116417.2265625,
820
+ "high": 116951.7890625,
821
+ "low": 116031.484375,
822
+ "close": 116506.4453125,
823
+ "volume": 808.601318359375,
824
+ "amount": 93406744.0
825
+ },
826
+ {
827
+ "timestamp": "2025-09-02T02:00:00+08:00",
828
+ "open": 116429.640625,
829
+ "high": 116834.796875,
830
+ "low": 116019.84375,
831
+ "close": 116483.15625,
832
+ "volume": 710.8600463867188,
833
+ "amount": 82647384.0
834
+ },
835
+ {
836
+ "timestamp": "2025-09-02T03:00:00+08:00",
837
+ "open": 116495.25,
838
+ "high": 116970.953125,
839
+ "low": 116084.34375,
840
+ "close": 116569.046875,
841
+ "volume": 686.535400390625,
842
+ "amount": 79612024.0
843
+ },
844
+ {
845
+ "timestamp": "2025-09-02T04:00:00+08:00",
846
+ "open": 116586.171875,
847
+ "high": 117087.5234375,
848
+ "low": 116261.9609375,
849
+ "close": 116622.140625,
850
+ "volume": 735.083984375,
851
+ "amount": 85561152.0
852
+ },
853
+ {
854
+ "timestamp": "2025-09-02T05:00:00+08:00",
855
+ "open": 116569.5,
856
+ "high": 117161.53125,
857
+ "low": 116007.578125,
858
+ "close": 116711.9921875,
859
+ "volume": 816.1932983398438,
860
+ "amount": 94527072.0
861
+ },
862
+ {
863
+ "timestamp": "2025-09-02T06:00:00+08:00",
864
+ "open": 116695.4140625,
865
+ "high": 117297.7890625,
866
+ "low": 116287.859375,
867
+ "close": 116752.4765625,
868
+ "volume": 736.2598876953125,
869
+ "amount": 84852048.0
870
+ },
871
+ {
872
+ "timestamp": "2025-09-02T07:00:00+08:00",
873
+ "open": 116725.03125,
874
+ "high": 117269.546875,
875
+ "low": 116203.7109375,
876
+ "close": 116853.1640625,
877
+ "volume": 763.790771484375,
878
+ "amount": 87616032.0
879
+ },
880
+ {
881
+ "timestamp": "2025-09-02T08:00:00+08:00",
882
+ "open": 116773.21875,
883
+ "high": 117348.953125,
884
+ "low": 116227.7109375,
885
+ "close": 116833.1328125,
886
+ "volume": 725.4615478515625,
887
+ "amount": 83941232.0
888
+ },
889
+ {
890
+ "timestamp": "2025-09-02T09:00:00+08:00",
891
+ "open": 116720.015625,
892
+ "high": 117093.6796875,
893
+ "low": 116395.734375,
894
+ "close": 116710.140625,
895
+ "volume": 614.5234375,
896
+ "amount": 70651232.0
897
+ },
898
+ {
899
+ "timestamp": "2025-09-02T10:00:00+08:00",
900
+ "open": 116630.1328125,
901
+ "high": 117353.0625,
902
+ "low": 116104.546875,
903
+ "close": 116951.4296875,
904
+ "volume": 880.6514892578125,
905
+ "amount": 101482296.0
906
+ },
907
+ {
908
+ "timestamp": "2025-09-02T11:00:00+08:00",
909
+ "open": 116990.328125,
910
+ "high": 117588.421875,
911
+ "low": 116374.0234375,
912
+ "close": 117017.65625,
913
+ "volume": 1038.6826171875,
914
+ "amount": 119858336.0
915
+ },
916
+ {
917
+ "timestamp": "2025-09-02T12:00:00+08:00",
918
+ "open": 116960.0390625,
919
+ "high": 117878.4453125,
920
+ "low": 116285.1171875,
921
+ "close": 117057.5390625,
922
+ "volume": 1086.5096435546875,
923
+ "amount": 126333256.0
924
+ },
925
+ {
926
+ "timestamp": "2025-09-02T13:00:00+08:00",
927
+ "open": 116975.890625,
928
+ "high": 117648.390625,
929
+ "low": 116486.5078125,
930
+ "close": 116986.75,
931
+ "volume": 1048.0028076171875,
932
+ "amount": 121992384.0
933
+ },
934
+ {
935
+ "timestamp": "2025-09-02T14:00:00+08:00",
936
+ "open": 116970.4609375,
937
+ "high": 117512.6171875,
938
+ "low": 116285.015625,
939
+ "close": 116903.984375,
940
+ "volume": 1220.4796142578125,
941
+ "amount": 141025200.0
942
+ },
943
+ {
944
+ "timestamp": "2025-09-02T15:00:00+08:00",
945
+ "open": 116793.2734375,
946
+ "high": 117350.84375,
947
+ "low": 116253.96875,
948
+ "close": 116932.8828125,
949
+ "volume": 1061.6988525390625,
950
+ "amount": 122746336.0
951
+ },
952
+ {
953
+ "timestamp": "2025-09-02T16:00:00+08:00",
954
+ "open": 116853.75,
955
+ "high": 117340.28125,
956
+ "low": 116209.3203125,
957
+ "close": 116892.1953125,
958
+ "volume": 974.4564819335938,
959
+ "amount": 113368176.0
960
+ },
961
+ {
962
+ "timestamp": "2025-09-02T17:00:00+08:00",
963
+ "open": 116773.203125,
964
+ "high": 117273.4921875,
965
+ "low": 116271.046875,
966
+ "close": 116836.796875,
967
+ "volume": 854.284912109375,
968
+ "amount": 99006200.0
969
+ },
970
+ {
971
+ "timestamp": "2025-09-02T18:00:00+08:00",
972
+ "open": 116814.1796875,
973
+ "high": 117335.03125,
974
+ "low": 116232.4609375,
975
+ "close": 116615.2109375,
976
+ "volume": 915.4868774414062,
977
+ "amount": 106284608.0
978
+ },
979
+ {
980
+ "timestamp": "2025-09-02T19:00:00+08:00",
981
+ "open": 116645.75,
982
+ "high": 117190.46875,
983
+ "low": 116190.78125,
984
+ "close": 116695.890625,
985
+ "volume": 877.5885009765625,
986
+ "amount": 102406208.0
987
+ },
988
+ {
989
+ "timestamp": "2025-09-02T20:00:00+08:00",
990
+ "open": 116690.3359375,
991
+ "high": 117289.0,
992
+ "low": 116284.9921875,
993
+ "close": 116861.890625,
994
+ "volume": 813.2171020507812,
995
+ "amount": 95104096.0
996
+ },
997
+ {
998
+ "timestamp": "2025-09-02T21:00:00+08:00",
999
+ "open": 116586.84375,
1000
+ "high": 117456.0390625,
1001
+ "low": 116077.8515625,
1002
+ "close": 116976.3046875,
1003
+ "volume": 837.3500366210938,
1004
+ "amount": 97072624.0
1005
+ },
1006
+ {
1007
+ "timestamp": "2025-09-02T22:00:00+08:00",
1008
+ "open": 116821.7734375,
1009
+ "high": 117490.1875,
1010
+ "low": 116459.0625,
1011
+ "close": 117040.109375,
1012
+ "volume": 823.6553955078125,
1013
+ "amount": 95456992.0
1014
+ },
1015
+ {
1016
+ "timestamp": "2025-09-02T23:00:00+08:00",
1017
+ "open": 116939.8359375,
1018
+ "high": 117548.5,
1019
+ "low": 116343.2734375,
1020
+ "close": 116860.359375,
1021
+ "volume": 903.7700805664062,
1022
+ "amount": 106190528.0
1023
+ },
1024
+ {
1025
+ "timestamp": "2025-09-03T00:00:00+08:00",
1026
+ "open": 116851.59375,
1027
+ "high": 117449.265625,
1028
+ "low": 116460.4609375,
1029
+ "close": 116942.8671875,
1030
+ "volume": 916.7927856445312,
1031
+ "amount": 105813096.0
1032
+ },
1033
+ {
1034
+ "timestamp": "2025-09-03T01:00:00+08:00",
1035
+ "open": 116909.53125,
1036
+ "high": 117407.3828125,
1037
+ "low": 116448.3515625,
1038
+ "close": 117044.453125,
1039
+ "volume": 970.6868286132812,
1040
+ "amount": 111699568.0
1041
+ },
1042
+ {
1043
+ "timestamp": "2025-09-03T02:00:00+08:00",
1044
+ "open": 116947.421875,
1045
+ "high": 117452.09375,
1046
+ "low": 116580.1796875,
1047
+ "close": 117036.84375,
1048
+ "volume": 878.35986328125,
1049
+ "amount": 101479472.0
1050
+ },
1051
+ {
1052
+ "timestamp": "2025-09-03T03:00:00+08:00",
1053
+ "open": 117057.7265625,
1054
+ "high": 117585.34375,
1055
+ "low": 116583.21875,
1056
+ "close": 116957.5,
1057
+ "volume": 864.3232421875,
1058
+ "amount": 101240544.0
1059
+ },
1060
+ {
1061
+ "timestamp": "2025-09-03T04:00:00+08:00",
1062
+ "open": 116940.359375,
1063
+ "high": 117445.15625,
1064
+ "low": 116404.328125,
1065
+ "close": 116904.671875,
1066
+ "volume": 965.25244140625,
1067
+ "amount": 111657992.0
1068
+ },
1069
+ {
1070
+ "timestamp": "2025-09-03T05:00:00+08:00",
1071
+ "open": 116881.9921875,
1072
+ "high": 117506.8359375,
1073
+ "low": 116296.328125,
1074
+ "close": 116913.8828125,
1075
+ "volume": 894.0365600585938,
1076
+ "amount": 102694544.0
1077
+ },
1078
+ {
1079
+ "timestamp": "2025-09-03T06:00:00+08:00",
1080
+ "open": 116839.6875,
1081
+ "high": 117333.625,
1082
+ "low": 116448.0,
1083
+ "close": 116912.3828125,
1084
+ "volume": 804.3404541015625,
1085
+ "amount": 92952784.0
1086
+ },
1087
+ {
1088
+ "timestamp": "2025-09-03T07:00:00+08:00",
1089
+ "open": 116795.6796875,
1090
+ "high": 117417.1875,
1091
+ "low": 116176.1875,
1092
+ "close": 116844.609375,
1093
+ "volume": 940.32763671875,
1094
+ "amount": 107772080.0
1095
+ },
1096
+ {
1097
+ "timestamp": "2025-09-03T08:00:00+08:00",
1098
+ "open": 116873.9609375,
1099
+ "high": 117542.6484375,
1100
+ "low": 116350.9140625,
1101
+ "close": 117018.234375,
1102
+ "volume": 1004.404541015625,
1103
+ "amount": 116074672.0
1104
+ },
1105
+ {
1106
+ "timestamp": "2025-09-03T09:00:00+08:00",
1107
+ "open": 117027.796875,
1108
+ "high": 117507.4765625,
1109
+ "low": 116469.2890625,
1110
+ "close": 117087.5,
1111
+ "volume": 854.998291015625,
1112
+ "amount": 97757368.0
1113
+ },
1114
+ {
1115
+ "timestamp": "2025-09-03T10:00:00+08:00",
1116
+ "open": 117158.8203125,
1117
+ "high": 117742.921875,
1118
+ "low": 116412.296875,
1119
+ "close": 117156.15625,
1120
+ "volume": 863.2265014648438,
1121
+ "amount": 99458456.0
1122
+ },
1123
+ {
1124
+ "timestamp": "2025-09-03T11:00:00+08:00",
1125
+ "open": 117090.3984375,
1126
+ "high": 117729.953125,
1127
+ "low": 116688.0703125,
1128
+ "close": 117370.34375,
1129
+ "volume": 1098.5123291015625,
1130
+ "amount": 125798176.0
1131
+ }
1132
+ ],
1133
+ "actual_data": [],
1134
+ "analysis": {}
1135
+ }
webui/prediction_results/prediction_20250829_144119.json ADDED
@@ -0,0 +1,2243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "timestamp": "2025-08-29T14:41:19.787855",
3
+ "file_path": "SOLUSDT_1h",
4
+ "prediction_type": "Kronos model prediction (latest data)",
5
+ "prediction_params": {
6
+ "symbol": "SOLUSDT",
7
+ "interval": "1h",
8
+ "limit": 1000,
9
+ "lookback": 400,
10
+ "pred_len": 120,
11
+ "temperature": 1.0,
12
+ "top_p": 0.9,
13
+ "sample_count": 1,
14
+ "start_date": "latest"
15
+ },
16
+ "input_data_summary": {
17
+ "rows": 400,
18
+ "columns": [
19
+ "open",
20
+ "high",
21
+ "low",
22
+ "close",
23
+ "volume",
24
+ "amount"
25
+ ],
26
+ "price_range": {
27
+ "open": {
28
+ "min": 156.64,
29
+ "max": 205.7
30
+ },
31
+ "high": {
32
+ "min": 158.52,
33
+ "max": 206.3
34
+ },
35
+ "low": {
36
+ "min": 155.83,
37
+ "max": 203.36
38
+ },
39
+ "close": {
40
+ "min": 156.63,
41
+ "max": 205.7
42
+ }
43
+ },
44
+ "last_values": {
45
+ "open": 162.23,
46
+ "high": 162.44,
47
+ "low": 161.26,
48
+ "close": 162.23
49
+ }
50
+ },
51
+ "prediction_results": [
52
+ {
53
+ "timestamp": "2025-08-29T15:00:00+08:00",
54
+ "open": 161.17906188964844,
55
+ "high": 161.45286560058594,
56
+ "low": 160.79344177246094,
57
+ "close": 160.83462524414062,
58
+ "volume": 70348.1953125,
59
+ "amount": 11386960.0
60
+ },
61
+ {
62
+ "timestamp": "2025-08-29T16:00:00+08:00",
63
+ "open": 161.05076599121094,
64
+ "high": 161.78805541992188,
65
+ "low": 159.93914794921875,
66
+ "close": 160.9297637939453,
67
+ "volume": 167794.0625,
68
+ "amount": 26701548.0
69
+ },
70
+ {
71
+ "timestamp": "2025-08-29T17:00:00+08:00",
72
+ "open": 160.85980224609375,
73
+ "high": 161.50103759765625,
74
+ "low": 159.98812866210938,
75
+ "close": 160.59483337402344,
76
+ "volume": 126656.7421875,
77
+ "amount": 20341272.0
78
+ },
79
+ {
80
+ "timestamp": "2025-08-29T18:00:00+08:00",
81
+ "open": 161.05235290527344,
82
+ "high": 161.1339111328125,
83
+ "low": 157.01278686523438,
84
+ "close": 157.97239685058594,
85
+ "volume": 227488.5625,
86
+ "amount": 36477924.0
87
+ },
88
+ {
89
+ "timestamp": "2025-08-29T19:00:00+08:00",
90
+ "open": 157.89866638183594,
91
+ "high": 158.9061737060547,
92
+ "low": 156.7437744140625,
93
+ "close": 157.7850341796875,
94
+ "volume": 184277.515625,
95
+ "amount": 29438422.0
96
+ },
97
+ {
98
+ "timestamp": "2025-08-29T20:00:00+08:00",
99
+ "open": 158.34718322753906,
100
+ "high": 159.40484619140625,
101
+ "low": 158.11962890625,
102
+ "close": 158.8380889892578,
103
+ "volume": 92614.171875,
104
+ "amount": 14456772.0
105
+ },
106
+ {
107
+ "timestamp": "2025-08-29T21:00:00+08:00",
108
+ "open": 160.07186889648438,
109
+ "high": 161.02035522460938,
110
+ "low": 158.61012268066406,
111
+ "close": 160.25523376464844,
112
+ "volume": 85173.9375,
113
+ "amount": 11956822.0
114
+ },
115
+ {
116
+ "timestamp": "2025-08-29T22:00:00+08:00",
117
+ "open": 160.3734893798828,
118
+ "high": 161.83810424804688,
119
+ "low": 159.63441467285156,
120
+ "close": 161.0004119873047,
121
+ "volume": 132487.359375,
122
+ "amount": 20846220.0
123
+ },
124
+ {
125
+ "timestamp": "2025-08-29T23:00:00+08:00",
126
+ "open": 162.53939819335938,
127
+ "high": 163.0418701171875,
128
+ "low": 159.56105041503906,
129
+ "close": 159.72625732421875,
130
+ "volume": 145127.640625,
131
+ "amount": 23415742.0
132
+ },
133
+ {
134
+ "timestamp": "2025-08-30T00:00:00+08:00",
135
+ "open": 160.64381408691406,
136
+ "high": 161.28497314453125,
137
+ "low": 160.38970947265625,
138
+ "close": 160.77296447753906,
139
+ "volume": 71809.2265625,
140
+ "amount": 11642340.0
141
+ },
142
+ {
143
+ "timestamp": "2025-08-30T01:00:00+08:00",
144
+ "open": 160.72378540039062,
145
+ "high": 162.29811096191406,
146
+ "low": 160.02459716796875,
147
+ "close": 161.84666442871094,
148
+ "volume": 87875.03125,
149
+ "amount": 14132009.0
150
+ },
151
+ {
152
+ "timestamp": "2025-08-30T02:00:00+08:00",
153
+ "open": 161.62696838378906,
154
+ "high": 161.76670837402344,
155
+ "low": 160.96514892578125,
156
+ "close": 160.9419403076172,
157
+ "volume": 74637.171875,
158
+ "amount": 12041958.0
159
+ },
160
+ {
161
+ "timestamp": "2025-08-30T03:00:00+08:00",
162
+ "open": 161.14598083496094,
163
+ "high": 161.54042053222656,
164
+ "low": 160.8828887939453,
165
+ "close": 160.97665405273438,
166
+ "volume": 61887.0625,
167
+ "amount": 10198354.0
168
+ },
169
+ {
170
+ "timestamp": "2025-08-30T04:00:00+08:00",
171
+ "open": 161.08091735839844,
172
+ "high": 161.11135864257812,
173
+ "low": 160.46658325195312,
174
+ "close": 160.5911865234375,
175
+ "volume": 55093.03125,
176
+ "amount": 9022342.0
177
+ },
178
+ {
179
+ "timestamp": "2025-08-30T05:00:00+08:00",
180
+ "open": 160.5637664794922,
181
+ "high": 161.41160583496094,
182
+ "low": 159.7776641845703,
183
+ "close": 160.62754821777344,
184
+ "volume": 108710.03125,
185
+ "amount": 17464460.0
186
+ },
187
+ {
188
+ "timestamp": "2025-08-30T06:00:00+08:00",
189
+ "open": 159.79046630859375,
190
+ "high": 162.5747833251953,
191
+ "low": 158.92007446289062,
192
+ "close": 162.000732421875,
193
+ "volume": 146738.90625,
194
+ "amount": 23292004.0
195
+ },
196
+ {
197
+ "timestamp": "2025-08-30T07:00:00+08:00",
198
+ "open": 161.6672821044922,
199
+ "high": 162.92276000976562,
200
+ "low": 160.92135620117188,
201
+ "close": 162.2119598388672,
202
+ "volume": 113902.171875,
203
+ "amount": 18079454.0
204
+ },
205
+ {
206
+ "timestamp": "2025-08-30T08:00:00+08:00",
207
+ "open": 161.6236572265625,
208
+ "high": 162.6363983154297,
209
+ "low": 160.5178985595703,
210
+ "close": 161.68124389648438,
211
+ "volume": 124147.4296875,
212
+ "amount": 19821166.0
213
+ },
214
+ {
215
+ "timestamp": "2025-08-30T09:00:00+08:00",
216
+ "open": 161.41561889648438,
217
+ "high": 162.56195068359375,
218
+ "low": 160.4806671142578,
219
+ "close": 161.75148010253906,
220
+ "volume": 129868.703125,
221
+ "amount": 20738592.0
222
+ },
223
+ {
224
+ "timestamp": "2025-08-30T10:00:00+08:00",
225
+ "open": 162.20692443847656,
226
+ "high": 162.2939453125,
227
+ "low": 159.66802978515625,
228
+ "close": 159.9722900390625,
229
+ "volume": 165946.34375,
230
+ "amount": 26951640.0
231
+ },
232
+ {
233
+ "timestamp": "2025-08-30T11:00:00+08:00",
234
+ "open": 159.56224060058594,
235
+ "high": 162.63214111328125,
236
+ "low": 158.2108154296875,
237
+ "close": 161.28077697753906,
238
+ "volume": 248590.21875,
239
+ "amount": 38900288.0
240
+ },
241
+ {
242
+ "timestamp": "2025-08-30T12:00:00+08:00",
243
+ "open": 161.2432403564453,
244
+ "high": 161.38619995117188,
245
+ "low": 160.46864318847656,
246
+ "close": 160.70884704589844,
247
+ "volume": 72224.78125,
248
+ "amount": 11461064.0
249
+ },
250
+ {
251
+ "timestamp": "2025-08-30T13:00:00+08:00",
252
+ "open": 161.16954040527344,
253
+ "high": 162.46363830566406,
254
+ "low": 160.8431396484375,
255
+ "close": 161.90090942382812,
256
+ "volume": 89050.453125,
257
+ "amount": 14281813.0
258
+ },
259
+ {
260
+ "timestamp": "2025-08-30T14:00:00+08:00",
261
+ "open": 161.4658203125,
262
+ "high": 162.0313720703125,
263
+ "low": 160.48248291015625,
264
+ "close": 161.01217651367188,
265
+ "volume": 112678.671875,
266
+ "amount": 18114584.0
267
+ },
268
+ {
269
+ "timestamp": "2025-08-30T15:00:00+08:00",
270
+ "open": 160.9954071044922,
271
+ "high": 161.2670135498047,
272
+ "low": 159.81051635742188,
273
+ "close": 159.9397430419922,
274
+ "volume": 103631.3203125,
275
+ "amount": 16626471.0
276
+ },
277
+ {
278
+ "timestamp": "2025-08-30T16:00:00+08:00",
279
+ "open": 160.16465759277344,
280
+ "high": 162.23768615722656,
281
+ "low": 159.4470977783203,
282
+ "close": 161.68736267089844,
283
+ "volume": 94569.109375,
284
+ "amount": 15133030.0
285
+ },
286
+ {
287
+ "timestamp": "2025-08-30T17:00:00+08:00",
288
+ "open": 161.5039825439453,
289
+ "high": 162.46461486816406,
290
+ "low": 160.74798583984375,
291
+ "close": 161.6398162841797,
292
+ "volume": 104232.078125,
293
+ "amount": 17014232.0
294
+ },
295
+ {
296
+ "timestamp": "2025-08-30T18:00:00+08:00",
297
+ "open": 161.4305877685547,
298
+ "high": 162.67420959472656,
299
+ "low": 160.66598510742188,
300
+ "close": 162.05223083496094,
301
+ "volume": 91566.140625,
302
+ "amount": 14759682.0
303
+ },
304
+ {
305
+ "timestamp": "2025-08-30T19:00:00+08:00",
306
+ "open": 163.6189422607422,
307
+ "high": 163.2269287109375,
308
+ "low": 159.4185791015625,
309
+ "close": 159.3329315185547,
310
+ "volume": 174770.5,
311
+ "amount": 29251498.0
312
+ },
313
+ {
314
+ "timestamp": "2025-08-30T20:00:00+08:00",
315
+ "open": 161.492919921875,
316
+ "high": 162.29168701171875,
317
+ "low": 159.6300506591797,
318
+ "close": 161.3277130126953,
319
+ "volume": 96570.21875,
320
+ "amount": 14269164.0
321
+ },
322
+ {
323
+ "timestamp": "2025-08-30T21:00:00+08:00",
324
+ "open": 161.47935485839844,
325
+ "high": 162.03028869628906,
326
+ "low": 161.01309204101562,
327
+ "close": 161.294677734375,
328
+ "volume": 77153.609375,
329
+ "amount": 12156504.0
330
+ },
331
+ {
332
+ "timestamp": "2025-08-30T22:00:00+08:00",
333
+ "open": 161.44398498535156,
334
+ "high": 161.51011657714844,
335
+ "low": 160.69593811035156,
336
+ "close": 160.8939971923828,
337
+ "volume": 60425.140625,
338
+ "amount": 9547498.0
339
+ },
340
+ {
341
+ "timestamp": "2025-08-30T23:00:00+08:00",
342
+ "open": 160.93128967285156,
343
+ "high": 161.4699249267578,
344
+ "low": 160.6180877685547,
345
+ "close": 160.85044860839844,
346
+ "volume": 67414.671875,
347
+ "amount": 10920558.0
348
+ },
349
+ {
350
+ "timestamp": "2025-08-31T00:00:00+08:00",
351
+ "open": 160.69317626953125,
352
+ "high": 161.03347778320312,
353
+ "low": 159.5727996826172,
354
+ "close": 159.81100463867188,
355
+ "volume": 90971.5390625,
356
+ "amount": 14634173.0
357
+ },
358
+ {
359
+ "timestamp": "2025-08-31T01:00:00+08:00",
360
+ "open": 160.38609313964844,
361
+ "high": 163.7931671142578,
362
+ "low": 159.31918334960938,
363
+ "close": 163.0769500732422,
364
+ "volume": 117866.2734375,
365
+ "amount": 18909072.0
366
+ },
367
+ {
368
+ "timestamp": "2025-08-31T02:00:00+08:00",
369
+ "open": 162.4783477783203,
370
+ "high": 162.56265258789062,
371
+ "low": 160.9515838623047,
372
+ "close": 161.543701171875,
373
+ "volume": 80715.6640625,
374
+ "amount": 11966504.0
375
+ },
376
+ {
377
+ "timestamp": "2025-08-31T03:00:00+08:00",
378
+ "open": 162.1942596435547,
379
+ "high": 163.8866424560547,
380
+ "low": 161.9018096923828,
381
+ "close": 163.31442260742188,
382
+ "volume": 79117.4765625,
383
+ "amount": 12835516.0
384
+ },
385
+ {
386
+ "timestamp": "2025-08-31T04:00:00+08:00",
387
+ "open": 163.2894287109375,
388
+ "high": 163.20985412597656,
389
+ "low": 160.4002685546875,
390
+ "close": 160.60891723632812,
391
+ "volume": 143881.578125,
392
+ "amount": 23569008.0
393
+ },
394
+ {
395
+ "timestamp": "2025-08-31T05:00:00+08:00",
396
+ "open": 161.2875518798828,
397
+ "high": 162.34719848632812,
398
+ "low": 159.91839599609375,
399
+ "close": 161.49600219726562,
400
+ "volume": 78041.7109375,
401
+ "amount": 11359644.0
402
+ },
403
+ {
404
+ "timestamp": "2025-08-31T06:00:00+08:00",
405
+ "open": 162.6195068359375,
406
+ "high": 163.1264190673828,
407
+ "low": 161.93960571289062,
408
+ "close": 162.53570556640625,
409
+ "volume": 69858.921875,
410
+ "amount": 11077598.0
411
+ },
412
+ {
413
+ "timestamp": "2025-08-31T07:00:00+08:00",
414
+ "open": 162.4152374267578,
415
+ "high": 162.33221435546875,
416
+ "low": 161.5100860595703,
417
+ "close": 161.56878662109375,
418
+ "volume": 56789.3671875,
419
+ "amount": 8957020.0
420
+ },
421
+ {
422
+ "timestamp": "2025-08-31T08:00:00+08:00",
423
+ "open": 162.19097900390625,
424
+ "high": 164.0687255859375,
425
+ "low": 161.6475830078125,
426
+ "close": 163.48123168945312,
427
+ "volume": 106377.65625,
428
+ "amount": 17364742.0
429
+ },
430
+ {
431
+ "timestamp": "2025-08-31T09:00:00+08:00",
432
+ "open": 163.2387237548828,
433
+ "high": 164.34071350097656,
434
+ "low": 161.87831115722656,
435
+ "close": 163.06814575195312,
436
+ "volume": 161232.453125,
437
+ "amount": 26354684.0
438
+ },
439
+ {
440
+ "timestamp": "2025-08-31T10:00:00+08:00",
441
+ "open": 163.49978637695312,
442
+ "high": 165.74432373046875,
443
+ "low": 162.79638671875,
444
+ "close": 164.7208251953125,
445
+ "volume": 301892.375,
446
+ "amount": 50468612.0
447
+ },
448
+ {
449
+ "timestamp": "2025-08-31T11:00:00+08:00",
450
+ "open": 164.99673461914062,
451
+ "high": 166.3669891357422,
452
+ "low": 164.15130615234375,
453
+ "close": 165.47671508789062,
454
+ "volume": 199991.78125,
455
+ "amount": 33256228.0
456
+ },
457
+ {
458
+ "timestamp": "2025-08-31T12:00:00+08:00",
459
+ "open": 165.79513549804688,
460
+ "high": 167.0158233642578,
461
+ "low": 165.00082397460938,
462
+ "close": 166.29966735839844,
463
+ "volume": 154040.796875,
464
+ "amount": 25580630.0
465
+ },
466
+ {
467
+ "timestamp": "2025-08-31T13:00:00+08:00",
468
+ "open": 166.0205841064453,
469
+ "high": 166.70193481445312,
470
+ "low": 164.46112060546875,
471
+ "close": 165.34878540039062,
472
+ "volume": 178085.3125,
473
+ "amount": 29476518.0
474
+ },
475
+ {
476
+ "timestamp": "2025-08-31T14:00:00+08:00",
477
+ "open": 166.24501037597656,
478
+ "high": 167.0667724609375,
479
+ "low": 164.58224487304688,
480
+ "close": 166.05015563964844,
481
+ "volume": 129364.75,
482
+ "amount": 21628500.0
483
+ },
484
+ {
485
+ "timestamp": "2025-08-31T15:00:00+08:00",
486
+ "open": 166.03521728515625,
487
+ "high": 167.3617706298828,
488
+ "low": 165.32102966308594,
489
+ "close": 166.63978576660156,
490
+ "volume": 211953.453125,
491
+ "amount": 35320700.0
492
+ },
493
+ {
494
+ "timestamp": "2025-08-31T16:00:00+08:00",
495
+ "open": 166.36239624023438,
496
+ "high": 167.03709411621094,
497
+ "low": 165.2759246826172,
498
+ "close": 165.89297485351562,
499
+ "volume": 194446.28125,
500
+ "amount": 32096862.0
501
+ },
502
+ {
503
+ "timestamp": "2025-08-31T17:00:00+08:00",
504
+ "open": 165.83676147460938,
505
+ "high": 167.5804443359375,
506
+ "low": 165.13429260253906,
507
+ "close": 167.40374755859375,
508
+ "volume": 117510.796875,
509
+ "amount": 19549350.0
510
+ },
511
+ {
512
+ "timestamp": "2025-08-31T18:00:00+08:00",
513
+ "open": 167.718505859375,
514
+ "high": 169.7425994873047,
515
+ "low": 165.9463348388672,
516
+ "close": 167.79901123046875,
517
+ "volume": 154990.125,
518
+ "amount": 25936012.0
519
+ },
520
+ {
521
+ "timestamp": "2025-08-31T19:00:00+08:00",
522
+ "open": 166.98268127441406,
523
+ "high": 169.21694946289062,
524
+ "low": 166.4047088623047,
525
+ "close": 168.42735290527344,
526
+ "volume": 150092.703125,
527
+ "amount": 24862448.0
528
+ },
529
+ {
530
+ "timestamp": "2025-08-31T20:00:00+08:00",
531
+ "open": 169.00360107421875,
532
+ "high": 170.40652465820312,
533
+ "low": 167.4154510498047,
534
+ "close": 168.48382568359375,
535
+ "volume": 163585.84375,
536
+ "amount": 27783852.0
537
+ },
538
+ {
539
+ "timestamp": "2025-08-31T21:00:00+08:00",
540
+ "open": 171.0612030029297,
541
+ "high": 170.92372131347656,
542
+ "low": 166.41586303710938,
543
+ "close": 166.46148681640625,
544
+ "volume": 211049.984375,
545
+ "amount": 35654996.0
546
+ },
547
+ {
548
+ "timestamp": "2025-08-31T22:00:00+08:00",
549
+ "open": 167.1434326171875,
550
+ "high": 169.17343139648438,
551
+ "low": 166.25559997558594,
552
+ "close": 168.48736572265625,
553
+ "volume": 108616.5234375,
554
+ "amount": 18216512.0
555
+ },
556
+ {
557
+ "timestamp": "2025-08-31T23:00:00+08:00",
558
+ "open": 168.4060516357422,
559
+ "high": 169.8519287109375,
560
+ "low": 167.69500732421875,
561
+ "close": 169.23049926757812,
562
+ "volume": 132322.421875,
563
+ "amount": 22429392.0
564
+ },
565
+ {
566
+ "timestamp": "2025-09-01T00:00:00+08:00",
567
+ "open": 169.1307373046875,
568
+ "high": 169.9923858642578,
569
+ "low": 168.27291870117188,
570
+ "close": 169.3440704345703,
571
+ "volume": 130938.1953125,
572
+ "amount": 22266326.0
573
+ },
574
+ {
575
+ "timestamp": "2025-09-01T01:00:00+08:00",
576
+ "open": 170.71987915039062,
577
+ "high": 172.1166229248047,
578
+ "low": 166.57391357421875,
579
+ "close": 166.91111755371094,
580
+ "volume": 178145.109375,
581
+ "amount": 31085734.0
582
+ },
583
+ {
584
+ "timestamp": "2025-09-01T02:00:00+08:00",
585
+ "open": 167.87940979003906,
586
+ "high": 169.94754028320312,
587
+ "low": 167.2145233154297,
588
+ "close": 169.26026916503906,
589
+ "volume": 237452.25,
590
+ "amount": 40556208.0
591
+ },
592
+ {
593
+ "timestamp": "2025-09-01T03:00:00+08:00",
594
+ "open": 169.79873657226562,
595
+ "high": 172.52313232421875,
596
+ "low": 168.80136108398438,
597
+ "close": 170.95692443847656,
598
+ "volume": 153268.984375,
599
+ "amount": 26564128.0
600
+ },
601
+ {
602
+ "timestamp": "2025-09-01T04:00:00+08:00",
603
+ "open": 171.47755432128906,
604
+ "high": 173.36245727539062,
605
+ "low": 170.61672973632812,
606
+ "close": 172.36859130859375,
607
+ "volume": 163983.890625,
608
+ "amount": 28440466.0
609
+ },
610
+ {
611
+ "timestamp": "2025-09-01T05:00:00+08:00",
612
+ "open": 171.81057739257812,
613
+ "high": 172.78013610839844,
614
+ "low": 170.8435821533203,
615
+ "close": 171.7489776611328,
616
+ "volume": 197065.3125,
617
+ "amount": 34102096.0
618
+ },
619
+ {
620
+ "timestamp": "2025-09-01T06:00:00+08:00",
621
+ "open": 172.0683135986328,
622
+ "high": 172.26524353027344,
623
+ "low": 170.71437072753906,
624
+ "close": 171.19569396972656,
625
+ "volume": 107609.1171875,
626
+ "amount": 18627106.0
627
+ },
628
+ {
629
+ "timestamp": "2025-09-01T07:00:00+08:00",
630
+ "open": 172.02198791503906,
631
+ "high": 172.12525939941406,
632
+ "low": 170.07484436035156,
633
+ "close": 170.31605529785156,
634
+ "volume": 85563.9375,
635
+ "amount": 14812041.0
636
+ },
637
+ {
638
+ "timestamp": "2025-09-01T08:00:00+08:00",
639
+ "open": 170.72235107421875,
640
+ "high": 171.53712463378906,
641
+ "low": 170.04710388183594,
642
+ "close": 170.90992736816406,
643
+ "volume": 79716.265625,
644
+ "amount": 13632395.0
645
+ },
646
+ {
647
+ "timestamp": "2025-09-01T09:00:00+08:00",
648
+ "open": 169.92446899414062,
649
+ "high": 171.5326385498047,
650
+ "low": 168.66513061523438,
651
+ "close": 170.45872497558594,
652
+ "volume": 90610.1171875,
653
+ "amount": 15508768.0
654
+ },
655
+ {
656
+ "timestamp": "2025-09-01T10:00:00+08:00",
657
+ "open": 170.16798400878906,
658
+ "high": 170.7797393798828,
659
+ "low": 169.3549346923828,
660
+ "close": 170.08651733398438,
661
+ "volume": 62793.8125,
662
+ "amount": 10855436.0
663
+ },
664
+ {
665
+ "timestamp": "2025-09-01T11:00:00+08:00",
666
+ "open": 170.4576873779297,
667
+ "high": 171.4794921875,
668
+ "low": 169.7115020751953,
669
+ "close": 170.74472045898438,
670
+ "volume": 70444.0859375,
671
+ "amount": 12303686.0
672
+ },
673
+ {
674
+ "timestamp": "2025-09-01T12:00:00+08:00",
675
+ "open": 170.3846435546875,
676
+ "high": 170.76490783691406,
677
+ "low": 169.48455810546875,
678
+ "close": 170.03225708007812,
679
+ "volume": 55656.328125,
680
+ "amount": 9871196.0
681
+ },
682
+ {
683
+ "timestamp": "2025-09-01T13:00:00+08:00",
684
+ "open": 169.16986083984375,
685
+ "high": 169.72764587402344,
686
+ "low": 168.61109924316406,
687
+ "close": 169.28616333007812,
688
+ "volume": 45208.1796875,
689
+ "amount": 7306340.0
690
+ },
691
+ {
692
+ "timestamp": "2025-09-01T14:00:00+08:00",
693
+ "open": 169.48617553710938,
694
+ "high": 170.8197021484375,
695
+ "low": 168.74118041992188,
696
+ "close": 170.28099060058594,
697
+ "volume": 96348.890625,
698
+ "amount": 16455361.0
699
+ },
700
+ {
701
+ "timestamp": "2025-09-01T15:00:00+08:00",
702
+ "open": 171.13844299316406,
703
+ "high": 171.14691162109375,
704
+ "low": 169.20101928710938,
705
+ "close": 169.30259704589844,
706
+ "volume": 75712.1171875,
707
+ "amount": 13124450.0
708
+ },
709
+ {
710
+ "timestamp": "2025-09-01T16:00:00+08:00",
711
+ "open": 169.6844024658203,
712
+ "high": 170.75648498535156,
713
+ "low": 168.8416290283203,
714
+ "close": 170.13108825683594,
715
+ "volume": 97837.0,
716
+ "amount": 16710126.0
717
+ },
718
+ {
719
+ "timestamp": "2025-09-01T17:00:00+08:00",
720
+ "open": 170.2710723876953,
721
+ "high": 171.19650268554688,
722
+ "low": 169.44618225097656,
723
+ "close": 170.04685974121094,
724
+ "volume": 74498.9453125,
725
+ "amount": 12934730.0
726
+ },
727
+ {
728
+ "timestamp": "2025-09-01T18:00:00+08:00",
729
+ "open": 170.1904754638672,
730
+ "high": 171.22679138183594,
731
+ "low": 169.22848510742188,
732
+ "close": 170.45179748535156,
733
+ "volume": 152042.359375,
734
+ "amount": 26143896.0
735
+ },
736
+ {
737
+ "timestamp": "2025-09-01T19:00:00+08:00",
738
+ "open": 170.73147583007812,
739
+ "high": 171.6114959716797,
740
+ "low": 169.873046875,
741
+ "close": 170.72625732421875,
742
+ "volume": 105481.890625,
743
+ "amount": 18068312.0
744
+ },
745
+ {
746
+ "timestamp": "2025-09-01T20:00:00+08:00",
747
+ "open": 171.06761169433594,
748
+ "high": 172.69766235351562,
749
+ "low": 170.50868225097656,
750
+ "close": 172.04443359375,
751
+ "volume": 135309.109375,
752
+ "amount": 23287214.0
753
+ },
754
+ {
755
+ "timestamp": "2025-09-01T21:00:00+08:00",
756
+ "open": 172.0660400390625,
757
+ "high": 173.3494873046875,
758
+ "low": 171.3815460205078,
759
+ "close": 172.69503784179688,
760
+ "volume": 167505.40625,
761
+ "amount": 29050666.0
762
+ },
763
+ {
764
+ "timestamp": "2025-09-01T22:00:00+08:00",
765
+ "open": 172.3904266357422,
766
+ "high": 172.7864532470703,
767
+ "low": 170.29837036132812,
768
+ "close": 170.63870239257812,
769
+ "volume": 301409.03125,
770
+ "amount": 51769616.0
771
+ },
772
+ {
773
+ "timestamp": "2025-09-01T23:00:00+08:00",
774
+ "open": 172.06173706054688,
775
+ "high": 172.8977813720703,
776
+ "low": 170.80819702148438,
777
+ "close": 171.73826599121094,
778
+ "volume": 104111.421875,
779
+ "amount": 18266884.0
780
+ },
781
+ {
782
+ "timestamp": "2025-09-02T00:00:00+08:00",
783
+ "open": 171.26173400878906,
784
+ "high": 173.4921875,
785
+ "low": 170.76124572753906,
786
+ "close": 172.94126892089844,
787
+ "volume": 122761.265625,
788
+ "amount": 21003698.0
789
+ },
790
+ {
791
+ "timestamp": "2025-09-02T01:00:00+08:00",
792
+ "open": 172.88360595703125,
793
+ "high": 173.62242126464844,
794
+ "low": 171.92535400390625,
795
+ "close": 172.69586181640625,
796
+ "volume": 94996.3515625,
797
+ "amount": 16521730.0
798
+ },
799
+ {
800
+ "timestamp": "2025-09-02T02:00:00+08:00",
801
+ "open": 173.1378173828125,
802
+ "high": 172.5879669189453,
803
+ "low": 171.05499267578125,
804
+ "close": 171.13232421875,
805
+ "volume": 109271.3203125,
806
+ "amount": 19259964.0
807
+ },
808
+ {
809
+ "timestamp": "2025-09-02T03:00:00+08:00",
810
+ "open": 172.68212890625,
811
+ "high": 174.18875122070312,
812
+ "low": 169.23243713378906,
813
+ "close": 169.4415740966797,
814
+ "volume": 142279.40625,
815
+ "amount": 24221024.0
816
+ },
817
+ {
818
+ "timestamp": "2025-09-02T04:00:00+08:00",
819
+ "open": 170.35081481933594,
820
+ "high": 172.00311279296875,
821
+ "low": 169.50978088378906,
822
+ "close": 171.177978515625,
823
+ "volume": 116025.5625,
824
+ "amount": 20077584.0
825
+ },
826
+ {
827
+ "timestamp": "2025-09-02T05:00:00+08:00",
828
+ "open": 171.27137756347656,
829
+ "high": 172.49578857421875,
830
+ "low": 170.58456420898438,
831
+ "close": 171.75389099121094,
832
+ "volume": 92343.4453125,
833
+ "amount": 15935463.0
834
+ },
835
+ {
836
+ "timestamp": "2025-09-02T06:00:00+08:00",
837
+ "open": 171.88011169433594,
838
+ "high": 172.8335418701172,
839
+ "low": 171.1839141845703,
840
+ "close": 172.137939453125,
841
+ "volume": 87056.3359375,
842
+ "amount": 15105010.0
843
+ },
844
+ {
845
+ "timestamp": "2025-09-02T07:00:00+08:00",
846
+ "open": 172.30003356933594,
847
+ "high": 173.23089599609375,
848
+ "low": 171.3990020751953,
849
+ "close": 172.49359130859375,
850
+ "volume": 149420.609375,
851
+ "amount": 26362652.0
852
+ },
853
+ {
854
+ "timestamp": "2025-09-02T08:00:00+08:00",
855
+ "open": 172.6053009033203,
856
+ "high": 173.82785034179688,
857
+ "low": 171.89857482910156,
858
+ "close": 173.19960021972656,
859
+ "volume": 170247.453125,
860
+ "amount": 29726446.0
861
+ },
862
+ {
863
+ "timestamp": "2025-09-02T09:00:00+08:00",
864
+ "open": 173.422119140625,
865
+ "high": 174.26101684570312,
866
+ "low": 172.7417449951172,
867
+ "close": 173.6376495361328,
868
+ "volume": 78947.53125,
869
+ "amount": 13900633.0
870
+ },
871
+ {
872
+ "timestamp": "2025-09-02T10:00:00+08:00",
873
+ "open": 173.60279846191406,
874
+ "high": 174.1590118408203,
875
+ "low": 172.65638732910156,
876
+ "close": 173.3321533203125,
877
+ "volume": 85853.453125,
878
+ "amount": 15012355.0
879
+ },
880
+ {
881
+ "timestamp": "2025-09-02T11:00:00+08:00",
882
+ "open": 173.75494384765625,
883
+ "high": 174.98439025878906,
884
+ "low": 173.13827514648438,
885
+ "close": 174.35629272460938,
886
+ "volume": 103285.15625,
887
+ "amount": 18170972.0
888
+ },
889
+ {
890
+ "timestamp": "2025-09-02T12:00:00+08:00",
891
+ "open": 174.3738555908203,
892
+ "high": 175.6508026123047,
893
+ "low": 173.41061401367188,
894
+ "close": 175.03883361816406,
895
+ "volume": 187793.34375,
896
+ "amount": 33190078.0
897
+ },
898
+ {
899
+ "timestamp": "2025-09-02T13:00:00+08:00",
900
+ "open": 175.10772705078125,
901
+ "high": 177.5194091796875,
902
+ "low": 173.93133544921875,
903
+ "close": 176.3385467529297,
904
+ "volume": 135665.421875,
905
+ "amount": 24008888.0
906
+ },
907
+ {
908
+ "timestamp": "2025-09-02T14:00:00+08:00",
909
+ "open": 176.3673095703125,
910
+ "high": 177.819091796875,
911
+ "low": 175.21450805664062,
912
+ "close": 177.1330108642578,
913
+ "volume": 176910.390625,
914
+ "amount": 31357882.0
915
+ },
916
+ {
917
+ "timestamp": "2025-09-02T15:00:00+08:00",
918
+ "open": 176.37306213378906,
919
+ "high": 177.49002075195312,
920
+ "low": 174.83949279785156,
921
+ "close": 176.60696411132812,
922
+ "volume": 140812.421875,
923
+ "amount": 24919428.0
924
+ },
925
+ {
926
+ "timestamp": "2025-09-02T16:00:00+08:00",
927
+ "open": 176.0399169921875,
928
+ "high": 176.607666015625,
929
+ "low": 174.42787170410156,
930
+ "close": 175.29393005371094,
931
+ "volume": 104101.8125,
932
+ "amount": 18057188.0
933
+ },
934
+ {
935
+ "timestamp": "2025-09-02T17:00:00+08:00",
936
+ "open": 175.9430694580078,
937
+ "high": 177.2678680419922,
938
+ "low": 174.47486877441406,
939
+ "close": 175.67279052734375,
940
+ "volume": 169130.03125,
941
+ "amount": 29807220.0
942
+ },
943
+ {
944
+ "timestamp": "2025-09-02T18:00:00+08:00",
945
+ "open": 175.82568359375,
946
+ "high": 176.75839233398438,
947
+ "low": 174.56826782226562,
948
+ "close": 175.5581512451172,
949
+ "volume": 169220.21875,
950
+ "amount": 29845672.0
951
+ },
952
+ {
953
+ "timestamp": "2025-09-02T19:00:00+08:00",
954
+ "open": 175.6074981689453,
955
+ "high": 178.08590698242188,
956
+ "low": 174.42449951171875,
957
+ "close": 176.9770050048828,
958
+ "volume": 135605.125,
959
+ "amount": 23945990.0
960
+ },
961
+ {
962
+ "timestamp": "2025-09-02T20:00:00+08:00",
963
+ "open": 177.2335205078125,
964
+ "high": 177.9937744140625,
965
+ "low": 175.6226043701172,
966
+ "close": 176.60552978515625,
967
+ "volume": 96588.1875,
968
+ "amount": 17118386.0
969
+ },
970
+ {
971
+ "timestamp": "2025-09-02T21:00:00+08:00",
972
+ "open": 176.52210998535156,
973
+ "high": 177.1573944091797,
974
+ "low": 175.49166870117188,
975
+ "close": 176.2715301513672,
976
+ "volume": 78103.421875,
977
+ "amount": 13693300.0
978
+ },
979
+ {
980
+ "timestamp": "2025-09-02T22:00:00+08:00",
981
+ "open": 176.7212677001953,
982
+ "high": 178.14431762695312,
983
+ "low": 176.14109802246094,
984
+ "close": 177.5001220703125,
985
+ "volume": 96987.625,
986
+ "amount": 17102190.0
987
+ },
988
+ {
989
+ "timestamp": "2025-09-02T23:00:00+08:00",
990
+ "open": 177.41270446777344,
991
+ "high": 177.8789520263672,
992
+ "low": 176.53936767578125,
993
+ "close": 177.11184692382812,
994
+ "volume": 50418.796875,
995
+ "amount": 8836982.0
996
+ },
997
+ {
998
+ "timestamp": "2025-09-03T00:00:00+08:00",
999
+ "open": 177.38307189941406,
1000
+ "high": 178.13760375976562,
1001
+ "low": 176.84130859375,
1002
+ "close": 177.6638946533203,
1003
+ "volume": 55947.140625,
1004
+ "amount": 9850114.0
1005
+ },
1006
+ {
1007
+ "timestamp": "2025-09-03T01:00:00+08:00",
1008
+ "open": 177.52337646484375,
1009
+ "high": 177.96353149414062,
1010
+ "low": 176.839599609375,
1011
+ "close": 177.4904022216797,
1012
+ "volume": 41717.828125,
1013
+ "amount": 7215820.0
1014
+ },
1015
+ {
1016
+ "timestamp": "2025-09-03T02:00:00+08:00",
1017
+ "open": 177.45333862304688,
1018
+ "high": 179.24002075195312,
1019
+ "low": 176.14212036132812,
1020
+ "close": 178.16275024414062,
1021
+ "volume": 118730.640625,
1022
+ "amount": 21027116.0
1023
+ },
1024
+ {
1025
+ "timestamp": "2025-09-03T03:00:00+08:00",
1026
+ "open": 178.5370635986328,
1027
+ "high": 180.56956481933594,
1028
+ "low": 177.5654296875,
1029
+ "close": 179.0944061279297,
1030
+ "volume": 147129.921875,
1031
+ "amount": 26418422.0
1032
+ },
1033
+ {
1034
+ "timestamp": "2025-09-03T04:00:00+08:00",
1035
+ "open": 179.23562622070312,
1036
+ "high": 180.2884521484375,
1037
+ "low": 178.24453735351562,
1038
+ "close": 179.3507537841797,
1039
+ "volume": 137848.046875,
1040
+ "amount": 24822310.0
1041
+ },
1042
+ {
1043
+ "timestamp": "2025-09-03T05:00:00+08:00",
1044
+ "open": 179.2522430419922,
1045
+ "high": 180.3149871826172,
1046
+ "low": 178.25698852539062,
1047
+ "close": 179.59359741210938,
1048
+ "volume": 142900.984375,
1049
+ "amount": 25635280.0
1050
+ },
1051
+ {
1052
+ "timestamp": "2025-09-03T06:00:00+08:00",
1053
+ "open": 180.89599609375,
1054
+ "high": 185.49746704101562,
1055
+ "low": 177.82252502441406,
1056
+ "close": 182.8541717529297,
1057
+ "volume": 260915.296875,
1058
+ "amount": 49695936.0
1059
+ },
1060
+ {
1061
+ "timestamp": "2025-09-03T07:00:00+08:00",
1062
+ "open": 180.2205047607422,
1063
+ "high": 186.1641387939453,
1064
+ "low": 174.51675415039062,
1065
+ "close": 185.35244750976562,
1066
+ "volume": 148369.46875,
1067
+ "amount": 26892272.0
1068
+ },
1069
+ {
1070
+ "timestamp": "2025-09-03T08:00:00+08:00",
1071
+ "open": 183.45098876953125,
1072
+ "high": 184.46099853515625,
1073
+ "low": 181.01943969726562,
1074
+ "close": 182.07785034179688,
1075
+ "volume": 162732.40625,
1076
+ "amount": 29322210.0
1077
+ },
1078
+ {
1079
+ "timestamp": "2025-09-03T09:00:00+08:00",
1080
+ "open": 182.52078247070312,
1081
+ "high": 183.9163818359375,
1082
+ "low": 181.5021209716797,
1083
+ "close": 183.0242156982422,
1084
+ "volume": 113012.6875,
1085
+ "amount": 20492764.0
1086
+ },
1087
+ {
1088
+ "timestamp": "2025-09-03T10:00:00+08:00",
1089
+ "open": 182.77818298339844,
1090
+ "high": 183.3599090576172,
1091
+ "low": 181.3691864013672,
1092
+ "close": 182.08364868164062,
1093
+ "volume": 78449.921875,
1094
+ "amount": 14072343.0
1095
+ },
1096
+ {
1097
+ "timestamp": "2025-09-03T11:00:00+08:00",
1098
+ "open": 181.9405975341797,
1099
+ "high": 182.52511596679688,
1100
+ "low": 180.5789794921875,
1101
+ "close": 181.54661560058594,
1102
+ "volume": 98601.484375,
1103
+ "amount": 17860920.0
1104
+ },
1105
+ {
1106
+ "timestamp": "2025-09-03T12:00:00+08:00",
1107
+ "open": 181.1760711669922,
1108
+ "high": 181.62213134765625,
1109
+ "low": 180.15235900878906,
1110
+ "close": 180.6356964111328,
1111
+ "volume": 52819.78125,
1112
+ "amount": 9259378.0
1113
+ },
1114
+ {
1115
+ "timestamp": "2025-09-03T13:00:00+08:00",
1116
+ "open": 180.7042694091797,
1117
+ "high": 181.27230834960938,
1118
+ "low": 179.67007446289062,
1119
+ "close": 180.5001678466797,
1120
+ "volume": 84131.140625,
1121
+ "amount": 15167241.0
1122
+ },
1123
+ {
1124
+ "timestamp": "2025-09-03T14:00:00+08:00",
1125
+ "open": 180.37013244628906,
1126
+ "high": 180.78932189941406,
1127
+ "low": 179.5408477783203,
1128
+ "close": 180.01419067382812,
1129
+ "volume": 48513.5390625,
1130
+ "amount": 8444374.0
1131
+ }
1132
+ ],
1133
+ "actual_data": [
1134
+ {
1135
+ "timestamp": "2025-08-04T15:00:00+08:00",
1136
+ "open": 162.23,
1137
+ "high": 163.3,
1138
+ "low": 162.06,
1139
+ "close": 163.03,
1140
+ "volume": 74136.921,
1141
+ "amount": 12059770.94194
1142
+ },
1143
+ {
1144
+ "timestamp": "2025-08-04T16:00:00+08:00",
1145
+ "open": 163.04,
1146
+ "high": 164.06,
1147
+ "low": 162.64,
1148
+ "close": 163.77,
1149
+ "volume": 117525.213,
1150
+ "amount": 19210826.27414
1151
+ },
1152
+ {
1153
+ "timestamp": "2025-08-04T17:00:00+08:00",
1154
+ "open": 163.77,
1155
+ "high": 164.08,
1156
+ "low": 162.43,
1157
+ "close": 162.47,
1158
+ "volume": 85060.23,
1159
+ "amount": 13892276.8872
1160
+ },
1161
+ {
1162
+ "timestamp": "2025-08-04T18:00:00+08:00",
1163
+ "open": 162.47,
1164
+ "high": 163.0,
1165
+ "low": 162.12,
1166
+ "close": 162.38,
1167
+ "volume": 100129.901,
1168
+ "amount": 16272640.11824
1169
+ },
1170
+ {
1171
+ "timestamp": "2025-08-04T19:00:00+08:00",
1172
+ "open": 162.38,
1173
+ "high": 162.58,
1174
+ "low": 161.64,
1175
+ "close": 162.38,
1176
+ "volume": 72772.577,
1177
+ "amount": 11798816.78322
1178
+ },
1179
+ {
1180
+ "timestamp": "2025-08-04T20:00:00+08:00",
1181
+ "open": 162.39,
1182
+ "high": 163.7,
1183
+ "low": 162.14,
1184
+ "close": 163.69,
1185
+ "volume": 101723.541,
1186
+ "amount": 16578100.9589
1187
+ },
1188
+ {
1189
+ "timestamp": "2025-08-04T21:00:00+08:00",
1190
+ "open": 163.7,
1191
+ "high": 165.79,
1192
+ "low": 163.21,
1193
+ "close": 165.47,
1194
+ "volume": 193752.012,
1195
+ "amount": 31851746.47853
1196
+ },
1197
+ {
1198
+ "timestamp": "2025-08-04T22:00:00+08:00",
1199
+ "open": 165.47,
1200
+ "high": 166.91,
1201
+ "low": 164.5,
1202
+ "close": 165.03,
1203
+ "volume": 275254.258,
1204
+ "amount": 45750129.99692
1205
+ },
1206
+ {
1207
+ "timestamp": "2025-08-04T23:00:00+08:00",
1208
+ "open": 165.03,
1209
+ "high": 166.01,
1210
+ "low": 164.53,
1211
+ "close": 165.49,
1212
+ "volume": 106764.854,
1213
+ "amount": 17656292.42605
1214
+ },
1215
+ {
1216
+ "timestamp": "2025-08-05T00:00:00+08:00",
1217
+ "open": 165.49,
1218
+ "high": 168.17,
1219
+ "low": 165.48,
1220
+ "close": 168.02,
1221
+ "volume": 158859.491,
1222
+ "amount": 26562796.92357
1223
+ },
1224
+ {
1225
+ "timestamp": "2025-08-05T01:00:00+08:00",
1226
+ "open": 168.02,
1227
+ "high": 169.8,
1228
+ "low": 167.63,
1229
+ "close": 167.83,
1230
+ "volume": 225977.749,
1231
+ "amount": 38135115.37123
1232
+ },
1233
+ {
1234
+ "timestamp": "2025-08-05T02:00:00+08:00",
1235
+ "open": 167.82,
1236
+ "high": 168.15,
1237
+ "low": 166.43,
1238
+ "close": 166.67,
1239
+ "volume": 62494.281,
1240
+ "amount": 10449570.22186
1241
+ },
1242
+ {
1243
+ "timestamp": "2025-08-05T03:00:00+08:00",
1244
+ "open": 166.66,
1245
+ "high": 166.66,
1246
+ "low": 165.0,
1247
+ "close": 165.65,
1248
+ "volume": 92910.808,
1249
+ "amount": 15399091.07364
1250
+ },
1251
+ {
1252
+ "timestamp": "2025-08-05T04:00:00+08:00",
1253
+ "open": 165.64,
1254
+ "high": 168.44,
1255
+ "low": 165.3,
1256
+ "close": 167.29,
1257
+ "volume": 138413.064,
1258
+ "amount": 23120298.99166
1259
+ },
1260
+ {
1261
+ "timestamp": "2025-08-05T05:00:00+08:00",
1262
+ "open": 167.28,
1263
+ "high": 168.78,
1264
+ "low": 167.27,
1265
+ "close": 168.54,
1266
+ "volume": 90532.368,
1267
+ "amount": 15213774.63313
1268
+ },
1269
+ {
1270
+ "timestamp": "2025-08-05T06:00:00+08:00",
1271
+ "open": 168.54,
1272
+ "high": 169.54,
1273
+ "low": 168.23,
1274
+ "close": 169.47,
1275
+ "volume": 99295.578,
1276
+ "amount": 16765316.64126
1277
+ },
1278
+ {
1279
+ "timestamp": "2025-08-05T07:00:00+08:00",
1280
+ "open": 169.47,
1281
+ "high": 169.78,
1282
+ "low": 168.96,
1283
+ "close": 169.55,
1284
+ "volume": 76925.323,
1285
+ "amount": 13027064.79868
1286
+ },
1287
+ {
1288
+ "timestamp": "2025-08-05T08:00:00+08:00",
1289
+ "open": 169.55,
1290
+ "high": 169.76,
1291
+ "low": 168.59,
1292
+ "close": 169.31,
1293
+ "volume": 82214.747,
1294
+ "amount": 13902743.33407
1295
+ },
1296
+ {
1297
+ "timestamp": "2025-08-05T09:00:00+08:00",
1298
+ "open": 169.31,
1299
+ "high": 169.97,
1300
+ "low": 168.15,
1301
+ "close": 168.21,
1302
+ "volume": 70824.086,
1303
+ "amount": 11973446.20439
1304
+ },
1305
+ {
1306
+ "timestamp": "2025-08-05T10:00:00+08:00",
1307
+ "open": 168.22,
1308
+ "high": 169.48,
1309
+ "low": 167.95,
1310
+ "close": 169.42,
1311
+ "volume": 60355.659,
1312
+ "amount": 10174298.68738
1313
+ },
1314
+ {
1315
+ "timestamp": "2025-08-05T11:00:00+08:00",
1316
+ "open": 169.42,
1317
+ "high": 169.44,
1318
+ "low": 167.57,
1319
+ "close": 167.92,
1320
+ "volume": 67324.879,
1321
+ "amount": 11319806.88757
1322
+ },
1323
+ {
1324
+ "timestamp": "2025-08-05T12:00:00+08:00",
1325
+ "open": 167.92,
1326
+ "high": 168.51,
1327
+ "low": 167.23,
1328
+ "close": 167.48,
1329
+ "volume": 53783.38,
1330
+ "amount": 9020520.47306
1331
+ },
1332
+ {
1333
+ "timestamp": "2025-08-05T13:00:00+08:00",
1334
+ "open": 167.48,
1335
+ "high": 168.6,
1336
+ "low": 167.42,
1337
+ "close": 168.42,
1338
+ "volume": 58015.301,
1339
+ "amount": 9746167.59901
1340
+ },
1341
+ {
1342
+ "timestamp": "2025-08-05T14:00:00+08:00",
1343
+ "open": 168.42,
1344
+ "high": 169.28,
1345
+ "low": 167.31,
1346
+ "close": 167.71,
1347
+ "volume": 64403.219,
1348
+ "amount": 10853931.01296
1349
+ },
1350
+ {
1351
+ "timestamp": "2025-08-05T15:00:00+08:00",
1352
+ "open": 167.71,
1353
+ "high": 168.52,
1354
+ "low": 165.78,
1355
+ "close": 166.22,
1356
+ "volume": 144397.434,
1357
+ "amount": 24077310.95995
1358
+ },
1359
+ {
1360
+ "timestamp": "2025-08-05T16:00:00+08:00",
1361
+ "open": 166.21,
1362
+ "high": 167.25,
1363
+ "low": 165.66,
1364
+ "close": 166.84,
1365
+ "volume": 72724.394,
1366
+ "amount": 12107991.17777
1367
+ },
1368
+ {
1369
+ "timestamp": "2025-08-05T17:00:00+08:00",
1370
+ "open": 166.83,
1371
+ "high": 169.4,
1372
+ "low": 166.77,
1373
+ "close": 168.88,
1374
+ "volume": 93974.184,
1375
+ "amount": 15800043.81255
1376
+ },
1377
+ {
1378
+ "timestamp": "2025-08-05T18:00:00+08:00",
1379
+ "open": 168.89,
1380
+ "high": 171.73,
1381
+ "low": 168.43,
1382
+ "close": 171.03,
1383
+ "volume": 146021.969,
1384
+ "amount": 24859549.09327
1385
+ },
1386
+ {
1387
+ "timestamp": "2025-08-05T19:00:00+08:00",
1388
+ "open": 171.04,
1389
+ "high": 171.65,
1390
+ "low": 170.56,
1391
+ "close": 170.89,
1392
+ "volume": 89180.665,
1393
+ "amount": 15249888.4715
1394
+ },
1395
+ {
1396
+ "timestamp": "2025-08-05T20:00:00+08:00",
1397
+ "open": 170.89,
1398
+ "high": 171.04,
1399
+ "low": 166.77,
1400
+ "close": 167.23,
1401
+ "volume": 187653.275,
1402
+ "amount": 31608650.29139
1403
+ },
1404
+ {
1405
+ "timestamp": "2025-08-05T21:00:00+08:00",
1406
+ "open": 167.23,
1407
+ "high": 168.14,
1408
+ "low": 166.63,
1409
+ "close": 167.76,
1410
+ "volume": 184125.095,
1411
+ "amount": 30820396.27592
1412
+ },
1413
+ {
1414
+ "timestamp": "2025-08-05T22:00:00+08:00",
1415
+ "open": 167.76,
1416
+ "high": 167.8,
1417
+ "low": 163.61,
1418
+ "close": 164.3,
1419
+ "volume": 343847.03,
1420
+ "amount": 56680992.41483
1421
+ },
1422
+ {
1423
+ "timestamp": "2025-08-05T23:00:00+08:00",
1424
+ "open": 164.29,
1425
+ "high": 165.33,
1426
+ "low": 162.9,
1427
+ "close": 163.78,
1428
+ "volume": 192355.206,
1429
+ "amount": 31563223.60904
1430
+ },
1431
+ {
1432
+ "timestamp": "2025-08-06T00:00:00+08:00",
1433
+ "open": 163.77,
1434
+ "high": 164.73,
1435
+ "low": 162.74,
1436
+ "close": 163.83,
1437
+ "volume": 167910.678,
1438
+ "amount": 27507045.08349
1439
+ },
1440
+ {
1441
+ "timestamp": "2025-08-06T01:00:00+08:00",
1442
+ "open": 163.83,
1443
+ "high": 164.93,
1444
+ "low": 163.36,
1445
+ "close": 164.81,
1446
+ "volume": 100989.57,
1447
+ "amount": 16570106.54807
1448
+ },
1449
+ {
1450
+ "timestamp": "2025-08-06T02:00:00+08:00",
1451
+ "open": 164.8,
1452
+ "high": 164.94,
1453
+ "low": 163.0,
1454
+ "close": 164.02,
1455
+ "volume": 99084.727,
1456
+ "amount": 16253427.6356
1457
+ },
1458
+ {
1459
+ "timestamp": "2025-08-06T03:00:00+08:00",
1460
+ "open": 164.02,
1461
+ "high": 164.53,
1462
+ "low": 162.28,
1463
+ "close": 162.76,
1464
+ "volume": 64811.187,
1465
+ "amount": 10588413.05836
1466
+ },
1467
+ {
1468
+ "timestamp": "2025-08-06T04:00:00+08:00",
1469
+ "open": 162.76,
1470
+ "high": 163.7,
1471
+ "low": 162.37,
1472
+ "close": 162.61,
1473
+ "volume": 48970.354,
1474
+ "amount": 7983830.49318
1475
+ },
1476
+ {
1477
+ "timestamp": "2025-08-06T05:00:00+08:00",
1478
+ "open": 162.62,
1479
+ "high": 163.46,
1480
+ "low": 161.6,
1481
+ "close": 162.38,
1482
+ "volume": 49155.96,
1483
+ "amount": 7994559.93456
1484
+ },
1485
+ {
1486
+ "timestamp": "2025-08-06T06:00:00+08:00",
1487
+ "open": 162.37,
1488
+ "high": 163.88,
1489
+ "low": 161.3,
1490
+ "close": 163.87,
1491
+ "volume": 64389.815,
1492
+ "amount": 10473223.66777
1493
+ },
1494
+ {
1495
+ "timestamp": "2025-08-06T07:00:00+08:00",
1496
+ "open": 163.88,
1497
+ "high": 164.54,
1498
+ "low": 163.62,
1499
+ "close": 164.09,
1500
+ "volume": 48445.195,
1501
+ "amount": 7953475.18119
1502
+ },
1503
+ {
1504
+ "timestamp": "2025-08-06T08:00:00+08:00",
1505
+ "open": 164.09,
1506
+ "high": 164.17,
1507
+ "low": 162.55,
1508
+ "close": 162.75,
1509
+ "volume": 43163.896,
1510
+ "amount": 7057842.77139
1511
+ },
1512
+ {
1513
+ "timestamp": "2025-08-06T09:00:00+08:00",
1514
+ "open": 162.74,
1515
+ "high": 163.1,
1516
+ "low": 161.72,
1517
+ "close": 162.86,
1518
+ "volume": 76846.534,
1519
+ "amount": 12480634.75106
1520
+ },
1521
+ {
1522
+ "timestamp": "2025-08-06T10:00:00+08:00",
1523
+ "open": 162.85,
1524
+ "high": 163.3,
1525
+ "low": 161.89,
1526
+ "close": 162.68,
1527
+ "volume": 29810.556,
1528
+ "amount": 4852556.5443
1529
+ },
1530
+ {
1531
+ "timestamp": "2025-08-06T11:00:00+08:00",
1532
+ "open": 162.68,
1533
+ "high": 162.78,
1534
+ "low": 161.13,
1535
+ "close": 161.86,
1536
+ "volume": 54824.373,
1537
+ "amount": 8873539.23202
1538
+ },
1539
+ {
1540
+ "timestamp": "2025-08-06T12:00:00+08:00",
1541
+ "open": 161.86,
1542
+ "high": 162.56,
1543
+ "low": 161.25,
1544
+ "close": 162.44,
1545
+ "volume": 41127.848,
1546
+ "amount": 6663819.62399
1547
+ },
1548
+ {
1549
+ "timestamp": "2025-08-06T13:00:00+08:00",
1550
+ "open": 162.43,
1551
+ "high": 164.79,
1552
+ "low": 162.13,
1553
+ "close": 164.26,
1554
+ "volume": 80618.825,
1555
+ "amount": 13207339.73608
1556
+ },
1557
+ {
1558
+ "timestamp": "2025-08-06T14:00:00+08:00",
1559
+ "open": 164.26,
1560
+ "high": 164.3,
1561
+ "low": 163.4,
1562
+ "close": 163.91,
1563
+ "volume": 39135.78,
1564
+ "amount": 6413948.17988
1565
+ },
1566
+ {
1567
+ "timestamp": "2025-08-06T15:00:00+08:00",
1568
+ "open": 163.91,
1569
+ "high": 164.63,
1570
+ "low": 163.62,
1571
+ "close": 164.25,
1572
+ "volume": 55141.803,
1573
+ "amount": 9055194.53629
1574
+ },
1575
+ {
1576
+ "timestamp": "2025-08-06T16:00:00+08:00",
1577
+ "open": 164.26,
1578
+ "high": 164.51,
1579
+ "low": 162.72,
1580
+ "close": 163.31,
1581
+ "volume": 110996.881,
1582
+ "amount": 18152710.47713
1583
+ },
1584
+ {
1585
+ "timestamp": "2025-08-06T17:00:00+08:00",
1586
+ "open": 163.3,
1587
+ "high": 164.51,
1588
+ "low": 162.93,
1589
+ "close": 163.97,
1590
+ "volume": 51789.523,
1591
+ "amount": 8484891.56098
1592
+ },
1593
+ {
1594
+ "timestamp": "2025-08-06T18:00:00+08:00",
1595
+ "open": 163.98,
1596
+ "high": 164.17,
1597
+ "low": 162.91,
1598
+ "close": 163.64,
1599
+ "volume": 45388.472,
1600
+ "amount": 7421376.01486
1601
+ },
1602
+ {
1603
+ "timestamp": "2025-08-06T19:00:00+08:00",
1604
+ "open": 163.65,
1605
+ "high": 164.64,
1606
+ "low": 163.25,
1607
+ "close": 164.2,
1608
+ "volume": 43880.215,
1609
+ "amount": 7196384.74457
1610
+ },
1611
+ {
1612
+ "timestamp": "2025-08-06T20:00:00+08:00",
1613
+ "open": 164.2,
1614
+ "high": 164.7,
1615
+ "low": 162.65,
1616
+ "close": 163.29,
1617
+ "volume": 66651.944,
1618
+ "amount": 10919521.63981
1619
+ },
1620
+ {
1621
+ "timestamp": "2025-08-06T21:00:00+08:00",
1622
+ "open": 163.3,
1623
+ "high": 164.74,
1624
+ "low": 163.11,
1625
+ "close": 164.29,
1626
+ "volume": 118473.808,
1627
+ "amount": 19442562.65022
1628
+ },
1629
+ {
1630
+ "timestamp": "2025-08-06T22:00:00+08:00",
1631
+ "open": 164.29,
1632
+ "high": 168.03,
1633
+ "low": 163.99,
1634
+ "close": 167.9,
1635
+ "volume": 229018.348,
1636
+ "amount": 38017718.63702
1637
+ },
1638
+ {
1639
+ "timestamp": "2025-08-06T23:00:00+08:00",
1640
+ "open": 167.9,
1641
+ "high": 169.42,
1642
+ "low": 167.18,
1643
+ "close": 169.04,
1644
+ "volume": 188836.518,
1645
+ "amount": 31752467.168
1646
+ },
1647
+ {
1648
+ "timestamp": "2025-08-07T00:00:00+08:00",
1649
+ "open": 169.05,
1650
+ "high": 169.5,
1651
+ "low": 167.3,
1652
+ "close": 167.74,
1653
+ "volume": 134701.749,
1654
+ "amount": 22684012.2248
1655
+ },
1656
+ {
1657
+ "timestamp": "2025-08-07T01:00:00+08:00",
1658
+ "open": 167.74,
1659
+ "high": 169.14,
1660
+ "low": 167.18,
1661
+ "close": 169.13,
1662
+ "volume": 71216.863,
1663
+ "amount": 11976517.48489
1664
+ },
1665
+ {
1666
+ "timestamp": "2025-08-07T02:00:00+08:00",
1667
+ "open": 169.13,
1668
+ "high": 169.93,
1669
+ "low": 168.39,
1670
+ "close": 168.53,
1671
+ "volume": 91193.689,
1672
+ "amount": 15425414.34944
1673
+ },
1674
+ {
1675
+ "timestamp": "2025-08-07T03:00:00+08:00",
1676
+ "open": 168.54,
1677
+ "high": 169.1,
1678
+ "low": 167.97,
1679
+ "close": 168.82,
1680
+ "volume": 63496.229,
1681
+ "amount": 10701215.20875
1682
+ },
1683
+ {
1684
+ "timestamp": "2025-08-07T04:00:00+08:00",
1685
+ "open": 168.82,
1686
+ "high": 168.85,
1687
+ "low": 167.77,
1688
+ "close": 168.01,
1689
+ "volume": 37725.966,
1690
+ "amount": 6345885.41282
1691
+ },
1692
+ {
1693
+ "timestamp": "2025-08-07T05:00:00+08:00",
1694
+ "open": 168.01,
1695
+ "high": 168.6,
1696
+ "low": 167.32,
1697
+ "close": 168.05,
1698
+ "volume": 45074.396,
1699
+ "amount": 7572011.80834
1700
+ },
1701
+ {
1702
+ "timestamp": "2025-08-07T06:00:00+08:00",
1703
+ "open": 168.06,
1704
+ "high": 168.52,
1705
+ "low": 167.84,
1706
+ "close": 168.4,
1707
+ "volume": 40030.181,
1708
+ "amount": 6734961.48444
1709
+ },
1710
+ {
1711
+ "timestamp": "2025-08-07T07:00:00+08:00",
1712
+ "open": 168.39,
1713
+ "high": 168.43,
1714
+ "low": 167.9,
1715
+ "close": 168.09,
1716
+ "volume": 38347.032,
1717
+ "amount": 6447076.81682
1718
+ },
1719
+ {
1720
+ "timestamp": "2025-08-07T08:00:00+08:00",
1721
+ "open": 168.1,
1722
+ "high": 168.43,
1723
+ "low": 167.5,
1724
+ "close": 167.89,
1725
+ "volume": 42120.103,
1726
+ "amount": 7073984.82298
1727
+ },
1728
+ {
1729
+ "timestamp": "2025-08-07T09:00:00+08:00",
1730
+ "open": 167.9,
1731
+ "high": 169.0,
1732
+ "low": 167.7,
1733
+ "close": 167.87,
1734
+ "volume": 63347.932,
1735
+ "amount": 10667891.24492
1736
+ },
1737
+ {
1738
+ "timestamp": "2025-08-07T10:00:00+08:00",
1739
+ "open": 167.88,
1740
+ "high": 168.03,
1741
+ "low": 166.77,
1742
+ "close": 167.07,
1743
+ "volume": 62002.104,
1744
+ "amount": 10381788.88788
1745
+ },
1746
+ {
1747
+ "timestamp": "2025-08-07T11:00:00+08:00",
1748
+ "open": 167.07,
1749
+ "high": 167.45,
1750
+ "low": 166.7,
1751
+ "close": 166.89,
1752
+ "volume": 32383.859,
1753
+ "amount": 5409448.35906
1754
+ },
1755
+ {
1756
+ "timestamp": "2025-08-07T12:00:00+08:00",
1757
+ "open": 166.9,
1758
+ "high": 167.59,
1759
+ "low": 166.76,
1760
+ "close": 167.14,
1761
+ "volume": 54513.73,
1762
+ "amount": 9113596.06166
1763
+ },
1764
+ {
1765
+ "timestamp": "2025-08-07T13:00:00+08:00",
1766
+ "open": 167.14,
1767
+ "high": 168.78,
1768
+ "low": 166.9,
1769
+ "close": 168.76,
1770
+ "volume": 67272.7,
1771
+ "amount": 11282713.31824
1772
+ },
1773
+ {
1774
+ "timestamp": "2025-08-07T14:00:00+08:00",
1775
+ "open": 168.75,
1776
+ "high": 169.78,
1777
+ "low": 168.59,
1778
+ "close": 169.2,
1779
+ "volume": 142910.245,
1780
+ "amount": 24187068.86434
1781
+ },
1782
+ {
1783
+ "timestamp": "2025-08-07T15:00:00+08:00",
1784
+ "open": 169.2,
1785
+ "high": 170.45,
1786
+ "low": 169.17,
1787
+ "close": 169.99,
1788
+ "volume": 101757.927,
1789
+ "amount": 17292602.95288
1790
+ },
1791
+ {
1792
+ "timestamp": "2025-08-07T16:00:00+08:00",
1793
+ "open": 169.99,
1794
+ "high": 170.54,
1795
+ "low": 169.25,
1796
+ "close": 169.38,
1797
+ "volume": 53396.157,
1798
+ "amount": 9070993.83894
1799
+ },
1800
+ {
1801
+ "timestamp": "2025-08-07T17:00:00+08:00",
1802
+ "open": 169.39,
1803
+ "high": 169.74,
1804
+ "low": 169.06,
1805
+ "close": 169.64,
1806
+ "volume": 62798.597,
1807
+ "amount": 10638595.19901
1808
+ },
1809
+ {
1810
+ "timestamp": "2025-08-07T18:00:00+08:00",
1811
+ "open": 169.64,
1812
+ "high": 173.33,
1813
+ "low": 169.41,
1814
+ "close": 173.11,
1815
+ "volume": 384304.067,
1816
+ "amount": 66077162.88463
1817
+ },
1818
+ {
1819
+ "timestamp": "2025-08-07T19:00:00+08:00",
1820
+ "open": 173.12,
1821
+ "high": 173.49,
1822
+ "low": 172.55,
1823
+ "close": 172.82,
1824
+ "volume": 186048.277,
1825
+ "amount": 32193407.74879
1826
+ },
1827
+ {
1828
+ "timestamp": "2025-08-07T20:00:00+08:00",
1829
+ "open": 172.83,
1830
+ "high": 173.18,
1831
+ "low": 171.53,
1832
+ "close": 172.44,
1833
+ "volume": 239496.463,
1834
+ "amount": 41268302.40848
1835
+ },
1836
+ {
1837
+ "timestamp": "2025-08-07T21:00:00+08:00",
1838
+ "open": 172.44,
1839
+ "high": 172.63,
1840
+ "low": 171.3,
1841
+ "close": 171.71,
1842
+ "volume": 190193.126,
1843
+ "amount": 32729635.12419
1844
+ },
1845
+ {
1846
+ "timestamp": "2025-08-07T22:00:00+08:00",
1847
+ "open": 171.71,
1848
+ "high": 171.78,
1849
+ "low": 169.93,
1850
+ "close": 170.29,
1851
+ "volume": 195035.421,
1852
+ "amount": 33279394.99653
1853
+ },
1854
+ {
1855
+ "timestamp": "2025-08-07T23:00:00+08:00",
1856
+ "open": 170.3,
1857
+ "high": 170.83,
1858
+ "low": 169.7,
1859
+ "close": 170.49,
1860
+ "volume": 103344.875,
1861
+ "amount": 17605556.63468
1862
+ },
1863
+ {
1864
+ "timestamp": "2025-08-08T00:00:00+08:00",
1865
+ "open": 170.48,
1866
+ "high": 170.6,
1867
+ "low": 167.0,
1868
+ "close": 168.21,
1869
+ "volume": 195488.878,
1870
+ "amount": 33013670.23084
1871
+ },
1872
+ {
1873
+ "timestamp": "2025-08-08T01:00:00+08:00",
1874
+ "open": 168.22,
1875
+ "high": 169.56,
1876
+ "low": 167.97,
1877
+ "close": 169.43,
1878
+ "volume": 118983.774,
1879
+ "amount": 20088079.37201
1880
+ },
1881
+ {
1882
+ "timestamp": "2025-08-08T02:00:00+08:00",
1883
+ "open": 169.43,
1884
+ "high": 169.97,
1885
+ "low": 168.77,
1886
+ "close": 169.83,
1887
+ "volume": 81531.6,
1888
+ "amount": 13805010.09553
1889
+ },
1890
+ {
1891
+ "timestamp": "2025-08-08T03:00:00+08:00",
1892
+ "open": 169.82,
1893
+ "high": 171.94,
1894
+ "low": 169.8,
1895
+ "close": 171.75,
1896
+ "volume": 90401.494,
1897
+ "amount": 15451891.70214
1898
+ },
1899
+ {
1900
+ "timestamp": "2025-08-08T04:00:00+08:00",
1901
+ "open": 171.76,
1902
+ "high": 173.18,
1903
+ "low": 171.52,
1904
+ "close": 172.93,
1905
+ "volume": 165662.361,
1906
+ "amount": 28588575.41687
1907
+ },
1908
+ {
1909
+ "timestamp": "2025-08-08T05:00:00+08:00",
1910
+ "open": 172.94,
1911
+ "high": 174.29,
1912
+ "low": 172.52,
1913
+ "close": 173.56,
1914
+ "volume": 134633.652,
1915
+ "amount": 23367840.25631
1916
+ },
1917
+ {
1918
+ "timestamp": "2025-08-08T06:00:00+08:00",
1919
+ "open": 173.56,
1920
+ "high": 175.16,
1921
+ "low": 173.56,
1922
+ "close": 175.09,
1923
+ "volume": 156328.311,
1924
+ "amount": 27254689.66104
1925
+ },
1926
+ {
1927
+ "timestamp": "2025-08-08T07:00:00+08:00",
1928
+ "open": 175.1,
1929
+ "high": 175.51,
1930
+ "low": 174.39,
1931
+ "close": 175.36,
1932
+ "volume": 90707.342,
1933
+ "amount": 15871027.6557
1934
+ },
1935
+ {
1936
+ "timestamp": "2025-08-08T08:00:00+08:00",
1937
+ "open": 175.37,
1938
+ "high": 175.55,
1939
+ "low": 173.56,
1940
+ "close": 174.28,
1941
+ "volume": 285971.901,
1942
+ "amount": 49905519.86187
1943
+ },
1944
+ {
1945
+ "timestamp": "2025-08-08T09:00:00+08:00",
1946
+ "open": 174.28,
1947
+ "high": 174.84,
1948
+ "low": 173.43,
1949
+ "close": 174.54,
1950
+ "volume": 229160.382,
1951
+ "amount": 39899798.41686
1952
+ },
1953
+ {
1954
+ "timestamp": "2025-08-08T10:00:00+08:00",
1955
+ "open": 174.53,
1956
+ "high": 175.28,
1957
+ "low": 173.85,
1958
+ "close": 174.84,
1959
+ "volume": 111560.099,
1960
+ "amount": 19472752.49667
1961
+ },
1962
+ {
1963
+ "timestamp": "2025-08-08T11:00:00+08:00",
1964
+ "open": 174.84,
1965
+ "high": 175.92,
1966
+ "low": 174.49,
1967
+ "close": 174.71,
1968
+ "volume": 107748.238,
1969
+ "amount": 18887951.95409
1970
+ },
1971
+ {
1972
+ "timestamp": "2025-08-08T12:00:00+08:00",
1973
+ "open": 174.71,
1974
+ "high": 175.2,
1975
+ "low": 173.89,
1976
+ "close": 174.38,
1977
+ "volume": 98808.746,
1978
+ "amount": 17249425.80614
1979
+ },
1980
+ {
1981
+ "timestamp": "2025-08-08T13:00:00+08:00",
1982
+ "open": 174.39,
1983
+ "high": 174.8,
1984
+ "low": 174.07,
1985
+ "close": 174.21,
1986
+ "volume": 71768.975,
1987
+ "amount": 12520281.86918
1988
+ },
1989
+ {
1990
+ "timestamp": "2025-08-08T14:00:00+08:00",
1991
+ "open": 174.2,
1992
+ "high": 175.12,
1993
+ "low": 173.88,
1994
+ "close": 175.07,
1995
+ "volume": 47720.465,
1996
+ "amount": 8326921.08184
1997
+ },
1998
+ {
1999
+ "timestamp": "2025-08-08T15:00:00+08:00",
2000
+ "open": 175.08,
2001
+ "high": 177.87,
2002
+ "low": 174.33,
2003
+ "close": 177.14,
2004
+ "volume": 229541.676,
2005
+ "amount": 40528429.97951
2006
+ },
2007
+ {
2008
+ "timestamp": "2025-08-08T16:00:00+08:00",
2009
+ "open": 177.13,
2010
+ "high": 177.86,
2011
+ "low": 174.88,
2012
+ "close": 175.37,
2013
+ "volume": 221907.145,
2014
+ "amount": 39115276.85478
2015
+ },
2016
+ {
2017
+ "timestamp": "2025-08-08T17:00:00+08:00",
2018
+ "open": 175.38,
2019
+ "high": 176.13,
2020
+ "low": 175.01,
2021
+ "close": 176.06,
2022
+ "volume": 73177.332,
2023
+ "amount": 12844547.6769
2024
+ },
2025
+ {
2026
+ "timestamp": "2025-08-08T18:00:00+08:00",
2027
+ "open": 176.06,
2028
+ "high": 177.0,
2029
+ "low": 175.73,
2030
+ "close": 176.65,
2031
+ "volume": 97484.632,
2032
+ "amount": 17194816.92097
2033
+ },
2034
+ {
2035
+ "timestamp": "2025-08-08T19:00:00+08:00",
2036
+ "open": 176.65,
2037
+ "high": 177.95,
2038
+ "low": 176.57,
2039
+ "close": 177.65,
2040
+ "volume": 123436.572,
2041
+ "amount": 21896869.12395
2042
+ },
2043
+ {
2044
+ "timestamp": "2025-08-08T20:00:00+08:00",
2045
+ "open": 177.65,
2046
+ "high": 177.67,
2047
+ "low": 176.11,
2048
+ "close": 176.45,
2049
+ "volume": 136248.014,
2050
+ "amount": 24089803.31777
2051
+ },
2052
+ {
2053
+ "timestamp": "2025-08-08T21:00:00+08:00",
2054
+ "open": 176.45,
2055
+ "high": 178.8,
2056
+ "low": 175.47,
2057
+ "close": 178.63,
2058
+ "volume": 251938.117,
2059
+ "amount": 44630741.1163
2060
+ },
2061
+ {
2062
+ "timestamp": "2025-08-08T22:00:00+08:00",
2063
+ "open": 178.64,
2064
+ "high": 179.14,
2065
+ "low": 175.43,
2066
+ "close": 176.51,
2067
+ "volume": 323953.21,
2068
+ "amount": 57372288.63739
2069
+ },
2070
+ {
2071
+ "timestamp": "2025-08-08T23:00:00+08:00",
2072
+ "open": 176.51,
2073
+ "high": 176.7,
2074
+ "low": 174.21,
2075
+ "close": 175.23,
2076
+ "volume": 213655.986,
2077
+ "amount": 37441428.9877
2078
+ },
2079
+ {
2080
+ "timestamp": "2025-08-09T00:00:00+08:00",
2081
+ "open": 175.23,
2082
+ "high": 176.33,
2083
+ "low": 175.01,
2084
+ "close": 175.9,
2085
+ "volume": 163119.182,
2086
+ "amount": 28646747.51801
2087
+ },
2088
+ {
2089
+ "timestamp": "2025-08-09T01:00:00+08:00",
2090
+ "open": 175.89,
2091
+ "high": 179.36,
2092
+ "low": 175.55,
2093
+ "close": 179.34,
2094
+ "volume": 205835.192,
2095
+ "amount": 36560503.20317
2096
+ },
2097
+ {
2098
+ "timestamp": "2025-08-09T02:00:00+08:00",
2099
+ "open": 179.35,
2100
+ "high": 179.66,
2101
+ "low": 177.21,
2102
+ "close": 177.6,
2103
+ "volume": 275884.101,
2104
+ "amount": 49304914.38911
2105
+ },
2106
+ {
2107
+ "timestamp": "2025-08-09T03:00:00+08:00",
2108
+ "open": 177.59,
2109
+ "high": 178.47,
2110
+ "low": 177.4,
2111
+ "close": 178.47,
2112
+ "volume": 166152.661,
2113
+ "amount": 29570335.49701
2114
+ },
2115
+ {
2116
+ "timestamp": "2025-08-09T04:00:00+08:00",
2117
+ "open": 178.46,
2118
+ "high": 178.76,
2119
+ "low": 177.24,
2120
+ "close": 178.25,
2121
+ "volume": 70076.448,
2122
+ "amount": 12463914.31461
2123
+ },
2124
+ {
2125
+ "timestamp": "2025-08-09T05:00:00+08:00",
2126
+ "open": 178.24,
2127
+ "high": 178.6,
2128
+ "low": 177.41,
2129
+ "close": 177.61,
2130
+ "volume": 53024.121,
2131
+ "amount": 9434502.51846
2132
+ },
2133
+ {
2134
+ "timestamp": "2025-08-09T06:00:00+08:00",
2135
+ "open": 177.61,
2136
+ "high": 178.07,
2137
+ "low": 177.07,
2138
+ "close": 177.63,
2139
+ "volume": 77857.406,
2140
+ "amount": 13832572.48314
2141
+ },
2142
+ {
2143
+ "timestamp": "2025-08-09T07:00:00+08:00",
2144
+ "open": 177.63,
2145
+ "high": 177.91,
2146
+ "low": 176.62,
2147
+ "close": 176.78,
2148
+ "volume": 42760.054,
2149
+ "amount": 7574519.60434
2150
+ },
2151
+ {
2152
+ "timestamp": "2025-08-09T08:00:00+08:00",
2153
+ "open": 176.79,
2154
+ "high": 177.22,
2155
+ "low": 176.64,
2156
+ "close": 176.94,
2157
+ "volume": 65341.697,
2158
+ "amount": 11561450.4816
2159
+ },
2160
+ {
2161
+ "timestamp": "2025-08-09T09:00:00+08:00",
2162
+ "open": 176.94,
2163
+ "high": 179.02,
2164
+ "low": 176.67,
2165
+ "close": 178.67,
2166
+ "volume": 98455.121,
2167
+ "amount": 17508615.06199
2168
+ },
2169
+ {
2170
+ "timestamp": "2025-08-09T10:00:00+08:00",
2171
+ "open": 178.68,
2172
+ "high": 178.71,
2173
+ "low": 177.56,
2174
+ "close": 177.58,
2175
+ "volume": 83765.293,
2176
+ "amount": 14920736.18133
2177
+ },
2178
+ {
2179
+ "timestamp": "2025-08-09T11:00:00+08:00",
2180
+ "open": 177.58,
2181
+ "high": 177.75,
2182
+ "low": 177.03,
2183
+ "close": 177.26,
2184
+ "volume": 64366.253,
2185
+ "amount": 11413770.00552
2186
+ },
2187
+ {
2188
+ "timestamp": "2025-08-09T12:00:00+08:00",
2189
+ "open": 177.26,
2190
+ "high": 178.82,
2191
+ "low": 176.94,
2192
+ "close": 178.67,
2193
+ "volume": 127054.29,
2194
+ "amount": 22593505.13424
2195
+ },
2196
+ {
2197
+ "timestamp": "2025-08-09T13:00:00+08:00",
2198
+ "open": 178.66,
2199
+ "high": 182.15,
2200
+ "low": 178.26,
2201
+ "close": 180.85,
2202
+ "volume": 439624.908,
2203
+ "amount": 79481177.72109
2204
+ },
2205
+ {
2206
+ "timestamp": "2025-08-09T14:00:00+08:00",
2207
+ "open": 180.85,
2208
+ "high": 180.93,
2209
+ "low": 179.26,
2210
+ "close": 179.59,
2211
+ "volume": 208875.43,
2212
+ "amount": 37596188.47394
2213
+ }
2214
+ ],
2215
+ "analysis": {
2216
+ "continuity": {
2217
+ "last_prediction": {
2218
+ "open": 161.17906188964844,
2219
+ "high": 161.45286560058594,
2220
+ "low": 160.79344177246094,
2221
+ "close": 160.83462524414062
2222
+ },
2223
+ "first_actual": {
2224
+ "open": 162.23,
2225
+ "high": 163.3,
2226
+ "low": 162.06,
2227
+ "close": 163.03
2228
+ },
2229
+ "gaps": {
2230
+ "open_gap": 1.0509381103515523,
2231
+ "high_gap": 1.8471343994140739,
2232
+ "low_gap": 1.2665582275390648,
2233
+ "close_gap": 2.195374755859376
2234
+ },
2235
+ "gap_percentages": {
2236
+ "open_gap_pct": 0.6478075019118241,
2237
+ "high_gap_pct": 1.1311294546320108,
2238
+ "low_gap_pct": 0.7815366083790354,
2239
+ "close_gap_pct": 1.3466078365082355
2240
+ }
2241
+ }
2242
+ }
2243
+ }
webui/prediction_results/prediction_20250829_144330.json ADDED
@@ -0,0 +1,1135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "timestamp": "2025-08-29T14:43:30.188199",
3
+ "file_path": "SOLUSDT_15m",
4
+ "prediction_type": "Kronos model prediction (latest data)",
5
+ "prediction_params": {
6
+ "symbol": "SOLUSDT",
7
+ "interval": "15m",
8
+ "limit": 1000,
9
+ "lookback": 1000,
10
+ "pred_len": 120,
11
+ "temperature": 1.0,
12
+ "top_p": 0.9,
13
+ "sample_count": 1,
14
+ "start_date": "latest"
15
+ },
16
+ "input_data_summary": {
17
+ "rows": 1000,
18
+ "columns": [
19
+ "open",
20
+ "high",
21
+ "low",
22
+ "close",
23
+ "volume",
24
+ "amount"
25
+ ],
26
+ "price_range": {
27
+ "open": {
28
+ "min": 176.01,
29
+ "max": 217.72
30
+ },
31
+ "high": {
32
+ "min": 176.72,
33
+ "max": 218.0
34
+ },
35
+ "low": {
36
+ "min": 175.69,
37
+ "max": 217.13
38
+ },
39
+ "close": {
40
+ "min": 176.01,
41
+ "max": 217.72
42
+ }
43
+ },
44
+ "last_values": {
45
+ "open": 213.07,
46
+ "high": 214.52,
47
+ "low": 212.7,
48
+ "close": 214.23
49
+ }
50
+ },
51
+ "prediction_results": [
52
+ {
53
+ "timestamp": "2025-08-29T14:45:00+08:00",
54
+ "open": 211.51339721679688,
55
+ "high": 214.00616455078125,
56
+ "low": 209.9340362548828,
57
+ "close": 213.39547729492188,
58
+ "volume": 86834.421875,
59
+ "amount": 18310972.0
60
+ },
61
+ {
62
+ "timestamp": "2025-08-29T15:00:00+08:00",
63
+ "open": 212.58941650390625,
64
+ "high": 213.1258087158203,
65
+ "low": 211.07875061035156,
66
+ "close": 212.0814666748047,
67
+ "volume": 130910.078125,
68
+ "amount": 27360328.0
69
+ },
70
+ {
71
+ "timestamp": "2025-08-29T15:15:00+08:00",
72
+ "open": 212.44505310058594,
73
+ "high": 213.10435485839844,
74
+ "low": 211.4364013671875,
75
+ "close": 212.0792236328125,
76
+ "volume": 126443.1640625,
77
+ "amount": 26386130.0
78
+ },
79
+ {
80
+ "timestamp": "2025-08-29T15:30:00+08:00",
81
+ "open": 211.63641357421875,
82
+ "high": 211.96054077148438,
83
+ "low": 210.07322692871094,
84
+ "close": 210.6654510498047,
85
+ "volume": 108974.0,
86
+ "amount": 22760646.0
87
+ },
88
+ {
89
+ "timestamp": "2025-08-29T15:45:00+08:00",
90
+ "open": 212.30247497558594,
91
+ "high": 214.23239135742188,
92
+ "low": 210.99102783203125,
93
+ "close": 212.90011596679688,
94
+ "volume": 140603.53125,
95
+ "amount": 29848152.0
96
+ },
97
+ {
98
+ "timestamp": "2025-08-29T16:00:00+08:00",
99
+ "open": 212.1909637451172,
100
+ "high": 212.7652130126953,
101
+ "low": 211.329345703125,
102
+ "close": 212.16781616210938,
103
+ "volume": 73370.21875,
104
+ "amount": 15517934.0
105
+ },
106
+ {
107
+ "timestamp": "2025-08-29T16:15:00+08:00",
108
+ "open": 211.7748260498047,
109
+ "high": 212.1476593017578,
110
+ "low": 210.31756591796875,
111
+ "close": 210.9963836669922,
112
+ "volume": 52782.3359375,
113
+ "amount": 11086273.0
114
+ },
115
+ {
116
+ "timestamp": "2025-08-29T16:30:00+08:00",
117
+ "open": 210.53074645996094,
118
+ "high": 211.03573608398438,
119
+ "low": 209.6986083984375,
120
+ "close": 210.32786560058594,
121
+ "volume": 41089.17578125,
122
+ "amount": 8539190.0
123
+ },
124
+ {
125
+ "timestamp": "2025-08-29T16:45:00+08:00",
126
+ "open": 210.44935607910156,
127
+ "high": 212.29441833496094,
128
+ "low": 210.07159423828125,
129
+ "close": 211.98670959472656,
130
+ "volume": 68096.4765625,
131
+ "amount": 14205086.0
132
+ },
133
+ {
134
+ "timestamp": "2025-08-29T17:00:00+08:00",
135
+ "open": 210.83738708496094,
136
+ "high": 212.97824096679688,
137
+ "low": 209.92237854003906,
138
+ "close": 212.56190490722656,
139
+ "volume": 82293.9375,
140
+ "amount": 17353550.0
141
+ },
142
+ {
143
+ "timestamp": "2025-08-29T17:15:00+08:00",
144
+ "open": 211.63482666015625,
145
+ "high": 211.90684509277344,
146
+ "low": 210.16702270507812,
147
+ "close": 210.8386688232422,
148
+ "volume": 70014.984375,
149
+ "amount": 14754854.0
150
+ },
151
+ {
152
+ "timestamp": "2025-08-29T17:30:00+08:00",
153
+ "open": 210.51437377929688,
154
+ "high": 211.04525756835938,
155
+ "low": 209.57029724121094,
156
+ "close": 210.1754608154297,
157
+ "volume": 42686.02734375,
158
+ "amount": 8864302.0
159
+ },
160
+ {
161
+ "timestamp": "2025-08-29T17:45:00+08:00",
162
+ "open": 210.36618041992188,
163
+ "high": 210.45816040039062,
164
+ "low": 207.9525146484375,
165
+ "close": 208.2962646484375,
166
+ "volume": 92520.171875,
167
+ "amount": 19173682.0
168
+ },
169
+ {
170
+ "timestamp": "2025-08-29T18:00:00+08:00",
171
+ "open": 210.05482482910156,
172
+ "high": 211.09640502929688,
173
+ "low": 208.7134246826172,
174
+ "close": 210.0265655517578,
175
+ "volume": 110214.2265625,
176
+ "amount": 22950180.0
177
+ },
178
+ {
179
+ "timestamp": "2025-08-29T18:15:00+08:00",
180
+ "open": 210.1600341796875,
181
+ "high": 211.27049255371094,
182
+ "low": 209.66726684570312,
183
+ "close": 210.81997680664062,
184
+ "volume": 72831.359375,
185
+ "amount": 15233739.0
186
+ },
187
+ {
188
+ "timestamp": "2025-08-29T18:30:00+08:00",
189
+ "open": 210.5278778076172,
190
+ "high": 210.79995727539062,
191
+ "low": 209.1676025390625,
192
+ "close": 209.78085327148438,
193
+ "volume": 43755.91015625,
194
+ "amount": 9176511.0
195
+ },
196
+ {
197
+ "timestamp": "2025-08-29T18:45:00+08:00",
198
+ "open": 210.052734375,
199
+ "high": 210.8660888671875,
200
+ "low": 209.5419921875,
201
+ "close": 210.33163452148438,
202
+ "volume": 29026.037109375,
203
+ "amount": 5859170.0
204
+ },
205
+ {
206
+ "timestamp": "2025-08-29T19:00:00+08:00",
207
+ "open": 210.54861450195312,
208
+ "high": 211.3253631591797,
209
+ "low": 209.9462127685547,
210
+ "close": 210.8623504638672,
211
+ "volume": 44435.34375,
212
+ "amount": 9155286.0
213
+ },
214
+ {
215
+ "timestamp": "2025-08-29T19:15:00+08:00",
216
+ "open": 211.11680603027344,
217
+ "high": 211.7168426513672,
218
+ "low": 210.35516357421875,
219
+ "close": 211.09742736816406,
220
+ "volume": 35745.59375,
221
+ "amount": 7474263.5
222
+ },
223
+ {
224
+ "timestamp": "2025-08-29T19:30:00+08:00",
225
+ "open": 209.4849853515625,
226
+ "high": 211.83053588867188,
227
+ "low": 208.27938842773438,
228
+ "close": 211.5763702392578,
229
+ "volume": 80538.65625,
230
+ "amount": 16946778.0
231
+ },
232
+ {
233
+ "timestamp": "2025-08-29T19:45:00+08:00",
234
+ "open": 210.48641967773438,
235
+ "high": 210.95533752441406,
236
+ "low": 209.174560546875,
237
+ "close": 209.92507934570312,
238
+ "volume": 53238.65234375,
239
+ "amount": 11103928.0
240
+ },
241
+ {
242
+ "timestamp": "2025-08-29T20:00:00+08:00",
243
+ "open": 209.8693084716797,
244
+ "high": 210.39688110351562,
245
+ "low": 208.95127868652344,
246
+ "close": 209.66575622558594,
247
+ "volume": 49658.05078125,
248
+ "amount": 10256466.0
249
+ },
250
+ {
251
+ "timestamp": "2025-08-29T20:15:00+08:00",
252
+ "open": 209.44285583496094,
253
+ "high": 210.0704345703125,
254
+ "low": 208.9563446044922,
255
+ "close": 209.46649169921875,
256
+ "volume": 20944.90234375,
257
+ "amount": 4152075.5
258
+ },
259
+ {
260
+ "timestamp": "2025-08-29T20:30:00+08:00",
261
+ "open": 209.97705078125,
262
+ "high": 210.73448181152344,
263
+ "low": 209.5391082763672,
264
+ "close": 210.39401245117188,
265
+ "volume": 33596.3984375,
266
+ "amount": 6804480.5
267
+ },
268
+ {
269
+ "timestamp": "2025-08-29T20:45:00+08:00",
270
+ "open": 210.44635009765625,
271
+ "high": 211.0862274169922,
272
+ "low": 209.93402099609375,
273
+ "close": 210.67153930664062,
274
+ "volume": 35226.9765625,
275
+ "amount": 7165888.0
276
+ },
277
+ {
278
+ "timestamp": "2025-08-29T21:00:00+08:00",
279
+ "open": 210.67523193359375,
280
+ "high": 211.26776123046875,
281
+ "low": 210.13519287109375,
282
+ "close": 210.83396911621094,
283
+ "volume": 35266.84375,
284
+ "amount": 7175695.5
285
+ },
286
+ {
287
+ "timestamp": "2025-08-29T21:15:00+08:00",
288
+ "open": 210.49832153320312,
289
+ "high": 210.7288818359375,
290
+ "low": 209.61260986328125,
291
+ "close": 210.11769104003906,
292
+ "volume": 55429.57421875,
293
+ "amount": 11461123.0
294
+ },
295
+ {
296
+ "timestamp": "2025-08-29T21:30:00+08:00",
297
+ "open": 210.3923797607422,
298
+ "high": 211.1156768798828,
299
+ "low": 209.90573120117188,
300
+ "close": 210.68084716796875,
301
+ "volume": 38174.9453125,
302
+ "amount": 7821370.0
303
+ },
304
+ {
305
+ "timestamp": "2025-08-29T21:45:00+08:00",
306
+ "open": 210.8993682861328,
307
+ "high": 212.03997802734375,
308
+ "low": 210.72451782226562,
309
+ "close": 211.70399475097656,
310
+ "volume": 38179.03125,
311
+ "amount": 7661766.5
312
+ },
313
+ {
314
+ "timestamp": "2025-08-29T22:00:00+08:00",
315
+ "open": 211.4993438720703,
316
+ "high": 211.9414520263672,
317
+ "low": 210.78012084960938,
318
+ "close": 211.36322021484375,
319
+ "volume": 34923.05859375,
320
+ "amount": 7115356.0
321
+ },
322
+ {
323
+ "timestamp": "2025-08-29T22:15:00+08:00",
324
+ "open": 211.34388732910156,
325
+ "high": 211.81924438476562,
326
+ "low": 210.72543334960938,
327
+ "close": 211.34307861328125,
328
+ "volume": 34331.078125,
329
+ "amount": 6967878.5
330
+ },
331
+ {
332
+ "timestamp": "2025-08-29T22:30:00+08:00",
333
+ "open": 211.2760772705078,
334
+ "high": 211.70272827148438,
335
+ "low": 210.6693572998047,
336
+ "close": 211.16433715820312,
337
+ "volume": 25462.25390625,
338
+ "amount": 5064244.0
339
+ },
340
+ {
341
+ "timestamp": "2025-08-29T22:45:00+08:00",
342
+ "open": 211.3609619140625,
343
+ "high": 211.8013153076172,
344
+ "low": 210.67880249023438,
345
+ "close": 211.30140686035156,
346
+ "volume": 30539.8046875,
347
+ "amount": 6341840.0
348
+ },
349
+ {
350
+ "timestamp": "2025-08-29T23:00:00+08:00",
351
+ "open": 211.2964324951172,
352
+ "high": 211.74449157714844,
353
+ "low": 210.7322540283203,
354
+ "close": 211.23956298828125,
355
+ "volume": 24322.55078125,
356
+ "amount": 4848314.0
357
+ },
358
+ {
359
+ "timestamp": "2025-08-29T23:15:00+08:00",
360
+ "open": 211.30015563964844,
361
+ "high": 211.79763793945312,
362
+ "low": 210.7742156982422,
363
+ "close": 211.39276123046875,
364
+ "volume": 32017.6796875,
365
+ "amount": 6489058.0
366
+ },
367
+ {
368
+ "timestamp": "2025-08-29T23:30:00+08:00",
369
+ "open": 211.47940063476562,
370
+ "high": 211.96221923828125,
371
+ "low": 210.8484649658203,
372
+ "close": 211.52926635742188,
373
+ "volume": 41659.9921875,
374
+ "amount": 8555861.0
375
+ },
376
+ {
377
+ "timestamp": "2025-08-29T23:45:00+08:00",
378
+ "open": 211.63604736328125,
379
+ "high": 212.12120056152344,
380
+ "low": 210.98277282714844,
381
+ "close": 211.65774536132812,
382
+ "volume": 43134.015625,
383
+ "amount": 8890192.0
384
+ },
385
+ {
386
+ "timestamp": "2025-08-30T00:00:00+08:00",
387
+ "open": 210.55528259277344,
388
+ "high": 212.9385986328125,
389
+ "low": 209.76622009277344,
390
+ "close": 212.5945281982422,
391
+ "volume": 78540.40625,
392
+ "amount": 16541705.0
393
+ },
394
+ {
395
+ "timestamp": "2025-08-30T00:15:00+08:00",
396
+ "open": 212.27511596679688,
397
+ "high": 212.74612426757812,
398
+ "low": 211.2952117919922,
399
+ "close": 211.95860290527344,
400
+ "volume": 36397.0234375,
401
+ "amount": 7663594.0
402
+ },
403
+ {
404
+ "timestamp": "2025-08-30T00:30:00+08:00",
405
+ "open": 211.87197875976562,
406
+ "high": 212.40676879882812,
407
+ "low": 211.25355529785156,
408
+ "close": 211.89537048339844,
409
+ "volume": 33833.78125,
410
+ "amount": 6902406.5
411
+ },
412
+ {
413
+ "timestamp": "2025-08-30T00:45:00+08:00",
414
+ "open": 211.7979736328125,
415
+ "high": 212.30690002441406,
416
+ "low": 211.20896911621094,
417
+ "close": 211.82948303222656,
418
+ "volume": 33770.0234375,
419
+ "amount": 6861364.5
420
+ },
421
+ {
422
+ "timestamp": "2025-08-30T01:00:00+08:00",
423
+ "open": 210.84812927246094,
424
+ "high": 212.1645050048828,
425
+ "low": 209.8130340576172,
426
+ "close": 211.9027557373047,
427
+ "volume": 66634.1328125,
428
+ "amount": 13859492.0
429
+ },
430
+ {
431
+ "timestamp": "2025-08-30T01:15:00+08:00",
432
+ "open": 210.95025634765625,
433
+ "high": 211.3640899658203,
434
+ "low": 209.91064453125,
435
+ "close": 210.35145568847656,
436
+ "volume": 40140.0703125,
437
+ "amount": 8325933.0
438
+ },
439
+ {
440
+ "timestamp": "2025-08-30T01:30:00+08:00",
441
+ "open": 210.76486206054688,
442
+ "high": 211.3911590576172,
443
+ "low": 210.25592041015625,
444
+ "close": 210.86212158203125,
445
+ "volume": 26227.634765625,
446
+ "amount": 5215925.5
447
+ },
448
+ {
449
+ "timestamp": "2025-08-30T01:45:00+08:00",
450
+ "open": 210.96017456054688,
451
+ "high": 211.4601287841797,
452
+ "low": 210.43228149414062,
453
+ "close": 210.94363403320312,
454
+ "volume": 24321.9921875,
455
+ "amount": 4820165.0
456
+ },
457
+ {
458
+ "timestamp": "2025-08-30T02:00:00+08:00",
459
+ "open": 211.06475830078125,
460
+ "high": 211.60125732421875,
461
+ "low": 210.5694122314453,
462
+ "close": 211.2263946533203,
463
+ "volume": 32565.541015625,
464
+ "amount": 6602710.0
465
+ },
466
+ {
467
+ "timestamp": "2025-08-30T02:15:00+08:00",
468
+ "open": 211.19464111328125,
469
+ "high": 211.62118530273438,
470
+ "low": 210.66087341308594,
471
+ "close": 211.14324951171875,
472
+ "volume": 24745.34765625,
473
+ "amount": 4926806.5
474
+ },
475
+ {
476
+ "timestamp": "2025-08-30T02:30:00+08:00",
477
+ "open": 210.58091735839844,
478
+ "high": 210.76492309570312,
479
+ "low": 209.6467742919922,
480
+ "close": 210.01905822753906,
481
+ "volume": 34922.8828125,
482
+ "amount": 7261115.5
483
+ },
484
+ {
485
+ "timestamp": "2025-08-30T02:45:00+08:00",
486
+ "open": 210.32757568359375,
487
+ "high": 211.07138061523438,
488
+ "low": 209.89422607421875,
489
+ "close": 210.7227325439453,
490
+ "volume": 34217.8203125,
491
+ "amount": 6954625.0
492
+ },
493
+ {
494
+ "timestamp": "2025-08-30T03:00:00+08:00",
495
+ "open": 210.42422485351562,
496
+ "high": 210.68772888183594,
497
+ "low": 209.50099182128906,
498
+ "close": 209.9556121826172,
499
+ "volume": 44837.74609375,
500
+ "amount": 9235406.0
501
+ },
502
+ {
503
+ "timestamp": "2025-08-30T03:15:00+08:00",
504
+ "open": 209.80821228027344,
505
+ "high": 210.2867889404297,
506
+ "low": 209.33633422851562,
507
+ "close": 209.73934936523438,
508
+ "volume": 18545.98046875,
509
+ "amount": 3663702.0
510
+ },
511
+ {
512
+ "timestamp": "2025-08-30T03:30:00+08:00",
513
+ "open": 210.1922149658203,
514
+ "high": 210.8268280029297,
515
+ "low": 209.78961181640625,
516
+ "close": 210.5609893798828,
517
+ "volume": 31621.603515625,
518
+ "amount": 6376182.0
519
+ },
520
+ {
521
+ "timestamp": "2025-08-30T03:45:00+08:00",
522
+ "open": 210.94371032714844,
523
+ "high": 211.93673706054688,
524
+ "low": 210.4797821044922,
525
+ "close": 211.73333740234375,
526
+ "volume": 50752.0703125,
527
+ "amount": 10396533.0
528
+ },
529
+ {
530
+ "timestamp": "2025-08-30T04:00:00+08:00",
531
+ "open": 211.6557159423828,
532
+ "high": 212.0537872314453,
533
+ "low": 210.9847412109375,
534
+ "close": 211.52381896972656,
535
+ "volume": 35644.7421875,
536
+ "amount": 7314861.0
537
+ },
538
+ {
539
+ "timestamp": "2025-08-30T04:15:00+08:00",
540
+ "open": 211.4846649169922,
541
+ "high": 211.84259033203125,
542
+ "low": 210.87466430664062,
543
+ "close": 211.3356475830078,
544
+ "volume": 25026.9140625,
545
+ "amount": 4980066.5
546
+ },
547
+ {
548
+ "timestamp": "2025-08-30T04:30:00+08:00",
549
+ "open": 211.29684448242188,
550
+ "high": 211.747314453125,
551
+ "low": 210.76278686523438,
552
+ "close": 211.36915588378906,
553
+ "volume": 32053.091796875,
554
+ "amount": 6492776.5
555
+ },
556
+ {
557
+ "timestamp": "2025-08-30T04:45:00+08:00",
558
+ "open": 211.348876953125,
559
+ "high": 211.7285614013672,
560
+ "low": 210.78187561035156,
561
+ "close": 211.2506561279297,
562
+ "volume": 24300.98828125,
563
+ "amount": 4828423.5
564
+ },
565
+ {
566
+ "timestamp": "2025-08-30T05:00:00+08:00",
567
+ "open": 211.336181640625,
568
+ "high": 211.69810485839844,
569
+ "low": 210.79225158691406,
570
+ "close": 211.24884033203125,
571
+ "volume": 22949.3828125,
572
+ "amount": 4546290.5
573
+ },
574
+ {
575
+ "timestamp": "2025-08-30T05:15:00+08:00",
576
+ "open": 211.3269500732422,
577
+ "high": 211.691650390625,
578
+ "low": 210.7984619140625,
579
+ "close": 211.25265502929688,
580
+ "volume": 22618.08984375,
581
+ "amount": 4475127.0
582
+ },
583
+ {
584
+ "timestamp": "2025-08-30T05:30:00+08:00",
585
+ "open": 211.289306640625,
586
+ "high": 211.66055297851562,
587
+ "low": 210.77154541015625,
588
+ "close": 211.22607421875,
589
+ "volume": 22380.26953125,
590
+ "amount": 4421126.5
591
+ },
592
+ {
593
+ "timestamp": "2025-08-30T05:45:00+08:00",
594
+ "open": 211.2808380126953,
595
+ "high": 211.74436950683594,
596
+ "low": 210.79595947265625,
597
+ "close": 211.40455627441406,
598
+ "volume": 31100.044921875,
599
+ "amount": 6286864.0
600
+ },
601
+ {
602
+ "timestamp": "2025-08-30T06:00:00+08:00",
603
+ "open": 210.76229858398438,
604
+ "high": 211.18490600585938,
605
+ "low": 210.05076599121094,
606
+ "close": 210.6517791748047,
607
+ "volume": 43474.8203125,
608
+ "amount": 8886004.0
609
+ },
610
+ {
611
+ "timestamp": "2025-08-30T06:15:00+08:00",
612
+ "open": 209.90682983398438,
613
+ "high": 210.40191650390625,
614
+ "low": 207.84718322753906,
615
+ "close": 209.27548217773438,
616
+ "volume": 61941.90625,
617
+ "amount": 12910675.0
618
+ },
619
+ {
620
+ "timestamp": "2025-08-30T06:30:00+08:00",
621
+ "open": 206.94691467285156,
622
+ "high": 207.7908172607422,
623
+ "low": 203.89559936523438,
624
+ "close": 204.99234008789062,
625
+ "volume": 81169.890625,
626
+ "amount": 17041364.0
627
+ },
628
+ {
629
+ "timestamp": "2025-08-30T06:45:00+08:00",
630
+ "open": 205.01893615722656,
631
+ "high": 206.74095153808594,
632
+ "low": 204.5406494140625,
633
+ "close": 206.2381591796875,
634
+ "volume": 69149.890625,
635
+ "amount": 14121952.0
636
+ },
637
+ {
638
+ "timestamp": "2025-08-30T07:00:00+08:00",
639
+ "open": 205.64878845214844,
640
+ "high": 206.30490112304688,
641
+ "low": 203.89483642578125,
642
+ "close": 205.00003051757812,
643
+ "volume": 111015.3046875,
644
+ "amount": 22658542.0
645
+ },
646
+ {
647
+ "timestamp": "2025-08-30T07:15:00+08:00",
648
+ "open": 204.421630859375,
649
+ "high": 208.46713256835938,
650
+ "low": 203.50547790527344,
651
+ "close": 207.89694213867188,
652
+ "volume": 121007.5546875,
653
+ "amount": 24426236.0
654
+ },
655
+ {
656
+ "timestamp": "2025-08-30T07:30:00+08:00",
657
+ "open": 206.92843627929688,
658
+ "high": 207.72479248046875,
659
+ "low": 206.15213012695312,
660
+ "close": 207.23660278320312,
661
+ "volume": 46236.0546875,
662
+ "amount": 9422554.0
663
+ },
664
+ {
665
+ "timestamp": "2025-08-30T07:45:00+08:00",
666
+ "open": 207.0982666015625,
667
+ "high": 207.7059783935547,
668
+ "low": 206.4016571044922,
669
+ "close": 207.19973754882812,
670
+ "volume": 34567.2265625,
671
+ "amount": 7014663.5
672
+ },
673
+ {
674
+ "timestamp": "2025-08-30T08:00:00+08:00",
675
+ "open": 207.47459411621094,
676
+ "high": 209.49899291992188,
677
+ "low": 207.2506103515625,
678
+ "close": 209.15408325195312,
679
+ "volume": 65896.5390625,
680
+ "amount": 13479186.0
681
+ },
682
+ {
683
+ "timestamp": "2025-08-30T08:15:00+08:00",
684
+ "open": 208.68939208984375,
685
+ "high": 209.53033447265625,
686
+ "low": 208.0458526611328,
687
+ "close": 208.9080047607422,
688
+ "volume": 55882.3125,
689
+ "amount": 11488814.0
690
+ },
691
+ {
692
+ "timestamp": "2025-08-30T08:30:00+08:00",
693
+ "open": 209.2847137451172,
694
+ "high": 210.0909423828125,
695
+ "low": 208.68968200683594,
696
+ "close": 209.6594696044922,
697
+ "volume": 39269.265625,
698
+ "amount": 7994326.5
699
+ },
700
+ {
701
+ "timestamp": "2025-08-30T08:45:00+08:00",
702
+ "open": 209.3502655029297,
703
+ "high": 209.6461944580078,
704
+ "low": 208.42019653320312,
705
+ "close": 209.08448791503906,
706
+ "volume": 57113.2734375,
707
+ "amount": 11677034.0
708
+ },
709
+ {
710
+ "timestamp": "2025-08-30T09:00:00+08:00",
711
+ "open": 208.2587432861328,
712
+ "high": 208.58682250976562,
713
+ "low": 206.73037719726562,
714
+ "close": 207.2214813232422,
715
+ "volume": 43398.9453125,
716
+ "amount": 9030006.0
717
+ },
718
+ {
719
+ "timestamp": "2025-08-30T09:15:00+08:00",
720
+ "open": 207.32313537597656,
721
+ "high": 208.15773010253906,
722
+ "low": 206.9442138671875,
723
+ "close": 207.73532104492188,
724
+ "volume": 33828.48828125,
725
+ "amount": 6862379.0
726
+ },
727
+ {
728
+ "timestamp": "2025-08-30T09:30:00+08:00",
729
+ "open": 207.28106689453125,
730
+ "high": 207.620361328125,
731
+ "low": 206.23338317871094,
732
+ "close": 206.6953125,
733
+ "volume": 40982.328125,
734
+ "amount": 8440633.0
735
+ },
736
+ {
737
+ "timestamp": "2025-08-30T09:45:00+08:00",
738
+ "open": 206.6194305419922,
739
+ "high": 207.24417114257812,
740
+ "low": 206.20986938476562,
741
+ "close": 206.69509887695312,
742
+ "volume": 29271.65234375,
743
+ "amount": 5902997.0
744
+ },
745
+ {
746
+ "timestamp": "2025-08-30T10:00:00+08:00",
747
+ "open": 206.8211669921875,
748
+ "high": 209.52674865722656,
749
+ "low": 206.14599609375,
750
+ "close": 207.52096557617188,
751
+ "volume": 21463.578125,
752
+ "amount": 4311557.0
753
+ },
754
+ {
755
+ "timestamp": "2025-08-30T10:15:00+08:00",
756
+ "open": 207.5680389404297,
757
+ "high": 208.1266632080078,
758
+ "low": 206.99095153808594,
759
+ "close": 207.58596801757812,
760
+ "volume": 19337.65234375,
761
+ "amount": 3745935.5
762
+ },
763
+ {
764
+ "timestamp": "2025-08-30T10:30:00+08:00",
765
+ "open": 207.1122283935547,
766
+ "high": 207.41647338867188,
767
+ "low": 206.59402465820312,
768
+ "close": 207.01211547851562,
769
+ "volume": 23504.7265625,
770
+ "amount": 4754291.0
771
+ },
772
+ {
773
+ "timestamp": "2025-08-30T10:45:00+08:00",
774
+ "open": 206.93002319335938,
775
+ "high": 211.2899169921875,
776
+ "low": 205.90670776367188,
777
+ "close": 208.10205078125,
778
+ "volume": 32952.453125,
779
+ "amount": 6630525.5
780
+ },
781
+ {
782
+ "timestamp": "2025-08-30T11:00:00+08:00",
783
+ "open": 207.5081787109375,
784
+ "high": 207.791748046875,
785
+ "low": 206.83070373535156,
786
+ "close": 207.2534637451172,
787
+ "volume": 24705.60546875,
788
+ "amount": 5013673.5
789
+ },
790
+ {
791
+ "timestamp": "2025-08-30T11:15:00+08:00",
792
+ "open": 207.28826904296875,
793
+ "high": 209.80618286132812,
794
+ "low": 206.54495239257812,
795
+ "close": 207.70274353027344,
796
+ "volume": 19185.953125,
797
+ "amount": 3812771.5
798
+ },
799
+ {
800
+ "timestamp": "2025-08-30T11:30:00+08:00",
801
+ "open": 207.8123016357422,
802
+ "high": 208.32888793945312,
803
+ "low": 207.2188262939453,
804
+ "close": 207.74874877929688,
805
+ "volume": 17542.2265625,
806
+ "amount": 3351547.0
807
+ },
808
+ {
809
+ "timestamp": "2025-08-30T11:45:00+08:00",
810
+ "open": 207.8240966796875,
811
+ "high": 208.3235321044922,
812
+ "low": 207.2559814453125,
813
+ "close": 207.74180603027344,
814
+ "volume": 16876.01953125,
815
+ "amount": 3185554.0
816
+ },
817
+ {
818
+ "timestamp": "2025-08-30T12:00:00+08:00",
819
+ "open": 207.29611206054688,
820
+ "high": 207.60755920410156,
821
+ "low": 206.78382873535156,
822
+ "close": 207.21327209472656,
823
+ "volume": 21559.8359375,
824
+ "amount": 4304230.5
825
+ },
826
+ {
827
+ "timestamp": "2025-08-30T12:15:00+08:00",
828
+ "open": 207.2395782470703,
829
+ "high": 207.78256225585938,
830
+ "low": 206.77745056152344,
831
+ "close": 207.4265594482422,
832
+ "volume": 28205.36328125,
833
+ "amount": 5654142.5
834
+ },
835
+ {
836
+ "timestamp": "2025-08-30T12:30:00+08:00",
837
+ "open": 207.29664611816406,
838
+ "high": 208.02996826171875,
839
+ "low": 206.9815673828125,
840
+ "close": 207.25357055664062,
841
+ "volume": 9578.18359375,
842
+ "amount": 1760535.0
843
+ },
844
+ {
845
+ "timestamp": "2025-08-30T12:45:00+08:00",
846
+ "open": 206.562255859375,
847
+ "high": 206.92535400390625,
848
+ "low": 205.78204345703125,
849
+ "close": 206.21188354492188,
850
+ "volume": 27746.986328125,
851
+ "amount": 5597320.5
852
+ },
853
+ {
854
+ "timestamp": "2025-08-30T13:00:00+08:00",
855
+ "open": 206.0684814453125,
856
+ "high": 206.7278289794922,
857
+ "low": 205.73089599609375,
858
+ "close": 206.02276611328125,
859
+ "volume": 27872.4921875,
860
+ "amount": 5547554.0
861
+ },
862
+ {
863
+ "timestamp": "2025-08-30T13:15:00+08:00",
864
+ "open": 206.22244262695312,
865
+ "high": 207.2269287109375,
866
+ "low": 206.0123291015625,
867
+ "close": 206.50833129882812,
868
+ "volume": 10387.8359375,
869
+ "amount": 1889385.0
870
+ },
871
+ {
872
+ "timestamp": "2025-08-30T13:30:00+08:00",
873
+ "open": 206.5584716796875,
874
+ "high": 207.3116455078125,
875
+ "low": 206.27244567871094,
876
+ "close": 206.59613037109375,
877
+ "volume": 7669.484375,
878
+ "amount": 1410481.0
879
+ },
880
+ {
881
+ "timestamp": "2025-08-30T13:45:00+08:00",
882
+ "open": 206.06491088867188,
883
+ "high": 206.4641571044922,
884
+ "low": 205.33670043945312,
885
+ "close": 205.78799438476562,
886
+ "volume": 28521.083984375,
887
+ "amount": 5766101.5
888
+ },
889
+ {
890
+ "timestamp": "2025-08-30T14:00:00+08:00",
891
+ "open": 206.30789184570312,
892
+ "high": 206.7210235595703,
893
+ "low": 205.69021606445312,
894
+ "close": 206.29412841796875,
895
+ "volume": 19588.84375,
896
+ "amount": 3672096.5
897
+ },
898
+ {
899
+ "timestamp": "2025-08-30T14:15:00+08:00",
900
+ "open": 206.56814575195312,
901
+ "high": 207.3887481689453,
902
+ "low": 206.25823974609375,
903
+ "close": 207.09091186523438,
904
+ "volume": 36508.96484375,
905
+ "amount": 7403843.0
906
+ },
907
+ {
908
+ "timestamp": "2025-08-30T14:30:00+08:00",
909
+ "open": 206.72618103027344,
910
+ "high": 207.0769805908203,
911
+ "low": 206.1815643310547,
912
+ "close": 206.6709442138672,
913
+ "volume": 24982.01953125,
914
+ "amount": 5016495.5
915
+ },
916
+ {
917
+ "timestamp": "2025-08-30T14:45:00+08:00",
918
+ "open": 206.42266845703125,
919
+ "high": 206.9484100341797,
920
+ "low": 206.0428466796875,
921
+ "close": 206.47726440429688,
922
+ "volume": 34478.90625,
923
+ "amount": 7017496.5
924
+ },
925
+ {
926
+ "timestamp": "2025-08-30T15:00:00+08:00",
927
+ "open": 207.3406982421875,
928
+ "high": 208.54075622558594,
929
+ "low": 206.9233856201172,
930
+ "close": 208.2393798828125,
931
+ "volume": 35766.29296875,
932
+ "amount": 7149538.0
933
+ },
934
+ {
935
+ "timestamp": "2025-08-30T15:15:00+08:00",
936
+ "open": 208.33697509765625,
937
+ "high": 209.1883087158203,
938
+ "low": 207.91339111328125,
939
+ "close": 208.81930541992188,
940
+ "volume": 34788.0625,
941
+ "amount": 6995742.5
942
+ },
943
+ {
944
+ "timestamp": "2025-08-30T15:30:00+08:00",
945
+ "open": 208.88450622558594,
946
+ "high": 209.39715576171875,
947
+ "low": 208.3055419921875,
948
+ "close": 208.8970947265625,
949
+ "volume": 25539.2734375,
950
+ "amount": 5015440.5
951
+ },
952
+ {
953
+ "timestamp": "2025-08-30T15:45:00+08:00",
954
+ "open": 208.9174346923828,
955
+ "high": 209.41851806640625,
956
+ "low": 208.37869262695312,
957
+ "close": 208.94873046875,
958
+ "volume": 23665.64453125,
959
+ "amount": 4615060.5
960
+ },
961
+ {
962
+ "timestamp": "2025-08-30T16:00:00+08:00",
963
+ "open": 208.49978637695312,
964
+ "high": 208.89210510253906,
965
+ "low": 207.89845275878906,
966
+ "close": 208.331787109375,
967
+ "volume": 35396.58984375,
968
+ "amount": 7224694.5
969
+ },
970
+ {
971
+ "timestamp": "2025-08-30T16:15:00+08:00",
972
+ "open": 208.30181884765625,
973
+ "high": 208.77146911621094,
974
+ "low": 207.7388916015625,
975
+ "close": 208.17803955078125,
976
+ "volume": 17787.4609375,
977
+ "amount": 3379139.5
978
+ },
979
+ {
980
+ "timestamp": "2025-08-30T16:30:00+08:00",
981
+ "open": 208.68223571777344,
982
+ "high": 209.24478149414062,
983
+ "low": 208.20973205566406,
984
+ "close": 208.84716796875,
985
+ "volume": 22763.6875,
986
+ "amount": 4388920.5
987
+ },
988
+ {
989
+ "timestamp": "2025-08-30T16:45:00+08:00",
990
+ "open": 209.03126525878906,
991
+ "high": 209.5188751220703,
992
+ "low": 208.5084228515625,
993
+ "close": 209.06687927246094,
994
+ "volume": 23088.17578125,
995
+ "amount": 4485907.0
996
+ },
997
+ {
998
+ "timestamp": "2025-08-30T17:00:00+08:00",
999
+ "open": 208.74835205078125,
1000
+ "high": 209.1454315185547,
1001
+ "low": 208.1572265625,
1002
+ "close": 208.51858520507812,
1003
+ "volume": 15801.97265625,
1004
+ "amount": 3012316.0
1005
+ },
1006
+ {
1007
+ "timestamp": "2025-08-30T17:15:00+08:00",
1008
+ "open": 209.06504821777344,
1009
+ "high": 209.78887939453125,
1010
+ "low": 208.71043395996094,
1011
+ "close": 209.54180908203125,
1012
+ "volume": 31049.439453125,
1013
+ "amount": 6195858.5
1014
+ },
1015
+ {
1016
+ "timestamp": "2025-08-30T17:30:00+08:00",
1017
+ "open": 210.06785583496094,
1018
+ "high": 211.21372985839844,
1019
+ "low": 209.65682983398438,
1020
+ "close": 211.02857971191406,
1021
+ "volume": 50952.578125,
1022
+ "amount": 10393463.0
1023
+ },
1024
+ {
1025
+ "timestamp": "2025-08-30T17:45:00+08:00",
1026
+ "open": 210.6922607421875,
1027
+ "high": 212.7685089111328,
1028
+ "low": 210.48013305664062,
1029
+ "close": 212.44638061523438,
1030
+ "volume": 77230.0703125,
1031
+ "amount": 16116440.0
1032
+ },
1033
+ {
1034
+ "timestamp": "2025-08-30T18:00:00+08:00",
1035
+ "open": 212.39254760742188,
1036
+ "high": 212.92198181152344,
1037
+ "low": 211.56918334960938,
1038
+ "close": 212.4889373779297,
1039
+ "volume": 55172.46875,
1040
+ "amount": 11482781.0
1041
+ },
1042
+ {
1043
+ "timestamp": "2025-08-30T18:15:00+08:00",
1044
+ "open": 211.56109619140625,
1045
+ "high": 212.07351684570312,
1046
+ "low": 210.49551391601562,
1047
+ "close": 211.1416473388672,
1048
+ "volume": 38471.2109375,
1049
+ "amount": 7931743.0
1050
+ },
1051
+ {
1052
+ "timestamp": "2025-08-30T18:30:00+08:00",
1053
+ "open": 211.31785583496094,
1054
+ "high": 211.90797424316406,
1055
+ "low": 210.52484130859375,
1056
+ "close": 211.40509033203125,
1057
+ "volume": 43308.4140625,
1058
+ "amount": 8856770.0
1059
+ },
1060
+ {
1061
+ "timestamp": "2025-08-30T18:45:00+08:00",
1062
+ "open": 211.40362548828125,
1063
+ "high": 211.97486877441406,
1064
+ "low": 210.7671661376953,
1065
+ "close": 211.47540283203125,
1066
+ "volume": 34866.4140625,
1067
+ "amount": 7060054.0
1068
+ },
1069
+ {
1070
+ "timestamp": "2025-08-30T19:00:00+08:00",
1071
+ "open": 209.8347625732422,
1072
+ "high": 211.67477416992188,
1073
+ "low": 209.2275390625,
1074
+ "close": 211.0730743408203,
1075
+ "volume": 50929.08203125,
1076
+ "amount": 10501012.0
1077
+ },
1078
+ {
1079
+ "timestamp": "2025-08-30T19:15:00+08:00",
1080
+ "open": 211.29388427734375,
1081
+ "high": 212.3085174560547,
1082
+ "low": 210.6793212890625,
1083
+ "close": 212.03553771972656,
1084
+ "volume": 52482.7265625,
1085
+ "amount": 10795927.0
1086
+ },
1087
+ {
1088
+ "timestamp": "2025-08-30T19:30:00+08:00",
1089
+ "open": 211.76470947265625,
1090
+ "high": 212.2696533203125,
1091
+ "low": 211.07388305664062,
1092
+ "close": 211.60971069335938,
1093
+ "volume": 25636.4609375,
1094
+ "amount": 5085773.0
1095
+ },
1096
+ {
1097
+ "timestamp": "2025-08-30T19:45:00+08:00",
1098
+ "open": 211.4890899658203,
1099
+ "high": 211.96034240722656,
1100
+ "low": 210.89694213867188,
1101
+ "close": 211.39459228515625,
1102
+ "volume": 22473.10546875,
1103
+ "amount": 4375774.0
1104
+ },
1105
+ {
1106
+ "timestamp": "2025-08-30T20:00:00+08:00",
1107
+ "open": 211.45584106445312,
1108
+ "high": 211.98915100097656,
1109
+ "low": 210.77133178710938,
1110
+ "close": 211.5296630859375,
1111
+ "volume": 40627.421875,
1112
+ "amount": 8282252.0
1113
+ },
1114
+ {
1115
+ "timestamp": "2025-08-30T20:15:00+08:00",
1116
+ "open": 211.48614501953125,
1117
+ "high": 212.0394744873047,
1118
+ "low": 210.8609161376953,
1119
+ "close": 211.54188537597656,
1120
+ "volume": 34246.671875,
1121
+ "amount": 6913385.0
1122
+ },
1123
+ {
1124
+ "timestamp": "2025-08-30T20:30:00+08:00",
1125
+ "open": 211.10330200195312,
1126
+ "high": 211.35922241210938,
1127
+ "low": 209.96116638183594,
1128
+ "close": 210.44415283203125,
1129
+ "volume": 44392.234375,
1130
+ "amount": 9109514.0
1131
+ }
1132
+ ],
1133
+ "actual_data": [],
1134
+ "analysis": {}
1135
+ }
webui/prediction_results/prediction_20250829_144445.json ADDED
@@ -0,0 +1,1135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "timestamp": "2025-08-29T14:44:45.923056",
3
+ "file_path": "ETHUSDT_15m",
4
+ "prediction_type": "Kronos model prediction (latest data)",
5
+ "prediction_params": {
6
+ "symbol": "ETHUSDT",
7
+ "interval": "15m",
8
+ "limit": 1000,
9
+ "lookback": 1000,
10
+ "pred_len": 120,
11
+ "temperature": 1.0,
12
+ "top_p": 0.9,
13
+ "sample_count": 1,
14
+ "start_date": "latest"
15
+ },
16
+ "input_data_summary": {
17
+ "rows": 1000,
18
+ "columns": [
19
+ "open",
20
+ "high",
21
+ "low",
22
+ "close",
23
+ "volume",
24
+ "amount"
25
+ ],
26
+ "price_range": {
27
+ "open": {
28
+ "min": 4075.58,
29
+ "max": 4942.98
30
+ },
31
+ "high": {
32
+ "min": 4095.0,
33
+ "max": 4956.78
34
+ },
35
+ "low": {
36
+ "min": 4060.0,
37
+ "max": 4933.85
38
+ },
39
+ "close": {
40
+ "min": 4075.59,
41
+ "max": 4942.98
42
+ }
43
+ },
44
+ "last_values": {
45
+ "open": 4453.89,
46
+ "high": 4471.42,
47
+ "low": 4443.37,
48
+ "close": 4467.7
49
+ }
50
+ },
51
+ "prediction_results": [
52
+ {
53
+ "timestamp": "2025-08-29T14:45:00+08:00",
54
+ "open": 4475.39306640625,
55
+ "high": 4490.494140625,
56
+ "low": 4457.38525390625,
57
+ "close": 4468.2412109375,
58
+ "volume": 7627.9443359375,
59
+ "amount": 33887576.0
60
+ },
61
+ {
62
+ "timestamp": "2025-08-29T15:00:00+08:00",
63
+ "open": 4471.74755859375,
64
+ "high": 4493.09619140625,
65
+ "low": 4463.29248046875,
66
+ "close": 4484.59619140625,
67
+ "volume": 9789.4853515625,
68
+ "amount": 43127524.0
69
+ },
70
+ {
71
+ "timestamp": "2025-08-29T15:15:00+08:00",
72
+ "open": 4488.310546875,
73
+ "high": 4509.32568359375,
74
+ "low": 4453.65966796875,
75
+ "close": 4467.154296875,
76
+ "volume": 7698.359375,
77
+ "amount": 33999204.0
78
+ },
79
+ {
80
+ "timestamp": "2025-08-29T15:30:00+08:00",
81
+ "open": 4470.44287109375,
82
+ "high": 4481.6591796875,
83
+ "low": 4454.85302734375,
84
+ "close": 4465.54345703125,
85
+ "volume": 5820.64453125,
86
+ "amount": 25431182.0
87
+ },
88
+ {
89
+ "timestamp": "2025-08-29T15:45:00+08:00",
90
+ "open": 4458.853515625,
91
+ "high": 4468.3095703125,
92
+ "low": 4434.0849609375,
93
+ "close": 4444.95361328125,
94
+ "volume": 5545.421875,
95
+ "amount": 24117800.0
96
+ },
97
+ {
98
+ "timestamp": "2025-08-29T16:00:00+08:00",
99
+ "open": 4447.17041015625,
100
+ "high": 4458.72998046875,
101
+ "low": 4426.33642578125,
102
+ "close": 4441.75537109375,
103
+ "volume": 9062.5048828125,
104
+ "amount": 40147176.0
105
+ },
106
+ {
107
+ "timestamp": "2025-08-29T16:15:00+08:00",
108
+ "open": 4439.44677734375,
109
+ "high": 4446.65380859375,
110
+ "low": 4415.10205078125,
111
+ "close": 4421.83154296875,
112
+ "volume": 5505.30810546875,
113
+ "amount": 24136666.0
114
+ },
115
+ {
116
+ "timestamp": "2025-08-29T16:30:00+08:00",
117
+ "open": 4436.0615234375,
118
+ "high": 4456.52001953125,
119
+ "low": 4425.62109375,
120
+ "close": 4446.4462890625,
121
+ "volume": 4403.462890625,
122
+ "amount": 19484500.0
123
+ },
124
+ {
125
+ "timestamp": "2025-08-29T16:45:00+08:00",
126
+ "open": 4451.66552734375,
127
+ "high": 4470.400390625,
128
+ "low": 4444.31201171875,
129
+ "close": 4457.67724609375,
130
+ "volume": 5625.443359375,
131
+ "amount": 25156120.0
132
+ },
133
+ {
134
+ "timestamp": "2025-08-29T17:00:00+08:00",
135
+ "open": 4459.34326171875,
136
+ "high": 4469.34423828125,
137
+ "low": 4447.14306640625,
138
+ "close": 4456.50830078125,
139
+ "volume": 3870.957763671875,
140
+ "amount": 17261686.0
141
+ },
142
+ {
143
+ "timestamp": "2025-08-29T17:15:00+08:00",
144
+ "open": 4460.0244140625,
145
+ "high": 4470.13037109375,
146
+ "low": 4450.25341796875,
147
+ "close": 4459.39453125,
148
+ "volume": 3543.47998046875,
149
+ "amount": 15846772.0
150
+ },
151
+ {
152
+ "timestamp": "2025-08-29T17:30:00+08:00",
153
+ "open": 4457.65625,
154
+ "high": 4465.13232421875,
155
+ "low": 4441.35498046875,
156
+ "close": 4445.8349609375,
157
+ "volume": 3931.339599609375,
158
+ "amount": 17498512.0
159
+ },
160
+ {
161
+ "timestamp": "2025-08-29T17:45:00+08:00",
162
+ "open": 4452.3505859375,
163
+ "high": 4463.13037109375,
164
+ "low": 4439.46484375,
165
+ "close": 4449.302734375,
166
+ "volume": 4718.111328125,
167
+ "amount": 21203534.0
168
+ },
169
+ {
170
+ "timestamp": "2025-08-29T18:00:00+08:00",
171
+ "open": 4447.71484375,
172
+ "high": 4456.546875,
173
+ "low": 4434.51416015625,
174
+ "close": 4440.126953125,
175
+ "volume": 4100.62890625,
176
+ "amount": 18166164.0
177
+ },
178
+ {
179
+ "timestamp": "2025-08-29T18:15:00+08:00",
180
+ "open": 4447.2802734375,
181
+ "high": 4460.69677734375,
182
+ "low": 4439.892578125,
183
+ "close": 4451.873046875,
184
+ "volume": 3434.46240234375,
185
+ "amount": 15316880.0
186
+ },
187
+ {
188
+ "timestamp": "2025-08-29T18:30:00+08:00",
189
+ "open": 4452.91162109375,
190
+ "high": 4459.91748046875,
191
+ "low": 4444.13720703125,
192
+ "close": 4448.80908203125,
193
+ "volume": 2484.7412109375,
194
+ "amount": 11067866.0
195
+ },
196
+ {
197
+ "timestamp": "2025-08-29T18:45:00+08:00",
198
+ "open": 4452.9365234375,
199
+ "high": 4458.94677734375,
200
+ "low": 4444.92529296875,
201
+ "close": 4449.43408203125,
202
+ "volume": 2297.6748046875,
203
+ "amount": 10239600.0
204
+ },
205
+ {
206
+ "timestamp": "2025-08-29T19:00:00+08:00",
207
+ "open": 4455.3037109375,
208
+ "high": 4465.3408203125,
209
+ "low": 4448.1884765625,
210
+ "close": 4458.28271484375,
211
+ "volume": 3101.412109375,
212
+ "amount": 13888214.0
213
+ },
214
+ {
215
+ "timestamp": "2025-08-29T19:15:00+08:00",
216
+ "open": 4460.62255859375,
217
+ "high": 4469.52099609375,
218
+ "low": 4452.10693359375,
219
+ "close": 4460.59228515625,
220
+ "volume": 3259.80224609375,
221
+ "amount": 14603738.0
222
+ },
223
+ {
224
+ "timestamp": "2025-08-29T19:30:00+08:00",
225
+ "open": 4457.66943359375,
226
+ "high": 4464.20361328125,
227
+ "low": 4441.87646484375,
228
+ "close": 4445.90478515625,
229
+ "volume": 3729.024658203125,
230
+ "amount": 16602088.0
231
+ },
232
+ {
233
+ "timestamp": "2025-08-29T19:45:00+08:00",
234
+ "open": 4443.259765625,
235
+ "high": 4448.1943359375,
236
+ "low": 4430.2275390625,
237
+ "close": 4432.64892578125,
238
+ "volume": 2764.3388671875,
239
+ "amount": 12397988.0
240
+ },
241
+ {
242
+ "timestamp": "2025-08-29T20:00:00+08:00",
243
+ "open": 4437.5859375,
244
+ "high": 4446.86962890625,
245
+ "low": 4427.27392578125,
246
+ "close": 4434.41015625,
247
+ "volume": 3517.18896484375,
248
+ "amount": 15581724.0
249
+ },
250
+ {
251
+ "timestamp": "2025-08-29T20:15:00+08:00",
252
+ "open": 4439.7998046875,
253
+ "high": 4448.30908203125,
254
+ "low": 4431.89111328125,
255
+ "close": 4438.5234375,
256
+ "volume": 2338.8857421875,
257
+ "amount": 10383752.0
258
+ },
259
+ {
260
+ "timestamp": "2025-08-29T20:30:00+08:00",
261
+ "open": 4443.41943359375,
262
+ "high": 4450.49560546875,
263
+ "low": 4435.98095703125,
264
+ "close": 4441.56591796875,
265
+ "volume": 2189.70361328125,
266
+ "amount": 9767136.0
267
+ },
268
+ {
269
+ "timestamp": "2025-08-29T20:45:00+08:00",
270
+ "open": 4445.99462890625,
271
+ "high": 4452.1650390625,
272
+ "low": 4438.48876953125,
273
+ "close": 4443.62646484375,
274
+ "volume": 2149.84619140625,
275
+ "amount": 9582980.0
276
+ },
277
+ {
278
+ "timestamp": "2025-08-29T21:00:00+08:00",
279
+ "open": 4447.6494140625,
280
+ "high": 4453.33251953125,
281
+ "low": 4440.0693359375,
282
+ "close": 4445.0166015625,
283
+ "volume": 2126.830078125,
284
+ "amount": 9457254.0
285
+ },
286
+ {
287
+ "timestamp": "2025-08-29T21:15:00+08:00",
288
+ "open": 4451.2958984375,
289
+ "high": 4461.515625,
290
+ "low": 4444.52685546875,
291
+ "close": 4455.0224609375,
292
+ "volume": 2950.3798828125,
293
+ "amount": 13174318.0
294
+ },
295
+ {
296
+ "timestamp": "2025-08-29T21:30:00+08:00",
297
+ "open": 4463.78369140625,
298
+ "high": 4474.42919921875,
299
+ "low": 4457.12158203125,
300
+ "close": 4465.7509765625,
301
+ "volume": 2112.369140625,
302
+ "amount": 9460990.0
303
+ },
304
+ {
305
+ "timestamp": "2025-08-29T21:45:00+08:00",
306
+ "open": 4465.39599609375,
307
+ "high": 4468.57373046875,
308
+ "low": 4455.44970703125,
309
+ "close": 4458.39306640625,
310
+ "volume": 2150.73779296875,
311
+ "amount": 9565008.0
312
+ },
313
+ {
314
+ "timestamp": "2025-08-29T22:00:00+08:00",
315
+ "open": 4463.8203125,
316
+ "high": 4470.90673828125,
317
+ "low": 4455.60888671875,
318
+ "close": 4464.00634765625,
319
+ "volume": 2996.248046875,
320
+ "amount": 13370722.0
321
+ },
322
+ {
323
+ "timestamp": "2025-08-29T22:15:00+08:00",
324
+ "open": 4466.0341796875,
325
+ "high": 4473.34423828125,
326
+ "low": 4457.1318359375,
327
+ "close": 4464.7451171875,
328
+ "volume": 3177.6201171875,
329
+ "amount": 14182380.0
330
+ },
331
+ {
332
+ "timestamp": "2025-08-29T22:30:00+08:00",
333
+ "open": 4465.1748046875,
334
+ "high": 4469.259765625,
335
+ "low": 4455.42333984375,
336
+ "close": 4458.80810546875,
337
+ "volume": 2305.25341796875,
338
+ "amount": 10204460.0
339
+ },
340
+ {
341
+ "timestamp": "2025-08-29T22:45:00+08:00",
342
+ "open": 4456.71875,
343
+ "high": 4462.33642578125,
344
+ "low": 4442.1904296875,
345
+ "close": 4446.46240234375,
346
+ "volume": 3515.01318359375,
347
+ "amount": 15601176.0
348
+ },
349
+ {
350
+ "timestamp": "2025-08-29T23:00:00+08:00",
351
+ "open": 4447.88720703125,
352
+ "high": 4455.390625,
353
+ "low": 4435.08056640625,
354
+ "close": 4440.0048828125,
355
+ "volume": 3668.009765625,
356
+ "amount": 16222542.0
357
+ },
358
+ {
359
+ "timestamp": "2025-08-29T23:15:00+08:00",
360
+ "open": 4451.14794921875,
361
+ "high": 4467.03515625,
362
+ "low": 4430.35009765625,
363
+ "close": 4438.390625,
364
+ "volume": 6680.0849609375,
365
+ "amount": 29301914.0
366
+ },
367
+ {
368
+ "timestamp": "2025-08-29T23:30:00+08:00",
369
+ "open": 4434.3623046875,
370
+ "high": 4437.36328125,
371
+ "low": 4405.90869140625,
372
+ "close": 4405.78857421875,
373
+ "volume": 10929.482421875,
374
+ "amount": 48557132.0
375
+ },
376
+ {
377
+ "timestamp": "2025-08-29T23:45:00+08:00",
378
+ "open": 4408.3837890625,
379
+ "high": 4422.7353515625,
380
+ "low": 4396.68017578125,
381
+ "close": 4406.693359375,
382
+ "volume": 5351.13671875,
383
+ "amount": 23324156.0
384
+ },
385
+ {
386
+ "timestamp": "2025-08-30T00:00:00+08:00",
387
+ "open": 4407.900390625,
388
+ "high": 4426.98193359375,
389
+ "low": 4399.10302734375,
390
+ "close": 4414.2802734375,
391
+ "volume": 4985.232421875,
392
+ "amount": 21656318.0
393
+ },
394
+ {
395
+ "timestamp": "2025-08-30T00:15:00+08:00",
396
+ "open": 4419.51171875,
397
+ "high": 4432.8291015625,
398
+ "low": 4409.4990234375,
399
+ "close": 4419.48876953125,
400
+ "volume": 3905.1591796875,
401
+ "amount": 17215756.0
402
+ },
403
+ {
404
+ "timestamp": "2025-08-30T00:30:00+08:00",
405
+ "open": 4423.07568359375,
406
+ "high": 4434.990234375,
407
+ "low": 4413.3447265625,
408
+ "close": 4421.8095703125,
409
+ "volume": 3696.855712890625,
410
+ "amount": 16365186.0
411
+ },
412
+ {
413
+ "timestamp": "2025-08-30T00:45:00+08:00",
414
+ "open": 4425.412109375,
415
+ "high": 4436.4072265625,
416
+ "low": 4415.48828125,
417
+ "close": 4423.09716796875,
418
+ "volume": 3656.831298828125,
419
+ "amount": 16200730.0
420
+ },
421
+ {
422
+ "timestamp": "2025-08-30T01:00:00+08:00",
423
+ "open": 4427.07421875,
424
+ "high": 4437.56103515625,
425
+ "low": 4417.10791015625,
426
+ "close": 4424.1650390625,
427
+ "volume": 3650.77880859375,
428
+ "amount": 16163038.0
429
+ },
430
+ {
431
+ "timestamp": "2025-08-30T01:15:00+08:00",
432
+ "open": 4423.990234375,
433
+ "high": 4429.60546875,
434
+ "low": 4412.88525390625,
435
+ "close": 4416.09716796875,
436
+ "volume": 2709.11767578125,
437
+ "amount": 12078352.0
438
+ },
439
+ {
440
+ "timestamp": "2025-08-30T01:30:00+08:00",
441
+ "open": 4422.77978515625,
442
+ "high": 4433.359375,
443
+ "low": 4414.36279296875,
444
+ "close": 4422.4248046875,
445
+ "volume": 3398.93310546875,
446
+ "amount": 15033004.0
447
+ },
448
+ {
449
+ "timestamp": "2025-08-30T01:45:00+08:00",
450
+ "open": 4422.82080078125,
451
+ "high": 4428.03125,
452
+ "low": 4412.04345703125,
453
+ "close": 4415.1455078125,
454
+ "volume": 2624.51025390625,
455
+ "amount": 11725686.0
456
+ },
457
+ {
458
+ "timestamp": "2025-08-30T02:00:00+08:00",
459
+ "open": 4417.7353515625,
460
+ "high": 4422.8154296875,
461
+ "low": 4408.658203125,
462
+ "close": 4412.39111328125,
463
+ "volume": 2436.2763671875,
464
+ "amount": 10884686.0
465
+ },
466
+ {
467
+ "timestamp": "2025-08-30T02:15:00+08:00",
468
+ "open": 4419.49658203125,
469
+ "high": 4430.1337890625,
470
+ "low": 4411.44287109375,
471
+ "close": 4419.994140625,
472
+ "volume": 3253.17236328125,
473
+ "amount": 14373996.0
474
+ },
475
+ {
476
+ "timestamp": "2025-08-30T02:30:00+08:00",
477
+ "open": 4426.5625,
478
+ "high": 4434.4697265625,
479
+ "low": 4419.0185546875,
480
+ "close": 4425.71240234375,
481
+ "volume": 2173.82421875,
482
+ "amount": 9593102.0
483
+ },
484
+ {
485
+ "timestamp": "2025-08-30T02:45:00+08:00",
486
+ "open": 4431.125,
487
+ "high": 4437.8212890625,
488
+ "low": 4424.39501953125,
489
+ "close": 4430.10595703125,
490
+ "volume": 2030.0625,
491
+ "amount": 8996584.0
492
+ },
493
+ {
494
+ "timestamp": "2025-08-30T03:00:00+08:00",
495
+ "open": 4432.4482421875,
496
+ "high": 4440.4033203125,
497
+ "low": 4422.708984375,
498
+ "close": 4428.4755859375,
499
+ "volume": 3258.76123046875,
500
+ "amount": 14471588.0
501
+ },
502
+ {
503
+ "timestamp": "2025-08-30T03:15:00+08:00",
504
+ "open": 4434.09423828125,
505
+ "high": 4440.85595703125,
506
+ "low": 4426.19775390625,
507
+ "close": 4432.1748046875,
508
+ "volume": 2192.650390625,
509
+ "amount": 9661786.0
510
+ },
511
+ {
512
+ "timestamp": "2025-08-30T03:30:00+08:00",
513
+ "open": 4436.89794921875,
514
+ "high": 4449.38525390625,
515
+ "low": 4430.4541015625,
516
+ "close": 4439.28173828125,
517
+ "volume": 3777.546630859375,
518
+ "amount": 16553222.0
519
+ },
520
+ {
521
+ "timestamp": "2025-08-30T03:45:00+08:00",
522
+ "open": 4443.34521484375,
523
+ "high": 4448.34521484375,
524
+ "low": 4433.31396484375,
525
+ "close": 4437.76025390625,
526
+ "volume": 2307.06494140625,
527
+ "amount": 10187352.0
528
+ },
529
+ {
530
+ "timestamp": "2025-08-30T04:00:00+08:00",
531
+ "open": 4445.75830078125,
532
+ "high": 4456.35498046875,
533
+ "low": 4439.30908203125,
534
+ "close": 4449.79833984375,
535
+ "volume": 2986.740234375,
536
+ "amount": 13296126.0
537
+ },
538
+ {
539
+ "timestamp": "2025-08-30T04:15:00+08:00",
540
+ "open": 4453.3271484375,
541
+ "high": 4461.97900390625,
542
+ "low": 4445.7275390625,
543
+ "close": 4454.1044921875,
544
+ "volume": 3141.96240234375,
545
+ "amount": 14019666.0
546
+ },
547
+ {
548
+ "timestamp": "2025-08-30T04:30:00+08:00",
549
+ "open": 4460.35302734375,
550
+ "high": 4468.6044921875,
551
+ "low": 4449.45751953125,
552
+ "close": 4458.955078125,
553
+ "volume": 3893.1748046875,
554
+ "amount": 17371366.0
555
+ },
556
+ {
557
+ "timestamp": "2025-08-30T04:45:00+08:00",
558
+ "open": 4458.69091796875,
559
+ "high": 4462.13525390625,
560
+ "low": 4448.71923828125,
561
+ "close": 4451.681640625,
562
+ "volume": 2403.53173828125,
563
+ "amount": 10631452.0
564
+ },
565
+ {
566
+ "timestamp": "2025-08-30T05:00:00+08:00",
567
+ "open": 4455.412109375,
568
+ "high": 4458.86572265625,
569
+ "low": 4447.08447265625,
570
+ "close": 4450.326171875,
571
+ "volume": 2194.31005859375,
572
+ "amount": 9697510.0
573
+ },
574
+ {
575
+ "timestamp": "2025-08-30T05:15:00+08:00",
576
+ "open": 4456.33349609375,
577
+ "high": 4464.39599609375,
578
+ "low": 4449.61181640625,
579
+ "close": 4458.34228515625,
580
+ "volume": 3008.1005859375,
581
+ "amount": 13391762.0
582
+ },
583
+ {
584
+ "timestamp": "2025-08-30T05:30:00+08:00",
585
+ "open": 4459.1015625,
586
+ "high": 4462.34814453125,
587
+ "low": 4449.98876953125,
588
+ "close": 4452.84326171875,
589
+ "volume": 2261.19775390625,
590
+ "amount": 10009704.0
591
+ },
592
+ {
593
+ "timestamp": "2025-08-30T05:45:00+08:00",
594
+ "open": 4458.75244140625,
595
+ "high": 4466.1484375,
596
+ "low": 4451.54150390625,
597
+ "close": 4459.73583984375,
598
+ "volume": 3006.083984375,
599
+ "amount": 13381342.0
600
+ },
601
+ {
602
+ "timestamp": "2025-08-30T06:00:00+08:00",
603
+ "open": 4460.3203125,
604
+ "high": 4463.41259765625,
605
+ "low": 4451.142578125,
606
+ "close": 4453.876953125,
607
+ "volume": 2250.26123046875,
608
+ "amount": 9964284.0
609
+ },
610
+ {
611
+ "timestamp": "2025-08-30T06:15:00+08:00",
612
+ "open": 4459.52685546875,
613
+ "high": 4466.78955078125,
614
+ "low": 4452.3046875,
615
+ "close": 4460.33642578125,
616
+ "volume": 2989.49072265625,
617
+ "amount": 13307256.0
618
+ },
619
+ {
620
+ "timestamp": "2025-08-30T06:30:00+08:00",
621
+ "open": 4466.103515625,
622
+ "high": 4473.357421875,
623
+ "low": 4455.0498046875,
624
+ "close": 4463.7744140625,
625
+ "volume": 3843.999755859375,
626
+ "amount": 17168558.0
627
+ },
628
+ {
629
+ "timestamp": "2025-08-30T06:45:00+08:00",
630
+ "open": 4463.78955078125,
631
+ "high": 4466.755859375,
632
+ "low": 4453.74658203125,
633
+ "close": 4456.37109375,
634
+ "volume": 2359.63232421875,
635
+ "amount": 10438442.0
636
+ },
637
+ {
638
+ "timestamp": "2025-08-30T07:00:00+08:00",
639
+ "open": 4460.02587890625,
640
+ "high": 4462.9697265625,
641
+ "low": 4451.57958984375,
642
+ "close": 4454.49169921875,
643
+ "volume": 2149.61865234375,
644
+ "amount": 9492492.0
645
+ },
646
+ {
647
+ "timestamp": "2025-08-30T07:15:00+08:00",
648
+ "open": 4458.18701171875,
649
+ "high": 4461.1494140625,
650
+ "low": 4450.248046875,
651
+ "close": 4453.38916015625,
652
+ "volume": 2091.15185546875,
653
+ "amount": 9235408.0
654
+ },
655
+ {
656
+ "timestamp": "2025-08-30T07:30:00+08:00",
657
+ "open": 4456.94775390625,
658
+ "high": 4459.888671875,
659
+ "low": 4449.107421875,
660
+ "close": 4452.421875,
661
+ "volume": 2046.2802734375,
662
+ "amount": 9028306.0
663
+ },
664
+ {
665
+ "timestamp": "2025-08-30T07:45:00+08:00",
666
+ "open": 4450.64111328125,
667
+ "high": 4455.8544921875,
668
+ "low": 4437.90234375,
669
+ "close": 4442.01123046875,
670
+ "volume": 3325.45947265625,
671
+ "amount": 14708284.0
672
+ },
673
+ {
674
+ "timestamp": "2025-08-30T08:00:00+08:00",
675
+ "open": 4443.60009765625,
676
+ "high": 4450.54150390625,
677
+ "low": 4431.58544921875,
678
+ "close": 4436.2099609375,
679
+ "volume": 3507.669921875,
680
+ "amount": 15459794.0
681
+ },
682
+ {
683
+ "timestamp": "2025-08-30T08:15:00+08:00",
684
+ "open": 4442.1611328125,
685
+ "high": 4448.74267578125,
686
+ "low": 4434.025390625,
687
+ "close": 4439.4833984375,
688
+ "volume": 2220.54150390625,
689
+ "amount": 9763768.0
690
+ },
691
+ {
692
+ "timestamp": "2025-08-30T08:30:00+08:00",
693
+ "open": 4444.66455078125,
694
+ "high": 4449.8037109375,
695
+ "low": 4437.31982421875,
696
+ "close": 4441.72900390625,
697
+ "volume": 2054.14501953125,
698
+ "amount": 9095126.0
699
+ },
700
+ {
701
+ "timestamp": "2025-08-30T08:45:00+08:00",
702
+ "open": 4446.98876953125,
703
+ "high": 4451.1435546875,
704
+ "low": 4439.60498046875,
705
+ "close": 4443.5478515625,
706
+ "volume": 1997.9091796875,
707
+ "amount": 8857388.0
708
+ },
709
+ {
710
+ "timestamp": "2025-08-30T09:00:00+08:00",
711
+ "open": 4448.36767578125,
712
+ "high": 4452.1748046875,
713
+ "low": 4440.8837890625,
714
+ "close": 4444.8212890625,
715
+ "volume": 1971.53466796875,
716
+ "amount": 8724846.0
717
+ },
718
+ {
719
+ "timestamp": "2025-08-30T09:15:00+08:00",
720
+ "open": 4449.26171875,
721
+ "high": 4452.9658203125,
722
+ "low": 4441.6767578125,
723
+ "close": 4445.7197265625,
724
+ "volume": 1957.69775390625,
725
+ "amount": 8646988.0
726
+ },
727
+ {
728
+ "timestamp": "2025-08-30T09:30:00+08:00",
729
+ "open": 4450.08984375,
730
+ "high": 4453.64404296875,
731
+ "low": 4442.3984375,
732
+ "close": 4446.4521484375,
733
+ "volume": 1940.76513671875,
734
+ "amount": 8560176.0
735
+ },
736
+ {
737
+ "timestamp": "2025-08-30T09:45:00+08:00",
738
+ "open": 4441.83154296875,
739
+ "high": 4444.29736328125,
740
+ "low": 4430.7626953125,
741
+ "close": 4432.7177734375,
742
+ "volume": 2199.5634765625,
743
+ "amount": 9831958.0
744
+ },
745
+ {
746
+ "timestamp": "2025-08-30T10:00:00+08:00",
747
+ "open": 4435.56201171875,
748
+ "high": 4443.05859375,
749
+ "low": 4425.48876953125,
750
+ "close": 4431.7099609375,
751
+ "volume": 3201.94921875,
752
+ "amount": 14076856.0
753
+ },
754
+ {
755
+ "timestamp": "2025-08-30T10:15:00+08:00",
756
+ "open": 4435.11669921875,
757
+ "high": 4443.1513671875,
758
+ "low": 4424.16748046875,
759
+ "close": 4429.5693359375,
760
+ "volume": 3393.9794921875,
761
+ "amount": 14940854.0
762
+ },
763
+ {
764
+ "timestamp": "2025-08-30T10:30:00+08:00",
765
+ "open": 4449.251953125,
766
+ "high": 4468.1787109375,
767
+ "low": 4407.73876953125,
768
+ "close": 4413.61572265625,
769
+ "volume": 6180.857421875,
770
+ "amount": 27232986.0
771
+ },
772
+ {
773
+ "timestamp": "2025-08-30T10:45:00+08:00",
774
+ "open": 4418.56640625,
775
+ "high": 4426.99755859375,
776
+ "low": 4407.890625,
777
+ "close": 4414.6923828125,
778
+ "volume": 2911.21923828125,
779
+ "amount": 12764714.0
780
+ },
781
+ {
782
+ "timestamp": "2025-08-30T11:00:00+08:00",
783
+ "open": 4423.27490234375,
784
+ "high": 4434.11669921875,
785
+ "low": 4414.24365234375,
786
+ "close": 4423.75830078125,
787
+ "volume": 2159.18115234375,
788
+ "amount": 9464844.0
789
+ },
790
+ {
791
+ "timestamp": "2025-08-30T11:15:00+08:00",
792
+ "open": 4422.890625,
793
+ "high": 4430.45263671875,
794
+ "low": 4406.41748046875,
795
+ "close": 4413.015625,
796
+ "volume": 4069.020263671875,
797
+ "amount": 17834534.0
798
+ },
799
+ {
800
+ "timestamp": "2025-08-30T11:30:00+08:00",
801
+ "open": 4422.1123046875,
802
+ "high": 4432.6279296875,
803
+ "low": 4413.69677734375,
804
+ "close": 4422.66162109375,
805
+ "volume": 2245.869140625,
806
+ "amount": 9839772.0
807
+ },
808
+ {
809
+ "timestamp": "2025-08-30T11:45:00+08:00",
810
+ "open": 4426.66943359375,
811
+ "high": 4437.044921875,
812
+ "low": 4417.4345703125,
813
+ "close": 4424.703125,
814
+ "volume": 3279.62548828125,
815
+ "amount": 14532810.0
816
+ },
817
+ {
818
+ "timestamp": "2025-08-30T12:00:00+08:00",
819
+ "open": 4428.41796875,
820
+ "high": 4438.08251953125,
821
+ "low": 4417.6142578125,
822
+ "close": 4424.30712890625,
823
+ "volume": 3482.80322265625,
824
+ "amount": 15369926.0
825
+ },
826
+ {
827
+ "timestamp": "2025-08-30T12:15:00+08:00",
828
+ "open": 4424.35693359375,
829
+ "high": 4429.4638671875,
830
+ "low": 4413.07470703125,
831
+ "close": 4416.146484375,
832
+ "volume": 2542.1484375,
833
+ "amount": 11286276.0
834
+ },
835
+ {
836
+ "timestamp": "2025-08-30T12:30:00+08:00",
837
+ "open": 4424.92626953125,
838
+ "high": 4433.3505859375,
839
+ "low": 4417.375,
840
+ "close": 4425.17724609375,
841
+ "volume": 2033.24462890625,
842
+ "amount": 8929204.0
843
+ },
844
+ {
845
+ "timestamp": "2025-08-30T12:45:00+08:00",
846
+ "open": 4431.095703125,
847
+ "high": 4437.9970703125,
848
+ "low": 4424.1591796875,
849
+ "close": 4430.1064453125,
850
+ "volume": 1961.21630859375,
851
+ "amount": 8675884.0
852
+ },
853
+ {
854
+ "timestamp": "2025-08-30T13:00:00+08:00",
855
+ "open": 4435.22412109375,
856
+ "high": 4440.904296875,
857
+ "low": 4427.9931640625,
858
+ "close": 4433.2490234375,
859
+ "volume": 1934.3203125,
860
+ "amount": 8542236.0
861
+ },
862
+ {
863
+ "timestamp": "2025-08-30T13:15:00+08:00",
864
+ "open": 4441.78955078125,
865
+ "high": 4452.7998046875,
866
+ "low": 4435.89892578125,
867
+ "close": 4447.0693359375,
868
+ "volume": 2780.62744140625,
869
+ "amount": 12354512.0
870
+ },
871
+ {
872
+ "timestamp": "2025-08-30T13:30:00+08:00",
873
+ "open": 4450.72314453125,
874
+ "high": 4459.70361328125,
875
+ "low": 4443.11572265625,
876
+ "close": 4451.88916015625,
877
+ "volume": 2998.10791015625,
878
+ "amount": 13337032.0
879
+ },
880
+ {
881
+ "timestamp": "2025-08-30T13:45:00+08:00",
882
+ "open": 4453.06103515625,
883
+ "high": 4456.916015625,
884
+ "low": 4443.51220703125,
885
+ "close": 4446.93359375,
886
+ "volume": 2147.71728515625,
887
+ "amount": 9464878.0
888
+ },
889
+ {
890
+ "timestamp": "2025-08-30T14:00:00+08:00",
891
+ "open": 4451.41259765625,
892
+ "high": 4454.98291015625,
893
+ "low": 4443.05126953125,
894
+ "close": 4446.6728515625,
895
+ "volume": 2020.13720703125,
896
+ "amount": 8899476.0
897
+ },
898
+ {
899
+ "timestamp": "2025-08-30T14:15:00+08:00",
900
+ "open": 4450.83984375,
901
+ "high": 4454.37158203125,
902
+ "low": 4442.8291015625,
903
+ "close": 4446.57470703125,
904
+ "volume": 1977.5205078125,
905
+ "amount": 8720166.0
906
+ },
907
+ {
908
+ "timestamp": "2025-08-30T14:30:00+08:00",
909
+ "open": 4450.6123046875,
910
+ "high": 4454.08056640625,
911
+ "low": 4442.6259765625,
912
+ "close": 4446.470703125,
913
+ "volume": 1946.2275390625,
914
+ "amount": 8577792.0
915
+ },
916
+ {
917
+ "timestamp": "2025-08-30T14:45:00+08:00",
918
+ "open": 4450.72314453125,
919
+ "high": 4454.1025390625,
920
+ "low": 4442.66650390625,
921
+ "close": 4446.58935546875,
922
+ "volume": 1925.15380859375,
923
+ "amount": 8472904.0
924
+ },
925
+ {
926
+ "timestamp": "2025-08-30T15:00:00+08:00",
927
+ "open": 4450.73486328125,
928
+ "high": 4454.03125,
929
+ "low": 4442.70361328125,
930
+ "close": 4446.6357421875,
931
+ "volume": 1902.77197265625,
932
+ "amount": 8358786.0
933
+ },
934
+ {
935
+ "timestamp": "2025-08-30T15:15:00+08:00",
936
+ "open": 4449.1904296875,
937
+ "high": 4458.5654296875,
938
+ "low": 4439.82958984375,
939
+ "close": 4447.3193359375,
940
+ "volume": 3754.225830078125,
941
+ "amount": 16352920.0
942
+ },
943
+ {
944
+ "timestamp": "2025-08-30T15:30:00+08:00",
945
+ "open": 4451.1796875,
946
+ "high": 4455.5283203125,
947
+ "low": 4440.46484375,
948
+ "close": 4444.556640625,
949
+ "volume": 2196.74560546875,
950
+ "amount": 9607372.0
951
+ },
952
+ {
953
+ "timestamp": "2025-08-30T15:45:00+08:00",
954
+ "open": 4449.95751953125,
955
+ "high": 4454.2392578125,
956
+ "low": 4441.34423828125,
957
+ "close": 4445.36962890625,
958
+ "volume": 2033.66259765625,
959
+ "amount": 8954060.0
960
+ },
961
+ {
962
+ "timestamp": "2025-08-30T16:00:00+08:00",
963
+ "open": 4452.71826171875,
964
+ "high": 4461.85302734375,
965
+ "low": 4445.93310546875,
966
+ "close": 4455.3662109375,
967
+ "volume": 2869.0107421875,
968
+ "amount": 12766232.0
969
+ },
970
+ {
971
+ "timestamp": "2025-08-30T16:15:00+08:00",
972
+ "open": 4456.76904296875,
973
+ "high": 4460.29638671875,
974
+ "low": 4447.1376953125,
975
+ "close": 4450.2431640625,
976
+ "volume": 2119.6484375,
977
+ "amount": 9350508.0
978
+ },
979
+ {
980
+ "timestamp": "2025-08-30T16:30:00+08:00",
981
+ "open": 4454.650390625,
982
+ "high": 4458.021484375,
983
+ "low": 4446.01904296875,
984
+ "close": 4449.41552734375,
985
+ "volume": 2001.9658203125,
986
+ "amount": 8809458.0
987
+ },
988
+ {
989
+ "timestamp": "2025-08-30T16:45:00+08:00",
990
+ "open": 4456.00244140625,
991
+ "high": 4464.26953125,
992
+ "low": 4449.099609375,
993
+ "close": 4457.9091796875,
994
+ "volume": 2862.791015625,
995
+ "amount": 12715424.0
996
+ },
997
+ {
998
+ "timestamp": "2025-08-30T17:00:00+08:00",
999
+ "open": 4461.19921875,
1000
+ "high": 4468.45654296875,
1001
+ "low": 4452.8603515625,
1002
+ "close": 4460.0908203125,
1003
+ "volume": 3035.2373046875,
1004
+ "amount": 13495972.0
1005
+ },
1006
+ {
1007
+ "timestamp": "2025-08-30T17:15:00+08:00",
1008
+ "open": 4461.71875,
1009
+ "high": 4464.89501953125,
1010
+ "low": 4451.8251953125,
1011
+ "close": 4454.52490234375,
1012
+ "volume": 2150.0859375,
1013
+ "amount": 9457424.0
1014
+ },
1015
+ {
1016
+ "timestamp": "2025-08-30T17:30:00+08:00",
1017
+ "open": 4458.8837890625,
1018
+ "high": 4461.86376953125,
1019
+ "low": 4450.1875,
1020
+ "close": 4453.25,
1021
+ "volume": 2018.88818359375,
1022
+ "amount": 8873592.0
1023
+ },
1024
+ {
1025
+ "timestamp": "2025-08-30T17:45:00+08:00",
1026
+ "open": 4457.4638671875,
1027
+ "high": 4460.474609375,
1028
+ "low": 4449.154296875,
1029
+ "close": 4452.4384765625,
1030
+ "volume": 1968.6240234375,
1031
+ "amount": 8652570.0
1032
+ },
1033
+ {
1034
+ "timestamp": "2025-08-30T18:00:00+08:00",
1035
+ "open": 4456.51953125,
1036
+ "high": 4459.55078125,
1037
+ "low": 4448.25439453125,
1038
+ "close": 4451.73388671875,
1039
+ "volume": 1931.48046875,
1040
+ "amount": 8480152.0
1041
+ },
1042
+ {
1043
+ "timestamp": "2025-08-30T18:15:00+08:00",
1044
+ "open": 4455.92236328125,
1045
+ "high": 4458.9658203125,
1046
+ "low": 4447.59814453125,
1047
+ "close": 4451.22705078125,
1048
+ "volume": 1906.451171875,
1049
+ "amount": 8359996.0
1050
+ },
1051
+ {
1052
+ "timestamp": "2025-08-30T18:30:00+08:00",
1053
+ "open": 4455.41015625,
1054
+ "high": 4458.42578125,
1055
+ "low": 4447.06884765625,
1056
+ "close": 4450.74853515625,
1057
+ "volume": 1881.97705078125,
1058
+ "amount": 8244206.0
1059
+ },
1060
+ {
1061
+ "timestamp": "2025-08-30T18:45:00+08:00",
1062
+ "open": 4454.880859375,
1063
+ "high": 4457.85888671875,
1064
+ "low": 4446.56298828125,
1065
+ "close": 4450.24365234375,
1066
+ "volume": 1859.8369140625,
1067
+ "amount": 8143162.0
1068
+ },
1069
+ {
1070
+ "timestamp": "2025-08-30T19:00:00+08:00",
1071
+ "open": 4454.4931640625,
1072
+ "high": 4457.44384765625,
1073
+ "low": 4446.19677734375,
1074
+ "close": 4449.88427734375,
1075
+ "volume": 1844.34375,
1076
+ "amount": 8072410.0
1077
+ },
1078
+ {
1079
+ "timestamp": "2025-08-30T19:15:00+08:00",
1080
+ "open": 4448.9033203125,
1081
+ "high": 4454.20166015625,
1082
+ "low": 4436.1005859375,
1083
+ "close": 4440.21728515625,
1084
+ "volume": 3178.27099609375,
1085
+ "amount": 14001542.0
1086
+ },
1087
+ {
1088
+ "timestamp": "2025-08-30T19:30:00+08:00",
1089
+ "open": 4438.18408203125,
1090
+ "high": 4441.70556640625,
1091
+ "low": 4426.0986328125,
1092
+ "close": 4428.201171875,
1093
+ "volume": 2323.46044921875,
1094
+ "amount": 10249692.0
1095
+ },
1096
+ {
1097
+ "timestamp": "2025-08-30T19:45:00+08:00",
1098
+ "open": 4436.38818359375,
1099
+ "high": 4443.2783203125,
1100
+ "low": 4428.2373046875,
1101
+ "close": 4435.158203125,
1102
+ "volume": 1885.62255859375,
1103
+ "amount": 8202620.0
1104
+ },
1105
+ {
1106
+ "timestamp": "2025-08-30T20:00:00+08:00",
1107
+ "open": 4441.103515625,
1108
+ "high": 4446.53515625,
1109
+ "low": 4433.41796875,
1110
+ "close": 4438.57958984375,
1111
+ "volume": 1831.78271484375,
1112
+ "amount": 8041696.0
1113
+ },
1114
+ {
1115
+ "timestamp": "2025-08-30T20:15:00+08:00",
1116
+ "open": 4436.1572265625,
1117
+ "high": 4438.953125,
1118
+ "low": 4425.17529296875,
1119
+ "close": 4427.3349609375,
1120
+ "volume": 2042.33837890625,
1121
+ "amount": 9105280.0
1122
+ },
1123
+ {
1124
+ "timestamp": "2025-08-30T20:30:00+08:00",
1125
+ "open": 4427.47021484375,
1126
+ "high": 4430.9775390625,
1127
+ "low": 4417.41259765625,
1128
+ "close": 4420.6572265625,
1129
+ "volume": 2053.37890625,
1130
+ "amount": 9087156.0
1131
+ }
1132
+ ],
1133
+ "actual_data": [],
1134
+ "analysis": {}
1135
+ }
webui/prediction_results/prediction_20250829_144621.json ADDED
@@ -0,0 +1,1135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "timestamp": "2025-08-29T14:46:21.732774",
3
+ "file_path": "BTCUSDT_15m",
4
+ "prediction_type": "Kronos model prediction (latest data)",
5
+ "prediction_params": {
6
+ "symbol": "BTCUSDT",
7
+ "interval": "15m",
8
+ "limit": 1000,
9
+ "lookback": 1000,
10
+ "pred_len": 120,
11
+ "temperature": 1.0,
12
+ "top_p": 0.9,
13
+ "sample_count": 1,
14
+ "start_date": "latest"
15
+ },
16
+ "input_data_summary": {
17
+ "rows": 1000,
18
+ "columns": [
19
+ "open",
20
+ "high",
21
+ "low",
22
+ "close",
23
+ "volume",
24
+ "amount"
25
+ ],
26
+ "price_range": {
27
+ "open": {
28
+ "min": 109100.24,
29
+ "max": 117410.0
30
+ },
31
+ "high": {
32
+ "min": 109580.0,
33
+ "max": 117429.05
34
+ },
35
+ "low": {
36
+ "min": 108666.66,
37
+ "max": 117024.0
38
+ },
39
+ "close": {
40
+ "min": 109100.23,
41
+ "max": 117410.0
42
+ }
43
+ },
44
+ "last_values": {
45
+ "open": 111000.01,
46
+ "high": 111252.83,
47
+ "low": 110955.41,
48
+ "close": 111236.0
49
+ }
50
+ },
51
+ "prediction_results": [
52
+ {
53
+ "timestamp": "2025-08-29T14:45:00+08:00",
54
+ "open": 111168.84375,
55
+ "high": 111428.984375,
56
+ "low": 111069.21875,
57
+ "close": 111291.6328125,
58
+ "volume": 107.74244689941406,
59
+ "amount": 11905271.0
60
+ },
61
+ {
62
+ "timestamp": "2025-08-29T15:00:00+08:00",
63
+ "open": 111459.4765625,
64
+ "high": 111390.40625,
65
+ "low": 111016.0390625,
66
+ "close": 111065.3515625,
67
+ "volume": 100.44855499267578,
68
+ "amount": 11109445.0
69
+ },
70
+ {
71
+ "timestamp": "2025-08-29T15:15:00+08:00",
72
+ "open": 111008.5390625,
73
+ "high": 111307.0,
74
+ "low": 110882.4375,
75
+ "close": 111207.53125,
76
+ "volume": 102.61687469482422,
77
+ "amount": 11261764.0
78
+ },
79
+ {
80
+ "timestamp": "2025-08-29T15:30:00+08:00",
81
+ "open": 111131.90625,
82
+ "high": 111246.015625,
83
+ "low": 110920.6953125,
84
+ "close": 111047.25,
85
+ "volume": 148.45530700683594,
86
+ "amount": 16270636.0
87
+ },
88
+ {
89
+ "timestamp": "2025-08-29T15:45:00+08:00",
90
+ "open": 111185.6171875,
91
+ "high": 111286.0859375,
92
+ "low": 110959.171875,
93
+ "close": 111138.0078125,
94
+ "volume": 92.29530334472656,
95
+ "amount": 10299675.0
96
+ },
97
+ {
98
+ "timestamp": "2025-08-29T16:00:00+08:00",
99
+ "open": 111115.3125,
100
+ "high": 111351.90625,
101
+ "low": 110853.75,
102
+ "close": 111050.90625,
103
+ "volume": 266.1111755371094,
104
+ "amount": 29438244.0
105
+ },
106
+ {
107
+ "timestamp": "2025-08-29T16:15:00+08:00",
108
+ "open": 111077.7265625,
109
+ "high": 111302.3359375,
110
+ "low": 110955.71875,
111
+ "close": 111179.125,
112
+ "volume": 106.41625213623047,
113
+ "amount": 11760253.0
114
+ },
115
+ {
116
+ "timestamp": "2025-08-29T16:30:00+08:00",
117
+ "open": 111089.0859375,
118
+ "high": 111214.0234375,
119
+ "low": 110989.0625,
120
+ "close": 111124.0,
121
+ "volume": 68.92633056640625,
122
+ "amount": 7498789.0
123
+ },
124
+ {
125
+ "timestamp": "2025-08-29T16:45:00+08:00",
126
+ "open": 110984.625,
127
+ "high": 111356.890625,
128
+ "low": 110859.59375,
129
+ "close": 111248.921875,
130
+ "volume": 124.86672973632812,
131
+ "amount": 13508892.0
132
+ },
133
+ {
134
+ "timestamp": "2025-08-29T17:00:00+08:00",
135
+ "open": 111104.5703125,
136
+ "high": 111239.1875,
137
+ "low": 110994.875,
138
+ "close": 111135.6328125,
139
+ "volume": 69.62108612060547,
140
+ "amount": 7636843.0
141
+ },
142
+ {
143
+ "timestamp": "2025-08-29T17:15:00+08:00",
144
+ "open": 111193.140625,
145
+ "high": 111428.375,
146
+ "low": 111081.0,
147
+ "close": 111280.5234375,
148
+ "volume": 126.43584442138672,
149
+ "amount": 13772505.0
150
+ },
151
+ {
152
+ "timestamp": "2025-08-29T17:30:00+08:00",
153
+ "open": 111309.828125,
154
+ "high": 111541.59375,
155
+ "low": 111185.7578125,
156
+ "close": 111401.3125,
157
+ "volume": 123.78298950195312,
158
+ "amount": 13412482.0
159
+ },
160
+ {
161
+ "timestamp": "2025-08-29T17:45:00+08:00",
162
+ "open": 111806.9375,
163
+ "high": 112311.90625,
164
+ "low": 111424.1171875,
165
+ "close": 111659.2109375,
166
+ "volume": 139.4436798095703,
167
+ "amount": 15323338.0
168
+ },
169
+ {
170
+ "timestamp": "2025-08-29T18:00:00+08:00",
171
+ "open": 111639.109375,
172
+ "high": 111780.765625,
173
+ "low": 111386.4375,
174
+ "close": 111548.6875,
175
+ "volume": 148.95150756835938,
176
+ "amount": 16218812.0
177
+ },
178
+ {
179
+ "timestamp": "2025-08-29T18:15:00+08:00",
180
+ "open": 111710.59375,
181
+ "high": 111658.40625,
182
+ "low": 111286.703125,
183
+ "close": 111321.578125,
184
+ "volume": 100.94964599609375,
185
+ "amount": 11356062.0
186
+ },
187
+ {
188
+ "timestamp": "2025-08-29T18:30:00+08:00",
189
+ "open": 111373.3125,
190
+ "high": 111577.5546875,
191
+ "low": 111266.9765625,
192
+ "close": 111429.0390625,
193
+ "volume": 116.31037139892578,
194
+ "amount": 12787782.0
195
+ },
196
+ {
197
+ "timestamp": "2025-08-29T18:45:00+08:00",
198
+ "open": 111474.4921875,
199
+ "high": 111660.609375,
200
+ "low": 111365.328125,
201
+ "close": 111485.296875,
202
+ "volume": 71.23162841796875,
203
+ "amount": 7891943.0
204
+ },
205
+ {
206
+ "timestamp": "2025-08-29T19:00:00+08:00",
207
+ "open": 111475.9140625,
208
+ "high": 111648.7265625,
209
+ "low": 111353.3046875,
210
+ "close": 111510.1796875,
211
+ "volume": 95.99016571044922,
212
+ "amount": 10584742.0
213
+ },
214
+ {
215
+ "timestamp": "2025-08-29T19:15:00+08:00",
216
+ "open": 111467.125,
217
+ "high": 111612.3125,
218
+ "low": 111319.375,
219
+ "close": 111469.078125,
220
+ "volume": 92.43978881835938,
221
+ "amount": 10077935.0
222
+ },
223
+ {
224
+ "timestamp": "2025-08-29T19:30:00+08:00",
225
+ "open": 111579.0625,
226
+ "high": 111583.6875,
227
+ "low": 111324.40625,
228
+ "close": 111378.0703125,
229
+ "volume": 74.32500457763672,
230
+ "amount": 8576552.0
231
+ },
232
+ {
233
+ "timestamp": "2025-08-29T19:45:00+08:00",
234
+ "open": 111421.875,
235
+ "high": 111553.3671875,
236
+ "low": 111267.4921875,
237
+ "close": 111383.75,
238
+ "volume": 87.70850372314453,
239
+ "amount": 9725700.0
240
+ },
241
+ {
242
+ "timestamp": "2025-08-29T20:00:00+08:00",
243
+ "open": 111450.9609375,
244
+ "high": 111654.7109375,
245
+ "low": 111406.65625,
246
+ "close": 111571.953125,
247
+ "volume": 82.95088195800781,
248
+ "amount": 9009520.0
249
+ },
250
+ {
251
+ "timestamp": "2025-08-29T20:15:00+08:00",
252
+ "open": 111704.140625,
253
+ "high": 111806.5078125,
254
+ "low": 111532.9765625,
255
+ "close": 111625.3046875,
256
+ "volume": 62.82911682128906,
257
+ "amount": 6942181.0
258
+ },
259
+ {
260
+ "timestamp": "2025-08-29T20:30:00+08:00",
261
+ "open": 111683.0078125,
262
+ "high": 111835.5703125,
263
+ "low": 111585.109375,
264
+ "close": 111725.78125,
265
+ "volume": 88.10262298583984,
266
+ "amount": 9629783.0
267
+ },
268
+ {
269
+ "timestamp": "2025-08-29T20:45:00+08:00",
270
+ "open": 111672.40625,
271
+ "high": 111736.0859375,
272
+ "low": 111539.4765625,
273
+ "close": 111606.6171875,
274
+ "volume": 63.07331848144531,
275
+ "amount": 7014140.0
276
+ },
277
+ {
278
+ "timestamp": "2025-08-29T21:00:00+08:00",
279
+ "open": 111628.25,
280
+ "high": 111734.5703125,
281
+ "low": 111528.4453125,
282
+ "close": 111635.3828125,
283
+ "volume": 76.92945098876953,
284
+ "amount": 8487643.0
285
+ },
286
+ {
287
+ "timestamp": "2025-08-29T21:15:00+08:00",
288
+ "open": 111788.8046875,
289
+ "high": 111873.2265625,
290
+ "low": 111618.5234375,
291
+ "close": 111706.25,
292
+ "volume": 63.47200012207031,
293
+ "amount": 7041327.0
294
+ },
295
+ {
296
+ "timestamp": "2025-08-29T21:30:00+08:00",
297
+ "open": 111694.3828125,
298
+ "high": 111812.2734375,
299
+ "low": 111560.140625,
300
+ "close": 111667.34375,
301
+ "volume": 118.85958862304688,
302
+ "amount": 13174423.0
303
+ },
304
+ {
305
+ "timestamp": "2025-08-29T21:45:00+08:00",
306
+ "open": 111660.84375,
307
+ "high": 111736.3046875,
308
+ "low": 111542.3515625,
309
+ "close": 111613.125,
310
+ "volume": 66.44634246826172,
311
+ "amount": 7380835.0
312
+ },
313
+ {
314
+ "timestamp": "2025-08-29T22:00:00+08:00",
315
+ "open": 111611.671875,
316
+ "high": 111753.0,
317
+ "low": 111515.1796875,
318
+ "close": 111639.390625,
319
+ "volume": 117.2723388671875,
320
+ "amount": 13000749.0
321
+ },
322
+ {
323
+ "timestamp": "2025-08-29T22:15:00+08:00",
324
+ "open": 111548.84375,
325
+ "high": 111896.4375,
326
+ "low": 111464.296875,
327
+ "close": 111789.859375,
328
+ "volume": 117.73016357421875,
329
+ "amount": 12884928.0
330
+ },
331
+ {
332
+ "timestamp": "2025-08-29T22:30:00+08:00",
333
+ "open": 111776.890625,
334
+ "high": 111730.734375,
335
+ "low": 111468.46875,
336
+ "close": 111497.65625,
337
+ "volume": 106.01500701904297,
338
+ "amount": 12278978.0
339
+ },
340
+ {
341
+ "timestamp": "2025-08-29T22:45:00+08:00",
342
+ "open": 111485.265625,
343
+ "high": 111664.640625,
344
+ "low": 111365.3125,
345
+ "close": 111527.875,
346
+ "volume": 95.62970733642578,
347
+ "amount": 10423011.0
348
+ },
349
+ {
350
+ "timestamp": "2025-08-29T23:00:00+08:00",
351
+ "open": 111498.1640625,
352
+ "high": 111645.5234375,
353
+ "low": 111360.5546875,
354
+ "close": 111507.578125,
355
+ "volume": 92.1799087524414,
356
+ "amount": 10050062.0
357
+ },
358
+ {
359
+ "timestamp": "2025-08-29T23:15:00+08:00",
360
+ "open": 111642.765625,
361
+ "high": 111824.0,
362
+ "low": 111321.234375,
363
+ "close": 111405.5859375,
364
+ "volume": 158.8213653564453,
365
+ "amount": 17752150.0
366
+ },
367
+ {
368
+ "timestamp": "2025-08-29T23:30:00+08:00",
369
+ "open": 111522.359375,
370
+ "high": 111740.6484375,
371
+ "low": 111156.6328125,
372
+ "close": 111259.046875,
373
+ "volume": 166.03677368164062,
374
+ "amount": 18484528.0
375
+ },
376
+ {
377
+ "timestamp": "2025-08-29T23:45:00+08:00",
378
+ "open": 111239.0625,
379
+ "high": 111474.8828125,
380
+ "low": 111154.921875,
381
+ "close": 111369.359375,
382
+ "volume": 94.53020477294922,
383
+ "amount": 10369703.0
384
+ },
385
+ {
386
+ "timestamp": "2025-08-30T00:00:00+08:00",
387
+ "open": 111352.203125,
388
+ "high": 111583.1796875,
389
+ "low": 111202.46875,
390
+ "close": 111437.015625,
391
+ "volume": 212.87124633789062,
392
+ "amount": 23654354.0
393
+ },
394
+ {
395
+ "timestamp": "2025-08-30T00:15:00+08:00",
396
+ "open": 111412.140625,
397
+ "high": 111516.265625,
398
+ "low": 111201.3828125,
399
+ "close": 111324.140625,
400
+ "volume": 142.65975952148438,
401
+ "amount": 15808126.0
402
+ },
403
+ {
404
+ "timestamp": "2025-08-30T00:30:00+08:00",
405
+ "open": 111400.1875,
406
+ "high": 111569.53125,
407
+ "low": 111256.2265625,
408
+ "close": 111396.8359375,
409
+ "volume": 108.13775634765625,
410
+ "amount": 11788523.0
411
+ },
412
+ {
413
+ "timestamp": "2025-08-30T00:45:00+08:00",
414
+ "open": 111395.734375,
415
+ "high": 111568.5703125,
416
+ "low": 111188.984375,
417
+ "close": 111384.4140625,
418
+ "volume": 62.96758270263672,
419
+ "amount": 7546139.0
420
+ },
421
+ {
422
+ "timestamp": "2025-08-30T01:00:00+08:00",
423
+ "open": 111406.9296875,
424
+ "high": 111587.65625,
425
+ "low": 111283.796875,
426
+ "close": 111462.921875,
427
+ "volume": 137.7883758544922,
428
+ "amount": 15157422.0
429
+ },
430
+ {
431
+ "timestamp": "2025-08-30T01:15:00+08:00",
432
+ "open": 111458.4453125,
433
+ "high": 111513.3359375,
434
+ "low": 111148.125,
435
+ "close": 111252.4140625,
436
+ "volume": 121.01518249511719,
437
+ "amount": 13389022.0
438
+ },
439
+ {
440
+ "timestamp": "2025-08-30T01:30:00+08:00",
441
+ "open": 111255.6640625,
442
+ "high": 111435.0703125,
443
+ "low": 111158.890625,
444
+ "close": 111313.296875,
445
+ "volume": 79.61592864990234,
446
+ "amount": 8713377.0
447
+ },
448
+ {
449
+ "timestamp": "2025-08-30T01:45:00+08:00",
450
+ "open": 111379.46875,
451
+ "high": 111572.53125,
452
+ "low": 111265.3203125,
453
+ "close": 111417.7109375,
454
+ "volume": 62.886993408203125,
455
+ "amount": 7012918.0
456
+ },
457
+ {
458
+ "timestamp": "2025-08-30T02:00:00+08:00",
459
+ "open": 111602.8515625,
460
+ "high": 111522.2578125,
461
+ "low": 111240.671875,
462
+ "close": 111260.25,
463
+ "volume": 81.55489349365234,
464
+ "amount": 9592672.0
465
+ },
466
+ {
467
+ "timestamp": "2025-08-30T02:15:00+08:00",
468
+ "open": 111423.7265625,
469
+ "high": 111425.953125,
470
+ "low": 111084.0234375,
471
+ "close": 111178.9765625,
472
+ "volume": 114.49605560302734,
473
+ "amount": 12567647.0
474
+ },
475
+ {
476
+ "timestamp": "2025-08-30T02:30:00+08:00",
477
+ "open": 111168.109375,
478
+ "high": 111316.1953125,
479
+ "low": 110965.4296875,
480
+ "close": 111112.0078125,
481
+ "volume": 152.15391540527344,
482
+ "amount": 16635125.0
483
+ },
484
+ {
485
+ "timestamp": "2025-08-30T02:45:00+08:00",
486
+ "open": 111271.6953125,
487
+ "high": 111295.9921875,
488
+ "low": 110945.421875,
489
+ "close": 110998.375,
490
+ "volume": 104.71627044677734,
491
+ "amount": 11526440.0
492
+ },
493
+ {
494
+ "timestamp": "2025-08-30T03:00:00+08:00",
495
+ "open": 111188.0390625,
496
+ "high": 111354.46875,
497
+ "low": 110829.703125,
498
+ "close": 110948.078125,
499
+ "volume": 198.8612518310547,
500
+ "amount": 21980518.0
501
+ },
502
+ {
503
+ "timestamp": "2025-08-30T03:15:00+08:00",
504
+ "open": 111046.65625,
505
+ "high": 111285.4765625,
506
+ "low": 110955.609375,
507
+ "close": 111169.65625,
508
+ "volume": 78.87939453125,
509
+ "amount": 8709723.0
510
+ },
511
+ {
512
+ "timestamp": "2025-08-30T03:30:00+08:00",
513
+ "open": 111305.7109375,
514
+ "high": 111389.1484375,
515
+ "low": 110939.3203125,
516
+ "close": 110998.0703125,
517
+ "volume": 76.06775665283203,
518
+ "amount": 8735864.0
519
+ },
520
+ {
521
+ "timestamp": "2025-08-30T03:45:00+08:00",
522
+ "open": 111046.5078125,
523
+ "high": 111175.2421875,
524
+ "low": 110940.5078125,
525
+ "close": 111065.453125,
526
+ "volume": 72.09185791015625,
527
+ "amount": 8154678.0
528
+ },
529
+ {
530
+ "timestamp": "2025-08-30T04:00:00+08:00",
531
+ "open": 111200.796875,
532
+ "high": 111230.2265625,
533
+ "low": 110947.1640625,
534
+ "close": 111034.1875,
535
+ "volume": 58.83280944824219,
536
+ "amount": 6855019.0
537
+ },
538
+ {
539
+ "timestamp": "2025-08-30T04:15:00+08:00",
540
+ "open": 111298.2734375,
541
+ "high": 111350.6875,
542
+ "low": 110913.875,
543
+ "close": 110961.2734375,
544
+ "volume": 71.72576904296875,
545
+ "amount": 8369619.0
546
+ },
547
+ {
548
+ "timestamp": "2025-08-30T04:30:00+08:00",
549
+ "open": 111184.7265625,
550
+ "high": 111339.1796875,
551
+ "low": 111071.125,
552
+ "close": 111272.921875,
553
+ "volume": 80.84431457519531,
554
+ "amount": 9332349.0
555
+ },
556
+ {
557
+ "timestamp": "2025-08-30T04:45:00+08:00",
558
+ "open": 111137.078125,
559
+ "high": 111276.15625,
560
+ "low": 111081.3984375,
561
+ "close": 111169.453125,
562
+ "volume": 50.87566375732422,
563
+ "amount": 5981040.0
564
+ },
565
+ {
566
+ "timestamp": "2025-08-30T05:00:00+08:00",
567
+ "open": 111146.21875,
568
+ "high": 111289.640625,
569
+ "low": 111074.0,
570
+ "close": 111205.7890625,
571
+ "volume": 62.981712341308594,
572
+ "amount": 7147150.0
573
+ },
574
+ {
575
+ "timestamp": "2025-08-30T05:15:00+08:00",
576
+ "open": 111189.3359375,
577
+ "high": 111331.0078125,
578
+ "low": 111096.0078125,
579
+ "close": 111216.2578125,
580
+ "volume": 88.78456115722656,
581
+ "amount": 9649521.0
582
+ },
583
+ {
584
+ "timestamp": "2025-08-30T05:30:00+08:00",
585
+ "open": 111248.21875,
586
+ "high": 111398.6640625,
587
+ "low": 111152.5,
588
+ "close": 111276.7265625,
589
+ "volume": 105.08946228027344,
590
+ "amount": 11606438.0
591
+ },
592
+ {
593
+ "timestamp": "2025-08-30T05:45:00+08:00",
594
+ "open": 111323.9296875,
595
+ "high": 111515.6875,
596
+ "low": 111232.875,
597
+ "close": 111386.34375,
598
+ "volume": 111.58527374267578,
599
+ "amount": 12095142.0
600
+ },
601
+ {
602
+ "timestamp": "2025-08-30T06:00:00+08:00",
603
+ "open": 111330.3984375,
604
+ "high": 111404.796875,
605
+ "low": 111099.1015625,
606
+ "close": 111189.7578125,
607
+ "volume": 138.23782348632812,
608
+ "amount": 15181994.0
609
+ },
610
+ {
611
+ "timestamp": "2025-08-30T06:15:00+08:00",
612
+ "open": 111208.2109375,
613
+ "high": 111355.484375,
614
+ "low": 111119.1953125,
615
+ "close": 111242.671875,
616
+ "volume": 75.48944854736328,
617
+ "amount": 8307290.0
618
+ },
619
+ {
620
+ "timestamp": "2025-08-30T06:30:00+08:00",
621
+ "open": 111203.984375,
622
+ "high": 111348.0859375,
623
+ "low": 111128.1015625,
624
+ "close": 111248.0859375,
625
+ "volume": 68.8346939086914,
626
+ "amount": 7675256.0
627
+ },
628
+ {
629
+ "timestamp": "2025-08-30T06:45:00+08:00",
630
+ "open": 111149.890625,
631
+ "high": 111254.7265625,
632
+ "low": 111073.734375,
633
+ "close": 111187.6328125,
634
+ "volume": 60.28900146484375,
635
+ "amount": 6712586.0
636
+ },
637
+ {
638
+ "timestamp": "2025-08-30T07:00:00+08:00",
639
+ "open": 111281.0,
640
+ "high": 111334.4140625,
641
+ "low": 111057.453125,
642
+ "close": 111196.4140625,
643
+ "volume": 78.940673828125,
644
+ "amount": 8958955.0
645
+ },
646
+ {
647
+ "timestamp": "2025-08-30T07:15:00+08:00",
648
+ "open": 111443.6171875,
649
+ "high": 111337.5859375,
650
+ "low": 111000.703125,
651
+ "close": 111027.3984375,
652
+ "volume": 93.67547607421875,
653
+ "amount": 10425298.0
654
+ },
655
+ {
656
+ "timestamp": "2025-08-30T07:30:00+08:00",
657
+ "open": 111074.453125,
658
+ "high": 111263.03125,
659
+ "low": 111003.2421875,
660
+ "close": 111170.5234375,
661
+ "volume": 71.69232940673828,
662
+ "amount": 7894782.0
663
+ },
664
+ {
665
+ "timestamp": "2025-08-30T07:45:00+08:00",
666
+ "open": 111064.8828125,
667
+ "high": 111130.5078125,
668
+ "low": 110878.1875,
669
+ "close": 110962.265625,
670
+ "volume": 98.40040588378906,
671
+ "amount": 10814296.0
672
+ },
673
+ {
674
+ "timestamp": "2025-08-30T08:00:00+08:00",
675
+ "open": 110991.0078125,
676
+ "high": 111117.1015625,
677
+ "low": 110826.4609375,
678
+ "close": 110969.5859375,
679
+ "volume": 127.24305725097656,
680
+ "amount": 13824850.0
681
+ },
682
+ {
683
+ "timestamp": "2025-08-30T08:15:00+08:00",
684
+ "open": 110994.9609375,
685
+ "high": 111071.3125,
686
+ "low": 110919.9765625,
687
+ "close": 110983.1171875,
688
+ "volume": 57.98933410644531,
689
+ "amount": 6384177.0
690
+ },
691
+ {
692
+ "timestamp": "2025-08-30T08:30:00+08:00",
693
+ "open": 110996.9921875,
694
+ "high": 111095.3203125,
695
+ "low": 110909.4375,
696
+ "close": 111008.5703125,
697
+ "volume": 65.76761627197266,
698
+ "amount": 7413650.0
699
+ },
700
+ {
701
+ "timestamp": "2025-08-30T08:45:00+08:00",
702
+ "open": 110994.78125,
703
+ "high": 111086.03125,
704
+ "low": 110901.421875,
705
+ "close": 110998.9453125,
706
+ "volume": 66.78579711914062,
707
+ "amount": 7532935.0
708
+ },
709
+ {
710
+ "timestamp": "2025-08-30T09:00:00+08:00",
711
+ "open": 110868.3125,
712
+ "high": 111005.109375,
713
+ "low": 110722.5234375,
714
+ "close": 110864.375,
715
+ "volume": 89.55391693115234,
716
+ "amount": 9613289.0
717
+ },
718
+ {
719
+ "timestamp": "2025-08-30T09:15:00+08:00",
720
+ "open": 111109.953125,
721
+ "high": 111155.0390625,
722
+ "low": 110744.25,
723
+ "close": 110791.71875,
724
+ "volume": 81.81380462646484,
725
+ "amount": 9516021.0
726
+ },
727
+ {
728
+ "timestamp": "2025-08-30T09:30:00+08:00",
729
+ "open": 110878.703125,
730
+ "high": 110999.453125,
731
+ "low": 110786.625,
732
+ "close": 110907.1953125,
733
+ "volume": 66.76164245605469,
734
+ "amount": 7531565.0
735
+ },
736
+ {
737
+ "timestamp": "2025-08-30T09:45:00+08:00",
738
+ "open": 110905.5859375,
739
+ "high": 111014.9765625,
740
+ "low": 110812.3203125,
741
+ "close": 110928.3984375,
742
+ "volume": 64.68898010253906,
743
+ "amount": 7343935.0
744
+ },
745
+ {
746
+ "timestamp": "2025-08-30T10:00:00+08:00",
747
+ "open": 110908.890625,
748
+ "high": 111054.390625,
749
+ "low": 110804.765625,
750
+ "close": 110956.7265625,
751
+ "volume": 89.25154876708984,
752
+ "amount": 9904305.0
753
+ },
754
+ {
755
+ "timestamp": "2025-08-30T10:15:00+08:00",
756
+ "open": 110964.859375,
757
+ "high": 111038.703125,
758
+ "low": 110882.09375,
759
+ "close": 110939.984375,
760
+ "volume": 53.86793518066406,
761
+ "amount": 6138050.0
762
+ },
763
+ {
764
+ "timestamp": "2025-08-30T10:30:00+08:00",
765
+ "open": 111180.3515625,
766
+ "high": 111243.3359375,
767
+ "low": 110826.78125,
768
+ "close": 110872.359375,
769
+ "volume": 69.9632797241211,
770
+ "amount": 8204932.0
771
+ },
772
+ {
773
+ "timestamp": "2025-08-30T10:45:00+08:00",
774
+ "open": 111078.0078125,
775
+ "high": 111255.7734375,
776
+ "low": 110944.671875,
777
+ "close": 111095.2578125,
778
+ "volume": 85.97515106201172,
779
+ "amount": 9346369.0
780
+ },
781
+ {
782
+ "timestamp": "2025-08-30T11:00:00+08:00",
783
+ "open": 111070.4921875,
784
+ "high": 111222.1796875,
785
+ "low": 110985.1015625,
786
+ "close": 111117.421875,
787
+ "volume": 67.38510131835938,
788
+ "amount": 7617978.0
789
+ },
790
+ {
791
+ "timestamp": "2025-08-30T11:15:00+08:00",
792
+ "open": 111142.640625,
793
+ "high": 111293.6640625,
794
+ "low": 110922.6640625,
795
+ "close": 111123.4921875,
796
+ "volume": 52.77381896972656,
797
+ "amount": 6502052.0
798
+ },
799
+ {
800
+ "timestamp": "2025-08-30T11:30:00+08:00",
801
+ "open": 111001.75,
802
+ "high": 111129.828125,
803
+ "low": 110914.2265625,
804
+ "close": 111010.484375,
805
+ "volume": 73.64842224121094,
806
+ "amount": 8380469.0
807
+ },
808
+ {
809
+ "timestamp": "2025-08-30T11:45:00+08:00",
810
+ "open": 110982.8125,
811
+ "high": 111070.375,
812
+ "low": 110928.6484375,
813
+ "close": 110997.75,
814
+ "volume": 49.78855895996094,
815
+ "amount": 5833820.0
816
+ },
817
+ {
818
+ "timestamp": "2025-08-30T12:00:00+08:00",
819
+ "open": 110996.421875,
820
+ "high": 111005.6875,
821
+ "low": 110855.921875,
822
+ "close": 110899.25,
823
+ "volume": 63.615753173828125,
824
+ "amount": 7277021.0
825
+ },
826
+ {
827
+ "timestamp": "2025-08-30T12:15:00+08:00",
828
+ "open": 110929.8515625,
829
+ "high": 111037.703125,
830
+ "low": 110848.328125,
831
+ "close": 110964.484375,
832
+ "volume": 63.891075134277344,
833
+ "amount": 7312494.0
834
+ },
835
+ {
836
+ "timestamp": "2025-08-30T12:30:00+08:00",
837
+ "open": 110853.8203125,
838
+ "high": 110985.0,
839
+ "low": 110792.171875,
840
+ "close": 110900.03125,
841
+ "volume": 68.45826721191406,
842
+ "amount": 7849445.0
843
+ },
844
+ {
845
+ "timestamp": "2025-08-30T12:45:00+08:00",
846
+ "open": 111015.1484375,
847
+ "high": 110955.515625,
848
+ "low": 110751.078125,
849
+ "close": 110813.703125,
850
+ "volume": 75.043701171875,
851
+ "amount": 7848931.0
852
+ },
853
+ {
854
+ "timestamp": "2025-08-30T13:00:00+08:00",
855
+ "open": 110887.0703125,
856
+ "high": 110912.3515625,
857
+ "low": 110747.8671875,
858
+ "close": 110803.015625,
859
+ "volume": 66.48946380615234,
860
+ "amount": 7494755.0
861
+ },
862
+ {
863
+ "timestamp": "2025-08-30T13:15:00+08:00",
864
+ "open": 110844.734375,
865
+ "high": 110979.796875,
866
+ "low": 110708.3359375,
867
+ "close": 110928.40625,
868
+ "volume": 66.75776672363281,
869
+ "amount": 7387242.0
870
+ },
871
+ {
872
+ "timestamp": "2025-08-30T13:30:00+08:00",
873
+ "open": 110775.0,
874
+ "high": 110924.09375,
875
+ "low": 110717.328125,
876
+ "close": 110830.84375,
877
+ "volume": 70.78501892089844,
878
+ "amount": 7972145.0
879
+ },
880
+ {
881
+ "timestamp": "2025-08-30T13:45:00+08:00",
882
+ "open": 110833.28125,
883
+ "high": 110947.5390625,
884
+ "low": 110763.578125,
885
+ "close": 110875.84375,
886
+ "volume": 63.871124267578125,
887
+ "amount": 7286225.0
888
+ },
889
+ {
890
+ "timestamp": "2025-08-30T14:00:00+08:00",
891
+ "open": 111067.2734375,
892
+ "high": 111097.4609375,
893
+ "low": 110724.8984375,
894
+ "close": 110760.6875,
895
+ "volume": 75.15328979492188,
896
+ "amount": 8855330.0
897
+ },
898
+ {
899
+ "timestamp": "2025-08-30T14:15:00+08:00",
900
+ "open": 110825.8828125,
901
+ "high": 110946.3984375,
902
+ "low": 110743.375,
903
+ "close": 110870.3828125,
904
+ "volume": 64.47406005859375,
905
+ "amount": 7334688.0
906
+ },
907
+ {
908
+ "timestamp": "2025-08-30T14:30:00+08:00",
909
+ "open": 110851.4375,
910
+ "high": 110960.671875,
911
+ "low": 110774.8203125,
912
+ "close": 110891.5859375,
913
+ "volume": 62.37579345703125,
914
+ "amount": 7147503.0
915
+ },
916
+ {
917
+ "timestamp": "2025-08-30T14:45:00+08:00",
918
+ "open": 111086.1484375,
919
+ "high": 111111.4140625,
920
+ "low": 110732.9453125,
921
+ "close": 110762.1640625,
922
+ "volume": 74.91941833496094,
923
+ "amount": 8832942.0
924
+ },
925
+ {
926
+ "timestamp": "2025-08-30T15:00:00+08:00",
927
+ "open": 110826.671875,
928
+ "high": 110946.5390625,
929
+ "low": 110743.2734375,
930
+ "close": 110867.84375,
931
+ "volume": 64.68904113769531,
932
+ "amount": 7379103.0
933
+ },
934
+ {
935
+ "timestamp": "2025-08-30T15:15:00+08:00",
936
+ "open": 110845.203125,
937
+ "high": 110956.1015625,
938
+ "low": 110766.65625,
939
+ "close": 110883.2578125,
940
+ "volume": 62.80986022949219,
941
+ "amount": 7212651.0
942
+ },
943
+ {
944
+ "timestamp": "2025-08-30T15:30:00+08:00",
945
+ "open": 110774.6328125,
946
+ "high": 110912.4375,
947
+ "low": 110717.5859375,
948
+ "close": 110837.96875,
949
+ "volume": 68.65061950683594,
950
+ "amount": 7879980.0
951
+ },
952
+ {
953
+ "timestamp": "2025-08-30T15:45:00+08:00",
954
+ "open": 110752.3046875,
955
+ "high": 110891.3828125,
956
+ "low": 110698.609375,
957
+ "close": 110820.7421875,
958
+ "volume": 68.49166107177734,
959
+ "amount": 7869639.0
960
+ },
961
+ {
962
+ "timestamp": "2025-08-30T16:00:00+08:00",
963
+ "open": 110910.8671875,
964
+ "high": 110867.8828125,
965
+ "low": 110657.7109375,
966
+ "close": 110741.84375,
967
+ "volume": 75.15116119384766,
968
+ "amount": 7797491.0
969
+ },
970
+ {
971
+ "timestamp": "2025-08-30T16:15:00+08:00",
972
+ "open": 110678.7890625,
973
+ "high": 110852.3125,
974
+ "low": 110629.0078125,
975
+ "close": 110770.859375,
976
+ "volume": 71.22074890136719,
977
+ "amount": 8026450.0
978
+ },
979
+ {
980
+ "timestamp": "2025-08-30T16:30:00+08:00",
981
+ "open": 110977.21875,
982
+ "high": 111027.8359375,
983
+ "low": 110648.453125,
984
+ "close": 110694.2421875,
985
+ "volume": 74.5619888305664,
986
+ "amount": 8765571.0
987
+ },
988
+ {
989
+ "timestamp": "2025-08-30T16:45:00+08:00",
990
+ "open": 110753.90625,
991
+ "high": 110884.296875,
992
+ "low": 110679.0390625,
993
+ "close": 110808.078125,
994
+ "volume": 65.1622314453125,
995
+ "amount": 7421333.0
996
+ },
997
+ {
998
+ "timestamp": "2025-08-30T17:00:00+08:00",
999
+ "open": 111011.8515625,
1000
+ "high": 111050.7890625,
1001
+ "low": 110662.1796875,
1002
+ "close": 110702.8515625,
1003
+ "volume": 75.08160400390625,
1004
+ "amount": 8876836.0
1005
+ },
1006
+ {
1007
+ "timestamp": "2025-08-30T17:15:00+08:00",
1008
+ "open": 110804.1875,
1009
+ "high": 110993.1328125,
1010
+ "low": 110669.8125,
1011
+ "close": 110865.9296875,
1012
+ "volume": 105.89447021484375,
1013
+ "amount": 11376246.0
1014
+ },
1015
+ {
1016
+ "timestamp": "2025-08-30T17:30:00+08:00",
1017
+ "open": 110987.3984375,
1018
+ "high": 111073.7421875,
1019
+ "low": 110757.609375,
1020
+ "close": 110928.6953125,
1021
+ "volume": 78.04934692382812,
1022
+ "amount": 8805081.0
1023
+ },
1024
+ {
1025
+ "timestamp": "2025-08-30T17:45:00+08:00",
1026
+ "open": 110913.5390625,
1027
+ "high": 111018.328125,
1028
+ "low": 110806.9609375,
1029
+ "close": 110912.1171875,
1030
+ "volume": 69.97149658203125,
1031
+ "amount": 7867074.0
1032
+ },
1033
+ {
1034
+ "timestamp": "2025-08-30T18:00:00+08:00",
1035
+ "open": 110883.9140625,
1036
+ "high": 111017.6328125,
1037
+ "low": 110724.890625,
1038
+ "close": 110871.0234375,
1039
+ "volume": 137.30715942382812,
1040
+ "amount": 14961190.0
1041
+ },
1042
+ {
1043
+ "timestamp": "2025-08-30T18:15:00+08:00",
1044
+ "open": 110785.1328125,
1045
+ "high": 111097.7265625,
1046
+ "low": 110732.7421875,
1047
+ "close": 111020.8203125,
1048
+ "volume": 80.94500732421875,
1049
+ "amount": 8915283.0
1050
+ },
1051
+ {
1052
+ "timestamp": "2025-08-30T18:30:00+08:00",
1053
+ "open": 110945.2890625,
1054
+ "high": 111135.4140625,
1055
+ "low": 110863.984375,
1056
+ "close": 111046.390625,
1057
+ "volume": 84.47595977783203,
1058
+ "amount": 9454623.0
1059
+ },
1060
+ {
1061
+ "timestamp": "2025-08-30T18:45:00+08:00",
1062
+ "open": 111020.5078125,
1063
+ "high": 111117.5234375,
1064
+ "low": 110903.8359375,
1065
+ "close": 110997.609375,
1066
+ "volume": 80.08727264404297,
1067
+ "amount": 9038030.0
1068
+ },
1069
+ {
1070
+ "timestamp": "2025-08-30T19:00:00+08:00",
1071
+ "open": 111046.0703125,
1072
+ "high": 111251.0234375,
1073
+ "low": 110897.7421875,
1074
+ "close": 111167.0,
1075
+ "volume": 92.00077056884766,
1076
+ "amount": 10341724.0
1077
+ },
1078
+ {
1079
+ "timestamp": "2025-08-30T19:15:00+08:00",
1080
+ "open": 111134.3515625,
1081
+ "high": 111302.265625,
1082
+ "low": 111040.1640625,
1083
+ "close": 111166.890625,
1084
+ "volume": 107.83051300048828,
1085
+ "amount": 11930536.0
1086
+ },
1087
+ {
1088
+ "timestamp": "2025-08-30T19:30:00+08:00",
1089
+ "open": 111245.265625,
1090
+ "high": 111351.8671875,
1091
+ "low": 111086.3828125,
1092
+ "close": 111214.5390625,
1093
+ "volume": 86.44621276855469,
1094
+ "amount": 9522093.0
1095
+ },
1096
+ {
1097
+ "timestamp": "2025-08-30T19:45:00+08:00",
1098
+ "open": 111218.578125,
1099
+ "high": 111397.09375,
1100
+ "low": 111111.78125,
1101
+ "close": 111279.8671875,
1102
+ "volume": 131.67941284179688,
1103
+ "amount": 14411454.0
1104
+ },
1105
+ {
1106
+ "timestamp": "2025-08-30T20:00:00+08:00",
1107
+ "open": 111295.90625,
1108
+ "high": 111435.515625,
1109
+ "low": 111150.9765625,
1110
+ "close": 111280.5390625,
1111
+ "volume": 114.0282211303711,
1112
+ "amount": 12461344.0
1113
+ },
1114
+ {
1115
+ "timestamp": "2025-08-30T20:15:00+08:00",
1116
+ "open": 111325.8125,
1117
+ "high": 111426.296875,
1118
+ "low": 111154.25,
1119
+ "close": 111243.4921875,
1120
+ "volume": 89.13931274414062,
1121
+ "amount": 9991889.0
1122
+ },
1123
+ {
1124
+ "timestamp": "2025-08-30T20:30:00+08:00",
1125
+ "open": 111194.6328125,
1126
+ "high": 111269.7734375,
1127
+ "low": 111033.0546875,
1128
+ "close": 111162.5078125,
1129
+ "volume": 78.17929077148438,
1130
+ "amount": 8710262.0
1131
+ }
1132
+ ],
1133
+ "actual_data": [],
1134
+ "analysis": {}
1135
+ }
webui/prediction_results/prediction_20250829_145631.json ADDED
@@ -0,0 +1,1135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "timestamp": "2025-08-29T14:56:31.758230",
3
+ "file_path": "BTCUSDT_15m",
4
+ "prediction_type": "Kronos model prediction (latest data)",
5
+ "prediction_params": {
6
+ "symbol": "BTCUSDT",
7
+ "interval": "15m",
8
+ "limit": 1000,
9
+ "lookback": 1000,
10
+ "pred_len": 120,
11
+ "temperature": 1.0,
12
+ "top_p": 0.9,
13
+ "sample_count": 12,
14
+ "start_date": "latest"
15
+ },
16
+ "input_data_summary": {
17
+ "rows": 1000,
18
+ "columns": [
19
+ "open",
20
+ "high",
21
+ "low",
22
+ "close",
23
+ "volume",
24
+ "amount"
25
+ ],
26
+ "price_range": {
27
+ "open": {
28
+ "min": 109100.24,
29
+ "max": 117410.0
30
+ },
31
+ "high": {
32
+ "min": 109580.0,
33
+ "max": 117429.05
34
+ },
35
+ "low": {
36
+ "min": 108666.66,
37
+ "max": 117024.0
38
+ },
39
+ "close": {
40
+ "min": 109100.23,
41
+ "max": 117410.0
42
+ }
43
+ },
44
+ "last_values": {
45
+ "open": 111245.69,
46
+ "high": 111246.09,
47
+ "low": 111221.98,
48
+ "close": 111221.98
49
+ }
50
+ },
51
+ "prediction_results": [
52
+ {
53
+ "timestamp": "2025-08-29T15:00:00+08:00",
54
+ "open": 111169.4765625,
55
+ "high": 111286.6640625,
56
+ "low": 110882.9609375,
57
+ "close": 111017.2109375,
58
+ "volume": 133.6641387939453,
59
+ "amount": 14748266.0
60
+ },
61
+ {
62
+ "timestamp": "2025-08-29T15:15:00+08:00",
63
+ "open": 111093.3671875,
64
+ "high": 111210.0859375,
65
+ "low": 110862.734375,
66
+ "close": 110999.046875,
67
+ "volume": 126.7567138671875,
68
+ "amount": 13991243.0
69
+ },
70
+ {
71
+ "timestamp": "2025-08-29T15:30:00+08:00",
72
+ "open": 111040.875,
73
+ "high": 111257.1796875,
74
+ "low": 110860.765625,
75
+ "close": 111082.9921875,
76
+ "volume": 145.006591796875,
77
+ "amount": 15980576.0
78
+ },
79
+ {
80
+ "timestamp": "2025-08-29T15:45:00+08:00",
81
+ "open": 111099.1875,
82
+ "high": 111268.6484375,
83
+ "low": 110866.734375,
84
+ "close": 111056.4765625,
85
+ "volume": 134.9705047607422,
86
+ "amount": 14906833.0
87
+ },
88
+ {
89
+ "timestamp": "2025-08-29T16:00:00+08:00",
90
+ "open": 111123.6796875,
91
+ "high": 111281.125,
92
+ "low": 110875.1796875,
93
+ "close": 111063.046875,
94
+ "volume": 164.16329956054688,
95
+ "amount": 17778158.0
96
+ },
97
+ {
98
+ "timestamp": "2025-08-29T16:15:00+08:00",
99
+ "open": 111086.90625,
100
+ "high": 111265.375,
101
+ "low": 110925.2578125,
102
+ "close": 111095.921875,
103
+ "volume": 113.75747680664062,
104
+ "amount": 12440173.0
105
+ },
106
+ {
107
+ "timestamp": "2025-08-29T16:30:00+08:00",
108
+ "open": 111235.6640625,
109
+ "high": 111391.5390625,
110
+ "low": 110984.625,
111
+ "close": 111131.421875,
112
+ "volume": 109.91775512695312,
113
+ "amount": 12183982.0
114
+ },
115
+ {
116
+ "timestamp": "2025-08-29T16:45:00+08:00",
117
+ "open": 111174.734375,
118
+ "high": 111321.5390625,
119
+ "low": 110994.046875,
120
+ "close": 111141.2890625,
121
+ "volume": 97.423095703125,
122
+ "amount": 10803830.0
123
+ },
124
+ {
125
+ "timestamp": "2025-08-29T17:00:00+08:00",
126
+ "open": 111238.4453125,
127
+ "high": 111352.1171875,
128
+ "low": 111004.296875,
129
+ "close": 111139.5234375,
130
+ "volume": 105.70687866210938,
131
+ "amount": 11692542.0
132
+ },
133
+ {
134
+ "timestamp": "2025-08-29T17:15:00+08:00",
135
+ "open": 111214.609375,
136
+ "high": 111364.3671875,
137
+ "low": 111043.34375,
138
+ "close": 111206.6328125,
139
+ "volume": 102.69979095458984,
140
+ "amount": 11316412.0
141
+ },
142
+ {
143
+ "timestamp": "2025-08-29T17:30:00+08:00",
144
+ "open": 111237.984375,
145
+ "high": 111420.6640625,
146
+ "low": 111090.375,
147
+ "close": 111253.3125,
148
+ "volume": 110.2011489868164,
149
+ "amount": 12105284.0
150
+ },
151
+ {
152
+ "timestamp": "2025-08-29T17:45:00+08:00",
153
+ "open": 111270.828125,
154
+ "high": 111402.953125,
155
+ "low": 111143.3125,
156
+ "close": 111269.484375,
157
+ "volume": 93.22903442382812,
158
+ "amount": 10318237.0
159
+ },
160
+ {
161
+ "timestamp": "2025-08-29T18:00:00+08:00",
162
+ "open": 111266.0390625,
163
+ "high": 111480.8828125,
164
+ "low": 111111.5859375,
165
+ "close": 111340.1875,
166
+ "volume": 116.34564971923828,
167
+ "amount": 12560659.0
168
+ },
169
+ {
170
+ "timestamp": "2025-08-29T18:15:00+08:00",
171
+ "open": 111337.7265625,
172
+ "high": 111505.6015625,
173
+ "low": 111196.328125,
174
+ "close": 111353.4140625,
175
+ "volume": 95.64814758300781,
176
+ "amount": 10498123.0
177
+ },
178
+ {
179
+ "timestamp": "2025-08-29T18:30:00+08:00",
180
+ "open": 111431.0625,
181
+ "high": 111531.34375,
182
+ "low": 111202.6875,
183
+ "close": 111307.6484375,
184
+ "volume": 116.13081359863281,
185
+ "amount": 12837304.0
186
+ },
187
+ {
188
+ "timestamp": "2025-08-29T18:45:00+08:00",
189
+ "open": 111382.796875,
190
+ "high": 111552.734375,
191
+ "low": 111208.2734375,
192
+ "close": 111377.6796875,
193
+ "volume": 105.46437072753906,
194
+ "amount": 11618260.0
195
+ },
196
+ {
197
+ "timestamp": "2025-08-29T19:00:00+08:00",
198
+ "open": 111442.6796875,
199
+ "high": 111582.515625,
200
+ "low": 111269.0625,
201
+ "close": 111414.59375,
202
+ "volume": 89.62226867675781,
203
+ "amount": 9996248.0
204
+ },
205
+ {
206
+ "timestamp": "2025-08-29T19:15:00+08:00",
207
+ "open": 111442.640625,
208
+ "high": 111603.28125,
209
+ "low": 111299.03125,
210
+ "close": 111441.359375,
211
+ "volume": 88.33848571777344,
212
+ "amount": 9741673.0
213
+ },
214
+ {
215
+ "timestamp": "2025-08-29T19:30:00+08:00",
216
+ "open": 111508.421875,
217
+ "high": 111696.1171875,
218
+ "low": 111364.078125,
219
+ "close": 111553.671875,
220
+ "volume": 114.33439636230469,
221
+ "amount": 12555341.0
222
+ },
223
+ {
224
+ "timestamp": "2025-08-29T19:45:00+08:00",
225
+ "open": 111602.21875,
226
+ "high": 111801.7734375,
227
+ "low": 111454.265625,
228
+ "close": 111627.0703125,
229
+ "volume": 102.29329681396484,
230
+ "amount": 11272232.0
231
+ },
232
+ {
233
+ "timestamp": "2025-08-29T20:00:00+08:00",
234
+ "open": 111652.2265625,
235
+ "high": 111782.796875,
236
+ "low": 111488.9375,
237
+ "close": 111626.5,
238
+ "volume": 110.90338134765625,
239
+ "amount": 12250775.0
240
+ },
241
+ {
242
+ "timestamp": "2025-08-29T20:15:00+08:00",
243
+ "open": 111661.375,
244
+ "high": 111839.46875,
245
+ "low": 111522.984375,
246
+ "close": 111695.3203125,
247
+ "volume": 105.9512710571289,
248
+ "amount": 11719609.0
249
+ },
250
+ {
251
+ "timestamp": "2025-08-29T20:30:00+08:00",
252
+ "open": 111711.1328125,
253
+ "high": 111839.234375,
254
+ "low": 111548.765625,
255
+ "close": 111687.9296875,
256
+ "volume": 121.10868835449219,
257
+ "amount": 13405922.0
258
+ },
259
+ {
260
+ "timestamp": "2025-08-29T20:45:00+08:00",
261
+ "open": 111704.6875,
262
+ "high": 111814.9921875,
263
+ "low": 111504.6796875,
264
+ "close": 111603.9765625,
265
+ "volume": 99.18999481201172,
266
+ "amount": 11010030.0
267
+ },
268
+ {
269
+ "timestamp": "2025-08-29T21:00:00+08:00",
270
+ "open": 111686.125,
271
+ "high": 111873.609375,
272
+ "low": 111489.6953125,
273
+ "close": 111669.3203125,
274
+ "volume": 134.42730712890625,
275
+ "amount": 14908210.0
276
+ },
277
+ {
278
+ "timestamp": "2025-08-29T21:15:00+08:00",
279
+ "open": 111712.0390625,
280
+ "high": 111954.4453125,
281
+ "low": 111570.4140625,
282
+ "close": 111808.0859375,
283
+ "volume": 126.19930267333984,
284
+ "amount": 13898752.0
285
+ },
286
+ {
287
+ "timestamp": "2025-08-29T21:30:00+08:00",
288
+ "open": 111850.0859375,
289
+ "high": 111966.5,
290
+ "low": 111690.546875,
291
+ "close": 111807.3828125,
292
+ "volume": 106.12403106689453,
293
+ "amount": 11793642.0
294
+ },
295
+ {
296
+ "timestamp": "2025-08-29T21:45:00+08:00",
297
+ "open": 111852.90625,
298
+ "high": 111977.1875,
299
+ "low": 111675.109375,
300
+ "close": 111789.2109375,
301
+ "volume": 107.31920623779297,
302
+ "amount": 11903872.0
303
+ },
304
+ {
305
+ "timestamp": "2025-08-29T22:00:00+08:00",
306
+ "open": 111809.515625,
307
+ "high": 111929.6015625,
308
+ "low": 111644.6640625,
309
+ "close": 111765.1640625,
310
+ "volume": 115.47978973388672,
311
+ "amount": 12797432.0
312
+ },
313
+ {
314
+ "timestamp": "2025-08-29T22:15:00+08:00",
315
+ "open": 111760.046875,
316
+ "high": 111913.3828125,
317
+ "low": 111627.3203125,
318
+ "close": 111784.5234375,
319
+ "volume": 97.37040710449219,
320
+ "amount": 10761853.0
321
+ },
322
+ {
323
+ "timestamp": "2025-08-29T22:30:00+08:00",
324
+ "open": 111811.53125,
325
+ "high": 112017.453125,
326
+ "low": 111670.1171875,
327
+ "close": 111852.3203125,
328
+ "volume": 116.19581604003906,
329
+ "amount": 12838051.0
330
+ },
331
+ {
332
+ "timestamp": "2025-08-29T22:45:00+08:00",
333
+ "open": 111866.375,
334
+ "high": 112028.640625,
335
+ "low": 111739.7734375,
336
+ "close": 111900.65625,
337
+ "volume": 84.4815902709961,
338
+ "amount": 9403430.0
339
+ },
340
+ {
341
+ "timestamp": "2025-08-29T23:00:00+08:00",
342
+ "open": 111902.5078125,
343
+ "high": 112064.609375,
344
+ "low": 111773.296875,
345
+ "close": 111926.8828125,
346
+ "volume": 107.46073913574219,
347
+ "amount": 11871028.0
348
+ },
349
+ {
350
+ "timestamp": "2025-08-29T23:15:00+08:00",
351
+ "open": 111941.4140625,
352
+ "high": 112092.2109375,
353
+ "low": 111812.4140625,
354
+ "close": 111954.140625,
355
+ "volume": 123.07998657226562,
356
+ "amount": 13605938.0
357
+ },
358
+ {
359
+ "timestamp": "2025-08-29T23:30:00+08:00",
360
+ "open": 111966.984375,
361
+ "high": 112076.828125,
362
+ "low": 111744.3828125,
363
+ "close": 111852.8671875,
364
+ "volume": 134.875,
365
+ "amount": 14929412.0
366
+ },
367
+ {
368
+ "timestamp": "2025-08-29T23:45:00+08:00",
369
+ "open": 111886.5625,
370
+ "high": 111993.1015625,
371
+ "low": 111712.6640625,
372
+ "close": 111824.2265625,
373
+ "volume": 109.18719482421875,
374
+ "amount": 12098620.0
375
+ },
376
+ {
377
+ "timestamp": "2025-08-30T00:00:00+08:00",
378
+ "open": 111936.2578125,
379
+ "high": 112101.8515625,
380
+ "low": 111745.0859375,
381
+ "close": 111918.59375,
382
+ "volume": 166.5782012939453,
383
+ "amount": 18353800.0
384
+ },
385
+ {
386
+ "timestamp": "2025-08-30T00:15:00+08:00",
387
+ "open": 112043.0390625,
388
+ "high": 112194.6328125,
389
+ "low": 111838.015625,
390
+ "close": 111964.796875,
391
+ "volume": 128.78582763671875,
392
+ "amount": 14352829.0
393
+ },
394
+ {
395
+ "timestamp": "2025-08-30T00:30:00+08:00",
396
+ "open": 112008.046875,
397
+ "high": 112152.8125,
398
+ "low": 111833.3828125,
399
+ "close": 111985.0703125,
400
+ "volume": 132.19151306152344,
401
+ "amount": 14571858.0
402
+ },
403
+ {
404
+ "timestamp": "2025-08-30T00:45:00+08:00",
405
+ "open": 111999.578125,
406
+ "high": 112109.4921875,
407
+ "low": 111831.28125,
408
+ "close": 111943.8359375,
409
+ "volume": 90.95932006835938,
410
+ "amount": 10064076.0
411
+ },
412
+ {
413
+ "timestamp": "2025-08-30T01:00:00+08:00",
414
+ "open": 111992.421875,
415
+ "high": 112106.9453125,
416
+ "low": 111810.296875,
417
+ "close": 111930.1875,
418
+ "volume": 116.3121109008789,
419
+ "amount": 12883970.0
420
+ },
421
+ {
422
+ "timestamp": "2025-08-30T01:15:00+08:00",
423
+ "open": 111951.890625,
424
+ "high": 112050.828125,
425
+ "low": 111795.2421875,
426
+ "close": 111897.8359375,
427
+ "volume": 99.48136901855469,
428
+ "amount": 11042675.0
429
+ },
430
+ {
431
+ "timestamp": "2025-08-30T01:30:00+08:00",
432
+ "open": 111911.1171875,
433
+ "high": 112012.4921875,
434
+ "low": 111775.34375,
435
+ "close": 111879.5546875,
436
+ "volume": 87.62853240966797,
437
+ "amount": 9714546.0
438
+ },
439
+ {
440
+ "timestamp": "2025-08-30T01:45:00+08:00",
441
+ "open": 111922.4921875,
442
+ "high": 112033.8515625,
443
+ "low": 111772.203125,
444
+ "close": 111884.46875,
445
+ "volume": 79.35269927978516,
446
+ "amount": 8829243.0
447
+ },
448
+ {
449
+ "timestamp": "2025-08-30T02:00:00+08:00",
450
+ "open": 111904.71875,
451
+ "high": 112034.4453125,
452
+ "low": 111734.1875,
453
+ "close": 111853.9921875,
454
+ "volume": 103.8651351928711,
455
+ "amount": 11505330.0
456
+ },
457
+ {
458
+ "timestamp": "2025-08-30T02:15:00+08:00",
459
+ "open": 111881.6171875,
460
+ "high": 111984.9609375,
461
+ "low": 111733.96875,
462
+ "close": 111843.5859375,
463
+ "volume": 84.92535400390625,
464
+ "amount": 9402822.0
465
+ },
466
+ {
467
+ "timestamp": "2025-08-30T02:30:00+08:00",
468
+ "open": 111882.4140625,
469
+ "high": 111945.1640625,
470
+ "low": 111701.3359375,
471
+ "close": 111773.6796875,
472
+ "volume": 81.62976837158203,
473
+ "amount": 9231286.0
474
+ },
475
+ {
476
+ "timestamp": "2025-08-30T02:45:00+08:00",
477
+ "open": 111778.2734375,
478
+ "high": 111900.0,
479
+ "low": 111670.3671875,
480
+ "close": 111778.9375,
481
+ "volume": 72.34359741210938,
482
+ "amount": 8040056.0
483
+ },
484
+ {
485
+ "timestamp": "2025-08-30T03:00:00+08:00",
486
+ "open": 111820.140625,
487
+ "high": 111915.9453125,
488
+ "low": 111659.1328125,
489
+ "close": 111760.0234375,
490
+ "volume": 83.56487274169922,
491
+ "amount": 9336540.0
492
+ },
493
+ {
494
+ "timestamp": "2025-08-30T03:15:00+08:00",
495
+ "open": 111793.2578125,
496
+ "high": 111904.2578125,
497
+ "low": 111603.4921875,
498
+ "close": 111718.0078125,
499
+ "volume": 96.4046630859375,
500
+ "amount": 10660871.0
501
+ },
502
+ {
503
+ "timestamp": "2025-08-30T03:30:00+08:00",
504
+ "open": 111786.0234375,
505
+ "high": 111858.8828125,
506
+ "low": 111600.8828125,
507
+ "close": 111691.359375,
508
+ "volume": 97.03984069824219,
509
+ "amount": 10867320.0
510
+ },
511
+ {
512
+ "timestamp": "2025-08-30T03:45:00+08:00",
513
+ "open": 111744.2265625,
514
+ "high": 111844.625,
515
+ "low": 111580.078125,
516
+ "close": 111688.328125,
517
+ "volume": 80.87574768066406,
518
+ "amount": 8981413.0
519
+ },
520
+ {
521
+ "timestamp": "2025-08-30T04:00:00+08:00",
522
+ "open": 111693.109375,
523
+ "high": 111871.7734375,
524
+ "low": 111535.46875,
525
+ "close": 111712.7734375,
526
+ "volume": 110.76882934570312,
527
+ "amount": 12306102.0
528
+ },
529
+ {
530
+ "timestamp": "2025-08-30T04:15:00+08:00",
531
+ "open": 111736.9609375,
532
+ "high": 111863.3984375,
533
+ "low": 111607.453125,
534
+ "close": 111733.71875,
535
+ "volume": 93.17861938476562,
536
+ "amount": 10339148.0
537
+ },
538
+ {
539
+ "timestamp": "2025-08-30T04:30:00+08:00",
540
+ "open": 111752.90625,
541
+ "high": 111921.0703125,
542
+ "low": 111617.3515625,
543
+ "close": 111777.6640625,
544
+ "volume": 96.2171401977539,
545
+ "amount": 10661223.0
546
+ },
547
+ {
548
+ "timestamp": "2025-08-30T04:45:00+08:00",
549
+ "open": 111761.75,
550
+ "high": 111850.28125,
551
+ "low": 111638.984375,
552
+ "close": 111722.2890625,
553
+ "volume": 76.68721771240234,
554
+ "amount": 8542356.0
555
+ },
556
+ {
557
+ "timestamp": "2025-08-30T05:00:00+08:00",
558
+ "open": 111786.890625,
559
+ "high": 111873.078125,
560
+ "low": 111596.203125,
561
+ "close": 111717.6484375,
562
+ "volume": 88.36457061767578,
563
+ "amount": 9837959.0
564
+ },
565
+ {
566
+ "timestamp": "2025-08-30T05:15:00+08:00",
567
+ "open": 111741.0546875,
568
+ "high": 111860.7578125,
569
+ "low": 111597.9453125,
570
+ "close": 111709.0390625,
571
+ "volume": 82.78638458251953,
572
+ "amount": 9248871.0
573
+ },
574
+ {
575
+ "timestamp": "2025-08-30T05:30:00+08:00",
576
+ "open": 111770.078125,
577
+ "high": 111864.828125,
578
+ "low": 111613.421875,
579
+ "close": 111732.0,
580
+ "volume": 92.80091857910156,
581
+ "amount": 10290091.0
582
+ },
583
+ {
584
+ "timestamp": "2025-08-30T05:45:00+08:00",
585
+ "open": 111777.15625,
586
+ "high": 111882.9375,
587
+ "low": 111646.125,
588
+ "close": 111744.5390625,
589
+ "volume": 80.8597183227539,
590
+ "amount": 9073378.0
591
+ },
592
+ {
593
+ "timestamp": "2025-08-30T06:00:00+08:00",
594
+ "open": 111800.859375,
595
+ "high": 111938.375,
596
+ "low": 111671.09375,
597
+ "close": 111800.7421875,
598
+ "volume": 101.37644958496094,
599
+ "amount": 11161978.0
600
+ },
601
+ {
602
+ "timestamp": "2025-08-30T06:15:00+08:00",
603
+ "open": 111865.828125,
604
+ "high": 111955.46875,
605
+ "low": 111720.3671875,
606
+ "close": 111810.359375,
607
+ "volume": 86.99627685546875,
608
+ "amount": 9755229.0
609
+ },
610
+ {
611
+ "timestamp": "2025-08-30T06:30:00+08:00",
612
+ "open": 111851.5703125,
613
+ "high": 111958.3671875,
614
+ "low": 111734.375,
615
+ "close": 111843.6484375,
616
+ "volume": 88.52561950683594,
617
+ "amount": 9861068.0
618
+ },
619
+ {
620
+ "timestamp": "2025-08-30T06:45:00+08:00",
621
+ "open": 111887.4609375,
622
+ "high": 112047.5,
623
+ "low": 111738.125,
624
+ "close": 111886.375,
625
+ "volume": 93.07894897460938,
626
+ "amount": 10285172.0
627
+ },
628
+ {
629
+ "timestamp": "2025-08-30T07:00:00+08:00",
630
+ "open": 111904.703125,
631
+ "high": 112049.0,
632
+ "low": 111783.890625,
633
+ "close": 111914.28125,
634
+ "volume": 101.98164367675781,
635
+ "amount": 11277976.0
636
+ },
637
+ {
638
+ "timestamp": "2025-08-30T07:15:00+08:00",
639
+ "open": 111953.59375,
640
+ "high": 112048.1328125,
641
+ "low": 111810.1796875,
642
+ "close": 111912.203125,
643
+ "volume": 90.25052642822266,
644
+ "amount": 10097586.0
645
+ },
646
+ {
647
+ "timestamp": "2025-08-30T07:30:00+08:00",
648
+ "open": 111954.34375,
649
+ "high": 112084.640625,
650
+ "low": 111825.828125,
651
+ "close": 111951.5703125,
652
+ "volume": 107.92276763916016,
653
+ "amount": 12070878.0
654
+ },
655
+ {
656
+ "timestamp": "2025-08-30T07:45:00+08:00",
657
+ "open": 111998.9453125,
658
+ "high": 112103.9140625,
659
+ "low": 111885.984375,
660
+ "close": 111988.4375,
661
+ "volume": 89.00755310058594,
662
+ "amount": 9932353.0
663
+ },
664
+ {
665
+ "timestamp": "2025-08-30T08:00:00+08:00",
666
+ "open": 111981.3984375,
667
+ "high": 112115.8125,
668
+ "low": 111802.6484375,
669
+ "close": 111927.5625,
670
+ "volume": 138.4607696533203,
671
+ "amount": 15368191.0
672
+ },
673
+ {
674
+ "timestamp": "2025-08-30T08:15:00+08:00",
675
+ "open": 111991.828125,
676
+ "high": 112120.1484375,
677
+ "low": 111838.8515625,
678
+ "close": 111957.40625,
679
+ "volume": 96.40286254882812,
680
+ "amount": 10699868.0
681
+ },
682
+ {
683
+ "timestamp": "2025-08-30T08:30:00+08:00",
684
+ "open": 112027.2421875,
685
+ "high": 112202.109375,
686
+ "low": 111859.90625,
687
+ "close": 112022.984375,
688
+ "volume": 104.6871109008789,
689
+ "amount": 11840170.0
690
+ },
691
+ {
692
+ "timestamp": "2025-08-30T08:45:00+08:00",
693
+ "open": 112084.765625,
694
+ "high": 112172.71875,
695
+ "low": 111945.5234375,
696
+ "close": 112030.3515625,
697
+ "volume": 87.16902160644531,
698
+ "amount": 9773938.0
699
+ },
700
+ {
701
+ "timestamp": "2025-08-30T09:00:00+08:00",
702
+ "open": 112086.7578125,
703
+ "high": 112191.5546875,
704
+ "low": 111950.78125,
705
+ "close": 112052.703125,
706
+ "volume": 90.99862670898438,
707
+ "amount": 10224398.0
708
+ },
709
+ {
710
+ "timestamp": "2025-08-30T09:15:00+08:00",
711
+ "open": 112069.4453125,
712
+ "high": 112144.140625,
713
+ "low": 111943.921875,
714
+ "close": 112027.84375,
715
+ "volume": 83.24454498291016,
716
+ "amount": 9354530.0
717
+ },
718
+ {
719
+ "timestamp": "2025-08-30T09:30:00+08:00",
720
+ "open": 112062.3828125,
721
+ "high": 112144.5859375,
722
+ "low": 111947.4453125,
723
+ "close": 112031.3125,
724
+ "volume": 75.74029541015625,
725
+ "amount": 8507400.0
726
+ },
727
+ {
728
+ "timestamp": "2025-08-30T09:45:00+08:00",
729
+ "open": 112060.421875,
730
+ "high": 112142.796875,
731
+ "low": 111946.3125,
732
+ "close": 112026.5078125,
733
+ "volume": 70.72943878173828,
734
+ "amount": 7964594.0
735
+ },
736
+ {
737
+ "timestamp": "2025-08-30T10:00:00+08:00",
738
+ "open": 112063.7734375,
739
+ "high": 112130.296875,
740
+ "low": 111945.7734375,
741
+ "close": 112021.2421875,
742
+ "volume": 72.86896514892578,
743
+ "amount": 8181000.0
744
+ },
745
+ {
746
+ "timestamp": "2025-08-30T10:15:00+08:00",
747
+ "open": 112043.078125,
748
+ "high": 112167.390625,
749
+ "low": 111937.6640625,
750
+ "close": 112062.125,
751
+ "volume": 70.6407699584961,
752
+ "amount": 7922684.0
753
+ },
754
+ {
755
+ "timestamp": "2025-08-30T10:30:00+08:00",
756
+ "open": 112128.0703125,
757
+ "high": 112195.6640625,
758
+ "low": 111976.859375,
759
+ "close": 112047.421875,
760
+ "volume": 73.72329711914062,
761
+ "amount": 8318643.0
762
+ },
763
+ {
764
+ "timestamp": "2025-08-30T10:45:00+08:00",
765
+ "open": 112072.640625,
766
+ "high": 112233.65625,
767
+ "low": 111945.4296875,
768
+ "close": 112103.5234375,
769
+ "volume": 92.0282211303711,
770
+ "amount": 10267641.0
771
+ },
772
+ {
773
+ "timestamp": "2025-08-30T11:00:00+08:00",
774
+ "open": 112120.6484375,
775
+ "high": 112217.265625,
776
+ "low": 111969.171875,
777
+ "close": 112067.8984375,
778
+ "volume": 87.43103790283203,
779
+ "amount": 9765810.0
780
+ },
781
+ {
782
+ "timestamp": "2025-08-30T11:15:00+08:00",
783
+ "open": 112122.0,
784
+ "high": 112232.53125,
785
+ "low": 111983.203125,
786
+ "close": 112085.2734375,
787
+ "volume": 87.32120513916016,
788
+ "amount": 9764636.0
789
+ },
790
+ {
791
+ "timestamp": "2025-08-30T11:30:00+08:00",
792
+ "open": 112173.453125,
793
+ "high": 112280.3203125,
794
+ "low": 111924.140625,
795
+ "close": 112050.2890625,
796
+ "volume": 104.56067657470703,
797
+ "amount": 11663960.0
798
+ },
799
+ {
800
+ "timestamp": "2025-08-30T11:45:00+08:00",
801
+ "open": 112102.8515625,
802
+ "high": 112175.84375,
803
+ "low": 111970.4375,
804
+ "close": 112039.4140625,
805
+ "volume": 67.20665740966797,
806
+ "amount": 7588341.0
807
+ },
808
+ {
809
+ "timestamp": "2025-08-30T12:00:00+08:00",
810
+ "open": 112095.015625,
811
+ "high": 112197.7734375,
812
+ "low": 111970.75,
813
+ "close": 112071.9140625,
814
+ "volume": 82.2674331665039,
815
+ "amount": 9231251.0
816
+ },
817
+ {
818
+ "timestamp": "2025-08-30T12:15:00+08:00",
819
+ "open": 112097.65625,
820
+ "high": 112238.28125,
821
+ "low": 112002.1796875,
822
+ "close": 112131.1640625,
823
+ "volume": 74.65169525146484,
824
+ "amount": 8348942.0
825
+ },
826
+ {
827
+ "timestamp": "2025-08-30T12:30:00+08:00",
828
+ "open": 112165.5625,
829
+ "high": 112277.359375,
830
+ "low": 112072.671875,
831
+ "close": 112185.0625,
832
+ "volume": 78.97994995117188,
833
+ "amount": 8826491.0
834
+ },
835
+ {
836
+ "timestamp": "2025-08-30T12:45:00+08:00",
837
+ "open": 112188.453125,
838
+ "high": 112269.015625,
839
+ "low": 112072.109375,
840
+ "close": 112162.1484375,
841
+ "volume": 68.9449691772461,
842
+ "amount": 7831554.0
843
+ },
844
+ {
845
+ "timestamp": "2025-08-30T13:00:00+08:00",
846
+ "open": 112190.953125,
847
+ "high": 112286.2734375,
848
+ "low": 112089.34375,
849
+ "close": 112197.96875,
850
+ "volume": 69.2558364868164,
851
+ "amount": 7745253.0
852
+ },
853
+ {
854
+ "timestamp": "2025-08-30T13:15:00+08:00",
855
+ "open": 112230.0234375,
856
+ "high": 112326.9765625,
857
+ "low": 112138.2109375,
858
+ "close": 112239.3515625,
859
+ "volume": 71.58203887939453,
860
+ "amount": 8026911.0
861
+ },
862
+ {
863
+ "timestamp": "2025-08-30T13:30:00+08:00",
864
+ "open": 112250.0625,
865
+ "high": 112334.2578125,
866
+ "low": 112113.515625,
867
+ "close": 112198.328125,
868
+ "volume": 75.6541748046875,
869
+ "amount": 8507868.0
870
+ },
871
+ {
872
+ "timestamp": "2025-08-30T13:45:00+08:00",
873
+ "open": 112255.828125,
874
+ "high": 112339.78125,
875
+ "low": 112117.1953125,
876
+ "close": 112196.53125,
877
+ "volume": 74.15754699707031,
878
+ "amount": 8361086.0
879
+ },
880
+ {
881
+ "timestamp": "2025-08-30T14:00:00+08:00",
882
+ "open": 112249.3671875,
883
+ "high": 112332.6171875,
884
+ "low": 112101.8046875,
885
+ "close": 112185.9296875,
886
+ "volume": 82.35772705078125,
887
+ "amount": 9188284.0
888
+ },
889
+ {
890
+ "timestamp": "2025-08-30T14:15:00+08:00",
891
+ "open": 112195.1484375,
892
+ "high": 112349.9609375,
893
+ "low": 112043.9609375,
894
+ "close": 112164.9296875,
895
+ "volume": 82.1603012084961,
896
+ "amount": 9130755.0
897
+ },
898
+ {
899
+ "timestamp": "2025-08-30T14:30:00+08:00",
900
+ "open": 112181.140625,
901
+ "high": 112298.6640625,
902
+ "low": 112052.1171875,
903
+ "close": 112171.046875,
904
+ "volume": 73.72782897949219,
905
+ "amount": 8197644.0
906
+ },
907
+ {
908
+ "timestamp": "2025-08-30T14:45:00+08:00",
909
+ "open": 112212.1484375,
910
+ "high": 112305.9453125,
911
+ "low": 112067.921875,
912
+ "close": 112163.2578125,
913
+ "volume": 89.1031723022461,
914
+ "amount": 9989858.0
915
+ },
916
+ {
917
+ "timestamp": "2025-08-30T15:00:00+08:00",
918
+ "open": 112197.5078125,
919
+ "high": 112334.5234375,
920
+ "low": 112076.546875,
921
+ "close": 112194.546875,
922
+ "volume": 96.2724838256836,
923
+ "amount": 10684269.0
924
+ },
925
+ {
926
+ "timestamp": "2025-08-30T15:15:00+08:00",
927
+ "open": 112215.59375,
928
+ "high": 112327.1328125,
929
+ "low": 112075.84375,
930
+ "close": 112177.7578125,
931
+ "volume": 98.1348648071289,
932
+ "amount": 10984503.0
933
+ },
934
+ {
935
+ "timestamp": "2025-08-30T15:30:00+08:00",
936
+ "open": 112247.8046875,
937
+ "high": 112380.296875,
938
+ "low": 112065.3515625,
939
+ "close": 112184.8359375,
940
+ "volume": 117.23890686035156,
941
+ "amount": 13090492.0
942
+ },
943
+ {
944
+ "timestamp": "2025-08-30T15:45:00+08:00",
945
+ "open": 112227.4453125,
946
+ "high": 112360.484375,
947
+ "low": 112096.953125,
948
+ "close": 112219.25,
949
+ "volume": 101.76166534423828,
950
+ "amount": 11302862.0
951
+ },
952
+ {
953
+ "timestamp": "2025-08-30T16:00:00+08:00",
954
+ "open": 112248.3984375,
955
+ "high": 112330.0390625,
956
+ "low": 112007.75,
957
+ "close": 112110.765625,
958
+ "volume": 136.02972412109375,
959
+ "amount": 15218441.0
960
+ },
961
+ {
962
+ "timestamp": "2025-08-30T16:15:00+08:00",
963
+ "open": 112173.9453125,
964
+ "high": 112297.421875,
965
+ "low": 112001.265625,
966
+ "close": 112124.15625,
967
+ "volume": 98.07292175292969,
968
+ "amount": 10773396.0
969
+ },
970
+ {
971
+ "timestamp": "2025-08-30T16:30:00+08:00",
972
+ "open": 112145.5,
973
+ "high": 112270.2890625,
974
+ "low": 112032.4453125,
975
+ "close": 112150.6875,
976
+ "volume": 86.155029296875,
977
+ "amount": 9518677.0
978
+ },
979
+ {
980
+ "timestamp": "2025-08-30T16:45:00+08:00",
981
+ "open": 112177.875,
982
+ "high": 112292.3515625,
983
+ "low": 112050.734375,
984
+ "close": 112165.8125,
985
+ "volume": 76.6077651977539,
986
+ "amount": 8471837.0
987
+ },
988
+ {
989
+ "timestamp": "2025-08-30T17:00:00+08:00",
990
+ "open": 112174.21875,
991
+ "high": 112284.34375,
992
+ "low": 112049.046875,
993
+ "close": 112156.375,
994
+ "volume": 81.96548461914062,
995
+ "amount": 9135485.0
996
+ },
997
+ {
998
+ "timestamp": "2025-08-30T17:15:00+08:00",
999
+ "open": 112184.1640625,
1000
+ "high": 112277.8828125,
1001
+ "low": 112051.7890625,
1002
+ "close": 112147.7421875,
1003
+ "volume": 83.50753784179688,
1004
+ "amount": 9276246.0
1005
+ },
1006
+ {
1007
+ "timestamp": "2025-08-30T17:30:00+08:00",
1008
+ "open": 112181.4375,
1009
+ "high": 112288.28125,
1010
+ "low": 112052.3984375,
1011
+ "close": 112151.71875,
1012
+ "volume": 88.9229507446289,
1013
+ "amount": 10006353.0
1014
+ },
1015
+ {
1016
+ "timestamp": "2025-08-30T17:45:00+08:00",
1017
+ "open": 112181.1171875,
1018
+ "high": 112297.25,
1019
+ "low": 112080.8046875,
1020
+ "close": 112190.5703125,
1021
+ "volume": 92.39521026611328,
1022
+ "amount": 10375275.0
1023
+ },
1024
+ {
1025
+ "timestamp": "2025-08-30T18:00:00+08:00",
1026
+ "open": 112265.875,
1027
+ "high": 112427.671875,
1028
+ "low": 112139.6328125,
1029
+ "close": 112282.640625,
1030
+ "volume": 91.09273529052734,
1031
+ "amount": 10151012.0
1032
+ },
1033
+ {
1034
+ "timestamp": "2025-08-30T18:15:00+08:00",
1035
+ "open": 112281.40625,
1036
+ "high": 112404.9140625,
1037
+ "low": 112166.8125,
1038
+ "close": 112291.3671875,
1039
+ "volume": 84.6778793334961,
1040
+ "amount": 9539039.0
1041
+ },
1042
+ {
1043
+ "timestamp": "2025-08-30T18:30:00+08:00",
1044
+ "open": 112314.3828125,
1045
+ "high": 112437.8046875,
1046
+ "low": 112219.8203125,
1047
+ "close": 112333.734375,
1048
+ "volume": 77.6357421875,
1049
+ "amount": 8722920.0
1050
+ },
1051
+ {
1052
+ "timestamp": "2025-08-30T18:45:00+08:00",
1053
+ "open": 112369.96875,
1054
+ "high": 112510.7734375,
1055
+ "low": 112258.5234375,
1056
+ "close": 112373.3671875,
1057
+ "volume": 73.10360717773438,
1058
+ "amount": 8268064.0
1059
+ },
1060
+ {
1061
+ "timestamp": "2025-08-30T19:00:00+08:00",
1062
+ "open": 112385.9609375,
1063
+ "high": 112491.5625,
1064
+ "low": 112263.2421875,
1065
+ "close": 112373.234375,
1066
+ "volume": 88.50096893310547,
1067
+ "amount": 9900305.0
1068
+ },
1069
+ {
1070
+ "timestamp": "2025-08-30T19:15:00+08:00",
1071
+ "open": 112416.546875,
1072
+ "high": 112574.28125,
1073
+ "low": 112231.359375,
1074
+ "close": 112403.921875,
1075
+ "volume": 95.40093994140625,
1076
+ "amount": 10958724.0
1077
+ },
1078
+ {
1079
+ "timestamp": "2025-08-30T19:30:00+08:00",
1080
+ "open": 112374.75,
1081
+ "high": 112452.265625,
1082
+ "low": 112208.7421875,
1083
+ "close": 112308.953125,
1084
+ "volume": 84.44782257080078,
1085
+ "amount": 9512642.0
1086
+ },
1087
+ {
1088
+ "timestamp": "2025-08-30T19:45:00+08:00",
1089
+ "open": 112311.4765625,
1090
+ "high": 112407.1796875,
1091
+ "low": 112191.4140625,
1092
+ "close": 112291.9296875,
1093
+ "volume": 82.6038589477539,
1094
+ "amount": 9220620.0
1095
+ },
1096
+ {
1097
+ "timestamp": "2025-08-30T20:00:00+08:00",
1098
+ "open": 112325.7265625,
1099
+ "high": 112453.875,
1100
+ "low": 112119.9453125,
1101
+ "close": 112248.5078125,
1102
+ "volume": 125.05335998535156,
1103
+ "amount": 13905253.0
1104
+ },
1105
+ {
1106
+ "timestamp": "2025-08-30T20:15:00+08:00",
1107
+ "open": 112286.2421875,
1108
+ "high": 112426.1484375,
1109
+ "low": 112129.5078125,
1110
+ "close": 112260.8046875,
1111
+ "volume": 101.14073944091797,
1112
+ "amount": 11259147.0
1113
+ },
1114
+ {
1115
+ "timestamp": "2025-08-30T20:30:00+08:00",
1116
+ "open": 112336.9609375,
1117
+ "high": 112460.3828125,
1118
+ "low": 112170.1328125,
1119
+ "close": 112296.9609375,
1120
+ "volume": 108.94501495361328,
1121
+ "amount": 12218919.0
1122
+ },
1123
+ {
1124
+ "timestamp": "2025-08-30T20:45:00+08:00",
1125
+ "open": 112325.484375,
1126
+ "high": 112446.140625,
1127
+ "low": 112197.1171875,
1128
+ "close": 112315.21875,
1129
+ "volume": 83.64878845214844,
1130
+ "amount": 9414279.0
1131
+ }
1132
+ ],
1133
+ "actual_data": [],
1134
+ "analysis": {}
1135
+ }
webui/prediction_results/prediction_20250829_150514.json ADDED
@@ -0,0 +1,1135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "timestamp": "2025-08-29T15:05:14.962361",
3
+ "file_path": "ETHUSDT_15m",
4
+ "prediction_type": "Kronos model prediction (latest data)",
5
+ "prediction_params": {
6
+ "symbol": "ETHUSDT",
7
+ "interval": "15m",
8
+ "limit": 1000,
9
+ "lookback": 1000,
10
+ "pred_len": 120,
11
+ "temperature": 1.0,
12
+ "top_p": 0.9,
13
+ "sample_count": 12,
14
+ "start_date": "latest"
15
+ },
16
+ "input_data_summary": {
17
+ "rows": 1000,
18
+ "columns": [
19
+ "open",
20
+ "high",
21
+ "low",
22
+ "close",
23
+ "volume",
24
+ "amount"
25
+ ],
26
+ "price_range": {
27
+ "open": {
28
+ "min": 4075.58,
29
+ "max": 4942.98
30
+ },
31
+ "high": {
32
+ "min": 4095.0,
33
+ "max": 4956.78
34
+ },
35
+ "low": {
36
+ "min": 4060.0,
37
+ "max": 4933.85
38
+ },
39
+ "close": {
40
+ "min": 4075.59,
41
+ "max": 4942.98
42
+ }
43
+ },
44
+ "last_values": {
45
+ "open": 4472.29,
46
+ "high": 4473.17,
47
+ "low": 4454.28,
48
+ "close": 4458.7
49
+ }
50
+ },
51
+ "prediction_results": [
52
+ {
53
+ "timestamp": "2025-08-29T15:00:00+08:00",
54
+ "open": 4444.56591796875,
55
+ "high": 4465.90478515625,
56
+ "low": 4415.63671875,
57
+ "close": 4443.26953125,
58
+ "volume": 9217.275390625,
59
+ "amount": 40805148.0
60
+ },
61
+ {
62
+ "timestamp": "2025-08-29T15:15:00+08:00",
63
+ "open": 4445.2421875,
64
+ "high": 4461.99365234375,
65
+ "low": 4426.9677734375,
66
+ "close": 4441.669921875,
67
+ "volume": 6457.33642578125,
68
+ "amount": 28364656.0
69
+ },
70
+ {
71
+ "timestamp": "2025-08-29T15:30:00+08:00",
72
+ "open": 4444.40185546875,
73
+ "high": 4458.494140625,
74
+ "low": 4425.56494140625,
75
+ "close": 4438.82763671875,
76
+ "volume": 6437.61962890625,
77
+ "amount": 28472140.0
78
+ },
79
+ {
80
+ "timestamp": "2025-08-29T15:45:00+08:00",
81
+ "open": 4442.63916015625,
82
+ "high": 4460.41064453125,
83
+ "low": 4428.01123046875,
84
+ "close": 4443.92333984375,
85
+ "volume": 6154.728515625,
86
+ "amount": 27168418.0
87
+ },
88
+ {
89
+ "timestamp": "2025-08-29T16:00:00+08:00",
90
+ "open": 4443.24267578125,
91
+ "high": 4465.15625,
92
+ "low": 4426.150390625,
93
+ "close": 4446.44677734375,
94
+ "volume": 7082.49755859375,
95
+ "amount": 31837018.0
96
+ },
97
+ {
98
+ "timestamp": "2025-08-29T16:15:00+08:00",
99
+ "open": 4448.5888671875,
100
+ "high": 4461.3193359375,
101
+ "low": 4433.79638671875,
102
+ "close": 4446.01904296875,
103
+ "volume": 5071.296875,
104
+ "amount": 22424840.0
105
+ },
106
+ {
107
+ "timestamp": "2025-08-29T16:30:00+08:00",
108
+ "open": 4450.31201171875,
109
+ "high": 4462.99462890625,
110
+ "low": 4432.09912109375,
111
+ "close": 4443.74365234375,
112
+ "volume": 5389.142578125,
113
+ "amount": 24045034.0
114
+ },
115
+ {
116
+ "timestamp": "2025-08-29T16:45:00+08:00",
117
+ "open": 4447.33740234375,
118
+ "high": 4460.9599609375,
119
+ "low": 4434.24658203125,
120
+ "close": 4446.2080078125,
121
+ "volume": 4811.583984375,
122
+ "amount": 21232422.0
123
+ },
124
+ {
125
+ "timestamp": "2025-08-29T17:00:00+08:00",
126
+ "open": 4450.42822265625,
127
+ "high": 4462.5126953125,
128
+ "low": 4429.68017578125,
129
+ "close": 4442.61669921875,
130
+ "volume": 5684.46728515625,
131
+ "amount": 25023126.0
132
+ },
133
+ {
134
+ "timestamp": "2025-08-29T17:15:00+08:00",
135
+ "open": 4444.83349609375,
136
+ "high": 4456.32470703125,
137
+ "low": 4431.37158203125,
138
+ "close": 4441.24755859375,
139
+ "volume": 5026.57861328125,
140
+ "amount": 22191646.0
141
+ },
142
+ {
143
+ "timestamp": "2025-08-29T17:30:00+08:00",
144
+ "open": 4444.7890625,
145
+ "high": 4456.08203125,
146
+ "low": 4431.85986328125,
147
+ "close": 4441.16748046875,
148
+ "volume": 3917.94140625,
149
+ "amount": 17363496.0
150
+ },
151
+ {
152
+ "timestamp": "2025-08-29T17:45:00+08:00",
153
+ "open": 4444.8046875,
154
+ "high": 4455.31298828125,
155
+ "low": 4431.2138671875,
156
+ "close": 4441.10693359375,
157
+ "volume": 4654.3193359375,
158
+ "amount": 20566798.0
159
+ },
160
+ {
161
+ "timestamp": "2025-08-29T18:00:00+08:00",
162
+ "open": 4444.2880859375,
163
+ "high": 4455.0703125,
164
+ "low": 4429.15380859375,
165
+ "close": 4439.7666015625,
166
+ "volume": 6178.53515625,
167
+ "amount": 27322580.0
168
+ },
169
+ {
170
+ "timestamp": "2025-08-29T18:15:00+08:00",
171
+ "open": 4442.96142578125,
172
+ "high": 4453.37841796875,
173
+ "low": 4426.81103515625,
174
+ "close": 4436.28076171875,
175
+ "volume": 4740.16357421875,
176
+ "amount": 20856040.0
177
+ },
178
+ {
179
+ "timestamp": "2025-08-29T18:30:00+08:00",
180
+ "open": 4439.814453125,
181
+ "high": 4453.78515625,
182
+ "low": 4423.60693359375,
183
+ "close": 4435.65380859375,
184
+ "volume": 4550.0615234375,
185
+ "amount": 19977028.0
186
+ },
187
+ {
188
+ "timestamp": "2025-08-29T18:45:00+08:00",
189
+ "open": 4437.978515625,
190
+ "high": 4447.69873046875,
191
+ "low": 4425.95751953125,
192
+ "close": 4433.853515625,
193
+ "volume": 3539.611328125,
194
+ "amount": 15629640.0
195
+ },
196
+ {
197
+ "timestamp": "2025-08-29T19:00:00+08:00",
198
+ "open": 4439.0234375,
199
+ "high": 4451.14794921875,
200
+ "low": 4427.4091796875,
201
+ "close": 4437.88330078125,
202
+ "volume": 4457.74072265625,
203
+ "amount": 19741456.0
204
+ },
205
+ {
206
+ "timestamp": "2025-08-29T19:15:00+08:00",
207
+ "open": 4440.67236328125,
208
+ "high": 4450.251953125,
209
+ "low": 4424.75244140625,
210
+ "close": 4434.4404296875,
211
+ "volume": 4041.19970703125,
212
+ "amount": 17870412.0
213
+ },
214
+ {
215
+ "timestamp": "2025-08-29T19:30:00+08:00",
216
+ "open": 4439.81591796875,
217
+ "high": 4448.09716796875,
218
+ "low": 4422.6083984375,
219
+ "close": 4431.39306640625,
220
+ "volume": 4699.3359375,
221
+ "amount": 21181264.0
222
+ },
223
+ {
224
+ "timestamp": "2025-08-29T19:45:00+08:00",
225
+ "open": 4435.97265625,
226
+ "high": 4446.8984375,
227
+ "low": 4424.90283203125,
228
+ "close": 4434.27978515625,
229
+ "volume": 4268.640625,
230
+ "amount": 18895636.0
231
+ },
232
+ {
233
+ "timestamp": "2025-08-29T20:00:00+08:00",
234
+ "open": 4434.98291015625,
235
+ "high": 4444.10107421875,
236
+ "low": 4415.77880859375,
237
+ "close": 4425.10498046875,
238
+ "volume": 5284.3544921875,
239
+ "amount": 23360280.0
240
+ },
241
+ {
242
+ "timestamp": "2025-08-29T20:15:00+08:00",
243
+ "open": 4430.73779296875,
244
+ "high": 4446.8466796875,
245
+ "low": 4416.8623046875,
246
+ "close": 4430.75537109375,
247
+ "volume": 4821.13671875,
248
+ "amount": 21274184.0
249
+ },
250
+ {
251
+ "timestamp": "2025-08-29T20:30:00+08:00",
252
+ "open": 4433.912109375,
253
+ "high": 4441.0498046875,
254
+ "low": 4418.09033203125,
255
+ "close": 4425.23291015625,
256
+ "volume": 5097.58984375,
257
+ "amount": 22713672.0
258
+ },
259
+ {
260
+ "timestamp": "2025-08-29T20:45:00+08:00",
261
+ "open": 4429.697265625,
262
+ "high": 4442.6748046875,
263
+ "low": 4417.91455078125,
264
+ "close": 4429.427734375,
265
+ "volume": 4236.5927734375,
266
+ "amount": 18617122.0
267
+ },
268
+ {
269
+ "timestamp": "2025-08-29T21:00:00+08:00",
270
+ "open": 4431.796875,
271
+ "high": 4440.27001953125,
272
+ "low": 4416.4306640625,
273
+ "close": 4424.44287109375,
274
+ "volume": 4971.64501953125,
275
+ "amount": 22127160.0
276
+ },
277
+ {
278
+ "timestamp": "2025-08-29T21:15:00+08:00",
279
+ "open": 4428.65380859375,
280
+ "high": 4438.82666015625,
281
+ "low": 4410.0908203125,
282
+ "close": 4419.958984375,
283
+ "volume": 4880.84814453125,
284
+ "amount": 21470996.0
285
+ },
286
+ {
287
+ "timestamp": "2025-08-29T21:30:00+08:00",
288
+ "open": 4423.84765625,
289
+ "high": 4435.455078125,
290
+ "low": 4408.8212890625,
291
+ "close": 4418.8388671875,
292
+ "volume": 5310.017578125,
293
+ "amount": 23468740.0
294
+ },
295
+ {
296
+ "timestamp": "2025-08-29T21:45:00+08:00",
297
+ "open": 4422.228515625,
298
+ "high": 4436.84912109375,
299
+ "low": 4406.013671875,
300
+ "close": 4421.1357421875,
301
+ "volume": 5691.2919921875,
302
+ "amount": 25062086.0
303
+ },
304
+ {
305
+ "timestamp": "2025-08-29T22:00:00+08:00",
306
+ "open": 4423.30615234375,
307
+ "high": 4432.3310546875,
308
+ "low": 4410.02978515625,
309
+ "close": 4418.75,
310
+ "volume": 4468.89208984375,
311
+ "amount": 19694380.0
312
+ },
313
+ {
314
+ "timestamp": "2025-08-29T22:15:00+08:00",
315
+ "open": 4424.423828125,
316
+ "high": 4431.634765625,
317
+ "low": 4408.798828125,
318
+ "close": 4415.80712890625,
319
+ "volume": 4531.4365234375,
320
+ "amount": 20034978.0
321
+ },
322
+ {
323
+ "timestamp": "2025-08-29T22:30:00+08:00",
324
+ "open": 4421.29541015625,
325
+ "high": 4434.6357421875,
326
+ "low": 4405.32470703125,
327
+ "close": 4418.87744140625,
328
+ "volume": 6036.533203125,
329
+ "amount": 26565786.0
330
+ },
331
+ {
332
+ "timestamp": "2025-08-29T22:45:00+08:00",
333
+ "open": 4420.73046875,
334
+ "high": 4433.45703125,
335
+ "low": 4409.806640625,
336
+ "close": 4420.74609375,
337
+ "volume": 4460.77197265625,
338
+ "amount": 19610600.0
339
+ },
340
+ {
341
+ "timestamp": "2025-08-29T23:00:00+08:00",
342
+ "open": 4420.107421875,
343
+ "high": 4434.1953125,
344
+ "low": 4408.61767578125,
345
+ "close": 4422.34716796875,
346
+ "volume": 4672.87890625,
347
+ "amount": 20587718.0
348
+ },
349
+ {
350
+ "timestamp": "2025-08-29T23:15:00+08:00",
351
+ "open": 4422.76708984375,
352
+ "high": 4432.43115234375,
353
+ "low": 4408.826171875,
354
+ "close": 4417.640625,
355
+ "volume": 4759.7646484375,
356
+ "amount": 21004958.0
357
+ },
358
+ {
359
+ "timestamp": "2025-08-29T23:30:00+08:00",
360
+ "open": 4419.259765625,
361
+ "high": 4428.599609375,
362
+ "low": 4404.37060546875,
363
+ "close": 4413.42822265625,
364
+ "volume": 5411.2177734375,
365
+ "amount": 23824832.0
366
+ },
367
+ {
368
+ "timestamp": "2025-08-29T23:45:00+08:00",
369
+ "open": 4417.21240234375,
370
+ "high": 4429.10791015625,
371
+ "low": 4404.77587890625,
372
+ "close": 4415.55810546875,
373
+ "volume": 4215.689453125,
374
+ "amount": 18526096.0
375
+ },
376
+ {
377
+ "timestamp": "2025-08-30T00:00:00+08:00",
378
+ "open": 4418.54345703125,
379
+ "high": 4428.8037109375,
380
+ "low": 4398.87255859375,
381
+ "close": 4407.85986328125,
382
+ "volume": 6221.10546875,
383
+ "amount": 27428534.0
384
+ },
385
+ {
386
+ "timestamp": "2025-08-30T00:15:00+08:00",
387
+ "open": 4413.6416015625,
388
+ "high": 4426.369140625,
389
+ "low": 4397.6455078125,
390
+ "close": 4408.888671875,
391
+ "volume": 4846.1611328125,
392
+ "amount": 21438312.0
393
+ },
394
+ {
395
+ "timestamp": "2025-08-30T00:30:00+08:00",
396
+ "open": 4415.146484375,
397
+ "high": 4429.01708984375,
398
+ "low": 4403.10888671875,
399
+ "close": 4415.638671875,
400
+ "volume": 4306.1875,
401
+ "amount": 18928148.0
402
+ },
403
+ {
404
+ "timestamp": "2025-08-30T00:45:00+08:00",
405
+ "open": 4418.8798828125,
406
+ "high": 4428.71044921875,
407
+ "low": 4404.5888671875,
408
+ "close": 4413.03857421875,
409
+ "volume": 3644.2890625,
410
+ "amount": 16080228.0
411
+ },
412
+ {
413
+ "timestamp": "2025-08-30T01:00:00+08:00",
414
+ "open": 4415.8271484375,
415
+ "high": 4426.33251953125,
416
+ "low": 4402.8564453125,
417
+ "close": 4412.7236328125,
418
+ "volume": 4705.95751953125,
419
+ "amount": 20670044.0
420
+ },
421
+ {
422
+ "timestamp": "2025-08-30T01:15:00+08:00",
423
+ "open": 4418.57470703125,
424
+ "high": 4431.08935546875,
425
+ "low": 4401.22021484375,
426
+ "close": 4412.13916015625,
427
+ "volume": 4448.58349609375,
428
+ "amount": 19791164.0
429
+ },
430
+ {
431
+ "timestamp": "2025-08-30T01:30:00+08:00",
432
+ "open": 4416.92333984375,
433
+ "high": 4427.01806640625,
434
+ "low": 4405.50732421875,
435
+ "close": 4414.26513671875,
436
+ "volume": 4067.416259765625,
437
+ "amount": 17912714.0
438
+ },
439
+ {
440
+ "timestamp": "2025-08-30T01:45:00+08:00",
441
+ "open": 4418.7880859375,
442
+ "high": 4427.201171875,
443
+ "low": 4408.40576171875,
444
+ "close": 4416.146484375,
445
+ "volume": 3535.79296875,
446
+ "amount": 15609990.0
447
+ },
448
+ {
449
+ "timestamp": "2025-08-30T02:00:00+08:00",
450
+ "open": 4419.7021484375,
451
+ "high": 4431.84228515625,
452
+ "low": 4407.12841796875,
453
+ "close": 4418.0009765625,
454
+ "volume": 4544.619140625,
455
+ "amount": 20005372.0
456
+ },
457
+ {
458
+ "timestamp": "2025-08-30T02:15:00+08:00",
459
+ "open": 4421.0029296875,
460
+ "high": 4432.982421875,
461
+ "low": 4407.189453125,
462
+ "close": 4418.17529296875,
463
+ "volume": 4134.5302734375,
464
+ "amount": 18248920.0
465
+ },
466
+ {
467
+ "timestamp": "2025-08-30T02:30:00+08:00",
468
+ "open": 4421.5673828125,
469
+ "high": 4432.07568359375,
470
+ "low": 4411.0654296875,
471
+ "close": 4420.30322265625,
472
+ "volume": 3632.405517578125,
473
+ "amount": 15964916.0
474
+ },
475
+ {
476
+ "timestamp": "2025-08-30T02:45:00+08:00",
477
+ "open": 4420.4794921875,
478
+ "high": 4431.26806640625,
479
+ "low": 4410.98583984375,
480
+ "close": 4420.8994140625,
481
+ "volume": 3259.43212890625,
482
+ "amount": 14317208.0
483
+ },
484
+ {
485
+ "timestamp": "2025-08-30T03:00:00+08:00",
486
+ "open": 4423.84521484375,
487
+ "high": 4432.77978515625,
488
+ "low": 4412.89208984375,
489
+ "close": 4420.69189453125,
490
+ "volume": 3624.80908203125,
491
+ "amount": 15956880.0
492
+ },
493
+ {
494
+ "timestamp": "2025-08-30T03:15:00+08:00",
495
+ "open": 4425.9189453125,
496
+ "high": 4437.70751953125,
497
+ "low": 4414.8876953125,
498
+ "close": 4424.462890625,
499
+ "volume": 3949.387939453125,
500
+ "amount": 17384614.0
501
+ },
502
+ {
503
+ "timestamp": "2025-08-30T03:30:00+08:00",
504
+ "open": 4426.03955078125,
505
+ "high": 4433.37841796875,
506
+ "low": 4415.3369140625,
507
+ "close": 4421.17626953125,
508
+ "volume": 3493.44189453125,
509
+ "amount": 15436086.0
510
+ },
511
+ {
512
+ "timestamp": "2025-08-30T03:45:00+08:00",
513
+ "open": 4424.3330078125,
514
+ "high": 4430.51416015625,
515
+ "low": 4414.5927734375,
516
+ "close": 4420.818359375,
517
+ "volume": 2994.544921875,
518
+ "amount": 13187168.0
519
+ },
520
+ {
521
+ "timestamp": "2025-08-30T04:00:00+08:00",
522
+ "open": 4423.94580078125,
523
+ "high": 4431.31982421875,
524
+ "low": 4411.32568359375,
525
+ "close": 4419.4541015625,
526
+ "volume": 3898.42138671875,
527
+ "amount": 17125172.0
528
+ },
529
+ {
530
+ "timestamp": "2025-08-30T04:15:00+08:00",
531
+ "open": 4422.64306640625,
532
+ "high": 4428.61767578125,
533
+ "low": 4410.3349609375,
534
+ "close": 4416.2822265625,
535
+ "volume": 3311.53125,
536
+ "amount": 14581276.0
537
+ },
538
+ {
539
+ "timestamp": "2025-08-30T04:30:00+08:00",
540
+ "open": 4422.2939453125,
541
+ "high": 4430.4462890625,
542
+ "low": 4410.84912109375,
543
+ "close": 4417.822265625,
544
+ "volume": 3295.32958984375,
545
+ "amount": 14558054.0
546
+ },
547
+ {
548
+ "timestamp": "2025-08-30T04:45:00+08:00",
549
+ "open": 4421.650390625,
550
+ "high": 4430.6005859375,
551
+ "low": 4412.48828125,
552
+ "close": 4420.51025390625,
553
+ "volume": 3250.7177734375,
554
+ "amount": 14294590.0
555
+ },
556
+ {
557
+ "timestamp": "2025-08-30T05:00:00+08:00",
558
+ "open": 4422.33837890625,
559
+ "high": 4428.3662109375,
560
+ "low": 4412.38232421875,
561
+ "close": 4418.01171875,
562
+ "volume": 3147.05908203125,
563
+ "amount": 13809538.0
564
+ },
565
+ {
566
+ "timestamp": "2025-08-30T05:15:00+08:00",
567
+ "open": 4421.9990234375,
568
+ "high": 4427.93212890625,
569
+ "low": 4411.55712890625,
570
+ "close": 4417.81494140625,
571
+ "volume": 3193.78662109375,
572
+ "amount": 14034316.0
573
+ },
574
+ {
575
+ "timestamp": "2025-08-30T05:30:00+08:00",
576
+ "open": 4419.53759765625,
577
+ "high": 4425.20166015625,
578
+ "low": 4408.55810546875,
579
+ "close": 4414.31982421875,
580
+ "volume": 3129.86669921875,
581
+ "amount": 13743752.0
582
+ },
583
+ {
584
+ "timestamp": "2025-08-30T05:45:00+08:00",
585
+ "open": 4417.65576171875,
586
+ "high": 4424.513671875,
587
+ "low": 4407.9814453125,
588
+ "close": 4414.47705078125,
589
+ "volume": 3058.30224609375,
590
+ "amount": 13429728.0
591
+ },
592
+ {
593
+ "timestamp": "2025-08-30T06:00:00+08:00",
594
+ "open": 4414.5751953125,
595
+ "high": 4424.234375,
596
+ "low": 4404.935546875,
597
+ "close": 4414.05419921875,
598
+ "volume": 3295.88916015625,
599
+ "amount": 14439916.0
600
+ },
601
+ {
602
+ "timestamp": "2025-08-30T06:15:00+08:00",
603
+ "open": 4418.474609375,
604
+ "high": 4425.13134765625,
605
+ "low": 4407.90576171875,
606
+ "close": 4414.169921875,
607
+ "volume": 3265.73095703125,
608
+ "amount": 14369210.0
609
+ },
610
+ {
611
+ "timestamp": "2025-08-30T06:30:00+08:00",
612
+ "open": 4421.73046875,
613
+ "high": 4428.77392578125,
614
+ "low": 4406.12353515625,
615
+ "close": 4412.76416015625,
616
+ "volume": 3599.36767578125,
617
+ "amount": 15863754.0
618
+ },
619
+ {
620
+ "timestamp": "2025-08-30T06:45:00+08:00",
621
+ "open": 4414.2158203125,
622
+ "high": 4421.57666015625,
623
+ "low": 4402.5341796875,
624
+ "close": 4409.57470703125,
625
+ "volume": 3420.73876953125,
626
+ "amount": 15046830.0
627
+ },
628
+ {
629
+ "timestamp": "2025-08-30T07:00:00+08:00",
630
+ "open": 4414.4306640625,
631
+ "high": 4425.03564453125,
632
+ "low": 4401.88525390625,
633
+ "close": 4409.59375,
634
+ "volume": 3124.46044921875,
635
+ "amount": 13750980.0
636
+ },
637
+ {
638
+ "timestamp": "2025-08-30T07:15:00+08:00",
639
+ "open": 4414.96923828125,
640
+ "high": 4424.0751953125,
641
+ "low": 4404.77734375,
642
+ "close": 4412.271484375,
643
+ "volume": 3336.994140625,
644
+ "amount": 14746958.0
645
+ },
646
+ {
647
+ "timestamp": "2025-08-30T07:30:00+08:00",
648
+ "open": 4414.515625,
649
+ "high": 4425.46875,
650
+ "low": 4403.79638671875,
651
+ "close": 4413.37158203125,
652
+ "volume": 3633.9140625,
653
+ "amount": 15962774.0
654
+ },
655
+ {
656
+ "timestamp": "2025-08-30T07:45:00+08:00",
657
+ "open": 4416.53369140625,
658
+ "high": 4424.92333984375,
659
+ "low": 4407.9765625,
660
+ "close": 4415.19140625,
661
+ "volume": 3039.89111328125,
662
+ "amount": 13374326.0
663
+ },
664
+ {
665
+ "timestamp": "2025-08-30T08:00:00+08:00",
666
+ "open": 4417.24267578125,
667
+ "high": 4436.892578125,
668
+ "low": 4397.80615234375,
669
+ "close": 4422.52490234375,
670
+ "volume": 3849.573974609375,
671
+ "amount": 17092132.0
672
+ },
673
+ {
674
+ "timestamp": "2025-08-30T08:15:00+08:00",
675
+ "open": 4424.06396484375,
676
+ "high": 4436.06640625,
677
+ "low": 4410.9990234375,
678
+ "close": 4420.64990234375,
679
+ "volume": 3848.12060546875,
680
+ "amount": 17000952.0
681
+ },
682
+ {
683
+ "timestamp": "2025-08-30T08:30:00+08:00",
684
+ "open": 4423.544921875,
685
+ "high": 4436.00146484375,
686
+ "low": 4409.4111328125,
687
+ "close": 4421.40771484375,
688
+ "volume": 4132.8212890625,
689
+ "amount": 18360988.0
690
+ },
691
+ {
692
+ "timestamp": "2025-08-30T08:45:00+08:00",
693
+ "open": 4422.3837890625,
694
+ "high": 4434.77099609375,
695
+ "low": 4411.365234375,
696
+ "close": 4422.79541015625,
697
+ "volume": 3339.5146484375,
698
+ "amount": 14676568.0
699
+ },
700
+ {
701
+ "timestamp": "2025-08-30T09:00:00+08:00",
702
+ "open": 4424.86083984375,
703
+ "high": 4433.580078125,
704
+ "low": 4412.78125,
705
+ "close": 4421.5048828125,
706
+ "volume": 3503.95654296875,
707
+ "amount": 15373982.0
708
+ },
709
+ {
710
+ "timestamp": "2025-08-30T09:15:00+08:00",
711
+ "open": 4427.529296875,
712
+ "high": 4435.2880859375,
713
+ "low": 4413.16796875,
714
+ "close": 4419.97998046875,
715
+ "volume": 3335.650390625,
716
+ "amount": 14718534.0
717
+ },
718
+ {
719
+ "timestamp": "2025-08-30T09:30:00+08:00",
720
+ "open": 4426.05126953125,
721
+ "high": 4436.7822265625,
722
+ "low": 4416.0390625,
723
+ "close": 4425.57763671875,
724
+ "volume": 3070.638671875,
725
+ "amount": 13595170.0
726
+ },
727
+ {
728
+ "timestamp": "2025-08-30T09:45:00+08:00",
729
+ "open": 4431.537109375,
730
+ "high": 4436.86328125,
731
+ "low": 4414.892578125,
732
+ "close": 4421.59326171875,
733
+ "volume": 3467.83447265625,
734
+ "amount": 15386442.0
735
+ },
736
+ {
737
+ "timestamp": "2025-08-30T10:00:00+08:00",
738
+ "open": 4425.47314453125,
739
+ "high": 4432.24365234375,
740
+ "low": 4413.5439453125,
741
+ "close": 4419.54931640625,
742
+ "volume": 3326.73974609375,
743
+ "amount": 14762258.0
744
+ },
745
+ {
746
+ "timestamp": "2025-08-30T10:15:00+08:00",
747
+ "open": 4422.1220703125,
748
+ "high": 4431.0966796875,
749
+ "low": 4410.22314453125,
750
+ "close": 4419.17333984375,
751
+ "volume": 3139.20849609375,
752
+ "amount": 13884208.0
753
+ },
754
+ {
755
+ "timestamp": "2025-08-30T10:30:00+08:00",
756
+ "open": 4421.65576171875,
757
+ "high": 4429.0693359375,
758
+ "low": 4411.23291015625,
759
+ "close": 4418.46484375,
760
+ "volume": 2916.35888671875,
761
+ "amount": 12854348.0
762
+ },
763
+ {
764
+ "timestamp": "2025-08-30T10:45:00+08:00",
765
+ "open": 4424.79833984375,
766
+ "high": 4432.74267578125,
767
+ "low": 4411.53955078125,
768
+ "close": 4418.89453125,
769
+ "volume": 3240.97021484375,
770
+ "amount": 14294440.0
771
+ },
772
+ {
773
+ "timestamp": "2025-08-30T11:00:00+08:00",
774
+ "open": 4421.3486328125,
775
+ "high": 4426.65625,
776
+ "low": 4407.02880859375,
777
+ "close": 4413.22509765625,
778
+ "volume": 3523.09814453125,
779
+ "amount": 15522222.0
780
+ },
781
+ {
782
+ "timestamp": "2025-08-30T11:15:00+08:00",
783
+ "open": 4418.146484375,
784
+ "high": 4424.46630859375,
785
+ "low": 4400.74853515625,
786
+ "close": 4406.23779296875,
787
+ "volume": 4581.16748046875,
788
+ "amount": 20284268.0
789
+ },
790
+ {
791
+ "timestamp": "2025-08-30T11:30:00+08:00",
792
+ "open": 4408.302734375,
793
+ "high": 4422.57177734375,
794
+ "low": 4397.77685546875,
795
+ "close": 4413.76611328125,
796
+ "volume": 3456.4287109375,
797
+ "amount": 15155204.0
798
+ },
799
+ {
800
+ "timestamp": "2025-08-30T11:45:00+08:00",
801
+ "open": 4412.24169921875,
802
+ "high": 4419.21875,
803
+ "low": 4401.53564453125,
804
+ "close": 4408.38330078125,
805
+ "volume": 2967.7177734375,
806
+ "amount": 13093582.0
807
+ },
808
+ {
809
+ "timestamp": "2025-08-30T12:00:00+08:00",
810
+ "open": 4413.201171875,
811
+ "high": 4420.21533203125,
812
+ "low": 4403.00146484375,
813
+ "close": 4409.58447265625,
814
+ "volume": 2852.73388671875,
815
+ "amount": 12607770.0
816
+ },
817
+ {
818
+ "timestamp": "2025-08-30T12:15:00+08:00",
819
+ "open": 4410.72509765625,
820
+ "high": 4417.58642578125,
821
+ "low": 4399.541015625,
822
+ "close": 4405.8291015625,
823
+ "volume": 2915.83349609375,
824
+ "amount": 12912654.0
825
+ },
826
+ {
827
+ "timestamp": "2025-08-30T12:30:00+08:00",
828
+ "open": 4410.140625,
829
+ "high": 4417.90771484375,
830
+ "low": 4400.58056640625,
831
+ "close": 4408.63916015625,
832
+ "volume": 3110.79296875,
833
+ "amount": 13686536.0
834
+ },
835
+ {
836
+ "timestamp": "2025-08-30T12:45:00+08:00",
837
+ "open": 4410.9755859375,
838
+ "high": 4416.7744140625,
839
+ "low": 4400.47705078125,
840
+ "close": 4405.619140625,
841
+ "volume": 2681.83349609375,
842
+ "amount": 11842682.0
843
+ },
844
+ {
845
+ "timestamp": "2025-08-30T13:00:00+08:00",
846
+ "open": 4410.396484375,
847
+ "high": 4414.861328125,
848
+ "low": 4399.03662109375,
849
+ "close": 4403.9638671875,
850
+ "volume": 2766.78173828125,
851
+ "amount": 12221064.0
852
+ },
853
+ {
854
+ "timestamp": "2025-08-30T13:15:00+08:00",
855
+ "open": 4408.42724609375,
856
+ "high": 4413.07861328125,
857
+ "low": 4398.11328125,
858
+ "close": 4402.30126953125,
859
+ "volume": 2492.78515625,
860
+ "amount": 11033420.0
861
+ },
862
+ {
863
+ "timestamp": "2025-08-30T13:30:00+08:00",
864
+ "open": 4404.88037109375,
865
+ "high": 4410.33837890625,
866
+ "low": 4393.736328125,
867
+ "close": 4399.4814453125,
868
+ "volume": 2845.458984375,
869
+ "amount": 12485714.0
870
+ },
871
+ {
872
+ "timestamp": "2025-08-30T13:45:00+08:00",
873
+ "open": 4404.4873046875,
874
+ "high": 4407.4208984375,
875
+ "low": 4391.830078125,
876
+ "close": 4395.24951171875,
877
+ "volume": 2740.58203125,
878
+ "amount": 12119266.0
879
+ },
880
+ {
881
+ "timestamp": "2025-08-30T14:00:00+08:00",
882
+ "open": 4398.63330078125,
883
+ "high": 4405.14208984375,
884
+ "low": 4386.615234375,
885
+ "close": 4393.927734375,
886
+ "volume": 3936.732666015625,
887
+ "amount": 17217616.0
888
+ },
889
+ {
890
+ "timestamp": "2025-08-30T14:15:00+08:00",
891
+ "open": 4396.3203125,
892
+ "high": 4403.37841796875,
893
+ "low": 4384.75537109375,
894
+ "close": 4391.39697265625,
895
+ "volume": 3536.3125,
896
+ "amount": 15451760.0
897
+ },
898
+ {
899
+ "timestamp": "2025-08-30T14:30:00+08:00",
900
+ "open": 4400.17822265625,
901
+ "high": 4404.41748046875,
902
+ "low": 4379.8505859375,
903
+ "close": 4384.228515625,
904
+ "volume": 3587.30029296875,
905
+ "amount": 16007364.0
906
+ },
907
+ {
908
+ "timestamp": "2025-08-30T14:45:00+08:00",
909
+ "open": 4389.55224609375,
910
+ "high": 4398.9892578125,
911
+ "low": 4378.63427734375,
912
+ "close": 4387.65869140625,
913
+ "volume": 3590.80126953125,
914
+ "amount": 15753638.0
915
+ },
916
+ {
917
+ "timestamp": "2025-08-30T15:00:00+08:00",
918
+ "open": 4391.515625,
919
+ "high": 4396.142578125,
920
+ "low": 4374.96044921875,
921
+ "close": 4380.99658203125,
922
+ "volume": 4202.033203125,
923
+ "amount": 18451072.0
924
+ },
925
+ {
926
+ "timestamp": "2025-08-30T15:15:00+08:00",
927
+ "open": 4385.1337890625,
928
+ "high": 4396.03466796875,
929
+ "low": 4373.654296875,
930
+ "close": 4383.20458984375,
931
+ "volume": 3860.292236328125,
932
+ "amount": 16817400.0
933
+ },
934
+ {
935
+ "timestamp": "2025-08-30T15:30:00+08:00",
936
+ "open": 4386.3564453125,
937
+ "high": 4397.07568359375,
938
+ "low": 4372.4892578125,
939
+ "close": 4380.6318359375,
940
+ "volume": 4397.4423828125,
941
+ "amount": 19344552.0
942
+ },
943
+ {
944
+ "timestamp": "2025-08-30T15:45:00+08:00",
945
+ "open": 4388.64599609375,
946
+ "high": 4400.20068359375,
947
+ "low": 4376.72314453125,
948
+ "close": 4385.39599609375,
949
+ "volume": 3529.169921875,
950
+ "amount": 15449336.0
951
+ },
952
+ {
953
+ "timestamp": "2025-08-30T16:00:00+08:00",
954
+ "open": 4393.103515625,
955
+ "high": 4406.48095703125,
956
+ "low": 4376.4130859375,
957
+ "close": 4388.72119140625,
958
+ "volume": 4653.05078125,
959
+ "amount": 20416496.0
960
+ },
961
+ {
962
+ "timestamp": "2025-08-30T16:15:00+08:00",
963
+ "open": 4392.412109375,
964
+ "high": 4400.7255859375,
965
+ "low": 4380.5771484375,
966
+ "close": 4387.78466796875,
967
+ "volume": 3571.53466796875,
968
+ "amount": 15618524.0
969
+ },
970
+ {
971
+ "timestamp": "2025-08-30T16:30:00+08:00",
972
+ "open": 4392.3642578125,
973
+ "high": 4400.869140625,
974
+ "low": 4381.845703125,
975
+ "close": 4388.1064453125,
976
+ "volume": 3050.03564453125,
977
+ "amount": 13407420.0
978
+ },
979
+ {
980
+ "timestamp": "2025-08-30T16:45:00+08:00",
981
+ "open": 4392.14892578125,
982
+ "high": 4400.43408203125,
983
+ "low": 4381.8828125,
984
+ "close": 4388.71728515625,
985
+ "volume": 3258.2666015625,
986
+ "amount": 14306942.0
987
+ },
988
+ {
989
+ "timestamp": "2025-08-30T17:00:00+08:00",
990
+ "open": 4392.5986328125,
991
+ "high": 4399.025390625,
992
+ "low": 4379.68798828125,
993
+ "close": 4386.57666015625,
994
+ "volume": 3694.155517578125,
995
+ "amount": 16192044.0
996
+ },
997
+ {
998
+ "timestamp": "2025-08-30T17:15:00+08:00",
999
+ "open": 4390.42919921875,
1000
+ "high": 4394.9580078125,
1001
+ "low": 4377.2666015625,
1002
+ "close": 4382.47705078125,
1003
+ "volume": 3545.0595703125,
1004
+ "amount": 15581308.0
1005
+ },
1006
+ {
1007
+ "timestamp": "2025-08-30T17:30:00+08:00",
1008
+ "open": 4393.29833984375,
1009
+ "high": 4401.6435546875,
1010
+ "low": 4377.59619140625,
1011
+ "close": 4385.189453125,
1012
+ "volume": 3497.0185546875,
1013
+ "amount": 15394266.0
1014
+ },
1015
+ {
1016
+ "timestamp": "2025-08-30T17:45:00+08:00",
1017
+ "open": 4391.01513671875,
1018
+ "high": 4397.365234375,
1019
+ "low": 4379.25537109375,
1020
+ "close": 4385.8173828125,
1021
+ "volume": 3270.29345703125,
1022
+ "amount": 14417080.0
1023
+ },
1024
+ {
1025
+ "timestamp": "2025-08-30T18:00:00+08:00",
1026
+ "open": 4389.8994140625,
1027
+ "high": 4396.234375,
1028
+ "low": 4373.8671875,
1029
+ "close": 4381.0380859375,
1030
+ "volume": 3859.208251953125,
1031
+ "amount": 16922050.0
1032
+ },
1033
+ {
1034
+ "timestamp": "2025-08-30T18:15:00+08:00",
1035
+ "open": 4385.35009765625,
1036
+ "high": 4395.9814453125,
1037
+ "low": 4371.84619140625,
1038
+ "close": 4382.32373046875,
1039
+ "volume": 4179.4794921875,
1040
+ "amount": 18383076.0
1041
+ },
1042
+ {
1043
+ "timestamp": "2025-08-30T18:30:00+08:00",
1044
+ "open": 4384.7890625,
1045
+ "high": 4393.91845703125,
1046
+ "low": 4372.982421875,
1047
+ "close": 4381.81884765625,
1048
+ "volume": 3708.03662109375,
1049
+ "amount": 16251688.0
1050
+ },
1051
+ {
1052
+ "timestamp": "2025-08-30T18:45:00+08:00",
1053
+ "open": 4385.36376953125,
1054
+ "high": 4391.58154296875,
1055
+ "low": 4370.24853515625,
1056
+ "close": 4376.2255859375,
1057
+ "volume": 3531.42431640625,
1058
+ "amount": 15498266.0
1059
+ },
1060
+ {
1061
+ "timestamp": "2025-08-30T19:00:00+08:00",
1062
+ "open": 4379.822265625,
1063
+ "high": 4391.349609375,
1064
+ "low": 4362.35009765625,
1065
+ "close": 4377.1650390625,
1066
+ "volume": 5046.7177734375,
1067
+ "amount": 22327908.0
1068
+ },
1069
+ {
1070
+ "timestamp": "2025-08-30T19:15:00+08:00",
1071
+ "open": 4383.283203125,
1072
+ "high": 4397.99853515625,
1073
+ "low": 4366.62890625,
1074
+ "close": 4378.2568359375,
1075
+ "volume": 5746.00146484375,
1076
+ "amount": 25179304.0
1077
+ },
1078
+ {
1079
+ "timestamp": "2025-08-30T19:30:00+08:00",
1080
+ "open": 4380.6630859375,
1081
+ "high": 4394.68994140625,
1082
+ "low": 4369.58154296875,
1083
+ "close": 4381.57568359375,
1084
+ "volume": 4714.3505859375,
1085
+ "amount": 20650648.0
1086
+ },
1087
+ {
1088
+ "timestamp": "2025-08-30T19:45:00+08:00",
1089
+ "open": 4381.564453125,
1090
+ "high": 4391.97705078125,
1091
+ "low": 4368.33447265625,
1092
+ "close": 4378.0390625,
1093
+ "volume": 3612.40185546875,
1094
+ "amount": 15722476.0
1095
+ },
1096
+ {
1097
+ "timestamp": "2025-08-30T20:00:00+08:00",
1098
+ "open": 4383.794921875,
1099
+ "high": 4393.82861328125,
1100
+ "low": 4369.12744140625,
1101
+ "close": 4379.046875,
1102
+ "volume": 4308.6005859375,
1103
+ "amount": 18862996.0
1104
+ },
1105
+ {
1106
+ "timestamp": "2025-08-30T20:15:00+08:00",
1107
+ "open": 4386.48583984375,
1108
+ "high": 4397.3115234375,
1109
+ "low": 4375.50439453125,
1110
+ "close": 4384.826171875,
1111
+ "volume": 3685.409912109375,
1112
+ "amount": 16122716.0
1113
+ },
1114
+ {
1115
+ "timestamp": "2025-08-30T20:30:00+08:00",
1116
+ "open": 4389.767578125,
1117
+ "high": 4403.5791015625,
1118
+ "low": 4374.4814453125,
1119
+ "close": 4388.224609375,
1120
+ "volume": 4619.0830078125,
1121
+ "amount": 20723512.0
1122
+ },
1123
+ {
1124
+ "timestamp": "2025-08-30T20:45:00+08:00",
1125
+ "open": 4389.21533203125,
1126
+ "high": 4398.07958984375,
1127
+ "low": 4378.00634765625,
1128
+ "close": 4386.8154296875,
1129
+ "volume": 3414.56640625,
1130
+ "amount": 14915880.0
1131
+ }
1132
+ ],
1133
+ "actual_data": [],
1134
+ "analysis": {}
1135
+ }
webui/prediction_results/prediction_20250829_172152.json ADDED
@@ -0,0 +1,1135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "timestamp": "2025-08-29T17:21:52.373116",
3
+ "file_path": "ETHUSDT_1h",
4
+ "prediction_type": "Kronos model prediction (latest data)",
5
+ "prediction_params": {
6
+ "symbol": "ETHUSDT",
7
+ "interval": "1h",
8
+ "limit": 400,
9
+ "lookback": 400,
10
+ "pred_len": 120,
11
+ "temperature": 1.0,
12
+ "top_p": 0.9,
13
+ "sample_count": 3,
14
+ "start_date": "latest"
15
+ },
16
+ "input_data_summary": {
17
+ "rows": 400,
18
+ "columns": [
19
+ "open",
20
+ "high",
21
+ "low",
22
+ "close",
23
+ "volume",
24
+ "amount"
25
+ ],
26
+ "price_range": {
27
+ "open": {
28
+ "min": 4075.58,
29
+ "max": 4935.01
30
+ },
31
+ "high": {
32
+ "min": 4115.51,
33
+ "max": 4956.78
34
+ },
35
+ "low": {
36
+ "min": 4060.0,
37
+ "max": 4897.31
38
+ },
39
+ "close": {
40
+ "min": 4075.59,
41
+ "max": 4935.0
42
+ }
43
+ },
44
+ "last_values": {
45
+ "open": 4334.5,
46
+ "high": 4336.71,
47
+ "low": 4318.57,
48
+ "close": 4329.22
49
+ }
50
+ },
51
+ "prediction_results": [
52
+ {
53
+ "timestamp": "2025-08-29T18:00:00+08:00",
54
+ "open": 4282.4912109375,
55
+ "high": 4361.2294921875,
56
+ "low": 4234.88427734375,
57
+ "close": 4333.234375,
58
+ "volume": 41564.41015625,
59
+ "amount": 185734416.0
60
+ },
61
+ {
62
+ "timestamp": "2025-08-29T19:00:00+08:00",
63
+ "open": 4352.28759765625,
64
+ "high": 4410.75634765625,
65
+ "low": 4319.48388671875,
66
+ "close": 4363.30517578125,
67
+ "volume": 42923.6640625,
68
+ "amount": 192469344.0
69
+ },
70
+ {
71
+ "timestamp": "2025-08-29T20:00:00+08:00",
72
+ "open": 4382.796875,
73
+ "high": 4430.58544921875,
74
+ "low": 4314.2060546875,
75
+ "close": 4372.49755859375,
76
+ "volume": 41269.53515625,
77
+ "amount": 186288384.0
78
+ },
79
+ {
80
+ "timestamp": "2025-08-29T21:00:00+08:00",
81
+ "open": 4385.24951171875,
82
+ "high": 4419.478515625,
83
+ "low": 4358.85302734375,
84
+ "close": 4396.03173828125,
85
+ "volume": 21383.30859375,
86
+ "amount": 97311136.0
87
+ },
88
+ {
89
+ "timestamp": "2025-08-29T22:00:00+08:00",
90
+ "open": 4368.0087890625,
91
+ "high": 4440.18017578125,
92
+ "low": 4311.091796875,
93
+ "close": 4390.7529296875,
94
+ "volume": 29735.900390625,
95
+ "amount": 132181960.0
96
+ },
97
+ {
98
+ "timestamp": "2025-08-29T23:00:00+08:00",
99
+ "open": 4408.7294921875,
100
+ "high": 4463.3076171875,
101
+ "low": 4390.833984375,
102
+ "close": 4445.92236328125,
103
+ "volume": 28343.66015625,
104
+ "amount": 127795416.0
105
+ },
106
+ {
107
+ "timestamp": "2025-08-30T00:00:00+08:00",
108
+ "open": 4442.02197265625,
109
+ "high": 4481.58544921875,
110
+ "low": 4408.95068359375,
111
+ "close": 4432.58251953125,
112
+ "volume": 24402.416015625,
113
+ "amount": 110463672.0
114
+ },
115
+ {
116
+ "timestamp": "2025-08-30T01:00:00+08:00",
117
+ "open": 4444.79833984375,
118
+ "high": 4468.03466796875,
119
+ "low": 4411.03369140625,
120
+ "close": 4432.7431640625,
121
+ "volume": 19657.90234375,
122
+ "amount": 89113328.0
123
+ },
124
+ {
125
+ "timestamp": "2025-08-30T02:00:00+08:00",
126
+ "open": 4429.126953125,
127
+ "high": 4453.34521484375,
128
+ "low": 4399.0439453125,
129
+ "close": 4421.98046875,
130
+ "volume": 21773.8125,
131
+ "amount": 101144800.0
132
+ },
133
+ {
134
+ "timestamp": "2025-08-30T03:00:00+08:00",
135
+ "open": 4429.234375,
136
+ "high": 4436.63671875,
137
+ "low": 4387.5693359375,
138
+ "close": 4397.3525390625,
139
+ "volume": 28516.181640625,
140
+ "amount": 129596288.0
141
+ },
142
+ {
143
+ "timestamp": "2025-08-30T04:00:00+08:00",
144
+ "open": 4381.88671875,
145
+ "high": 4439.51806640625,
146
+ "low": 4374.1650390625,
147
+ "close": 4430.93994140625,
148
+ "volume": 23852.7734375,
149
+ "amount": 104623216.0
150
+ },
151
+ {
152
+ "timestamp": "2025-08-30T05:00:00+08:00",
153
+ "open": 4423.650390625,
154
+ "high": 4441.466796875,
155
+ "low": 4400.42529296875,
156
+ "close": 4420.38037109375,
157
+ "volume": 14760.81640625,
158
+ "amount": 67411320.0
159
+ },
160
+ {
161
+ "timestamp": "2025-08-30T06:00:00+08:00",
162
+ "open": 4420.02099609375,
163
+ "high": 4445.5625,
164
+ "low": 4397.81298828125,
165
+ "close": 4426.611328125,
166
+ "volume": 17794.2890625,
167
+ "amount": 80365224.0
168
+ },
169
+ {
170
+ "timestamp": "2025-08-30T07:00:00+08:00",
171
+ "open": 4424.841796875,
172
+ "high": 4445.0068359375,
173
+ "low": 4403.95947265625,
174
+ "close": 4427.0380859375,
175
+ "volume": 13068.787109375,
176
+ "amount": 58870920.0
177
+ },
178
+ {
179
+ "timestamp": "2025-08-30T08:00:00+08:00",
180
+ "open": 4428.99658203125,
181
+ "high": 4447.88134765625,
182
+ "low": 4410.6669921875,
183
+ "close": 4428.81201171875,
184
+ "volume": 11668.935546875,
185
+ "amount": 53033040.0
186
+ },
187
+ {
188
+ "timestamp": "2025-08-30T09:00:00+08:00",
189
+ "open": 4428.638671875,
190
+ "high": 4449.5693359375,
191
+ "low": 4412.54345703125,
192
+ "close": 4433.689453125,
193
+ "volume": 10685.646484375,
194
+ "amount": 48891032.0
195
+ },
196
+ {
197
+ "timestamp": "2025-08-30T10:00:00+08:00",
198
+ "open": 4438.92626953125,
199
+ "high": 4459.74560546875,
200
+ "low": 4411.07470703125,
201
+ "close": 4426.2802734375,
202
+ "volume": 13976.712890625,
203
+ "amount": 63491480.0
204
+ },
205
+ {
206
+ "timestamp": "2025-08-30T11:00:00+08:00",
207
+ "open": 4426.97412109375,
208
+ "high": 4449.53076171875,
209
+ "low": 4408.8984375,
210
+ "close": 4430.98095703125,
211
+ "volume": 18471.4375,
212
+ "amount": 83599296.0
213
+ },
214
+ {
215
+ "timestamp": "2025-08-30T12:00:00+08:00",
216
+ "open": 4428.93212890625,
217
+ "high": 4451.17529296875,
218
+ "low": 4413.1083984375,
219
+ "close": 4436.455078125,
220
+ "volume": 13301.4609375,
221
+ "amount": 60281400.0
222
+ },
223
+ {
224
+ "timestamp": "2025-08-30T13:00:00+08:00",
225
+ "open": 4439.32177734375,
226
+ "high": 4464.7841796875,
227
+ "low": 4427.1044921875,
228
+ "close": 4451.64599609375,
229
+ "volume": 14181.94140625,
230
+ "amount": 65029576.0
231
+ },
232
+ {
233
+ "timestamp": "2025-08-30T14:00:00+08:00",
234
+ "open": 4446.501953125,
235
+ "high": 4464.52685546875,
236
+ "low": 4429.45751953125,
237
+ "close": 4445.22265625,
238
+ "volume": 18854.76171875,
239
+ "amount": 85267664.0
240
+ },
241
+ {
242
+ "timestamp": "2025-08-30T15:00:00+08:00",
243
+ "open": 4435.689453125,
244
+ "high": 4471.3876953125,
245
+ "low": 4402.07421875,
246
+ "close": 4443.52734375,
247
+ "volume": 30264.58984375,
248
+ "amount": 136563376.0
249
+ },
250
+ {
251
+ "timestamp": "2025-08-30T16:00:00+08:00",
252
+ "open": 4441.3876953125,
253
+ "high": 4467.85107421875,
254
+ "low": 4422.400390625,
255
+ "close": 4452.53564453125,
256
+ "volume": 19033.14453125,
257
+ "amount": 86610320.0
258
+ },
259
+ {
260
+ "timestamp": "2025-08-30T17:00:00+08:00",
261
+ "open": 4465.3056640625,
262
+ "high": 4488.111328125,
263
+ "low": 4449.31884765625,
264
+ "close": 4473.35595703125,
265
+ "volume": 15677.2705078125,
266
+ "amount": 71282888.0
267
+ },
268
+ {
269
+ "timestamp": "2025-08-30T18:00:00+08:00",
270
+ "open": 4476.12939453125,
271
+ "high": 4488.830078125,
272
+ "low": 4455.40185546875,
273
+ "close": 4467.69189453125,
274
+ "volume": 18212.05859375,
275
+ "amount": 83243360.0
276
+ },
277
+ {
278
+ "timestamp": "2025-08-30T19:00:00+08:00",
279
+ "open": 4463.439453125,
280
+ "high": 4500.99755859375,
281
+ "low": 4454.453125,
282
+ "close": 4495.87451171875,
283
+ "volume": 23368.607421875,
284
+ "amount": 104860384.0
285
+ },
286
+ {
287
+ "timestamp": "2025-08-30T20:00:00+08:00",
288
+ "open": 4475.77294921875,
289
+ "high": 4525.76708984375,
290
+ "low": 4459.5869140625,
291
+ "close": 4489.36572265625,
292
+ "volume": 25631.126953125,
293
+ "amount": 116907184.0
294
+ },
295
+ {
296
+ "timestamp": "2025-08-30T21:00:00+08:00",
297
+ "open": 4500.6728515625,
298
+ "high": 4516.06201171875,
299
+ "low": 4467.33984375,
300
+ "close": 4486.43701171875,
301
+ "volume": 27984.078125,
302
+ "amount": 126316808.0
303
+ },
304
+ {
305
+ "timestamp": "2025-08-30T22:00:00+08:00",
306
+ "open": 4486.53125,
307
+ "high": 4519.55419921875,
308
+ "low": 4467.80810546875,
309
+ "close": 4495.17236328125,
310
+ "volume": 20402.703125,
311
+ "amount": 93258720.0
312
+ },
313
+ {
314
+ "timestamp": "2025-08-30T23:00:00+08:00",
315
+ "open": 4498.48779296875,
316
+ "high": 4538.9287109375,
317
+ "low": 4484.64453125,
318
+ "close": 4522.88671875,
319
+ "volume": 26715.03125,
320
+ "amount": 121698272.0
321
+ },
322
+ {
323
+ "timestamp": "2025-08-31T00:00:00+08:00",
324
+ "open": 4524.87255859375,
325
+ "high": 4621.68310546875,
326
+ "low": 4499.73486328125,
327
+ "close": 4561.12060546875,
328
+ "volume": 49894.8984375,
329
+ "amount": 223559728.0
330
+ },
331
+ {
332
+ "timestamp": "2025-08-31T01:00:00+08:00",
333
+ "open": 4559.73876953125,
334
+ "high": 4587.0126953125,
335
+ "low": 4533.35546875,
336
+ "close": 4568.609375,
337
+ "volume": 36147.6328125,
338
+ "amount": 165589824.0
339
+ },
340
+ {
341
+ "timestamp": "2025-08-31T02:00:00+08:00",
342
+ "open": 4567.623046875,
343
+ "high": 4598.1220703125,
344
+ "low": 4537.68798828125,
345
+ "close": 4569.8056640625,
346
+ "volume": 35936.2109375,
347
+ "amount": 160498608.0
348
+ },
349
+ {
350
+ "timestamp": "2025-08-31T03:00:00+08:00",
351
+ "open": 4573.375,
352
+ "high": 4600.0380859375,
353
+ "low": 4548.076171875,
354
+ "close": 4575.8720703125,
355
+ "volume": 30765.90234375,
356
+ "amount": 136558160.0
357
+ },
358
+ {
359
+ "timestamp": "2025-08-31T04:00:00+08:00",
360
+ "open": 4567.00927734375,
361
+ "high": 4590.32958984375,
362
+ "low": 4541.55126953125,
363
+ "close": 4569.16162109375,
364
+ "volume": 22723.94921875,
365
+ "amount": 103475488.0
366
+ },
367
+ {
368
+ "timestamp": "2025-08-31T05:00:00+08:00",
369
+ "open": 4553.81298828125,
370
+ "high": 4608.302734375,
371
+ "low": 4506.8779296875,
372
+ "close": 4545.40283203125,
373
+ "volume": 34898.23046875,
374
+ "amount": 160449520.0
375
+ },
376
+ {
377
+ "timestamp": "2025-08-31T06:00:00+08:00",
378
+ "open": 4550.72216796875,
379
+ "high": 4573.18310546875,
380
+ "low": 4529.55419921875,
381
+ "close": 4552.14599609375,
382
+ "volume": 20792.20703125,
383
+ "amount": 94255152.0
384
+ },
385
+ {
386
+ "timestamp": "2025-08-31T07:00:00+08:00",
387
+ "open": 4552.25732421875,
388
+ "high": 4581.28759765625,
389
+ "low": 4536.3828125,
390
+ "close": 4563.97509765625,
391
+ "volume": 22510.587890625,
392
+ "amount": 101917040.0
393
+ },
394
+ {
395
+ "timestamp": "2025-08-31T08:00:00+08:00",
396
+ "open": 4561.23095703125,
397
+ "high": 4580.966796875,
398
+ "low": 4530.3701171875,
399
+ "close": 4544.28466796875,
400
+ "volume": 14353.876953125,
401
+ "amount": 65249832.0
402
+ },
403
+ {
404
+ "timestamp": "2025-08-31T09:00:00+08:00",
405
+ "open": 4539.275390625,
406
+ "high": 4580.435546875,
407
+ "low": 4495.68701171875,
408
+ "close": 4527.88623046875,
409
+ "volume": 26263.330078125,
410
+ "amount": 120025968.0
411
+ },
412
+ {
413
+ "timestamp": "2025-08-31T10:00:00+08:00",
414
+ "open": 4517.18701171875,
415
+ "high": 4541.53564453125,
416
+ "low": 4482.7607421875,
417
+ "close": 4515.69873046875,
418
+ "volume": 34039.8203125,
419
+ "amount": 152376688.0
420
+ },
421
+ {
422
+ "timestamp": "2025-08-31T11:00:00+08:00",
423
+ "open": 4523.0908203125,
424
+ "high": 4567.8837890625,
425
+ "low": 4500.87548828125,
426
+ "close": 4524.88671875,
427
+ "volume": 34569.421875,
428
+ "amount": 157650848.0
429
+ },
430
+ {
431
+ "timestamp": "2025-08-31T12:00:00+08:00",
432
+ "open": 4521.97607421875,
433
+ "high": 4554.66796875,
434
+ "low": 4492.2939453125,
435
+ "close": 4518.55908203125,
436
+ "volume": 29718.35546875,
437
+ "amount": 133930088.0
438
+ },
439
+ {
440
+ "timestamp": "2025-08-31T13:00:00+08:00",
441
+ "open": 4512.5498046875,
442
+ "high": 4543.76611328125,
443
+ "low": 4498.451171875,
444
+ "close": 4519.244140625,
445
+ "volume": 26441.828125,
446
+ "amount": 121619864.0
447
+ },
448
+ {
449
+ "timestamp": "2025-08-31T14:00:00+08:00",
450
+ "open": 4518.3701171875,
451
+ "high": 4539.8212890625,
452
+ "low": 4493.92431640625,
453
+ "close": 4520.0908203125,
454
+ "volume": 19778.484375,
455
+ "amount": 89527424.0
456
+ },
457
+ {
458
+ "timestamp": "2025-08-31T15:00:00+08:00",
459
+ "open": 4515.78857421875,
460
+ "high": 4536.0283203125,
461
+ "low": 4492.599609375,
462
+ "close": 4519.13720703125,
463
+ "volume": 19288.88671875,
464
+ "amount": 87809264.0
465
+ },
466
+ {
467
+ "timestamp": "2025-08-31T16:00:00+08:00",
468
+ "open": 4511.93701171875,
469
+ "high": 4534.26904296875,
470
+ "low": 4489.48095703125,
471
+ "close": 4516.10986328125,
472
+ "volume": 23741.22265625,
473
+ "amount": 107723896.0
474
+ },
475
+ {
476
+ "timestamp": "2025-08-31T17:00:00+08:00",
477
+ "open": 4505.01904296875,
478
+ "high": 4531.9072265625,
479
+ "low": 4491.36474609375,
480
+ "close": 4512.52734375,
481
+ "volume": 37825.3046875,
482
+ "amount": 166912688.0
483
+ },
484
+ {
485
+ "timestamp": "2025-08-31T18:00:00+08:00",
486
+ "open": 4511.67529296875,
487
+ "high": 4537.43798828125,
488
+ "low": 4485.5615234375,
489
+ "close": 4495.9404296875,
490
+ "volume": 27621.8984375,
491
+ "amount": 125282592.0
492
+ },
493
+ {
494
+ "timestamp": "2025-08-31T19:00:00+08:00",
495
+ "open": 4484.9697265625,
496
+ "high": 4529.4853515625,
497
+ "low": 4471.75,
498
+ "close": 4513.2138671875,
499
+ "volume": 29425.353515625,
500
+ "amount": 132308856.0
501
+ },
502
+ {
503
+ "timestamp": "2025-08-31T20:00:00+08:00",
504
+ "open": 4512.09716796875,
505
+ "high": 4541.115234375,
506
+ "low": 4498.42724609375,
507
+ "close": 4524.0126953125,
508
+ "volume": 20643.24609375,
509
+ "amount": 93192464.0
510
+ },
511
+ {
512
+ "timestamp": "2025-08-31T21:00:00+08:00",
513
+ "open": 4528.1806640625,
514
+ "high": 4561.1640625,
515
+ "low": 4511.8212890625,
516
+ "close": 4544.34228515625,
517
+ "volume": 25064.21484375,
518
+ "amount": 114048264.0
519
+ },
520
+ {
521
+ "timestamp": "2025-08-31T22:00:00+08:00",
522
+ "open": 4546.2099609375,
523
+ "high": 4575.966796875,
524
+ "low": 4506.91259765625,
525
+ "close": 4550.21923828125,
526
+ "volume": 26318.26953125,
527
+ "amount": 119626688.0
528
+ },
529
+ {
530
+ "timestamp": "2025-08-31T23:00:00+08:00",
531
+ "open": 4557.521484375,
532
+ "high": 4577.556640625,
533
+ "low": 4541.15478515625,
534
+ "close": 4554.4970703125,
535
+ "volume": 23678.0859375,
536
+ "amount": 107923184.0
537
+ },
538
+ {
539
+ "timestamp": "2025-09-01T00:00:00+08:00",
540
+ "open": 4543.68798828125,
541
+ "high": 4581.7158203125,
542
+ "low": 4528.740234375,
543
+ "close": 4565.15576171875,
544
+ "volume": 25644.58984375,
545
+ "amount": 116082848.0
546
+ },
547
+ {
548
+ "timestamp": "2025-09-01T01:00:00+08:00",
549
+ "open": 4579.47607421875,
550
+ "high": 4603.38134765625,
551
+ "low": 4550.8212890625,
552
+ "close": 4568.69189453125,
553
+ "volume": 27431.19921875,
554
+ "amount": 123956640.0
555
+ },
556
+ {
557
+ "timestamp": "2025-09-01T02:00:00+08:00",
558
+ "open": 4573.646484375,
559
+ "high": 4592.0595703125,
560
+ "low": 4554.6572265625,
561
+ "close": 4572.03759765625,
562
+ "volume": 25802.00390625,
563
+ "amount": 118018480.0
564
+ },
565
+ {
566
+ "timestamp": "2025-09-01T03:00:00+08:00",
567
+ "open": 4566.6142578125,
568
+ "high": 4581.90576171875,
569
+ "low": 4545.2978515625,
570
+ "close": 4558.9677734375,
571
+ "volume": 24661.32421875,
572
+ "amount": 112163976.0
573
+ },
574
+ {
575
+ "timestamp": "2025-09-01T04:00:00+08:00",
576
+ "open": 4552.43603515625,
577
+ "high": 4585.63037109375,
578
+ "low": 4529.01025390625,
579
+ "close": 4554.7109375,
580
+ "volume": 16708.92578125,
581
+ "amount": 77551888.0
582
+ },
583
+ {
584
+ "timestamp": "2025-09-01T05:00:00+08:00",
585
+ "open": 4558.77001953125,
586
+ "high": 4584.6142578125,
587
+ "low": 4528.00146484375,
588
+ "close": 4559.5107421875,
589
+ "volume": 17492.35546875,
590
+ "amount": 80375648.0
591
+ },
592
+ {
593
+ "timestamp": "2025-09-01T06:00:00+08:00",
594
+ "open": 4564.69189453125,
595
+ "high": 4595.5302734375,
596
+ "low": 4538.27001953125,
597
+ "close": 4562.96826171875,
598
+ "volume": 24135.6484375,
599
+ "amount": 111718280.0
600
+ },
601
+ {
602
+ "timestamp": "2025-09-01T07:00:00+08:00",
603
+ "open": 4567.8740234375,
604
+ "high": 4609.28955078125,
605
+ "low": 4555.80029296875,
606
+ "close": 4590.12890625,
607
+ "volume": 24418.46484375,
608
+ "amount": 111945312.0
609
+ },
610
+ {
611
+ "timestamp": "2025-09-01T08:00:00+08:00",
612
+ "open": 4585.9306640625,
613
+ "high": 4629.86474609375,
614
+ "low": 4554.5703125,
615
+ "close": 4597.60693359375,
616
+ "volume": 45699.41796875,
617
+ "amount": 208058048.0
618
+ },
619
+ {
620
+ "timestamp": "2025-09-01T09:00:00+08:00",
621
+ "open": 4598.7119140625,
622
+ "high": 4632.7607421875,
623
+ "low": 4570.5556640625,
624
+ "close": 4599.759765625,
625
+ "volume": 55701.24609375,
626
+ "amount": 251193984.0
627
+ },
628
+ {
629
+ "timestamp": "2025-09-01T10:00:00+08:00",
630
+ "open": 4600.978515625,
631
+ "high": 4629.189453125,
632
+ "low": 4584.8876953125,
633
+ "close": 4618.509765625,
634
+ "volume": 34998.15234375,
635
+ "amount": 159200544.0
636
+ },
637
+ {
638
+ "timestamp": "2025-09-01T11:00:00+08:00",
639
+ "open": 4623.90673828125,
640
+ "high": 4666.21142578125,
641
+ "low": 4594.66650390625,
642
+ "close": 4639.1611328125,
643
+ "volume": 49190.8046875,
644
+ "amount": 218169760.0
645
+ },
646
+ {
647
+ "timestamp": "2025-09-01T12:00:00+08:00",
648
+ "open": 4637.67041015625,
649
+ "high": 4650.14697265625,
650
+ "low": 4608.2109375,
651
+ "close": 4624.9609375,
652
+ "volume": 29688.853515625,
653
+ "amount": 135407440.0
654
+ },
655
+ {
656
+ "timestamp": "2025-09-01T13:00:00+08:00",
657
+ "open": 4621.27734375,
658
+ "high": 4648.79541015625,
659
+ "low": 4603.6044921875,
660
+ "close": 4627.67529296875,
661
+ "volume": 35657.02734375,
662
+ "amount": 163058880.0
663
+ },
664
+ {
665
+ "timestamp": "2025-09-01T14:00:00+08:00",
666
+ "open": 4620.064453125,
667
+ "high": 4647.880859375,
668
+ "low": 4600.5810546875,
669
+ "close": 4630.55859375,
670
+ "volume": 30879.0625,
671
+ "amount": 140533136.0
672
+ },
673
+ {
674
+ "timestamp": "2025-09-01T15:00:00+08:00",
675
+ "open": 4630.5087890625,
676
+ "high": 4653.1083984375,
677
+ "low": 4609.7763671875,
678
+ "close": 4633.50146484375,
679
+ "volume": 29725.2421875,
680
+ "amount": 135044912.0
681
+ },
682
+ {
683
+ "timestamp": "2025-09-01T16:00:00+08:00",
684
+ "open": 4625.20361328125,
685
+ "high": 4680.0771484375,
686
+ "low": 4594.08544921875,
687
+ "close": 4629.0224609375,
688
+ "volume": 32395.45703125,
689
+ "amount": 149289776.0
690
+ },
691
+ {
692
+ "timestamp": "2025-09-01T17:00:00+08:00",
693
+ "open": 4618.87646484375,
694
+ "high": 4660.0810546875,
695
+ "low": 4586.17578125,
696
+ "close": 4616.03076171875,
697
+ "volume": 40876.6875,
698
+ "amount": 185788720.0
699
+ },
700
+ {
701
+ "timestamp": "2025-09-01T18:00:00+08:00",
702
+ "open": 4612.5302734375,
703
+ "high": 4631.13427734375,
704
+ "low": 4579.44287109375,
705
+ "close": 4603.97705078125,
706
+ "volume": 44852.16796875,
707
+ "amount": 201618656.0
708
+ },
709
+ {
710
+ "timestamp": "2025-09-01T19:00:00+08:00",
711
+ "open": 4596.31201171875,
712
+ "high": 4615.9482421875,
713
+ "low": 4551.85302734375,
714
+ "close": 4571.9765625,
715
+ "volume": 32732.37109375,
716
+ "amount": 147656352.0
717
+ },
718
+ {
719
+ "timestamp": "2025-09-01T20:00:00+08:00",
720
+ "open": 4553.04443359375,
721
+ "high": 4598.6025390625,
722
+ "low": 4526.375,
723
+ "close": 4574.17333984375,
724
+ "volume": 45349.90234375,
725
+ "amount": 205476416.0
726
+ },
727
+ {
728
+ "timestamp": "2025-09-01T21:00:00+08:00",
729
+ "open": 4535.736328125,
730
+ "high": 4593.24072265625,
731
+ "low": 4484.623046875,
732
+ "close": 4544.16064453125,
733
+ "volume": 50606.8515625,
734
+ "amount": 228750848.0
735
+ },
736
+ {
737
+ "timestamp": "2025-09-01T22:00:00+08:00",
738
+ "open": 4546.3798828125,
739
+ "high": 4574.67333984375,
740
+ "low": 4518.16015625,
741
+ "close": 4546.830078125,
742
+ "volume": 34987.0390625,
743
+ "amount": 157888992.0
744
+ },
745
+ {
746
+ "timestamp": "2025-09-01T23:00:00+08:00",
747
+ "open": 4539.12841796875,
748
+ "high": 4574.484375,
749
+ "low": 4536.7412109375,
750
+ "close": 4570.06396484375,
751
+ "volume": 41529.95703125,
752
+ "amount": 184078144.0
753
+ },
754
+ {
755
+ "timestamp": "2025-09-02T00:00:00+08:00",
756
+ "open": 4573.04443359375,
757
+ "high": 4606.427734375,
758
+ "low": 4546.5576171875,
759
+ "close": 4579.04150390625,
760
+ "volume": 45473.6953125,
761
+ "amount": 205677600.0
762
+ },
763
+ {
764
+ "timestamp": "2025-09-02T01:00:00+08:00",
765
+ "open": 4562.56005859375,
766
+ "high": 4578.8427734375,
767
+ "low": 4512.76318359375,
768
+ "close": 4533.95947265625,
769
+ "volume": 51186.8671875,
770
+ "amount": 231018080.0
771
+ },
772
+ {
773
+ "timestamp": "2025-09-02T02:00:00+08:00",
774
+ "open": 4542.1748046875,
775
+ "high": 4573.12939453125,
776
+ "low": 4522.77783203125,
777
+ "close": 4552.6904296875,
778
+ "volume": 28601.126953125,
779
+ "amount": 129992528.0
780
+ },
781
+ {
782
+ "timestamp": "2025-09-02T03:00:00+08:00",
783
+ "open": 4522.6396484375,
784
+ "high": 4578.81689453125,
785
+ "low": 4459.96044921875,
786
+ "close": 4558.75,
787
+ "volume": 41981.30859375,
788
+ "amount": 188149632.0
789
+ },
790
+ {
791
+ "timestamp": "2025-09-02T04:00:00+08:00",
792
+ "open": 4559.30322265625,
793
+ "high": 4581.96240234375,
794
+ "low": 4525.0703125,
795
+ "close": 4553.23681640625,
796
+ "volume": 36516.484375,
797
+ "amount": 165957904.0
798
+ },
799
+ {
800
+ "timestamp": "2025-09-02T05:00:00+08:00",
801
+ "open": 4570.3994140625,
802
+ "high": 4598.8740234375,
803
+ "low": 4522.03173828125,
804
+ "close": 4544.6806640625,
805
+ "volume": 50358.54296875,
806
+ "amount": 227078368.0
807
+ },
808
+ {
809
+ "timestamp": "2025-09-02T06:00:00+08:00",
810
+ "open": 4544.51806640625,
811
+ "high": 4590.9169921875,
812
+ "low": 4500.47705078125,
813
+ "close": 4557.3349609375,
814
+ "volume": 39941.49609375,
815
+ "amount": 178581312.0
816
+ },
817
+ {
818
+ "timestamp": "2025-09-02T07:00:00+08:00",
819
+ "open": 4553.31884765625,
820
+ "high": 4580.443359375,
821
+ "low": 4497.81884765625,
822
+ "close": 4559.482421875,
823
+ "volume": 32119.33984375,
824
+ "amount": 143948256.0
825
+ },
826
+ {
827
+ "timestamp": "2025-09-02T08:00:00+08:00",
828
+ "open": 4554.10888671875,
829
+ "high": 4582.85595703125,
830
+ "low": 4533.85986328125,
831
+ "close": 4564.11181640625,
832
+ "volume": 30980.69140625,
833
+ "amount": 140477920.0
834
+ },
835
+ {
836
+ "timestamp": "2025-09-02T09:00:00+08:00",
837
+ "open": 4558.92333984375,
838
+ "high": 4581.53125,
839
+ "low": 4531.6513671875,
840
+ "close": 4551.93212890625,
841
+ "volume": 33996.38671875,
842
+ "amount": 151220016.0
843
+ },
844
+ {
845
+ "timestamp": "2025-09-02T10:00:00+08:00",
846
+ "open": 4575.06787109375,
847
+ "high": 4607.47314453125,
848
+ "low": 4522.3984375,
849
+ "close": 4549.4853515625,
850
+ "volume": 42086.359375,
851
+ "amount": 190869376.0
852
+ },
853
+ {
854
+ "timestamp": "2025-09-02T11:00:00+08:00",
855
+ "open": 4544.6484375,
856
+ "high": 4584.3056640625,
857
+ "low": 4518.8369140625,
858
+ "close": 4554.1689453125,
859
+ "volume": 47829.125,
860
+ "amount": 217350336.0
861
+ },
862
+ {
863
+ "timestamp": "2025-09-02T12:00:00+08:00",
864
+ "open": 4543.71826171875,
865
+ "high": 4579.34716796875,
866
+ "low": 4523.8759765625,
867
+ "close": 4551.22265625,
868
+ "volume": 39084.0859375,
869
+ "amount": 176619664.0
870
+ },
871
+ {
872
+ "timestamp": "2025-09-02T13:00:00+08:00",
873
+ "open": 4528.4853515625,
874
+ "high": 4599.97021484375,
875
+ "low": 4511.2265625,
876
+ "close": 4575.837890625,
877
+ "volume": 48299.79296875,
878
+ "amount": 217204640.0
879
+ },
880
+ {
881
+ "timestamp": "2025-09-02T14:00:00+08:00",
882
+ "open": 4567.57177734375,
883
+ "high": 4607.9677734375,
884
+ "low": 4530.62744140625,
885
+ "close": 4586.640625,
886
+ "volume": 36176.4609375,
887
+ "amount": 164095360.0
888
+ },
889
+ {
890
+ "timestamp": "2025-09-02T15:00:00+08:00",
891
+ "open": 4588.90478515625,
892
+ "high": 4646.93505859375,
893
+ "low": 4577.720703125,
894
+ "close": 4602.759765625,
895
+ "volume": 58277.03125,
896
+ "amount": 267393888.0
897
+ },
898
+ {
899
+ "timestamp": "2025-09-02T16:00:00+08:00",
900
+ "open": 4607.30126953125,
901
+ "high": 4632.18701171875,
902
+ "low": 4572.208984375,
903
+ "close": 4604.7998046875,
904
+ "volume": 40777.45703125,
905
+ "amount": 185327616.0
906
+ },
907
+ {
908
+ "timestamp": "2025-09-02T17:00:00+08:00",
909
+ "open": 4587.7373046875,
910
+ "high": 4626.07177734375,
911
+ "low": 4576.98291015625,
912
+ "close": 4617.84716796875,
913
+ "volume": 41108.71484375,
914
+ "amount": 185267584.0
915
+ },
916
+ {
917
+ "timestamp": "2025-09-02T18:00:00+08:00",
918
+ "open": 4594.61572265625,
919
+ "high": 4657.50927734375,
920
+ "low": 4554.33251953125,
921
+ "close": 4631.79345703125,
922
+ "volume": 78342.4609375,
923
+ "amount": 357262880.0
924
+ },
925
+ {
926
+ "timestamp": "2025-09-02T19:00:00+08:00",
927
+ "open": 4610.7978515625,
928
+ "high": 4696.26123046875,
929
+ "low": 4592.91259765625,
930
+ "close": 4631.50439453125,
931
+ "volume": 55026.8046875,
932
+ "amount": 257604768.0
933
+ },
934
+ {
935
+ "timestamp": "2025-09-02T20:00:00+08:00",
936
+ "open": 4641.12939453125,
937
+ "high": 4685.048828125,
938
+ "low": 4615.712890625,
939
+ "close": 4654.58837890625,
940
+ "volume": 54181.140625,
941
+ "amount": 246508448.0
942
+ },
943
+ {
944
+ "timestamp": "2025-09-02T21:00:00+08:00",
945
+ "open": 4637.77978515625,
946
+ "high": 4682.42138671875,
947
+ "low": 4610.5810546875,
948
+ "close": 4665.576171875,
949
+ "volume": 49693.25,
950
+ "amount": 225123552.0
951
+ },
952
+ {
953
+ "timestamp": "2025-09-02T22:00:00+08:00",
954
+ "open": 4681.29248046875,
955
+ "high": 4740.318359375,
956
+ "low": 4597.82177734375,
957
+ "close": 4661.62451171875,
958
+ "volume": 60103.78515625,
959
+ "amount": 267436096.0
960
+ },
961
+ {
962
+ "timestamp": "2025-09-02T23:00:00+08:00",
963
+ "open": 4633.21435546875,
964
+ "high": 4710.7861328125,
965
+ "low": 4590.373046875,
966
+ "close": 4670.8994140625,
967
+ "volume": 55723.1484375,
968
+ "amount": 251792720.0
969
+ },
970
+ {
971
+ "timestamp": "2025-09-03T00:00:00+08:00",
972
+ "open": 4662.916015625,
973
+ "high": 4708.58056640625,
974
+ "low": 4635.18994140625,
975
+ "close": 4685.55712890625,
976
+ "volume": 59321.28125,
977
+ "amount": 268025536.0
978
+ },
979
+ {
980
+ "timestamp": "2025-09-03T01:00:00+08:00",
981
+ "open": 4688.93896484375,
982
+ "high": 4734.8369140625,
983
+ "low": 4644.1123046875,
984
+ "close": 4670.93994140625,
985
+ "volume": 51711.8046875,
986
+ "amount": 231927232.0
987
+ },
988
+ {
989
+ "timestamp": "2025-09-03T02:00:00+08:00",
990
+ "open": 4700.83154296875,
991
+ "high": 4733.08837890625,
992
+ "low": 4619.01025390625,
993
+ "close": 4650.29052734375,
994
+ "volume": 58490.3359375,
995
+ "amount": 262043264.0
996
+ },
997
+ {
998
+ "timestamp": "2025-09-03T03:00:00+08:00",
999
+ "open": 4645.990234375,
1000
+ "high": 4683.6787109375,
1001
+ "low": 4609.28662109375,
1002
+ "close": 4649.47265625,
1003
+ "volume": 61720.171875,
1004
+ "amount": 276722752.0
1005
+ },
1006
+ {
1007
+ "timestamp": "2025-09-03T04:00:00+08:00",
1008
+ "open": 4614.64697265625,
1009
+ "high": 4655.0869140625,
1010
+ "low": 4592.39697265625,
1011
+ "close": 4627.66357421875,
1012
+ "volume": 51670.4375,
1013
+ "amount": 232529280.0
1014
+ },
1015
+ {
1016
+ "timestamp": "2025-09-03T05:00:00+08:00",
1017
+ "open": 4610.529296875,
1018
+ "high": 4671.7578125,
1019
+ "low": 4584.61083984375,
1020
+ "close": 4645.67529296875,
1021
+ "volume": 74684.5703125,
1022
+ "amount": 338857920.0
1023
+ },
1024
+ {
1025
+ "timestamp": "2025-09-03T06:00:00+08:00",
1026
+ "open": 4643.1103515625,
1027
+ "high": 4667.91748046875,
1028
+ "low": 4590.53515625,
1029
+ "close": 4614.19970703125,
1030
+ "volume": 59175.0625,
1031
+ "amount": 268682688.0
1032
+ },
1033
+ {
1034
+ "timestamp": "2025-09-03T07:00:00+08:00",
1035
+ "open": 4609.8515625,
1036
+ "high": 4640.9453125,
1037
+ "low": 4520.59423828125,
1038
+ "close": 4598.2822265625,
1039
+ "volume": 72765.0859375,
1040
+ "amount": 325068256.0
1041
+ },
1042
+ {
1043
+ "timestamp": "2025-09-03T08:00:00+08:00",
1044
+ "open": 4603.22412109375,
1045
+ "high": 4634.6767578125,
1046
+ "low": 4572.61474609375,
1047
+ "close": 4598.98583984375,
1048
+ "volume": 43102.9765625,
1049
+ "amount": 197034048.0
1050
+ },
1051
+ {
1052
+ "timestamp": "2025-09-03T09:00:00+08:00",
1053
+ "open": 4593.30810546875,
1054
+ "high": 4633.56103515625,
1055
+ "low": 4552.8984375,
1056
+ "close": 4581.37548828125,
1057
+ "volume": 51989.66015625,
1058
+ "amount": 234605216.0
1059
+ },
1060
+ {
1061
+ "timestamp": "2025-09-03T10:00:00+08:00",
1062
+ "open": 4575.935546875,
1063
+ "high": 4641.82080078125,
1064
+ "low": 4497.005859375,
1065
+ "close": 4603.63623046875,
1066
+ "volume": 47871.4765625,
1067
+ "amount": 214601440.0
1068
+ },
1069
+ {
1070
+ "timestamp": "2025-09-03T11:00:00+08:00",
1071
+ "open": 4609.21337890625,
1072
+ "high": 4645.482421875,
1073
+ "low": 4578.58740234375,
1074
+ "close": 4612.64599609375,
1075
+ "volume": 35885.48046875,
1076
+ "amount": 162265200.0
1077
+ },
1078
+ {
1079
+ "timestamp": "2025-09-03T12:00:00+08:00",
1080
+ "open": 4633.18310546875,
1081
+ "high": 4665.02978515625,
1082
+ "low": 4602.62548828125,
1083
+ "close": 4638.02978515625,
1084
+ "volume": 53854.7734375,
1085
+ "amount": 248254848.0
1086
+ },
1087
+ {
1088
+ "timestamp": "2025-09-03T13:00:00+08:00",
1089
+ "open": 4646.67626953125,
1090
+ "high": 4653.615234375,
1091
+ "low": 4592.232421875,
1092
+ "close": 4604.73486328125,
1093
+ "volume": 49153.4453125,
1094
+ "amount": 221965440.0
1095
+ },
1096
+ {
1097
+ "timestamp": "2025-09-03T14:00:00+08:00",
1098
+ "open": 4606.6630859375,
1099
+ "high": 4637.55029296875,
1100
+ "low": 4580.646484375,
1101
+ "close": 4610.39453125,
1102
+ "volume": 39266.15625,
1103
+ "amount": 178462880.0
1104
+ },
1105
+ {
1106
+ "timestamp": "2025-09-03T15:00:00+08:00",
1107
+ "open": 4606.39208984375,
1108
+ "high": 4638.4033203125,
1109
+ "low": 4580.3828125,
1110
+ "close": 4618.9287109375,
1111
+ "volume": 43400.5703125,
1112
+ "amount": 195518320.0
1113
+ },
1114
+ {
1115
+ "timestamp": "2025-09-03T16:00:00+08:00",
1116
+ "open": 4588.09130859375,
1117
+ "high": 4660.7490234375,
1118
+ "low": 4518.75439453125,
1119
+ "close": 4625.62841796875,
1120
+ "volume": 51758.93359375,
1121
+ "amount": 237718176.0
1122
+ },
1123
+ {
1124
+ "timestamp": "2025-09-03T17:00:00+08:00",
1125
+ "open": 4626.99951171875,
1126
+ "high": 4668.74755859375,
1127
+ "low": 4595.6923828125,
1128
+ "close": 4633.265625,
1129
+ "volume": 50869.5859375,
1130
+ "amount": 233086032.0
1131
+ }
1132
+ ],
1133
+ "actual_data": [],
1134
+ "analysis": {}
1135
+ }