# AmazingData 金融数据服务平台 - 完整实现方案 ## 一、项目概述 基于AmazingData SDK构建的金融数据服务平台,提供历史数据缓存、实时数据订阅、批量数据管理等功能。 --- ## 二、技术架构 ``` ┌─────────────────────────────────────────────────────────────────────────────────┐ │ 前端层 (Frontend) │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ 登录页面 │ │ 配置管理页面 │ │ 数据查询页面 │ │ 测试中心页面 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────────┐ │ API网关层 (API Gateway) │ │ ┌─────────────────────────────────────────────────────────────────────────┐ │ │ │ FastAPI + Uvicorn │ JWT认证 │ 限流/熔断 │ 日志/监控 │ CORS │ │ │ └─────────────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────────┐ │ 业务服务层 (Services) │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ 认证服务 │ │ 配置服务 │ │ 历史数据服务 │ │ 实时数据服务 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ 缓存管理服务 │ │ 财务数据服务 │ │ 基础数据服务 │ │ 测试服务 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────────┐ │ 数据访问层 (Data Access) │ │ ┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐ │ │ │ SQLAlchemy ORM │ │ Redis Cache │ │ AmazingData SDK │ │ │ └────────────────────┘ └────────────────────┘ └────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────────┐ │ 数据存储层 (Storage) │ │ ┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐ │ │ │ PostgreSQL │ │ Redis │ │ File System │ │ │ │ (主数据库) │ │ (缓存/消息队列) │ │ (日志/导出) │ │ │ └────────────────────┘ └────────────────────┘ └────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────────────┘ ``` --- ## 三、技术栈选型 | 层级 | 技术 | 版本 | 说明 | |------|------|------|------| | 后端框架 | FastAPI | ^0.104.0 | 高性能异步Web框架 | | ORM | SQLAlchemy | ^2.0.0 | 数据库ORM | | 数据库 | PostgreSQL | 15+ | 主数据库 | | 缓存 | Redis | 7+ | 缓存与消息队列 | | 前端 | Vue3 + TypeScript | ^3.3.0 | 前端框架 | | UI组件 | Element Plus | ^2.4.0 | UI组件库 | | 图表 | ECharts | ^5.4.0 | K线图展示 | | 认证 | JWT + bcrypt | - | 用户认证 | | 任务调度 | APScheduler | ^3.10.0 | 定时任务 | | SDK | AmazingData | 1.0.24 | 数据源SDK | --- ## 四、数据库设计 ### 4.1 实体关系图 (ER Diagram) ``` ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ users │ │ sdk_configs │ │ system_configs │ ├──────────────────┤ ├──────────────────┤ ├──────────────────┤ │ id (PK) │ │ id (PK) │ │ id (PK) │ │ username │ │ name │ │ key │ │ password_hash │ │ username │ │ value │ │ is_active │ │ password │ │ description │ │ created_at │ │ host │ │ created_at │ │ updated_at │ │ port │ │ updated_at │ └──────────────────┘ │ is_active │ └──────────────────┘ │ created_at │ └──────────────────┘ │ ▼ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │stock_kline_daily │ │ stock_kline_min │ │stock_kline_other │ ├──────────────────┤ ├──────────────────┤ ├──────────────────┤ │ id (PK) │ │ id (PK) │ │ id (PK) │ │ code │ │ code │ │ code │ │ trade_date │ │ trade_datetime │ │ period_type │ │ open │ │ open │ │ trade_date │ │ high │ │ high │ │ open │ │ low │ │ low │ │ high │ │ close │ │ close │ │ low │ │ volume │ │ volume │ │ close │ │ amount │ │ amount │ │ volume │ │ created_at │ │ created_at │ │ amount │ └──────────────────┘ └──────────────────┘ │ created_at │ └──────────────────┘ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │future_kline_daily│ │ future_kline_min │ │realtime_snapshot │ ├──────────────────┤ ├──────────────────┤ ├──────────────────┤ │ id (PK) │ │ id (PK) │ │ id (PK) │ │ code │ │ code │ │ code │ │ trade_date │ │ trade_datetime │ │ trade_time │ │ open │ │ open │ │ pre_close │ │ high │ │ high │ │ last │ │ low │ │ low │ │ open │ │ close │ │ close │ │ high │ │ volume │ │ volume │ │ low │ │ amount │ │ amount │ │ volume │ │ settle │ │ settle │ │ amount │ │ open_interest │ │ open_interest │ │ ...其他字段 │ │ created_at │ │ created_at │ │ created_at │ └──────────────────┘ └──────────────────┘ │ expires_at │ └──────────────────┘ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ cache_tasks │ │ cache_records │ │ api_test_logs │ ├──────────────────┤ ├──────────────────┤ ├──────────────────┤ │ id (PK) │ │ id (PK) │ │ id (PK) │ │ task_name │ │ task_id (FK) │ │ test_name │ │ task_type │ │ code │ │ api_endpoint │ │ security_type │ │ trade_date │ │ request_params │ │ start_date │ │ status │ │ response_data │ │ end_date │ │ record_count │ │ status_code │ │ status │ │ created_at │ │ execution_time │ │ progress │ └──────────────────┘ │ error_message │ │ total_count │ │ created_at │ │ success_count │ └──────────────────┘ │ error_count │ │ created_at │ │ completed_at │ └──────────────────┘ ``` ### 4.2 表结构详细定义 #### 4.2.1 用户表 (users) ```sql CREATE TABLE users ( id SERIAL PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ); ``` #### 4.2.2 SDK配置表 (sdk_configs) ```sql CREATE TABLE sdk_configs ( id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL, username VARCHAR(100) NOT NULL, password VARCHAR(255) NOT NULL, host VARCHAR(100) NOT NULL, port INTEGER NOT NULL, local_path VARCHAR(255) DEFAULT './amazing_data_cache/', is_active BOOLEAN DEFAULT TRUE, is_default BOOLEAN DEFAULT FALSE, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ); ``` #### 4.2.3 股票日线数据表 (stock_kline_daily) ```sql CREATE TABLE stock_kline_daily ( id BIGSERIAL PRIMARY KEY, code VARCHAR(20) NOT NULL, trade_date DATE NOT NULL, open DECIMAL(12, 4) NOT NULL, high DECIMAL(12, 4) NOT NULL, low DECIMAL(12, 4) NOT NULL, close DECIMAL(12, 4) NOT NULL, volume BIGINT NOT NULL, amount DECIMAL(18, 4) NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, UNIQUE(code, trade_date) ); CREATE INDEX idx_stock_daily_code_date ON stock_kline_daily(code, trade_date); CREATE INDEX idx_stock_daily_trade_date ON stock_kline_daily(trade_date); ``` #### 4.2.4 股票分钟数据表 (stock_kline_min) ```sql CREATE TABLE stock_kline_min ( id BIGSERIAL PRIMARY KEY, code VARCHAR(20) NOT NULL, period_type VARCHAR(10) NOT NULL, -- min1, min5, min15, min30, min60 trade_datetime TIMESTAMP NOT NULL, open DECIMAL(12, 4) NOT NULL, high DECIMAL(12, 4) NOT NULL, low DECIMAL(12, 4) NOT NULL, close DECIMAL(12, 4) NOT NULL, volume BIGINT NOT NULL, amount DECIMAL(18, 4) NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, UNIQUE(code, period_type, trade_datetime) ); CREATE INDEX idx_stock_min_code_period_datetime ON stock_kline_min(code, period_type, trade_datetime); CREATE INDEX idx_stock_min_trade_datetime ON stock_kline_min(trade_datetime); ``` #### 4.2.5 期货日线数据表 (future_kline_daily) ```sql CREATE TABLE future_kline_daily ( id BIGSERIAL PRIMARY KEY, code VARCHAR(20) NOT NULL, trade_date DATE NOT NULL, open DECIMAL(12, 4) NOT NULL, high DECIMAL(12, 4) NOT NULL, low DECIMAL(12, 4) NOT NULL, close DECIMAL(12, 4) NOT NULL, volume BIGINT NOT NULL, amount DECIMAL(18, 4) NOT NULL, settle DECIMAL(12, 4), open_interest BIGINT, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, UNIQUE(code, trade_date) ); CREATE INDEX idx_future_daily_code_date ON future_kline_daily(code, trade_date); CREATE INDEX idx_future_daily_trade_date ON future_kline_daily(trade_date); ``` #### 4.2.6 期货分钟数据表 (future_kline_min) ```sql CREATE TABLE future_kline_min ( id BIGSERIAL PRIMARY KEY, code VARCHAR(20) NOT NULL, period_type VARCHAR(10) NOT NULL, trade_datetime TIMESTAMP NOT NULL, open DECIMAL(12, 4) NOT NULL, high DECIMAL(12, 4) NOT NULL, low DECIMAL(12, 4) NOT NULL, close DECIMAL(12, 4) NOT NULL, volume BIGINT NOT NULL, amount DECIMAL(18, 4) NOT NULL, settle DECIMAL(12, 4), open_interest BIGINT, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, UNIQUE(code, period_type, trade_datetime) ); CREATE INDEX idx_future_min_code_period_datetime ON future_kline_min(code, period_type, trade_datetime); ``` #### 4.2.7 实时快照数据表 (realtime_snapshot) ```sql CREATE TABLE realtime_snapshot ( id BIGSERIAL PRIMARY KEY, code VARCHAR(20) NOT NULL, security_type VARCHAR(20) NOT NULL, -- stock, future, index, etc. trade_time TIMESTAMP NOT NULL, pre_close DECIMAL(12, 4), last DECIMAL(12, 4), open DECIMAL(12, 4), high DECIMAL(12, 4), low DECIMAL(12, 4), close DECIMAL(12, 4), volume BIGINT, amount DECIMAL(18, 4), ask_price1 DECIMAL(12, 4), ask_volume1 INTEGER, bid_price1 DECIMAL(12, 4), bid_volume1 INTEGER, -- ... 其他快照字段 created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, expires_at TIMESTAMP WITH TIME ZONE NOT NULL -- 7天后过期 ); CREATE INDEX idx_snapshot_code_time ON realtime_snapshot(code, trade_time); CREATE INDEX idx_snapshot_expires ON realtime_snapshot(expires_at); ``` #### 4.2.8 缓存任务表 (cache_tasks) ```sql CREATE TABLE cache_tasks ( id SERIAL PRIMARY KEY, task_name VARCHAR(200) NOT NULL, task_type VARCHAR(50) NOT NULL, -- 'detect_missing', 'cache_data' security_type VARCHAR(20) NOT NULL, -- 'stock', 'future' period_type VARCHAR(10), -- daily, min1, etc. start_date DATE NOT NULL, end_date DATE NOT NULL, status VARCHAR(20) DEFAULT 'pending', -- pending, running, completed, failed progress DECIMAL(5, 2) DEFAULT 0, total_count INTEGER DEFAULT 0, success_count INTEGER DEFAULT 0, error_count INTEGER DEFAULT 0, error_message TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, started_at TIMESTAMP WITH TIME ZONE, completed_at TIMESTAMP WITH TIME ZONE ); ``` #### 4.2.9 缓存记录表 (cache_records) ```sql CREATE TABLE cache_records ( id BIGSERIAL PRIMARY KEY, task_id INTEGER REFERENCES cache_tasks(id), code VARCHAR(20) NOT NULL, trade_date DATE NOT NULL, record_count INTEGER NOT NULL, status VARCHAR(20) DEFAULT 'success', error_message TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ); ``` #### 4.2.10 API测试日志表 (api_test_logs) ```sql CREATE TABLE api_test_logs ( id BIGSERIAL PRIMARY KEY, test_name VARCHAR(200) NOT NULL, api_category VARCHAR(50) NOT NULL, api_endpoint VARCHAR(200) NOT NULL, request_method VARCHAR(10) NOT NULL, request_params JSONB, response_data JSONB, status_code INTEGER, execution_time_ms INTEGER, is_success BOOLEAN DEFAULT FALSE, error_message TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX idx_test_logs_category ON api_test_logs(api_category); CREATE INDEX idx_test_logs_created ON api_test_logs(created_at); ``` --- ## 五、API接口设计 ### 5.1 认证相关接口 | 方法 | 路径 | 说明 | |------|------|------| | POST | /api/v1/auth/login | 用户登录 | | POST | /api/v1/auth/logout | 用户登出 | | GET | /api/v1/auth/me | 获取当前用户信息 | | POST | /api/v1/auth/refresh | 刷新Token | ### 5.2 配置管理接口 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/configs/sdk | 获取SDK配置列表 | | GET | /api/v1/configs/sdk/{id} | 获取指定SDK配置 | | POST | /api/v1/configs/sdk | 创建SDK配置 | | PUT | /api/v1/configs/sdk/{id} | 更新SDK配置 | | DELETE | /api/v1/configs/sdk/{id} | 删除SDK配置 | | POST | /api/v1/configs/sdk/{id}/test | 测试SDK连接 | | POST | /api/v1/configs/sdk/{id}/set-default | 设为默认配置 | ### 5.3 基础数据接口 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/base/codes | 获取代码列表 | | GET | /api/v1/base/codes/{code}/info | 获取证券信息 | | GET | /api/v1/base/calendar | 获取交易日历 | | GET | /api/v1/base/calendar/trading-days | 获取指定区间交易日 | ### 5.4 历史行情数据接口 #### 股票历史数据 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/stock/kline | 获取股票K线数据(单个/批量) | | GET | /api/v1/stock/kline/{code}/chart | 获取股票K线图数据 | | GET | /api/v1/stock/snapshot | 获取股票历史快照数据 | #### 期货历史数据 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/future/kline | 获取期货K线数据(单个/批量) | | GET | /api/v1/future/kline/{code}/chart | 获取期货K线图数据 | | GET | /api/v1/future/snapshot | 获取期货历史快照数据 | ### 5.5 实时数据接口 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/realtime/snapshot | 获取最新快照数据 | | POST | /api/v1/realtime/subscribe | 开始实时数据订阅 | | DELETE | /api/v1/realtime/subscribe | 停止实时数据订阅 | | GET | /api/v1/realtime/subscribe/status | 获取订阅状态 | | GET | /api/v1/realtime/snapshot/stream | WebSocket实时数据流 | ### 5.6 财务数据接口 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/finance/balance-sheet | 获取资产负债表 | | GET | /api/v1/finance/cash-flow | 获取现金流量表 | | GET | /api/v1/finance/income | 获取利润表 | | GET | /api/v1/finance/profit-express | 获取业绩快报 | | GET | /api/v1/finance/profit-notice | 获取业绩预告 | ### 5.7 股东股本数据接口 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/shareholder/top10 | 获取十大股东数据 | | GET | /api/v1/shareholder/count | 获取股东户数 | | GET | /api/v1/shareholder/equity | 获取股本结构 | ### 5.8 融资融券数据接口 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/margin/summary | 获取融资融券汇总 | | GET | /api/v1/margin/detail | 获取融资融券明细 | ### 5.9 指数数据接口 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/index/constituents | 获取指数成分股 | | GET | /api/v1/index/weights | 获取指数权重 | ### 5.10 ETF数据接口 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/etf/pcf | 获取ETF申赎数据 | | GET | /api/v1/etf/share | 获取ETF份额数据 | ### 5.11 可转债数据接口 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/kzz/issuance | 获取可转债发行数据 | ### 5.12 数据缓存管理接口 | 方法 | 路径 | 说明 | |------|------|------| | POST | /api/v1/cache/detect-missing | 检测缺失数据 | | POST | /api/v1/cache/batch-cache | 批量缓存数据 | | GET | /api/v1/cache/tasks | 获取缓存任务列表 | | GET | /api/v1/cache/tasks/{id} | 获取任务详情 | | DELETE | /api/v1/cache/tasks/{id} | 取消任务 | | GET | /api/v1/cache/status/{code} | 获取代码缓存状态 | ### 5.13 测试中心接口 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/test/categories | 获取测试分类 | | GET | /api/v1/test/endpoints | 获取所有接口列表 | | POST | /api/v1/test/run | 执行单个接口测试 | | POST | /api/v1/test/run-all | 执行全部接口测试 | | GET | /api/v1/test/history | 获取测试历史记录 | | GET | /api/v1/test/history/{id} | 获取单次测试详情 | --- ## 六、核心业务逻辑 ### 6.1 数据获取流程 (缓存优先) ``` 用户请求 → 检查本地缓存 → 有数据 → 直接返回 ↓ 无数据/不完整 ↓ 调用AmazingData SDK → 获取数据 → 写入缓存 → 返回数据 ``` ### 6.2 缺失数据检测算法 ```python # 伪代码 def detect_missing_data(code, start_date, end_date, period='daily'): # 1. 获取指定区间的交易日列表 trading_days = get_trading_days(start_date, end_date) # 2. 查询数据库中已有数据的日期 existing_data = query_db_for_existing_dates(code, start_date, end_date, period) # 3. 计算每个交易日的数据条数 missing_dates = [] for date in trading_days: expected_count = get_expected_count_for_date(code, date, period) actual_count = existing_data.get(date, 0) # 4. 偏差超过10%认为缺失 if actual_count < expected_count * 0.9: missing_dates.append({ 'date': date, 'expected': expected_count, 'actual': actual_count, 'missing_ratio': 1 - actual_count / expected_count }) return missing_dates ``` ### 6.3 数据去重插入逻辑 ```python # 伪代码 def cache_data_with_dedup(code, data_df, period='daily'): # 1. 构建唯一键 if period == 'daily': existing = query_existing_data(code, data_df.index.min(), data_df.index.max()) else: existing = query_existing_data(code, data_df.index.min(), data_df.index.max(), period) # 2. 比较核心数据字段 (open, high, low, close, volume) core_columns = ['open', 'high', 'low', 'close', 'volume'] to_insert = [] for idx, row in data_df.iterrows(): key = (code, idx) if period == 'daily' else (code, period, idx) if key in existing: # 3. 数据已存在,比较核心字段 existing_row = existing[key] is_same = all( abs(row[col] - existing_row[col]) < 0.0001 for col in core_columns ) if is_same: continue # 数据相同,跳过 to_insert.append(row) # 4. 批量插入新数据 if to_insert: batch_insert(to_insert) ``` ### 6.4 实时数据订阅流程 ``` 前端请求订阅 → 后端建立WebSocket连接 → 初始化AmazingData订阅 ↓ 前端 ← WebSocket推送 ← 回调函数接收数据 ← SDK实时推送 ``` --- ## 七、前端页面设计 ### 7.1 页面结构 ``` ┌─────────────────────────────────────────────────────────────┐ │ [Logo] AmazingData金融数据服务平台 [用户] [退出] │ ├─────────────────────────────────────────────────────────────┤ │ ┌──────┐ │ │ │ 首页 │ ┌──────────────────────────────────────────┐ │ │ ├──────┤ │ │ │ │ │数据查询│ │ 页面内容区域 │ │ │ ├──────┤ │ │ │ │ │配置管理│ │ │ │ │ ├──────┤ │ │ │ │ │缓存管理│ │ │ │ │ ├──────┤ │ │ │ │ │测试中心│ │ │ │ │ └──────┘ └──────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` ### 7.2 登录页面 - 用户名/密码输入框 - 记住我选项 - 登录按钮 ### 7.3 配置管理页面 - SDK配置列表(卡片形式) - 添加/编辑配置表单(弹窗) - 测试连接按钮 - 设为默认按钮 ### 7.4 数据查询页面 - **K线图查询** - 代码输入(支持股票/期货) - 时间区间选择(默认1年) - 周期选择(日线/分钟线) - K线图展示(ECharts) - 数据表格展示 - **批量数据查询** - 多代码输入(支持批量粘贴) - 时间区间选择 - 数据列表展示(分页) - 导出功能 ### 7.5 缓存管理页面 - **缺失数据检测** - 品种选择(股票/期货) - 时间区间选择 - 检测结果列表 - 一键缓存按钮 - **缓存任务管理** - 任务列表(进度条展示) - 任务详情(成功/失败统计) - 取消任务按钮 ### 7.6 测试中心页面 - 接口分类树(基础数据/历史数据/实时数据/财务数据/...) - 接口列表(表格) - 单个接口测试(参数表单 + 结果展示) - 一键全部测试按钮 - 测试历史记录 --- ## 八、项目目录结构 ``` amazing-data-service/ ├── backend/ │ ├── app/ │ │ ├── __init__.py │ │ ├── main.py # FastAPI入口 │ │ ├── config.py # 配置管理 │ │ ├── dependencies.py # 依赖注入 │ │ ├── core/ │ │ │ ├── __init__.py │ │ │ ├── security.py # JWT认证 │ │ │ ├── exceptions.py # 异常处理 │ │ │ └── middleware.py # 中间件 │ │ ├── api/ │ │ │ ├── __init__.py │ │ │ ├── v1/ │ │ │ │ ├── __init__.py │ │ │ │ ├── auth.py # 认证接口 │ │ │ │ ├── configs.py # 配置接口 │ │ │ │ ├── base_data.py # 基础数据接口 │ │ │ │ ├── stock.py # 股票数据接口 │ │ │ │ ├── future.py # 期货数据接口 │ │ │ │ ├── realtime.py # 实时数据接口 │ │ │ │ ├── finance.py # 财务数据接口 │ │ │ │ ├── shareholder.py # 股东数据接口 │ │ │ │ ├── margin.py # 融资融券接口 │ │ │ │ ├── index.py # 指数数据接口 │ │ │ │ ├── etf.py # ETF数据接口 │ │ │ │ ├── kzz.py # 可转债数据接口 │ │ │ │ ├── cache.py # 缓存管理接口 │ │ │ │ └── test.py # 测试中心接口 │ │ ├── models/ │ │ │ ├── __init__.py │ │ │ ├── user.py # 用户模型 │ │ │ ├── config.py # 配置模型 │ │ │ ├── stock.py # 股票数据模型 │ │ │ ├── future.py # 期货数据模型 │ │ │ ├── realtime.py # 实时数据模型 │ │ │ ├── finance.py # 财务数据模型 │ │ │ ├── cache.py # 缓存任务模型 │ │ │ └── test.py # 测试日志模型 │ │ ├── schemas/ │ │ │ ├── __init__.py │ │ │ ├── auth.py # 认证Schema │ │ │ ├── base.py # 基础Schema │ │ │ ├── config.py # 配置Schema │ │ │ ├── kline.py # K线Schema │ │ │ ├── finance.py # 财务Schema │ │ │ ├── cache.py # 缓存Schema │ │ │ └── test.py # 测试Schema │ │ ├── services/ │ │ │ ├── __init__.py │ │ │ ├── auth_service.py # 认证服务 │ │ │ ├── config_service.py # 配置服务 │ │ │ ├── amazing_data_service.py # SDK封装服务 │ │ │ ├── cache_service.py # 缓存服务 │ │ │ ├── stock_service.py # 股票数据服务 │ │ │ ├── future_service.py # 期货数据服务 │ │ │ ├── realtime_service.py # 实时数据服务 │ │ │ ├── finance_service.py # 财务数据服务 │ │ │ ├── base_data_service.py # 基础数据服务 │ │ │ └── test_service.py # 测试服务 │ │ ├── db/ │ │ │ ├── __init__.py │ │ │ ├── base.py # 数据库基础 │ │ │ └── session.py # 会话管理 │ │ └── utils/ │ │ ├── __init__.py │ │ ├── date_utils.py # 日期工具 │ │ ├── data_utils.py # 数据处理工具 │ │ └── validators.py # 验证器 │ ├── alembic/ # 数据库迁移 │ ├── tests/ │ ├── requirements.txt │ └── Dockerfile ├── frontend/ │ ├── src/ │ │ ├── api/ # API接口封装 │ │ ├── components/ # 公共组件 │ │ ├── views/ # 页面视图 │ │ │ ├── Login.vue │ │ │ ├── Dashboard.vue │ │ │ ├── ConfigManager.vue │ │ │ ├── DataQuery/ │ │ │ │ ├── KlineChart.vue │ │ │ │ └── BatchQuery.vue │ │ │ ├── CacheManager/ │ │ │ │ ├── DetectMissing.vue │ │ │ │ └── TaskManager.vue │ │ │ └── TestCenter/ │ │ │ ├── ApiTest.vue │ │ │ └── TestHistory.vue │ │ ├── router/ │ │ ├── store/ │ │ ├── utils/ │ │ └── App.vue │ ├── public/ │ ├── package.json │ └── vite.config.ts ├── database/ │ ├── init.sql # 数据库初始化脚本 │ └── migrations/ ├── docker/ │ ├── docker-compose.yml │ └── nginx.conf ├── docs/ │ ├── api.md │ └── deploy.md ├── scripts/ │ ├── init_db.py │ └── create_admin.py └── README.md ``` --- ## 九、部署架构 ``` ┌─────────────────────────────────────────────────────────────────────┐ │ Docker Compose │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Nginx │ │ Frontend │ │ Backend │ │ │ │ (反向代理) │ │ (Vue3) │ │ (FastAPI) │ │ │ └──────┬───────┘ └──────────────┘ └──────┬───────┘ │ │ │ │ │ │ └────────────────────────────────────┘ │ │ │ │ │ ┌────────────┼────────────┐ │ │ ▼ ▼ ▼ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ PostgreSQL │ │ Redis │ │ (AmazingData │ │ │ │ (主数据库) │ │ (缓存) │ │ SDK连接) │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────────────┘ ``` --- ## 十、关键功能实现要点 ### 10.1 AmazingData SDK适配器 ```python class AmazingDataAdapter: """SDK适配器,封装AmazingData所有接口""" def __init__(self, config: SDKConfig): self.config = config self._ad = None self._base_data = None self._market_data = None self._info_data = None self._calendar = None def connect(self) -> bool: """建立连接""" import AmazingData as ad ad.login(**self.config.to_dict()) self._ad = ad self._base_data = ad.BaseData() self._info_data = ad.InfoData() self._calendar = self._base_data.get_calendar() self._market_data = ad.MarketData(self._calendar) return True # 基础数据接口 def get_code_list(self, security_type: str) -> List[str]: ... def get_code_info(self, security_type: str) -> pd.DataFrame: ... def get_trading_calendar(self, market: str) -> List[int]: ... # 历史行情接口 def get_kline(self, codes, start_date, end_date, period) -> Dict[str, pd.DataFrame]: ... def get_snapshot(self, codes, start_date, end_date) -> Dict[str, pd.DataFrame]: ... # 财务数据接口 def get_balance_sheet(self, codes, start_date, end_date) -> Dict[str, pd.DataFrame]: ... def get_cash_flow(self, codes, start_date, end_date) -> Dict[str, pd.DataFrame]: ... def get_income_statement(self, codes, start_date, end_date) -> Dict[str, pd.DataFrame]: ... # 其他所有接口... ``` ### 10.2 缓存服务 ```python class CacheService: """数据缓存服务""" def get_kline_with_cache(self, code: str, start_date: date, end_date: date, period: str) -> pd.DataFrame: """优先从缓存获取,否则从SDK获取并缓存""" # 1. 查询本地数据库 cached_data = self.db.query_kline(code, start_date, end_date, period) # 2. 检查数据完整性 if self._is_data_complete(cached_data, start_date, end_date): return cached_data # 3. 从SDK获取缺失数据 missing_ranges = self._find_missing_ranges(cached_data, start_date, end_date) for range_start, range_end in missing_ranges: sdk_data = self.sdk.get_kline(code, range_start, range_end, period) self.db.save_kline(code, sdk_data, period) # 4. 重新查询完整数据 return self.db.query_kline(code, start_date, end_date, period) ``` ### 10.3 实时数据WebSocket ```python class RealtimeManager: """实时数据管理器""" def __init__(self): self.subscribers: Dict[str, Set[WebSocket]] = {} self.sdk_subscriber = None async def subscribe(self, websocket: WebSocket, codes: List[str]): """客户端订阅""" await websocket.accept() for code in codes: if code not in self.subscribers: self.subscribers[code] = set() # 启动SDK订阅 self._start_sdk_subscription(code) self.subscribers[code].add(websocket) def _on_sdk_data(self, code: str, data: dict): """SDK数据回调""" # 1. 保存到数据库(带过期时间) self.db.save_realtime(data) # 2. 推送给所有订阅者 for ws in self.subscribers.get(code, []): asyncio.create_task(ws.send_json(data)) ``` --- ## 十一、开发计划 | 阶段 | 任务 | 预计时间 | |------|------|----------| | 第一阶段 | 项目初始化、数据库设计、基础框架搭建 | 2天 | | 第二阶段 | 认证模块、配置管理模块开发 | 2天 | | 第三阶段 | SDK适配器、基础数据接口开发 | 3天 | | 第四阶段 | 历史数据接口(股票/期货)、缓存逻辑 | 4天 | | 第五阶段 | 实时数据订阅功能 | 3天 | | 第六阶段 | 财务/股东/融资融券等数据接口 | 3天 | | 第七阶段 | 批量缓存管理功能 | 3天 | | 第八阶段 | 测试中心功能 | 2天 | | 第九阶段 | 前端页面开发 | 5天 | | 第十阶段 | 集成测试、部署文档 | 2天 | **总计:约29天** --- ## 十二、风险与注意事项 1. **数据准确性**:AmazingData SDK返回的数据需要验证,建议增加数据校验逻辑 2. **并发性能**:大量数据查询时需要控制并发,避免SDK连接超时 3. **存储空间**:历史数据量巨大,需要定期归档或清理 4. **SDK连接**:AmazingData SDK需要保持连接,建议使用连接池 5. **实时数据延迟**:网络延迟可能导致实时数据推送不及时 --- *文档版本: 1.0* *创建日期: 2025年*