diff options
Diffstat (limited to 'store.py')
-rw-r--r-- | store.py | 85 |
1 files changed, 82 insertions, 3 deletions
@@ -1,10 +1,14 @@ | |||
1 | import time | ||
2 | import requests | ||
1 | import portfolio | 3 | import portfolio |
2 | import simplejson as json | 4 | import simplejson as json |
3 | from decimal import Decimal as D, ROUND_DOWN | 5 | from decimal import Decimal as D, ROUND_DOWN |
4 | from datetime import date, datetime | 6 | from datetime import date, datetime, timedelta |
5 | import inspect | 7 | import inspect |
8 | from json import JSONDecodeError | ||
9 | from simplejson.errors import JSONDecodeError as SimpleJSONDecodeError | ||
6 | 10 | ||
7 | __all__ = ["BalanceStore", "ReportStore", "TradeStore"] | 11 | __all__ = ["Portfolio", "BalanceStore", "ReportStore", "TradeStore"] |
8 | 12 | ||
9 | class ReportStore: | 13 | class ReportStore: |
10 | def __init__(self, market, verbose_print=True): | 14 | def __init__(self, market, verbose_print=True): |
@@ -213,7 +217,7 @@ class BalanceStore: | |||
213 | 217 | ||
214 | def dispatch_assets(self, amount, liquidity="medium", repartition=None): | 218 | def dispatch_assets(self, amount, liquidity="medium", repartition=None): |
215 | if repartition is None: | 219 | if repartition is None: |
216 | repartition = portfolio.Portfolio.repartition(self.market, liquidity=liquidity) | 220 | repartition = Portfolio.repartition(liquidity=liquidity) |
217 | sum_ratio = sum([v[0] for k, v in repartition.items()]) | 221 | sum_ratio = sum([v[0] for k, v in repartition.items()]) |
218 | amounts = {} | 222 | amounts = {} |
219 | for currency, (ptt, trade_type) in repartition.items(): | 223 | for currency, (ptt, trade_type) in repartition.items(): |
@@ -301,4 +305,79 @@ class TradeStore: | |||
301 | for order in self.all_orders(state="open"): | 305 | for order in self.all_orders(state="open"): |
302 | order.get_status() | 306 | order.get_status() |
303 | 307 | ||
308 | class Portfolio: | ||
309 | URL = "https://cryptoportfolio.io/wp-content/uploads/portfolio/json/cryptoportfolio.json" | ||
310 | liquidities = {} | ||
311 | data = None | ||
312 | last_date = None | ||
313 | report = ReportStore(None) | ||
314 | |||
315 | @classmethod | ||
316 | def wait_for_recent(cls, delta=4): | ||
317 | cls.get_cryptoportfolio() | ||
318 | while cls.last_date is None or datetime.now() - cls.last_date > timedelta(delta): | ||
319 | time.sleep(30) | ||
320 | cls.report.print_log("Attempt to fetch up-to-date cryptoportfolio") | ||
321 | cls.get_cryptoportfolio(refetch=True) | ||
322 | |||
323 | @classmethod | ||
324 | def repartition(cls, liquidity="medium"): | ||
325 | cls.get_cryptoportfolio() | ||
326 | liquidities = cls.liquidities[liquidity] | ||
327 | return liquidities[cls.last_date] | ||
328 | |||
329 | @classmethod | ||
330 | def get_cryptoportfolio(cls, refetch=False): | ||
331 | if cls.data is not None and not refetch: | ||
332 | return | ||
333 | try: | ||
334 | r = requests.get(cls.URL) | ||
335 | cls.report.log_http_request(r.request.method, | ||
336 | r.request.url, r.request.body, r.request.headers, r) | ||
337 | except Exception as e: | ||
338 | cls.report.log_error("get_cryptoportfolio", exception=e) | ||
339 | return | ||
340 | try: | ||
341 | cls.data = r.json(parse_int=D, parse_float=D) | ||
342 | cls.parse_cryptoportfolio() | ||
343 | except (JSONDecodeError, SimpleJSONDecodeError): | ||
344 | cls.data = None | ||
345 | cls.liquidities = {} | ||
346 | |||
347 | @classmethod | ||
348 | def parse_cryptoportfolio(cls): | ||
349 | def filter_weights(weight_hash): | ||
350 | if weight_hash[1][0] == 0: | ||
351 | return False | ||
352 | if weight_hash[0] == "_row": | ||
353 | return False | ||
354 | return True | ||
355 | |||
356 | def clean_weights(i): | ||
357 | def clean_weights_(h): | ||
358 | if h[0].endswith("s"): | ||
359 | return [h[0][0:-1], (h[1][i], "short")] | ||
360 | else: | ||
361 | return [h[0], (h[1][i], "long")] | ||
362 | return clean_weights_ | ||
363 | |||
364 | def parse_weights(portfolio_hash): | ||
365 | weights_hash = portfolio_hash["weights"] | ||
366 | weights = {} | ||
367 | for i in range(len(weights_hash["_row"])): | ||
368 | date = datetime.strptime(weights_hash["_row"][i], "%Y-%m-%d") | ||
369 | weights[date] = dict(filter( | ||
370 | filter_weights, | ||
371 | map(clean_weights(i), weights_hash.items()))) | ||
372 | return weights | ||
373 | |||
374 | high_liquidity = parse_weights(cls.data["portfolio_1"]) | ||
375 | medium_liquidity = parse_weights(cls.data["portfolio_2"]) | ||
376 | |||
377 | cls.liquidities = { | ||
378 | "medium": medium_liquidity, | ||
379 | "high": high_liquidity, | ||
380 | } | ||
381 | cls.last_date = max(max(medium_liquidity.keys()), max(high_liquidity.keys())) | ||
382 | |||
304 | 383 | ||