82 lines
1.9 KiB
Python
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
|