Files
Funding_Rate/ng.py
2026-05-07 00:25:49 +00:00

102 lines
4.1 KiB
Python

import os
from nicegui import ui, app
from sqlalchemy import create_engine
# import requests
import json
# import time
# import re
import valkey
import asyncio
# import datetime as dt
# from random import random
# from nicegui_modules import data
# from nicegui_modules import ui_components
ALLOW_BODY_SCROLL: bool = True
LOOKBACK: int = 60
LOOKBACK_RT_TV_MAX_POINTS: int = 3000
REFRESH_INTERVAL_SEC: float = 10
REFRESH_INTERVAL_RT_SEC: float = 1/30
ENGINE = create_engine('mysql+pymysql://root:pwd@localhost/fund_rate')
VALKEY = valkey.Valkey(host='localhost', port=6379, db=0, decode_responses=True)
### Utils ###
def update_body_scroll(e=None, bool_override=False):
if e is None:
if bool_override:
ui.query('body').style('height: 100%; overflow-y: auto;')
else:
ui.query('body').style('height: 100%; overflow-y: hidden;')
else:
if e.value:
ui.query('body').style('height: 100%; overflow-y: auto;')
else:
ui.query('body').style('height: 100%; overflow-y: hidden;')
### Callbacks ###
async def update_tv():
series_update_aster_tob = json.loads(VALKEY.get('fut_ticker_aster')) # ty:ignore[invalid-argument-type]
series_update_extend_tob = json.loads(VALKEY.get('fut_ticker_extended')) # ty:ignore[invalid-argument-type]
series_update_algo_status = json.loads(VALKEY.get('algo_status')) # ty:ignore[invalid-argument-type]
timestamp_aster_tob = round( ( series_update_aster_tob['timestamp_arrival'] / 1000 ) , 2)
timestamp_extend_tob = round( ( series_update_extend_tob['timestamp_arrival'] / 1000 ) , 2)
timestamp_algo_status = round( ( series_update_algo_status['timestamp_arrival'] / 1000 ) , 2)
value_aster_tob = ( float(series_update_aster_tob['best_ask_px']) + float(series_update_aster_tob['best_bid_px']) ) / 2
value_extend_tob = ( float(series_update_extend_tob['best_ask_px']) + float(series_update_extend_tob['best_bid_px']) ) / 2
value_algo_expected_alpha = float(series_update_algo_status['price'])
data_dict = {
'timestamp': timestamp_aster_tob,
'timestamp_b': timestamp_extend_tob,
'timestamp_c': timestamp_algo_status,
'value': value_aster_tob,
'value_b': value_extend_tob,
'value_c': value_algo_expected_alpha,
'target': series_update_algo_status['target_price'],
'LOOKBACK_RT_TV_MAX_POINTS': LOOKBACK_RT_TV_MAX_POINTS,
}
ui.run_javascript(f'await update_tv(data_dict={data_dict});')
### Pages ###
async def rt_chart_page():
global LOOKBACK
LOOKBACK = app.storage.user.get('lookback', LOOKBACK)
timer = ui.timer(REFRESH_INTERVAL_RT_SEC, update_tv)
with ui.row():
with ui.column():
ui.switch('☸︎', value=ALLOW_BODY_SCROLL, on_change=lambda e: update_body_scroll(e))
with ui.column():
ui.switch('▶️', value=True).bind_value_to(timer, 'active')
with ui.column().style('position: absolute; right: 20px; font-family: monospace; align-self: center;'):
ui.label('Atwater Trading: Orderbook')
with ui.grid(columns=16).classes('w-full gap-0 auto-fit'):
with ui.card().tight().classes('w-full col-span-full no-shadow border border-black-200').style('overflow: auto;'):
ui.html('<div id="tv" style="width:100%; height:800px;"></div>', sanitize=False).classes('w-full')
ui.run_javascript('await create_tv();')
def root():
app.add_static_files(max_cache_age=0, url_path='/static', local_directory=os.path.join(os.path.dirname(__file__), 'nicegui_modules/static'))
ui.add_head_html('''
<meta name="darkreader-lock">
<link rel="stylesheet" type="text/css" href="/static/styles.css">
<script type="text/javascript" src="https://unpkg.com/lightweight-charts/dist/lightweight-charts.standalone.production.js"></script>
<script src="/static/script.js"></script>
'''
)
# ui.add_head_html('<meta name="darkreader-lock">')
update_body_scroll(bool_override=ALLOW_BODY_SCROLL)
ui.sub_pages({
'/': rt_chart_page,
}).classes('w-full')
ui.run(root, storage_secret="123ABC", reload=True, dark=True, title='Atwater Trading')