iT邦幫忙

2024 iThome 鐵人賽

DAY 12
0
AI/ ML & Data

自動交易程式探索系列 第 12

Day 12 - 使用 Polygon.io 抓大量日內數據 (1/3)

  • 分享至 

  • xImage
  •  

在進行量化交易學習時,特別是使用 FinRL,發現大多數範例主要基於日線級別數據。然而,接下來我希望開始嘗試使用更小時間級別的數據訓練DRL,畢竟日線的數據量實在是非常少,而且只是要交易日線的話,看起來買大盤指數ETF就綽綽有餘,或者是用類似MVO的方法優化投資配置分散風險後直接報長線,其實更簡單,獲利應該也低不到哪裡去。

因此在接下來的學習過程中,我想嘗試使用更大量的數據跟更小的時間級別;在這樣的需求底下只使用免費的API無法滿足我的需求;因此我打算先找到合適的數據源,並嘗試抓取更大量的資料。

我打算嘗試使用Polygon.io抓取S&P500+DOW30的成分股過去五年的1小時級別的資料,並在此過程中完善抓資料的程式碼,先拿這些數據玩玩看,如果有戲,再嘗試更久遠以及更小的時間級別數據。

為什麼選擇 Polygon.io?

Yahoo Finance 雖然提供免費的歷史數據,但在分鐘級別等短時間框架的數據上存在明顯的限制——只能獲取最近 60 天 的數據。這對於需要大量歷史數據進行回測和模型訓練的策略來說,顯然不夠用。

相比之下,Polygon.io 提供了更靈活的時間框架選擇,包括每小時、每分鐘甚至秒級別的數據。此外,Polygon.io 還能提供更長時間範圍的歷史數據,這對於高頻交易和需要大量數據來訓練模型的策略非常關鍵。

直接使用 requests 抓取數據

Polygon.io 使用起來很方便,用requests就能很輕鬆的抓取想要的資料。

import requests
import pandas as pd
from datetime import datetime, timedelta

# 股票代碼
symbol = 'AAPL'

# 設定日期範圍:60天內
end_date = datetime.now()
start_date = end_date - timedelta(days=30)

# 格式化日期
start_date_str = start_date.strftime('%Y-%m-%d')
end_date_str = end_date.strftime('%Y-%m-%d')

# 請求URL,範例中的時間間隔為1小時,並取過去60天的數據
url = f'https://api.polygon.io/v2/aggs/ticker/{symbol}/range/1/hour/{start_date_str}/{end_date_str}?apiKey={API_KEY}'

# 發送請求
response = requests.get(url)
data = response.json()

# 檢查請求是否成功
if response.status_code == 200:
    results = data.get('results', [])
    if results:
        # 將結果轉換為Pandas DataFrame
        df = pd.DataFrame(results)
        
        # 轉換時間戳為可讀格式
        df['timestamp'] = pd.to_datetime(df['t'], unit='ms')
        
        # 選擇並重命名需要的欄位
        df = df[['timestamp', 'o', 'h', 'l', 'c', 'v']].rename(columns={
            'o': 'Open',
            'h': 'High',
            'l': 'Low',
            'c': 'Close',
            'v': 'Volume'
        })
        
        # 顯示數據
        print(df.head())
        
        # 如果需要,可以將數據保存到CSV文件
        df.to_csv(f'{symbol}_1hr_30days.csv', index=False)
        print(f"數據已保存到 {symbol}_1hr_30days.csv")
    else:
        print("無法取得數據,可能時間範圍內沒有可用數據。")
else:
    print(f"請求失敗,狀態碼:{response.status_code}, 原因:{data}")

使用 Polygon.io 的 Python API 抓取大量數據

但直接使用requests需要額外花費很多精力處理一些細節,尤其是處理大量數據時,還需要考慮到分頁抓取的問題很麻煩。
由於 Polygon.io 都提供 python 的 API,因此我是直接使用 Python API 來開發抓數據的程式。
要使用 Polygon.io 的 API,首先需要安裝官方提供的 Python 客戶端:

pip install polygon-api-client

免費與付費機制

股票的價格表如下
https://ithelp.ithome.com.tw/upload/images/20240926/20161802U1QkCK4lJt.jpg
Polygon.io 提供不同的訂閱方案以滿足不同用戶的需求。目前,免費帳號有以下限制:

  • 每分鐘最多 5 次 API 請求:在大量抓取數據時,需要合理劃分請求頻率,避免超過速率限制。
  • 數據範圍限制:免費帳號只能存取2年內數據;並且無法訪問高頻數據。

如果需求更大,如抓取 S&P500 成分股及 DOW30 成分股過去 5 年的 1 小時級別數據,則需要考慮升級到付費方案,例如 Starter 等級帳號,以獲得更高的 API 調用限額和更全面的數據訪問權限。

外匯及加密貨幣

Polygon.io對於不同類別的資產標的的收費是分開的,所以在付費時要注意,先搞清楚自己要抓的資料到底屬於哪個類別。
其實看完收費以後,有點想改做加密貨幣了,價格差好多。
https://ithelp.ithome.com.tw/upload/images/20240927/20161802rfUslJyxG3.jpg

如何抓取大量數據

在使用 Polygon.io 免費帳號時,處理大量數據請求時需注意速率限制。以下是一個抓取大量數據的範例程式碼,利用 list_aggs 方法自動處理分頁問題,確保完整抓取所需數據:

from polygon import RESTClient
import pandas as pd

def fetch_large_data(ticker, start_date_str, end_date_str, timespan='minute', multiplier=1):
    client = RESTClient()  # 自動使用環境變數中的 API 金鑰
    aggs = []

    # 使用 list_aggs 來自動處理分頁
    for a in client.list_aggs(ticker=ticker, multiplier=multiplier, timespan=timespan, from_=start_date_str, to=end_date_str, limit=5000):
        aggs.append(a)

    # 將數據轉換為 Pandas DataFrame
    df = pd.DataFrame([agg.__dict__ for agg in aggs])

    return df

程式碼說明:

  • list_aggs 方法:支援自動分頁,無需手動切割日期範圍。
  • 速率限制考量:免費帳號每分鐘最多 5 次 API 調用,因此在大量抓取數據時,需要在請求之間設置適當的間隔時間,以避免超過限額。

遇到的常見問題及解決方案

  1. 資料回傳不完整

    • 問題:使用 get_aggs 方法請求大量數據時,若請求範圍過大,API 可能只返回部分數據而不報錯。
    • 解決方案:使用 list_aggs 方法進行分頁抓取,確保完整抓取所需數據。
  2. 免費帳號的速率限制

    • 問題:免費帳號每分鐘最多 5 次 API 調用,頻繁請求可能觸發速率限制。
    • 解決方案:合理劃分請求頻率和數據量,必要時考慮升級到付費方案以獲得更高的調用限額。

總結

Polygon.io 提供靈活且豐富的數據抓取功能,特別適合短線或高頻交易策略。通過合理使用 list_aggs 方法,可以有效解決大量數據抓取的問題。同時,需注意免費帳號的速率限制,根據需求選擇合適的訂閱方案,以確保數據抓取的穩定性和完整性。

接下來會把Polygon.io的python api,並參考FinRL跟YahooFinance的api,方便之後使用付費帳號抓取大量的日內數據。


上一篇
Day 11 - 複習Pandas與Datetime
下一篇
Day 13 - 使用 Polygon.io 抓大量日內數據 (2/3)
系列文
自動交易程式探索30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言