Sources: extract http reqs from fetch method.
This commit is contained in:
parent
a91309678c
commit
93ca00f5a5
3 changed files with 44 additions and 37 deletions
|
@ -45,6 +45,13 @@ class CoinDesk(BaseSource):
|
||||||
return symbols
|
return symbols
|
||||||
|
|
||||||
def fetch(self, series):
|
def fetch(self, series):
|
||||||
|
data = self._data(series)
|
||||||
|
prices = []
|
||||||
|
for (d, v) in data["bpi"].items():
|
||||||
|
prices.append(Price(d, Decimal(str(v))))
|
||||||
|
return dataclasses.replace(series, prices=prices)
|
||||||
|
|
||||||
|
def _data(self, series):
|
||||||
url = "https://api.coindesk.com/v1/bpi/historical/close.json"
|
url = "https://api.coindesk.com/v1/bpi/historical/close.json"
|
||||||
params = {
|
params = {
|
||||||
"currency": series.quote,
|
"currency": series.quote,
|
||||||
|
@ -52,9 +59,4 @@ class CoinDesk(BaseSource):
|
||||||
"end": series.end,
|
"end": series.end,
|
||||||
}
|
}
|
||||||
response = requests.get(url, params=params)
|
response = requests.get(url, params=params)
|
||||||
data = json.loads(response.content)
|
return json.loads(response.content)
|
||||||
prices = []
|
|
||||||
for (d, v) in data["bpi"].items():
|
|
||||||
prices.append(Price(d, Decimal(str(v))))
|
|
||||||
|
|
||||||
return dataclasses.replace(series, prices=prices)
|
|
||||||
|
|
|
@ -47,29 +47,34 @@ class CoinMarketCap:
|
||||||
return rows
|
return rows
|
||||||
|
|
||||||
def fetch(self, series):
|
def fetch(self, series):
|
||||||
|
data = self._data(series)
|
||||||
|
|
||||||
|
prices = []
|
||||||
|
for item in data["data"]["quotes"]:
|
||||||
|
d = item["time_open"][0:10]
|
||||||
|
amount = self._amount(next(iter(item["quote"].values())), series.type)
|
||||||
|
prices.append(Price(d, amount))
|
||||||
|
|
||||||
|
output_base, output_quote = self._output_pair(series.base, series.quote)
|
||||||
|
|
||||||
|
return dataclasses.replace(
|
||||||
|
series, base=output_base, quote=output_quote, prices=prices
|
||||||
|
)
|
||||||
|
|
||||||
|
def _data(self, series):
|
||||||
url = "https://web-api.coinmarketcap.com/v1/cryptocurrency/ohlcv/historical"
|
url = "https://web-api.coinmarketcap.com/v1/cryptocurrency/ohlcv/historical"
|
||||||
|
|
||||||
params = {}
|
params = {}
|
||||||
if series.base.startswith("id=") or series.quote.startswith("id="):
|
|
||||||
symbols = {}
|
|
||||||
for i in self._symbol_data():
|
|
||||||
symbols[str(i["id"])] = i["symbol"] or i["code"]
|
|
||||||
|
|
||||||
if series.base.startswith("id="):
|
if series.base.startswith("id="):
|
||||||
params["id"] = series.base[3:]
|
params["id"] = series.base[3:]
|
||||||
output_base = symbols[series.base[3:]]
|
|
||||||
else:
|
else:
|
||||||
params["symbol"] = series.base
|
params["symbol"] = series.base
|
||||||
output_base = series.base
|
|
||||||
|
|
||||||
if series.quote.startswith("id="):
|
if series.quote.startswith("id="):
|
||||||
params["convert_id"] = series.quote[3:]
|
params["convert_id"] = series.quote[3:]
|
||||||
quote_key = series.quote[3:]
|
|
||||||
output_quote = symbols[series.quote[3:]]
|
|
||||||
else:
|
else:
|
||||||
params["convert"] = series.quote
|
params["convert"] = series.quote
|
||||||
quote_key = series.quote
|
|
||||||
output_quote = series.quote
|
|
||||||
|
|
||||||
params["time_start"] = int(
|
params["time_start"] = int(
|
||||||
datetime.strptime(series.start, "%Y-%m-%d").timestamp()
|
datetime.strptime(series.start, "%Y-%m-%d").timestamp()
|
||||||
|
@ -79,17 +84,25 @@ class CoinMarketCap:
|
||||||
) # round up to include the last day
|
) # round up to include the last day
|
||||||
|
|
||||||
response = requests.get(url, params=params)
|
response = requests.get(url, params=params)
|
||||||
data = json.loads(response.content)
|
|
||||||
|
|
||||||
prices = []
|
return json.loads(response.content)
|
||||||
for item in data["data"]["quotes"]:
|
|
||||||
d = item["time_open"][0:10]
|
|
||||||
amount = self._amount(item["quote"][quote_key], series.type)
|
|
||||||
prices.append(Price(d, amount))
|
|
||||||
|
|
||||||
return dataclasses.replace(
|
def _amount(self, data, type):
|
||||||
series, base=output_base, quote=output_quote, prices=prices
|
if type in [None, "mid"]:
|
||||||
)
|
high = Decimal(str(data["high"]))
|
||||||
|
low = Decimal(str(data["low"]))
|
||||||
|
return sum([high, low]) / 2
|
||||||
|
else:
|
||||||
|
return Decimal(str(data[type]))
|
||||||
|
|
||||||
|
def _output_pair(self, base, quote):
|
||||||
|
if base.startswith("id=") or quote.startswith("id="):
|
||||||
|
symbols = {i["id"]: (i["symbol"] or i["code"]) for i in self._symbol_data()}
|
||||||
|
|
||||||
|
output_base = symbols[int(base[3:])] if base.startswith("id=") else base
|
||||||
|
output_quote = symbols[int(quote[3:])] if quote.startswith("id=") else quote
|
||||||
|
|
||||||
|
return (output_base, output_quote)
|
||||||
|
|
||||||
def _symbol_data(self):
|
def _symbol_data(self):
|
||||||
fiat_url = "https://web-api.coinmarketcap.com/v1/fiat/map?include_metals=true"
|
fiat_url = "https://web-api.coinmarketcap.com/v1/fiat/map?include_metals=true"
|
||||||
|
@ -101,11 +114,3 @@ class CoinMarketCap:
|
||||||
crypto_res = requests.get(crypto_url)
|
crypto_res = requests.get(crypto_url)
|
||||||
crypto = json.loads(crypto_res.content)
|
crypto = json.loads(crypto_res.content)
|
||||||
return crypto["data"] + fiat["data"]
|
return crypto["data"] + fiat["data"]
|
||||||
|
|
||||||
def _amount(self, data, type):
|
|
||||||
if type in [None, "mid"]:
|
|
||||||
high = Decimal(str(data["high"]))
|
|
||||||
low = Decimal(str(data["low"]))
|
|
||||||
return sum([high, low]) / 2
|
|
||||||
else:
|
|
||||||
return Decimal(str(data[type]))
|
|
||||||
|
|
|
@ -42,8 +42,7 @@ class ECB:
|
||||||
|
|
||||||
def fetch(self, series):
|
def fetch(self, series):
|
||||||
almost_90_days_ago = str(datetime.now().date() - timedelta(days=85))
|
almost_90_days_ago = str(datetime.now().date() - timedelta(days=85))
|
||||||
data = self._raw_data(series.start < almost_90_days_ago)
|
root = self._data(series.start < almost_90_days_ago)
|
||||||
root = etree.fromstring(data)
|
|
||||||
|
|
||||||
all_rows = []
|
all_rows = []
|
||||||
for day in root.cssselect("[time]"):
|
for day in root.cssselect("[time]"):
|
||||||
|
@ -59,7 +58,7 @@ class ECB:
|
||||||
|
|
||||||
return dataclasses.replace(series, prices=selected)
|
return dataclasses.replace(series, prices=selected)
|
||||||
|
|
||||||
def _raw_data(self, more_than_90_days=False):
|
def _data(self, more_than_90_days=False):
|
||||||
url_base = "https://www.ecb.europa.eu/stats/eurofxref"
|
url_base = "https://www.ecb.europa.eu/stats/eurofxref"
|
||||||
if more_than_90_days:
|
if more_than_90_days:
|
||||||
source_url = f"{url_base}/eurofxref-hist.xml" # since 1999
|
source_url = f"{url_base}/eurofxref-hist.xml" # since 1999
|
||||||
|
@ -67,4 +66,5 @@ class ECB:
|
||||||
source_url = f"{url_base}/eurofxref-hist-90d.xml" # last 90 days
|
source_url = f"{url_base}/eurofxref-hist-90d.xml" # last 90 days
|
||||||
|
|
||||||
response = requests.get(source_url)
|
response = requests.get(source_url)
|
||||||
return response.content
|
root = etree.fromstring(response.content)
|
||||||
|
return root
|
||||||
|
|
Loading…
Add table
Reference in a new issue