Async enter/open the symcache in paper engine
Since we don't want to be doing a `trio.run()` from async code (being already in the `tractor` runtime and all); for now just put a top level block wrapping async enter until we figure out to embed it (likely) inside `open_account()` and pass the ref to `open_trade_ledger()`.account_tests
parent
108e8c7082
commit
06c581bfab
|
@ -49,9 +49,10 @@ from ..accounting import (
|
||||||
Transaction,
|
Transaction,
|
||||||
TransactionLedger,
|
TransactionLedger,
|
||||||
open_trade_ledger,
|
open_trade_ledger,
|
||||||
open_pps,
|
open_account,
|
||||||
)
|
)
|
||||||
from ..data import iterticks
|
from ..data import iterticks
|
||||||
|
from ..data._symcache import open_symcache
|
||||||
from ..accounting import unpack_fqme
|
from ..accounting import unpack_fqme
|
||||||
from ._util import (
|
from ._util import (
|
||||||
log, # sub-sys logger
|
log, # sub-sys logger
|
||||||
|
@ -541,141 +542,146 @@ async def open_trade_dialog(
|
||||||
# enable piker.clearing console log for *this* subactor
|
# enable piker.clearing console log for *this* subactor
|
||||||
get_console_log(loglevel)
|
get_console_log(loglevel)
|
||||||
|
|
||||||
acnt: Account
|
async with open_symcache(get_brokermod(broker)) as symcache:
|
||||||
ledger: TransactionLedger
|
acnt: Account
|
||||||
with (
|
ledger: TransactionLedger
|
||||||
open_pps(
|
with (
|
||||||
broker,
|
|
||||||
'paper',
|
|
||||||
write_on_exit=True,
|
|
||||||
) as acnt,
|
|
||||||
|
|
||||||
open_trade_ledger(
|
# TODO: probably do the symcache and ledger loading
|
||||||
broker,
|
# implicitly behind this? Deliver an account, and ledger
|
||||||
'paper',
|
# pair or make the ledger an attr of the account?
|
||||||
) as ledger
|
open_account(
|
||||||
):
|
broker,
|
||||||
# NOTE: retreive market(pair) info from the backend broker
|
'paper',
|
||||||
# since ledger entries (in their backend native format) often
|
write_on_exit=True,
|
||||||
# don't contain necessary market info per trade record entry..
|
) as acnt,
|
||||||
# - if no fqme was passed in, we presume we're running in
|
|
||||||
# "ledger-sync-only mode" and thus we load mkt info for
|
|
||||||
# each symbol found in the ledger to a acnt table manually.
|
|
||||||
|
|
||||||
# TODO: how to process ledger info from backends?
|
open_trade_ledger(
|
||||||
# - should we be rolling our own actor-cached version of these
|
broker,
|
||||||
# client API refs or using portal IPC to send requests to the
|
'paper',
|
||||||
# existing brokerd daemon?
|
symcache=symcache,
|
||||||
# - alternatively we can possibly expect and use
|
) as ledger
|
||||||
# a `.broker.norm_trade_records()` ep?
|
):
|
||||||
brokermod = get_brokermod(broker)
|
# NOTE: retreive market(pair) info from the backend broker
|
||||||
gmi = getattr(brokermod, 'get_mkt_info', None)
|
# since ledger entries (in their backend native format) often
|
||||||
|
# don't contain necessary market info per trade record entry..
|
||||||
|
# - if no fqme was passed in, we presume we're running in
|
||||||
|
# "ledger-sync-only mode" and thus we load mkt info for
|
||||||
|
# each symbol found in the ledger to a acnt table manually.
|
||||||
|
|
||||||
# update all transactions with mkt info before
|
# TODO: how to process ledger info from backends?
|
||||||
# loading any pps
|
# - should we be rolling our own actor-cached version of these
|
||||||
mkt_by_fqme: dict[str, MktPair] = {}
|
# client API refs or using portal IPC to send requests to the
|
||||||
if fqme:
|
# existing brokerd daemon?
|
||||||
bs_fqme, _, broker = fqme.rpartition('.')
|
# - alternatively we can possibly expect and use
|
||||||
mkt, pair = await brokermod.get_mkt_info(bs_fqme)
|
# a `.broker.norm_trade_records()` ep?
|
||||||
mkt_by_fqme[mkt.fqme] = mkt
|
brokermod = get_brokermod(broker)
|
||||||
|
gmi = getattr(brokermod, 'get_mkt_info', None)
|
||||||
|
|
||||||
# for each sym in the ledger load it's `MktPair` info
|
# update all transactions with mkt info before
|
||||||
for tid, txdict in ledger.data.items():
|
# loading any pps
|
||||||
l_fqme: str = txdict.get('fqme') or txdict['fqsn']
|
mkt_by_fqme: dict[str, MktPair] = {}
|
||||||
|
if fqme:
|
||||||
|
bs_fqme, _, broker = fqme.rpartition('.')
|
||||||
|
mkt, pair = await brokermod.get_mkt_info(bs_fqme)
|
||||||
|
mkt_by_fqme[mkt.fqme] = mkt
|
||||||
|
|
||||||
if (
|
# for each sym in the ledger load it's `MktPair` info
|
||||||
gmi
|
for tid, txdict in ledger.data.items():
|
||||||
and l_fqme not in mkt_by_fqme
|
l_fqme: str = txdict.get('fqme') or txdict['fqsn']
|
||||||
):
|
|
||||||
mkt, pair = await gmi(
|
|
||||||
l_fqme.rstrip(f'.{broker}'),
|
|
||||||
)
|
|
||||||
mkt_by_fqme[l_fqme] = mkt
|
|
||||||
|
|
||||||
# if an ``fqme: str`` input was provided we only
|
if (
|
||||||
# need a ``MktPair`` for that one market, since we're
|
gmi
|
||||||
# running in real simulated-clearing mode, not just ledger
|
and l_fqme not in mkt_by_fqme
|
||||||
# syncing.
|
):
|
||||||
if (
|
mkt, pair = await gmi(
|
||||||
fqme is not None
|
l_fqme.rstrip(f'.{broker}'),
|
||||||
and fqme in mkt_by_fqme
|
)
|
||||||
):
|
mkt_by_fqme[l_fqme] = mkt
|
||||||
break
|
|
||||||
|
|
||||||
# update pos table from ledger history and provide a ``MktPair``
|
# if an ``fqme: str`` input was provided we only
|
||||||
# lookup for internal position accounting calcs.
|
# need a ``MktPair`` for that one market, since we're
|
||||||
acnt.update_from_ledger(ledger)
|
# running in real simulated-clearing mode, not just ledger
|
||||||
|
# syncing.
|
||||||
|
if (
|
||||||
|
fqme is not None
|
||||||
|
and fqme in mkt_by_fqme
|
||||||
|
):
|
||||||
|
break
|
||||||
|
|
||||||
pp_msgs: list[BrokerdPosition] = []
|
# update pos table from ledger history and provide a ``MktPair``
|
||||||
pos: Position
|
# lookup for internal position accounting calcs.
|
||||||
token: str # f'{symbol}.{self.broker}'
|
acnt.update_from_ledger(ledger)
|
||||||
for token, pos in acnt.pps.items():
|
|
||||||
pp_msgs.append(BrokerdPosition(
|
pp_msgs: list[BrokerdPosition] = []
|
||||||
broker=broker,
|
pos: Position
|
||||||
account='paper',
|
token: str # f'{symbol}.{self.broker}'
|
||||||
symbol=pos.mkt.fqme,
|
for token, pos in acnt.pps.items():
|
||||||
size=pos.size,
|
pp_msgs.append(BrokerdPosition(
|
||||||
avg_price=pos.ppu,
|
broker=broker,
|
||||||
|
account='paper',
|
||||||
|
symbol=pos.mkt.fqme,
|
||||||
|
size=pos.size,
|
||||||
|
avg_price=pos.ppu,
|
||||||
|
))
|
||||||
|
|
||||||
|
await ctx.started((
|
||||||
|
pp_msgs,
|
||||||
|
['paper'],
|
||||||
))
|
))
|
||||||
|
|
||||||
await ctx.started((
|
# write new positions state in case ledger was
|
||||||
pp_msgs,
|
# newer then that tracked in pps.toml
|
||||||
['paper'],
|
acnt.write_config()
|
||||||
))
|
|
||||||
|
|
||||||
# write new positions state in case ledger was
|
# exit early since no fqme was passed,
|
||||||
# newer then that tracked in pps.toml
|
# normally this case is just to load
|
||||||
acnt.write_config()
|
# positions "offline".
|
||||||
|
if fqme is None:
|
||||||
# exit early since no fqme was passed,
|
log.warning(
|
||||||
# normally this case is just to load
|
'Paper engine only running in position delivery mode!\n'
|
||||||
# positions "offline".
|
'NO SIMULATED CLEARING LOOP IS ACTIVE!'
|
||||||
if fqme is None:
|
)
|
||||||
log.warning(
|
await trio.sleep_forever()
|
||||||
'Paper engine only running in position delivery mode!\n'
|
return
|
||||||
'NO SIMULATED CLEARING LOOP IS ACTIVE!'
|
|
||||||
)
|
|
||||||
await trio.sleep_forever()
|
|
||||||
return
|
|
||||||
|
|
||||||
async with (
|
|
||||||
data.open_feed(
|
|
||||||
[fqme],
|
|
||||||
loglevel=loglevel,
|
|
||||||
) as feed,
|
|
||||||
):
|
|
||||||
# sanity check all the mkt infos
|
|
||||||
for fqme, flume in feed.flumes.items():
|
|
||||||
mkt = mkt_by_fqme[fqme]
|
|
||||||
print(mkt - flume.mkt)
|
|
||||||
assert mkt == flume.mkt
|
|
||||||
|
|
||||||
async with (
|
async with (
|
||||||
ctx.open_stream() as ems_stream,
|
data.open_feed(
|
||||||
trio.open_nursery() as n,
|
[fqme],
|
||||||
|
loglevel=loglevel,
|
||||||
|
) as feed,
|
||||||
):
|
):
|
||||||
client = PaperBoi(
|
# sanity check all the mkt infos
|
||||||
broker=broker,
|
for fqme, flume in feed.flumes.items():
|
||||||
ems_trades_stream=ems_stream,
|
mkt = mkt_by_fqme[fqme]
|
||||||
acnt=acnt,
|
assert mkt == flume.mkt
|
||||||
ledger=ledger,
|
|
||||||
|
|
||||||
_buys=_buys,
|
async with (
|
||||||
_sells=_sells,
|
ctx.open_stream() as ems_stream,
|
||||||
_reqids=_reqids,
|
trio.open_nursery() as n,
|
||||||
|
):
|
||||||
|
client = PaperBoi(
|
||||||
|
broker=broker,
|
||||||
|
ems_trades_stream=ems_stream,
|
||||||
|
acnt=acnt,
|
||||||
|
ledger=ledger,
|
||||||
|
|
||||||
_mkts=mkt_by_fqme,
|
_buys=_buys,
|
||||||
|
_sells=_sells,
|
||||||
|
_reqids=_reqids,
|
||||||
|
|
||||||
)
|
_mkts=mkt_by_fqme,
|
||||||
|
|
||||||
n.start_soon(
|
)
|
||||||
handle_order_requests,
|
|
||||||
client,
|
|
||||||
ems_stream,
|
|
||||||
)
|
|
||||||
|
|
||||||
# paper engine simulator clearing task
|
n.start_soon(
|
||||||
await simulate_fills(feed.streams[broker], client)
|
handle_order_requests,
|
||||||
|
client,
|
||||||
|
ems_stream,
|
||||||
|
)
|
||||||
|
|
||||||
|
# paper engine simulator clearing task
|
||||||
|
await simulate_fills(feed.streams[broker], client)
|
||||||
|
|
||||||
|
|
||||||
@acm
|
@acm
|
||||||
|
|
Loading…
Reference in New Issue