Last active
May 13, 2023 22:12
-
-
Save sammchardy/0c740c40276e8f05b6390ce304476605 to your computer and use it in GitHub Desktop.
Get historical Klines from Binance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# uses the date_to_milliseconds and interval_to_milliseconds functions | |
# https://gist.github.com/sammchardy/3547cfab1faf78e385b3fcb83ad86395 | |
# https://gist.github.com/sammchardy/fcbb2b836d1f694f39bddd569d1c16fe | |
from binance.client import Client | |
import time | |
def get_historical_klines(symbol, interval, start_str, end_str=None): | |
"""Get Historical Klines from Binance | |
See dateparse docs for valid start and end string formats http://dateparser.readthedocs.io/en/latest/ | |
If using offset strings for dates add "UTC" to date string e.g. "now UTC", "11 hours ago UTC" | |
:param symbol: Name of symbol pair e.g BNBBTC | |
:type symbol: str | |
:param interval: Biannce Kline interval | |
:type interval: str | |
:param start_str: Start date string in UTC format | |
:type start_str: str | |
:param end_str: optional - end date string in UTC format | |
:type end_str: str | |
:return: list of OHLCV values | |
""" | |
# create the Binance client, no need for api key | |
client = Client("", "") | |
# init our list | |
output_data = [] | |
# setup the max limit | |
limit = 500 | |
# convert interval to useful value in seconds | |
timeframe = interval_to_milliseconds(interval) | |
# convert our date strings to milliseconds | |
start_ts = date_to_milliseconds(start_str) | |
# if an end time was passed convert it | |
end_ts = None | |
if end_str: | |
end_ts = date_to_milliseconds(end_str) | |
idx = 0 | |
# it can be difficult to know when a symbol was listed on Binance so allow start time to be before list date | |
symbol_existed = False | |
while True: | |
# fetch the klines from start_ts up to max 500 entries or the end_ts if set | |
temp_data = client.get_klines( | |
symbol=symbol, | |
interval=interval, | |
limit=limit, | |
startTime=start_ts, | |
endTime=end_ts | |
) | |
# handle the case where our start date is before the symbol pair listed on Binance | |
if not symbol_existed and len(temp_data): | |
symbol_existed = True | |
if symbol_existed: | |
# append this loops data to our output data | |
output_data += temp_data | |
# update our start timestamp using the last value in the array and add the interval timeframe | |
start_ts = temp_data[len(temp_data) - 1][0] + timeframe | |
else: | |
# it wasn't listed yet, increment our start date | |
start_ts += timeframe | |
idx += 1 | |
# check if we received less than the required limit and exit the loop | |
if len(temp_data) < limit: | |
# exit the while loop | |
break | |
# sleep after every 3rd call to be kind to the API | |
if idx % 3 == 0: | |
time.sleep(1) | |
return output_data |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
line #60
handle the case where our start date is before the symbol pair listed on Binance
It seems that if we try to set start_ts earlier than the date when the pair was listed, Binance API would return data starting from the listing date.
In case start_ts is later than the latest data available, this line (#61) will not trigger:
if not symbol_existed and len(temp_data):
and it seems we will end up in an infinite loop.
Please correct me if I am wrong.