Add 1m ohlc sample rate support to `Client.bars()`; frame query is 1 day
parent
5144299f4f
commit
1adf5fb9c0
|
@ -78,26 +78,11 @@ _time_units = {
|
||||||
'h': ' hours',
|
'h': ' hours',
|
||||||
}
|
}
|
||||||
|
|
||||||
_time_frames = {
|
_bar_sizes = {
|
||||||
'1s': '1 Sec',
|
1: '1 Sec',
|
||||||
'5s': '5 Sec',
|
60: '1 min',
|
||||||
'30s': '30 Sec',
|
60*60: '1 hour',
|
||||||
'1m': 'OneMinute',
|
24*60*60: '1 day',
|
||||||
'2m': 'TwoMinutes',
|
|
||||||
'3m': 'ThreeMinutes',
|
|
||||||
'4m': 'FourMinutes',
|
|
||||||
'5m': 'FiveMinutes',
|
|
||||||
'10m': 'TenMinutes',
|
|
||||||
'15m': 'FifteenMinutes',
|
|
||||||
'20m': 'TwentyMinutes',
|
|
||||||
'30m': 'HalfHour',
|
|
||||||
'1h': 'OneHour',
|
|
||||||
'2h': 'TwoHours',
|
|
||||||
'4h': 'FourHours',
|
|
||||||
'D': 'OneDay',
|
|
||||||
'W': 'OneWeek',
|
|
||||||
'M': 'OneMonth',
|
|
||||||
'Y': 'OneYear',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_show_wap_in_history: bool = False
|
_show_wap_in_history: bool = False
|
||||||
|
@ -338,19 +323,36 @@ class Client:
|
||||||
start_dt: Union[datetime, str] = "1970-01-01T00:00:00.000000-05:00",
|
start_dt: Union[datetime, str] = "1970-01-01T00:00:00.000000-05:00",
|
||||||
end_dt: Union[datetime, str] = "",
|
end_dt: Union[datetime, str] = "",
|
||||||
|
|
||||||
sample_period_s: str = 1, # ohlc sample period
|
# ohlc sample period in seconds
|
||||||
period_count: int = int(2e3), # <- max per 1s sample query
|
sample_period_s: int = 1,
|
||||||
|
|
||||||
) -> list[dict[str, Any]]:
|
) -> list[dict[str, Any]]:
|
||||||
'''
|
'''
|
||||||
Retreive OHLCV bars for a fqsn over a range to the present.
|
Retreive OHLCV bars for a fqsn over a range to the present.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
# See API docs here:
|
||||||
|
# https://interactivebrokers.github.io/tws-api/historical_data.html
|
||||||
bars_kwargs = {'whatToShow': 'TRADES'}
|
bars_kwargs = {'whatToShow': 'TRADES'}
|
||||||
|
|
||||||
|
# NOTE: pacing violations exist for higher sample rates:
|
||||||
|
# https://interactivebrokers.github.io/tws-api/historical_limitations.html#pacing_violations
|
||||||
|
# Also see note on duration limits being lifted on 1m+ periods,
|
||||||
|
# but they say "use with discretion":
|
||||||
|
# https://interactivebrokers.github.io/tws-api/historical_limitations.html#non-available_hd
|
||||||
|
bar_size, duration = {
|
||||||
|
1: ('1 secs', f'{int(2e3)} S'),
|
||||||
|
# TODO: benchmark >1 D duration on query to see if
|
||||||
|
# throughput can be made faster during backfilling.
|
||||||
|
60: ('1 min', '1 D'),
|
||||||
|
}[sample_period_s]
|
||||||
|
|
||||||
global _enters
|
global _enters
|
||||||
# log.info(f'REQUESTING BARS {_enters} @ end={end_dt}')
|
# log.info(f'REQUESTING BARS {_enters} @ end={end_dt}')
|
||||||
print(f'REQUESTING BARS {_enters} @ end={end_dt}')
|
print(
|
||||||
|
f"REQUESTING {duration}'s worth {bar_size} BARS\n"
|
||||||
|
f'{_enters} @ end={end_dt}"'
|
||||||
|
)
|
||||||
|
|
||||||
if not end_dt:
|
if not end_dt:
|
||||||
end_dt = ''
|
end_dt = ''
|
||||||
|
@ -360,30 +362,20 @@ class Client:
|
||||||
contract = (await self.find_contracts(fqsn))[0]
|
contract = (await self.find_contracts(fqsn))[0]
|
||||||
bars_kwargs.update(getattr(contract, 'bars_kwargs', {}))
|
bars_kwargs.update(getattr(contract, 'bars_kwargs', {}))
|
||||||
|
|
||||||
# _min = min(2000*100, count)
|
|
||||||
bars = await self.ib.reqHistoricalDataAsync(
|
bars = await self.ib.reqHistoricalDataAsync(
|
||||||
contract,
|
contract,
|
||||||
endDateTime=end_dt,
|
endDateTime=end_dt,
|
||||||
formatDate=2,
|
formatDate=2,
|
||||||
|
|
||||||
# time history length values format:
|
|
||||||
# ``durationStr=integer{SPACE}unit (S|D|W|M|Y)``
|
|
||||||
|
|
||||||
# OHLC sampling values:
|
# OHLC sampling values:
|
||||||
# 1 secs, 5 secs, 10 secs, 15 secs, 30 secs, 1 min, 2 mins,
|
# 1 secs, 5 secs, 10 secs, 15 secs, 30 secs, 1 min, 2 mins,
|
||||||
# 3 mins, 5 mins, 10 mins, 15 mins, 20 mins, 30 mins,
|
# 3 mins, 5 mins, 10 mins, 15 mins, 20 mins, 30 mins,
|
||||||
# 1 hour, 2 hours, 3 hours, 4 hours, 8 hours, 1 day, 1W, 1M
|
# 1 hour, 2 hours, 3 hours, 4 hours, 8 hours, 1 day, 1W, 1M
|
||||||
# barSizeSetting='1 secs',
|
barSizeSetting=bar_size,
|
||||||
|
|
||||||
# durationStr='{count} S'.format(count=15000 * 5),
|
# time history length values format:
|
||||||
# durationStr='{count} D'.format(count=1),
|
# ``durationStr=integer{SPACE}unit (S|D|W|M|Y)``
|
||||||
# barSizeSetting='5 secs',
|
durationStr=duration,
|
||||||
|
|
||||||
durationStr='{count} S'.format(count=period_count),
|
|
||||||
# barSizeSetting='5 secs',
|
|
||||||
barSizeSetting='1 secs',
|
|
||||||
|
|
||||||
# barSizeSetting='1 min',
|
|
||||||
|
|
||||||
# always use extended hours
|
# always use extended hours
|
||||||
useRTH=False,
|
useRTH=False,
|
||||||
|
@ -394,8 +386,8 @@ class Client:
|
||||||
# whatToShow='TRADES',
|
# whatToShow='TRADES',
|
||||||
)
|
)
|
||||||
if not bars:
|
if not bars:
|
||||||
# TODO: raise underlying error here
|
# trigger ``NoData`` raise by ``get_bars()`` caller.
|
||||||
raise ValueError(f"No bars retreived for {fqsn}?")
|
return None
|
||||||
|
|
||||||
nparr = bars_to_np(bars)
|
nparr = bars_to_np(bars)
|
||||||
return bars, nparr
|
return bars, nparr
|
||||||
|
|
Loading…
Reference in New Issue