16 KiB
可转债轮动分析系统 V1.0
软件设计说明书
第一章 引言
1.1 编写目的
本文档是「可转债轮动分析系统 V1.0」的软件设计说明书,旨在详细描述系统的总体架构设计、模块划分、数据结构、接口设计、关键算法及安全与性能设计,作为软件著作权登记的技术文档依据,同时为系统的后续维护与功能迭代提供设计参考。
1.2 项目背景
可转债作为一种兼具债券属性与股票属性的金融工具,近年来市场规模不断扩大。投资者在进行可转债投资决策时,需要对全市场可转债的实时行情进行监控,并通过历史数据回测验证轮动策略的有效性。传统的人工分析与手工数据整理方式效率低下、时效性差。本系统旨在构建一个集行情浏览、策略回测、数据入库与任务管理于一体的可转债分析平台,提升可转债量化研究的效率与准确性。
1.3 术语定义
| 术语 | 说明 |
|---|---|
| 可转债 | 可转换公司债券,可在特定条件下转换为公司股票 |
| 溢价率 | 转股溢价率,衡量可转债价格相对其转股价值的溢价程度 |
| 转股价值 | 可转债按当前转股价转换后对应的股票市值 |
| 轮动策略 | 定期按特定指标排序、调仓的投资策略 |
| 全量入库 | 拉取全部可转债的历史K线数据并写入数据库 |
| 增量同步 | 仅同步自上次入库日期之后新增的数据 |
| 熔断 | 数据源连续失败达到阈值后,短时间内直接切换备用源的机制 |
| 限速器 | 令牌桶算法实现的请求速率控制组件 |
第二章 总体设计
2.1 设计目标
- 提供可转债实时行情浏览与多维度排序、筛选能力。
- 提供多策略历史回测能力,输出收益、回撤、夏普比率等关键指标。
- 提供可转债历史数据的高效入库能力,支持全量与增量两种同步方式。
- 提供异步任务管理能力,实现入库任务进度的实时展示。
- 保证系统在数据源异常、缓存服务不可用等情况下的可用性。
2.2 系统架构
系统采用 B/S 架构,总体分为三层:
- 表示层(View):基于 HTML、JavaScript、CSS 开发的单页应用,包含登录页与主页(实时行情、策略回测、数据管理三个标签页)。
- 控制层(Controller):基于 Go 语言 net/http 开发的路由与控制器,负责接收 HTTP 请求、权限校验、参数解析与响应封装。
- 模型层(Model):包含数据模型定义、存储接口抽象、数据源访问与业务服务四部分。
系统整体遵循 MVC 设计模式,控制层与模型层通过接口解耦,便于替换数据源与存储实现。
2.3 技术选型
| 技术 | 用途 | 选型理由 |
|---|---|---|
| Go 1.25 | 后端开发语言 | 高并发、静态编译、部署简单 |
| net/http | HTTP 服务框架 | 标准库,无额外依赖 |
| SQLite 3 | 数据持久化 | 单文件、零配置、适合个人分析场景 |
| modernc.org/sqlite | SQLite 驱动 | 纯 Go 实现,无 CGO 依赖 |
| Redis | 任务状态缓存 | 高性能内存存储,支持实时状态查询 |
| go-redis/v9 | Redis 客户端 | 官方维护的 Go Redis 客户端 |
| Chart.js | 前端图表 | 开源图表库,用于回测净值曲线展示 |
| Docker | 容器化部署 | 便于 Redis 等中间件的一键启动 |
| golang.org/x/crypto | 密码加密 | 提供 bcrypt 密码哈希算法 |
第三章 模块设计
系统按功能划分为六大模块,各模块职责如下。
3.1 用户认证模块
负责用户注册、登录、登出与权限校验。
功能组成:
- 注册:用户名 + 邮箱 + 验证码 + 密码。
- 登录:支持用户名密码登录与邮箱验证码登录两种方式。
- 权限校验:通过 token 识别登录用户,未登录访问受保护资源时自动跳转或返回未授权。
- 管理员账号:系统初始化时自动创建管理员账号。
关键设计:
- 密码使用 bcrypt 算法加盐哈希存储,不保存明文。
- 登录成功后生成随机 token,前端同时写入 localStorage 与 cookie,保证前后端鉴权一致。
- 验证码设置有效期与使用状态,验证后标记已使用。
3.2 行情模块
负责可转债实时行情与历史K线数据的获取与展示。
功能组成:
- 实时行情:获取全量可转债实时报价,过滤已退市转债。
- 历史K线:获取指定转债的日K线数据。
- 搜索与排序:支持按代码、名称、正股搜索,按多字段排序。
关键设计:
- 采用主备数据源机制,主数据源为东方财富接口,备用数据源为腾讯财经接口。
- 主数据源失败时自动切换备用数据源,保证数据可用性。
3.3 策略回测模块
负责轮动策略的历史回测与结果展示。
功能组成:
- 三种轮动策略:低价轮动、双低轮动、溢价率轮动。
- 回测参数配置:起止日期、初始资金、持仓数量、调仓周期、价格区间等。
- 基本面过滤:排除正股 ST、资产负债率过高或净利润为负的转债。
- 结果展示:累计收益、年化收益、最大回撤、夏普比率、波动率、胜率等指标及净值曲线。
关键设计:
- 回测引擎以交易日为步长遍历历史数据,按调仓周期执行策略选股与调仓。
- 账户模型模拟现金与持仓,计算每日净值。
- 同时计算等权全转债基准,用于超额收益对比。
3.4 数据入库模块
负责可转债历史数据的入库与同步。
功能组成:
- 全量入库:拉取全部转债的历史K线。
- 增量同步:仅同步已入库转债的新增数据。
- 断点续跑:全量模式下跳过已入库转债,增量模式基于最后K线日期确定起点。
关键设计:
- 采用并发拉取 + 批量写入的架构,多 worker 并发获取数据,单 collector 串行批量写入数据库。
- SQLite 连接数限制为 1,避免写锁竞争。
- K线写入采用幂等 upsert 语义,重复写入自动跳过。
3.5 异步任务模块
负责数据入库任务的异步执行与状态管理。
功能组成:
- 任务创建:创建全量或增量入库任务。
- 任务执行:异步并发执行入库任务。
- 任务查询:查询任务列表与单个任务状态。
- 任务取消:取消运行中的任务。
- 实时进度:任务进度实时写入缓存,前端轮询展示。
关键设计:
- 任务管理器统一管理任务注册表与全局限速器,支持多任务并发。
- 任务状态同时写入 Redis(实时)与 SQLite(持久化),Redis 不可用时自动降级到 SQLite。
- 全局限速器采用令牌桶算法,控制数据源请求速率,避免高频请求被限流。
3.6 数据源模块
负责外部行情数据的访问与容错。
功能组成:
- 东财数据源:实时行情、历史K线、转债列表、基本面数据。
- 腾讯数据源:历史K线备用源、实时报价。
- 主备切换:主数据源失败时自动切换备用源。
- 熔断机制:主源连续失败达到阈值后进入熔断窗口。
关键设计:
- 定义统一的数据源接口(MarketDataSource),屏蔽不同数据源的实现差异。
- 熔断窗口结束后自动放行一次探测请求,成功则解除熔断。
第四章 数据库设计
4.1 数据库选型
系统采用 SQLite 3 作为持久化数据库。SQLite 为单文件嵌入式数据库,无需独立部署,适合个人分析场景;同时 SQL 语句遵循通用标准语法,便于后续迁移至 PostgreSQL 等数据库。
4.2 核心数据表
(1)可转债K线表(convertible_kline)
存储每只可转债的日K线数据。
| 字段 | 类型 | 说明 |
|---|---|---|
| code | TEXT | 转债代码 |
| date | TEXT | 交易日期 |
| open | REAL | 开盘价 |
| close | REAL | 收盘价 |
| high | REAL | 最高价 |
| low | REAL | 最低价 |
| volume | INTEGER | 成交量 |
| amount | REAL | 成交额 |
| convert_price | REAL | 转股价 |
| convert_value | REAL | 转股价值 |
| premium_rate | REAL | 溢价率 |
主键:code + date 联合主键。
(2)转债基础信息表(convert_bond)
存储转债的基本信息。
| 字段 | 类型 | 说明 |
|---|---|---|
| code | TEXT | 转债代码(主键) |
| name | TEXT | 转债名称 |
| stock_code | TEXT | 正股代码 |
| initial_convert_price | REAL | 初始转股价 |
| list_date | TEXT | 上市日期 |
| delist_date | TEXT | 退市日期 |
(3)用户表(user)
存储注册用户信息。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | INTEGER | 用户ID(自增主键) |
| username | TEXT | 用户名 |
| TEXT | 邮箱 | |
| password_hash | TEXT | 密码哈希 |
| created_at | TEXT | 创建时间 |
| updated_at | TEXT | 更新时间 |
(4)验证码表(verify_code)
存储邮箱验证码信息。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | INTEGER | 主键 |
| TEXT | 邮箱 | |
| code | TEXT | 验证码 |
| purpose | TEXT | 用途(注册/登录) |
| expires_at | INTEGER | 过期时间 |
| used | INTEGER | 是否已使用 |
(5)任务表(ingest_task)
存储数据入库任务的持久化记录。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | TEXT | 任务ID(主键) |
| type | TEXT | 任务类型(full/incremental) |
| status | TEXT | 任务状态 |
| total | INTEGER | 总数量 |
| done | INTEGER | 已完成数量 |
| success | INTEGER | 成功数量 |
| failed | INTEGER | 失败数量 |
| failed_codes | TEXT | 失败转债代码 |
| params | TEXT | 任务参数 |
| error | TEXT | 错误信息 |
| started_at | TEXT | 开始时间 |
| finished_at | TEXT | 完成时间 |
(6)正股基本面表(stock_fundamental)
存储正股的基本面数据,用于回测基本面过滤。
| 字段 | 类型 | 说明 |
|---|---|---|
| code | TEXT | 正股代码(主键) |
| name | TEXT | 名称 |
| roe | REAL | 净资产收益率 |
| debt_ratio | REAL | 资产负债率 |
| net_profit | REAL | 净利润 |
| status | INTEGER | 状态 |
| total_asset | REAL | 总资产 |
| total_debt | REAL | 总负债 |
| update_date | TEXT | 更新日期 |
第五章 接口设计
系统采用 RESTful 风格的 HTTP 接口,接口响应统一使用 JSON 格式,字段采用 camelCase 命名。除认证相关接口外,其余接口均需在请求头携带 Bearer token。
5.1 认证接口
| 接口 | 方法 | 说明 |
|---|---|---|
| /api/auth/send-code | POST | 发送邮箱验证码 |
| /api/auth/register | POST | 注册账号 |
| /api/auth/login | POST | 登录 |
| /api/auth/logout | POST | 登出 |
| /api/auth/me | GET | 获取当前用户信息 |
5.2 行情接口
| 接口 | 方法 | 说明 |
|---|---|---|
| /api/bonds | GET | 获取全量可转债实时行情 |
| /api/bonds/{code}/kline | GET | 获取指定转债日K线 |
5.3 回测接口
| 接口 | 方法 | 说明 |
|---|---|---|
| /api/backtest | POST | 执行策略回测 |
5.4 数据接口
| 接口 | 方法 | 说明 |
|---|---|---|
| /api/status | GET | 获取数据库数据状态 |
| /api/db/bonds | GET | 获取数据库中已有转债列表 |
5.5 任务接口
| 接口 | 方法 | 说明 |
|---|---|---|
| /api/tasks | POST | 创建入库任务 |
| /api/tasks | GET | 获取任务列表 |
| /api/tasks/{id} | GET | 获取单个任务状态 |
| /api/tasks/{id}/cancel | POST | 取消任务 |
第六章 关键算法设计
6.1 轮动策略算法
轮动策略的核心逻辑为:在每个调仓周期,按指定指标对可转债进行排序,选取排名靠前的 N 只转债作为持仓,卖出不在持仓中的转债,买入新进入的转债。
低价轮动按价格升序选债;双低轮动按「价格 + 溢价率」综合指标升序选债;溢价率轮动按溢价率升序选债。调仓周期、持仓数量、价格区间等参数由用户配置。
6.2 主备切换与熔断算法
数据源请求采用「主源优先,失败切换」策略:
- 请求首先发往主数据源。
- 主源失败时,记录失败计数,并立即切换到备用数据源。
- 当主源连续失败次数达到阈值(3 次)时,开启熔断,后续请求直接使用备用源。
- 熔断窗口(10 分钟)结束后,放行一次探测请求;探测成功则解除熔断恢复主源。
6.3 全局限速算法
系统采用令牌桶算法实现全局限速。令牌桶以固定速率(默认 400 毫秒一个令牌)生成令牌,初始突发额度为 4。每个数据请求在发出前必须获取一个令牌,未获取到令牌的请求等待。该算法保证数据请求速率稳定,避免因高频请求触发数据源的限流封禁。
6.4 增量同步起点算法
增量同步时,系统一次性查询所有已入库转债的最后K线日期(GROUP BY 聚合查询),形成「转债代码 → 最后日期」映射。对每只转债,其增量同步起点为该最后日期的次日;若指定了起始日期参数,则以两者中较晚者为起点。该设计避免了逐只查询导致的性能损耗。
第七章 安全设计
7.1 身份认证
系统采用 token 机制进行身份认证。登录成功后服务端生成随机 token,客户端在后续请求中携带 token,服务端校验 token 有效性。未登录用户访问受保护资源时,页面请求自动跳转登录页,接口请求返回 401 未授权。
7.2 密码安全
用户密码采用 bcrypt 算法加盐哈希后存储,数据库中不保存明文密码。bcrypt 算法具有自适应的计算成本,能有效抵御暴力破解。
7.3 数据安全
- 敏感数据(如密码哈希)仅存储在本地数据库中,不对外暴露。
- 接口响应仅返回必要字段,不泄露数据库连接信息等敏感数据。
- 前端对用户输入进行基础校验,后端对请求参数进行统一校验。
7.4 权限控制
系统通过中间件统一实现权限控制,所有受保护接口均经过权限校验中间件,确保只有登录用户才能访问业务数据。
第八章 性能与容错设计
8.1 性能设计
- 并发拉取:数据入库任务采用多 worker 并发拉取数据,默认 8 个并发。
- 批量写入:拉取结果汇聚后按批次(默认 20 只)批量写入数据库,减少事务开销。
- 单写者模型:SQLite 连接数限制为 1,仅 collector 单 goroutine 写入,避免写锁竞争。
- 聚合查询:增量同步使用一次性聚合查询获取全部最后日期,避免逐只查询。
8.2 容错设计
- 数据源容错:主备数据源切换 + 熔断机制,保证数据源异常时的可用性。
- 缓存降级:Redis 不可用时自动降级到内存空实现,任务系统仍可运行,仅失去实时状态缓存能力。
- 写入重试:数据库写入失败时自动重试(最多 3 次),应对文件系统短暂占用。
- 请求退避:数据源请求失败时按 3 秒、6 秒递增退避重试。
- 优雅退出:服务关闭时自动取消运行中的任务,避免数据不一致。
第九章 部署设计
9.1 部署架构
系统后端编译为单个可执行文件,前端静态资源随程序提供。数据库为 SQLite 单文件。Redis 作为可选中间件通过 Docker 部署。
9.2 部署步骤
- 编译后端程序:
go build ./cmd/server。 - 配置环境变量(端口、数据库路径、Redis 地址等)。
- 启动后端服务。
- 如需 Redis,执行
docker compose up -d启动 Redis 容器。 - 浏览器访问系统地址完成使用。
9.3 环境变量配置
| 变量 | 默认值 | 说明 |
|---|---|---|
| PORT | 8080 | 服务端口 |
| STOCK_DB_PATH | 可执行目录下 stock.db | 数据库路径 |
| REDIS_ADDR | localhost:6379 | Redis 地址 |
| REDIS_PASSWORD | 空 | Redis 密码 |
| JOB_WORKERS | 8 | 任务并发数 |
| JOB_BATCH_SIZE | 20 | 批量写入阈值 |
第十章 总结
「可转债轮动分析系统 V1.0」采用 MVC 架构,通过模块化设计实现了用户认证、实时行情、策略回测、数据入库与异步任务管理五大核心功能。系统在数据源容错、缓存降级、并发性能、权限安全等方面进行了专门设计,具备良好的可用性、健壮性与可扩展性,能够满足可转债量化研究与投资决策的实际需求。