diff options
Diffstat (limited to 'portfolio.py')
-rw-r--r-- | portfolio.py | 79 |
1 files changed, 1 insertions, 78 deletions
diff --git a/portfolio.py b/portfolio.py index 0f2c011..554b34f 100644 --- a/portfolio.py +++ b/portfolio.py | |||
@@ -1,87 +1,10 @@ | |||
1 | import time | 1 | from datetime import datetime |
2 | from datetime import datetime, timedelta | ||
3 | from decimal import Decimal as D, ROUND_DOWN | 2 | from decimal import Decimal as D, ROUND_DOWN |
4 | from json import JSONDecodeError | ||
5 | from simplejson.errors import JSONDecodeError as SimpleJSONDecodeError | ||
6 | from ccxt import ExchangeError, InsufficientFunds, ExchangeNotAvailable, InvalidOrder, OrderNotCached, OrderNotFound | 3 | from ccxt import ExchangeError, InsufficientFunds, ExchangeNotAvailable, InvalidOrder, OrderNotCached, OrderNotFound |
7 | from retry import retry | 4 | from retry import retry |
8 | import requests | ||
9 | 5 | ||
10 | # FIXME: correctly handle web call timeouts | 6 | # FIXME: correctly handle web call timeouts |
11 | 7 | ||
12 | class Portfolio: | ||
13 | URL = "https://cryptoportfolio.io/wp-content/uploads/portfolio/json/cryptoportfolio.json" | ||
14 | liquidities = {} | ||
15 | data = None | ||
16 | last_date = None | ||
17 | |||
18 | @classmethod | ||
19 | def wait_for_recent(cls, market, delta=4): | ||
20 | cls.repartition(market, refetch=True) | ||
21 | while cls.last_date is None or datetime.now() - cls.last_date > timedelta(delta): | ||
22 | time.sleep(30) | ||
23 | market.report.print_log("Attempt to fetch up-to-date cryptoportfolio") | ||
24 | cls.repartition(market, refetch=True) | ||
25 | |||
26 | @classmethod | ||
27 | def repartition(cls, market, liquidity="medium", refetch=False): | ||
28 | cls.parse_cryptoportfolio(market, refetch=refetch) | ||
29 | liquidities = cls.liquidities[liquidity] | ||
30 | return liquidities[cls.last_date] | ||
31 | |||
32 | @classmethod | ||
33 | def get_cryptoportfolio(cls, market): | ||
34 | try: | ||
35 | r = requests.get(cls.URL) | ||
36 | market.report.log_http_request(r.request.method, | ||
37 | r.request.url, r.request.body, r.request.headers, r) | ||
38 | except Exception as e: | ||
39 | market.report.log_error("get_cryptoportfolio", exception=e) | ||
40 | return | ||
41 | try: | ||
42 | cls.data = r.json(parse_int=D, parse_float=D) | ||
43 | except (JSONDecodeError, SimpleJSONDecodeError): | ||
44 | cls.data = None | ||
45 | |||
46 | @classmethod | ||
47 | def parse_cryptoportfolio(cls, market, refetch=False): | ||
48 | if refetch or cls.data is None: | ||
49 | cls.get_cryptoportfolio(market) | ||
50 | |||
51 | def filter_weights(weight_hash): | ||
52 | if weight_hash[1][0] == 0: | ||
53 | return False | ||
54 | if weight_hash[0] == "_row": | ||
55 | return False | ||
56 | return True | ||
57 | |||
58 | def clean_weights(i): | ||
59 | def clean_weights_(h): | ||
60 | if h[0].endswith("s"): | ||
61 | return [h[0][0:-1], (h[1][i], "short")] | ||
62 | else: | ||
63 | return [h[0], (h[1][i], "long")] | ||
64 | return clean_weights_ | ||
65 | |||
66 | def parse_weights(portfolio_hash): | ||
67 | weights_hash = portfolio_hash["weights"] | ||
68 | weights = {} | ||
69 | for i in range(len(weights_hash["_row"])): | ||
70 | date = datetime.strptime(weights_hash["_row"][i], "%Y-%m-%d") | ||
71 | weights[date] = dict(filter( | ||
72 | filter_weights, | ||
73 | map(clean_weights(i), weights_hash.items()))) | ||
74 | return weights | ||
75 | |||
76 | high_liquidity = parse_weights(cls.data["portfolio_1"]) | ||
77 | medium_liquidity = parse_weights(cls.data["portfolio_2"]) | ||
78 | |||
79 | cls.liquidities = { | ||
80 | "medium": medium_liquidity, | ||
81 | "high": high_liquidity, | ||
82 | } | ||
83 | cls.last_date = max(max(medium_liquidity.keys()), max(high_liquidity.keys())) | ||
84 | |||
85 | class Computation: | 8 | class Computation: |
86 | computations = { | 9 | computations = { |
87 | "default": lambda x, y: x[y], | 10 | "default": lambda x, y: x[y], |