Files
QTradeProgram/cleaned_source_code/Sqbase/qhistoryorderdialog.cpp
2026-02-25 23:01:42 +08:00

208 lines
7.2 KiB
C++
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.

#pragma execution_character_set("utf-8")
#include "qhistoryorderdialog.h"
#include "qbigordermanager.h"
#include <QHeaderView>
#include <QFileDialog>
#include <QTextStream>
#include <QCoreApplication>
#include <QDateTime>
#include <QDebug>
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<int>::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<QStandardItem*> 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<QSharedPointer<class BigOrderInfo>>& 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<QSharedPointer<BigOrderInfo>> 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<QSharedPointer<BigOrderInfo>>();
}
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly)) {
qWarning() << "Failed to open history file:" << filePath;
return QList<QSharedPointer<BigOrderInfo>>();
}
QList<QSharedPointer<BigOrderInfo>> 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<BigOrderInfo>::create(order));
}
}
file.close();
m_historyCache.insert(date, orders);
return orders;
}
QList<QDate> QHistoryOrderDialog::getAvailableDates() const
{
QList<QDate> 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;
}