Better doc strings and detailed comments
							parent
							
								
									ce1eb11b59
								
							
						
					
					
						commit
						de77c7d209
					
				|  | @ -312,9 +312,14 @@ async def trades_dialogue( | |||
|             accounts.add(account) | ||||
| 
 | ||||
|         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 pos in client.positions(): | ||||
| 
 | ||||
|                 msg = pack_position(pos) | ||||
|                 msg.account = accounts_def.inverse[msg.account] | ||||
|                 pp_msgs[msg.symbol] = msg | ||||
|  | @ -322,8 +327,14 @@ async def trades_dialogue( | |||
|                 assert msg.account in accounts, ( | ||||
|                     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 = {} | ||||
|         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(): | ||||
|             trade_entries = await proxy.trades() | ||||
|             records = trades_to_records( | ||||
|  | @ -332,18 +343,27 @@ async def trades_dialogue( | |||
|             ) | ||||
|             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(): | ||||
|             with config.open_trade_ledger('ib', acctid) as ledger: | ||||
|                 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) | ||||
|             active = update_pps_conf('ib', acctid, records) | ||||
| 
 | ||||
|             # relay re-formatted pps as msgs to the ems. | ||||
|             for fqsn, pp in active.items(): | ||||
| 
 | ||||
|                 ibppmsg = pp_msgs[fqsn.rstrip('.ib')] | ||||
|                 msg = BrokerdPosition( | ||||
|                     broker='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, | ||||
|                     # XXX: the `.ib` is stripped..? | ||||
|                     symbol=ibppmsg.symbol, | ||||
|  | @ -614,6 +634,7 @@ def norm_trade_records( | |||
| 
 | ||||
| 
 | ||||
| def trades_to_records( | ||||
| 
 | ||||
|     accounts: bidict, | ||||
|     trade_entries: list[object], | ||||
|     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 ( | ||||
|     Any, | ||||
|     Optional, | ||||
|     Union, | ||||
| ) | ||||
|  | @ -153,14 +152,15 @@ def update_pps( | |||
|     Compile a set of positions from a trades ledger. | ||||
| 
 | ||||
|     ''' | ||||
| 
 | ||||
|     pps: dict[str, Position] = pps or {} | ||||
| 
 | ||||
|     # lifo update all pps from records | ||||
|     for r in records: | ||||
|         key = r.fqsn or r.symkey | ||||
| 
 | ||||
|         pp = pps.setdefault( | ||||
|             key, | ||||
|             r.fqsn or r.symkey, | ||||
| 
 | ||||
|             # if no existing pp, allocate fresh one. | ||||
|             Position( | ||||
|                 Symbol.from_fqsn( | ||||
|                     r.fqsn, | ||||
|  | @ -173,6 +173,11 @@ def update_pps( | |||
|         # don't do updates for ledger records we already have | ||||
|         # included in the current pps state. | ||||
|         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 | ||||
| 
 | ||||
|         # lifo style average price calc | ||||
|  | @ -187,7 +192,16 @@ def _split_active( | |||
|     pps: dict[str, Position], | ||||
| 
 | ||||
| ) -> 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 = {} | ||||
|     closed = {} | ||||
| 
 | ||||
|  | @ -207,8 +221,14 @@ def load_pps_from_ledger( | |||
|     brokername: 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( | ||||
|         brokername, | ||||
|         acctname, | ||||
|  | @ -217,10 +237,8 @@ def load_pps_from_ledger( | |||
| 
 | ||||
|     brokermod = get_brokermod(brokername) | ||||
|     records = brokermod.norm_trade_records(ledger) | ||||
|     pps = update_pps( | ||||
|         brokername, | ||||
|         records, | ||||
|     ) | ||||
|     pps = update_pps(brokername, records) | ||||
| 
 | ||||
|     return _split_active(pps) | ||||
| 
 | ||||
| 
 | ||||
|  | @ -282,14 +300,12 @@ def update_pps_conf( | |||
|     config.write( | ||||
|         conf, | ||||
|         'pps', | ||||
|         # TODO: make nested tables and/or inline tables work? | ||||
|         # encoder=config.toml.Encoder(preserve=True), | ||||
|     ) | ||||
| 
 | ||||
|     return active | ||||
| 
 | ||||
|     # from pprint import pprint | ||||
|     # pprint(conf) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     update_pps_conf('ib', 'algopaper') | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue