C:\Users\m\bybit>python api.py
Traceback (most recent call last):
  File "C:\Python312\Lib\site-packages\requests\models.py", line 974, in json
    return complexjson.loads(self.text, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\json\__init__.py", line 346, in loads
    return _default_decoder.decode(s)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\json\decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\json\decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\m\bybit\api.py", line 43, in <module>
    kline_data = fetch_kline_data(symbol, interval, current_time)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\m\bybit\api.py", line 15, in fetch_kline_data
    data = response.json()
           ^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\requests\models.py", line 978, in json
    raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

C:\Users\m\bybit>python api.py
Ошибка запроса: 429 Client Error: Too Many Requests for url: https://api.bybit.com/v2/public/kline/list?symbol=NEARUSDT&interval=1&from=1672520400
Данные за год успешно сохранены в bybit_data_year.csv

C:\Users\m\bybit>python api.py
Превышен лимит запросов. Ожидание перед повторной попыткой...





import requests
import csv
import time

# Функция для получения данных свечей
def fetch_kline_data(symbol, interval, start_time):
    url = "https://api.bybit.com/v2/public/kline/list"
    params = {
        "symbol": symbol,
        "interval": interval,
        "from": start_time
    }
    
    try:
        response = requests.get(url, params=params)
        response.raise_for_status()  # Проверка на ошибки HTTP
        
        if response.status_code == 200:
            try:
                data = response.json()
                if data["ret_code"] == 0:
                    return data["result"]
                else:
                    print("Ошибка API:", data["ret_msg"])
                    return []
            except requests.exceptions.JSONDecodeError:
                print("Ошибка при декодировании JSON. Ответ сервера: ", response.text)
                return []
        else:
            print(f"Ошибка HTTP {response.status_code}")
            return []
    
    except requests.exceptions.HTTPError as e:
        if e.response.status_code == 429:
            print("Превышен лимит запросов. Ожидание перед повторной попыткой...")
            time.sleep(60)  # Задержка 60 секунд
            return fetch_kline_data(symbol, interval, start_time)
        else:
            print("Ошибка запроса:", e)
            return []

# Конвертация даты в UNIX timestamp
def to_unix_timestamp(year, month, day):
    return int(time.mktime(time.strptime(f"{year}-{month}-{day}", "%Y-%m-%d")))

# Параметры
symbol = "BTCUSD"
interval = "1"  # 1 минута
start_time = to_unix_timestamp(2023, 1, 1)  # Начало сбора данных: 1 января 2023 года
end_time = to_unix_timestamp(2024, 1, 1)  # Конец сбора данных: 1 января 2024 года
max_candles_per_request = 200  # Максимум свечей на один запрос (ограничение API)

# Открываем файл для записи
with open("bybit_data_year.csv", "w", newline="") as file:
    writer = csv.writer(file)
    writer.writerow(["timestamp", "open", "high", "low", "close", "volume"])

    current_time = start_time

    while current_time < end_time:
        # Получаем данные за текущий период
        kline_data = fetch_kline_data(symbol, interval, current_time)
        
        if not kline_data:
            break
        
        # Записываем данные в файл
        for entry in kline_data:
            writer.writerow([
                time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(entry['open_time'])),
                entry['open'],
                entry['high'],
                entry['low'],
                entry['close'],
                entry['volume']
            ])
        
        # Обновляем текущее время для следующего запроса
        current_time = kline_data[-1]['open_time'] + (max_candles_per_request * 60)  # Переходим к следующему интервалу

    print("Данные за год успешно сохранены в bybit_data_year.csv")