Files
QTradeProgram/Sqbase/qorderprocessor.md
2025-08-15 15:56:40 +08:00

251 lines
7.2 KiB
Markdown
Raw Permalink 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.

## qorderprocessor
完整头文件和cpp文件
以下是完整的头文件和实现文件代码根据您提供的JSON格式订单簿数据进行了完整实现
### 头文件 `qorderprocessor.h`
cpp
复制
```
#ifndef QORDERPROCESSOR_H
#define QORDERPROCESSOR_H
#include <QObject>
#include <QVector>
#include <QThreadPool>
#include <QMutex>
#include <QtConcurrent>
struct OrderBookItem {
double price = 0.0;
double volume = 0.0;
int orderCount = 0;
bool isValid() const { return price > 0 && volume > 0; }
};
struct OrderBookData {
QString securityCode;
QString securityName;
QVector<OrderBookItem> asks; // 卖盘
QVector<OrderBookItem> bids; // 买盘
};
class QOrderProcessor : public QObject
{
Q_OBJECT
public:
explicit QOrderProcessor(QObject *parent = nullptr);
~QOrderProcessor();
void processOrderBook(const QByteArray& jsonData);
signals:
void maxAskOrderReady(double price, double volume, int orderCount);
void maxBidOrderReady(double price, double volume, int orderCount);
void maxOrdersReady(const OrderBookItem& maxAsk, const OrderBookItem& maxBid);
void parseError(const QString& error);
private:
OrderBookData parseOrderBookJson(const QByteArray& jsonData) const;
std::pair<OrderBookItem, OrderBookItem> findMaxOrder(const QByteArray& jsonData) const;
OrderBookItem findMaxVolumeItem(const QVector<OrderBookItem>& items) const;
QThreadPool m_threadPool;
mutable QMutex m_resultMutex;
};
#endif // QORDERPROCESSOR_H
```
### 实现文件 `qorderprocessor.cpp`
cpp
复制
```
#include "qorderprocessor.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>
#include <immintrin.h> // SIMD指令集头文件
QOrderProcessor::QOrderProcessor(QObject *parent)
: QObject(parent)
{
const int threads = qBound(2, QThread::idealThreadCount() - 1, 8);
m_threadPool.setMaxThreadCount(threads);
}
QOrderProcessor::~QOrderProcessor()
{
m_threadPool.waitForDone();
}
OrderBookData QOrderProcessor::parseOrderBookJson(const QByteArray& jsonData) const
{
OrderBookData result;
QJsonParseError parseError;
QJsonDocument doc = QJsonDocument::fromJson(jsonData, &parseError);
if(parseError.error != QJsonParseError::NoError) {
emit this->parseError(parseError.errorString());
return result;
}
QJsonObject root = doc.object();
if(!root.contains("s2c")) {
emit this->parseError("Missing 's2c' field in JSON");
return result;
}
QJsonObject s2c = root["s2c"].toObject();
QJsonObject security = s2c["security"].toObject();
result.securityCode = security["code"].toString();
result.securityName = s2c["name"].toString();
// 解析卖盘(asks)
if(s2c.contains("orderBookAskList")) {
QJsonArray askArray = s2c["orderBookAskList"].toArray();
for(const QJsonValue& val : askArray) {
QJsonObject obj = val.toObject();
OrderBookItem item;
item.price = obj["price"].toDouble();
item.volume = obj["volume"].toString().toDouble(); // 字符串转double
item.orderCount = obj["orederCount"].toInt(); // 注意原数据有拼写错误
result.asks.append(item);
}
}
// 解析买盘(bids)
if(s2c.contains("orderBookBidList")) {
QJsonArray bidArray = s2c["orderBookBidList"].toArray();
for(const QJsonValue& val : bidArray) {
QJsonObject obj = val.toObject();
OrderBookItem item;
item.price = obj["price"].toDouble();
item.volume = obj["volume"].toString().toDouble();
item.orderCount = obj["orederCount"].toInt();
result.bids.append(item);
}
}
return result;
}
OrderBookItem QOrderProcessor::findMaxVolumeItem(const QVector<OrderBookItem>& items) const
{
if(items.isEmpty()) return {};
#ifdef __AVX2__
// AVX2 SIMD优化版本
const double* volumes = &items[0].volume;
const size_t size = items.size();
__m256d maxVec = _mm256_set1_pd(-DBL_MAX);
double maxVolume = -DBL_MAX;
OrderBookItem result;
size_t i = 0;
for(; i + 4 <= size; i += 4) {
__m256d current = _mm256_loadu_pd(volumes + i);
__m256d cmp = _mm256_cmp_pd(current, maxVec, _CMP_GT_OS);
if(_mm256_movemask_pd(cmp)) {
// 需要逐个比较
for(size_t j = 0; j < 4; ++j) {
if(items[i + j].volume > maxVolume) {
maxVolume = items[i + j].volume;
result = items[i + j];
}
}
maxVec = _mm256_set1_pd(maxVolume);
}
}
// 处理剩余元素
for(; i < size; ++i) {
if(items[i].volume > maxVolume) {
maxVolume = items[i].volume;
result = items[i];
}
}
return result;
#else
// 普通版本
return *std::max_element(items.begin(), items.end(),
[](const OrderBookItem& a, const OrderBookItem& b) {
return a.volume < b.volume;
});
#endif
}
std::pair<OrderBookItem, OrderBookItem> QOrderProcessor::findMaxOrder(const QByteArray& jsonData) const
{
OrderBookData data = parseOrderBookJson(jsonData);
OrderBookItem maxAsk = findMaxVolumeItem(data.asks);
OrderBookItem maxBid = findMaxVolumeItem(data.bids);
return {maxAsk, maxBid};
}
void QOrderProcessor::processOrderBook(const QByteArray& jsonData)
{
QtConcurrent::run(&m_threadPool, [this, jsonData]() {
auto result = findMaxOrder(jsonData);
QMutexLocker lock(&m_resultMutex);
// 发射卖盘最大订单信号
if(result.first.isValid()) {
emit maxAskOrderReady(result.first.price,
result.first.volume,
result.first.orderCount);
}
// 发射买盘最大订单信号
if(result.second.isValid()) {
emit maxBidOrderReady(result.second.price,
result.second.volume,
result.second.orderCount);
}
// 同时发射完整结果信号
emit maxOrdersReady(result.first, result.second);
});
}
```
### 主要改进说明:
1. **完整的数据结构**
- 定义了`OrderBookItem``OrderBookData`结构体来精确匹配JSON数据结构
- 处理了volume字段从字符串到double的转换
2. **健壮的JSON解析**
- 添加了完整的错误检查和处理
- 处理了字段缺失的情况
- 添加了parseError信号报告解析错误
3. **优化的查找算法**
- 提供了AVX2 SIMD优化版本和普通版本
- 通过预处理器指令自动选择最佳实现
4. **线程安全**
- 使用QMutex保护共享数据
- 通过QtConcurrent实现多线程处理
5. **详细的信号通知**
- 分别通知买卖盘的最大订单
- 提供组合通知信号
- 添加了数据有效性检查
6. **可扩展性**
- 结构设计便于添加新的处理逻辑
- 支持未来添加更多分析功能
这个实现完整处理了您提供的JSON格式订单簿数据并提供了高性能的多线程处理能力。