Как извлечь исторические данные по опционам Deribit (Implied Volatility) с Python requests

Как извлечь исторические данные по опционам Deribit (Implied Volatility) с Python requests Python & API
Подробное техническое руководство для Senior Quant Developer по извлечению исторических данных подразумеваемой волатильности (Implied Volatility) опционов Deribit с помощью Python и библиотеки requests. Включает примеры кода и разбор API.
Суть: Для извлечения исторических данных подразумеваемой волатильности (IV) опционов Deribit необходимо использовать публичный API Deribit, в частности методы public/get_instruments для получения списка инструментов и public/get_book_summary_by_instrument для получения текущей IV (mark_iv). Для создания исторического ряда данных этот процесс следует автоматизировать и выполнять с заданной периодичностью, сохраняя результаты в базе данных или файлах.

Исходный код

Представленный ниже Python-скрипт демонстрирует, как подключиться к публичному API Deribit, получить список всех активных BTC-опционов, а затем для каждого опциона извлечь его текущую подразумеваемую волатильность (mark_iv). Этот подход является основой для сбора исторических данных: для получения исторического ряда вам потребуется запускать этот скрипт регулярно и сохранять полученные данные.


import requests
import json
import time
import pandas as pd
from datetime import datetime

class DeribitIVExtractor:
    BASE_URL = 'https://www.deribit.com/api/v2/public/'

    def __init__(self, currency='BTC', kind='option'):
        self.currency = currency
        self.kind = kind
        self.session = requests.Session()

    def _make_request(self, method, params=None):
        url = f'{self.BASE_URL}{method}'
        try:
            response = self.session.get(url, params=params)
            response.raise_for_status() # Raise an HTTPError for bad responses (4xx or 5xx)
            return response.json()
        except requests.exceptions.HTTPError as http_err:
            print(f"HTTP error occurred: {http_err} - Response: {response.text}")
        except requests.exceptions.ConnectionError as conn_err:
            print(f"Connection error occurred: {conn_err}")
        except requests.exceptions.Timeout as timeout_err:
            print(f"Timeout error occurred: {timeout_err}")
        except requests.exceptions.RequestException as req_err:
            print(f"An unexpected error occurred: {req_err}")
        return None

    def get_instruments(self):
        params = {
            'currency': self.currency,
            'kind': self.kind,
            'expired': False # Only active instruments
        }
        result = self._make_request('get_instruments', params)
        if result and result['result']:
            return [instr['instrument_name'] for instr in result['result']]
        return []

    def get_book_summary(self, instrument_name):
        params = {
            'instrument_name': instrument_name
        }
        result = self._make_request('get_book_summary_by_instrument', params)
        if result and result['result']:
            # The result is a list, we take the first (and usually only) element
            return result['result'][0]
        return None

    def fetch_current_iv_data(self):
        print(f"Fetching instruments for {self.currency} {self.kind}...")
        instrument_names = self.get_instruments()
        if not instrument_names:
            print("No instruments found.")
            return pd.DataFrame()

        iv_data = []
        timestamp = datetime.utcnow().isoformat()
        print(f"Found {len(instrument_names)} instruments. Fetching book summaries...")

        for i, instrument_name in enumerate(instrument_names):
            summary = self.get_book_summary(instrument_name)
            if summary and 'mark_iv' in summary:
                iv_data.append({
                    'timestamp': timestamp,
                    'instrument_name': instrument_name,
                    'mark_iv': summary['mark_iv'],
                    'bid_iv': summary.get('bid_iv'),
                    'ask_iv': summary.get('ask_iv'),
                    'last_price': summary.get('last_price'),
                    'underlying_price': summary.get('underlying_price')
                })
            # Optional: Add a small delay to avoid hitting rate limits
            # time.sleep(0.05)
            if (i + 1) % 100 == 0:
                print(f"Processed {i + 1}/{len(instrument_names)} instruments.")

        df = pd.DataFrame(iv_data)
        print("Data fetching complete.")
        return df

# --- Пример использования ---
if __name__ == '__main__':
    extractor = DeribitIVExtractor(currency='BTC', kind='option')
    current_iv_df = extractor.fetch_current_iv_data()

    if not current_iv_df.empty:
        print("\n--- Извлеченные данные IV (первые 5 строк) ---")
        print(current_iv_df.head())

        # Сохранение данных в CSV файл
        filename = f'deribit_{extractor.currency}_{extractor.kind}_iv_data_{datetime.now().strftime("%Y%m%d_%H%M%S")}.csv'
        current_iv_df.to_csv(filename, index=False)
        print(f"\nДанные сохранены в файл: {filename}")

        # Для сбора исторических данных, этот скрипт должен запускаться периодически.
        # Например, каждые 5 минут, и данные должны добавляться в одну и ту же базу данных/файл.
        print("\nДля сбора исторических данных, автоматизируйте запуск этого скрипта и сохранение результатов.")
        print("Рассмотрите использование планировщиков задач (cron на Linux, Task Scheduler на Windows) или Airflow.")

    else:
        print("Не удалось получить данные IV.")

Разбор параметров

  • BASE_URL: Базовый URL для публичного API Deribit. Все запросы будут отправляться к этому адресу с добавлением имени метода.
  • currency: Валюта, для которой запрашиваются опционы. Примеры: 'BTC', 'ETH'.
  • kind: Тип инструмента. Для опционов используется 'option'. Для фьючерсов — 'future'.
  • expired: Булево значение, указывающее, включать ли в результат истекшие инструменты. False (по умолчанию) означает только активные инструменты.
  • instrument_name: Полное название инструмента, например, 'BTC-29SEP23-30000-C'. Используется для запроса сводки по конкретному инструменту.
  • method: Имя метода API Deribit, который вызывается, например, 'get_instruments' или 'get_book_summary_by_instrument'.
  • params: Словарь с параметрами, передаваемыми в запрос API.

Как запустить

Для успешного запуска скрипта и извлечения данных по опционам Deribit, выполните следующие шаги:

  1. Установите Python: Убедитесь, что у вас установлен Python 3.x. Вы можете скачать его с официального сайта python.org.

  2. Установите необходимые библиотеки: Откройте терминал или командную строку и выполните следующую команду для установки библиотек requests и pandas:

    
    pip install requests pandas
    
  3. Сохраните код: Скопируйте предоставленный выше Python-код и сохраните его в файл с расширением .py, например, deribit_iv_extractor.py.

  4. Запустите скрипт: Откройте терминал или командную строку, перейдите в директорию, где вы сохранили файл, и выполните команду:

    
    python deribit_iv_extractor.py
    
  5. Проверьте результаты: Скрипт выведет первые строки извлеченных данных в консоль и сохранит полный набор данных в CSV-файл в той же директории, что и скрипт. Имя файла будет содержать текущую дату и время.

  6. Автоматизация для исторических данных: Для сбора полноценного исторического ряда данных вам потребуется автоматизировать запуск этого скрипта. Вы можете использовать планировщики задач, такие как cron в Linux/macOS или Task Scheduler в Windows, чтобы запускать скрипт через определенные интервалы (например, каждые 5-15 минут). Полученные данные следует сохранять в единое хранилище (например, базу данных PostgreSQL, MongoDB или добавлять в один и тот же CSV-файл), чтобы сформировать непрерывный исторический ряд. Это позволит вам отслеживать изменения подразумеваемой волатильности с течением времени, что критически важно для количественного анализа и торговых стратегий. Подобные подходы к работе с API и автоматизации могут быть применены и в других контекстах, например, при мониторинге Flash Loan атак в Ethereum на Web3.py и Alchemy API или при автоматическом переводе между суб-аккаунтами Binance на Python. Для более сложных систем сбора и обработки данных можно рассмотреть использование фреймворков, таких как Apache Airflow, что также может быть полезно при реализации высокочастотных стратегий, например, Token Sniping на PancakeSwap через Mempool с Python.

Оцените статью
FinFluct