251 lines
7.2 KiB
Markdown
251 lines
7.2 KiB
Markdown
## 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格式订单簿数据,并提供了高性能的多线程处理能力。 |