Merge pull request #327 from pikers/flexxin
Flexxin: `ib` trade reports parsing basicsupdate_last_datums_in_view
commit
e9f0ea3daa
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue