FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Add example about saving historical data related to blog post · SoniCoder/python-binance@19b9256 · GitHub

Commit 19b9256

Browse files
Sam McHardy
committed
Add example about saving historical data related to blog post
1 parent 4e426a7 commit 19b9256

1 file changed

Lines changed: 156 additions & 0 deletions

File tree

‎examples/save_historical_data.py‎

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import time
2+
import dateparser
3+
import pytz
4+
import json
5+
6+
from datetime import datetime
7+
from binance.client import Client
8+
9+
10+
def date_to_milliseconds(date_str):
11+
"""Convert UTC date to milliseconds
12+
13+
If using offset strings add "UTC" to date string e.g. "now UTC", "11 hours ago UTC"
14+
15+
See dateparse docs for formats http://dateparser.readthedocs.io/en/latest/
16+
17+
:param date_str: date in readable format, i.e. "January 01, 2018", "11 hours ago UTC", "now UTC"
18+
:type date_str: str
19+
"""
20+
# get epoch value in UTC
21+
epoch = datetime.utcfromtimestamp(0).replace(tzinfo=pytz.utc)
22+
# parse our date string
23+
d = dateparser.parse(date_str)
24+
# if the date is not timezone aware apply UTC timezone
25+
if d.tzinfo is None or d.tzinfo.utcoffset(d) is None:
26+
d = d.replace(tzinfo=pytz.utc)
27+
28+
# return the difference in time
29+
return int((d - epoch).total_seconds() * 1000.0)
30+
31+
32+
def interval_to_milliseconds(interval):
33+
"""Convert a Binance interval string to milliseconds
34+
35+
:param interval: Binance interval string 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w
36+
:type interval: str
37+
38+
:return:
39+
None if unit not one of m, h, d or w
40+
None if string not in correct format
41+
int value of interval in milliseconds
42+
"""
43+
ms = None
44+
seconds_per_unit = {
45+
"m": 60,
46+
"h": 60 * 60,
47+
"d": 24 * 60 * 60,
48+
"w": 7 * 24 * 60 * 60
49+
}
50+
51+
unit = interval[-1]
52+
if unit in seconds_per_unit:
53+
try:
54+
ms = int(interval[:-1]) * seconds_per_unit[unit] * 1000
55+
except ValueError:
56+
pass
57+
return ms
58+
59+
60+
def get_historical_klines(symbol, interval, start_str, end_str=None):
61+
"""Get Historical Klines from Binance
62+
63+
See dateparse docs for valid start and end string formats http://dateparser.readthedocs.io/en/latest/
64+
65+
If using offset strings for dates add "UTC" to date string e.g. "now UTC", "11 hours ago UTC"
66+
67+
:param symbol: Name of symbol pair e.g BNBBTC
68+
:type symbol: str
69+
:param interval: Biannce Kline interval
70+
:type interval: str
71+
:param start_str: Start date string in UTC format
72+
:type start_str: str
73+
:param end_str: optional - end date string in UTC format
74+
:type end_str: str
75+
76+
:return: list of OHLCV values
77+
78+
"""
79+
# create the Binance client, no need for api key
80+
client = Client("", "")
81+
82+
# init our list
83+
output_data = []
84+
85+
# setup the max limit
86+
limit = 500
87+
88+
# convert interval to useful value in seconds
89+
timeframe = interval_to_milliseconds(interval)
90+
91+
# convert our date strings to milliseconds
92+
start_ts = date_to_milliseconds(start_str)
93+
94+
# if an end time was passed convert it
95+
end_ts = None
96+
if end_str:
97+
end_ts = date_to_milliseconds(end_str)
98+
99+
idx = 0
100+
# it can be difficult to know when a symbol was listed on Binance so allow start time to be before list date
101+
symbol_existed = False
102+
while True:
103+
# fetch the klines from start_ts up to max 500 entries or the end_ts if set
104+
temp_data = client.get_klines(
105+
symbol=symbol,
106+
interval=interval,
107+
limit=limit,
108+
startTime=start_ts,
109+
endTime=end_ts
110+
)
111+
112+
# handle the case where our start date is before the symbol pair listed on Binance
113+
if not symbol_existed and len(temp_data):
114+
symbol_existed = True
115+
116+
if symbol_existed:
117+
# append this loops data to our output data
118+
output_data += temp_data
119+
120+
# update our start timestamp using the last value in the array and add the interval timeframe
121+
start_ts = temp_data[len(temp_data) - 1][0] + timeframe
122+
else:
123+
# it wasn't listed yet, increment our start date
124+
start_ts += timeframe
125+
126+
idx += 1
127+
# check if we received less than the required limit and exit the loop
128+
if len(temp_data) < limit:
129+
# exit the while loop
130+
break
131+
132+
# sleep after every 3rd call to be kind to the API
133+
if idx % 3 == 0:
134+
time.sleep(1)
135+
136+
return output_data
137+
138+
139+
symbol = "ETHBTC"
140+
start = "1 Dec, 2017"
141+
end = "1 Jan, 2018"
142+
interval = Client.KLINE_INTERVAL_30MINUTE
143+
144+
klines = get_historical_klines(symbol, interval, start, end)
145+
146+
# open a file with filename including symbol, interval and start and end converted to milliseconds
147+
with open(
148+
"Binance_{}_{}_{}-{}.json".format(
149+
symbol,
150+
interval,
151+
date_to_milliseconds(start),
152+
date_to_milliseconds(end)
153+
),
154+
'w' # set file write mode
155+
) as f:
156+
f.write(json.dumps(klines))

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL