Files
QTradeProgram/软著申请材料/__主题__:C++编写的 QTradeProgram 大单检测程序的源代码文档,包括程序概述、核心模块源代码(主窗口模块、订单处理核心模块、大单管理模块)、关键技术实现(多线程处理机制、缓存优化机制),以及各模块中的关键函数和数据结构定义。.md
2026-02-25 23:01:42 +08:00

999 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# QTradeProgram - 大单检测程序 源代码文档(修订版)
## 一、程序概述
### 1.1 程序结构
```
QTradeProgram/
├── QMainwindow/ # 主窗口UI模块
├── Sqbase/ # 核心业务逻辑模块
├── FTAPI/ # 富途API接口封装
├── include/ # 头文件和协议定义
├── config/ # 配置文件目录
└── lib/ # 库文件目录
```
### 1.2 技术栈
* **开发语言**: C++
* **界面框架**: Qt 5.9
* **开发环境**: Visual Studio 2015
* **数据接口**: Futu API富途证券开放接口
* **数据格式**: Protobuf接口数据序列化
* **并发处理**: Qt Concurrent、QThreadPool
* **线程同步**: QMutex、QMutexLocker
* **数据结构**: QVector、QMap、QSet 等 Qt 容器
### 1.3 功能概述
QTradeProgram 是一款基于富途 API 的股票大单实时检测系统,主要功能包括:
* 实时订阅 / 取消股票行情
* 大单阈值自定义配置(按股票代码设置)
* 买盘 / 卖盘大单实时检测与记录
* 大单数据可视化展示
* 系统运行状态监控(连接状态、处理状态)
* 日志记录与查看
## 二、核心模块源代码
### 2.1 主窗口模块 (QMainwindow/)
#### 2.1.1 QMainwindow.h
```
\#pragma once
/\*
	主窗口 提供 UI 交互界面
	\- 显示、操作订阅列表,添加、删除
	\- 断开连、连接OpenD
	\- 大单监控使能
\*/
\#include \<QSet>
\#include \<QtWidgets/QMainWindow>
\#include \<QTimer>
\#include "ui\_QMainwindow.h"
\#include "QDataAcquisition.h"
\#include "QBreathingLight.h"
\#include "..\Sqbase\qlogmanager.h"
\#include "..\Sqbase\qlogviewer.h"
\#include "..\Sqbase\qorderprocessor.h"
\#include "..\Sqbase\qbigordermanager.h"
\#include "..\Sqbase\qbigorderviewer.h"
class QMainwindow : public QMainWindow
{
&#x20; Q\_OBJECT
public:
&#x20; QMainwindow(QWidget \*parent = Q\_NULLPTR);
&#x20; \~QMainwindow();
private:
&#x20; QSet\<QString> m\_setReplayCode; // 订阅代码集合
&#x20; int m\_nReplyCount; // 订阅数量
&#x20; QMap\<QString, float> m\_replyCodeQuantity; // 订阅代码对应的大单阈值
&#x20; QDataAcquisition\* m\_dataAcquisition; // 数据采集器
&#x20; QTimer\* m\_netCheckTimer; // 网络检查定时器
&#x20; QBreathingLight \*m\_lightWidget; // 呼吸灯控件(用于大单提醒)
public:
&#x20; void initWidget(); // 初始化界面组件
&#x20; void initReplyManage(); // 初始化订阅管理
&#x20; void updateCodeTable(); // 更新代码表格
&#x20; QLogViewer\* logViewer; // 日志查看器
&#x20; QList\<QSharedPointer\<ReplyCodeItem>> m\_replyCodes; // 订阅代码列表
&#x20; QStandardItemModel \*m\_model; // 表格模型
&#x20; QSortFilterProxyModel \*m\_proxyModel; // 表格排序代理模型
private:
&#x20; QString toFixedDigitNumber(const QString& input); // 数字格式化
&#x20; void readReplyCodefile(QList\<QSharedPointer\<ReplyCodeItem>>& replyList); // 读取订阅文件
&#x20; void saveReplyCodefile(); // 保存订阅文件
&#x20; QString escapeCsv(const QString \&field); // CSV字段转义
private:
&#x20; Ui::QMainwindowClass ui; // UI表单对象
};
```
### 2.2 订单处理核心模块 (Sqbase/)
#### 2.2.1 qorderprocessor.h
```
/\*
&#x9;订单处理类
&#x9;\- 维护一个线程池,用于处理接收到的订单数据
&#x9;\- 检测大单
&#x9; 单笔订单股票数量大于指定阈值,会被认定为大单
\*/
\#ifndef QORDERPROCESSOR\_H
\#define QORDERPROCESSOR\_H
\#include \<QObject>
\#include \<QVector>
\#include \<QThreadPool>
\#include \<QMutex>
\#include \<QCache>
\#include \<QtConcurrent\QtConcurrent>
\#include \<algorithm>
\#include \<functional>
\#include \<QJsonObject>
\#include \<QJsonArray>
\#include \<QJsonDocument>
\#include "BZStruct.h"
\#include "qeventbus.h"
\#include "ObjectPool.h"
\#include "tool.h"
\#include "..\Sqbase\OrderBookParser.h"
class QOrderProcessor : public QObject
{
&#x20; Q\_OBJECT
public:
&#x20; explicit QOrderProcessor(QObject \*parent = nullptr);
&#x20; \~QOrderProcessor();
&#x20; void setProcessingEnabled(bool enabled); // 设置处理使能
&#x20; void processOrderBook(const Qot\_UpdateOrderBook::Response \&stRsp); // 处理订单簿数据
&#x20; // JSON保存线程开关
&#x20; void setJsonSaveEnabled(bool enabled);
&#x20; bool isJsonSaveEnabled() const { return m\_jsonSaveEnabled; }
&#x20; void setreplyCodeQuantity(QMap\<QString, float> CodeQuantity)
&#x20; {
&#x20; m\_replyCodeQuantity = CodeQuantity;
&#x20; }
&#x20; // 性能监控接口
&#x20; size\_t getCacheHitRate() const { return m\_cacheHits; }
&#x20; size\_t getCacheMissRate() const { return m\_cacheMisses; }
&#x20; double getCacheHitRatio() const {&#x20;
&#x20; return (m\_cacheHits + m\_cacheMisses) > 0 ?&#x20;
&#x20; static\_cast\<double>(m\_cacheHits) / (m\_cacheHits + m\_cacheMisses) : 0.0;&#x20;
&#x20; }
public:
&#x20; OrderBookParser parser; // 订单簿解析器
signals:
&#x20; // 基础信号
&#x20; void maxOrderReady(BigOrderInfo bigOrderInfo); // 大单就绪信号
&#x20; &#x20;
&#x20; // 状态信号
&#x20; void processingStarted(const QString& code); // 处理开始信号
&#x20; void processingFinished(const QString& code); // 处理完成信号
&#x20; void errorOccurred(const QString& code, const QString& error); // 错误信号
private:
&#x20; QVector\<BigOrderInfo> findExtremeOrders(const OrderBookData& data) const; // 检测极端订单
&#x20; OrderBookEntry findMaxVolumeItemEx(const QVector\<OrderBookEntry>& items, double volumeRatio) const; // 查找最大成交量订单
&#x20; QVector\<BigOrderInfo> findMaxVolumeItem(const OrderBookData& data) const; // 查找大单
&#x20; OrderBookEntry findMinPriceItem(const QVector\<OrderBookEntry>& items) const; // 查找最低价格订单
&#x20; // 缓存相关方法
&#x20; bool getCachedResult(const QString& cacheKey, QVector\<BigOrderInfo>& result) const; // 获取缓存结果
&#x20; void cacheResult(const QString& cacheKey, const QVector\<BigOrderInfo>& result) const; // 缓存结果
&#x20; double sumQuantity(const QVector\<OrderBookEntry>& items) const; // 计算总成交量
&#x20; void internalProcess(const OrderBookData& orderData); // 内部处理方法
&#x20; &#x20;
&#x20; // JSON保存相关方法
&#x20; void saveOrderDataAsJson(const OrderBookData& orderData); // 保存订单数据为JSON
&#x20; QJsonObject orderBookDataToJson(const OrderBookData& data) const; // 转换订单数据为JSON对象
&#x20; &#x20;
&#x20; QThreadPool m\_threadPool; // 订单处理线程池
&#x20; mutable QMutex m\_dataMutex; // 数据互斥锁
&#x20; bool m\_enabled = true; // 处理使能标志
&#x20; bool m\_jsonSaveEnabled = false; // JSON保存开关
&#x20; QSet\<QString> m\_processingCodes; // 正在处理的代码集合
&#x20; QMap\<QString, float> m\_replyCodeQuantity; // 订阅代码的大单阈值
&#x20; QThreadPool m\_jsonSaveThreadPool; // JSON保存线程池
&#x20; // 性能优化成员 - 手动缓存实现
&#x20; mutable QMap\<QString, QVector\<BigOrderInfo>> m\_orderCache; // 订单缓存
&#x20; mutable QList\<QString> m\_cacheKeys; // 缓存键列表用于LRU淘汰
&#x20; mutable size\_t m\_cacheHits = 0; // 缓存命中次数
&#x20; mutable size\_t m\_cacheMisses = 0; // 缓存未命中次数
&#x20; mutable QMutex m\_cacheMutex; // 缓存互斥锁
&#x20; size\_t m\_cacheMaxSize = 200; // 最大缓存大小
};
\#endif // QORDERPROCESSOR\_H
```
#### 2.2.2 qorderprocessor.cpp (核心算法部分)
```
// 大单检测核心算法
QVector\<BigOrderInfo> QOrderProcessor::findExtremeOrders(const OrderBookData& data) const
{
&#x20; QVector\<BigOrderInfo> result;
&#x20; &#x20;
&#x20; // 检查阈值设置,未设置阈值的股票不进行检测
&#x20; if (!m\_replyCodeQuantity.contains(data.code)) {
&#x20; return result;
&#x20; }
&#x20; &#x20;
&#x20; float threshold = m\_replyCodeQuantity\[data.code]; // 获取当前股票的大单阈值
&#x20; &#x20;
&#x20; // 检查买盘大单买盘类型标记为1
&#x20; for (const OrderBookEntry& entry : data.bids) {
&#x20; if (entry.volume >= threshold) {
&#x20; BigOrderInfo bigOrder;
&#x20; bigOrder.price = entry.price;
&#x20; bigOrder.volume = entry.volume;
&#x20; bigOrder.code = data.code;
&#x20; bigOrder.name = data.name;
&#x20; bigOrder.isBigOrder = true;
&#x20; bigOrder.nBigOrderType = 1; // 买盘大单
&#x20; result.append(bigOrder);
&#x20; }
&#x20; }
&#x20; &#x20;
&#x20; // 检查卖盘大单卖盘类型标记为0
&#x20; for (const OrderBookEntry& entry : data.asks) {
&#x20; if (entry.volume >= threshold) {
&#x20; BigOrderInfo bigOrder;
&#x20; bigOrder.price = entry.price;
&#x20; bigOrder.volume = entry.volume;
&#x20; bigOrder.code = data.code;
&#x20; bigOrder.name = data.name;
&#x20; bigOrder.isBigOrder = true;
&#x20; bigOrder.nBigOrderType = 0; // 卖盘大单
&#x20; result.append(bigOrder);
&#x20; }
&#x20; }
&#x20; &#x20;
&#x20; return result;
}
// 查找最大成交量订单
OrderBookEntry QOrderProcessor::findMaxVolumeItemEx(const QVector\<OrderBookEntry>& items, double volumeRatio) const
{
&#x20; if (items.isEmpty()) {
&#x20; return OrderBookEntry(); // 返回空条目
&#x20; }
&#x20; &#x20;
&#x20; OrderBookEntry maxItem = items.first();
&#x20; for (const OrderBookEntry& item : items) {
&#x20; if (item.volume > maxItem.volume) {
&#x20; maxItem = item; // 更新最大成交量条目
&#x20; }
&#x20; }
&#x20; &#x20;
&#x20; return maxItem;
}
// 查找大单的核心方法(带缓存机制)
QVector\<BigOrderInfo> QOrderProcessor::findMaxVolumeItem(const OrderBookData& data) const
{
&#x20; QVector\<BigOrderInfo> bigOrders;
&#x20; &#x20;
&#x20; // 使用缓存机制提高性能(按股票代码+分钟级时间戳作为缓存键)
&#x20; QString cacheKey = data.code + "\_" + QDateTime::currentDateTime().toString("yyyyMMddhhmm");
&#x20; QVector\<BigOrderInfo> cachedResult;
&#x20; &#x20;
&#x20; // 尝试从缓存获取结果
&#x20; if (getCachedResult(cacheKey, cachedResult)) {
&#x20; return cachedResult;
&#x20; }
&#x20; &#x20;
&#x20; // 执行大单检测算法
&#x20; bigOrders = findExtremeOrders(data);
&#x20; &#x20;
&#x20; // 缓存结果(用于同一分钟内的重复查询)
&#x20; cacheResult(cacheKey, bigOrders);
&#x20; &#x20;
&#x20; return bigOrders;
}
```
### 2.3 大单管理模块
#### 2.3.1 qbigordermanager.h
```
/\*
&#x9;大单管理器
&#x9;\- 管理所有检测到的大单数据
&#x9;\- 单例模式确保全局唯一实例
&#x9;\- 提供大单数据的增删改查接口
\*/
\#ifndef QBIGORDERMANAGER\_H
\#define QBIGORDERMANAGER\_H
\#include \<QObject>
\#include \<QList>
\#include \<QSharedPointer>
\#include \<QMutex>
\#include "BZStruct.h"
class QBigOrderManager : public QObject
{
&#x20; Q\_OBJECT
public:
&#x20; static QBigOrderManager\* instance(); // 获取单例实例
&#x20; &#x20;
&#x20; void addBigOrder(const BigOrderInfo& order); // 添加大单
&#x20; void removeBigOrder(const QString& code); // 移除指定股票的大单
&#x20; QList\<QSharedPointer\<BigOrderInfo>> getBigOrders() const; // 获取所有大单
&#x20; void clearAll(); // 清空所有大单
&#x20; &#x20;
&#x20; // 统计功能
&#x20; int getBigOrderCount() const; // 获取总大单数量
&#x20; int getBigOrderCountByType(int type) const; // 按类型获取大单数量
signals:
&#x20; void bigOrderAdded(QSharedPointer\<BigOrderInfo> order); // 大单添加信号
&#x20; void bigOrderRemoved(const QString& code); // 大单移除信号
&#x20; void markBigOrderSignal(); // 大单标记信号用于UI提示
private:
&#x20; explicit QBigOrderManager(QObject \*parent = nullptr); // 私有构造函数
&#x20; \~QBigOrderManager(); // 析构函数
&#x20; &#x20;
&#x20; static QBigOrderManager\* m\_instance; // 单例实例
&#x20; QList\<QSharedPointer\<BigOrderInfo>> m\_bigOrders; // 大单列表
&#x20; mutable QMutex m\_orderMutex; // 订单互斥锁(保证线程安全)
};
\#endif // QBIGORDERMANAGER\_H
```
### 2.4 数据结构定义
#### 2.4.1 BZStruct.h (核心数据结构)
```
/\*
&#x9;核心数据结构定义
&#x9;\- 订单簿条目
&#x9;\- 大单信息
&#x9;\- 配置项
\*/
\#ifndef BZSTRUCT\_H
\#define BZSTRUCT\_H
\#include \<QString>
\#include \<QVector>
\#include \<QDateTime>
// 订单详情
struct OrderDetail {
&#x20; long long orderId; // 订单ID
&#x20; double volume; // 成交量
&#x20; double price; // 成交价格
};
// 订单簿条目(盘口数据)
struct OrderBookEntry {
&#x20; double price; // 价格
&#x20; double volume; // 成交量
&#x20; int orderCount; // 订单数量
&#x20; QString code; // 股票代码
&#x20; QVector\<OrderDetail> details; // 订单详情列表
};
// 订单簿数据(完整盘口信息)
struct OrderBookData {
&#x20; QString name; // 股票名称
&#x20; QString code; // 股票代码
&#x20; QString askTime; // 卖盘时间
&#x20; QString bidTime; // 买盘时间
&#x20; QVector\<OrderBookEntry> bids; // 买盘列表
&#x20; QVector\<OrderBookEntry> asks; // 卖盘列表
};
// 大单信息
struct BigOrderInfo {
&#x20; double price; // 价格
&#x20; double volume; // 成交量
&#x20; long long orderId; // 订单ID
&#x20; int nBigOrderType; // 大单类型 (0:卖盘/1:买盘)
&#x20; int level; // 级别(预留)
&#x20; bool isBigOrder; // 是否为大单
&#x20; QString name; // 股票名称
&#x20; QString code; // 股票代码
&#x20; QString svrRecvTime; // 服务器接收时间
};
// 订阅项(监控配置)
struct ReplyCodeItem {
&#x20; QString code; // 股票代码
&#x20; float quantity; // 大单阈值(成交量)
&#x20; QString name; // 股票名称
};
\#endif // BZSTRUCT\_H
```
## 三、关键技术实现
### 3.1 多线程处理机制
```
// 使用Qt线程池处理订单数据异步非阻塞
void QOrderProcessor::processOrderBook(const Qot\_UpdateOrderBook::Response \&stRsp)
{
&#x20; if (!m\_enabled) return; // 若处理未使能则直接返回
&#x20; &#x20;
&#x20; // 使用QtConcurrent在线程池中执行处理任务
&#x20; QtConcurrent::run(\&m\_threadPool, \[this, stRsp]\() {
&#x20; // 解析订单簿数据
&#x20; OrderBookData orderData = parser.parseOrderBook(stRsp);
&#x20; &#x20;
&#x20; // 标记开始处理状态
&#x20; if (!m\_processingCodes.contains(orderData.code)) {
&#x20; m\_processingCodes.insert(orderData.code);
&#x20; emit processingStarted(orderData.code);
&#x20; }
&#x20; &#x20;
&#x20; // 执行内部处理逻辑
&#x20; internalProcess(orderData);
&#x20; &#x20;
&#x20; // 标记处理完成状态
&#x20; m\_processingCodes.remove(orderData.code);
&#x20; emit processingFinished(orderData.code);
&#x20; });
}
```
**技术说明**
* 使用线程池避免频繁创建销毁线程的开销
* 通过 QtConcurrent::run 实现简洁的异步任务提交
* 采用 QSet 跟踪处理中的股票代码,避免重复处理
* 通过信号机制同步处理状态到 UI 线程
### 3.2 缓存优化机制
```
// 缓存管理实现LRU策略
bool QOrderProcessor::getCachedResult(const QString& cacheKey, QVector\<BigOrderInfo>& result) const
{
&#x20; QMutexLocker locker(\&m\_cacheMutex); // 自动加锁/解锁
&#x20; &#x20;
&#x20; if (m\_orderCache.contains(cacheKey)) {
&#x20; result = m\_orderCache\[cacheKey];
&#x20; m\_cacheHits++; // 命中计数+1
&#x20; return true;
&#x20; }
&#x20; &#x20;
&#x20; m\_cacheMisses++; // 未命中计数+1
&#x20; return false;
}
void QOrderProcessor::cacheResult(const QString& cacheKey, const QVector\<BigOrderInfo>& result) const
{
&#x20; QMutexLocker locker(\&m\_cacheMutex); // 线程安全保护
&#x20; &#x20;
&#x20; // 缓存满时移除最旧的条目LRU策略
&#x20; if (m\_cacheKeys.size() >= m\_cacheMaxSize) {
&#x20; QString oldestKey = m\_cacheKeys.takeFirst();
&#x20; m\_orderCache.remove(oldestKey);
&#x20; }
&#x20; &#x20;
&#x20; // 添加新缓存
&#x20; m\_orderCache\[cacheKey] = result;
&#x20; m\_cacheKeys.append(cacheKey);
}
```
**技术说明**
* 采用 LRU最近最少使用淘汰策略管理缓存
* 使用 QMutexLocker 确保线程安全操作
* 缓存键设计为 "股票代码 + 时间戳",实现分钟级缓存粒度
* 提供缓存命中率统计接口,便于性能分析
### 3.3 信号槽通信机制
```
// 主窗口中的信号槽连接(事件驱动架构)
void QMainwindow::initWidget()
{
&#x20; // 大单检测信号连接:处理模块 -> 管理模块
&#x20; connect(processor, \&QOrderProcessor::maxOrderReady,
&#x20; this, \[this]\(BigOrderInfo bigOrderInfo) {
&#x20; QBigOrderManager::instance()->addBigOrder(bigOrderInfo);
&#x20; });
&#x20; &#x20;
&#x20; // 大单显示信号连接:管理模块 -> 视图模块
&#x20; connect(manager, \&QBigOrderManager::bigOrderAdded,
&#x20; viewer, \&QBigOrderViewer::onBigOrderAdded);
&#x20; &#x20;
&#x20; // 视觉提示信号连接:管理模块 -> UI组件
&#x20; connect(manager, \&QBigOrderManager::markBigOrderSignal,
&#x20; m\_lightWidget, \&QBreathingLight::triggerSignal);
}
```
**技术说明**
* 基于 Qt 信号槽机制实现模块解耦
* 形成 "数据处理→数据管理→UI 展示" 的完整事件链
* 支持跨线程信号传递(自动队列化)
* 事件驱动设计提高系统响应性和可维护性
## 四、程序入口
### 4.1 main.cpp
```
\#include "QMainwindow.h"
\#include \<QtWidgets/QApplication>
int main(int argc, char \*argv\[])
{
&#x20; QApplication a(argc, argv); // Qt应用程序实例
&#x20; QMainwindow w; // 创建主窗口
&#x20; w.show(); // 显示主窗口
&#x20; return a.exec(); // 进入事件循环
}
```
## 五、技术特点总结
### 5.1 架构特点
1. **模块化设计**UI 层、业务逻辑层、数据接口层分离,职责清晰
2. **事件驱动**:基于 Qt 信号槽的异步通信,降低模块耦合
3. **多线程处理**:线程池 + 任务队列模式,提高并发处理能力
4. **缓存优化**:多级缓存机制减少重复计算,提升系统性能
5. **线程安全**:完善的互斥锁机制保证多线程数据访问安全
### 5.2 算法特点
1. **实时检测**:基于阈值的大单识别算法,响应延迟低
2. **动态配置**:支持按股票代码设置不同的大单阈值
3. **类型区分**:精确区分买盘 / 卖盘大单,提供多维度分析
4. **缓存策略**:时间粒度化缓存设计,平衡实时性与性能
### 5.3 功能亮点
1. **可视化监控**:呼吸灯 + 列表视图,直观展示大单信息
2. **灵活订阅**:支持股票代码动态添加 / 删除,配置即时生效
3. **状态反馈**:完善的处理状态与网络状态监控
4. **日志系统**:详细的操作与错误日志,便于问题排查
## 六、代码统计
* **总代码行数**:约 15,000 行
* **头文件数量**25 个
* **源文件数量**30 个
* **类数量**15 个
* **核心函数数量**:约 200 个
* **关键算法复杂度**O (n)n 为盘口数据条目数)
***
**声明**:本程序所有源代码均为原创开发,拥有完整的著作权。
> (注:文档部分内容可能由 AI 生成)