Compare commits
2 Commits
b2cfa3444f
...
499b2d0090
Author | SHA1 | Date |
---|---|---|
|
499b2d0090 | |
|
8b0f1e7045 |
|
@ -219,9 +219,11 @@ def get_config() -> dict[str, Any]:
|
|||
touch_if_dne=True,
|
||||
)
|
||||
section: dict = {}
|
||||
section['deribit'] = conf.get('deribit')
|
||||
section = conf.get('deribit')
|
||||
|
||||
section['log'] = {}
|
||||
section['log']['filename'] = 'feedhandler.log'
|
||||
section['log']['level'] = 'DEBUG'
|
||||
section['log']['disabled'] = True
|
||||
|
||||
if section is None:
|
||||
|
@ -230,6 +232,22 @@ def get_config() -> dict[str, Any]:
|
|||
|
||||
return section
|
||||
|
||||
def get_fh_config() -> dict[str, Any]:
|
||||
conf_option = get_config().get('option', {})
|
||||
conf_log = get_config().get('log', {})
|
||||
|
||||
return {
|
||||
'log': {
|
||||
'filename': conf_log.get('filename'),
|
||||
'level': conf_log.get('level'),
|
||||
'disabled': conf_log.get('disabled')
|
||||
},
|
||||
'deribit': {
|
||||
'key_id': conf_option.get('api_key'),
|
||||
'key_secret': conf_option.get('api_secret')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Client:
|
||||
|
||||
|
@ -241,10 +259,10 @@ class Client:
|
|||
) -> None:
|
||||
self._pairs: dict[str, Any] = None
|
||||
|
||||
config = get_config().get('deribit', {})
|
||||
config = get_config().get('option', {})
|
||||
|
||||
self._key_id = config.get('key_id')
|
||||
self._key_secret = config.get('key_secret')
|
||||
self._key_id = config.get('api_key')
|
||||
self._key_secret = config.get('api_secret')
|
||||
|
||||
self.json_rpc = json_rpc
|
||||
|
||||
|
@ -466,7 +484,6 @@ async def get_client(
|
|||
) as json_rpc
|
||||
):
|
||||
client = Client(json_rpc)
|
||||
|
||||
_refresh_token: Optional[str] = None
|
||||
_access_token: Optional[str] = None
|
||||
|
||||
|
@ -536,7 +553,7 @@ async def get_client(
|
|||
|
||||
@acm
|
||||
async def open_feed_handler():
|
||||
fh = FeedHandler(config=get_config())
|
||||
fh = FeedHandler(config=get_fh_config())
|
||||
yield fh
|
||||
await to_asyncio.run_task(fh.stop_async)
|
||||
|
||||
|
@ -581,11 +598,11 @@ async def aio_price_feed_relay(
|
|||
'price': float(data.ask_price), 'size': float(data.ask_size)}
|
||||
]
|
||||
}))
|
||||
|
||||
sym: Symbol = piker_sym_to_cb_sym(instrument)
|
||||
fh.add_feed(
|
||||
DERIBIT,
|
||||
channels=[TRADES, L1_BOOK],
|
||||
symbols=[piker_sym_to_cb_sym(instrument)],
|
||||
symbols=[sym],
|
||||
callbacks={
|
||||
TRADES: _trade,
|
||||
L1_BOOK: _l1
|
||||
|
@ -626,9 +643,9 @@ async def maybe_open_price_feed(
|
|||
async with maybe_open_context(
|
||||
acm_func=open_price_feed,
|
||||
kwargs={
|
||||
'instrument': instrument
|
||||
'instrument': instrument.split('.')[0]
|
||||
},
|
||||
key=f'{instrument}-price',
|
||||
key=f'{instrument.split('.')[0]}-price',
|
||||
) as (cache_hit, feed):
|
||||
if cache_hit:
|
||||
yield broadcast_receiver(feed, 10)
|
||||
|
@ -693,10 +710,10 @@ async def maybe_open_order_feed(
|
|||
async with maybe_open_context(
|
||||
acm_func=open_order_feed,
|
||||
kwargs={
|
||||
'instrument': instrument,
|
||||
'instrument': instrument.split('.')[0],
|
||||
'fh': fh
|
||||
},
|
||||
key=f'{instrument}-order',
|
||||
key=f'{instrument.split('.')[0]}-order',
|
||||
) as (cache_hit, feed):
|
||||
if cache_hit:
|
||||
yield broadcast_receiver(feed, 10)
|
||||
|
|
|
@ -156,7 +156,7 @@ async def stream_quotes(
|
|||
},
|
||||
}
|
||||
|
||||
nsym = piker_sym_to_cb_sym(sym)
|
||||
nsym = piker_sym_to_cb_sym(sym.split('.')[0])
|
||||
|
||||
async with maybe_open_price_feed(sym) as stream:
|
||||
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
# piker: trading gear for hackers
|
||||
# Copyright (C) Tyler Goodlet (in stewardship for pikers)
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
Per market data-type definitions and schemas types.
|
||||
|
||||
"""
|
||||
from __future__ import annotations
|
||||
from typing import (
|
||||
Literal,
|
||||
)
|
||||
from decimal import Decimal
|
||||
|
||||
from msgspec import field
|
||||
|
||||
from piker.types import Struct
|
||||
|
||||
|
||||
# API endpoint paths by venue / sub-API
|
||||
_domain: str = 'deribit.com'
|
||||
_url = f'https://www.{_domain}'
|
||||
|
||||
# WEBsocketz
|
||||
_ws_url: str = f'wss://www.{_domain}/ws/api/v2'
|
||||
|
||||
# test nets
|
||||
_testnet_ws_url: str = f'wss://test.{_domain}/ws/api/v2'
|
||||
|
||||
MarketType = Literal[
|
||||
'option'
|
||||
]
|
||||
|
||||
|
||||
def get_api_eps(venue: MarketType) -> tuple[str, str]:
|
||||
'''
|
||||
Return API ep root paths per venue.
|
||||
|
||||
'''
|
||||
return {
|
||||
'option': (
|
||||
_ws_url,
|
||||
),
|
||||
}[venue]
|
||||
|
||||
|
||||
class OptionPair(Struct, frozen=True, kw_only=True):
|
||||
|
||||
symbol: str
|
||||
venue: str
|
||||
|
||||
# src
|
||||
quote_currency: str
|
||||
|
||||
# dst
|
||||
base_currency: str
|
||||
|
||||
tick_size: float # 0.0001
|
||||
tick_size_steps: list[dict] # [{'above_price': 0.005, 'tick_size': 0.0005}]
|
||||
taker_commission: float # 0.0003
|
||||
strike: float # 5000.0
|
||||
settlement_period: str # 'day'
|
||||
settlement_currency: str # "BTC",
|
||||
rfq: bool # false
|
||||
quote_currency: str # 'BTC'
|
||||
price_index: str # 'btc_usd'
|
||||
option_type: str # 'call'
|
||||
min_trade_amount: float # 0.1
|
||||
maker_commission: float # 0.0003
|
||||
kind: str # 'option'
|
||||
is_active: bool # true
|
||||
instrument_type: str # 'reversed'
|
||||
instrument_name: str # 'BTC-1SEP24-55000-C'
|
||||
instrument_id: int # 364671
|
||||
expiration_timestamp: int # 1725177600000
|
||||
creation_timestamp: int # 1724918461000
|
||||
counter_currency: str # 'USD'
|
||||
contract_size: float # '1.0'
|
||||
block_trade_tick_size: float # '0.0001'
|
||||
block_trade_min_trade_amount: int # '25'
|
||||
block_trade_commission: float # '0.003'
|
||||
|
||||
|
||||
# NOTE: see `.data._symcache.SymbologyCache.load()` for why
|
||||
ns_path: str = 'piker.brokers.deribit:OptionPair'
|
||||
|
||||
@property
|
||||
def venue(self) -> str:
|
||||
return 'OPTION'
|
||||
|
||||
@property
|
||||
def bs_fqme(self) -> str:
|
||||
return f'{self.symbol}.OPTION'
|
||||
|
||||
@property
|
||||
def bs_src_asset(self) -> str:
|
||||
return f'{self.quote_currency}'
|
||||
|
||||
@property
|
||||
def bs_dst_asset(self) -> str:
|
||||
return f'{self.base_currency}'
|
||||
|
||||
@property
|
||||
def bs_mktid(self) -> str:
|
||||
return f'{self.symbol}.{self.venue}'
|
||||
|
||||
|
Loading…
Reference in New Issue