Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix test_get_historical_prices; make polygon test deterministic #659

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lumibot/entities/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,11 @@ def _get_bars_dict(self, dt, length=1, timestep=None, timeshift=0):

# Get bars.
end_row = self.get_iter_count(dt) - timeshift
if self.df.index[end_row] != dt:
# If dt is not in the dataframe, get_iter_count will return the last bar before dt.
# Since the data is not complete, we need to get the last bar, which is the end_row.
# And since the selection at the end is exclusive of end_row, we need to add 1 to end_row here.
end_row += 1
start_row = end_row - length

if start_row < 0:
Expand Down
51 changes: 40 additions & 11 deletions tests/test_get_historical_prices.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
from lumibot.tools import get_trading_days

# Global parameters
# API Key for testing Polygon.io
from lumibot.credentials import POLYGON_API_KEY
from lumibot.credentials import TRADIER_CONFIG, ALPACA_CONFIG
from lumibot.credentials import TRADIER_CONFIG, ALPACA_CONFIG, POLYGON_CONFIG


logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -134,13 +132,35 @@ def test_pandas_backtesting_data_source_get_historical_prices_daily_bars(self, p
self.check_date_of_last_bar_is_date_of_last_trading_date_before_backtest_start(bars, backtesting_start=backtesting_start)
self.check_dividends_and_adjusted_returns(bars)

@pytest.mark.skip(reason="This test exposes a possible bug in data.py that we have not investigated yet.")
@pytest.mark.skipif(POLYGON_API_KEY == '<your key here>', reason="This test requires a Polygon.io API key")
# First trading day after Thanksgiving test
backtesting_start = datetime(2019, 11, 2)
backtesting_end = datetime(2019, 12, 2)
data_source = PandasData(
datetime_start=backtesting_start,
datetime_end=backtesting_end,
pandas_data=pandas_data_fixture
)
bars = data_source.get_historical_prices(asset=self.asset, length=self.length, timestep=self.timestep)
check_bars(bars=bars, length=self.length)
self.check_date_of_last_bar_is_date_of_last_trading_date_before_backtest_start(bars, backtesting_start=backtesting_start)

@pytest.mark.skipif(not POLYGON_CONFIG["API_KEY"], reason="This test requires a Polygon.io API key")
@pytest.mark.skipif(not POLYGON_CONFIG["IS_PAID_SUBSCRIPTION"], reason="This test requires a paid Polygon.io API key")
def test_polygon_backtesting_data_source_get_historical_prices_daily_bars(self):
backtesting_end = datetime.now() - timedelta(days=1)
backtesting_start = backtesting_end - timedelta(days=self.length * 2 + 5)
backtesting_start = datetime(2019, 3, 25)
backtesting_end = datetime(2019, 4, 25)
data_source = PolygonDataBacktesting(
backtesting_start, backtesting_end, api_key=POLYGON_CONFIG["API_KEY"]
)
bars = data_source.get_historical_prices(asset=self.asset, length=self.length, timestep=self.timestep)
check_bars(bars=bars, length=self.length)
self.check_date_of_last_bar_is_date_of_last_trading_date_before_backtest_start(bars, backtesting_start=backtesting_start)

# First trading day after Thanksgiving test
backtesting_start = datetime(2019, 3, 25)
backtesting_end = datetime(2019, 4, 25)
data_source = PolygonDataBacktesting(
backtesting_start, backtesting_end, api_key=POLYGON_API_KEY
backtesting_start, backtesting_end, api_key=POLYGON_CONFIG["API_KEY"]
)
bars = data_source.get_historical_prices(asset=self.asset, length=self.length, timestep=self.timestep)
check_bars(bars=bars, length=self.length)
Expand All @@ -163,8 +183,19 @@ def test_yahoo_backtesting_data_source_get_historical_prices_daily_bars(self, pa
self.check_dividends_and_adjusted_returns(bars)
self.check_date_of_last_bar_is_date_of_last_trading_date_before_backtest_start(bars, backtesting_start=backtesting_start)

# First trading day after Thanksgiving test
backtesting_start = datetime(2019, 3, 25)
backtesting_end = datetime(2019, 4, 25)
data_source = YahooDataBacktesting(
datetime_start=backtesting_start,
datetime_end=backtesting_end,
pandas_data=pandas_data_fixture
)
bars = data_source.get_historical_prices(asset=self.asset, length=self.length, timestep=self.timestep)
check_bars(bars=bars, length=self.length)
self.check_date_of_last_bar_is_date_of_last_trading_date_before_backtest_start(bars, backtesting_start=backtesting_start)


# @pytest.mark.skip()
class TestDatasourceGetHistoricalPricesDailyData:
"""These tests check the daily Bars returned from get_historical_prices for live data sources."""

Expand Down Expand Up @@ -202,7 +233,6 @@ def check_date_of_last_bar_is_correct_for_live_data_sources(self, bars):
# if it's not a trading day, the last bar the bar should from the last trading day
assert bars.df.index[-1].date() == self.trading_days.index[-1].date()

# @pytest.mark.skip()
@pytest.mark.skipif(not ALPACA_CONFIG['API_KEY'], reason="This test requires an alpaca API key")
@pytest.mark.skipif(
ALPACA_CONFIG['API_KEY'] == '<your key here>',
Expand All @@ -225,7 +255,6 @@ def test_alpaca_data_source_get_historical_prices_daily_bars(self):
check_bars(bars=bars, length=1, check_timezone=False)
self.check_date_of_last_bar_is_correct_for_live_data_sources(bars)

# @pytest.mark.skip()
@pytest.mark.skipif(not TRADIER_CONFIG['ACCESS_TOKEN'], reason="No Tradier credentials provided.")
def test_tradier_data_source_get_historical_prices_daily_bars(self):
data_source = TradierData(
Expand Down
Loading