Update 更新文档

This commit is contained in:
2026-02-25 23:01:42 +08:00
parent 40aff32fb0
commit 80518309a7
679 changed files with 4611263 additions and 0 deletions

View File

@@ -0,0 +1,165 @@
#pragma once
#include <google/protobuf/arena.h>
#include <QVector>
#include <QDebug>
#include <QSet>
#include <QCache>
#include <algorithm>
#include <functional>
#include "tool.h"
#include "BZStruct.h"
class OrderBookParser {
public:
OrderBookParser() {
m_orderCache.setMaxCost(100);
}
bool parse(const char* data, int size, OrderBookData& output) {
google::protobuf::Arena arena;
auto* response = new Qot_UpdateOrderBook::Response;
if (!response->ParseFromArray(data, size)) {
return false;
}
if (response->rettype() != 0) {
arena.Reset();
return false;
}
if (!response->has_s2c()) {
arena.Reset();
return true;
}
const auto& s2c = response->s2c();
output.clear();
output.name = QString(s2c.name().c_str());
output.code = QString(s2c.security().code().c_str());
output.askTime = QString(s2c.svrrecvtimeask().c_str());
output.bidTime = QString(s2c.svrrecvtimebid().c_str());
if (s2c.orderbookbidlist_size() > 0) {
parseOrderBookList(s2c.orderbookbidlist(), output.bids);
}
if (s2c.orderbookasklist_size() > 0) {
parseOrderBookList(s2c.orderbookasklist(), output.asks);
}
if (!validateOrderData(*response)) {
arena.Reset();
return false;
}
compressOrderData(output);
removeDuplicateOrders(output);
arena.Reset();
return true;
}
bool validateOrderData(const Qot_UpdateOrderBook::Response &stRsp) {
if (!stRsp.has_s2c()) {
return false;
}
const auto& s2c = stRsp.s2c();
if (s2c.security().code().empty() || s2c.name().empty()) {
return false;
}
if (s2c.svrrecvtimeask().empty() && s2c.svrrecvtimebid().empty()) {
return false;
}
auto validatePriceVolume = [](const google::protobuf::RepeatedPtrField<Qot_Common::OrderBook>& list) {
for (const auto& item : list) {
if (item.price() <= 0 || item.volume() < 0) {
return false;
}
for (const auto& detail : item.detaillist()) {
if (detail.orderid() < 0 || detail.volume() < 0) {
return false;
}
}
}
return true;
};
if (!validatePriceVolume(s2c.orderbookbidlist()) ||
!validatePriceVolume(s2c.orderbookasklist())) {
return false;
}
return true;
}
void removeDuplicateOrders(OrderBookData& data) {
auto removeDuplicates = [](QVector<OrderBookEntry>& entries) {
QSet<QString> seenPrices;
QVector<OrderBookEntry> uniqueEntries;
uniqueEntries.reserve(entries.size());
for (const auto& entry : entries) {
QString priceKey = QString::number(entry.price, 'f', 4);
if (!seenPrices.contains(priceKey)) {
seenPrices.insert(priceKey);
uniqueEntries.append(entry);
}
}
entries = std::move(uniqueEntries);
};
removeDuplicates(data.bids);
removeDuplicates(data.asks);
}
void compressOrderData(OrderBookData& data) {
data.name = data.name.simplified();
data.code = data.code.simplified();
data.askTime = data.askTime.simplified();
data.bidTime = data.bidTime.simplified();
auto compressEntries = [](QVector<OrderBookEntry>& entries) {
QVector<OrderBookEntry> compressed;
compressed.reserve(entries.size());
for (auto& entry : entries) {
if (entry.isValid() && !entry.details.isEmpty()) {
QVector<OrderDetail> validDetails;
validDetails.reserve(entry.details.size());
for (const auto& detail : entry.details) {
if (detail.volume > 0 && detail.orderId > 0) {
validDetails.append(detail);
}
}
if (!validDetails.isEmpty()) {
entry.details = std::move(validDetails);
compressed.append(entry);
}
}
}
entries = std::move(compressed);
};
compressEntries(data.bids);
compressEntries(data.asks);
}
private:
QCache<QString, OrderBookData> m_orderCache;
void parseOrderBookList(
const google::protobuf::RepeatedPtrField<Qot_Common::OrderBook>& pbList,
QVector<OrderBookEntry>& output)
{
output.clear();
const int itemCount = pbList.size();
if (itemCount == 0) return;
output.reserve(itemCount);
int maxDetails = 0;
for (int i = 0; i < itemCount; ++i) {
maxDetails = std::max(maxDetails, pbList.Get(i).detaillist_size());
}
for (int i = 0; i < itemCount; ++i) {
const auto& pb_item = pbList.Get(i);
const int detailCount = pb_item.detaillist_size();
QVector<OrderDetail> detailsBuffer;
detailsBuffer.reserve(detailCount);
try {
for (int j = 0; j < detailCount; ++j) {
const auto& pb_detail = pb_item.detaillist(j);
OrderDetail detail;
detail.orderId = pb_detail.orderid();
detail.volume = pb_detail.volume();
detailsBuffer.append(detail);
}
}
catch (const std::exception& e) {
detailsBuffer.clear();
}
OrderBookEntry item;
item.price = pb_item.price();
item.volume = pb_item.volume();
item.orderCount = pb_item.oredercount();
item.details = detailCount > 0 ? std::move(detailsBuffer) : QVector<OrderDetail>{};
output.append(item);
}
}
};