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