wumu
2025-11-06 fcc4de01b336e73df6788fa6129ec15162ac6701
251106
1个文件已添加
5个文件已修改
418 ■■■■■ 已修改文件
agilestrategy.cpp 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
analysisbyrediscache.ui 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
etfstockinfo.cpp 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
etfstockinfo.h 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
etfstockinfo.ui 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
stock_plan_251106_etf.sql 36 ●●●●● 补丁 | 查看 | 原始文档 | 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 */;