Source code for h2o_dashboard.pages.okx_dashbaord_page.okx_orders_widget
import time
from typing import List
from h2o_wave import Q, ui, on, data, run_on, AsyncSite, pack # noqa F401
from h2o_dashboard.util import add_card, convert_to_col_type
from pyokx.data_structures import Algo_Order
from pyokx.redis_structured_streams import get_stream_okx_incomplete_algo_orders
[docs]
class OKX_Orders_StreamWidget:
def __init__(self, q: Q, card_name: str, box: str):
self.q = q
self.algo_orders_rest_stream: List[List[Algo_Order]] = []
self.card_name = card_name
self.box = box
self.okx_order_column_mappings = dict(
ordId={'label': 'Order ID', 'type': 'str'},
instId={'label': 'Instrument ID', 'type': 'str'},
state={'label': 'State', 'type': 'str'},
pnl={'label': 'Profit/Loss', 'type': 'float'},
sz={'label': 'Size', 'type': 'float'},
fillSz={'label': 'Fill Size', 'type': 'float'},
side={'label': 'Side', 'type': 'str'},
ordType={'label': 'Type', 'type': 'str'},
avgPx={'label': 'Avg Price', 'type': 'float'},
fee={'label': 'Fee', 'type': 'float'},
fillFee={'label': 'Fill Fee', 'type': 'float'},
lever={'label': 'Leverage', 'type': 'float'},
# slOrdPx={'label': 'SL Order Price', 'type': 'float'},
# slTriggerPx={'label': 'SL Trigger Price', 'type': 'float'},
# tpOrdPx={'label': 'TP Order Price', 'type': 'float'},
# tpTriggerPx={'label': 'TP Trigger Price', 'type': 'float'},
execType={'label': 'ExecType', 'type': 'str'},
feeCcy={'label': 'Fee Currency', 'type': 'str'},
fillPnl={'label': 'Fill Profit/Loss', 'type': 'float'},
fillFeeCcy={'label': 'Fill Fee Currency', 'type': 'str'},
msg={'label': 'Message', 'type': 'str'},
cancelSource={'label': 'Cancel Source', 'type': 'str'},
cTime={'label': 'cTime', 'type': 'timestamp'},
uTime={'label': 'uTime', 'type': 'timestamp'},
)
self.okx_order_column_mappings = dict(
ordId={'label': 'Order ID', 'type': 'str'},
instId={'label': 'Instrument ID', 'type': 'str'},
state={'label': 'State', 'type': 'str'},
pnl={'label': 'Profit/Loss', 'type': 'float'},
sz={'label': 'Size', 'type': 'float'},
fillSz={'label': 'Fill Size', 'type': 'float'},
side={'label': 'Side', 'type': 'str'},
ordType={'label': 'Type', 'type': 'str'},
avgPx={'label': 'Avg Price', 'type': 'float'},
fee={'label': 'Fee', 'type': 'float'},
fillFee={'label': 'Fill Fee', 'type': 'float'},
lever={'label': 'Leverage', 'type': 'float'},
# slOrdPx={'label': 'SL Order Price', 'type': 'float'},
# slTriggerPx={'label': 'SL Trigger Price', 'type': 'float'},
# tpOrdPx={'label': 'TP Order Price', 'type': 'float'},
# tpTriggerPx={'label': 'TP Trigger Price', 'type': 'float'},
execType={'label': 'ExecType', 'type': 'str'},
feeCcy={'label': 'Fee Currency', 'type': 'str'},
fillPnl={'label': 'Fill Profit/Loss', 'type': 'float'},
fillFeeCcy={'label': 'Fill Fee Currency', 'type': 'str'},
msg={'label': 'Message', 'type': 'str'},
cancelSource={'label': 'Cancel Source', 'type': 'str'},
cTime={'label': 'cTime', 'type': 'timestamp'},
uTime={'label': 'uTime', 'type': 'timestamp'},
)
self.okx_algo_order_column_mappings = dict(
algoClOrdId={'label': 'Order ID', 'type': 'str'},
instId={'label': 'Instrument ID', 'type': 'str'},
state={'label': 'State', 'type': 'str'},
# pnl={'label': 'Profit/Loss', 'type': 'float'},
sz={'label': 'Size', 'type': 'float'},
# fillSz={'label': 'Fill Size', 'type': 'float'},
side={'label': 'Side', 'type': 'str'},
ordType={'label': 'Type', 'type': 'str'},
# avgPx={'label': 'Avg Price', 'type': 'float'},
# fee={'label': 'Fee', 'type': 'float'},
# fillFee={'label': 'Fill Fee', 'type': 'float'},
lever={'label': 'Leverage', 'type': 'float'},
ordPx={'label': 'Exec Price', 'type': 'float'},
triggerPx={'label': 'Trigger Price', 'type': 'float'},
# slOrdPx={'label': 'SL Order Price', 'type': 'float'},
# slTriggerPx={'label': 'SL Trigger Price', 'type': 'float'},
# tpOrdPx={'label': 'TP Order Price', 'type': 'float'},
# tpTriggerPx={'label': 'TP Trigger Price', 'type': 'float'},
# execType={'label': 'ExecType', 'type': 'str'},
# feeCcy={'label': 'Fee Currency', 'type': 'str'},
# fillPnl={'label': 'Fill Profit/Loss', 'type': 'float'},
# fillFeeCcy={'label': 'Fill Fee Currency', 'type': 'str'},
# msg={'label': 'Message', 'type': 'str'},
# cancelSource={'label': 'Cancel Source', 'type': 'str'},
cTime={'label': 'cTime', 'type': 'timestamp'},
# uTime={'label': 'uTime', 'type': 'timestamp'},
)
async def _update_stream(self):
self.algo_orders_rest_stream: List[List[Algo_Order]] = await get_stream_okx_incomplete_algo_orders(
async_redis=self.q.client.async_redis)
return self.algo_orders_rest_stream
async def _is_initialized(self):
return len(self.algo_orders_rest_stream) > 0
[docs]
async def get_ui_algo_orders_table(self, box: str):
if await self._is_initialized():
last_n_orders_data: List[Algo_Order] = self.algo_orders_rest_stream[-1]
else:
print('Not initialized')
last_n_orders_data = []
print(f'last_n_orders_data: {last_n_orders_data}')
items = []
labels = []
for order in last_n_orders_data:
label_value = ''
values = []
newest_update = True
for i, (col_key, col_value) in enumerate(self.okx_algo_order_column_mappings.items()):
if i == 0:
label_value = f'{getattr(order, col_key)}'
if label_value in labels:
newest_update = False
break
newest_update = True
labels.append(label_value)
continue
order_col = getattr(order, col_key)
expected_type = None
try:
expected_type = col_value['type']
order_col = convert_to_col_type(order_col, expected_type)
except ValueError:
print(f"Error converting {col_key} to {expected_type}")
value = str(order_col)
values.append(value)
if newest_update:
items.append(ui.stat_table_item(label=label_value, values=values))
return ui.stat_table_card(
box=box,
title=f'Live Algo Orders - okx:rest@algo-orders (does not include completed or unfulfilled orders)',
columns=[col_value['label'] for col_value in self.okx_algo_order_column_mappings.values()],
items=items
)
[docs]
async def add_cards(self):
await self._update_stream()
await add_card(self.q, self.card_name + '_orders_table',
await self.get_ui_algo_orders_table(box=self.box))
await self.q.page.save()
[docs]
async def update_cards(self):
await self._update_stream()
if await self._is_initialized():
last_n_orders_data: List[Algo_Order] = self.algo_orders_rest_stream[-1]
else:
print('Not initialized')
last_n_orders_data = []
orders_table_card: ui.stat_table_card = self.q.page[self.card_name + '_orders_table']
items = []
labels = []
for order in last_n_orders_data:
label_value = ''
values = []
newest_update = True
for i, (col_key, col_value) in enumerate(self.okx_algo_order_column_mappings.items()):
if i == 0:
label_value = f'{getattr(order, col_key)}'
if label_value in labels:
newest_update = False
break
newest_update = True
labels.append(label_value)
continue
order_col = getattr(order, col_key)
expected_type = None
try:
expected_type = col_value['type']
order_col = convert_to_col_type(order_col, expected_type)
except ValueError:
print(f"Error converting {col_key} to {expected_type}")
value = str(order_col)
values.append(value)
if newest_update:
items.append(ui.stat_table_item(label=label_value, values=values))
orders_table_card.items = items
await self.q.page.save()