| agilestrategy.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| analysisbyrediscache.ui | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| etfstockinfo.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| etfstockinfo.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| etfstockinfo.ui | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| stock_plan_251106_etf.sql | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
agilestrategy.cpp
@@ -7,6 +7,7 @@ { ui->setupUi(this); m_widget = new QWidget(this); m_gridLayout = new QGridLayout(m_widget); analysisbyrediscache.ui
@@ -82,26 +82,6 @@ </widget> </item> <item> <widget class="QDateEdit" name="dateEdit_end"> <property name="dateTime"> <datetime> <hour>0</hour> <minute>0</minute> <second>0</second> <year>2025</year> <month>1</month> <day>1</day> </datetime> </property> <property name="displayFormat"> <string>yyyy-MM-dd</string> </property> <property name="calendarPopup"> <bool>true</bool> </property> </widget> </item> <item> <widget class="QLabel" name="label_load"> <property name="text"> <string>缓存未加载</string> @@ -129,6 +109,26 @@ </widget> </item> <item> <widget class="QDateEdit" name="dateEdit_end"> <property name="dateTime"> <datetime> <hour>0</hour> <minute>0</minute> <second>0</second> <year>2025</year> <month>1</month> <day>1</day> </datetime> </property> <property name="displayFormat"> <string>yyyy-MM-dd</string> </property> <property name="calendarPopup"> <bool>true</bool> </property> </widget> </item> <item> <widget class="QPushButton" name="pushButton_analysisByRedis"> <property name="text"> <string>缓存分析</string> etfstockinfo.cpp
@@ -8,6 +8,8 @@ #include <QJsonDocument> #include <QJsonObject> #include <QJsonArray> #include <QMessageBox> #include <QDateTime> ETFStockInfo::ETFStockInfo(QWidget *parent) : QMainWindow(parent), @@ -65,11 +67,34 @@ m_manager.get(m_request); qDebug()<<"请求中..."; ui->dateTimeEdit->setDateTime(QDateTime::currentDateTime()); ui->dateTimeEdit_3->setDateTime(QDateTime::currentDateTime()); } ETFStockInfo::~ETFStockInfo() { delete ui; } void ETFStockInfo::initMySQL() { //添加一个数据库 db=QSqlDatabase::addDatabase("QMYSQL"); //括号内要写出数据库的类型 //设置数据库 db.setHostName("127.0.0.1"); //设置数据库的主机ip //设置数据库的用户名 db.setUserName("root"); //设置数据库的密码 db.setPassword("root"); //这个就是安装MySQL时设置的密码 //设置数据库的名字 db.setDatabaseName("stock_plan"); //打开数据库(已经安装过mysql驱动了) if(db.open()==false){ QMessageBox::warning(this,"waring",db.lastError().text()); }else{ qDebug()<<"mysql conn ok"; } } void ETFStockInfo::getEtfInfo(QByteArray &buffer) @@ -151,6 +176,9 @@ // 添加一行数据项到模型中 //m_model->appendRow(rowItems); m_model_market->appendRow(rowItems); // 保存etf基金的代号和名字 m_codeNamesEtf[symbol] = name; } } @@ -210,6 +238,64 @@ } } void ETFStockInfo::getStockOne(QByteArray &buffer) { QJsonDocument jd = QJsonDocument::fromJson(buffer); if(jd.isObject()){ QJsonObject jObject = jd.object(); QJsonArray jArr = jObject.value("data").toObject().value("item").toArray(); // 通过键值对取值 int cnt = jArr.count(); qDebug()<<"数组size:"<<cnt; QString symbol = jObject.value("data").toObject().value("symbol").toString(); QString code = symbol; // 股票代号 QString name = m_codeNamesEtf[code]; qDebug()<<"历史:"<<code<<symbol; // 以批量写入的方式来获取多年数据 QString sql = "insert into etf_day_info (code,name,amount,chg,percent,volume,close,time_trade) values "; //qDebug()<<"sql 1:"<<sql; for(int i=0;i<cnt;++i){ qint64 timestamp = jArr.at(i).toArray().at(0).toVariant().toLongLong(); // double open = jArr.at(i).toArray().at(2).toVariant().toDouble(); // double high = jArr.at(i).toArray().at(3).toVariant().toDouble(); // double low = jArr.at(i).toArray().at(4).toVariant().toDouble(); double close = jArr.at(i).toArray().at(5).toVariant().toDouble(); double percent = jArr.at(i).toArray().at(7).toVariant().toDouble(); // double turnoverrate = jArr.at(i).toArray().at(8).toVariant().toDouble(); double amount = jArr.at(i).toArray().at(9).toVariant().toDouble(); // double pe_ttm = jArr.at(i).toArray().at(16).toVariant().toDouble(); // double market_capital = jArr.at(i).toArray().at(17).toVariant().toDouble(); long long volume = jArr.at(i).toArray().at(1).toVariant().toLongLong()/100; double chg = jArr.at(i).toArray().at(6).toVariant().toDouble(); //long long amount = jArr.at(i).toArray().at(9).toVariant().toLongLong()/100000000; // 亿 QString curDateTime = QDateTime::fromMSecsSinceEpoch(timestamp).toString("yyyy-MM-dd"); // qDebug()<<timestamp<<curDateTime<<close<<volume<<amount; // 处理数据保存到模型中 QString vals = QString("('%1','%2',%3,%4,%5,%6,%7,'%8')").arg(code).arg(name).arg(QString::number(amount)) .arg(QString::number(chg)).arg(QString::number(percent)).arg(QString::number(volume)).arg(QString::number(close)) .arg(curDateTime); if(i != cnt - 1){ vals.append(","); } sql.append(vals); //qDebug()<<"sql 3:"<<sql; } qDebug()<<"over:"<<sql.size(); // qDebug()<<"sql 2:"<<sql; // 太大了 显示不出来 QSqlQuery que(db); if(que.exec(sql)){ qDebug()<<"insert ok"; }else{ qDebug()<<"insert fail"<<que.lastError().text(); } } } void ETFStockInfo::showAplyData(QNetworkReply *reply) { qDebug()<<"收到响应etf"; @@ -224,7 +310,7 @@ }else if(reply->url().toString().indexOf("https://stock.xueqiu.com/v5/stock/chart/kline.json") != -1){ qDebug()<<"查看个股情况:"; // getStockOne(buffer); getStockOne(buffer); }else if(reply->url().toString().indexOf("https://stock.xueqiu.com/v5/stock/screener/quote/list.json?page=1&size=100&order=desc&order_by=percent&market=CN&ind_code") != -1){ qDebug()<<"根据行业获取股票信息"<<reply->url(); @@ -290,3 +376,105 @@ } } void ETFStockInfo::on_pushButton_search_date_clicked() { // 按日期查询数据库,了解趋势 QString cur_date = ui->dateTimeEdit->date().toString("yyyy-MM-dd"); QString sql = QString("select * from etf_day_info where time_trade = '%1' order by percent desc").arg(cur_date); QSqlQuery que(db); if(que.exec(sql)){ qDebug()<<"select ok"; m_model_market->setRowCount(0); // 重置模型行数 int rows = 0; while (que.next()) { QString code = que.value(1).toString(); QString name = que.value(2).toString(); QString amount = QString::number(que.value(3).toDouble()/100000000); QString chg = QString::number(que.value(4).toDouble()); QString percent = que.value(5).toString(); QString volume = que.value(6).toString(); QString close = que.value(7).toString(); QString time_trade = que.value(8).toString(); // QString turnover_rate = que.value(7).toString(); // QString pe_ttm = que.value(8).toString(); // QString amount_rank = que.value(9).toString(); // m_modelDatas.append({name,code,market_capital,percent,close,amount,volume,turnover_rate,pe_ttm,amount_rank}); QList<QStandardItem*> items; items.append(new QStandardItem(code)); items.append(new QStandardItem(name)); items.append(new QStandardItem(amount)); items.append(new QStandardItem(chg)); items.append(new QStandardItem("0")); items.append(new QStandardItem("0")); QStandardItem *percentItem = new QStandardItem(percent); if(percent.toDouble() > 0){ percentItem->setData(QColor("red"),Qt::DecorationRole); // 添加一个装饰的颜色为红色 percentItem->setData(QColor("red"),Qt::TextColorRole); // 将字体颜色设置为红色 items.at(0)->setData(QColor("red"),Qt::TextColorRole); // 将股票名字设置为红色 } else if(percent.toDouble() < 0){ percentItem->setData(QColor("green"),Qt::BackgroundColorRole); items.at(0)->setData(QColor("green"),Qt::TextColorRole); } items.append(percentItem); items.append(new QStandardItem(volume)); items.append(new QStandardItem(close)); items.append(new QStandardItem(time_trade)); // items.append(new QStandardItem(pe_ttm)); // items.append(new QStandardItem(amount_rank)); m_model_market->appendRow(items); rows++; } qDebug()<<"查询到行数:"<<rows; }else{ qDebug()<<"select fail"<<que.lastError().text(); } } void ETFStockInfo::on_pushButton_update_clicked() { // 更新到最新,默认全更 // 也可以指定天数的数量来更新 // 先保证获取到当前所有的etf基金的代码和名字,然后根据代码来发起更新请求 m_days = ui->comboBox_days->currentText().toInt(); if(m_days == 0) return; if(m_codeNamesEtf.size() > 0){ qint64 cur_time = QDateTime::currentMSecsSinceEpoch(); for(auto code:m_codeNamesEtf.keys()){ QString url = QString("https://stock.xueqiu.com/v5/stock/chart/kline.json?symbol=%1&begin=%2&period=day&type=before&count=-%3&indicator=kline,pe,market_capital,ma") .arg(code).arg(QString::number(cur_time)).arg(m_days); m_request.setUrl(QUrl(url)); m_manager.get(m_request); } qDebug()<<"发起请求完成"; }else{ // 如果为空,则需要去刷新一下最新的情况,获取基金信息 on_pushButton_market_clicked(); } } void ETFStockInfo::on_checkBox_update_clicked() { if(ui->checkBox_update->isChecked()){ ui->pushButton_update->setEnabled(true); }else{ ui->pushButton_update->setEnabled(false); } } etfstockinfo.h
@@ -23,8 +23,10 @@ explicit ETFStockInfo(QWidget *parent = 0); ~ETFStockInfo(); void initMySQL(); void getEtfInfo(QByteArray &buffer); void getStockFundPosition(QByteArray &buffer,QString url); // 获取个股对应基金持仓情况--总的统计 void getStockOne(QByteArray &buffer); // 获取单只etf股票的信息 signals: void sendSymbolNums(int); // 通过数量获取排名前N名的股票代号过来 @@ -40,6 +42,12 @@ void getStockFundPosSlot(QString symbol); // 通过股票代号获取基金持仓情况 void on_pushButton_search_date_clicked(); void on_pushButton_update_clicked(); void on_checkBox_update_clicked(); private: Ui::ETFStockInfo *ui; @@ -50,10 +58,13 @@ QSqlDatabase db; QMap<QString,QString> m_codeNames; // 股票代号和名字 QMap<QString,QString> m_codeNamesEtf; // Etf代号和名字 QNetworkRequest m_request; // 用于管理请求头的 QString m_cookie; // 缓存 QNetworkAccessManager m_manager; // 用于管理http请求及响应的 int m_days = 0; }; #endif // ETFSTOCKINFO_H etfstockinfo.ui
@@ -18,7 +18,7 @@ <item row="0" column="0"> <widget class="QTabWidget" name="tabWidget"> <property name="currentIndex"> <number>1</number> <number>0</number> </property> <widget class="QWidget" name="tab"> <attribute name="title"> @@ -35,7 +35,7 @@ <widget class="QComboBox" name="comboBox"> <item> <property name="text"> <string>类型1</string> <string>时间</string> </property> </item> <item> @@ -46,9 +46,84 @@ </widget> </item> <item> <widget class="QDateTimeEdit" name="dateTimeEdit"> <property name="date"> <date> <year>2025</year> <month>1</month> <day>1</day> </date> </property> <property name="displayFormat"> <string>yyyy-MM-dd HH:mm:ss</string> </property> <property name="calendarPopup"> <bool>true</bool> </property> </widget> </item> <item> <widget class="QPushButton" name="pushButton_search_date"> <property name="text"> <string>查询指定日期</string> </property> </widget> </item> <item> <widget class="QPushButton" name="pushButton_market"> <property name="text"> <string>查询最新</string> </property> </widget> </item> <item> <widget class="QCheckBox" name="checkBox_update"> <property name="text"> <string>更新</string> </property> </widget> </item> <item> <widget class="QComboBox" name="comboBox_days"> <property name="editable"> <bool>true</bool> </property> <item> <property name="text"> <string>0</string> </property> </item> <item> <property name="text"> <string>1</string> </property> </item> <item> <property name="text"> <string>2</string> </property> </item> <item> <property name="text"> <string>3</string> </property> </item> </widget> </item> <item> <widget class="QLabel" name="label_3"> <property name="text"> <string>天</string> </property> </widget> </item> <item> <widget class="QPushButton" name="pushButton_update"> <property name="enabled"> <bool>false</bool> </property> <property name="text"> <string>更新</string> </property> </widget> </item> @@ -149,6 +224,67 @@ </item> </layout> </widget> <widget class="QWidget" name="tab_3"> <attribute name="title"> <string>ETF趋势</string> </attribute> <layout class="QGridLayout" name="gridLayout_4"> <item row="0" column="0"> <widget class="QGroupBox" name="groupBox_3"> <property name="title"> <string>查询条件</string> </property> <layout class="QHBoxLayout" name="horizontalLayout_4"> <item> <layout class="QHBoxLayout" name="horizontalLayout_3"> <item> <widget class="QComboBox" name="comboBox_2"> <item> <property name="text"> <string>排名</string> </property> </item> <item> <property name="text"> <string>全部</string> </property> </item> </widget> </item> <item> <widget class="QDateTimeEdit" name="dateTimeEdit_3"> <property name="date"> <date> <year>2025</year> <month>1</month> <day>1</day> </date> </property> <property name="displayFormat"> <string>yyyy-MM-dd HH:mm:ss</string> </property> <property name="calendarPopup"> <bool>true</bool> </property> </widget> </item> <item> <widget class="QPushButton" name="pushButton_2"> <property name="text"> <string>查询</string> </property> </widget> </item> </layout> </item> </layout> </widget> </item> <item row="1" column="0"> <widget class="QTableView" name="tableView_trend"/> </item> </layout> </widget> </widget> </item> </layout> stock_plan_251106_etf.sql
New file @@ -0,0 +1,36 @@ -- -------------------------------------------------------- -- 主机: 127.0.0.1 -- 服务器版本: 5.6.35-log - MySQL Community Server (GPL) -- 服务器操作系统: Win64 -- HeidiSQL 版本: 9.5.0.5196 -- -------------------------------------------------------- /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET NAMES utf8 */; /*!50503 SET NAMES utf8mb4 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -- 导出 stock_plan 的数据库结构 CREATE DATABASE IF NOT EXISTS `stock_plan` /*!40100 DEFAULT CHARACTER SET utf8 */; USE `stock_plan`; -- 导出 表 stock_plan.etf_day_info 结构 CREATE TABLE IF NOT EXISTS `etf_day_info` ( `id` int(11) NOT NULL AUTO_INCREMENT, `code` varchar(50) DEFAULT NULL COMMENT '代码', `name` varchar(50) DEFAULT NULL COMMENT '名字', `amount` bigint(20) DEFAULT NULL COMMENT '成交额', `chg` double DEFAULT NULL COMMENT '涨跌额', `percent` double DEFAULT NULL COMMENT '涨跌幅', `volume` bigint(20) DEFAULT NULL COMMENT '成交量', `close` double DEFAULT NULL COMMENT '市价', `time_trade` varchar(50) DEFAULT NULL COMMENT '交易时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=640561 DEFAULT CHARSET=utf8 COMMENT='etf基金日线数据'; -- 数据导出被取消选择。 /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; /*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;