關(guān)于IB的錯(cuò)誤碼在我們進(jìn)一步深入IB的工作機(jī)理前,需要回到Wrapper中error函數(shù),如果善用error函數(shù)提供的錯(cuò)誤信息,將能幫助我們快速定位到錯(cuò)誤,并且修正我們的代碼。 關(guān)于IB錯(cuò)誤Code,具體的編碼,請(qǐng)查考網(wǎng)站 https://interactivebrokers./tws-api/message_codes.html。 這里,我重點(diǎn)說(shuō)一下error函數(shù)中,帶有id函數(shù),這是我們繼續(xù)開發(fā)客戶端算法非常重要的基礎(chǔ)。 public void error(int id, int errorCode, string errorMsg) { Console.WriteLine('TWS Error: id:{0} code:{1} message:{2}', id, errorCode, errorMsg); }
它包含3個(gè)返回參數(shù),整數(shù)型的id,整數(shù)型的errorCode,以及string型的errorMsg。這里的id是我們提交到TWS的任務(wù)id,也就是OrderId,當(dāng)它為-1時(shí),這個(gè)函數(shù)得到的信息,會(huì)有點(diǎn)類似一些Debug里面的Info級(jí)別消息,也就是告訴你當(dāng)前TWS的工作狀態(tài),你的客戶端與TWS連接情況,TWS與IB自身,交易所的連接情況等基礎(chǔ)信息。 所以,上一篇文章里,我們啥也沒干,在Console里一下子打出了一堆信息,就是這樣的原因。 而errorCode,就是比較有用的錯(cuò)誤信息了,它是不同的預(yù)定義的編碼,具體編碼信息,你可以從上面的連接里對(duì)照著找,比如這個(gè)截圖里出現(xiàn)的2104,在IB自己的官網(wǎng)定義就是:
至于message,就是返回的消息咯。 另一個(gè)帶Exception的error,指的是你調(diào)用IB API時(shí)產(chǎn)生的錯(cuò)誤。比如你試圖發(fā)送一個(gè)訂單,但是你并未建立起跟TWS的連接,這個(gè)時(shí)候就會(huì)出現(xiàn)TCP連接錯(cuò)誤的問(wèn)題,而這個(gè)錯(cuò)誤,就會(huì)通過(guò)
這個(gè)回調(diào)函數(shù)告訴你。因此,你可以使用調(diào)用棧信息,找出錯(cuò)誤的代碼位置,或者直接打印異常信息本身。 提交命令在IB API的架構(gòu)設(shè)計(jì),所有向IB Server提交的命令,都是通過(guò)EClient封裝好的API來(lái)提交。啥玩意是EClient? EclientSocket繼承了Eclient和EClientMsgSink,這個(gè)類自身所擔(dān)負(fù)的主要工作就是創(chuàng)建和維護(hù)與TWS通信的TCP信道。而任務(wù)命名請(qǐng)求,則全部交由EClient負(fù)責(zé)。 因此,對(duì)于TWS來(lái)說(shuō),你提交任務(wù)的基本方式,大體上是這樣的: clientSocket.reqXXXXX(id, ...);
因此,你能做什么,不能做什么,基本上就看Eclient是否封裝了對(duì)應(yīng)的API,以及API里需要的參數(shù)是什么樣子的,所以具體的你可以看看API手冊(cè)上是怎么寫的。 那么明白了這一點(diǎn),我們可以進(jìn)入到下一個(gè)內(nèi)容,向TWS提交合約信息。 合約所謂合約,如果從金融專業(yè)出發(fā),指的是合同,或者更俠義的說(shuō)是商品交割合同,也就是期貨、股指等商品的交易合同。 IB把絕大部分的交易請(qǐng)求行為定義為合約(Contract),這意味著用戶要提交具體的數(shù)據(jù)請(qǐng)求時(shí),需要像填表一樣,把相關(guān)任務(wù)的信息填入到Contract中,因此,不同類型的任務(wù),需要填寫的關(guān)鍵字是不一樣的。 IB將很多操作,比如查股價(jià),查期貨合約等任務(wù),都視為一個(gè)合約任務(wù),不知道這種定義更偏向金融系統(tǒng)的人還是更偏向IT系統(tǒng)的,如果用我們IT的行話說(shuō),那一個(gè)Contract其實(shí)就是一個(gè)Request。 你要是還不明白這個(gè)是什么意思,那么容許我引入一下網(wǎng)絡(luò)開發(fā)常提到的HTTP協(xié)議。在HTTP中,我們通過(guò)GET/POST命名,并附帶各種參數(shù),以此告知遠(yuǎn)程服務(wù)器對(duì)應(yīng)的任務(wù)形式。 Contract也是類似的,只不過(guò)是用類進(jìn)行表示的。所以要做什么事,能做什么事,兩件函數(shù)相同但功能不同的任務(wù)如何區(qū)分,思路也基本一樣,就是依靠提交的Contract類的不同參數(shù)定義來(lái)區(qū)分。 這其實(shí)也可以理解,因?yàn)镮B涵蓋的交易產(chǎn)品太多太廣泛,必然會(huì)出現(xiàn)很多重復(fù)的地方,所以一個(gè)交易產(chǎn)品,需要多個(gè)不同的字段去縮小它的定義。 舉例來(lái)說(shuō),當(dāng)你告知IB,幫我查找“蘋果”。如果不告知它具體的其他信息,它可能會(huì)以為你要查找蘋果現(xiàn)貨合約,蘋果股票期權(quán)合約,或者蘋果股票合約;它會(huì)完全confused。 所以要怎么去查找具體的商品合約信息呢? IB給出的建議是讓我們直接在TWS中找具體的信息(通過(guò)雙擊,或者在Contract Info -> Description): 然后我們可以得到這樣的信息: 這個(gè)框里的東西,告知了我們對(duì)應(yīng)的合約信息,包含交易所代碼,合約代碼,貨幣單位等重要的信息。所以如果你需要TWS告訴你蘋果公司的股票合約信息,而不是期權(quán)合約信息,甚至不是蘋果現(xiàn)貨合約信息,那么你需要通過(guò)這個(gè)方法,找到蘋果股票的合約信息。 接下來(lái)怎么做?還記得上一篇文章《#IB TWS編程手記——01.TWS建立基礎(chǔ)連接》中怎樣建立與TWS的連接么? 我們接下來(lái)要做的,就是在Main函數(shù)里先增加這么一個(gè)指令:
我們注意下這個(gè)新增的代碼: clientSocket.reqMatchingSymbols(wrapper.NextOrderId, 'IB');
這個(gè)指令的意思,是讓TWS幫我們查找合約中,合約代碼為“IB”的交易產(chǎn)品信息。還記得我們的Wrapper中,只實(shí)現(xiàn)了屈指可數(shù)的幾個(gè)函數(shù)嗎? 現(xiàn)在回到Wrapper的實(shí)現(xiàn)類,我們需要把回調(diào)函數(shù)“symbolSamples”實(shí)現(xiàn)它的方法:
然后你再重新執(zhí)行一遍代碼,看看有什么效果?然后再去跟TWS的信息做一下對(duì)比? |
|
來(lái)自: AIANT > 《量化交易學(xué)習(xí)》