Compare commits
22 Commits
09bb3759d7
...
deaf7dd1ab
| Author | SHA1 | Date |
|---|---|---|
|
|
deaf7dd1ab | |
|
|
702aae2544 | |
|
|
44d54babeb | |
|
|
b5a33e1217 | |
|
|
796a831c6e | |
|
|
de81d1e905 | |
|
|
170dd9794c | |
|
|
599c36aba6 | |
|
|
f174f79a1a | |
|
|
9b284c2256 | |
|
|
59f2d46a97 | |
|
|
c1b1e99693 | |
|
|
24651d2326 | |
|
|
2d00bb1024 | |
|
|
dd40ad603f | |
|
|
f2ace1b63b | |
|
|
9010f9c7ab | |
|
|
89a145113c | |
|
|
ec4db30cdc | |
|
|
2a394dba03 | |
|
|
19f16e1df3 | |
|
|
3adb0d8b9d |
|
|
@ -203,9 +203,13 @@ async def stream_messages(
|
||||||
yield 'trade', piker_quote
|
yield 'trade', piker_quote
|
||||||
|
|
||||||
|
|
||||||
def make_sub(pairs: list[str], sub_name: str, uid: int) -> dict[str, str]:
|
def make_sub(
|
||||||
|
pairs: list[str],
|
||||||
|
sub_name: str,
|
||||||
|
uid: int,
|
||||||
|
) -> dict[str, str]:
|
||||||
'''
|
'''
|
||||||
Create a request subscription packet dict.
|
Create a request subscription packet `dict`.
|
||||||
|
|
||||||
- spot:
|
- spot:
|
||||||
https://binance-docs.github.io/apidocs/spot/en/#live-subscribing-unsubscribing-to-streams
|
https://binance-docs.github.io/apidocs/spot/en/#live-subscribing-unsubscribing-to-streams
|
||||||
|
|
@ -332,7 +336,8 @@ async def get_mkt_info(
|
||||||
# TODO: handle coinm futes which have a margin asset that
|
# TODO: handle coinm futes which have a margin asset that
|
||||||
# is some crypto token!
|
# is some crypto token!
|
||||||
# https://binance-docs.github.io/apidocs/delivery/en/#exchange-information
|
# https://binance-docs.github.io/apidocs/delivery/en/#exchange-information
|
||||||
or 'btc' in venue_lower
|
or
|
||||||
|
'btc' in venue_lower
|
||||||
):
|
):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
@ -343,12 +348,14 @@ async def get_mkt_info(
|
||||||
|
|
||||||
if (
|
if (
|
||||||
venue
|
venue
|
||||||
and 'spot' not in venue_lower
|
and
|
||||||
|
'spot' not in venue_lower
|
||||||
|
|
||||||
# XXX: catch all in case user doesn't know which
|
# XXX: catch all in case user doesn't know which
|
||||||
# venue they want (usdtm vs. coinm) and we can choose
|
# venue they want (usdtm vs. coinm) and we can choose
|
||||||
# a default (via config?) once we support coin-m APIs.
|
# a default (via config?) once we support coin-m APIs.
|
||||||
or 'perp' in venue_lower
|
or
|
||||||
|
'perp' in venue_lower
|
||||||
):
|
):
|
||||||
if not mkt_mode:
|
if not mkt_mode:
|
||||||
mkt_mode: str = f'{venue_lower}_futes'
|
mkt_mode: str = f'{venue_lower}_futes'
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ runnable script-programs.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
import asyncio
|
||||||
from datetime import ( # noqa
|
from datetime import ( # noqa
|
||||||
datetime,
|
datetime,
|
||||||
date,
|
date,
|
||||||
|
|
@ -140,7 +141,8 @@ async def data_reset_hack(
|
||||||
except (
|
except (
|
||||||
OSError, # no VNC server avail..
|
OSError, # no VNC server avail..
|
||||||
PermissionError, # asyncvnc pw fail..
|
PermissionError, # asyncvnc pw fail..
|
||||||
):
|
) as _vnc_err:
|
||||||
|
vnc_err = _vnc_err
|
||||||
try:
|
try:
|
||||||
import i3ipc # noqa (since a deps dynamic check)
|
import i3ipc # noqa (since a deps dynamic check)
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
|
|
@ -166,14 +168,22 @@ async def data_reset_hack(
|
||||||
|
|
||||||
# localhost but no vnc-client or it borked..
|
# localhost but no vnc-client or it borked..
|
||||||
else:
|
else:
|
||||||
try_xdo_manual(client)
|
log.error(
|
||||||
|
'VNC CLICK HACK FAILE with,\n'
|
||||||
|
f'{vnc_err!r}\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
# breakpoint()
|
||||||
|
# try_xdo_manual(client)
|
||||||
|
|
||||||
case 'i3ipc_xdotool':
|
case 'i3ipc_xdotool':
|
||||||
try_xdo_manual(client)
|
try_xdo_manual(client)
|
||||||
# i3ipc_xdotool_manual_click_hack()
|
# i3ipc_xdotool_manual_click_hack()
|
||||||
|
|
||||||
case _ as tech:
|
case _ as tech:
|
||||||
raise RuntimeError(f'{tech} is not supported for reset tech!?')
|
raise RuntimeError(
|
||||||
|
f'{tech!r} is not supported for reset tech!?'
|
||||||
|
)
|
||||||
|
|
||||||
# we don't really need the ``xdotool`` approach any more B)
|
# we don't really need the ``xdotool`` approach any more B)
|
||||||
return True
|
return True
|
||||||
|
|
@ -269,10 +279,35 @@ async def vnc_click_hack(
|
||||||
500,
|
500,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
# in case a prior dialog win is open/active.
|
||||||
|
await client.press('ISO_Enter')
|
||||||
|
|
||||||
# ensure the ib-gw window is active
|
# ensure the ib-gw window is active
|
||||||
await client.click(MOUSE_BUTTON_LEFT)
|
await client.click(MOUSE_BUTTON_LEFT)
|
||||||
|
|
||||||
# send the hotkeys combo B)
|
# send the hotkeys combo B)
|
||||||
await client.press('Ctrl', 'Alt', key) # keys are stacked
|
await client.press(
|
||||||
|
'Ctrl',
|
||||||
|
'Alt',
|
||||||
|
key,
|
||||||
|
) # NOTE, keys are stacked
|
||||||
|
|
||||||
|
# XXX, sometimes a dialog asking if you want to "simulate
|
||||||
|
# a reset" will show, in which case we want to select
|
||||||
|
# "Yes" (by tabbing) and then hit enter.
|
||||||
|
iters: int = 1
|
||||||
|
delay: float = 0.3
|
||||||
|
await asyncio.sleep(delay)
|
||||||
|
|
||||||
|
for i in range(iters):
|
||||||
|
log.info(f'Sending TAB {i}')
|
||||||
|
await client.press('Tab')
|
||||||
|
await asyncio.sleep(delay)
|
||||||
|
|
||||||
|
for i in range(iters):
|
||||||
|
log.info(f'Sending ENTER {i}')
|
||||||
|
await client.press('KP_Enter')
|
||||||
|
await asyncio.sleep(delay)
|
||||||
|
|
||||||
|
|
||||||
def i3ipc_fin_wins_titled(
|
def i3ipc_fin_wins_titled(
|
||||||
|
|
|
||||||
|
|
@ -561,7 +561,7 @@ class Client:
|
||||||
# f'Recursing for more bars:\n'
|
# f'Recursing for more bars:\n'
|
||||||
)
|
)
|
||||||
# XXX, debug!
|
# XXX, debug!
|
||||||
breakpoint()
|
# breakpoint()
|
||||||
# XXX ? TODO? recursively try to re-request?
|
# XXX ? TODO? recursively try to re-request?
|
||||||
# => i think *NO* right?
|
# => i think *NO* right?
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ Platform configuration (files) mgmt.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import platform
|
import platform
|
||||||
import sys
|
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
from typing import (
|
from typing import (
|
||||||
|
|
@ -29,6 +28,7 @@ from typing import (
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from bidict import bidict
|
from bidict import bidict
|
||||||
|
import platformdirs
|
||||||
import tomlkit
|
import tomlkit
|
||||||
try:
|
try:
|
||||||
import tomllib
|
import tomllib
|
||||||
|
|
@ -41,7 +41,7 @@ from .log import get_logger
|
||||||
log = get_logger('broker-config')
|
log = get_logger('broker-config')
|
||||||
|
|
||||||
|
|
||||||
# XXX NOTE: taken from `click`
|
# XXX NOTE: orig impl was taken from `click`
|
||||||
# |_https://github.com/pallets/click/blob/main/src/click/utils.py#L449
|
# |_https://github.com/pallets/click/blob/main/src/click/utils.py#L449
|
||||||
#
|
#
|
||||||
# (since apparently they have some super weirdness with SIGINT and
|
# (since apparently they have some super weirdness with SIGINT and
|
||||||
|
|
@ -54,44 +54,21 @@ def get_app_dir(
|
||||||
force_posix: bool = False,
|
force_posix: bool = False,
|
||||||
|
|
||||||
) -> str:
|
) -> str:
|
||||||
r"""Returns the config folder for the application. The default behavior
|
'''
|
||||||
|
Returns the config folder for the application. The default behavior
|
||||||
is to return whatever is most appropriate for the operating system.
|
is to return whatever is most appropriate for the operating system.
|
||||||
|
|
||||||
To give you an idea, for an app called ``"Foo Bar"``, something like
|
----
|
||||||
the following folders could be returned:
|
NOTE, below is originally from `click` impl fn, we can prolly remove?
|
||||||
|
----
|
||||||
|
|
||||||
Mac OS X:
|
|
||||||
``~/Library/Application Support/Foo Bar``
|
|
||||||
Mac OS X (POSIX):
|
|
||||||
``~/.foo-bar``
|
|
||||||
Unix:
|
|
||||||
``~/.config/foo-bar``
|
|
||||||
Unix (POSIX):
|
|
||||||
``~/.foo-bar``
|
|
||||||
Win XP (roaming):
|
|
||||||
``C:\Documents and Settings\<user>\Local Settings\Application Data\Foo``
|
|
||||||
Win XP (not roaming):
|
|
||||||
``C:\Documents and Settings\<user>\Application Data\Foo Bar``
|
|
||||||
Win 7 (roaming):
|
|
||||||
``C:\Users\<user>\AppData\Roaming\Foo Bar``
|
|
||||||
Win 7 (not roaming):
|
|
||||||
``C:\Users\<user>\AppData\Local\Foo Bar``
|
|
||||||
|
|
||||||
.. versionadded:: 2.0
|
|
||||||
|
|
||||||
:param app_name: the application name. This should be properly capitalized
|
|
||||||
and can contain whitespace.
|
|
||||||
:param roaming: controls if the folder should be roaming or not on Windows.
|
:param roaming: controls if the folder should be roaming or not on Windows.
|
||||||
Has no affect otherwise.
|
Has no affect otherwise.
|
||||||
:param force_posix: if this is set to `True` then on any POSIX system the
|
:param force_posix: if this is set to `True` then on any POSIX system the
|
||||||
folder will be stored in the home folder with a leading
|
folder will be stored in the home folder with a leading
|
||||||
dot instead of the XDG config home or darwin's
|
dot instead of the XDG config home or darwin's
|
||||||
application support folder.
|
application support folder.
|
||||||
"""
|
'''
|
||||||
|
|
||||||
def _posixify(name):
|
|
||||||
return "-".join(name.split()).lower()
|
|
||||||
|
|
||||||
# NOTE: for testing with `pytest` we leverage the `tmp_dir`
|
# NOTE: for testing with `pytest` we leverage the `tmp_dir`
|
||||||
# fixture to generate (and clean up) a test-request-specific
|
# fixture to generate (and clean up) a test-request-specific
|
||||||
# directory for isolated configuration files such that,
|
# directory for isolated configuration files such that,
|
||||||
|
|
@ -117,23 +94,30 @@ def get_app_dir(
|
||||||
# assert testdirpath.exists(), 'piker test harness might be borked!?'
|
# assert testdirpath.exists(), 'piker test harness might be borked!?'
|
||||||
# app_name = str(testdirpath)
|
# app_name = str(testdirpath)
|
||||||
|
|
||||||
if platform.system() == 'Windows':
|
os_name: str = platform.system()
|
||||||
key = "APPDATA" if roaming else "LOCALAPPDATA"
|
conf_dir: Path = platformdirs.user_config_path()
|
||||||
folder = os.environ.get(key)
|
app_dir: Path = conf_dir / app_name
|
||||||
if folder is None:
|
|
||||||
folder = os.path.expanduser("~")
|
# ?TODO, from `click`; can remove?
|
||||||
return os.path.join(folder, app_name)
|
|
||||||
if force_posix:
|
if force_posix:
|
||||||
|
def _posixify(name):
|
||||||
|
return "-".join(name.split()).lower()
|
||||||
|
|
||||||
return os.path.join(
|
return os.path.join(
|
||||||
os.path.expanduser("~/.{}".format(_posixify(app_name))))
|
os.path.expanduser(
|
||||||
if sys.platform == "darwin":
|
"~/.{}".format(
|
||||||
return os.path.join(
|
_posixify(app_name)
|
||||||
os.path.expanduser("~/Library/Application Support"), app_name
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return os.path.join(
|
|
||||||
os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")),
|
log.info(
|
||||||
_posixify(app_name),
|
f'Using user config directory,\n'
|
||||||
|
f'platform.system(): {os_name!r}\n'
|
||||||
|
f'conf_dir: {conf_dir!r}\n'
|
||||||
|
f'app_dir: {conf_dir!r}\n'
|
||||||
)
|
)
|
||||||
|
return app_dir
|
||||||
|
|
||||||
|
|
||||||
_click_config_dir: Path = Path(get_app_dir('piker'))
|
_click_config_dir: Path = Path(get_app_dir('piker'))
|
||||||
|
|
@ -250,7 +234,9 @@ def repodir() -> Path:
|
||||||
repodir: Path = Path(os.environ.get('GITHUB_WORKSPACE'))
|
repodir: Path = Path(os.environ.get('GITHUB_WORKSPACE'))
|
||||||
confdir: Path = repodir / 'config'
|
confdir: Path = repodir / 'config'
|
||||||
|
|
||||||
assert confdir.is_dir(), f'{confdir} DNE, {repodir} is likely incorrect!'
|
assert confdir.is_dir(), (
|
||||||
|
f'{confdir} DNE, {repodir} is likely incorrect!'
|
||||||
|
)
|
||||||
return repodir
|
return repodir
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -739,12 +739,21 @@ async def start_backfill(
|
||||||
# including the dst[/src] source asset token. SO,
|
# including the dst[/src] source asset token. SO,
|
||||||
# 'tsla.nasdaq.ib' over 'tsla/usd.nasdaq.ib' for
|
# 'tsla.nasdaq.ib' over 'tsla/usd.nasdaq.ib' for
|
||||||
# historical reasons ONLY.
|
# historical reasons ONLY.
|
||||||
if mkt.dst.atype not in {
|
if (
|
||||||
'crypto',
|
mkt.dst.atype not in {
|
||||||
'crypto_currency',
|
'crypto',
|
||||||
'fiat', # a "forex pair"
|
'crypto_currency',
|
||||||
'perpetual_future', # stupid "perps" from cex land
|
'fiat', # a "forex pair"
|
||||||
}:
|
'perpetual_future', # stupid "perps" from cex land
|
||||||
|
}
|
||||||
|
and not (
|
||||||
|
mkt.src.atype == 'crypto_currency'
|
||||||
|
and
|
||||||
|
mkt.dst.atype in {
|
||||||
|
'future',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
):
|
||||||
col_sym_key: str = mkt.get_fqme(
|
col_sym_key: str = mkt.get_fqme(
|
||||||
delim_char='',
|
delim_char='',
|
||||||
without_src=True,
|
without_src=True,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue