成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

基于 IB 盈透證券的原生 Python API 連接

開發(fā) 后端
在本文中,我們將介紹如何為 Interactive Brokers Native Python API 提供的 EClient 和 EWrapper 類派生子類。然后,我們將提供端到端連接測試腳本,以確保我們能夠與 IB 進(jìn)行對話。

[[419168]]

Python中文社區(qū) (ID:python-china)

 在本文中,我們將介紹如何為 Interactive Brokers Native Python API 提供的 EClient 和 EWrapper 類派生子類。然后,我們將提供端到端連接測試腳本,以確保我們能夠與 IB 進(jìn)行對話。

盈透證券(Interactive Brokers)一直是受交易者歡迎的經(jīng)紀(jì)商。最初,這可能部分歸因于 IB 提供了一個應(yīng)用程序編程接口 (API),允許量化交易者獲取市場數(shù)據(jù)并直接在代碼中進(jìn)行交易。許多相互競爭的經(jīng)紀(jì)商花了一些時間來開發(fā)自己的 API,使 IB 在零售量化交易領(lǐng)域獲得了合理的先發(fā)優(yōu)勢。

雖然最初的 IB API 以接口復(fù)雜而著稱,但近年來隨著 IB Native Python API 庫的發(fā)布,情況發(fā)生了變化。

在這個新系列文章中,我們將使用 ibapi 庫,來解釋如何通過“原生 Python”接口與Interactive Brokers API交互。

最終我們將學(xué)習(xí)如何請求市場數(shù)據(jù)、定義合同和處理訂單。本文將重點(diǎn)介紹接口本身并測試基本連接。

本文假設(shè)您有一個可運(yùn)行的 Python 虛擬環(huán)境(例如 Anaconda 個人版)并已成功將 IB Python API 安裝到該環(huán)境中。安裝說明是特定于操作系統(tǒng)的??梢栽贗nteractive Brokers API 站點(diǎn)上找到最新的說明。

概述

IB API 通過異步'request-response'模型進(jìn)行工作。消息通過客戶端類發(fā)送到 IB 服務(wù)器(通過 Trader Workstation 或IB Gateway),而響應(yīng)(稱為“errors”)由包裝類單獨(dú)處理。

大部分內(nèi)部連接處理都通過 Python API 從最終用戶那里抽取出來,允許最少必要的'boilerplate'代碼進(jìn)行連接。但是,連接到 IB 的原始遺留機(jī)制仍然部分地影響了 API 的設(shè)計(jì)。因此,對于那些不習(xí)慣面向?qū)ο笤O(shè)計(jì)原則的人來說,這可能會令人困惑。

雖然最初似乎不清楚所有組件如何組合在一起,但在對以下類進(jìn)行編碼后,應(yīng)該開始了解 API 的構(gòu)建方式。

為了連接到 IB API,需要對四個主要組件進(jìn)行編碼。

第一個是 IB API EWrapper 類的派生子類。 EWrapper 用于處理來自 IB 服務(wù)器的所有響應(yīng)('errors')。

第二個是IB API EClient 類的派生子類。 EClient 用于將所有消息發(fā)送到 IB 服務(wù)器。

第三個是從 EWrapper 和 EClient 派生的子類的多重繼承類,用作 IB API 應(yīng)用程序的基礎(chǔ),它將所有通訊聯(lián)系在一起。

最后會有一個 if __name__ == "__main__": 入口點(diǎn),旨在允許從命令行執(zhí)行腳本。

初始化

第一步是導(dǎo)入腳本中使用的必要庫組件。

我們將需要 IB API EWrapper 和 EClient 類,這將在下面描述。我們還需要分別來自線程 和隊(duì)列庫的Thread和Queue標(biāo)準(zhǔn)庫組件。最后,我們將導(dǎo)入 datetime 以將 Unix 時間戳轉(zhuǎn)換為更易讀的格式: 

  1. # ib_api_connection.py  
  2. import datetime  
  3. import queue  
  4. import threading  
  5. from ibapi.client import EClient  
  6. from ibapi.wrapper import EWrapper 

我們現(xiàn)在可以定義 IBAPIWrapper 類。

IBAPIWrapper 類

EWrapper 類提供了一個接口處理來自 IB 服務(wù)器的響應(yīng)(描述為'errors')。接口指定可以在派生子類中實(shí)現(xiàn)的方法。通過繼承這個類,我們可以覆蓋這些方法以適應(yīng)我們自己特定的數(shù)據(jù)處理方法。

讓我們首先創(chuàng)建 EWrapper 的 IBAPIWrapper 派生子類并覆蓋一些方法。顯示此組件的完整代碼段,并將依次介紹每種方法: 

  1. # ib_api_connection.py  
  2. class IBAPIWrapper(EWrapper):  
  3.     """  
  4.     A derived subclass of the IB API EWrapper interface  
  5.     that allows more straightforward response processing 
  6.     from the IB Gateway or an instance of TWS.  
  7.     """  
  8.     def init_error(self):  
  9.         """  
  10.         Place all of the error messages from IB into a  
  11.         Python queue, which can be accessed elsewhere.  
  12.         """  
  13.         error_queue = queue.Queue()  
  14.         self._errors = error_queue  
  15.     def is_error(self):  
  16.         """  
  17.         Check the error queue for the presence  
  18.         of errors. 
  19.         Returns  
  20.         -------  
  21.         `boolean`  
  22.             Whether the error queue is not empty  
  23.         """  
  24.         return not self._errors.empty()  
  25.     def get_error(self, timeout=5):  
  26.         """  
  27.         Attempts to retrieve an error from the error queue,  
  28.         otherwise returns None.  
  29.         Parameters  
  30.         ----------  
  31.         timeout : `float`  
  32.             Time-out after this many seconds.  
  33.         Returns  
  34.         -------  
  35.         `str` or None  
  36.             A potential error message from the error queue.  
  37.         """  
  38.         if self.is_error():  
  39.             try:  
  40.                 return self._errors.get(timeouttimeout=timeout)  
  41.             except queue.Empty:  
  42.                 return None  
  43.         return None  
  44.     def error(self, id, errorCode, errorString):  
  45.         """  
  46.         Format the error message with appropriate codes and  
  47.         place the error string onto the error queue.  
  48.         """  
  49.         error_message = (  
  50.             "IB Error ID (%d), Error Code (%d) with "  
  51.             "response '%s'" % (id, errorCode, errorString)  
  52.         )  
  53.         self._errors.put(error_message)  
  54.     def init_time(self):  
  55.         """  
  56.         Instantiates a new queue to store the server  
  57.         time, assigning it to a 'private' instance  
  58.         variable and also returning it.  
  59.         Returns  
  60.         -------  
  61.         `Queue`  
  62.             The time queue instance.  
  63.         """  
  64.         time_queue = queue.Queue()  
  65.         self._time_queue = time_queue  
  66.         return time_queue  
  67.     def currentTime(self, server_time):  
  68.         """  
  69.         Takes the time received by the server and  
  70.         appends it to the class instance time queue.  
  71.         Parameters  
  72.         ----------  
  73.         server_time : `str`  
  74.             The server time message.  
  75.         """  
  76.         self._time_queue.put(server_time) 

init_error 的任務(wù)是創(chuàng)建一個 Python Queue隊(duì)列并將其附加一個名為_errors 的“私有”實(shí)例變量。該隊(duì)列將在整個類中用于存儲 IB 錯誤消息以供以后處理。

is_error 是一個簡單的方法,用于判斷_errors 隊(duì)列是否為空。

get_error嘗試從隊(duì)列中檢索錯誤消息,規(guī)定的超時時間以秒為單位。如果隊(duì)列為空或超時,則該方法不會返回任何內(nèi)容。

error 將提供的錯誤代碼與錯誤消息一起格式化為適當(dāng)?shù)淖址袷剑缓髮⑵浞湃?_errors 隊(duì)列。此方法用于在針對 API 執(zhí)行代碼時在控制臺上提供更好的調(diào)試信息。

這四種方法完成了對來自盈透證券的響應(yīng)('errors')的處理。需要注意的是,ibapi 庫中有很多內(nèi)部機(jī)器執(zhí)行此處理。從我們的派生子類中無法直接看到大部分工作。

其余兩個方法 init_time 和 currentTime 用于執(zhí)行連接“健全性檢查”('sanity check')。確定我們是否連接成功的一種簡單方法是檢索 IB 服務(wù)器上的本地時間。

這兩種方法只是創(chuàng)建一個新隊(duì)列來存儲服務(wù)器時間消息,并在請求時將新時間消息放置到這個隊(duì)列中。

我們的 EWrapper 簡單子類到此結(jié)束。我們現(xiàn)在能夠處理來自 IB 服務(wù)器的某些響應(yīng)。下一個任務(wù)是實(shí)際向 IB 服務(wù)器發(fā)送消息。為此,我們需要覆蓋 EClient 類。

IBAPIClient 類

EClient的 IBAPIClient 派生子類用于向 IB 服務(wù)器發(fā)送消息。

需要特別注意的是,我們派生子類的構(gòu)造函數(shù) __init__方法接受一個包裝參數(shù),然后將其傳遞給EClient父構(gòu)造函數(shù)。這意味著在 IBAPIClient類中沒有覆蓋本地 IB API 方法。相反,我們提供了包裝器實(shí)例(從 IBAPIWrapper實(shí)例化)來處理響應(yīng)。 

  1. # ib_api_connection.py  
  2. class IBAPIClient(EClient):  
  3.     """  
  4.     Used to send messages to the IB servers via the API. In this  
  5.     simple derived subclass of EClient we provide a method called  
  6.     obtain_server_time to carry out a 'sanity check' for connection  
  7.     testing.  
  8.     Parameters  
  9.     ----------  
  10.     wrapper : `EWrapper` derived subclass  
  11.         Used to handle the responses sent from IB servers  
  12.     """ 
  13.     MAX_WAIT_TIME_SECONDS = 10  
  14.     def __init__(self, wrapper):  
  15.         EClient.__init__(self, wrapper)  
  16.     def obtain_server_time(self):  
  17.         """  
  18.         Requests the current server time from IB then  
  19.         returns it if available.  
  20.         Returns  
  21.         -------  
  22.         `int`  
  23.             The server unix timestamp.  
  24.         """  
  25.         # Instantiate a queue to store the server time  
  26.         time_queue = self.wrapper.init_time()  
  27.         # Ask IB for the server time using the EClient method  
  28.         self.reqCurrentTime()  
  29.         # Try to obtain the latest server time if it exists  
  30.         # in the queue, otherwise issue a warning  
  31.         try:  
  32.             server_time = time_queue.get(  
  33.                 timeout=IBAPIClient.MAX_WAIT_TIME_SECONDS  
  34.             )  
  35.         except queue.Empty:  
  36.             print(  
  37.                 "Time queue was empty or exceeded maximum timeout of "  
  38.                 "%d seconds" % IBAPIClient.MAX_WAIT_TIME_SECONDS  
  39.             )  
  40.             server_time = None   
  41.         # Output all additional errors, if they exist  
  42.         while self.wrapper.is_error():  
  43.             print(self.get_error())  
  44.         return server_time 

在obtain_server_time中,我們首先創(chuàng)建一個隊(duì)列來保存來自服務(wù)器的時間戳消息。然后我們調(diào)用原生 EClient 方法 reqCurrentTime 從服務(wù)器獲取時間。

隨后,我們在 try...except 塊中包裝了一個從時間隊(duì)列中獲取值的調(diào)用。我們提供10秒的超時時間。如果超時或隊(duì)列為空,我們將服務(wù)器時間設(shè)置為None。

我們運(yùn)行一個 while 循環(huán)來檢查 EWrapper 派生子類中定義的錯誤隊(duì)列中的任何其他響應(yīng)。如果它們存在,它們將打印到控制臺。

最后我們返回服務(wù)器時間。

下一階段是創(chuàng)建一種機(jī)制來實(shí)例化 IBAPIWrapper和 IBAPIClient,以及實(shí)際連接到 IB 服務(wù)器。

IBAPIApp

本文中要派生的最后一個類是 IBAPIApp 類。

此類利用多重繼承從 IBAPIWrapper 和 IBAPIClient 類繼承。在初始化時,這兩個類也被初始化。但是,請注意 IBAPIClient 類將 wrapper=self 作為初始化關(guān)鍵字參數(shù),因?yàn)?IBAPIApp也是從 IBAPIWrapper 派生的。

在初始化兩個父類之后,使用適當(dāng)?shù)倪B接參數(shù)調(diào)用connect原生方法。

下一部分代碼初始化應(yīng)用程序所需的各種線程??蛻舳藢?shí)例有一個線程,另一個用于將響應(yīng)消息添加到各個隊(duì)列。

最后調(diào)用 init_error 方法開始監(jiān)聽 IB 響應(yīng)。 

  1. # ib_api_connection.py  
  2. class IBAPIApp(IBAPIWrapper, IBAPIClient):  
  3.     """  
  4.     The IB API application class creates the instances  
  5.     of IBAPIWrapper and IBAPIClient, through a multiple  
  6.     inheritance mechanism.  
  7.     When the class is initialised it connects to the IB  
  8.     server. At this stage multiple threads of execution  
  9.     are generated for the client and wrapper.  
  10.     Parameters  
  11.     ----------  
  12.     ipaddress : `str`  
  13.         The IP address of the TWS client/IB Gateway  
  14.     portid : `int`  
  15.         The port to connect to TWS/IB Gateway with  
  16.     clientid : `int`  
  17.         An (arbitrary) client ID, that must be a positive integer  
  18.     """  
  19.     def __init__(self, ipaddress, portid, clientid):  
  20.         IBAPIWrapper.__init__(self)  
  21.         IBAPIClient.__init__(self, wrapper=self 
  22.         # Connects to the IB server with the  
  23.         # appropriate connection parameters  
  24.         self.connect(ipaddress, portid, clientid)  
  25.         # Initialise the threads for various components  
  26.         thread = threading.Thread(target=self.run)  
  27.         thread.start()  
  28.         setattr(self, "_thread", thread)  
  29.         # Listen for the IB responses  
  30.         self.init_error() 

現(xiàn)在定義了前三個類,我們就可以創(chuàng)建腳本入口點(diǎn)了。

執(zhí)行代碼

我們首先設(shè)置連接參數(shù),包括主機(jī) IP 地址、連接到 TWS/IB 網(wǎng)關(guān)的端口和(任意)正整數(shù)客戶端 ID。

然后我們使用適當(dāng)?shù)倪B接參數(shù)實(shí)例化一個應(yīng)用程序?qū)嵗?/p>

我們使用該應(yīng)用程序從 IB 獲取服務(wù)器時間,然后使用 datetime 庫的 utcfromtimestamp 方法將 Unix 時間戳適當(dāng)?shù)馗袷交癁楦呖勺x性的日期格式。

最后我們斷開與IB服務(wù)器的連接并結(jié)束程序。 

  1. # ib_api_connection.py  
  2. if __name__ == '__main__':  
  3.     # Application parameters  
  4.     host = '127.0.0.1'  # Localhost, but change if TWS is running elsewhere  
  5.     port = 7497  # Change to the appropriate IB TWS account port number  
  6.     client_id = 1234  
  7.     print("Launching IB API application...")  
  8.     # Instantiate the IB API application  
  9.     app = IBAPIApp(host, port, client_id)  
  10.     print("Successfully launched IB API application...")  
  11.     # Obtain the server time via the IB API app  
  12.     server_time = app.obtain_server_time()  
  13.     server_time_readable = datetime.datetime.utcfromtimestamp(  
  14.         server_time  
  15.     ).strftime('%Y-%m-%d %H:%M:%S')  
  16.     print("Current IB server time: %s" % server_time_readable)  
  17.     # Disconnect from the IB server  
  18.     app.disconnect()  
  19.     print("Disconnected from the IB API application. Finished.") 

在這個階段,我們準(zhǔn)備運(yùn)行 ib_api_connection.py。只需導(dǎo)航到您存儲文件的目錄,確保帶有 ibapi的虛擬環(huán)境處于活動狀態(tài),并且 TWS(或 IB 網(wǎng)關(guān))已正確加載和配置,然后鍵入以下內(nèi)容:

  1. python ib_api_connection.py 

您應(yīng)該會看到類似于以下內(nèi)容的輸出: 

  1. Launching IB API application...  
  2. Successfully launched IB API application...  
  3. IB Error ID (-1), Error Code (2104) with response 'Market data farm connection is OK:usfarm'  
  4. IB Error ID (-1), Error Code (2106) with response 'HMDS data farm connection is OK:ushmds'  
  5. IB Error ID (-1), Error Code (2158) with response 'Sec-def data farm connection is OK:secdefnj'  
  6. Current IB server time: 2020-07-29 13:27:18  
  7. Disconnected from the IB API application. Finished.  
  8. unhandled exception in EReader thread  
  9. Traceback (most recent call last):  
  10.   File "/home/mhallsmoore/venv/qstrader/lib/python3.6/site-packages/ibapi/reader.py", line 34, in run  
  11.     data = self.conn.recvMsg() 
  12.    File "/home/mhallsmoore/venv/qstrader/lib/python3.6/site-packages/ibapi/connection.py", line 99, in recvMsg  
  13.     buf = self._recvAllMsg()  
  14.   File "/home/mhallsmoore/venv/qstrader/lib/python3.6/site-packages/ibapi/connection.py", line 119, in _recvAllMsg  
  15.     buf = self.socket.recv(4096)  
  16. OSError: [Errno 9] Bad file descriptor 

第一組輸出是帶有代碼 2104、2106 和 2158 的 IB 'errors'。這些實(shí)際上是說明與各種服務(wù)器的連接正常運(yùn)行的響應(yīng)。也就是說,它們不是'errors'!

服務(wù)器時間也從 Unix 時間戳正確轉(zhuǎn)換為更易讀的格式和輸出。在此階段,應(yīng)用程序斷開連接。

但是請注意,在 EReader 線程中引發(fā)了 OSError 異常。這是 IB API 本身的一個內(nèi)部問題,目前還沒有一個修復(fù)程序。出于本教程的目的,它可以被忽略。

現(xiàn)在完成了連接到 IB Python Native API 的教程。 ib_api_connection.py 的完整代碼請掃描下方二維碼獲取。

我們已經(jīng)成功連接到IB服務(wù)器,并通過調(diào)用檢查連接,獲取當(dāng)前服務(wù)器時間。后面我們將確定如何從 IB API 檢索股票的市場數(shù)據(jù)。 

責(zé)任編輯:龐桂玉 來源: Python中文社區(qū)
相關(guān)推薦

2023-04-17 16:21:20

JavaScriot前端開發(fā)

2024-05-09 09:41:45

2009-09-24 13:12:20

Hibernate原生

2021-04-14 08:51:55

HDFSJavaPython

2024-05-29 09:34:02

GPTs原生API

2022-08-21 07:25:09

Flink云原生K8S

2022-02-17 14:34:10

viewport項(xiàng)目API

2016-05-12 13:48:05

DockerAPI

2017-11-03 12:25:00

2023-11-08 00:23:08

網(wǎng)關(guān)API

2023-06-02 09:16:11

云原生網(wǎng)絡(luò)區(qū)域

2022-07-07 10:41:53

鯤鵬

2021-10-11 10:00:38

惡意軟件SolarWinds網(wǎng)絡(luò)攻擊

2010-03-31 13:41:46

證券市場Linux

2023-10-30 07:36:41

Envoy靜態(tài)配置

2017-12-12 13:44:17

Android谷歌Android Go

2023-06-29 08:38:37

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 国产精品美女视频 | 精品伊人 | 日本 欧美 国产 | 欧美电影在线 | 粉嫩一区二区三区四区公司1 | 亚洲高清视频一区二区 | 国产免费又黄又爽又刺激蜜月al | 成人精品国产免费网站 | 男女啪啪网址 | 成人日批视频 | 中文字幕亚洲精品 | 97色在线观看免费视频 | 精品久久久久久亚洲精品 | 国产亚洲精品a | 成人三级视频在线观看 | 国产精品免费观看 | 久久高清国产 | 精品欧美一区免费观看α√ | 二区av| 在线播放国产一区二区三区 | 天天av网 | 久操av在线| 成人免费一区二区 | 欧美日韩电影一区 | 日本一二区视频 | 亚洲视频免费播放 | 成人精品视频99在线观看免费 | 99这里只有精品 | 综合在线视频 | 羞羞视频网站 | 一区二区精品 | 国产高清在线精品 | 日本超碰| 欧美 日韩 国产 成人 在线 91 | 91精品国产综合久久久动漫日韩 | 日本成人在线免费视频 | 婷婷午夜天 | 久久精品亚洲精品国产欧美 | 成人深夜小视频 | 在线观看成人 | 产真a观专区 |