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,6 +501,7 @@ 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
|
||||||
|
with tractor.devx.maybe_open_crash_handler(): # as bxerr:
|
||||||
pair = Pair(xname=xkey, **data)
|
pair = Pair(xname=xkey, **data)
|
||||||
|
|
||||||
# register the above `Pair` structs for all
|
# register the above `Pair` structs for all
|
||||||
|
|
|
@ -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,6 +308,7 @@ class FormatLabel(QLabel):
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
self.setFont(_font.font)
|
self.setFont(_font.font)
|
||||||
|
if use_md:
|
||||||
self.setTextFormat(
|
self.setTextFormat(
|
||||||
Qt.TextFormat.MarkdownText
|
Qt.TextFormat.MarkdownText
|
||||||
)
|
)
|
||||||
|
@ -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