update code
This commit is contained in:
281
Sqbase/qorderlistmanager.cpp
Normal file
281
Sqbase/qorderlistmanager.cpp
Normal file
@@ -0,0 +1,281 @@
|
||||
#include "QOrderListManager.h"
|
||||
#include <QDebug>
|
||||
|
||||
QBasicAtomicPointer<QOrderListManager> QOrderListManager::s_instance = QBasicAtomicPointer<QOrderListManager>(nullptr);
|
||||
QMutex QOrderListManager::s_mutex;
|
||||
|
||||
QOrderListManager* QOrderListManager::instance()
|
||||
{
|
||||
if (!s_instance.loadAcquire()) {
|
||||
QMutexLocker locker(&s_mutex);
|
||||
if (!s_instance.loadAcquire()) {
|
||||
s_instance.storeRelease(new QOrderListManager());
|
||||
}
|
||||
}
|
||||
return s_instance.loadAcquire();
|
||||
}
|
||||
|
||||
void QOrderListManager::destroy()
|
||||
{
|
||||
QMutexLocker locker(&s_mutex);
|
||||
delete s_instance.loadAcquire();
|
||||
s_instance.storeRelease(nullptr);
|
||||
}
|
||||
|
||||
QOrderListManager::QOrderListManager(QObject *parent) : QObject(parent)
|
||||
{
|
||||
// 初始化代码
|
||||
}
|
||||
|
||||
QOrderListManager::~QOrderListManager()
|
||||
{
|
||||
// 清理代码
|
||||
}
|
||||
|
||||
bool QOrderListManager::addOrder(OrderType type, const OrderBookItem &order)
|
||||
{
|
||||
if (!order.isValid()) {
|
||||
qWarning() << "Invalid order data";
|
||||
return false;
|
||||
}
|
||||
|
||||
QMutexLocker locker(&m_orderMutex);
|
||||
|
||||
auto& orderMap = (type == BidOrder) ? m_bidOrders : m_askOrders;
|
||||
auto& orderList = orderMap[order.price];
|
||||
|
||||
// 检查订单是否已存在
|
||||
for (const auto& existingOrder : orderList) {
|
||||
if (existingOrder->orderId == order.orderId) {
|
||||
qWarning() << "Order already exists:" << order.orderId;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto newOrder = QSharedPointer<OrderBookItem>::create(order);
|
||||
orderList.append(newOrder);
|
||||
|
||||
// 排序订单
|
||||
sortOrders(type);
|
||||
calculatePriceLevels();
|
||||
|
||||
locker.unlock();
|
||||
|
||||
emit orderAdded(type, order);
|
||||
emit orderBookChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QOrderListManager::updateOrder(OrderType type, const QString &orderId, const OrderBookItem &newData)
|
||||
{
|
||||
if (!newData.isValid()) {
|
||||
qWarning() << "Invalid order data";
|
||||
return false;
|
||||
}
|
||||
|
||||
QMutexLocker locker(&m_orderMutex);
|
||||
|
||||
auto& orderMap = (type == BidOrder) ? m_bidOrders : m_askOrders;
|
||||
bool found = false;
|
||||
|
||||
for (auto it = orderMap.begin(); it != orderMap.end(); ++it) {
|
||||
for (auto& order : it.value()) {
|
||||
if (order->orderId == orderId) {
|
||||
// 如果价格变化,需要重新分组
|
||||
if (order->price != newData.price) {
|
||||
auto orderList = it.value();
|
||||
orderList.removeOne(order);
|
||||
if (orderList.isEmpty()) {
|
||||
orderMap.erase(it);
|
||||
}
|
||||
|
||||
auto newOrder = QSharedPointer<OrderBookItem>::create(newData);
|
||||
orderMap[newData.price].append(newOrder);
|
||||
} else {
|
||||
*order = newData;
|
||||
}
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) break;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
qWarning() << "Order not found:" << orderId;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 排序订单
|
||||
sortOrders(type);
|
||||
calculatePriceLevels();
|
||||
|
||||
locker.unlock();
|
||||
|
||||
emit orderUpdated(type, orderId);
|
||||
emit orderBookChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QOrderListManager::removeOrder(OrderType type, const QString &orderId)
|
||||
{
|
||||
QMutexLocker locker(&m_orderMutex);
|
||||
|
||||
auto& orderMap = (type == BidOrder) ? m_bidOrders : m_askOrders;
|
||||
bool found = false;
|
||||
|
||||
for (auto it = orderMap.begin(); it != orderMap.end(); ++it) {
|
||||
for (auto& order : it.value()) {
|
||||
if (order->orderId == orderId) {
|
||||
auto orderList = it.value();
|
||||
orderList.removeOne(order);
|
||||
if (orderList.isEmpty()) {
|
||||
orderMap.erase(it);
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) break;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
qWarning() << "Order not found:" << orderId;
|
||||
return false;
|
||||
}
|
||||
|
||||
calculatePriceLevels();
|
||||
|
||||
locker.unlock();
|
||||
|
||||
emit orderRemoved(type, orderId);
|
||||
emit orderBookChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QSharedPointer<OrderBookItem> QOrderListManager::getOrder(OrderType type, const QString &orderId) const
|
||||
{
|
||||
QMutexLocker locker(&m_orderMutex);
|
||||
|
||||
const auto& orderMap = (type == BidOrder) ? m_bidOrders : m_askOrders;
|
||||
|
||||
for (const auto& orderList : orderMap) {
|
||||
for (const auto& order : orderList) {
|
||||
if (order->orderId == orderId) {
|
||||
return order;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QMap<double, QList<QSharedPointer<OrderBookItem>>> QOrderListManager::getBidOrders() const
|
||||
{
|
||||
QMutexLocker locker(&m_orderMutex);
|
||||
return m_bidOrders;
|
||||
}
|
||||
|
||||
QMap<double, QList<QSharedPointer<OrderBookItem>>> QOrderListManager::getAskOrders() const
|
||||
{
|
||||
QMutexLocker locker(&m_orderMutex);
|
||||
return m_askOrders;
|
||||
}
|
||||
|
||||
QMap<double, double> QOrderListManager::getBidPriceLevels() const
|
||||
{
|
||||
QMutexLocker locker(&m_orderMutex);
|
||||
return m_bidPriceLevels;
|
||||
}
|
||||
|
||||
QMap<double, double> QOrderListManager::getAskPriceLevels() const
|
||||
{
|
||||
QMutexLocker locker(&m_orderMutex);
|
||||
return m_askPriceLevels;
|
||||
}
|
||||
|
||||
double QOrderListManager::getTotalBidVolume() const
|
||||
{
|
||||
QMutexLocker locker(&m_orderMutex);
|
||||
double total = 0.0;
|
||||
for (const auto& volume : m_bidPriceLevels) {
|
||||
total += volume;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
double QOrderListManager::getTotalAskVolume() const
|
||||
{
|
||||
QMutexLocker locker(&m_orderMutex);
|
||||
double total = 0.0;
|
||||
for (const auto& volume : m_askPriceLevels) {
|
||||
total += volume;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
double QOrderListManager::getBestBidPrice() const
|
||||
{
|
||||
QMutexLocker locker(&m_orderMutex);
|
||||
if (m_bidOrders.isEmpty()) return 0.0;
|
||||
return m_bidOrders.lastKey();
|
||||
}
|
||||
|
||||
double QOrderListManager::getBestAskPrice() const
|
||||
{
|
||||
QMutexLocker locker(&m_orderMutex);
|
||||
if (m_askOrders.isEmpty()) return 0.0;
|
||||
return m_askOrders.firstKey();
|
||||
}
|
||||
|
||||
void QOrderListManager::sortOrders(OrderType type)
|
||||
{
|
||||
auto& orderMap = (type == BidOrder) ? m_bidOrders : m_askOrders;
|
||||
|
||||
if (type == BidOrder) {
|
||||
// 买单按价格降序排列
|
||||
QMap<double, QList<QSharedPointer<OrderBookItem>>> sortedMap;
|
||||
auto keys = orderMap.keys();
|
||||
std::sort(keys.begin(), keys.end(), std::greater<double>());
|
||||
|
||||
for (const auto& key : keys) {
|
||||
sortedMap.insert(key, orderMap.value(key));
|
||||
}
|
||||
orderMap = sortedMap;
|
||||
} else {
|
||||
// 卖单按价格升序排列
|
||||
QMap<double, QList<QSharedPointer<OrderBookItem>>> sortedMap;
|
||||
auto keys = orderMap.keys();
|
||||
std::sort(keys.begin(), keys.end());
|
||||
|
||||
for (const auto& key : keys) {
|
||||
sortedMap.insert(key, orderMap.value(key));
|
||||
}
|
||||
orderMap = sortedMap;
|
||||
}
|
||||
}
|
||||
|
||||
void QOrderListManager::calculatePriceLevels()
|
||||
{
|
||||
m_bidPriceLevels.clear();
|
||||
for (auto it = m_bidOrders.constBegin(); it != m_bidOrders.constEnd(); ++it) {
|
||||
double totalVolume = 0.0;
|
||||
for (const auto& order : it.value()) {
|
||||
totalVolume += order->volume;
|
||||
}
|
||||
m_bidPriceLevels.insert(it.key(), totalVolume);
|
||||
}
|
||||
|
||||
m_askPriceLevels.clear();
|
||||
for (auto it = m_askOrders.constBegin(); it != m_askOrders.constEnd(); ++it) {
|
||||
double totalVolume = 0.0;
|
||||
for (const auto& order : it.value()) {
|
||||
totalVolume += order->volume;
|
||||
}
|
||||
m_askPriceLevels.insert(it.key(), totalVolume);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user