-
- 一、概述
- 二、效果展示
-
三、實(shí)現(xiàn)代碼
- 1、行情數(shù)據(jù)中心
- 2、數(shù)據(jù)拉取模塊
- 3、基礎(chǔ)服務(wù)模塊
- 4、UI展示
- 四、相關(guān)文章
原文鏈接:簡(jiǎn)單的股票行情演示(一) - 實(shí)時(shí)標(biāo)的數(shù)據(jù)
一、概述
很長(zhǎng)一段時(shí)間都有一個(gè)想法,使用QCP去做一個(gè)行情展示小事例,一直沒有著手開發(fā)的原因主要是行情數(shù)據(jù)源的問題,畢竟穩(wěn)定的數(shù)據(jù)才是核心,加上今年5月份有了小寶寶也一直比較忙。
最近得空研究了下用C++實(shí)現(xiàn)股票行情展示相關(guān)內(nèi)容,主要策略是通過拉取網(wǎng)上一些免費(fèi)的開源接口數(shù)據(jù),然后存儲(chǔ)到本地,在通過代碼讀取需要的日期數(shù)據(jù)進(jìn)行展示?;ヂ?lián)網(wǎng)拉取行情數(shù)據(jù)方法網(wǎng)上隨手百度后會(huì)發(fā)現(xiàn)有一大堆,調(diào)取個(gè)別接口進(jìn)行獲取數(shù)據(jù)也是很方便的,比如通過新浪開源獲取A股股票接口獲取實(shí)時(shí)行情數(shù)據(jù)就很簡(jiǎn)單,瀏覽器url輸入框中輸入http://hq.sinajs.cn/list=sz002208,sh601318
這段測(cè)試連接,按下回車,就會(huì)拿到list指定的兩支股票數(shù)據(jù),效果如下圖所示。
需要特別注意:該接口拉取頻繁后,會(huì)被后臺(tái)403,所以本地需要做一些策略,盡可能減少無效拉取
嘗到了簡(jiǎn)單的甜頭之后,接下來就是瘋狂百度、google,盡可能全面的整理開源的行情數(shù)據(jù)源,網(wǎng)上雖然文章很多,但是重復(fù)的內(nèi)容特別多,講的比較好的文章有新浪股票 api、股票數(shù)據(jù) API 接口合集、實(shí)時(shí)行情API,通過看這幾篇文章能大概了解到一些皮毛,簡(jiǎn)單使用不成問題。總的來說提供了一個(gè)可操作的入口,數(shù)據(jù)源的問題算是暫時(shí)得到一部分解決,至于其他更完善的數(shù)據(jù)后續(xù)文章會(huì)有介紹,是由開源軟件提供,而且文檔比較詳細(xì),之后更多的數(shù)據(jù)將會(huì)使用開源程序進(jìn)行獲取。
實(shí)時(shí)行情數(shù)據(jù)有了之后,接下來就是C++側(cè)代碼實(shí)現(xiàn),主要分為異步數(shù)據(jù)拉取、數(shù)據(jù)寫入本地文件、數(shù)據(jù)層讀取,回調(diào)給UI展示,本篇文章接下來的主要內(nèi)容將會(huì)講解怎么拉取數(shù)據(jù)、回調(diào)給UI等流程。
二、效果展示
如下效果圖所示,是一個(gè)簡(jiǎn)單的多窗口程序,支持同時(shí)拉取多支股票實(shí)時(shí)行情數(shù)據(jù)并回調(diào)給UI。拿其中一個(gè)行情數(shù)據(jù)展示窗口為例來說明,數(shù)據(jù)源是來自新浪行情API接口,測(cè)試程序UI展示總共分上中下三段,上半部分主要是股票盤口數(shù)據(jù),展示開收盤價(jià)格、實(shí)時(shí)成交量等,中段是股票買賣五檔數(shù)據(jù),最底下白色框中是數(shù)據(jù)源內(nèi)容,也就是從互聯(lián)網(wǎng)接口拉取后的數(shù)據(jù)。
正常情況下測(cè)試程序只會(huì)跑一個(gè)窗口,圖示中多個(gè)窗口主要是為了觀察方便。
三、實(shí)現(xiàn)代碼
1、行情數(shù)據(jù)中心
要想實(shí)現(xiàn)數(shù)據(jù)復(fù)用,并減少Server壓力,數(shù)據(jù)中心是必不可少的模塊,舉一個(gè)簡(jiǎn)單例子,當(dāng)UI界面上展示的兩支股票相同時(shí),那么數(shù)據(jù)中心只會(huì)維護(hù)一支股票數(shù)據(jù),并實(shí)時(shí)更新然后同步給兩份UI界面。
如下代碼所示,為行情中心接口類,其中展示了如何去訂閱股票詳情數(shù)據(jù)和取消訂閱,IQuoteCall
這是訂閱者唯一標(biāo)識(shí),每一個(gè)想要獲取數(shù)據(jù)的對(duì)象都應(yīng)該是一個(gè)IQuoteCall
、或者持有一個(gè)IQuoteCall
。
struct?QUOTECENTER_EXPORT?IQuoteCenter
{
public:
?virtual?~IQuoteCenter(){}
public:
?//訂閱detail
?virtual?void?SubscribeDetail(IQuoteCall * observer,?const?SecurityInfo & security)?=?0;
?virtual?void?UnSubscribeDetail(IQuoteCall * observer)?=?0;
????.
????.
????.
?//取消所有數(shù)據(jù)訂閱
?virtual?void?UnSubscribe(IQuoteCall * observer)?=?0;
?.
?.
?.
};
IQuoteCall
接口類中有一個(gè)UpdateDetail
接口,通過重寫該接口即可獲取訂閱的標(biāo)的行情數(shù)據(jù),切換標(biāo)的時(shí)從新訂閱即可,之前訂閱的標(biāo)的會(huì)被自動(dòng)取消。
股票實(shí)時(shí)行情數(shù)據(jù)需要啟動(dòng)一個(gè)輪訓(xùn)任務(wù),每隔3秒去請(qǐng)求一次當(dāng)前訂閱的所有標(biāo)的數(shù)據(jù),有了時(shí)間服務(wù)后,我們只需要拋一個(gè)任務(wù)對(duì)象和時(shí)間間隔,之后的定時(shí)觸發(fā)操作則會(huì)自動(dòng)被執(zhí)行。
QuoteCenter::QuoteCenter()
{
?qRegisterMetaType<DetailCNItem>("DetailCNItem");
?qRegisterMetaType<QList<DetailCNItem>>("QList<DetailCNItem>");
?m_strTaskID = Services::TimerServiceInstance()->AddTask(&DoRequests,?3000);
????.
????.
????.
}
DoRequests
函數(shù)比較重要,可謂之承上啟下,關(guān)鍵橋梁作用,因此這里單獨(dú)做下說明。
首先DoRequests
是一個(gè)C函數(shù),被行情模塊注冊(cè)到時(shí)間管理器中,該函數(shù)會(huì)在指定時(shí)間間隔后觸發(fā)一次,每次任務(wù)觸發(fā)我們都需要在主線程中構(gòu)造一個(gè)任務(wù)請(qǐng)求工作者,并把任務(wù)執(zhí)行完成后的觸發(fā)信號(hào)與行情對(duì)象的接收槽函數(shù)綁定,之后把任務(wù)對(duì)象拋給網(wǎng)絡(luò)請(qǐng)求服務(wù)即可。任務(wù)對(duì)象后續(xù)還會(huì)有更加詳細(xì)的說明,具體參看對(duì)detail請(qǐng)求對(duì)象說明。
void?DoRequests(long?long?mseconds)
{
?.
?.
?.
?DetailWorker * detail =?new?DetailWorker(securitys);
?QObject::connect(detail, &DetailWorker::Response
??,?static_cast<QuoteCenter *>(Quote::QuoteCenterInstance()), &QuoteCenter::OnDetailResponse);
?RLNet::NetworkInstance()->AddTask(detail);
}
2、數(shù)據(jù)拉取模塊
本地?cái)?shù)據(jù)的唯一來源就是從網(wǎng)絡(luò)拉取,為了程序運(yùn)行流程起見,必須要運(yùn)行在工作線程中,防止阻塞UI,我們開發(fā)此演示程序是基于Qt開發(fā)框架下,所以線程創(chuàng)建、線程交互將會(huì)變的很簡(jiǎn)單,具體細(xì)節(jié)接下來一步一步講解。
線程池
既然用到Qt,那么線程池肯定也要用Qt的,這樣我們開發(fā)起來會(huì)省很多力氣,如下代碼所示,簡(jiǎn)單的幾行代碼我們就搞出來一個(gè)線程池,我們只管往池子里丟任務(wù),當(dāng)池子中有空閑線程時(shí)就會(huì)幫我們處理任務(wù),是不是非常nice。
void?RLNetwork::AddTask(CommonWorker * task)
{
?// 添加任務(wù)
?QThreadPool::globalInstance()->start(task);
}
RLNetwork::RLNetwork()
{
?curl_global_init(CURL_GLOBAL_DEFAULT);
?// 線程池初始化,設(shè)置最大線程池?cái)?shù)
?QThreadPool::globalInstance()->setMaxThreadCount(8);
}
RLNetwork::~RLNetwork()
{
?curl_global_cleanup();
}
任務(wù)對(duì)象
有了線程池后,我們只管創(chuàng)建需要的task,然后丟到池子中,任務(wù)的觸發(fā)時(shí)機(jī)將交給Qt線程池進(jìn)行管理,我們只需要關(guān)心任務(wù)中要干什么、任務(wù)結(jié)束后怎么通知給外部即可。
任務(wù)基類
為了減少大量重復(fù)代碼,這里我們定義一個(gè)任務(wù)基類,基類中完成每個(gè)請(qǐng)求任務(wù)都需要操作的內(nèi)容,然后把請(qǐng)求體和寫入內(nèi)容封裝成接口,供子類重寫。
抽象內(nèi)容包括:
- libcurl請(qǐng)求初始化、參數(shù)配置和清理
- 回調(diào)函數(shù)取到返回?cái)?shù)據(jù)后整理標(biāo)準(zhǔn)字符串轉(zhuǎn)發(fā)給子類Write函數(shù)
class?RLNETWORK_EXPORT?CommonWorker :?public?QObject,?public?QRunnable
{
public:
?CommonWorker();
?~CommonWorker();
public:
?virtual?void?run()?override;
?virtual?void?Write(char?* data, std::size_t?len)?=?0;
?virtual?void?DoRequest(CURL * curl)?=?0;
?static?size_t??CurlWriteCb(char?*ptr,?size_t?size,?size_t?nmemb,?void?*userdata);
private:
};
Detail請(qǐng)求
說了這么多,終于到了最關(guān)鍵的detail請(qǐng)求環(huán)節(jié),如下StockListWorker
代碼所示,當(dāng)Detail請(qǐng)求完成后,通過Response信號(hào)通知外部任務(wù)已完成,標(biāo)的detail存放在了filePath指定的文件中。
對(duì)于StockListWorker
對(duì)象有以下幾點(diǎn)需要注意:
- 構(gòu)造于主線程中,并且請(qǐng)求完成信號(hào)與主線程中槽函數(shù)所綁定
- DoRequest、Write和信號(hào)函數(shù)均運(yùn)行于工作線程中
- 任務(wù)基類中我們?cè)O(shè)置了setAutoDelete為true,因此所有的請(qǐng)求對(duì)象在執(zhí)行完任務(wù)后都會(huì)析構(gòu)
- 析構(gòu)函數(shù)運(yùn)行于工作線程中,與run函數(shù)所在線程一致
class?RLNETWORK_EXPORT?StockListWorker :?public?CommonWorker
{
?Q_OBJECT
public:
?StockListWorker(const?QString & filePath);
?~StockListWorker();
signals:
?void?Response(const?QString & filePath);
public:
?virtual?void?Write(char?* data, std::size_t?len)?override;
?virtual?void?DoRequest(CURL * curl)?override;
private:
?QString m_filePath;
?QFile m_file;
};
DoRequest
函數(shù)是基類提供給我們重寫發(fā)送請(qǐng)求使用,如下代碼所示,展示了請(qǐng)求detail數(shù)據(jù)的過程,網(wǎng)絡(luò)請(qǐng)求我們統(tǒng)一使用libcurl進(jìn)行完成,不使用Qt網(wǎng)絡(luò)庫主要是覺著不好用。
void?StockListWorker::DoRequest(CURL * curl)
{
?curl_easy_setopt(curl, CURLOPT_URL, StockListUrl);//準(zhǔn)備發(fā)送request的url
?CURLcode res =?curl_easy_perform(curl);
?if?(res == CURLE_OK)
?{
??curl_off_t?val =?-1;
??curl_easy_getinfo(curl, CURLINFO_NAMELOOKUP_TIME_T, &val);
??emit?Response(m_filePath);
?}
?else
?{
??std::cout <<?"curl_easy_perform() failed: "?<<?curl_easy_strerror(res);
?}
}
3、基礎(chǔ)服務(wù)模塊
市場(chǎng)服務(wù)
市場(chǎng)服務(wù)主要提供市場(chǎng)相關(guān)接口,如下代碼所示,IsTradingStatus
接口獲取當(dāng)前標(biāo)的所屬市場(chǎng)是否屬于交易狀態(tài),根據(jù)市場(chǎng)狀態(tài)我們可以過濾一些無效操作,比如A股不開盤時(shí),不需要請(qǐng)求detail等。
struct?BASICSERVICES_EXPORT?IMarketService
{
?virtual?~IMarketService(){}
?virtual?bool?IsTradingStatus(const?SecurityInfo & security,?long?long?mseconds)?const?=?0;
?virtual?bool?IsTradingStatus(const?QList<SecurityInfo> & securitys,?long?long?mseconds)?const?=?0;
?·
?·
?·
};
時(shí)間服務(wù)
時(shí)間管理器對(duì)于數(shù)據(jù)中心是相當(dāng)重要的,因?yàn)橛辛藭r(shí)間維度后,我們才能去定制一批時(shí)間相關(guān)的任務(wù),比如輪訓(xùn)任務(wù)、獲取當(dāng)前時(shí)間等。
本文中的股票實(shí)時(shí)detail數(shù)據(jù)就需要添加了一個(gè)輪訓(xùn)任務(wù),因?yàn)闆]有長(zhǎng)連接的加持,很多數(shù)據(jù)都需要我們自己去跟服務(wù)器要,雖然這樣會(huì)增大服務(wù)器的壓力,但是目前除過長(zhǎng)連接外沒有其他更好的方式去完成這件事。
struct?BASICSERVICES_EXPORT?ITimerService
{
?virtual?~ITimerService(){}
?virtual?QString?AddTask(const?std::function<void(long?long)> & fun,?long?internal =?3000)?=?0;
?virtual?bool?HasTask(const?QString &)?=?0;
?virtual?void?RemoveTask(const?QString &)?=?0;
?virtual?void?ImmediatelyTask(const?QString &)?=?0;
?virtual?long?long?GetCurrentStamp()?const?=?0;
?·
?·
?·
};
4、UI展示
訂閱股票detail
如下代碼所示,通過行情中心我們可以很簡(jiǎn)單的去訂閱標(biāo)的數(shù)據(jù),之后通過重寫UpdateDetail
接口拿數(shù)據(jù)就行,其他的我們統(tǒng)一不用操心。
void?HqSimple::on_pushButton_pull_clicked()
{
?const?QString & name = ui.comboBox->currentText();
?const?QString & id = ui.comboBox->currentData().toString();
?const?QStringList & items = id.split('_');
?SecurityInfo info;
?info.market = items.at(0);
?info.symbol = items.at(1);
?info.secType =?"STK";
?Quote::QuoteCenterInstance()->SubscribeDetail(this, info);
}
每一個(gè)需要訂閱行情數(shù)據(jù)的對(duì)象目前都是繼承自IQuoteCall
,或者持有一個(gè)IQuoteCall
,本篇文章包括后續(xù)系列文章都會(huì)采用第一種方案來實(shí)現(xiàn)數(shù)據(jù)訂閱,關(guān)于繼承和包含的優(yōu)缺點(diǎn)及使用場(chǎng)景問題大家可以自行斟酌,本篇文章所講述案列數(shù)據(jù)類型較少,使用繼承足以完成目標(biāo)。
struct QUOTECENTER_EXPORT IQuoteCall
{
virtual ~IQuoteCall(){}
virtual void UpdateDetail(const DetailCNItem &) = 0;
.
.
.
};
A股Detail數(shù)據(jù)定義
/*
0: 通用股份 // 名字;
1 : 5.050 // 今日開盤價(jià)
2 : 5.060 // 昨日收盤價(jià)
3 : 5.090 // 當(dāng)前價(jià)格
4 : 5.110 // 今日最高價(jià)
5 : 5.030 // 今日最低價(jià)
6 : 5.090 // 競(jìng)買價(jià),即 “買一” 報(bào)價(jià);
7 : 5.100 // 競(jìng)賣價(jià),即 “賣一” 報(bào)價(jià);
8 : 3963000 // 成交的股票數(shù),轉(zhuǎn)手乘 100
9 : 20106078.000// 成交金額 (元),轉(zhuǎn)萬除 10000
10 : 52800 //“買一” 申請(qǐng) 52800 股
11 : 5.090 //“買一” 報(bào)價(jià);
12 : 90600 //“買二” 申請(qǐng) 90600 股
13 : 5.080 //“買二” 報(bào)價(jià);
14 : 98500 //..
15 : 5.070 //..
16 : 105200 //..
17 : 5.060 //..
18 : 127900 //..
19 : 5.050 //..
20 : 104400 //“賣一” 申報(bào) 104400 股
21 : 5.100 //“賣一” 報(bào)價(jià);
22 : 99700 //“賣二” 申報(bào) 99700 股
23 : 5.110 //“賣二” 報(bào)價(jià);
24 : 111800 //..
25 : 5.120 //..
26 : 87500 //..
27 : 5.130 //..
28 : 73300 //..
29 : 5.140 //..
30 : 2022 - 02 - 14 // 日期
31 : 11 : 18 : 56 // 時(shí)間
*/
struct?STOCKDATA_EXPORT?DetailCNItem :?public?SecurityInfo
{
?//0-9
?QString name;??//名字
?double?open;??//今日開盤價(jià)
?double?preClose;?// 昨日收盤價(jià)
?double?lastprice;?// 當(dāng)前價(jià)格
?double?high;??// 今日最高價(jià)
?double?low;???// 今日最低價(jià)
?double?bid;???// 競(jìng)買價(jià),即 “買一” 報(bào)價(jià);
?double?ask;???// 競(jìng)賣價(jià),即 “賣一” 報(bào)價(jià);
?double?volumn;??// 成交的股票數(shù),轉(zhuǎn)手乘 100
?double?amount;??// 成交金額 (元),轉(zhuǎn)萬除 10000
?
?struct?AskBid
?{
??double?price;//買/賣價(jià)
??double?volumn;//買/賣量
?};
?QVector<AskBid> asks;//賣五檔 //10-19
?QVector<AskBid> bids;//買五檔 //20-29
?
?//30-31
?QString date;?// 日期
?QString time;?// 時(shí)間
?QString source;?//原始數(shù)據(jù)
?DetailCNItem();
?DetailCNItem(const?QString & str);
?DetailCNItem(DetailCNItem && other);
?void?Clear();
};
刷新數(shù)據(jù)
UI數(shù)據(jù)刷新這里就比較簡(jiǎn)單了,文章最開始已經(jīng)描述過UI數(shù)據(jù)分為上中下三部分,上部和下部就是簡(jiǎn)單文案設(shè)置,然后通過qss加了一些漲跌色配置,這里就簡(jiǎn)單展示下部分代碼。
void?HqSimple::UpdateDetail(const?DetailCNItem & data)
{
?ui.label_open->setText(QString::number(data.open,?'f',?2));
?.
?.
?.
?ui.label_amount->setText(QString::number(data.amount,?'f',?2));
?m_pListmodel->SetAskBid(data);
?ui.textEdit->setText(QStringLiteral("原始數(shù)據(jù):") + data.source);
}
盤口數(shù)據(jù)分為6列:買檔、買價(jià)格、買數(shù)量、賣數(shù)量、賣價(jià)格和賣檔。實(shí)現(xiàn)起來也比較簡(jiǎn)單,標(biāo)準(zhǔn)MVC即可搞定,代碼中表現(xiàn)為QAbstractListModel
+QListView
+QStyledItemDelegate
,其中M和V都比較簡(jiǎn)單,簡(jiǎn)單的進(jìn)行綁定之后就可以,這里主要說下繪制界面用的QStyledItemDelegate
,其中最為關(guān)鍵的就是paint
函數(shù),相信用過Qt一年半載的同學(xué)都比較熟悉,代碼如下所示,繪制代碼比較簡(jiǎn)單就不做說明了,不明白的同學(xué)進(jìn)行留言或者私聊即可。
void?AskBidDelegate::paint(QPainter * painter,?const?QStyleOptionViewItem & option,?const?QModelIndex & index)?const
{
?const?DetailCNItem & detail = index.model()->data(index).value<DetailCNItem>();
?//left
?int?y =?15;
?int?lwidth = option.rect.width() /?2;
?const?QPoint & gPos = QCursor::pos();
?const?QPoint & lPos = option.widget->mapFromGlobal(gPos);
?int?t =?0;
?if?(lPos.x() >=?0?&& lPos.x() <= lwidth)
?{
??t =?1;
?}
?else?if?(lPos.x() >= lwidth && lPos.x() <= lwidth *?2)
?{
??t =?2;
?}
?{
??painter->fillRect(option.rect.adjusted(0,?0, lwidth,?0)
???, t ==?1?&& option.state.testFlag(QStyle::State_MouseOver) ??QColor(28,?109,?83) :?QColor(39,?67,?62));
??const?DetailCNItem::AskBid & bid = detail.bids.at(index.row());
??const?QString & bidName =?QStringLiteral("買%1").arg(index.row() +?1);
??painter->setPen(QColor(Qt::white));
??painter->drawText(10, option.rect.top() + y, bidName);
??painter->setPen(QColor(Qt::red));
??painter->drawText(60, option.rect.top() + y,?PriceText(bid.price));
??const?QString & volumnName =?PriceText(bid.volumn);
??int?volumW = painter->fontMetrics().width(volumnName);
??painter->setPen(QColor(Qt::white));
??painter->drawText(lwidth - volumW, option.rect.top() + y, volumnName);
?}
?//right
?{
??painter->fillRect(option.rect.adjusted(option.rect.width() /?2,?0,?0,?0)
???, t ==?2?&& option.state.testFlag(QStyle::State_MouseOver) ??QColor(28,?109,?83) :?QColor(68,?48,?58));
??const?DetailCNItem::AskBid & ask = detail.asks.at(index.row());
??const?QString & volumnName =?PriceText(ask.volumn);
??painter->setPen(QColor(Qt::white));
??painter->drawText(lwidth +?10, option.rect.top() + y, volumnName);
??painter->setPen(QColor(Qt::green));
??painter->drawText(option.rect.width() -?98, option.rect.top() + y,?PriceText(ask.price));
??const?QString & askName =?QStringLiteral("賣%1").arg(index.row() +?1);
??painter->setPen(QColor(Qt::white));
??painter->drawText(option.rect.width() -?28, option.rect.top() + y, askName);
?}
}
講到這里,股票行情展示程序也差不都完成了,從數(shù)據(jù)訂閱、數(shù)據(jù)求情、數(shù)據(jù)緩存、數(shù)據(jù)回調(diào)和數(shù)據(jù)刷新大致都說了一遍,最后貼上項(xiàng)目工程截圖,大家可以參考。
四、相關(guān)文章
- Qt 之股票組件 - 自選股 -- 列表可以拖拽、右鍵常用菜單
- Qt 之股票組件 - 股票檢索 -- 支持搜索結(jié)果預(yù)覽、鼠標(biāo)、鍵盤操作
- QCustomplot使用分享(一) 能做什么事
- QCustomplot使用分享(二) 源碼解讀
- QCustomplot使用分享(三) 圖
- QCustomplot使用分享(四) QCPAbstractItem
- QCustomplot使用分享(五) 布局
- QCustomplot使用分享(六) 坐標(biāo)軸和網(wǎng)格線
- QCustomplot使用分享(七) 層(完結(jié))
值得一看的優(yōu)秀文章:
- 財(cái)聯(lián)社-產(chǎn)品展示
- 廣聯(lián)達(dá)-產(chǎn)品展示
- Qt定制控件列表
- 牛逼哄哄的Qt庫
如果您覺得文章不錯(cuò),不妨給個(gè)打賞,寫作不易,感謝各位的支持。您的支持是我最大的動(dòng)力,謝謝!??!
?
很重要--轉(zhuǎn)載聲明
-
本站文章無特別說明,皆為原創(chuàng),版權(quán)所有,轉(zhuǎn)載時(shí)請(qǐng)用鏈接的方式,給出原文出處。同時(shí)寫上原作者:朝十晚八?or?Twowords文章來源:http://www.zghlxwxcb.cn/news/detail-506017.html
-
如要轉(zhuǎn)載,請(qǐng)?jiān)霓D(zhuǎn)載,如在轉(zhuǎn)載時(shí)修改本文,請(qǐng)事先告知,謝絕在轉(zhuǎn)載時(shí)通過修改本文達(dá)到有利于轉(zhuǎn)載者的目的。文章來源地址http://www.zghlxwxcb.cn/news/detail-506017.html
到了這里,關(guān)于簡(jiǎn)單的股票行情演示(一) - 實(shí)時(shí)標(biāo)的數(shù)據(jù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!