CoderCastrov logo
CoderCastrov
Анализ данных

Парсинг данных о ценах на криптовалюту с интервалом в 1 минуту (Python)

Парсинг данных о ценах на криптовалюту с интервалом в 1 минуту (Python)
просмотров
5 мин чтение
#Анализ данных

Пошаговое руководство по парсингу цен на различные криптовалюты с CoinDesk.


Цель

Эта статья направлена на то, чтобы показать, как использовать Python для парсинга данных о ценах на криптовалюту с интервалом в 1 минуту с помощью CoinDesk. Обычно вы можете получить только данные на основе часа или дня, и это нормально, если вы работаете над стратегией долгосрочных инвестиций. Однако, своевременные и короткие интервалы данных могут быть большой пользой, если вы занимаетесь ежедневной торговлей, так как вы сможете лучше анализировать предстоящую тенденцию и распознавать паттерны. Поэтому в следующем примере я покажу вам, как получить данные о ценах с интервалом в 1 минуту с известной платформы информации о криптовалюте - CoinDesk.


Список криптовалют

Для парсинга цен на криптовалюту требуется список криптовалют. На самом деле, на август 2021 года существует почти 6000 криптовалют, и не все из них подходят для торговли с точки зрения рыночной капитализации и ликвидности. "The CoinDesk 20" будет хорошей отправной точкой. Он фильтрует из большой вселенной тысяч криптовалют и цифровых активов, чтобы определить основную группу из 20. В следующем абзаце я буду парсить цены "The CoinDesk 20" в качестве демонстрации, и предстоящий учебник будет основан на этом наборе активов. (Обратите внимание, что 'MATIC' не включен, так как CoinDesk предоставляет данные о цене 'MATIC' только с июля 2021 года, и это недостаточно для анализа.) Также, если вас интересует, какие еще криптовалюты поддерживает CoinDesk, вы можете обратиться к его веб-сайту.

Пример других криптовалют, поддерживаемых CoinDesk
# The CoinDesk 20
coindesk20_list = ['BTC', 'ETH', 'XRP', 'ADA', 'USDT', 'DOGE', 'XLM', 'DOT', 'UNI', 'LINK', 'USDC', 'BCH', 'LTC', 'GRT', 'ETC', 'FIL', 'AAVE', 'ALGO', 'EOS']

CoinDesk API

Прежде чем мы начнем парсить цены, нам сначала нужно понять API CoinDesk, самый простой способ - это посмотреть график цен.

Left: 12h (1-minute) Right: 1w (1-hour)

Из графиков мы легко можем заметить, что данные представлены в интервале 1 минуты для графика '12h', в то время как данные представлены в интервале 1 часа для графика '1w'. Фактически, я суммировал это в таблице ниже.

Table

Поскольку меня интересуют данные о ценах за 1 минуту, я хотел бы использовать '12h' как основу. Для примера возьмем биткоин, ниже приведена структура API для CoinDesk.

https://production.api.coindesk.com/v2/price/values/**_BTC_**?start_date=**_2021-08-20T15:42_**&end_date=**_2021-08-21T03:42_**&ohlc=**_true_**

Я выделил параметры жирным и курсивом для вашего удобства. В основном, можно установить 4 параметра.

Обратите внимание, что (1) время указано в формате UTC+0, (2) разница между начальным и конечным временем не должна превышать 12 часов, если вас интересуют данные с интервалом в минуту, и (3) если ohlc установлено в false, будет возвращена только цена закрытия.

Парсинг данных

После получения списка криптовалют и полного понимания структуры API, мы можем начать парсить цены.

# Импорт библиотек
import requests
import numpy as np
import pandas as pd
from datetime import datetime
from dateutil.relativedelta import relativedelta# The CoinDesk 20
coindesk20_list = ['BTC', 'ETH', 'XRP', 'ADA', 'USDT', 'DOGE', 'XLM', 'DOT', 'UNI', 'LINK', 'USDC', 'BCH', 'LTC', 'GRT', 'ETC', 'FIL', 'AAVE', 'ALGO', 'EOS']raw_df = pd.DataFrame()
for coin in coindesk20_list:
    coin_df = pd.DataFrame()
    df = pd.DataFrame(index=[0])
    
    # Определение начальной и конечной даты
    end_datetime = datetime(2021, 8, 1, 0, 0)
    datetime_checkpt = datetime(2021, 7, 1, 0, 0)
    
    while len(df) > 0:
        if end_datetime == datetime_checkpt:
            break
        start_datetime = end_datetime - relativedelta(hours = 12)
        url = '[https://production.api.coindesk.com/v2/price/values/'](https://production.api.coindesk.com/v2/price/values/') + coin + '?start_date=' + start_datetime.strftime("%Y-%m-%dT%H:%M") + '&end_date=' + end_datetime.strftime("%Y-%m-%dT%H:%M") + '&ohlc=true'
        temp_data_json = requests.get(url)
        temp_data = temp_data_json.json()
        df = pd.DataFrame(temp_data['data']['entries'])
        df.columns = ['Timestamp', 'Open', 'High', 'Low', 'Close']
        
        # Обработка отсутствующих данных
        insert_idx_list = [np.nan]
        while len(insert_idx_list) > 0:
            timestamp_checking_array = np.array(df['Timestamp'][1:]) - np.array(df['Timestamp'][:-1])
            insert_idx_list = np.where(timestamp_checking_array != 60000)[0]
            if len(insert_idx_list) > 0:
                print('В данных есть ' + str(len(insert_idx_list)) + ' несоответствующих меток времени.')
                insert_idx = insert_idx_list[0]
                temp_df = df.iloc[insert_idx.repeat(int(timestamp_checking_array[insert_idx]/60000)-1)].reset_index(drop=True)
                temp_df['Timestamp'] = [temp_df['Timestamp'][0] + i*60000 for i in range(1, len(temp_df)+1)]
                df = df.loc[:insert_idx].append(temp_df).append(df.loc[insert_idx+1:]).reset_index(drop=True)
                insert_idx_list = insert_idx_list[1:]
        
        df = df.drop(['Timestamp'], axis=1)
        df['Datetime'] = [end_datetime - relativedelta(minutes=len(df)-i) for i in range(0, len(df))]
        coin_df = df.append(coin_df)
        end_datetime = start_datetime
    coin_df['Symbol'] = coin
    raw_df = raw_df.append(coin_df)
raw_df = raw_df[['Datetime', 'Symbol', 'Open', 'High', 'Low', 'Close']].reset_index(drop=True)
raw_df.to_csv('raw_df.csv', index=False)

Простыми словами, код можно разделить на 4 части.

  1. Получение JSON данных из API
temp_data_json = requests.get(url)
temp_data = temp_data_json.json()
df = pd.DataFrame(temp_data['data']['entries'])
df.columns = ['Timestamp', 'Open', 'High', 'Low', 'Close']

Используя пакет requests, мы легко можем получить JSON данные из API, а затем сохранить их в pandas data frame и изменить названия столбцов.

  1. Обработка отсутствующих данных
insert_idx_list = [np.nan]
        while len(insert_idx_list) > 0:
            timestamp_checking_array = np.array(df['Timestamp'][1:]) - np.array(df['Timestamp'][:-1])
            insert_idx_list = np.where(timestamp_checking_array != 60000)[0]
            if len(insert_idx_list) > 0:
                print('В данных есть ' + str(len(insert_idx_list)) + ' несоответствующих меток времени.')
                insert_idx = insert_idx_list[0]
                temp_df = df.iloc[insert_idx.repeat(int(timestamp_checking_array[insert_idx]/60000)-1)].reset_index(drop=True)
                temp_df['Timestamp'] = [temp_df['Timestamp'][0] + i*60000 for i in range(1, len(temp_df)+1)]
                df = df.loc[:insert_idx].append(temp_df).append(df.loc[insert_idx+1:]).reset_index(drop=True)
                insert_idx_list = insert_idx_list[1:]

Эта часть будет самой сложной. Это связано с тем, что я обнаружил, что CoinDesk не захватывает каждую минуту данных. Исходя из наблюдений, в обычной ситуации разница во времени между метками времени составляет 60000 для 1 минуты. Поэтому, как только я замечаю, что разница в строках для меток времени больше 60000, я могу сразу сказать, что это пропущенный период времени. Для обработки используется методика импутации hot-deck. Другими словами, ближайшие данные за минуту будут использоваться для замены отсутствующих данных.

  1. Добавление столбцов Datetime и Symbol в coin_df
df = df.drop(['Timestamp'], axis=1)
        df['Datetime'] = [end_datetime - relativedelta(minutes=len(df)-i) for i in range(0, len(df))]

Поскольку столбец Timestamp определен CoinDesk и не может быть легко интерпретирован, вместо написания функции преобразования времени, я просто вычисляю столбец Datetime, чтобы указать дату и время для цены криптовалюты.

coin_df['Symbol'] = coin

Также, символ криптовалюты добавляется в coin_df.

  1. Объединение coin_df в raw_df
raw_df = raw_df.append(coin_df)

Наконец, объединяется консолидированный набор данных под названием raw_df.

Raw Dataframe (raw_df.csv)

Cryptocurrency Dataframe

Наконец, мы можем преобразовать данные в криптовалютный dataframe.

cryptocurrency_df = pd.DataFrame(raw_df['Close'].values.reshape(len(coindesk20_list), -1).transpose(), index=raw_df['Datetime'][:int(len(raw_df) / len(coindesk20_list))], columns=coindesk20_list)
cryptocurrency_df.to_csv('cryptocurrency_df.csv')
Cryptocurrency Dataframe (cryptocurrency_df.csv)

Это завершает учебник. Теперь вы можете перейти к следующей части, чтобы узнать, как анализировать риск и доходность криптовалют. =)