import time
-from datetime import datetime
+from datetime import datetime, timedelta
from decimal import Decimal as D, ROUND_DOWN
# Put your poloniex api key in market.py
from json import JSONDecodeError
URL = "https://cryptoportfolio.io/wp-content/uploads/portfolio/json/cryptoportfolio.json"
liquidities = {}
data = None
+ last_date = None
@classmethod
- def repartition(cls, liquidity="medium"):
- cls.parse_cryptoportfolio()
+ def wait_for_recent(cls, delta=4):
+ cls.repartition(refetch=True)
+ while cls.last_date is None or datetime.now() - cls.last_date > timedelta(delta):
+ time.sleep(30)
+ cls.repartition(refetch=True)
+
+ @classmethod
+ def repartition(cls, liquidity="medium", refetch=False):
+ cls.parse_cryptoportfolio(refetch=refetch)
liquidities = cls.liquidities[liquidity]
- cls.last_date = sorted(liquidities.keys())[-1]
return liquidities[cls.last_date]
@classmethod
cls.data = None
@classmethod
- def parse_cryptoportfolio(cls):
- if cls.data is None:
+ def parse_cryptoportfolio(cls, refetch=False):
+ if refetch or cls.data is None:
cls.get_cryptoportfolio()
def filter_weights(weight_hash):
weights_hash = portfolio_hash["weights"]
weights = {}
for i in range(len(weights_hash["_row"])):
- weights[weights_hash["_row"][i]] = dict(filter(
+ date = datetime.strptime(weights_hash["_row"][i], "%Y-%m-%d")
+ weights[date] = dict(filter(
filter_weights,
map(clean_weights(i), weights_hash.items())))
return weights
"medium": medium_liquidity,
"high": high_liquidity,
}
+ cls.last_date = max(max(medium_liquidity.keys()), max(high_liquidity.keys()))
class Computation:
computations = {
mock.patch.multiple(portfolio.TradeStore,
all=[],
debug=False),
- mock.patch.multiple(portfolio.Portfolio, data=None, liquidities={}),
+ mock.patch.multiple(portfolio.Portfolio, last_date=None, data=None, liquidities={}),
mock.patch.multiple(portfolio.Computation,
computations=portfolio.Computation.computations),
mock.patch.multiple(helper,
'SC': (D("0.0623"), "long"),
'ZEC': (D("0.3701"), "long"),
}
- self.assertDictEqual(expected, liquidities["high"]['2018-01-08'])
+ date = portfolio.datetime(2018, 1, 8)
+ self.assertDictEqual(expected, liquidities["high"][date])
expected = {
'BTC': (D("1.1102e-16"), "long"),
'VIA': (D("0.1"), "long"),
'XCP': (D("0.1"), "long"),
}
- self.assertDictEqual(expected, liquidities["medium"]['2018-01-08'])
+ self.assertDictEqual(expected, liquidities["medium"][date])
+ self.assertEqual(portfolio.datetime(2018, 1, 15), portfolio.Portfolio.last_date)
# It doesn't refetch the data when available
portfolio.Portfolio.parse_cryptoportfolio()
self.assertEqual(1, self.wm.call_count)
+ portfolio.Portfolio.parse_cryptoportfolio(refetch=True)
+ self.assertEqual(2, self.wm.call_count)
+
def test_repartition(self):
expected_medium = {
'BTC': (D("1.1102e-16"), "long"),
self.assertEqual(expected_medium, portfolio.Portfolio.repartition(liquidity="medium"))
self.assertEqual(expected_high, portfolio.Portfolio.repartition(liquidity="high"))
+ self.assertEqual(1, self.wm.call_count)
+
+ portfolio.Portfolio.repartition()
+ self.assertEqual(1, self.wm.call_count)
+
+ portfolio.Portfolio.repartition(refetch=True)
+ self.assertEqual(2, self.wm.call_count)
+
+ @mock.patch.object(portfolio.time, "sleep")
+ @mock.patch.object(portfolio.Portfolio, "repartition")
+ def test_wait_for_recent(self, repartition, sleep):
+ self.call_count = 0
+ def _repartition(refetch):
+ self.assertTrue(refetch)
+ self.call_count += 1
+ portfolio.Portfolio.last_date = portfolio.datetime.now()\
+ - portfolio.timedelta(10)\
+ + portfolio.timedelta(self.call_count)
+ repartition.side_effect = _repartition
+
+ portfolio.Portfolio.wait_for_recent()
+ sleep.assert_called_with(30)
+ self.assertEqual(6, sleep.call_count)
+ self.assertEqual(7, repartition.call_count)
+
+ sleep.reset_mock()
+ repartition.reset_mock()
+ portfolio.Portfolio.last_date = None
+ self.call_count = 0
+ portfolio.Portfolio.wait_for_recent(delta=15)
+ sleep.assert_not_called()
+ self.assertEqual(1, repartition.call_count)
+
+ sleep.reset_mock()
+ repartition.reset_mock()
+ portfolio.Portfolio.last_date = None
+ self.call_count = 0
+ portfolio.Portfolio.wait_for_recent(delta=1)
+ sleep.assert_called_with(30)
+ self.assertEqual(9, sleep.call_count)
+ self.assertEqual(10, repartition.call_count)
+
@unittest.skipUnless("unit" in limits, "Unit skipped")
class AmountTest(WebMockTestCase):
def test_values(self):