Better doc strings and detailed comments
parent
ce1eb11b59
commit
de77c7d209
|
@ -312,9 +312,14 @@ async def trades_dialogue(
|
||||||
accounts.add(account)
|
accounts.add(account)
|
||||||
|
|
||||||
pp_msgs = {}
|
pp_msgs = {}
|
||||||
|
|
||||||
|
# process pp value reported from ib's system. we only use these
|
||||||
|
# to cross-check sizing since average pricing on their end uses
|
||||||
|
# the so called (bs) "FIFO" style which more or less results in
|
||||||
|
# a price that's not useful for traders who want to not lose
|
||||||
|
# money.. xb
|
||||||
for client in aioclients.values():
|
for client in aioclients.values():
|
||||||
for pos in client.positions():
|
for pos in client.positions():
|
||||||
|
|
||||||
msg = pack_position(pos)
|
msg = pack_position(pos)
|
||||||
msg.account = accounts_def.inverse[msg.account]
|
msg.account = accounts_def.inverse[msg.account]
|
||||||
pp_msgs[msg.symbol] = msg
|
pp_msgs[msg.symbol] = msg
|
||||||
|
@ -322,8 +327,14 @@ async def trades_dialogue(
|
||||||
assert msg.account in accounts, (
|
assert msg.account in accounts, (
|
||||||
f'Position for unknown account: {msg.account}')
|
f'Position for unknown account: {msg.account}')
|
||||||
|
|
||||||
|
# built-out piker pps from trade ledger, underneath using
|
||||||
|
# LIFO style breakeven pricing calcs.
|
||||||
trades_by_account: dict = {}
|
trades_by_account: dict = {}
|
||||||
conf = get_config()
|
conf = get_config()
|
||||||
|
|
||||||
|
# retreive new trade executions from the last session
|
||||||
|
# and/or day's worth of trading and convert into trade
|
||||||
|
# records suitable for a local ledger file.
|
||||||
for proxy in proxies.values():
|
for proxy in proxies.values():
|
||||||
trade_entries = await proxy.trades()
|
trade_entries = await proxy.trades()
|
||||||
records = trades_to_records(
|
records = trades_to_records(
|
||||||
|
@ -332,18 +343,27 @@ async def trades_dialogue(
|
||||||
)
|
)
|
||||||
trades_by_account.update(records)
|
trades_by_account.update(records)
|
||||||
|
|
||||||
|
# write recent session's trades to the user's (local) ledger
|
||||||
|
# file.
|
||||||
for acctid, trades_by_id in trades_by_account.items():
|
for acctid, trades_by_id in trades_by_account.items():
|
||||||
with config.open_trade_ledger('ib', acctid) as ledger:
|
with config.open_trade_ledger('ib', acctid) as ledger:
|
||||||
ledger.update(trades_by_id)
|
ledger.update(trades_by_id)
|
||||||
|
|
||||||
|
# (incrementally) update the user's pps in mem and
|
||||||
|
# in the `pps.toml`.
|
||||||
records = norm_trade_records(trades_by_id)
|
records = norm_trade_records(trades_by_id)
|
||||||
active = update_pps_conf('ib', acctid, records)
|
active = update_pps_conf('ib', acctid, records)
|
||||||
|
|
||||||
|
# relay re-formatted pps as msgs to the ems.
|
||||||
for fqsn, pp in active.items():
|
for fqsn, pp in active.items():
|
||||||
|
|
||||||
ibppmsg = pp_msgs[fqsn.rstrip('.ib')]
|
ibppmsg = pp_msgs[fqsn.rstrip('.ib')]
|
||||||
msg = BrokerdPosition(
|
msg = BrokerdPosition(
|
||||||
broker='ib',
|
broker='ib',
|
||||||
# account=acctid + '.ib',
|
# account=acctid + '.ib',
|
||||||
|
# XXX: ok so this is annoying, we're relaying
|
||||||
|
# an account name with the backend suffix prefixed
|
||||||
|
# but when reading accounts from ledgers
|
||||||
account=ibppmsg.account,
|
account=ibppmsg.account,
|
||||||
# XXX: the `.ib` is stripped..?
|
# XXX: the `.ib` is stripped..?
|
||||||
symbol=ibppmsg.symbol,
|
symbol=ibppmsg.symbol,
|
||||||
|
@ -614,6 +634,7 @@ def norm_trade_records(
|
||||||
|
|
||||||
|
|
||||||
def trades_to_records(
|
def trades_to_records(
|
||||||
|
|
||||||
accounts: bidict,
|
accounts: bidict,
|
||||||
trade_entries: list[object],
|
trade_entries: list[object],
|
||||||
source_type: str = 'api',
|
source_type: str = 'api',
|
||||||
|
|
40
piker/pp.py
40
piker/pp.py
|
@ -21,7 +21,6 @@ that doesn't try to cuk most humans who prefer to not lose their moneys..
|
||||||
|
|
||||||
'''
|
'''
|
||||||
from typing import (
|
from typing import (
|
||||||
Any,
|
|
||||||
Optional,
|
Optional,
|
||||||
Union,
|
Union,
|
||||||
)
|
)
|
||||||
|
@ -153,14 +152,15 @@ def update_pps(
|
||||||
Compile a set of positions from a trades ledger.
|
Compile a set of positions from a trades ledger.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
pps: dict[str, Position] = pps or {}
|
pps: dict[str, Position] = pps or {}
|
||||||
|
|
||||||
# lifo update all pps from records
|
# lifo update all pps from records
|
||||||
for r in records:
|
for r in records:
|
||||||
key = r.fqsn or r.symkey
|
|
||||||
pp = pps.setdefault(
|
pp = pps.setdefault(
|
||||||
key,
|
r.fqsn or r.symkey,
|
||||||
|
|
||||||
|
# if no existing pp, allocate fresh one.
|
||||||
Position(
|
Position(
|
||||||
Symbol.from_fqsn(
|
Symbol.from_fqsn(
|
||||||
r.fqsn,
|
r.fqsn,
|
||||||
|
@ -173,6 +173,11 @@ def update_pps(
|
||||||
# don't do updates for ledger records we already have
|
# don't do updates for ledger records we already have
|
||||||
# included in the current pps state.
|
# included in the current pps state.
|
||||||
if r.tid in pp.fills:
|
if r.tid in pp.fills:
|
||||||
|
# NOTE: likely you'll see repeats of the same
|
||||||
|
# ``TradeRecord`` passed in here if/when you are restarting
|
||||||
|
# a ``brokerd.ib`` where the API will re-report trades from
|
||||||
|
# the current session, so we need to make sure we don't
|
||||||
|
# "double count" these in pp calculations.
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# lifo style average price calc
|
# lifo style average price calc
|
||||||
|
@ -187,7 +192,16 @@ def _split_active(
|
||||||
pps: dict[str, Position],
|
pps: dict[str, Position],
|
||||||
|
|
||||||
) -> tuple[dict, dict]:
|
) -> tuple[dict, dict]:
|
||||||
|
'''
|
||||||
|
Split pps into those that are "active" (non-zero size) and "closed"
|
||||||
|
(zero size) and return in 2 dicts.
|
||||||
|
|
||||||
|
Returning the "closed" set is important for updating the pps state
|
||||||
|
in any ``pps.toml`` such that we remove entries which are no longer
|
||||||
|
part of any "VaR" set (well presumably, except of course your liquidity
|
||||||
|
asset could be full of "risk" XD ).
|
||||||
|
|
||||||
|
'''
|
||||||
active = {}
|
active = {}
|
||||||
closed = {}
|
closed = {}
|
||||||
|
|
||||||
|
@ -207,8 +221,14 @@ def load_pps_from_ledger(
|
||||||
brokername: str,
|
brokername: str,
|
||||||
acctname: str,
|
acctname: str,
|
||||||
|
|
||||||
) -> dict[str, Any]:
|
) -> tuple[dict, dict]:
|
||||||
|
'''
|
||||||
|
Open a ledger file by broker name and account and read in and
|
||||||
|
process any trade records into our normalized ``TradeRecord``
|
||||||
|
form and then pass these into the position processing routine
|
||||||
|
and deliver the two dict-sets of the active and closed pps.
|
||||||
|
|
||||||
|
'''
|
||||||
with config.open_trade_ledger(
|
with config.open_trade_ledger(
|
||||||
brokername,
|
brokername,
|
||||||
acctname,
|
acctname,
|
||||||
|
@ -217,10 +237,8 @@ def load_pps_from_ledger(
|
||||||
|
|
||||||
brokermod = get_brokermod(brokername)
|
brokermod = get_brokermod(brokername)
|
||||||
records = brokermod.norm_trade_records(ledger)
|
records = brokermod.norm_trade_records(ledger)
|
||||||
pps = update_pps(
|
pps = update_pps(brokername, records)
|
||||||
brokername,
|
|
||||||
records,
|
|
||||||
)
|
|
||||||
return _split_active(pps)
|
return _split_active(pps)
|
||||||
|
|
||||||
|
|
||||||
|
@ -282,14 +300,12 @@ def update_pps_conf(
|
||||||
config.write(
|
config.write(
|
||||||
conf,
|
conf,
|
||||||
'pps',
|
'pps',
|
||||||
|
# TODO: make nested tables and/or inline tables work?
|
||||||
# encoder=config.toml.Encoder(preserve=True),
|
# encoder=config.toml.Encoder(preserve=True),
|
||||||
)
|
)
|
||||||
|
|
||||||
return active
|
return active
|
||||||
|
|
||||||
# from pprint import pprint
|
|
||||||
# pprint(conf)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
update_pps_conf('ib', 'algopaper')
|
update_pps_conf('ib', 'algopaper')
|
||||||
|
|
Loading…
Reference in New Issue