QT实现简易ctp程序
1.開發(fā)環(huán)境
? qt5.9.9 msvc2017環(huán)境(mingw不能運(yùn)行) 以及自帶的Qt Creator,上期提供的穿透式api,并且導(dǎo)入qcustomplot庫以實(shí)現(xiàn)圖表效果。
? 本程序借鑒了b站視頻:BV1ET4y1L7iN。
2.效果展示
?
?
? 實(shí)現(xiàn)了行情,委托,成交,持倉,合約,等表的展示,以及用戶的登錄和下單等操作。注:登錄部分?jǐn)?shù)據(jù)固定,可以自行拓展,可以通過下載快期交易平臺來查看自己的下單等操作。程序運(yùn)行后,當(dāng)行情表沒有數(shù)據(jù),請使用另一個(gè)可以使用的端口登錄本程序(在快期交易平臺可以查看)。
3.代碼簡介
?? 引用:綜合交易平臺(Comprehensive Transaction Platform,CTP)是專門為期貨公司開發(fā)的一套期貨經(jīng)紀(jì)業(yè)務(wù)管理系統(tǒng),由交易、風(fēng)險(xiǎn)控制和結(jié)算三大系統(tǒng)組成。導(dǎo)入上期提供的api接口后,分別對行情,委托,成交,持倉,合約來進(jìn)行實(shí)現(xiàn)。
CTP 的所有接口都分為 Spi 和 Api 兩種,這里對其簡單說明
API:Api 類提供了交易/行情的各種功能,但這些需要我們主動(dòng)對服務(wù)器發(fā)出的請求。
SPI:Spi 類提供了交易/行情相關(guān)的回調(diào)接口,我們需要繼承該類并重載這些接口,以獲取響應(yīng)數(shù)據(jù)。
? api可以理解為是上期為我們提供的已經(jīng)封裝好的一類函數(shù),我們只需直接調(diào)用這些函數(shù),大部分無需重寫,即可使用該函數(shù)功能,而spi體現(xiàn)了一種回調(diào)的思想,當(dāng)我們的api調(diào)用后,spi會返回一些東西,我們可以通過這些返回值來判斷api執(zhí)行是否正常。
? 舉個(gè)例子,當(dāng)我們需要登錄行情的時(shí)候,我們需要使用RspUserLogin函數(shù),當(dāng)該函數(shù)執(zhí)行完畢后,會有與之對應(yīng)的OnRspUserLogin函數(shù)被自動(dòng)調(diào)用,我們可以利用其中的返回值來判斷登錄是否成功。
? 要實(shí)現(xiàn)行情部分,我們需要?jiǎng)?chuàng)建一個(gè)類來繼承CThostFtdcMdSpi并且重寫部分函數(shù)。
? 舉個(gè)例子,當(dāng)客戶端與交易后臺進(jìn)行通訊連接時(shí),我們可以對OnFrontConnected重寫來監(jiān)聽連接是否成功。
?
? 同時(shí)實(shí)現(xiàn)行情的登錄。接下來,我們通過對OnRtnDepthMarketData 的重寫來實(shí)現(xiàn)行情信息的獲取,由于涉及到多個(gè)類之間的信息通信,我們在獲取到數(shù)據(jù)后將其拼接為一個(gè)由 , 隔開的字符串并且寫一個(gè)帶有字符串參數(shù)的信號sendData來傳輸數(shù)據(jù),在主類中獲取并且打印在表單上。
?
?? 交易部分則復(fù)雜一些。不過還是讓我們從客戶端登錄做起,照葫蘆畫瓢,我們重寫了tradeapi中OnFrontConnected 函數(shù),來在信號連? 接的時(shí)候就實(shí)現(xiàn)其登錄,以下的userid也就是注冊時(shí)得到的investorID可以修改為您自己的investorID。
??? 要實(shí)現(xiàn)個(gè)人賬戶的登錄,我們在登錄按鈕上寫一個(gè)槽函數(shù),將正確的賬戶密碼寫上去,登陸成功。
? 在登錄后,程序會立馬獲取合約,持倉,賬戶等信息,三者的寫法不會有很大區(qū)別,讓我們以合約為例子來講一下。
? 我們需要重寫OnRspQryInstrument函數(shù),并且使用多個(gè)字符串來接受pInstrument中的數(shù)據(jù),接下來我們將其拼接為一個(gè)字符串,同上,由于涉及到多個(gè)類之間的信息通信,我們在獲取到數(shù)據(jù)后將其拼接為一個(gè)由 , 隔開的字符串并且寫一個(gè)帶有字符串參數(shù)的信號sendDataHy來傳輸數(shù)據(jù),同時(shí),我們也要將這些數(shù)據(jù)存儲在一個(gè)兩重字符串?dāng)?shù)組中以便之后使用,最后,在主類中分割字符串并將其寫入表中。
?? 合約,持倉,賬戶表單操作差異不大,學(xué)會了合約之后,就可以舉一反三了。我們來到很重要的一步,下單以及撤單,請繼續(xù)閱讀以下內(nèi)容。
??? 要實(shí)現(xiàn)這一功能,我們需要自行寫一個(gè)函數(shù)并且主動(dòng)調(diào)用它了,我們找到ReqOrderInsert函數(shù),發(fā)現(xiàn)這個(gè)函數(shù)可以用于下單,于是我們可以自己定義一個(gè)同名的ReqOrderInsert函數(shù),但是它擁有參數(shù)以便我們調(diào)用它。
?
??
void CTraderSpi::ReqOrderInsert(QString dm,QString lx,int lots,double price) {CThostFtdcInputOrderField ord ;memset(&ord, 0, sizeof(ord));strcpy_s(ord.BrokerID, "9999");strcpy_s(ord.InvestorID, "204925");strcpy_s(ord.ExchangeID, "SHFE");strcpy_s(ord.InstrumentID,dm.toStdString().data() );sprintf(ORDER_REF,"%d",iRequestID);strcpy_s(ord.OrderRef,ORDER_REF );ord.OrderPriceType = THOST_FTDC_OPT_LimitPrice;//限價(jià)if(lx =="kd"){ord.Direction = THOST_FTDC_D_Buy;//買 DIRECTIONord.CombOffsetFlag[0] = THOST_FTDC_OF_Open;//開}else if(lx =="pd"){ord.Direction = THOST_FTDC_D_Buy;//買 DIRECTIONord.CombOffsetFlag[0] = THOST_FTDC_OF_CloseToday;//開}else if(lx =="kk"){ord.Direction = THOST_FTDC_D_Sell;//買 DIRECTIONord.CombOffsetFlag[0] = THOST_FTDC_OF_Open;//開}else if(lx =="pk"){ord.Direction = THOST_FTDC_D_Sell;//買 DIRECTIONord.CombOffsetFlag[0] = THOST_FTDC_OF_CloseToday;//開}ord.CombHedgeFlag[0] = THOST_FTDC_HF_Speculation;//投機(jī)ord.LimitPrice = price;ord.VolumeTotalOriginal = lots;ord.TimeCondition = THOST_FTDC_TC_GFD;///當(dāng)日有效ord.VolumeCondition = THOST_FTDC_VC_AV;///任意數(shù)量ord.MinVolume = 1;ord.ContingentCondition = THOST_FTDC_CC_Immediately;ord.StopPrice = 0;ord.ForceCloseReason = THOST_FTDC_FCC_NotForceClose;ord.IsAutoSuspend = 0;pUserApi->ReqOrderInsert(&ord, ++iRequestID); };?? 函數(shù)看起來非常之長,但是其中很多都是比較固定的值,對于我們新手來說,復(fù)制粘貼就完事了,參數(shù)lx是用來區(qū)分是開多,平多,還是開空,平空的,作為非金融專業(yè)的我也不是很懂這些,大家可以自行查找以進(jìn)行拓展,我們將ord數(shù)據(jù)寫好后調(diào)用以ord為參數(shù)的ReqOrderInsert,即可實(shí)現(xiàn)下單。
? 再執(zhí)行下單后,委托會出現(xiàn)數(shù)據(jù),如果是處于還未成交的狀況下,我們可以實(shí)現(xiàn)撤單功能,那么在委托的表單中,我們就需要實(shí)現(xiàn) 點(diǎn)擊后識別點(diǎn)擊的一欄并且出現(xiàn)一個(gè)撤單選項(xiàng),點(diǎn)擊撤單我們就可以進(jìn)行撤單操作。
? 代碼如下:?
void MainWindow::OnWTmenu(const QPoint &pt) {qDebug()<<"onwtmenu";QMenu menu;menu.addAction(ui->actioncd);menu.exec(ui->tableWT_2->mapToGlobal(pt));}void MainWindow::ct() {if(ui->tableWT_2->rowCount()==0)return;int i = ui->tableWT_2->currentIndex().row();QString wth = ui->tableWT_2->item(i,7)->text();QString jys = ui->tableWT_2->item(i,8)->text();QString brokerid = "9999";qDebug()<<wth;qDebug()<<jys;if(wth == "")return;ptdUserSpi->ReqOrderAction(brokerid,wth,jys); }? 撤單相較來說簡單一點(diǎn),我們獲取到點(diǎn)擊的行數(shù)后,通過行數(shù)來獲得委托號以及交易所,最后加上brokerID即可調(diào)用撤單,撤單成功后,委托表中其狀態(tài)會變?yōu)橐猿穯?#xff0c;同時(shí),你也可以登錄快期交易平臺來查看交易是否撤單成功。
4.代碼獲取
?賬號注冊:?? sinmow?(有的時(shí)間段可能登錄不上)。
api獲取:上期技術(shù)官網(wǎng)? ,sinmow 。
gitee:?QTctp: QT簡單實(shí)現(xiàn)ctp程序 。
推薦閱讀文章 :CTP 學(xué)習(xí)筆記_EmoryHuang的博客-CSDN博客
總結(jié)
以上是生活随笔為你收集整理的QT实现简易ctp程序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 年度全球区块链最有影响力人物排行榜TOP
- 下一篇: 台电p10hd四核刷Android6.0