Break test into steps
parent
df868cec35
commit
95b9dacb7a
|
@ -238,6 +238,7 @@ async def open_ems(
|
||||||
mode = 'paper'
|
mode = 'paper'
|
||||||
|
|
||||||
from ._ems import _emsd_main
|
from ._ems import _emsd_main
|
||||||
|
|
||||||
async with (
|
async with (
|
||||||
# connect to emsd
|
# connect to emsd
|
||||||
portal.open_context(
|
portal.open_context(
|
||||||
|
@ -255,7 +256,6 @@ async def open_ems(
|
||||||
dialogs,
|
dialogs,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
||||||
# open 2-way trade command stream
|
# open 2-way trade command stream
|
||||||
ctx.open_stream() as trades_stream,
|
ctx.open_stream() as trades_stream,
|
||||||
):
|
):
|
||||||
|
@ -266,7 +266,6 @@ async def open_ems(
|
||||||
fqsn,
|
fqsn,
|
||||||
trades_stream
|
trades_stream
|
||||||
)
|
)
|
||||||
|
|
||||||
yield (
|
yield (
|
||||||
book,
|
book,
|
||||||
trades_stream,
|
trades_stream,
|
||||||
|
|
|
@ -1351,7 +1351,7 @@ async def maybe_open_trade_relays(
|
||||||
loglevel,
|
loglevel,
|
||||||
)
|
)
|
||||||
yield relay, feed, client_ready
|
yield relay, feed, client_ready
|
||||||
|
print("ABOUT TO OPEN CACHED MNGR")
|
||||||
async with tractor.trionics.maybe_open_context(
|
async with tractor.trionics.maybe_open_context(
|
||||||
acm_func=cached_mngr,
|
acm_func=cached_mngr,
|
||||||
kwargs={
|
kwargs={
|
||||||
|
@ -1365,6 +1365,7 @@ async def maybe_open_trade_relays(
|
||||||
cache_hit,
|
cache_hit,
|
||||||
(relay, feed, client_ready)
|
(relay, feed, client_ready)
|
||||||
):
|
):
|
||||||
|
print("YIELDING RELAY")
|
||||||
yield relay, feed, client_ready
|
yield relay, feed, client_ready
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -978,6 +978,7 @@ def open_pps(
|
||||||
pp.ensure_state()
|
pp.ensure_state()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# breakpoint()
|
||||||
yield table
|
yield table
|
||||||
finally:
|
finally:
|
||||||
if write_on_exit:
|
if write_on_exit:
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
from datetime import datetime
|
|
||||||
import time
|
|
||||||
import trio
|
import trio
|
||||||
import pytest
|
import pytest
|
||||||
import tractor
|
import tractor
|
||||||
|
@ -8,76 +6,72 @@ from piker.log import get_logger
|
||||||
from piker.clearing._messages import (
|
from piker.clearing._messages import (
|
||||||
Order
|
Order
|
||||||
)
|
)
|
||||||
|
from uuid import uuid4
|
||||||
from typing import (
|
from typing import (
|
||||||
AsyncContextManager,
|
AsyncContextManager,
|
||||||
Any,
|
Any,
|
||||||
|
Literal,
|
||||||
)
|
)
|
||||||
|
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from piker.pp import (
|
from piker.pp import (
|
||||||
Position,
|
|
||||||
Transaction,
|
|
||||||
open_trade_ledger,
|
open_trade_ledger,
|
||||||
open_pps
|
open_pps,
|
||||||
|
PpTable
|
||||||
)
|
)
|
||||||
|
|
||||||
from piker._daemon import (
|
|
||||||
find_service,
|
|
||||||
check_for_service,
|
|
||||||
Services,
|
|
||||||
)
|
|
||||||
from piker.data import (
|
|
||||||
open_feed,
|
|
||||||
)
|
|
||||||
from piker.clearing import (
|
from piker.clearing import (
|
||||||
open_ems,
|
open_ems,
|
||||||
)
|
)
|
||||||
from piker.clearing._messages import (
|
|
||||||
BrokerdPosition,
|
|
||||||
Status,
|
|
||||||
)
|
|
||||||
from piker.clearing._client import (
|
from piker.clearing._client import (
|
||||||
OrderBook,
|
OrderBook,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from piker.clearing._messages import (
|
||||||
|
BrokerdPosition
|
||||||
|
)
|
||||||
|
|
||||||
|
from exceptiongroup import BaseExceptionGroup
|
||||||
log = get_logger(__name__)
|
log = get_logger(__name__)
|
||||||
|
|
||||||
_clearing_price: float
|
|
||||||
|
|
||||||
|
|
||||||
def test_paper_trade(
|
def test_paper_trade(
|
||||||
open_test_pikerd: AsyncContextManager
|
open_test_pikerd: AsyncContextManager
|
||||||
):
|
):
|
||||||
_cleared_price: float
|
|
||||||
|
cleared_price: float
|
||||||
test_exec_mode='live'
|
test_exec_mode='live'
|
||||||
test_action = 'buy'
|
|
||||||
test_oid = '560beac8-b1b1-4dee-bd1e-6604a704c9ea'
|
|
||||||
test_account = 'paper'
|
test_account = 'paper'
|
||||||
test_size = 1
|
test_size = 1
|
||||||
test_price = 30000
|
|
||||||
test_broker = 'kraken'
|
test_broker = 'kraken'
|
||||||
test_brokers = [test_broker]
|
test_brokers = [test_broker]
|
||||||
test_symbol = 'xbtusdt'
|
test_symbol = 'xbtusdt'
|
||||||
test_fqsn = f'{test_symbol}.{test_broker}'
|
test_fqsn = f'{test_symbol}.{test_broker}'
|
||||||
test_pp_account = 'piker-paper'
|
test_pp_account = 'piker-paper'
|
||||||
|
positions: dict[
|
||||||
|
# brokername, acctid
|
||||||
|
tuple[str, str],
|
||||||
|
list[BrokerdPosition],
|
||||||
|
]
|
||||||
|
|
||||||
|
async def _async_main(
|
||||||
async def open(
|
|
||||||
open_pikerd: AsyncContextManager,
|
open_pikerd: AsyncContextManager,
|
||||||
send_order: bool = False,
|
action: Literal['buy', 'sell'] | None = None,
|
||||||
|
price: int = 30000,
|
||||||
assert_entries: bool = False,
|
assert_entries: bool = False,
|
||||||
teardown: bool = True,
|
|
||||||
) -> Any:
|
) -> Any:
|
||||||
# type declares
|
|
||||||
book: OrderBook
|
|
||||||
global _cleared_price
|
|
||||||
|
|
||||||
|
oid: str = str(uuid4())
|
||||||
|
book: OrderBook
|
||||||
|
global cleared_price
|
||||||
|
global positions
|
||||||
|
|
||||||
|
# Set up piker and EMS
|
||||||
async with (
|
async with (
|
||||||
open_pikerd() as (_, _, _, services),
|
open_pikerd() as (_, _, _, services),
|
||||||
|
|
||||||
open_ems(
|
open_ems(
|
||||||
'xbtusdt.kraken',
|
test_fqsn,
|
||||||
mode='paper',
|
mode=test_account,
|
||||||
) as (
|
) as (
|
||||||
book,
|
book,
|
||||||
trades_stream,
|
trades_stream,
|
||||||
|
@ -87,67 +81,73 @@ def test_paper_trade(
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
|
|
||||||
|
# Send order to EMS
|
||||||
if send_order:
|
if action:
|
||||||
order = Order(
|
order = Order(
|
||||||
exec_mode=test_exec_mode,
|
exec_mode=test_exec_mode,
|
||||||
action=test_action,
|
action=action,
|
||||||
oid=test_oid,
|
oid=oid,
|
||||||
account=test_account,
|
account=test_account,
|
||||||
size=test_size,
|
size=test_size,
|
||||||
symbol=test_fqsn,
|
symbol=test_fqsn,
|
||||||
price=test_price,
|
price=price,
|
||||||
brokers=test_brokers
|
brokers=test_brokers
|
||||||
)
|
)
|
||||||
|
|
||||||
book.send(order)
|
book.send(order)
|
||||||
|
|
||||||
await trio.sleep(1)
|
await trio.sleep(2)
|
||||||
|
|
||||||
|
# Assert entries are made in both ledger and PPS
|
||||||
if assert_entries:
|
if assert_entries:
|
||||||
|
|
||||||
cleared_ledger_entry = {}
|
cleared_ledger_entry = {}
|
||||||
# check if trades have been updated in in ledge and pp
|
|
||||||
with open_trade_ledger(test_broker, test_account) as ledger:
|
with open_trade_ledger(test_broker, test_account) as ledger:
|
||||||
cleared_ledger_entry = ledger[test_oid]
|
cleared_ledger_entry = ledger[oid]
|
||||||
_cleared_price = cleared_ledger_entry["price"]
|
cleared_price = cleared_ledger_entry["price"]
|
||||||
assert list(ledger.keys())[0] == test_oid
|
|
||||||
|
assert list(ledger.keys())[-1] == oid
|
||||||
assert cleared_ledger_entry['size'] == test_size
|
assert cleared_ledger_entry['size'] == test_size
|
||||||
assert cleared_ledger_entry['fqsn'] == test_fqsn
|
assert cleared_ledger_entry['fqsn'] == test_fqsn
|
||||||
|
|
||||||
|
|
||||||
with open_pps(test_broker, test_pp_account) as table:
|
with open_pps(test_broker, test_pp_account) as table:
|
||||||
# save pps in local state
|
|
||||||
assert table.brokername == test_broker
|
|
||||||
assert table.acctid == test_pp_account
|
|
||||||
# assert cleared_ledger_entry['price'] == table.conf.clears[0].price
|
|
||||||
pp_price = table.conf[test_broker][test_pp_account][test_fqsn]["ppu"]
|
pp_price = table.conf[test_broker][test_pp_account][test_fqsn]["ppu"]
|
||||||
assert math.isclose(pp_price, cleared_ledger_entry['size'], rel_tol=1)
|
assert math.isclose(pp_price, cleared_ledger_entry['size'], rel_tol=1)
|
||||||
|
assert table.brokername == test_broker
|
||||||
|
assert table.acctid == test_pp_account
|
||||||
|
|
||||||
if teardown:
|
positions = pps
|
||||||
|
|
||||||
|
# Close piker like a user would
|
||||||
raise KeyboardInterrupt
|
raise KeyboardInterrupt
|
||||||
return pps
|
|
||||||
|
|
||||||
async def open_and_assert_pps():
|
# Open piker and ensure last pps price is the same as ledger entry
|
||||||
pps = await open(open_test_pikerd)
|
async def _open_and_assert_pps():
|
||||||
assert pps(test_broker, test_account)[0] == _cleared_price
|
await _async_main(open_test_pikerd)
|
||||||
|
assert positions(test_broker, test_account)[-1] == cleared_price
|
||||||
|
|
||||||
|
# Close position and assert empty position in pps
|
||||||
|
async def _close_pp_and_assert():
|
||||||
|
await _async_main(open_test_pikerd, 'sell', 1)
|
||||||
|
with open_pps(test_broker, test_pp_account) as table:
|
||||||
|
assert len(table.pps) == 0
|
||||||
|
|
||||||
|
# run initial time and send sent and assert trade
|
||||||
|
with pytest.raises(
|
||||||
|
BaseExceptionGroup
|
||||||
|
) as exc_info:
|
||||||
|
trio.run(partial(_async_main,
|
||||||
|
open_pikerd=open_test_pikerd,
|
||||||
|
action='buy',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
trio.MultiError
|
BaseExceptionGroup
|
||||||
) as exc_info:
|
) as exc_info:
|
||||||
# run initial time and send sent and assert trade
|
trio.run(_open_and_assert_pps)
|
||||||
trio.run(partial(open,
|
|
||||||
open_pikerd=open_test_pikerd,
|
|
||||||
send_order=True,
|
|
||||||
assert_entries=True,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Run again just to boot piker
|
|
||||||
trio.run(partial(open,
|
|
||||||
open_pikerd=open_test_pikerd,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
trio.run(open_and_assert_pps)
|
|
||||||
|
|
||||||
|
with pytest.raises(
|
||||||
|
BaseExceptionGroup
|
||||||
|
) as exc_info:
|
||||||
|
trio.run(_close_pp_and_assert)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue