class PriceHistoryTestCase(TestCase): def setUp(self): self.price_history = PriceVolumeHistoryStorage( ticker=ticker1, exchange=exchange, timestamp=timestamp, index=index, value=value ) def test_must_use_standard_index(self): self.price_history.index = "some_other_price" self.assertRaises( PriceVolumeHistoryException, self.price_history.save ) def test_old_timestamp_raises_exception(self): def instantiate_old_price_history(): old_price_history = PriceVolumeHistoryStorage( ticker=ticker1, exchange=exchange, timestamp=JAN_1_2017_TIMESTAMP - 1, # too old index=index, value=value ) self.assertRaises( TimeseriesException, instantiate_old_price_history ) def test_dublicate_returns_0(self): self.price_history.index = "close_price" self.price_history.value = 12345 self.price_history.unix_timestamp = JAN_1_2017_TIMESTAMP + 298343 # first time saves, returns 1 for 1 entry added self.assertEqual(self.price_history.save(), 1) # second time saves, returns 0 for duplicate, no entry added self.assertEqual(self.price_history.save(), 0) def test_query_tolerance(self): query_results = PriceVolumeHistoryStorage.query(ticker=ticker1, exchange=exchange, index=index, timestamp=timestamp, periods_range=1, timestamp_tolerance=29) self.assertLess(len(query_results['values']), 7) def tearDown(self): from settings.redis_db import database database.delete(self.price_history.get_db_key())
def save_pv_histories_to_redis(ph_object, pipeline=None): if ph_object.source is not BINANCE or ph_object.counter_currency not in [ BTC, USDT ]: return pipeline or [0] using_local_pipeline = (not pipeline) if using_local_pipeline: pipeline = database.pipeline() # transaction=False ticker = f'{ph_object.transaction_currency}_{ph_object.get_counter_currency_display()}' exchange = str(ph_object.get_source_display()) unix_timestamp = int(ph_object.timestamp.timestamp()) # SAVE VALUES IN REDIS USING PriceVolumeHistoryStorage OBJECT # CREATE OBJECT FOR STORAGE pv_storage = PriceVolumeHistoryStorage(ticker=ticker, exchange=exchange, timestamp=unix_timestamp) publish_close_price = timestamp_is_near_5min(unix_timestamp) if ph_object.volume and ph_object.volume > 0: pv_storage.index = "close_volume" pv_storage.value = ph_object.volume pipeline = pv_storage.save(publish=publish_close_price, pipeline=pipeline) if ph_object.open_p and ph_object.open_p > 0: pv_storage.index = "open_price" pv_storage.value = ph_object.open_p pipeline = pv_storage.save(publish=False, pipeline=pipeline) if ph_object.high and ph_object.high > 0: pv_storage.index = "high_price" pv_storage.value = ph_object.high pipeline = pv_storage.save(publish=False, pipeline=pipeline) if ph_object.low and ph_object.low > 0: pv_storage.index = "low_price" pv_storage.value = ph_object.low pipeline = pv_storage.save(publish=False, pipeline=pipeline) # always run 'close_price' index last # why? when it saves, it triggers price storage to resample # after resampling history indexes are deleted # so all others should be available for resampling before being deleted if ph_object.close and ph_object.close > 0: pv_storage.index = "close_price" pv_storage.value = ph_object.close pipeline = pv_storage.save(publish=True, pipeline=pipeline) if using_local_pipeline: return pipeline.execute() else: return pipeline ### END PULL OF PRICE HISTORY RECORDS ###