piker/tests/test_ib_history.py

82 lines
1.9 KiB
Python

'''
IB historical-data request regressions.
'''
from datetime import (
UTC,
datetime,
)
from types import SimpleNamespace
from pendulum import datetime as pdatetime
import pytest
import trio
from piker.brokers.ib.api import Client
@pytest.mark.parametrize(
('end_dt', 'expected'),
[
(None, ''),
(
datetime(2026, 7, 28, 23, 30, tzinfo=UTC),
'20260728-23:30:00',
),
(
pdatetime(2026, 7, 28, 23, 30, tz='UTC'),
'20260728-23:30:00',
),
(
pdatetime(
2026,
7,
28,
23,
30,
tz='America/New_York',
),
'20260729-03:30:00',
),
],
)
def test_history_end_datetime_uses_ib_utc_format(
end_dt: datetime|None,
expected: str,
) -> None:
'''
Reverse history boundaries must use IB's explicit UTC syntax.
``ib_async`` adds a trailing ``UTC`` zone to aware datetimes.
The live IB gateway rejected that form with error 10314 while
filling an MNQ gap. Invoke ``Client.bars()`` with stdlib and
Pendulum boundaries, then capture the request kwargs.
Prove each becomes IB's UTC-dash form while latest requests stay
blank.
'''
request: dict = {}
class FakeIB:
async def reqHistoricalDataAsync(self, **kwargs) -> list:
request.update(kwargs)
return []
client = SimpleNamespace(ib=FakeIB())
async def find_contracts(fqme: str) -> list:
return [SimpleNamespace()]
client.find_contracts = find_contracts
async def main() -> None:
await Client.bars(
client,
fqme='mnq.cme.20260918',
sample_period_s=60,
end_dt=end_dt,
)
trio.run(main)
assert request['endDateTime'] == expected