使用Python輕松獲取Binance歷史交易
鑒于某些策略需要一定水平的技術(shù)數(shù)據(jù),而其他數(shù)據(jù)可能只需要花費一個小時的時間,該過程并不總是那么簡單,而基礎(chǔ)架構(gòu),可用性和連接性等元素可能會因數(shù)據(jù)類型的不同而大相徑庭。
但是為什么本文僅涉及獲取“交易”數(shù)據(jù),為什么我們使用Binance API?你可能對我的文章內(nèi)容有些疑問。
數(shù)據(jù)頻率和平衡
我想說,交易數(shù)據(jù)端點主要在99.99%的交易所中提供。它是細粒度的,提供了足夠的詳細信息(在某些非常特殊的情況下)用于回測高頻交易(HFT)策略,并且可以用作 OHLC candles(1S至24H或更多,如果你想要的話)的基礎(chǔ)。
交易數(shù)據(jù)是通用的,并且允許使用不同頻率的策略進行大量實驗。
為什么選擇Binance?
那只是因為它是我由于數(shù)量龐大而傾向于回溯的交易所之一。
我們將要進行的編碼
我們將創(chuàng)建一個Python腳本,該腳本接收對符號,開始日期和結(jié)束日期作為命令行參數(shù)。它將包含所有交易的CSV文件輸出到磁盤。該過程可以通過以下步驟進行詳細說明:
1、解析symbol,starting_date和ending_date論據(jù)。
2、獲取開始日期發(fā)生的第一筆交易,以獲取第一筆交易trade_id。
3、循環(huán)獲取每個請求1000筆交易(Binance API限制),直到ending_date達到為止。
4、最后,將數(shù)據(jù)保存到磁盤。對于示例,我們將其保存為CSV,但是你還有其他選擇,不一定保存為CSV。
5、我們將使用pandas,requests,time,sys,和datetime。在代碼段中,將不會顯示錯誤驗證,因為它不會為說明添加任何值。
編碼時間
該腳本將使用以下參數(shù):
1、symbol:交易對的符號,由Binance定義。可以在此處查詢,也可以從Binance Web應(yīng)用程序的URL復(fù)制(不包括 _ 字符)。
-starting_date and ending_date:不言自明。期望的格式為mm/dd/yyyy,或者使用Python lang語為%m/%d/%Y。
為了獲取參數(shù),我們將使用內(nèi)置函數(shù)sys(這里沒有什么花哨的地方),并且為了解析日期,我們將使用datetime庫。
我們將添加一天并減去一微秒,以使ending_date時間部分始終處于23:59:59.999,這使得獲取當(dāng)天間隔更加實用。
提取交易
使用Binance的API并使用aggTrades端點,我們可以在一個請求中獲得最多1000 筆交易,如果我們使用開始和結(jié)束參數(shù),則它們之間的間隔最多為一小時。
在出現(xiàn)一些失敗之后,通過使用時間間隔獲?。ㄔ谀硞€時間點或另一個時間點,流動性會變得瘋狂,我會失去一些寶貴的交易),我決定嘗試from_id策略。
將aggTrades選擇的端點,因為它返回壓縮行業(yè)。這樣,我們將不會丟失任何寶貴的信息。
獲得壓縮的總交易。在同一時間從同一訂單以相同價格執(zhí)行的交易將匯總數(shù)量。
該from_id策略是這樣的:
我們要得到的第一筆交易starting_date 通過發(fā)送日期的時間間隔向終點。之后,我們將從第一個獲取的交易ID開始獲取1000個交易。然后,我們將檢查最后一筆交易是否發(fā)生在我們之后ending_date。
如果是這樣,我們已經(jīng)遍歷了所有時間段,可以將結(jié)果保存到文件中。否則,我們將更新from_id變量以獲取最后的交易ID,然后重新開始循環(huán)。
取得第一個交易編號
首先,我們創(chuàng)建一個new_end_date。那是因為我們aggTrades通過傳遞a startTime和endTime 參數(shù)來使用。
現(xiàn)在,我們只需要知道該期間的第一個交易編號,因此我們將增加60秒。在低流動性貨幣對中,可以更改此參數(shù),因為不能保證在請求的第一天發(fā)生交易。
然后,使用我們的輔助函數(shù)解析日期,以使用該calendar.timegm函數(shù)將日期轉(zhuǎn)換為Unix毫秒表示形式。該timegm函數(shù)是首選函數(shù),因為它將日期保留為UTC。
請求的響應(yīng)是按日期排序的貿(mào)易對象列表,格式如下:
因此,由于我們需要第一個交易ID ,因此我們將返回該response[0]["a"]值。
主循環(huán)
現(xiàn)在我們有了第一個交易ID,我們可以一次提取1000個交易,直到達到ending_date。以下代碼將在我們的主循環(huán)中調(diào)用。它將使用from_id參數(shù),放棄startDate和endDate參數(shù),執(zhí)行我們的請求。
現(xiàn)在,這是我們的主循環(huán),它將執(zhí)行請求并創(chuàng)建我們的DataFrame。
我們檢查是否current_time包含最近獲取的交易日期大于to_date,如果是,則我們:
- 使用from_id參數(shù)獲取交易
- 使用從最新交易中獲取的信息來更新from_id和current_time參數(shù)
- 打印nice調(diào)試消息
- pd.concat 這些交易與我們之前的交易 DataFrame
- 使用sleep讓Binance不會給我們一個429 HTTP響應(yīng)
清潔和保存
組裝完之后DataFrame,我們需要執(zhí)行簡單的數(shù)據(jù)清理。我們將刪除重復(fù)trim的交易和之后發(fā)生的交易to_date(我們有這個問題,因為我們要獲取1000筆交易中的大部分,因此,我們有望在目標(biāo)結(jié)束日期之后執(zhí)行一些交易)。
我們可以封裝我們的trim功能:
并執(zhí)行我們的數(shù)據(jù)清理:
現(xiàn)在,我們可以使用以下to_csv方法將其保存到文件中:
我們還可以使用其他數(shù)據(jù)存儲機制,例如Arctic。
最后:驗證你的數(shù)據(jù)
在使用交易策略時,我們必須信任我們的數(shù)據(jù),這一點很重要。通過應(yīng)用以下驗證,我們可以輕松地利用獲取的交易數(shù)據(jù)來做到這一點:
在代碼段中,我們將其轉(zhuǎn)換DataFrame為NumPy數(shù)組,并逐行迭代,檢查交易ID是否每行遞增1。
Binance交易ID是以遞增方式編號的,并且是為每個交易品種創(chuàng)建的,因此,很容易驗證數(shù)據(jù)是否正確。
PS:創(chuàng)建成功的交易策略的第一步是擁有正確的數(shù)據(jù)。