Skip to content

Commit

Permalink
fix research.store_candles() + write unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
saleh-mir committed Sep 18, 2022
1 parent b09bb30 commit a00ab0d
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 18 deletions.
6 changes: 3 additions & 3 deletions jesse/modes/import_candles_mode/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def handle_time():
candles = _fill_absent_candles(candles, temp_start_timestamp, temp_end_timestamp)

# store in the database
_store_candles(candles)
store_candles_list(candles)

# add as much as driver's count to the temp_start_time
start_date = start_date.shift(minutes=driver.count)
Expand Down Expand Up @@ -262,7 +262,7 @@ def _get_candles_from_backup_exchange(exchange: str, backup_driver: CandleExchan
candles = _fill_absent_candles(candles, temp_start_timestamp, temp_end_timestamp)

# store in the database
_store_candles(candles)
store_candles_list(candles)

# add as much as driver's count to the temp_start_time
start_date = start_date.shift(minutes=backup_driver.count)
Expand Down Expand Up @@ -358,7 +358,7 @@ def _fill_absent_candles(temp_candles: List[Dict[str, Union[str, Any]]], start_t
return candles


def _store_candles(candles: List[Dict]) -> None:
def store_candles_list(candles: List[Dict]) -> None:
from jesse.models import Candle
for c in candles:
if 'timeframe' not in c:
Expand Down
42 changes: 27 additions & 15 deletions jesse/research/candles.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,30 +82,42 @@ def store_candles(candles: np.ndarray, exchange: str, symbol: str) -> None:
Stores candles in the database. The stored data can later be used for being fetched again via get_candles or even for running backtests on them.
A common use case for this function is for importing candles from a CSV file so you can later use them for backtesting.
"""
from jesse.services.db import store_candles as store_candles_from_list
from jesse.modes.import_candles_mode import store_candles_list as store_candles_from_list
import jesse.helpers as jh

# check if .env file exists
if not jh.is_jesse_project():
if not jh.is_unit_testing() and not jh.is_jesse_project():
raise FileNotFoundError(
'Invalid directory: ".env" file not found. To use Jesse inside notebooks, create notebooks inside the root of a Jesse project.'
)

# TODO: add validation for timeframe to make sure it's `1m`
# validate that candles type must be np.ndarray
if not isinstance(candles, np.ndarray):
raise TypeError('candles must be a numpy array.')

# add validation for timeframe to make sure it's `1m`
if candles[1][0] - candles[0][0] != 60_000:
raise ValueError(
f'Candles passed to the research.store_candles() must be 1m candles. '
f'\nThe difference between your candle timestamps is {candles[1][0] - candles[0][0]} milliseconds which is '
f'more than the accepted 60000 milliseconds.'
)

arr = [{
'id': jh.generate_unique_id(),
'symbol': symbol,
'exchange': exchange,
'timestamp': c[0],
'open': c[1],
'close': c[2],
'high': c[3],
'low': c[4],
'volume': c[5]
} for c in candles]

store_candles_from_list(arr)
'id': jh.generate_unique_id(),
'exchange': exchange,
'symbol': symbol,
'timeframe': '1m',
'timestamp': c[0],
'open': c[1],
'close': c[2],
'high': c[3],
'low': c[4],
'volume': c[5]
} for c in candles]

if not jh.is_unit_testing():
store_candles_from_list(arr)


def candlestick_chart(candles: np.ndarray):
Expand Down
26 changes: 26 additions & 0 deletions tests/test_research.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import pytest
from jesse import research


def test_store_candles():
"""
for now, don't actually store it in the db. But test validations, etc
"""
# validate that candles type must be np.ndarray
with pytest.raises(TypeError):
research.store_candles({}, 'Test Exchange', 'BTC-USDT')
with pytest.raises(TypeError):
research.store_candles([], 'Test Exchange', 'BTC-USDT')

# add validation for timeframe to make sure it's `1m`
with pytest.raises(ValueError):
close_prices = [10, 11]
np_candles = research.candles_from_close_prices(close_prices)
# change the timeframe to 5 minutes
np_candles[1][0] += 300_000
research.store_candles(np_candles, 'Test Exchange', 'BTC-USDT')

# just make sure it doesn't raise an error
close_prices = [10, 11, 12, 12, 11, 13, 14, 12, 11, 15]
np_candles = research.candles_from_close_prices(close_prices)
research.store_candles(np_candles, 'Test Exchange', 'BTC-USDT')

0 comments on commit a00ab0d

Please sign in to comment.