Reformat fake fill in paper engine,
Ensure tests pass, refactor test wrapperexplicit_write_pps_on_exit
							parent
							
								
									c99381216d
								
							
						
					
					
						commit
						e54d928405
					
				|  | @ -260,22 +260,16 @@ class PaperBoi(Struct): | |||
|             bsuid=key, | ||||
|         ) | ||||
| 
 | ||||
|         # Update in memory ledger per trade | ||||
|         ledger_entry = {oid: t.to_dict()} | ||||
| 
 | ||||
|         # Store txn in state for PP update | ||||
|         self._txn_dict[oid] = t | ||||
|         self._trade_ledger.update(ledger_entry) | ||||
| 
 | ||||
|         # Write to ledger toml right now | ||||
|         with open_trade_ledger(self.broker, 'paper') as ledger: | ||||
|             ledger.update(self._trade_ledger) | ||||
| 
 | ||||
|         # Write to pps toml right now | ||||
|         with open_pps(self.broker, 'piker-paper') as table: | ||||
|             table.update_from_trans(self._txn_dict) | ||||
|             # save pps in local state | ||||
|             self._positions = table.pps | ||||
|         with ( | ||||
|                 open_trade_ledger(self.broker, 'paper') as ledger, | ||||
|                 open_pps(self.broker, 'piker-paper') as table | ||||
|              ): | ||||
|                 ledger.update({oid: t.to_dict()}) | ||||
|                 # Write to pps toml right now | ||||
|                 table.update_from_trans({oid: t}) | ||||
|                 # save pps in local state | ||||
|                 self._positions.update(table.pps) | ||||
| 
 | ||||
|         # Ensure we have the latest positioning data when sending pp_msg | ||||
|         pp = self._positions[key] | ||||
|  |  | |||
|  | @ -78,7 +78,8 @@ def get_app_dir(app_name, roaming=True, force_posix=False): | |||
|     # within the tractor runtimes and store testing config data | ||||
|     # outside of the users filesystem  | ||||
|     if "pytest" in sys.modules: | ||||
|         app_name += TEST_CONFIG_DIR_PATH | ||||
|         log.info("TESTING") | ||||
|         os.path.join(app_name, TEST_CONFIG_DIR_PATH) | ||||
| 
 | ||||
|     # if WIN: | ||||
|     if platform.system() == 'Windows': | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| """ | ||||
| ''' | ||||
| Paper-mode testing | ||||
| """ | ||||
| ''' | ||||
| 
 | ||||
| import trio | ||||
| import math | ||||
|  | @ -22,6 +22,7 @@ from piker.config import get_app_dir | |||
| from piker.log import get_logger | ||||
| from piker.clearing._messages import Order | ||||
| from piker.pp import ( | ||||
|     PpTable, | ||||
|     open_trade_ledger, | ||||
|     open_pps, | ||||
| ) | ||||
|  | @ -36,31 +37,33 @@ from piker.clearing._messages import BrokerdPosition | |||
| 
 | ||||
| log = get_logger(__name__) | ||||
| 
 | ||||
| @pytest.fixture(scope="module") | ||||
| 
 | ||||
| @pytest.fixture(scope='module') | ||||
| def delete_testing_dir(): | ||||
|     '''This fixture removes the temp directory | ||||
|     used for storing all config/ledger/pp data | ||||
|     created during testing sessions | ||||
|     ''' | ||||
|     yield | ||||
|     app_dir = Path(get_app_dir("piker")).resolve() | ||||
|     app_dir = Path(get_app_dir('piker')).resolve() | ||||
|     if app_dir.is_dir(): | ||||
|         rmtree(str(app_dir)) | ||||
|         assert not app_dir.is_dir() | ||||
| 
 | ||||
| 
 | ||||
| def get_fqsn(broker, symbol): | ||||
|     fqsn = f"{symbol}.{broker}" | ||||
|     fqsn = f'{symbol}.{broker}' | ||||
|     return (fqsn, symbol, broker) | ||||
| 
 | ||||
| 
 | ||||
| def test_paper_trade(open_test_pikerd: AsyncContextManager): | ||||
|     cleared_price: float | ||||
|     test_exec_mode = "live" | ||||
|     test_account = "paper" | ||||
|     oid = '' | ||||
|     test_exec_mode = 'live' | ||||
|     test_account = 'paper' | ||||
|     test_size = 1 | ||||
|     (fqsn, symbol, broker) = get_fqsn("kraken", "xbtusdt") | ||||
|     (fqsn, symbol, broker) = get_fqsn('kraken', 'xbtusdt') | ||||
|     brokers = [broker] | ||||
|     test_pp_account = "piker-paper" | ||||
|     test_pp_account = 'piker-paper' | ||||
|     positions: dict[ | ||||
|         # brokername, acctid | ||||
|         tuple[str, str], | ||||
|  | @ -69,7 +72,7 @@ def test_paper_trade(open_test_pikerd: AsyncContextManager): | |||
| 
 | ||||
|     async def _async_main( | ||||
|         open_pikerd: AsyncContextManager, | ||||
|         action: Literal["buy", "sell"] | None = None, | ||||
|         action: Literal['buy', 'sell'] | None = None, | ||||
|         price: int = 30000, | ||||
|         assert_entries: bool = False, | ||||
|     ) -> None: | ||||
|  | @ -78,16 +81,14 @@ def test_paper_trade(open_test_pikerd: AsyncContextManager): | |||
|         that pps from previous trade exists in the ems pps. | ||||
|         Finally close the position and ensure that the position in pps.toml is closed. | ||||
|         ''' | ||||
| 
 | ||||
|         oid: str = str(uuid4()) | ||||
|         nonlocal oid | ||||
|         book: OrderBook | ||||
|         nonlocal cleared_price | ||||
|         nonlocal positions | ||||
| 
 | ||||
|         # Set up piker and EMS | ||||
|         async with ( | ||||
|             open_pikerd() as (_, _, _, services), | ||||
|             open_ems(fqsn, mode="paper") as ( | ||||
|             open_ems(fqsn, mode='paper') as ( | ||||
|                 book, | ||||
|                 trades_stream, | ||||
|                 pps, | ||||
|  | @ -97,6 +98,7 @@ def test_paper_trade(open_test_pikerd: AsyncContextManager): | |||
|         ): | ||||
|             # Send order to EMS | ||||
|             if action: | ||||
|                 oid = str(uuid4()) | ||||
|                 order = Order( | ||||
|                     exec_mode=test_exec_mode, | ||||
|                     action=action, | ||||
|  | @ -118,17 +120,15 @@ def test_paper_trade(open_test_pikerd: AsyncContextManager): | |||
|                 cleared_ledger_entry = {} | ||||
|                 with open_trade_ledger(broker, test_account) as ledger: | ||||
|                     cleared_ledger_entry = ledger[oid] | ||||
|                     cleared_price = cleared_ledger_entry["price"] | ||||
| 
 | ||||
|                     assert list(ledger.keys())[-1] == oid | ||||
|                     assert cleared_ledger_entry["size"] == test_size | ||||
|                     assert cleared_ledger_entry["fqsn"] == fqsn | ||||
|                     assert cleared_ledger_entry['size'] == test_size | ||||
|                     assert cleared_ledger_entry['fqsn'] == fqsn | ||||
| 
 | ||||
|                 with open_pps(broker, test_pp_account) as table: | ||||
|                     pp_price = table.conf[broker][test_pp_account][fqsn]["ppu"] | ||||
|                     pp_price = table.conf[broker][test_pp_account][fqsn]['ppu'] | ||||
|                     # Ensure the price-per-unit (breakeven) price is close to our clearing price | ||||
|                     assert math.isclose( | ||||
|                         pp_price, cleared_ledger_entry["size"], rel_tol=1 | ||||
|                         pp_price, cleared_ledger_entry['size'], rel_tol=1 | ||||
|                     ) | ||||
|                     assert table.brokername == broker | ||||
|                     assert table.acctid == test_pp_account | ||||
|  | @ -140,62 +140,78 @@ def test_paper_trade(open_test_pikerd: AsyncContextManager): | |||
| 
 | ||||
|     # Open piker load pps locally | ||||
|     # and ensure last pps price is the same as ledger entry | ||||
|     async def _open_and_assert_pps(): | ||||
|         await _async_main(open_test_pikerd) | ||||
|         assert positions(broker, test_account)[-1] == cleared_price | ||||
|     def _assert_pps(ledger, table): | ||||
|         return ( | ||||
|             positions[(broker, test_account)][-1]['avg_price'] == ledger[oid]['price'] | ||||
|         ) | ||||
| 
 | ||||
|     def _assert_no_pps(ledger, table): | ||||
|         return len(table.pps) == 0 | ||||
| 
 | ||||
|     # 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(broker, test_pp_account) as table: | ||||
|             assert len(table.pps) == 0 | ||||
| 
 | ||||
|     def _run_test_and_check(exception, fn): | ||||
|     def _run_test_and_check(exception, fn, assert_cb=None): | ||||
|         with pytest.raises(exception) as exc_info: | ||||
|             trio.run(fn) | ||||
| 
 | ||||
|         for exception in exc_info.value.exceptions: | ||||
|             assert isinstance(exception, KeyboardInterrupt) or isinstance( | ||||
|                 exception, ContextCancelled | ||||
|             ) | ||||
|         with ( | ||||
|             open_trade_ledger(broker, test_account) as ledger, | ||||
|             open_pps(broker, test_pp_account) as table, | ||||
|         ): | ||||
|             if assert_cb: | ||||
|                 assert assert_cb(ledger, table) | ||||
| 
 | ||||
|     # Send and execute a trade and assert trade | ||||
|             for exception in exc_info.value.exceptions: | ||||
|                 assert isinstance(exception, KeyboardInterrupt) or isinstance( | ||||
|                     exception, ContextCancelled | ||||
|                 ) | ||||
| 
 | ||||
|     # Setablend and execute a trade and assert trade | ||||
|     _run_test_and_check( | ||||
|         BaseExceptionGroup, | ||||
|         partial( | ||||
|             _async_main, | ||||
|             open_pikerd=open_test_pikerd, | ||||
|             action="buy", | ||||
|             action='buy', | ||||
|         ), | ||||
|     ) | ||||
|     _run_test_and_check(BaseExceptionGroup, _open_and_assert_pps) | ||||
|     _run_test_and_check(BaseExceptionGroup, _close_pp_and_assert) | ||||
| 
 | ||||
|      | ||||
| def test_paper_client( | ||||
|     open_test_pikerd: AsyncContextManager | ||||
| ): | ||||
|      | ||||
|     async def _async_main( | ||||
|         open_pikerd: AsyncContextManager, | ||||
|     ):  | ||||
|         (fqsn, symbol, broker) = get_fqsn("kraken", "xbtusdt") | ||||
|         async with ( | ||||
|             open_pikerd() as (_, _, _, services), | ||||
|             open_ems(fqsn, mode="paper") as ( | ||||
|                 book, | ||||
|                 trades_stream, | ||||
|                 pps, | ||||
|                 accounts, | ||||
|                 dialogs, | ||||
|             ), | ||||
|         ): | ||||
|             async with open_cached_client(broker) as client: | ||||
|                 symbol_info = await client.symbol_info() | ||||
|                 print(f'client: {symbol_info["XBTUSDT"]}') | ||||
| 
 | ||||
|     trio.run(partial( | ||||
|             _async_main, | ||||
|             open_pikerd=open_test_pikerd, | ||||
|         ), | ||||
|     _run_test_and_check( | ||||
|         BaseExceptionGroup, | ||||
|         partial(_async_main, open_pikerd=open_test_pikerd), | ||||
|         _assert_pps, | ||||
|     ) | ||||
| 
 | ||||
|     _run_test_and_check( | ||||
|         BaseExceptionGroup, | ||||
|         partial(_async_main, open_pikerd=open_test_pikerd, action='sell', price=1), | ||||
|         _assert_no_pps, | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| # def test_paper_client( | ||||
| #     open_test_pikerd: AsyncContextManager | ||||
| # ): | ||||
| # | ||||
| #     async def _async_main( | ||||
| #         open_pikerd: AsyncContextManager, | ||||
| #     ): | ||||
| #         (fqsn, symbol, broker) = get_fqsn('kraken', 'xbtusdt') | ||||
| #         async with ( | ||||
| #             open_pikerd() as (_, _, _, services), | ||||
| #             open_ems(fqsn, mode='paper') as ( | ||||
| #                 book, | ||||
| #                 trades_stream, | ||||
| #                 pps, | ||||
| #                 accounts, | ||||
| #                 dialogs, | ||||
| #             ), | ||||
| #         ): | ||||
| #             async with open_cached_client(broker) as client: | ||||
| #                 symbol_info = await client.symbol_info() | ||||
| #                 print(f'client: {symbol_info['XBTUSDT']}') | ||||
| # | ||||
| #     trio.run(partial( | ||||
| #             _async_main, | ||||
| #             open_pikerd=open_test_pikerd, | ||||
| #         ), | ||||
| #     ) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue