port_to_latest_tractor #45
			
				
			
		
		
		
	
							
								
								
									
										31
									
								
								README.rst
								
								
								
								
							
							
						
						
									
										31
									
								
								README.rst
								
								
								
								
							|  | @ -88,15 +88,23 @@ a sane install with `uv` | ||||||
| ************************ | ************************ | ||||||
| bc why install with `python` when you can faster with `rust` :: | bc why install with `python` when you can faster with `rust` :: | ||||||
| 
 | 
 | ||||||
|     uv lock |     uv sync | ||||||
| 
 | 
 | ||||||
| with all GUI support as well:: |     # ^ astral's docs, | ||||||
|  |     # https://docs.astral.sh/uv/concepts/projects/sync/ | ||||||
| 
 | 
 | ||||||
|     uv lock --extra uis | include all GUIs :: | ||||||
| 
 | 
 | ||||||
| AND with all dev (hacking) tools:: |     uv sync --extra uis | ||||||
| 
 | 
 | ||||||
|     uv lock --dev --extra uis | AND with all our hacking tools:: | ||||||
|  | 
 | ||||||
|  |     uv sync --dev --extra uis | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Ensure you can run the root-daemon:: | ||||||
|  | 
 | ||||||
|  |     uv run pikerd [-l info --pdb] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| hacky install on nixos | hacky install on nixos | ||||||
|  | @ -111,7 +119,18 @@ start a chart | ||||||
| ************* | ************* | ||||||
| run a realtime OHLCV chart stand-alone:: | run a realtime OHLCV chart stand-alone:: | ||||||
| 
 | 
 | ||||||
|     piker -l info chart btcusdt.spot.binance xmrusdt.spot.kraken |     [uv run] piker -l info chart btcusdt.spot.binance xmrusdt.spot.kraken | ||||||
|  | 
 | ||||||
|  |     # ^^^ iff you haven't activated the py-env, | ||||||
|  |     # - https://docs.astral.sh/uv/concepts/projects/run/ | ||||||
|  |     # | ||||||
|  |     # in order to create an explicit virt-env see, | ||||||
|  |     # - https://docs.astral.sh/uv/concepts/projects/layout/#the-project-environment | ||||||
|  |     # - https://docs.astral.sh/uv/pip/environments/ | ||||||
|  |     # | ||||||
|  |     # use $UV_PROJECT_ENVIRONMENT to select any non-`.venv/` | ||||||
|  |     # as the venv sudir in the repo's root. | ||||||
|  |     # - https://docs.astral.sh/uv/reference/environment/#uv_project_environment | ||||||
| 
 | 
 | ||||||
| this runs a chart UI (with 1m sampled OHLCV) and shows 2 spot markets from 2 diff cexes | this runs a chart UI (with 1m sampled OHLCV) and shows 2 spot markets from 2 diff cexes | ||||||
| overlayed on the same graph. Use of `piker` without first starting | overlayed on the same graph. Use of `piker` without first starting | ||||||
|  |  | ||||||
|  | @ -96,7 +96,10 @@ async def _setup_persistent_brokerd( | ||||||
|     # - `open_symbol_search()` |     # - `open_symbol_search()` | ||||||
|     # NOTE: see ep invocation details inside `.data.feed`. |     # NOTE: see ep invocation details inside `.data.feed`. | ||||||
|     try: |     try: | ||||||
|         async with trio.open_nursery() as service_nursery: |         async with ( | ||||||
|  |             tractor.trionics.collapse_eg(), | ||||||
|  |             trio.open_nursery() as service_nursery | ||||||
|  |         ): | ||||||
|             bus: _FeedsBus = feed.get_feed_bus( |             bus: _FeedsBus = feed.get_feed_bus( | ||||||
|                 brokername, |                 brokername, | ||||||
|                 service_nursery, |                 service_nursery, | ||||||
|  |  | ||||||
|  | @ -34,6 +34,7 @@ import urllib.parse | ||||||
| import hashlib | import hashlib | ||||||
| import hmac | import hmac | ||||||
| import base64 | import base64 | ||||||
|  | import tractor | ||||||
| import trio | import trio | ||||||
| 
 | 
 | ||||||
| from piker import config | from piker import config | ||||||
|  | @ -372,8 +373,7 @@ class Client: | ||||||
|         #     1658347714, 'status': 'Success'}]} |         #     1658347714, 'status': 'Success'}]} | ||||||
| 
 | 
 | ||||||
|         if xfers: |         if xfers: | ||||||
|             import tractor |             await tractor.pause() | ||||||
|             await tractor.pp() |  | ||||||
| 
 | 
 | ||||||
|         trans: dict[str, Transaction] = {} |         trans: dict[str, Transaction] = {} | ||||||
|         for entry in xfers: |         for entry in xfers: | ||||||
|  | @ -501,7 +501,8 @@ class Client: | ||||||
|             for xkey, data in resp['result'].items(): |             for xkey, data in resp['result'].items(): | ||||||
| 
 | 
 | ||||||
|                 # NOTE: always cache in pairs tables for faster lookup |                 # NOTE: always cache in pairs tables for faster lookup | ||||||
|                 pair = Pair(xname=xkey, **data) |                 with tractor.devx.maybe_open_crash_handler(): # as bxerr: | ||||||
|  |                     pair = Pair(xname=xkey, **data) | ||||||
| 
 | 
 | ||||||
|                 # register the above `Pair` structs for all |                 # register the above `Pair` structs for all | ||||||
|                 # key-sets/monikers: a set of 4 (frickin) tables |                 # key-sets/monikers: a set of 4 (frickin) tables | ||||||
|  |  | ||||||
|  | @ -21,7 +21,6 @@ Symbology defs and search. | ||||||
| from decimal import Decimal | from decimal import Decimal | ||||||
| 
 | 
 | ||||||
| import tractor | import tractor | ||||||
| from rapidfuzz import process as fuzzy |  | ||||||
| 
 | 
 | ||||||
| from piker._cacheables import ( | from piker._cacheables import ( | ||||||
|     async_lifo_cache, |     async_lifo_cache, | ||||||
|  | @ -41,8 +40,13 @@ from piker.accounting._mktinfo import ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # https://www.kraken.com/features/api#get-tradable-pairs |  | ||||||
| class Pair(Struct): | class Pair(Struct): | ||||||
|  |     ''' | ||||||
|  |     A tradable asset pair as schema-defined by, | ||||||
|  | 
 | ||||||
|  |     https://docs.kraken.com/api/docs/rest-api/get-tradable-asset-pairs | ||||||
|  | 
 | ||||||
|  |     ''' | ||||||
|     xname: str  # idiotic bs_mktid equiv i guess? |     xname: str  # idiotic bs_mktid equiv i guess? | ||||||
|     altname: str  # alternate pair name |     altname: str  # alternate pair name | ||||||
|     wsname: str  # WebSocket pair name (if available) |     wsname: str  # WebSocket pair name (if available) | ||||||
|  | @ -53,7 +57,6 @@ class Pair(Struct): | ||||||
|     lot: str  # volume lot size |     lot: str  # volume lot size | ||||||
| 
 | 
 | ||||||
|     cost_decimals: int |     cost_decimals: int | ||||||
|     costmin: float |  | ||||||
|     pair_decimals: int  # scaling decimal places for pair |     pair_decimals: int  # scaling decimal places for pair | ||||||
|     lot_decimals: int  # scaling decimal places for volume |     lot_decimals: int  # scaling decimal places for volume | ||||||
| 
 | 
 | ||||||
|  | @ -79,6 +82,7 @@ class Pair(Struct): | ||||||
|     tick_size: float  # min price step size |     tick_size: float  # min price step size | ||||||
|     status: str |     status: str | ||||||
| 
 | 
 | ||||||
|  |     costmin: str|None = None  # XXX, only some mktpairs? | ||||||
|     short_position_limit: float = 0 |     short_position_limit: float = 0 | ||||||
|     long_position_limit: float = float('inf') |     long_position_limit: float = float('inf') | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -25,7 +25,10 @@ from typing import TYPE_CHECKING | ||||||
| 
 | 
 | ||||||
| import trio | import trio | ||||||
| import tractor | import tractor | ||||||
| from tractor.trionics import broadcast_receiver | from tractor.trionics import ( | ||||||
|  |     broadcast_receiver, | ||||||
|  |     collapse_eg, | ||||||
|  | ) | ||||||
| 
 | 
 | ||||||
| from ._util import ( | from ._util import ( | ||||||
|     log,  # sub-sys logger |     log,  # sub-sys logger | ||||||
|  | @ -281,8 +284,11 @@ async def open_ems( | ||||||
|             client._ems_stream = trades_stream |             client._ems_stream = trades_stream | ||||||
| 
 | 
 | ||||||
|             # start sync code order msg delivery task |             # start sync code order msg delivery task | ||||||
|             async with trio.open_nursery() as n: |             async with ( | ||||||
|                 n.start_soon( |                 collapse_eg(), | ||||||
|  |                 trio.open_nursery() as tn, | ||||||
|  |             ): | ||||||
|  |                 tn.start_soon( | ||||||
|                     relay_orders_from_sync_code, |                     relay_orders_from_sync_code, | ||||||
|                     client, |                     client, | ||||||
|                     fqme, |                     fqme, | ||||||
|  | @ -298,4 +304,4 @@ async def open_ems( | ||||||
|                 ) |                 ) | ||||||
| 
 | 
 | ||||||
|                 # stop the sync-msg-relay task on exit. |                 # stop the sync-msg-relay task on exit. | ||||||
|                 n.cancel_scope.cancel() |                 tn.cancel_scope.cancel() | ||||||
|  |  | ||||||
|  | @ -39,6 +39,7 @@ from typing import ( | ||||||
|     AsyncContextManager, |     AsyncContextManager, | ||||||
|     Awaitable, |     Awaitable, | ||||||
|     Sequence, |     Sequence, | ||||||
|  |     TYPE_CHECKING, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| import trio | import trio | ||||||
|  | @ -75,6 +76,10 @@ from ._sampling import ( | ||||||
|     uniform_rate_send, |     uniform_rate_send, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | if TYPE_CHECKING: | ||||||
|  |     from tractor._addr import Address | ||||||
|  |     from tractor.msg.types import Aid | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class Sub(Struct, frozen=True): | class Sub(Struct, frozen=True): | ||||||
|     ''' |     ''' | ||||||
|  | @ -899,19 +904,19 @@ async def open_feed( | ||||||
|             feed.portals[brokermod] = portal |             feed.portals[brokermod] = portal | ||||||
| 
 | 
 | ||||||
|             # fill out "status info" that the UI can show |             # fill out "status info" that the UI can show | ||||||
|             host, port = portal.channel.raddr |             chan: tractor.Channel = portal.chan | ||||||
|             if host == '127.0.0.1': |             raddr: Address = chan.raddr | ||||||
|                 host = 'localhost' |             aid: Aid = chan.aid | ||||||
| 
 |             # TAG_feed_status_update | ||||||
|             feed.status.update({ |             feed.status.update({ | ||||||
|                 'actor_name': portal.channel.uid[0], |                 'actor_id': aid, | ||||||
|                 'host': host, |                 'actor_short_id': f'{aid.name}@{aid.pid}', | ||||||
|                 'port': port, |                 'ipc': chan.raddr.proto_key, | ||||||
|  |                 'ipc_addr': raddr, | ||||||
|                 'hist_shm': 'NA', |                 'hist_shm': 'NA', | ||||||
|                 'rt_shm': 'NA', |                 'rt_shm': 'NA', | ||||||
|                 'throttle_rate': tick_throttle, |                 'throttle_hz': tick_throttle, | ||||||
|             }) |             }) | ||||||
|             # feed.status.update(init_msg.pop('status', {})) |  | ||||||
| 
 | 
 | ||||||
|             # (allocate and) connect to any feed bus for this broker |             # (allocate and) connect to any feed bus for this broker | ||||||
|             bus_ctxs.append( |             bus_ctxs.append( | ||||||
|  |  | ||||||
|  | @ -498,6 +498,7 @@ async def cascade( | ||||||
| 
 | 
 | ||||||
|         func_name: str = func.__name__ |         func_name: str = func.__name__ | ||||||
|         async with ( |         async with ( | ||||||
|  |             tractor.trionics.collapse_eg(),  # avoid multi-taskc tb in console | ||||||
|             trio.open_nursery() as tn, |             trio.open_nursery() as tn, | ||||||
|         ): |         ): | ||||||
|             # TODO: might be better to just make a "restart" method where |             # TODO: might be better to just make a "restart" method where | ||||||
|  |  | ||||||
|  | @ -200,7 +200,8 @@ async def open_pikerd( | ||||||
|             reg_addrs, |             reg_addrs, | ||||||
|         ), |         ), | ||||||
|         tractor.open_nursery() as actor_nursery, |         tractor.open_nursery() as actor_nursery, | ||||||
|         trio.open_nursery() as service_nursery, |         tractor.trionics.collapse_eg(), | ||||||
|  |         trio.open_nursery() as service_tn, | ||||||
|     ): |     ): | ||||||
|         for addr in reg_addrs: |         for addr in reg_addrs: | ||||||
|             if addr not in root_actor.accept_addrs: |             if addr not in root_actor.accept_addrs: | ||||||
|  | @ -211,7 +212,7 @@ async def open_pikerd( | ||||||
| 
 | 
 | ||||||
|         # assign globally for future daemon/task creation |         # assign globally for future daemon/task creation | ||||||
|         Services.actor_n = actor_nursery |         Services.actor_n = actor_nursery | ||||||
|         Services.service_n = service_nursery |         Services.service_n = service_tn | ||||||
|         Services.debug_mode = debug_mode |         Services.debug_mode = debug_mode | ||||||
| 
 | 
 | ||||||
|         try: |         try: | ||||||
|  | @ -221,7 +222,7 @@ async def open_pikerd( | ||||||
|             # TODO: is this more clever/efficient? |             # TODO: is this more clever/efficient? | ||||||
|             # if 'samplerd' in Services.service_tasks: |             # if 'samplerd' in Services.service_tasks: | ||||||
|             #     await Services.cancel_service('samplerd') |             #     await Services.cancel_service('samplerd') | ||||||
|             service_nursery.cancel_scope.cancel() |             service_tn.cancel_scope.cancel() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # TODO: do we even need this? | # TODO: do we even need this? | ||||||
|  |  | ||||||
|  | @ -517,7 +517,7 @@ def with_dts( | ||||||
| 
 | 
 | ||||||
|     ''' |     ''' | ||||||
|     return df.with_columns([ |     return df.with_columns([ | ||||||
|         pl.col(time_col).shift(1).suffix('_prev'), |         pl.col(time_col).shift(1).name.suffix('_prev'), | ||||||
|         pl.col(time_col).diff().alias('s_diff'), |         pl.col(time_col).diff().alias('s_diff'), | ||||||
|         pl.from_epoch(pl.col(time_col)).alias('dt'), |         pl.from_epoch(pl.col(time_col)).alias('dt'), | ||||||
|     ]).with_columns([ |     ]).with_columns([ | ||||||
|  | @ -623,7 +623,7 @@ def detect_vlm_gaps( | ||||||
| 
 | 
 | ||||||
| ) -> pl.DataFrame: | ) -> pl.DataFrame: | ||||||
| 
 | 
 | ||||||
|     vnull: pl.DataFrame = w_dts.filter( |     vnull: pl.DataFrame = df.filter( | ||||||
|         pl.col(col) == 0 |         pl.col(col) == 0 | ||||||
|     ) |     ) | ||||||
|     return vnull |     return vnull | ||||||
|  |  | ||||||
|  | @ -21,6 +21,7 @@ Main app startup and run. | ||||||
| from functools import partial | from functools import partial | ||||||
| from types import ModuleType | from types import ModuleType | ||||||
| 
 | 
 | ||||||
|  | import tractor | ||||||
| import trio | import trio | ||||||
| 
 | 
 | ||||||
| from piker.ui.qt import ( | from piker.ui.qt import ( | ||||||
|  | @ -116,6 +117,7 @@ async def _async_main( | ||||||
|         needed_brokermods[brokername] = brokers[brokername] |         needed_brokermods[brokername] = brokers[brokername] | ||||||
| 
 | 
 | ||||||
|     async with ( |     async with ( | ||||||
|  |         tractor.trionics.collapse_eg(), | ||||||
|         trio.open_nursery() as root_n, |         trio.open_nursery() as root_n, | ||||||
|     ): |     ): | ||||||
|         # set root nursery and task stack for spawning other charts/feeds |         # set root nursery and task stack for spawning other charts/feeds | ||||||
|  |  | ||||||
|  | @ -33,7 +33,6 @@ import trio | ||||||
| 
 | 
 | ||||||
| from piker.ui.qt import ( | from piker.ui.qt import ( | ||||||
|     QtCore, |     QtCore, | ||||||
|     QtWidgets, |  | ||||||
|     Qt, |     Qt, | ||||||
|     QLineF, |     QLineF, | ||||||
|     QFrame, |     QFrame, | ||||||
|  |  | ||||||
|  | @ -1445,7 +1445,10 @@ async def display_symbol_data( | ||||||
|         # for pause/resume on mouse interaction |         # for pause/resume on mouse interaction | ||||||
|         rt_chart.feed = feed |         rt_chart.feed = feed | ||||||
| 
 | 
 | ||||||
|         async with trio.open_nursery() as ln: |         async with ( | ||||||
|  |             tractor.trionics.collapse_eg(), | ||||||
|  |             trio.open_nursery() as ln, | ||||||
|  |         ): | ||||||
|             # if available load volume related built-in display(s) |             # if available load volume related built-in display(s) | ||||||
|             vlm_charts: dict[ |             vlm_charts: dict[ | ||||||
|                 str, |                 str, | ||||||
|  |  | ||||||
|  | @ -22,7 +22,10 @@ from contextlib import asynccontextmanager as acm | ||||||
| from typing import Callable | from typing import Callable | ||||||
| 
 | 
 | ||||||
| import trio | import trio | ||||||
| from tractor.trionics import gather_contexts | from tractor.trionics import ( | ||||||
|  |     gather_contexts, | ||||||
|  |     collapse_eg, | ||||||
|  | ) | ||||||
| 
 | 
 | ||||||
| from piker.ui.qt import ( | from piker.ui.qt import ( | ||||||
|     QtCore, |     QtCore, | ||||||
|  | @ -207,7 +210,10 @@ async def open_signal_handler( | ||||||
|         async for args in recv: |         async for args in recv: | ||||||
|             await async_handler(*args) |             await async_handler(*args) | ||||||
| 
 | 
 | ||||||
|     async with trio.open_nursery() as tn: |     async with ( | ||||||
|  |         collapse_eg(), | ||||||
|  |         trio.open_nursery() as tn | ||||||
|  |     ): | ||||||
|         tn.start_soon(proxy_to_handler) |         tn.start_soon(proxy_to_handler) | ||||||
|         async with send: |         async with send: | ||||||
|             yield |             yield | ||||||
|  | @ -242,6 +248,7 @@ async def open_handlers( | ||||||
|     widget: QWidget |     widget: QWidget | ||||||
|     streams: list[trio.abc.ReceiveChannel] |     streams: list[trio.abc.ReceiveChannel] | ||||||
|     async with ( |     async with ( | ||||||
|  |         collapse_eg(), | ||||||
|         trio.open_nursery() as tn, |         trio.open_nursery() as tn, | ||||||
|         gather_contexts([ |         gather_contexts([ | ||||||
|             open_event_stream( |             open_event_stream( | ||||||
|  |  | ||||||
|  | @ -18,10 +18,11 @@ | ||||||
| Feed status and controls widget(s) for embedding in a UI-pane. | Feed status and controls widget(s) for embedding in a UI-pane. | ||||||
| 
 | 
 | ||||||
| """ | """ | ||||||
| 
 |  | ||||||
| from __future__ import annotations | from __future__ import annotations | ||||||
| from textwrap import dedent | from typing import ( | ||||||
| from typing import TYPE_CHECKING |     Any, | ||||||
|  |     TYPE_CHECKING, | ||||||
|  | ) | ||||||
| 
 | 
 | ||||||
| # from PyQt5.QtCore import Qt | # from PyQt5.QtCore import Qt | ||||||
| 
 | 
 | ||||||
|  | @ -49,35 +50,55 @@ def mk_feed_label( | ||||||
|     a feed control protocol. |     a feed control protocol. | ||||||
| 
 | 
 | ||||||
|     ''' |     ''' | ||||||
|     status = feed.status |     status: dict[str, Any] = feed.status | ||||||
|     assert status |     assert status | ||||||
| 
 | 
 | ||||||
|     msg = dedent(""" |     # SO tips on ws/nls, | ||||||
|         actor: **{actor_name}**\n |     # https://stackoverflow.com/a/15721400 | ||||||
|         |_ @**{host}:{port}**\n |     ws: str = ' ' | ||||||
|     """) |     # nl: str = '<br>'  # dun work? | ||||||
|  |     actor_info_repr: str = ( | ||||||
|  |         f')> **{status["actor_short_id"]}**\n' | ||||||
|  |         '\n'  # bc md? | ||||||
|  |     ) | ||||||
| 
 | 
 | ||||||
|     for key, val in status.items(): |     # fields to select *IN* for display | ||||||
|         if key in ('host', 'port', 'actor_name'): |     # (see `.data.feed.open_feed()` status | ||||||
|             continue |     #  update -> TAG_feed_status_update) | ||||||
|         msg += f'\n|_ {key}: **{{{key}}}**\n' |     for key in [ | ||||||
|  |         'ipc', | ||||||
|  |         'hist_shm', | ||||||
|  |         'rt_shm', | ||||||
|  |         'throttle_hz', | ||||||
|  |     ]: | ||||||
|  |         # NOTE, the 2nd key is filled via `.format()` updates. | ||||||
|  |         actor_info_repr += ( | ||||||
|  |             f'\n'  # bc md? | ||||||
|  |             f'{ws}|_{key}: **{{{key}}}**\n' | ||||||
|  |         ) | ||||||
|  |         # ^TODO? formatting and content.. | ||||||
|  |         # -[ ] showing which fqme is "forward" on the | ||||||
|  |         #    chart/fsp/order-mode? | ||||||
|  |         #  '|_ flows: **{symbols}**\n' | ||||||
|  |         # | ||||||
|  |         # -[x] why isn't the indent working? | ||||||
|  |         #  => markdown, now solved.. | ||||||
| 
 | 
 | ||||||
|     feed_label = FormatLabel( |     feed_label = FormatLabel( | ||||||
|         fmt_str=msg, |         fmt_str=actor_info_repr, | ||||||
|         # |_ streams: **{symbols}**\n |  | ||||||
|         font=_font.font, |         font=_font.font, | ||||||
|         font_size=_font_small.px_size, |         font_size=_font_small.px_size, | ||||||
|         font_color='default_lightest', |         font_color='default_lightest', | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|  |     # ?TODO, remove this? | ||||||
|     # form.vbox.setAlignment(feed_label, Qt.AlignBottom) |     # form.vbox.setAlignment(feed_label, Qt.AlignBottom) | ||||||
|     # form.vbox.setAlignment(Qt.AlignBottom) |     # form.vbox.setAlignment(Qt.AlignBottom) | ||||||
|     _ = chart.height() - ( |     # _ = chart.height() - ( | ||||||
|         form.height() + |     #     form.height() + | ||||||
|         form.fill_bar.height() |     #     form.fill_bar.height() | ||||||
|         # feed_label.height() |     #     # feed_label.height() | ||||||
|     ) |     # ) | ||||||
| 
 | 
 | ||||||
|     feed_label.format(**feed.status) |     feed_label.format(**feed.status) | ||||||
| 
 |  | ||||||
|     return feed_label |     return feed_label | ||||||
|  |  | ||||||
|  | @ -600,6 +600,7 @@ async def open_fsp_admin( | ||||||
|             kwargs=kwargs, |             kwargs=kwargs, | ||||||
|         ) as (cache_hit, cluster_map), |         ) as (cache_hit, cluster_map), | ||||||
| 
 | 
 | ||||||
|  |         tractor.trionics.collapse_eg(), | ||||||
|         trio.open_nursery() as tn, |         trio.open_nursery() as tn, | ||||||
|     ): |     ): | ||||||
|         if cache_hit: |         if cache_hit: | ||||||
|  | @ -613,6 +614,8 @@ async def open_fsp_admin( | ||||||
|         ) |         ) | ||||||
|         try: |         try: | ||||||
|             yield admin |             yield admin | ||||||
|  | 
 | ||||||
|  |         # ??TODO, does this *need* to be inside a finally? | ||||||
|         finally: |         finally: | ||||||
|             # terminate all tasks via signals |             # terminate all tasks via signals | ||||||
|             for key, entry in admin._registry.items(): |             for key, entry in admin._registry.items(): | ||||||
|  |  | ||||||
|  | @ -285,18 +285,20 @@ class FormatLabel(QLabel): | ||||||
|         font_size: int, |         font_size: int, | ||||||
|         font_color: str, |         font_color: str, | ||||||
| 
 | 
 | ||||||
|  |         use_md: bool = True, | ||||||
|  | 
 | ||||||
|         parent=None, |         parent=None, | ||||||
| 
 | 
 | ||||||
|     ) -> None: |     ) -> None: | ||||||
| 
 | 
 | ||||||
|         super().__init__(parent) |         super().__init__(parent) | ||||||
| 
 | 
 | ||||||
|         # by default set the format string verbatim and expect user to |         # by default set the format string verbatim and expect user | ||||||
|         # call ``.format()`` later (presumably they'll notice the |         # to call ``.format()`` later (presumably they'll notice the | ||||||
|         # unformatted content if ``fmt_str`` isn't meant to be |         # unformatted content if ``fmt_str`` isn't meant to be | ||||||
|         # unformatted). |         # unformatted). | ||||||
|         self.fmt_str = fmt_str |         self.fmt_str = fmt_str | ||||||
|         self.setText(fmt_str) |         # self.setText(fmt_str)  # ?TODO, why here? | ||||||
| 
 | 
 | ||||||
|         self.setStyleSheet( |         self.setStyleSheet( | ||||||
|             f"""QLabel {{ |             f"""QLabel {{ | ||||||
|  | @ -306,9 +308,10 @@ class FormatLabel(QLabel): | ||||||
|             """ |             """ | ||||||
|         ) |         ) | ||||||
|         self.setFont(_font.font) |         self.setFont(_font.font) | ||||||
|         self.setTextFormat( |         if use_md: | ||||||
|             Qt.TextFormat.MarkdownText |             self.setTextFormat( | ||||||
|         ) |                 Qt.TextFormat.MarkdownText | ||||||
|  |             ) | ||||||
|         self.setMargin(0) |         self.setMargin(0) | ||||||
| 
 | 
 | ||||||
|         self.setSizePolicy( |         self.setSizePolicy( | ||||||
|  | @ -316,7 +319,10 @@ class FormatLabel(QLabel): | ||||||
|             size_policy.Expanding, |             size_policy.Expanding, | ||||||
|         ) |         ) | ||||||
|         self.setAlignment( |         self.setAlignment( | ||||||
|             Qt.AlignVCenter | Qt.AlignLeft |             Qt.AlignLeft | ||||||
|  |             | | ||||||
|  |             Qt.AlignBottom | ||||||
|  |             # Qt.AlignVCenter | ||||||
|         ) |         ) | ||||||
|         self.setText(self.fmt_str) |         self.setText(self.fmt_str) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -269,6 +269,8 @@ def hcolor(name: str) -> str: | ||||||
| 
 | 
 | ||||||
|         # default ohlc-bars/curve gray |         # default ohlc-bars/curve gray | ||||||
|         'bracket': '#666666',  # like the logo |         'bracket': '#666666',  # like the logo | ||||||
|  |         'pikers': '#616161',  # a trader shade of.. | ||||||
|  |         'beast': '#161616',  # in the dark alone. | ||||||
| 
 | 
 | ||||||
|         # bluish |         # bluish | ||||||
|         'charcoal': '#36454F', |         'charcoal': '#36454F', | ||||||
|  |  | ||||||
|  | @ -792,6 +792,7 @@ async def open_order_mode( | ||||||
|             brokerd_accounts, |             brokerd_accounts, | ||||||
|             ems_dialog_msgs, |             ems_dialog_msgs, | ||||||
|         ), |         ), | ||||||
|  |         tractor.trionics.collapse_eg(), | ||||||
|         trio.open_nursery() as tn, |         trio.open_nursery() as tn, | ||||||
| 
 | 
 | ||||||
|     ): |     ): | ||||||
|  |  | ||||||
|  | @ -23,7 +23,7 @@ name = "piker" | ||||||
| version = "0.1.0a0dev0" | version = "0.1.0a0dev0" | ||||||
| description = "trading gear for hackers" | description = "trading gear for hackers" | ||||||
| authors = [{ name = "Tyler Goodlet", email = "goodboy_foss@protonmail.com" }] | authors = [{ name = "Tyler Goodlet", email = "goodboy_foss@protonmail.com" }] | ||||||
| requires-python = ">=3.12, <3.13" | requires-python = ">=3.12" | ||||||
| license = "AGPL-3.0-or-later" | license = "AGPL-3.0-or-later" | ||||||
| readme = "README.rst" | readme = "README.rst" | ||||||
| keywords = [ | keywords = [ | ||||||
|  | @ -39,8 +39,8 @@ classifiers = [ | ||||||
|     "Operating System :: POSIX :: Linux", |     "Operating System :: POSIX :: Linux", | ||||||
|     "Programming Language :: Python :: Implementation :: CPython", |     "Programming Language :: Python :: Implementation :: CPython", | ||||||
|     "Programming Language :: Python :: 3 :: Only", |     "Programming Language :: Python :: 3 :: Only", | ||||||
|     "Programming Language :: Python :: 3.11", |  | ||||||
|     "Programming Language :: Python :: 3.12", |     "Programming Language :: Python :: 3.12", | ||||||
|  |     "Programming Language :: Python :: 3.13", | ||||||
|     "Intended Audience :: Financial and Insurance Industry", |     "Intended Audience :: Financial and Insurance Industry", | ||||||
|     "Intended Audience :: Science/Research", |     "Intended Audience :: Science/Research", | ||||||
|     "Intended Audience :: Developers", |     "Intended Audience :: Developers", | ||||||
|  | @ -49,13 +49,13 @@ classifiers = [ | ||||||
| dependencies = [ | dependencies = [ | ||||||
|     "async-generator >=1.10, <2.0.0", |     "async-generator >=1.10, <2.0.0", | ||||||
|     "attrs >=23.1.0, <24.0.0", |     "attrs >=23.1.0, <24.0.0", | ||||||
|     "bidict >=0.22.1, <0.23.0", |     "bidict >=0.23.1", | ||||||
|     "colorama >=0.4.6, <0.5.0", |     "colorama >=0.4.6, <0.5.0", | ||||||
|     "colorlog >=6.7.0, <7.0.0", |     "colorlog >=6.7.0, <7.0.0", | ||||||
|     "ib-insync >=0.9.86, <0.10.0", |     "ib-insync >=0.9.86, <0.10.0", | ||||||
|     "numba >=0.59.0, <0.60.0", |     "numpy>=2.0", | ||||||
|     "numpy >=1.25, <2.0", |     "polars >=0.20.6", | ||||||
|     "polars >=0.18.13, <0.19.0", |     "polars-fuzzy-match>=0.1.5", | ||||||
|     "pygments >=2.16.1, <3.0.0", |     "pygments >=2.16.1, <3.0.0", | ||||||
|     "rich >=13.5.2, <14.0.0", |     "rich >=13.5.2, <14.0.0", | ||||||
|     "tomli >=2.0.1, <3.0.0", |     "tomli >=2.0.1, <3.0.0", | ||||||
|  | @ -65,16 +65,18 @@ dependencies = [ | ||||||
|     "typer >=0.9.0, <1.0.0", |     "typer >=0.9.0, <1.0.0", | ||||||
|     "rapidfuzz >=3.5.2, <4.0.0", |     "rapidfuzz >=3.5.2, <4.0.0", | ||||||
|     "pdbp >=1.5.0, <2.0.0", |     "pdbp >=1.5.0, <2.0.0", | ||||||
|     "trio >=0.24, <0.25", |     "trio >=0.27", | ||||||
|     "pendulum >=3.0.0, <4.0.0", |     "pendulum >=3.0.0, <4.0.0", | ||||||
|     "httpx >=0.27.0, <0.28.0", |     "httpx >=0.27.0, <0.28.0", | ||||||
|     "cryptofeed >=2.4.0, <3.0.0", |     "cryptofeed >=2.4.0, <3.0.0", | ||||||
|     "pyarrow >=17.0.0, <18.0.0", |     "pyarrow>=18.0.0", | ||||||
|     "websockets ==12.0", |     "websockets ==12.0", | ||||||
|     "msgspec", |     "msgspec>=0.19.0,<0.20", | ||||||
|     "tractor", |     "tractor", | ||||||
|     "asyncvnc", |     "asyncvnc", | ||||||
|     "tomlkit", |     "tomlkit", | ||||||
|  |     "trio-typing>=0.10.0", | ||||||
|  |     "numba>=0.61.0", | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
| [project.optional-dependencies] | [project.optional-dependencies] | ||||||
|  | @ -125,9 +127,18 @@ include = ["piker"] | ||||||
| [tool.hatch.build.targets.wheel] | [tool.hatch.build.targets.wheel] | ||||||
| include = ["piker"] | include = ["piker"] | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | # TODO? move to a `uv.toml`? | ||||||
|  | [tool.uv] | ||||||
|  | python-preference = 'system' | ||||||
|  | python-downloads = 'manual' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| [tool.uv.sources] | [tool.uv.sources] | ||||||
| pyqtgraph = { git = "https://github.com/pikers/pyqtgraph.git" } | pyqtgraph = { git = "https://github.com/pikers/pyqtgraph.git" } | ||||||
| asyncvnc = { git = "https://github.com/pikers/asyncvnc.git", branch = "main" } | asyncvnc = { git = "https://github.com/pikers/asyncvnc.git", branch = "main" } | ||||||
| tomlkit = { git = "https://github.com/pikers/tomlkit.git", branch ="piker_pin" } | tomlkit = { git = "https://github.com/pikers/tomlkit.git", branch ="piker_pin" } | ||||||
| msgspec = { git = "https://github.com/jcrist/msgspec.git" } | 
 | ||||||
|  | # tractor = { git = "https://pikers.dev/goodboy/tractor", branch = "main" } | ||||||
|  | # XXX, since i'm hacking 3.13 support atm.. | ||||||
| tractor = { path = "../tractor", editable = true } | tractor = { path = "../tractor", editable = true } | ||||||
|  |  | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | TAG_feed_status_update	./piker/data/feed.py	/TAG_feed_status_update/ | ||||||
		Loading…
	
		Reference in New Issue