#pragma execution_character_set("utf-8") #include "qhistoryorderdialog.h" #include "qbigordermanager.h" #include #include #include #include #include #include QHistoryOrderDialog::QHistoryOrderDialog(QWidget *parent) : QDialog(parent), m_dateSelector(new QDateEdit(this)), m_orderTypeFilter(new QComboBox(this)), m_stockCodeFilter(new QLineEdit(this)), m_tableView(new QTableView(this)), m_exportButton(new QPushButton("", this)), m_statsLabel(new QLabel(this)), m_model(new QStandardItemModel(this)), m_proxyModel(new QSortFilterProxyModel(this)), m_typeDelegate(new OrderTypeDelegate(this)), m_numberDelegate(new NumberFormatDelegate(this)) { setWindowTitle("ʷѯ"); setMinimumSize(800, 600); m_historyPath = QCoreApplication::applicationDirPath() + QString("/history"); initUI(); onDateChanged(QDate::currentDate()); } void QHistoryOrderDialog::initUI() { QVBoxLayout *mainLayout = new QVBoxLayout(this); QHBoxLayout *topLayout = new QHBoxLayout(); m_dateSelector->setDate(QDate::currentDate()); m_dateSelector->setCalendarPopup(true); topLayout->addWidget(new QLabel("ѡ:")); topLayout->addWidget(m_dateSelector); m_stockCodeFilter->setPlaceholderText("Ʊ"); topLayout->addWidget(new QLabel("Ʊ:")); topLayout->addWidget(m_stockCodeFilter); m_orderTypeFilter->addItem("ȫ", ""); m_orderTypeFilter->addItem("", "BID"); m_orderTypeFilter->addItem("", "ASK"); topLayout->addWidget(new QLabel(":")); topLayout->addWidget(m_orderTypeFilter); topLayout->addStretch(); topLayout->addWidget(m_exportButton); mainLayout->addLayout(topLayout); QHBoxLayout *statsLayout = new QHBoxLayout(); statsLayout->addWidget(m_statsLabel); statsLayout->addStretch(); mainLayout->addLayout(statsLayout); m_proxyModel->setSourceModel(m_model); m_tableView->setItemDelegateForColumn(2, m_typeDelegate); m_tableView->setItemDelegateForColumn(3, m_numberDelegate); m_tableView->setModel(m_proxyModel); m_tableView->setSortingEnabled(true); m_tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); m_tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows); m_model->setHorizontalHeaderLabels( QStringList() << "Ʊ" << "Ʊ" << "" << "Ʊ" << "Ʊ۸" << "λ" << "ʱ" ); mainLayout->addWidget(m_tableView); const int timeColumnIndex = 6; m_proxyModel->sort(timeColumnIndex, Qt::AscendingOrder); connect(m_dateSelector, &QDateEdit::dateChanged, this, &QHistoryOrderDialog::onDateChanged); connect(m_stockCodeFilter, &QLineEdit::textChanged, this, &QHistoryOrderDialog::onFilterChanged); connect(m_orderTypeFilter, QOverload::of(&QComboBox::currentIndexChanged), this, &QHistoryOrderDialog::onFilterChanged); connect(m_exportButton, &QPushButton::clicked, this, &QHistoryOrderDialog::onExportClicked); } void QHistoryOrderDialog::onDateChanged(const QDate &date) { loadOrdersForDate(date); } void QHistoryOrderDialog::loadOrdersForDate(const QDate &date) { auto orders = getHistoryOrders(date); m_model->removeRows(0, m_model->rowCount()); for (const auto& order : orders) { QList rowItems; rowItems << new QStandardItem(order->code); rowItems << new QStandardItem(order->name); rowItems << new QStandardItem(order->nBigOrderType == 0 ? "" : ""); rowItems << new QStandardItem(QString::number(std::fabs(order->volume / 1000)) + "K"); rowItems << new QStandardItem(QString::number(order->price, 'f', 2)); rowItems << new QStandardItem(QString::number(order->level)); QString str = order->svrRecvTime.mid(11); if (str == nullptr) { QDateTime dateTime = QDateTime::currentDateTime(); str = dateTime.toString("hh:mm:ss"); } rowItems << new QStandardItem(str); m_model->appendRow(rowItems); } updateStatistics(orders); } void QHistoryOrderDialog::updateStatistics(const QList>& orders) { int buyCount = 0, sellCount = 0; double totalBuyAmount = 0, totalSellAmount = 0; for (const auto& order : orders) { double value = order->price * order->volume; if (order->nBigOrderType) { buyCount++; totalBuyAmount += value; } else { sellCount++; totalSellAmount += value; } } QString stats = QString("ܶ: %1 | : %2 (%3 ) | : %4 (%5 )") .arg(orders.size()) .arg(buyCount) .arg(totalBuyAmount / 10000, 0, 'f', 1) .arg(sellCount) .arg(totalSellAmount / 10000, 0, 'f', 1); m_statsLabel->setText(stats); } void QHistoryOrderDialog::onFilterChanged() { QString stockCode = m_stockCodeFilter->text().trimmed(); QString orderType = m_orderTypeFilter->currentData().toString(); m_proxyModel->setFilterKeyColumn(0); m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); m_proxyModel->setFilterFixedString(stockCode); if (!orderType.isEmpty()) { m_proxyModel->setFilterKeyColumn(2); m_proxyModel->setFilterFixedString(orderType == "ASK" ? "" : ""); } } void QHistoryOrderDialog::onExportClicked() { QString fileName = QFileDialog::getSaveFileName(this, "ʷ", "", "CSVļ (*.csv)"); if (fileName.isEmpty()) return; QFile file(fileName); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return; QTextStream out(&file); out.setCodec("GBK"); for (int col = 0; col < m_model->columnCount(); ++col) { out << m_model->headerData(col, Qt::Horizontal).toString(); if (col < m_model->columnCount() - 1) out << ","; } out << "\n"; for (int row = 0; row < m_proxyModel->rowCount(); ++row) { for (int col = 0; col < m_proxyModel->columnCount(); ++col) { out << m_proxyModel->index(row, col).data().toString(); if (col < m_proxyModel->columnCount() - 1) out << ","; } out << "\n"; } file.close(); m_statsLabel->setText(QString("ѵ: %1").arg(fileName)); } QList> QHistoryOrderDialog::getHistoryOrders(const QDate& date) const { QMutexLocker locker(&m_cacheMutex); if (m_historyCache.contains(date)) { return m_historyCache[date]; } QString filePath = QString("%1/bigorders_%2.json") .arg(m_historyPath) .arg(date.toString("yyyyMMdd")); if (!QFile::exists(filePath)) { return QList>(); } QFile file(filePath); if (!file.open(QIODevice::ReadOnly)) { qWarning() << "Failed to open history file:" << filePath; return QList>(); } QList> orders; QTextStream in(&file); in.setCodec("UTF-8"); while (!in.atEnd()) { QJsonParseError error; QJsonDocument doc = QJsonDocument::fromJson(in.readLine().toUtf8(), &error); if (error.error == QJsonParseError::NoError && doc.isObject()) { BigOrderInfo order = BigOrderInfo::fromJson(doc.object()); orders.append(QSharedPointer::create(order)); } } file.close(); m_historyCache.insert(date, orders); return orders; } QList QHistoryOrderDialog::getAvailableDates() const { QList dates; QDir historyDir(m_historyPath); QStringList files = historyDir.entryList(QStringList() << "bigorders_*.json", QDir::Files); for (const QString& file : files) { QString dateStr = file.mid(10, 8); QDate date = QDate::fromString(dateStr, "yyyyMMdd"); if (date.isValid()) { dates.append(date); } } std::sort(dates.begin(), dates.end()); return dates; }