Merge pull request #327 from pikers/flexxin

Flexxin: `ib` trade reports parsing basics
update_last_datums_in_view
goodboy 2022-06-07 09:42:54 -04:00 committed by GitHub
commit e9f0ea3daa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 94 additions and 4 deletions

View File

@ -26,6 +26,13 @@ ports = [
7497, # tws 7497, # tws
] ]
# XXX: for a paper account the flex web query service
# is not supported so you have to manually download
# and XML report and put it in a location that can be
# accessed by the ``brokerd.ib`` backend code for parsing.
flex_token = '666666666666666666666666'
flex_trades_query_id = '666666' # live account
# when clients are being scanned this determines # when clients are being scanned this determines
# which clients are preferred to be used for data # which clients are preferred to be used for data
# feeds based on the order of account names, if # feeds based on the order of account names, if

View File

@ -780,23 +780,29 @@ class Client:
) -> None: ) -> None:
log.error(errorString)
reason = errorString reason = errorString
if reqId == -1: if reqId == -1:
# it's a general event? # it's a general event?
key = 'event' key = 'event'
log.info(errorString)
else: else:
key = 'error' key = 'error'
log.error(errorString)
try: try:
to_trio.send_nowait(( to_trio.send_nowait((
key, key,
# error "object" # error "object"
{'reqid': reqId, {
'reason': reason, 'type': key,
'contract': contract} 'reqid': reqId,
'reason': reason,
'error_code': errorCode,
'contract': contract,
}
)) ))
except trio.BrokenResourceError: except trio.BrokenResourceError:
# XXX: eventkit's ``Event.emit()`` for whatever redic # XXX: eventkit's ``Event.emit()`` for whatever redic
@ -2248,6 +2254,7 @@ async def trades_dialogue(
recv_trade_updates, recv_trade_updates,
client=client, client=client,
) as (first, trade_event_stream): ) as (first, trade_event_stream):
task_status.started(trade_event_stream) task_status.started(trade_event_stream)
await trio.sleep_forever() await trio.sleep_forever()
@ -2614,3 +2621,79 @@ async def data_reset_hack(
# we don't really need the ``xdotool`` approach any more B) # we don't really need the ``xdotool`` approach any more B)
return True return True
def load_flex_trades(
path: Optional[str] = None,
) -> dict[str, str]:
from pprint import pprint
from ib_insync import flexreport, util
conf = get_config()
if not path:
# load ``brokers.toml`` and try to get the flex
# token and query id that must be previously defined
# by the user.
token = conf.get('flex_token')
if not token:
raise ValueError(
'You must specify a ``flex_token`` field in your'
'`brokers.toml` in order load your trade log, see our'
'intructions for how to set this up here:\n'
'PUT LINK HERE!'
)
qid = conf['flex_trades_query_id']
# TODO: hack this into our logging
# system like we do with the API client..
util.logToConsole()
# TODO: rewrite the query part of this with async..httpx?
report = flexreport.FlexReport(
token=token,
queryId=qid,
)
else:
# XXX: another project we could potentially look at,
# https://pypi.org/project/ibflex/
report = flexreport.FlexReport(path=path)
trade_entries = report.extract('Trade')
trades = {
# XXX: LOL apparently ``toml`` has a bug
# where a section key error will show up in the write
# if you leave this as an ``int``?
str(t.__dict__['tradeID']): t.__dict__
for t in trade_entries
}
ln = len(trades)
log.info(f'Loaded {ln} trades from flex query')
trades_by_account = {}
for tid, trade in trades.items():
trades_by_account.setdefault(
# oddly for some so-called "BookTrade" entries
# this field seems to be blank, no cuckin clue.
# trade['ibExecID']
str(trade['accountId']), {}
)[tid] = trade
section = {'ib': trades_by_account}
pprint(section)
# TODO: load the config first and append in
# the new trades loaded here..
try:
config.write(section, 'trades')
except KeyError:
import pdbpp; pdbpp.set_trace()
if __name__ == '__main__':
load_flex_trades()