After running flake8.
This commit is contained in:
parent
b496ccb644
commit
2371ceda11
7 changed files with 40 additions and 22 deletions
|
@ -1,5 +1,4 @@
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from pricehist import outputs, sources
|
from pricehist import outputs, sources
|
||||||
|
@ -37,7 +36,6 @@ def cmd_source(args):
|
||||||
|
|
||||||
def cmd_fetch(args):
|
def cmd_fetch(args):
|
||||||
source = sources.by_id[args.source]()
|
source = sources.by_id[args.source]()
|
||||||
start = args.start or args.after
|
|
||||||
output = outputs.by_type[args.output]()
|
output = outputs.by_type[args.output]()
|
||||||
prices = source.fetch(args.pair, args.start, args.end)
|
prices = source.fetch(args.pair, args.start, args.end)
|
||||||
print(output.format(prices))
|
print(output.format(prices))
|
||||||
|
@ -66,7 +64,7 @@ def build_parser():
|
||||||
|
|
||||||
subparsers = parser.add_subparsers(title="commands", dest="command")
|
subparsers = parser.add_subparsers(title="commands", dest="command")
|
||||||
|
|
||||||
sources_parser = subparsers.add_parser("sources", help="list sources")
|
subparsers.add_parser("sources", help="list sources")
|
||||||
|
|
||||||
source_parser = subparsers.add_parser("source", help="show source details")
|
source_parser = subparsers.add_parser("source", help="show source details")
|
||||||
source_parser.add_argument(
|
source_parser.add_argument(
|
||||||
|
|
|
@ -2,7 +2,6 @@ class Beancount:
|
||||||
def format(self, prices):
|
def format(self, prices):
|
||||||
lines = []
|
lines = []
|
||||||
for price in prices:
|
for price in prices:
|
||||||
date = str(price.date).translate(str.maketrans("-", "/"))
|
|
||||||
lines.append(
|
lines.append(
|
||||||
f"{price.date} price {price.base} {price.amount} {price.quote}"
|
f"{price.date} price {price.base} {price.amount} {price.quote}"
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,7 +2,6 @@ class CSV:
|
||||||
def format(self, prices):
|
def format(self, prices):
|
||||||
lines = ["date,base,quote,amount"]
|
lines = ["date,base,quote,amount"]
|
||||||
for price in prices:
|
for price in prices:
|
||||||
date = str(price.date).translate(str.maketrans("-", "/"))
|
|
||||||
line = ",".join([price.date, price.base, price.quote, str(price.amount)])
|
line = ",".join([price.date, price.base, price.quote, str(price.amount)])
|
||||||
lines.append(line)
|
lines.append(line)
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|
|
@ -21,7 +21,18 @@ class GnuCashSQL:
|
||||||
guid = m.hexdigest()[0:32]
|
guid = m.hexdigest()[0:32]
|
||||||
value_num = str(price.amount).replace(".", "")
|
value_num = str(price.amount).replace(".", "")
|
||||||
value_denom = 10 ** len(f"{price.amount}.".split(".")[1])
|
value_denom = 10 ** len(f"{price.amount}.".split(".")[1])
|
||||||
v = f"('{guid}', '{date}', '{price.base}', '{price.quote}', '{source}', '{typ}', {value_num}, {value_denom})"
|
v = (
|
||||||
|
"("
|
||||||
|
f"'{guid}', "
|
||||||
|
f"'{date}', "
|
||||||
|
f"'{price.base}', "
|
||||||
|
f"'{price.quote}', "
|
||||||
|
f"'{source}', "
|
||||||
|
f"'{typ}', "
|
||||||
|
f"{value_num}, "
|
||||||
|
f"{value_denom}"
|
||||||
|
")"
|
||||||
|
)
|
||||||
values.append(v)
|
values.append(v)
|
||||||
|
|
||||||
comma_newline = ",\n"
|
comma_newline = ",\n"
|
||||||
|
|
|
@ -17,7 +17,10 @@ class CoinDesk:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def description():
|
def description():
|
||||||
return "An average of bitcoin prices across leading global exchanges. Powered by CoinDesk, https://www.coindesk.com/price/bitcoin"
|
return (
|
||||||
|
"An average of bitcoin prices across leading global exchanges. "
|
||||||
|
"Powered by CoinDesk, https://www.coindesk.com/price/bitcoin"
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def source_url():
|
def source_url():
|
||||||
|
@ -45,11 +48,17 @@ class CoinDesk:
|
||||||
min_start = "2010-07-17"
|
min_start = "2010-07-17"
|
||||||
if start < min_start:
|
if start < min_start:
|
||||||
exit(
|
exit(
|
||||||
f"start {start} too early. The CoinDesk BPI only covers data from {min_start} onwards."
|
f"start {start} too early. The CoinDesk BPI only covers data"
|
||||||
|
f"from {min_start} onwards."
|
||||||
)
|
)
|
||||||
|
|
||||||
url = f"https://api.coindesk.com/v1/bpi/historical/close.json?currency={quote}&start={start}&end={end}"
|
url = "https://api.coindesk.com/v1/bpi/historical/close.json"
|
||||||
response = requests.get(url)
|
params = {
|
||||||
|
"currency": quote,
|
||||||
|
"start": start,
|
||||||
|
"end": end,
|
||||||
|
}
|
||||||
|
response = requests.get(url, params=params)
|
||||||
data = json.loads(response.content)
|
data = json.loads(response.content)
|
||||||
prices = []
|
prices = []
|
||||||
for (d, v) in data["bpi"].items():
|
for (d, v) in data["bpi"].items():
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import json
|
import json
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from xml.etree import ElementTree
|
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
@ -25,9 +24,10 @@ class CoinMarketCap:
|
||||||
def source_url():
|
def source_url():
|
||||||
return "https://coinmarketcap.com/"
|
return "https://coinmarketcap.com/"
|
||||||
|
|
||||||
# # currency metadata - these may max out at 5k items (crypto data is currently 4720 items)
|
# # currency metadata - these may max out at 5k items
|
||||||
# curl 'https://web-api.coinmarketcap.com/v1/fiat/map?include_metals=true' | jq . | tee fiat-map.json
|
# # (crypto data is currently 4720 items)
|
||||||
# curl 'https://web-api.coinmarketcap.com/v1/cryptocurrency/map' | jq . | tee cryptocurrency-map.json
|
# curl '.../v1/fiat/map?include_metals=true' | jq . | tee fiat-map.json
|
||||||
|
# curl '.../v1/cryptocurrency/map' | jq . | tee cryptocurrency-map.json
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def bases():
|
def bases():
|
||||||
|
@ -40,13 +40,14 @@ class CoinMarketCap:
|
||||||
def fetch(self, pair, start, end):
|
def fetch(self, pair, start, end):
|
||||||
base, quote = pair.split("/")
|
base, quote = pair.split("/")
|
||||||
|
|
||||||
url = f"https://web-api.coinmarketcap.com/v1/cryptocurrency/ohlcv/historical"
|
url = "https://web-api.coinmarketcap.com/v1/cryptocurrency/ohlcv/historical"
|
||||||
params = {
|
params = {
|
||||||
"symbol": base,
|
"symbol": base,
|
||||||
"convert": quote,
|
"convert": quote,
|
||||||
"time_start": int(datetime.strptime(start, "%Y-%m-%d").timestamp()),
|
"time_start": int(datetime.strptime(start, "%Y-%m-%d").timestamp()),
|
||||||
"time_end": int(datetime.strptime(end, "%Y-%m-%d").timestamp())
|
"time_end": (
|
||||||
+ 24 * 60 * 60, # round up to include the last day
|
int(datetime.strptime(end, "%Y-%m-%d").timestamp()) + 24 * 60 * 60
|
||||||
|
), # round up to include the last day
|
||||||
}
|
}
|
||||||
|
|
||||||
response = requests.get(url, params=params)
|
response = requests.get(url, params=params)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import json
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from xml.etree import ElementTree
|
from xml.etree import ElementTree
|
||||||
|
@ -78,10 +77,11 @@ class ECB:
|
||||||
exit(f"start {start} too early. Minimum is {min_start}")
|
exit(f"start {start} too early. Minimum is {min_start}")
|
||||||
|
|
||||||
almost_90_days_ago = str(datetime.now().date() - timedelta(days=85))
|
almost_90_days_ago = str(datetime.now().date() - timedelta(days=85))
|
||||||
|
url_base = "https://www.ecb.europa.eu/stats/eurofxref"
|
||||||
if start > almost_90_days_ago:
|
if start > almost_90_days_ago:
|
||||||
source_url = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml" # last 90 days
|
source_url = f"{url_base}/eurofxref-hist-90d.xml" # last 90 days
|
||||||
else:
|
else:
|
||||||
source_url = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml" # since 1999
|
source_url = f"{url_base}/eurofxref-hist.xml" # since 1999
|
||||||
|
|
||||||
response = requests.get(source_url)
|
response = requests.get(source_url)
|
||||||
data = response.content
|
data = response.content
|
||||||
|
@ -96,7 +96,8 @@ class ECB:
|
||||||
for day in root.find("default:Cube", namespaces):
|
for day in root.find("default:Cube", namespaces):
|
||||||
date = day.attrib["time"]
|
date = day.attrib["time"]
|
||||||
rate_xpath = f"./*[@currency='{quote}']"
|
rate_xpath = f"./*[@currency='{quote}']"
|
||||||
# TODO what if it's not found for that day? (some quotes aren't in the earliest data)
|
# TODO what if it's not found for that day?
|
||||||
|
# (some quotes aren't in the earliest data)
|
||||||
rate = Decimal(day.find(rate_xpath).attrib["rate"])
|
rate = Decimal(day.find(rate_xpath).attrib["rate"])
|
||||||
all_rows.insert(0, (date, rate))
|
all_rows.insert(0, (date, rate))
|
||||||
selected = [
|
selected = [
|
||||||
|
|
Loading…
Add table
Reference in a new issue