aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2018-05-02 01:50:46 +0200
committerIsmaël Bouya <ismael.bouya@normalesup.org>2018-05-02 01:50:46 +0200
commit40d0fa279e0745b33676f21cdc8b496ebd301cf8 (patch)
tree0541455cde1a79d1b8f89e5de731c7cb4c1faa30
parent30700830b6c0aaaa59c148ebd8edb6931040ed13 (diff)
downloadTrader-40d0fa279e0745b33676f21cdc8b496ebd301cf8.tar.gz
Trader-40d0fa279e0745b33676f21cdc8b496ebd301cf8.tar.zst
Trader-40d0fa279e0745b33676f21cdc8b496ebd301cf8.zip
Store last cryptoportfolio repartition to redis
-rw-r--r--store.py14
-rw-r--r--tests/test_store.py37
2 files changed, 50 insertions, 1 deletions
diff --git a/store.py b/store.py
index cd0bf7b..81828f0 100644
--- a/store.py
+++ b/store.py
@@ -7,6 +7,7 @@ import datetime
7import inspect 7import inspect
8from json import JSONDecodeError 8from json import JSONDecodeError
9from simplejson.errors import JSONDecodeError as SimpleJSONDecodeError 9from simplejson.errors import JSONDecodeError as SimpleJSONDecodeError
10import dbs
10 11
11__all__ = ["Portfolio", "BalanceStore", "ReportStore", "TradeStore"] 12__all__ = ["Portfolio", "BalanceStore", "ReportStore", "TradeStore"]
12 13
@@ -530,12 +531,25 @@ class Portfolio:
530 try: 531 try:
531 cls.data.set(r.json(parse_int=D, parse_float=D)) 532 cls.data.set(r.json(parse_int=D, parse_float=D))
532 cls.parse_cryptoportfolio() 533 cls.parse_cryptoportfolio()
534 cls.store_cryptoportfolio()
533 except (JSONDecodeError, SimpleJSONDecodeError): 535 except (JSONDecodeError, SimpleJSONDecodeError):
534 cls.data.set(None) 536 cls.data.set(None)
535 cls.last_date.set(None) 537 cls.last_date.set(None)
536 cls.liquidities.set({}) 538 cls.liquidities.set({})
537 539
538 @classmethod 540 @classmethod
541 def store_cryptoportfolio(cls):
542 if dbs.redis_connected():
543 hash_ = {}
544 for liquidity, repartitions in cls.liquidities.items():
545 hash_[liquidity] = repartitions[cls.last_date.get()]
546 dump = json.dumps(hash_)
547 key = "/cryptoportfolio/repartition/latest"
548 dbs.redis.set(key, dump)
549 key = "/cryptoportfolio/repartition/date"
550 dbs.redis.set(key, cls.last_date.date().isoformat())
551
552 @classmethod
539 def parse_cryptoportfolio(cls): 553 def parse_cryptoportfolio(cls):
540 def filter_weights(weight_hash): 554 def filter_weights(weight_hash):
541 if weight_hash[1][0] == 0: 555 if weight_hash[1][0] == 0:
diff --git a/tests/test_store.py b/tests/test_store.py
index 12999d3..d0f7755 100644
--- a/tests/test_store.py
+++ b/tests/test_store.py
@@ -1101,7 +1101,8 @@ class PortfolioTest(WebMockTestCase):
1101 self.wm.get(market.Portfolio.URL, text=self.json_response) 1101 self.wm.get(market.Portfolio.URL, text=self.json_response)
1102 1102
1103 @mock.patch.object(market.Portfolio, "parse_cryptoportfolio") 1103 @mock.patch.object(market.Portfolio, "parse_cryptoportfolio")
1104 def test_get_cryptoportfolio(self, parse_cryptoportfolio): 1104 @mock.patch.object(market.Portfolio, "store_cryptoportfolio")
1105 def test_get_cryptoportfolio(self, store_cryptoportfolio, parse_cryptoportfolio):
1105 with self.subTest(parallel=False): 1106 with self.subTest(parallel=False):
1106 self.wm.get(market.Portfolio.URL, [ 1107 self.wm.get(market.Portfolio.URL, [
1107 {"text":'{ "foo": "bar" }', "status_code": 200}, 1108 {"text":'{ "foo": "bar" }', "status_code": 200},
@@ -1116,23 +1117,28 @@ class PortfolioTest(WebMockTestCase):
1116 market.Portfolio.report.log_error.assert_not_called() 1117 market.Portfolio.report.log_error.assert_not_called()
1117 market.Portfolio.report.log_http_request.assert_called_once() 1118 market.Portfolio.report.log_http_request.assert_called_once()
1118 parse_cryptoportfolio.assert_called_once_with() 1119 parse_cryptoportfolio.assert_called_once_with()
1120 store_cryptoportfolio.assert_called_once_with()
1119 market.Portfolio.report.log_http_request.reset_mock() 1121 market.Portfolio.report.log_http_request.reset_mock()
1120 parse_cryptoportfolio.reset_mock() 1122 parse_cryptoportfolio.reset_mock()
1123 store_cryptoportfolio.reset_mock()
1121 market.Portfolio.data = store.LockedVar(None) 1124 market.Portfolio.data = store.LockedVar(None)
1122 1125
1123 market.Portfolio.get_cryptoportfolio() 1126 market.Portfolio.get_cryptoportfolio()
1124 self.assertIsNone(market.Portfolio.data.get()) 1127 self.assertIsNone(market.Portfolio.data.get())
1125 self.assertEqual(2, self.wm.call_count) 1128 self.assertEqual(2, self.wm.call_count)
1126 parse_cryptoportfolio.assert_not_called() 1129 parse_cryptoportfolio.assert_not_called()
1130 store_cryptoportfolio.assert_not_called()
1127 market.Portfolio.report.log_error.assert_not_called() 1131 market.Portfolio.report.log_error.assert_not_called()
1128 market.Portfolio.report.log_http_request.assert_called_once() 1132 market.Portfolio.report.log_http_request.assert_called_once()
1129 market.Portfolio.report.log_http_request.reset_mock() 1133 market.Portfolio.report.log_http_request.reset_mock()
1130 parse_cryptoportfolio.reset_mock() 1134 parse_cryptoportfolio.reset_mock()
1135 store_cryptoportfolio.reset_mock()
1131 1136
1132 market.Portfolio.data = store.LockedVar("Foo") 1137 market.Portfolio.data = store.LockedVar("Foo")
1133 market.Portfolio.get_cryptoportfolio() 1138 market.Portfolio.get_cryptoportfolio()
1134 self.assertEqual(2, self.wm.call_count) 1139 self.assertEqual(2, self.wm.call_count)
1135 parse_cryptoportfolio.assert_not_called() 1140 parse_cryptoportfolio.assert_not_called()
1141 store_cryptoportfolio.assert_not_called()
1136 1142
1137 market.Portfolio.get_cryptoportfolio(refetch=True) 1143 market.Portfolio.get_cryptoportfolio(refetch=True)
1138 self.assertEqual("Foo", market.Portfolio.data.get()) 1144 self.assertEqual("Foo", market.Portfolio.data.get())
@@ -1153,6 +1159,7 @@ class PortfolioTest(WebMockTestCase):
1153 market.Portfolio.get_cryptoportfolio() 1159 market.Portfolio.get_cryptoportfolio()
1154 self.assertIn("foo", market.Portfolio.data.get()) 1160 self.assertIn("foo", market.Portfolio.data.get())
1155 parse_cryptoportfolio.reset_mock() 1161 parse_cryptoportfolio.reset_mock()
1162 store_cryptoportfolio.reset_mock()
1156 with self.subTest(worker=False): 1163 with self.subTest(worker=False):
1157 market.Portfolio.data = store.LockedVar(None) 1164 market.Portfolio.data = store.LockedVar(None)
1158 market.Portfolio.worker = mock.Mock() 1165 market.Portfolio.worker = mock.Mock()
@@ -1160,6 +1167,7 @@ class PortfolioTest(WebMockTestCase):
1160 market.Portfolio.get_cryptoportfolio() 1167 market.Portfolio.get_cryptoportfolio()
1161 notify.assert_called_once_with() 1168 notify.assert_called_once_with()
1162 parse_cryptoportfolio.assert_not_called() 1169 parse_cryptoportfolio.assert_not_called()
1170 store_cryptoportfolio.assert_not_called()
1163 1171
1164 def test_parse_cryptoportfolio(self): 1172 def test_parse_cryptoportfolio(self):
1165 with self.subTest(description="Normal case"): 1173 with self.subTest(description="Normal case"):
@@ -1223,6 +1231,33 @@ class PortfolioTest(WebMockTestCase):
1223 self.assertEqual({}, market.Portfolio.liquidities.get("high")) 1231 self.assertEqual({}, market.Portfolio.liquidities.get("high"))
1224 self.assertEqual(datetime.datetime(1,1,1), market.Portfolio.last_date.get()) 1232 self.assertEqual(datetime.datetime(1,1,1), market.Portfolio.last_date.get())
1225 1233
1234 @mock.patch.object(store.dbs, "redis_connected")
1235 @mock.patch.object(store.dbs, "redis")
1236 def test_store_cryptoportfolio(self, redis, redis_connected):
1237 store.Portfolio.liquidities = store.LockedVar({
1238 "medium": {
1239 datetime.datetime(2018,3,1): "medium_2018-03-01",
1240 datetime.datetime(2018,3,8): "medium_2018-03-08",
1241 },
1242 "high": {
1243 datetime.datetime(2018,3,1): "high_2018-03-01",
1244 datetime.datetime(2018,3,8): "high_2018-03-08",
1245 }
1246 })
1247 store.Portfolio.last_date = store.LockedVar(datetime.datetime(2018,3,8))
1248
1249 with self.subTest(redis_connected=False):
1250 redis_connected.return_value = False
1251 store.Portfolio.store_cryptoportfolio()
1252 redis.set.assert_not_called()
1253
1254 with self.subTest(redis_connected=True):
1255 redis_connected.return_value = True
1256 store.Portfolio.store_cryptoportfolio()
1257 redis.set.assert_has_calls([
1258 mock.call("/cryptoportfolio/repartition/latest", '{"medium": "medium_2018-03-08", "high": "high_2018-03-08"}'),
1259 mock.call("/cryptoportfolio/repartition/date", "2018-03-08"),
1260 ])
1226 1261
1227 @mock.patch.object(market.Portfolio, "get_cryptoportfolio") 1262 @mock.patch.object(market.Portfolio, "get_cryptoportfolio")
1228 def test_repartition(self, get_cryptoportfolio): 1263 def test_repartition(self, get_cryptoportfolio):