update switching fr logic for expected alpha
This commit is contained in:
23
algo.ipynb
23
algo.ipynb
@@ -2,7 +2,7 @@
|
|||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 7,
|
"execution_count": 1,
|
||||||
"id": "d1eed397",
|
"id": "d1eed397",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 8,
|
"execution_count": 2,
|
||||||
"id": "c6151613",
|
"id": "c6151613",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 9,
|
"execution_count": null,
|
||||||
"id": "d83c61e5",
|
"id": "d83c61e5",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@@ -48,6 +48,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
|
"\n",
|
||||||
"config_update = {\n",
|
"config_update = {\n",
|
||||||
" # 'Config': {\n",
|
" # 'Config': {\n",
|
||||||
" # 'Price_Worsener_Aster': 0,\n",
|
" # 'Price_Worsener_Aster': 0,\n",
|
||||||
@@ -57,15 +58,15 @@
|
|||||||
" # },\n",
|
" # },\n",
|
||||||
" 'Logging': {\n",
|
" 'Logging': {\n",
|
||||||
" 'Log_Summary_Each_Loop': False,\n",
|
" 'Log_Summary_Each_Loop': False,\n",
|
||||||
" 'Print_Summary_Each_Loop': True,\n",
|
" 'Print_Summary_Each_Loop': False,\n",
|
||||||
" },\n",
|
|
||||||
" 'Overrides': {\n",
|
|
||||||
" 'Allow_Ordering_Aster': True,\n",
|
|
||||||
" 'Allow_Ordering_Extend': True,\n",
|
|
||||||
" 'Allow_Symbol_Change': True,\n",
|
|
||||||
" # 'Flatten_Open_Positions': False,\n",
|
|
||||||
" # 'Flatten_Open_Positions_Opportunistic': False,\n",
|
|
||||||
" },\n",
|
" },\n",
|
||||||
|
" # 'Overrides': {\n",
|
||||||
|
" # 'Allow_Ordering_Aster': True,\n",
|
||||||
|
" # 'Allow_Ordering_Extend': True,\n",
|
||||||
|
" # 'Allow_Symbol_Change': True,\n",
|
||||||
|
" # # 'Flatten_Open_Positions': False,\n",
|
||||||
|
" # # 'Flatten_Open_Positions_Opportunistic': False,\n",
|
||||||
|
" # },\n",
|
||||||
"}\n",
|
"}\n",
|
||||||
"VAL_KEY.publish('fr_orchestrator_input', json.dumps(config_update))"
|
"VAL_KEY.publish('fr_orchestrator_input', json.dumps(config_update))"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"Updated_Timestamp": 1778133411421,
|
"Updated_Timestamp": 1778178429902,
|
||||||
"Config": {
|
"Config": {
|
||||||
"Loop_Sleep_Sec": 0.0,
|
"Loop_Sleep_Sec": 0.0,
|
||||||
"Max_Order_Over_Notional_Ratio": 1.05,
|
"Max_Order_Over_Notional_Ratio": 1.05,
|
||||||
|
|||||||
@@ -204,8 +204,8 @@ async def loop() -> None:
|
|||||||
|
|
||||||
df_best_fr_rate['last_trade_ts_dt_ast'] = pd.to_datetime(df_best_fr_rate['last_trade_ts_ast'], unit='ms')
|
df_best_fr_rate['last_trade_ts_dt_ast'] = pd.to_datetime(df_best_fr_rate['last_trade_ts_ast'], unit='ms')
|
||||||
df_best_fr_rate['last_trade_ts_dt_ext'] = pd.to_datetime(df_best_fr_rate['last_trade_ts_ext'], unit='ms')
|
df_best_fr_rate['last_trade_ts_dt_ext'] = pd.to_datetime(df_best_fr_rate['last_trade_ts_ext'], unit='ms')
|
||||||
df_best_fr_rate = df_best_fr_rate.loc[( (datetime.now().timestamp()*1000 )-df_best_fr_rate['last_trade_ts_ast']) < (3*60*1000) ]
|
df_best_fr_rate = df_best_fr_rate.loc[( (datetime.now().timestamp()*1000 )-df_best_fr_rate['last_trade_ts_ast']) < (5*60*1000) ] # Last traded in 3min
|
||||||
df_best_fr_rate = df_best_fr_rate.loc[( (datetime.now().timestamp()*1000 )-df_best_fr_rate['last_trade_ts_ext']) < (15*60*1000) ]
|
# df_best_fr_rate = df_best_fr_rate.loc[( (datetime.now().timestamp()*1000 )-df_best_fr_rate['last_trade_ts_ext']) < (15*60*1000) ] # Last traded in 15min
|
||||||
|
|
||||||
# print(df_best_fr_rate.columns)
|
# print(df_best_fr_rate.columns)
|
||||||
# print(df_best_fr_rate.iloc[0])
|
# print(df_best_fr_rate.iloc[0])
|
||||||
|
|||||||
61
main.py
61
main.py
@@ -249,33 +249,34 @@ def signal_alpha_over_taker(
|
|||||||
alpha_hurdle_adj: Decimal = Decimal('0.00'),
|
alpha_hurdle_adj: Decimal = Decimal('0.00'),
|
||||||
) -> Signal:
|
) -> Signal:
|
||||||
|
|
||||||
|
|
||||||
|
if funding_rate_exch == 'ASTER':
|
||||||
|
if funding_rate_side == 'BUY':
|
||||||
|
aster_buy_fund_rate_return = abs(funding_rate)
|
||||||
|
extend_buy_fund_rate_return = abs(funding_rate) * -1
|
||||||
|
else:
|
||||||
|
aster_buy_fund_rate_return = abs(funding_rate) * -1
|
||||||
|
extend_buy_fund_rate_return = abs(funding_rate)
|
||||||
|
else: # funding_rate_exch == 'EXTEND':
|
||||||
|
if funding_rate_side == 'BUY':
|
||||||
|
aster_buy_fund_rate_return = abs(funding_rate) * -1
|
||||||
|
extend_buy_fund_rate_return = abs(funding_rate)
|
||||||
|
else:
|
||||||
|
aster_buy_fund_rate_return = abs(funding_rate)
|
||||||
|
extend_buy_fund_rate_return = abs(funding_rate) * -1
|
||||||
|
|
||||||
|
|
||||||
if Config.Overrides.Flatten_Open_Positions_Opportunistic:
|
if Config.Overrides.Flatten_Open_Positions_Opportunistic:
|
||||||
if Decimal(str(Aster.notional_position)) > 0:
|
if Decimal(str(Aster.notional_position)) > 0:
|
||||||
aster_buy_fund_rate_return = abs(funding_rate_switch) * -1
|
aster_buy_fund_rate_return = aster_buy_fund_rate_return
|
||||||
extend_buy_fund_rate_return = abs(funding_rate_switch)
|
extend_buy_fund_rate_return = max([extend_buy_fund_rate_return, abs(funding_rate_switch)])
|
||||||
# funding_rate_exch = 'EXTEND'
|
# funding_rate_exch = 'EXTEND'
|
||||||
# funding_rate_side = 'BUY'
|
# funding_rate_side = 'BUY'
|
||||||
else: # Decimal(str(Aster.notional_position)) < 0:
|
else: # Decimal(str(Aster.notional_position)) < 0:
|
||||||
aster_buy_fund_rate_return = abs(funding_rate_switch)
|
aster_buy_fund_rate_return = max([aster_buy_fund_rate_return, abs(funding_rate_switch)])
|
||||||
extend_buy_fund_rate_return = abs(funding_rate_switch) * -1
|
extend_buy_fund_rate_return = extend_buy_fund_rate_return
|
||||||
# funding_rate_exch = 'ASTER'
|
# funding_rate_exch = 'ASTER'
|
||||||
# funding_rate_side = 'BUY'
|
# funding_rate_side = 'BUY'
|
||||||
else:
|
|
||||||
if funding_rate_exch == 'ASTER':
|
|
||||||
if funding_rate_side == 'BUY':
|
|
||||||
aster_buy_fund_rate_return = abs(funding_rate)
|
|
||||||
extend_buy_fund_rate_return = abs(funding_rate) * -1
|
|
||||||
else:
|
|
||||||
aster_buy_fund_rate_return = abs(funding_rate) * -1
|
|
||||||
extend_buy_fund_rate_return = abs(funding_rate)
|
|
||||||
else: # funding_rate_exch == 'EXTEND':
|
|
||||||
if funding_rate_side == 'BUY':
|
|
||||||
aster_buy_fund_rate_return = abs(funding_rate) * -1
|
|
||||||
extend_buy_fund_rate_return = abs(funding_rate)
|
|
||||||
else:
|
|
||||||
aster_buy_fund_rate_return = abs(funding_rate)
|
|
||||||
extend_buy_fund_rate_return = abs(funding_rate) * -1
|
|
||||||
|
|
||||||
|
|
||||||
aster_mid_px: Decimal = ( Decimal(str(aster_ticker_dict['best_ask_px'])) + Decimal(str(aster_ticker_dict['best_bid_px'])) ) / 2
|
aster_mid_px: Decimal = ( Decimal(str(aster_ticker_dict['best_ask_px'])) + Decimal(str(aster_ticker_dict['best_bid_px'])) ) / 2
|
||||||
extend_mid_px: Decimal = ( Decimal(str(extend_ticker_dict['best_ask_px'])) + Decimal(str(extend_ticker_dict['best_bid_px'])) ) / 2
|
extend_mid_px: Decimal = ( Decimal(str(extend_ticker_dict['best_ask_px'])) + Decimal(str(extend_ticker_dict['best_bid_px'])) ) / 2
|
||||||
@@ -288,7 +289,8 @@ def signal_alpha_over_taker(
|
|||||||
|
|
||||||
aster_buy_expected_alpha: Decimal = ( aster_buy_ratio_min_taker_hurdle - Decimal(str(Aster.buy_ratio)) ).quantize(Decimal('0.000001'), rounding='ROUND_DOWN') # Decimal Price % Diff (x Qty = Alpha $)
|
aster_buy_expected_alpha: Decimal = ( aster_buy_ratio_min_taker_hurdle - Decimal(str(Aster.buy_ratio)) ).quantize(Decimal('0.000001'), rounding='ROUND_DOWN') # Decimal Price % Diff (x Qty = Alpha $)
|
||||||
extend_buy_expected_alpha: Decimal = ( extend_buy_ratio_min_taker_hurdle - Decimal(str(Extend.buy_ratio)) ).quantize(Decimal('0.000001'), rounding='ROUND_DOWN') # Decimal Price % Diff (x Qty = Alpha $)
|
extend_buy_expected_alpha: Decimal = ( extend_buy_ratio_min_taker_hurdle - Decimal(str(Extend.buy_ratio)) ).quantize(Decimal('0.000001'), rounding='ROUND_DOWN') # Decimal Price % Diff (x Qty = Alpha $)
|
||||||
|
best_expected_alpha = max([aster_buy_expected_alpha, extend_buy_expected_alpha])
|
||||||
|
|
||||||
# logging.info(f'aster_buy_ratio_min_taker_hurdle: ( {aster_buy_ratio} - {aster_buy_fund_rate_return} ) - {taker_fee} - {alpha_hurdle_adj} = {aster_buy_ratio_min_taker_hurdle}')
|
# logging.info(f'aster_buy_ratio_min_taker_hurdle: ( {aster_buy_ratio} - {aster_buy_fund_rate_return} ) - {taker_fee} - {alpha_hurdle_adj} = {aster_buy_ratio_min_taker_hurdle}')
|
||||||
# logging.info(f'extend_buy_ratio_min_taker_hurdle: ( {extend_buy_ratio} - {extend_buy_fund_rate_return} ) - {taker_fee} - {alpha_hurdle_adj} = {extend_buy_ratio_min_taker_hurdle}')
|
# logging.info(f'extend_buy_ratio_min_taker_hurdle: ( {extend_buy_ratio} - {extend_buy_fund_rate_return} ) - {taker_fee} - {alpha_hurdle_adj} = {extend_buy_ratio_min_taker_hurdle}')
|
||||||
# logging.info(f'aster_buy_expected_alpha: {aster_buy_ratio_min_taker_hurdle} - {Decimal(str(Aster.buy_ratio))} = {aster_buy_expected_alpha}')
|
# logging.info(f'aster_buy_expected_alpha: {aster_buy_ratio_min_taker_hurdle} - {Decimal(str(Aster.buy_ratio))} = {aster_buy_expected_alpha}')
|
||||||
@@ -299,7 +301,7 @@ def signal_alpha_over_taker(
|
|||||||
# aster_buy_expected_alpha : 0.000673878630659394266895260 - 0.0014628375 = -0.0007
|
# aster_buy_expected_alpha : 0.000673878630659394266895260 - 0.0014628375 = -0.0007
|
||||||
# extend_buy_expected_alpha : -0.001173878630659394266895260 - -0.0014628375 = 0.0002
|
# extend_buy_expected_alpha : -0.001173878630659394266895260 - -0.0014628375 = 0.0002
|
||||||
|
|
||||||
if aster_buy_expected_alpha > 0:
|
if ( aster_buy_expected_alpha > 0 ) and ( best_expected_alpha == aster_buy_expected_alpha ):
|
||||||
signal: bool = True
|
signal: bool = True
|
||||||
exchange: str = 'ASTER'
|
exchange: str = 'ASTER'
|
||||||
side: str = 'BUY'
|
side: str = 'BUY'
|
||||||
@@ -307,7 +309,7 @@ def signal_alpha_over_taker(
|
|||||||
expected_alpha: Decimal = aster_buy_expected_alpha
|
expected_alpha: Decimal = aster_buy_expected_alpha
|
||||||
model_ratio: Decimal = Decimal(str(Aster.buy_ratio))
|
model_ratio: Decimal = Decimal(str(Aster.buy_ratio))
|
||||||
current_ratio: Decimal = aster_buy_ratio_min_taker_hurdle
|
current_ratio: Decimal = aster_buy_ratio_min_taker_hurdle
|
||||||
elif extend_buy_expected_alpha > 0:
|
elif ( extend_buy_expected_alpha > 0 ) and ( best_expected_alpha == extend_buy_expected_alpha ):
|
||||||
signal: bool = True
|
signal: bool = True
|
||||||
exchange: str = 'EXTEND'
|
exchange: str = 'EXTEND'
|
||||||
side: str = 'BUY'
|
side: str = 'BUY'
|
||||||
@@ -316,7 +318,7 @@ def signal_alpha_over_taker(
|
|||||||
model_ratio: Decimal = Decimal(str(Extend.buy_ratio))
|
model_ratio: Decimal = Decimal(str(Extend.buy_ratio))
|
||||||
current_ratio: Decimal = extend_buy_ratio_min_taker_hurdle
|
current_ratio: Decimal = extend_buy_ratio_min_taker_hurdle
|
||||||
else:
|
else:
|
||||||
if max([aster_buy_expected_alpha,extend_buy_expected_alpha]) == aster_buy_expected_alpha:
|
if best_expected_alpha == aster_buy_expected_alpha:
|
||||||
signal: bool = False
|
signal: bool = False
|
||||||
exchange: str = 'ASTER'
|
exchange: str = 'ASTER'
|
||||||
side: str = 'BUY'
|
side: str = 'BUY'
|
||||||
@@ -877,7 +879,7 @@ async def run_algo():
|
|||||||
aster_fund_rate = aster_fund_rate * -1
|
aster_fund_rate = aster_fund_rate * -1
|
||||||
extend_fund_rate = extend_fund_rate * -1
|
extend_fund_rate = extend_fund_rate * -1
|
||||||
|
|
||||||
aster_fund_rate_time = float(aster_fund_rate_dict.get('next_funding_time_ts_ms', 0))
|
aster_fund_rate_time = max([float(aster_fund_rate_dict.get('next_funding_time_ts_ms', 0)), 0])
|
||||||
aster_fund_rate_time = aster_fund_rate_time+(60*60*1000) if aster_fund_rate_time < (datetime.now().timestamp()*1000) else aster_fund_rate_time
|
aster_fund_rate_time = aster_fund_rate_time+(60*60*1000) if aster_fund_rate_time < (datetime.now().timestamp()*1000) else aster_fund_rate_time
|
||||||
|
|
||||||
extend_fund_rate_time = max([float(extend_fund_rate_dict.get('next_funding_time_ts_ms', 0)), 0])
|
extend_fund_rate_time = max([float(extend_fund_rate_dict.get('next_funding_time_ts_ms', 0)), 0])
|
||||||
@@ -893,7 +895,8 @@ async def run_algo():
|
|||||||
if next_funding_at_same_time:
|
if next_funding_at_same_time:
|
||||||
net_fr = max([fund_rate_ast, fund_rate_ext]) - min([fund_rate_ast, fund_rate_ext])
|
net_fr = max([fund_rate_ast, fund_rate_ext]) - min([fund_rate_ast, fund_rate_ext])
|
||||||
fr_best_exch = 'ASTER' if max([abs(fund_rate_ast), abs(fund_rate_ext)]) == abs(fund_rate_ast) else 'EXTEND'
|
fr_best_exch = 'ASTER' if max([abs(fund_rate_ast), abs(fund_rate_ext)]) == abs(fund_rate_ast) else 'EXTEND'
|
||||||
fr_best_side = 'BUY' if net_fr < 0 else 'SELL'
|
fr_best_rate = fund_rate_ast if max([abs(fund_rate_ast), abs(fund_rate_ext)]) == abs(fund_rate_ast) else fund_rate_ext
|
||||||
|
fr_best_side = 'BUY' if fr_best_rate < 0 else 'SELL'
|
||||||
return net_fr, fr_best_exch, fr_best_side
|
return net_fr, fr_best_exch, fr_best_side
|
||||||
else:
|
else:
|
||||||
fr_best_exch = 'EXTEND'
|
fr_best_exch = 'EXTEND'
|
||||||
@@ -1261,11 +1264,7 @@ async def main():
|
|||||||
VAL_KEY.set(name='fr_orchestrator_output', value=json.dumps(obj=Config.model_dump()))
|
VAL_KEY.set(name='fr_orchestrator_output', value=json.dumps(obj=Config.model_dump()))
|
||||||
VAL_KEY.set(name='fr_algo_working_symbol', value=json.dumps(obj={'ASTER': asdict(obj=Aster), 'EXTEND': asdict(obj=Extend)}))
|
VAL_KEY.set(name='fr_algo_working_symbol', value=json.dumps(obj={'ASTER': asdict(obj=Aster), 'EXTEND': asdict(obj=Extend)}))
|
||||||
|
|
||||||
Funding_Rates_Min_Remaining_Factor_Pcts = calc_fr_minutes_remaining_factor(
|
Funding_Rates_Min_Remaining_Factor_Pcts = calc_fr_minutes_remaining_factor()
|
||||||
min_start_procedure = 30,
|
|
||||||
min_to_end_procedure = 7,
|
|
||||||
factor_exp_pct = 0.50
|
|
||||||
)
|
|
||||||
|
|
||||||
Algo_Status = structs.Algo_Status(
|
Algo_Status = structs.Algo_Status(
|
||||||
last_update_ts_ms = int(round(datetime.now().timestamp()*1000, 2)),
|
last_update_ts_ms = int(round(datetime.now().timestamp()*1000, 2)),
|
||||||
|
|||||||
75
ng.py
75
ng.py
@@ -1,5 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
from nicegui import ui, app
|
from nicegui import ui, app, html
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
# import requests
|
# import requests
|
||||||
import json
|
import json
|
||||||
@@ -127,7 +127,8 @@ def update_body_scroll(e=None, bool_override=False):
|
|||||||
async def update_tv():
|
async def update_tv():
|
||||||
series_update_aster_tob = json.loads(VALKEY.get('fut_ticker_aster')) # ty:ignore[invalid-argument-type]
|
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_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]
|
series_update_algo_status = json.loads(VALKEY.get('algo_status')) # ty:ignore[invalid-argument-type]
|
||||||
|
master_data = json.loads(VALKEY.get(name='fr_engine_best_fund_rate_master')) # ty:ignore[invalid-argument-type]
|
||||||
|
|
||||||
timestamp_aster_tob = round( ( series_update_aster_tob['timestamp_transaction'] / 1000 ) , 2)
|
timestamp_aster_tob = round( ( series_update_aster_tob['timestamp_transaction'] / 1000 ) , 2)
|
||||||
timestamp_extend_tob = round( ( series_update_extend_tob['timestamp_msg'] / 1000 ) , 2)
|
timestamp_extend_tob = round( ( series_update_extend_tob['timestamp_msg'] / 1000 ) , 2)
|
||||||
@@ -172,18 +173,66 @@ async def rt_chart_page():
|
|||||||
LOOKBACK = app.storage.user.get('lookback', LOOKBACK)
|
LOOKBACK = app.storage.user.get('lookback', LOOKBACK)
|
||||||
timer = ui.timer(REFRESH_INTERVAL_RT_SEC, update_tv)
|
timer = ui.timer(REFRESH_INTERVAL_RT_SEC, update_tv)
|
||||||
|
|
||||||
with ui.row():
|
# ui.query('.q-page').classes('flex flex-col h-screen')
|
||||||
with ui.column():
|
|
||||||
ui.switch('☸︎', value=ALLOW_BODY_SCROLL, on_change=lambda e: update_body_scroll(e))
|
# with ui.row():
|
||||||
with ui.column():
|
# with ui.column():
|
||||||
ui.switch('▶️', value=True).bind_value_to(timer, 'active')
|
# ui.switch('☸︎', value=ALLOW_BODY_SCROLL, on_change=lambda e: update_body_scroll(e))
|
||||||
with ui.column().style('position: absolute; right: 20px; font-family: monospace; align-self: center;'):
|
# with ui.column():
|
||||||
ui.label('Atwater Trading - Funding Rate')
|
# 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 - Funding Rate')
|
||||||
|
|
||||||
with ui.grid(columns=16).classes('w-full gap-0 auto-fit'):
|
with ui.grid(columns=2, rows=2).classes('h-screen w-full flex-grow gap-2 auto-fit '):
|
||||||
with ui.card().tight().classes('w-full col-span-full no-shadow border border-black-200').style('overflow: auto;'):
|
aggrid = ui.aggrid({
|
||||||
ui.html('<div id="tv" style="width:100%; height:800px;"></div>', sanitize=False).classes('w-full')
|
'columnDefs': [
|
||||||
ui.run_javascript(f'await create_tv(charts_list={CHARTS}, create_chart_options={CHARTS_OPTIONS});')
|
{'field': 'name', 'editable': True, 'sortable': True},
|
||||||
|
{'field': 'age', 'editable': True},
|
||||||
|
{'field': 'id'},
|
||||||
|
],
|
||||||
|
'rowData': [
|
||||||
|
{'id': 0, 'name': 'Alice', 'age': 18},
|
||||||
|
{'id': 1, 'name': 'Bob', 'age': 21},
|
||||||
|
{'id': 2, 'name': 'Carol', 'age': 20},
|
||||||
|
],
|
||||||
|
'rowSelection': {'mode': 'multiRow'},
|
||||||
|
'stopEditingWhenCellsLoseFocus': True,
|
||||||
|
}).classes('auto-fit flex-grow w-full col-span-2 md:col-span-1')
|
||||||
|
# with ui.element(tag='div').classes('auto-fit flex-grow w-full').style("height:100%; width: 100%;"):
|
||||||
|
# with ui.tabs().classes('w-full') as tabs:
|
||||||
|
# one = ui.tab('One').classes('auto-fit flex-grow w-full').style("height:100%; width: 100%;")
|
||||||
|
# two = ui.tab('Two').classes('auto-fit flex-grow w-full').style("height:100%; width: 100%;")
|
||||||
|
# with ui.tab_panels(tabs, value=two).classes('auto-fit flex-grow w-full').style("height:100%; width: 100%;"):
|
||||||
|
# with ui.tab_panel(one).classes('auto-fit flex-grow w-full').style("height:100%; width: 100%;"):
|
||||||
|
# ui.label('First tab')
|
||||||
|
# with ui.tab_panel(two).classes('auto-fit flex-grow w-full').style("height:100%; width: 100%;"):
|
||||||
|
ui.html('<div id="tv" style="height:100%; width: 100%;"></div>', sanitize=False).classes('auto-fit flex-grow w-full col-span-2 md:col-span-1')
|
||||||
|
ui.run_javascript(f'await create_tv(charts_list={CHARTS}, create_chart_options={CHARTS_OPTIONS});')
|
||||||
|
|
||||||
|
with ui.element(tag='div').classes('col-span-2').style("height:100%; width: 100%;"):
|
||||||
|
with ui.tabs().classes('w-full') as tabs:
|
||||||
|
one = ui.tab('One')
|
||||||
|
two = ui.tab('Two')
|
||||||
|
with ui.tab_panels(tabs, value=two).classes('w-full').style("height:100%; width: 100%;"):
|
||||||
|
with ui.tab_panel(one):
|
||||||
|
ui.label('First tab')
|
||||||
|
with ui.tab_panel(two):
|
||||||
|
aggrid_2 = ui.aggrid({
|
||||||
|
'columnDefs': [
|
||||||
|
{'field': 'name', 'editable': True, 'sortable': True},
|
||||||
|
{'field': 'age', 'editable': True},
|
||||||
|
{'field': 'id'},
|
||||||
|
],
|
||||||
|
'rowData': [
|
||||||
|
{'id': 0, 'name': 'Alice', 'age': 18},
|
||||||
|
{'id': 1, 'name': 'Bob', 'age': 21},
|
||||||
|
{'id': 2, 'name': 'Carol', 'age': 20},
|
||||||
|
],
|
||||||
|
'rowSelection': {'mode': 'multiRow'},
|
||||||
|
'stopEditingWhenCellsLoseFocus': True,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def root():
|
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'))
|
app.add_static_files(max_cache_age=0, url_path='/static', local_directory=os.path.join(os.path.dirname(__file__), 'nicegui_modules/static'))
|
||||||
|
|||||||
@@ -36,10 +36,12 @@ async function update_tv(data_list, lookback_max_points) {
|
|||||||
|
|
||||||
|
|
||||||
async function create_tv(charts_list, create_chart_options) {
|
async function create_tv(charts_list, create_chart_options) {
|
||||||
|
const container = document.getElementById('tv');
|
||||||
|
|
||||||
if (create_chart_options.crosshair == 'NORMAL') {
|
if (create_chart_options.crosshair == 'NORMAL') {
|
||||||
create_chart_options.crosshair = { mode: LightweightCharts.CrosshairMode.Normal }
|
create_chart_options.crosshair = { mode: LightweightCharts.CrosshairMode.Normal }
|
||||||
};
|
};
|
||||||
window.chart = LightweightCharts.createChart(document.getElementById('tv'), create_chart_options);
|
window.chart = LightweightCharts.createChart(container, create_chart_options);
|
||||||
window.charts_arr = [];
|
window.charts_arr = [];
|
||||||
|
|
||||||
charts_list.forEach(function (item, index) {
|
charts_list.forEach(function (item, index) {
|
||||||
@@ -64,7 +66,18 @@ async function create_tv(charts_list, create_chart_options) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
window.chart.timeScale().fitContent();
|
window.chart.timeScale().fitContent();
|
||||||
|
|
||||||
|
// Handle responsiveness: Resize chart when container size changes
|
||||||
|
const resizeObserver = new ResizeObserver(entries => {{
|
||||||
|
for (let entry of entries) {{
|
||||||
|
window.chart.applyOptions({
|
||||||
|
width: entry.contentRect.width,
|
||||||
|
height: entry.contentRect.height
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
}});
|
||||||
|
resizeObserver.observe(container);
|
||||||
|
|
||||||
console.log("TV Created!")
|
console.log("TV Created!")
|
||||||
|
|
||||||
// window.midPriceLine_Config = {
|
// window.midPriceLine_Config = {
|
||||||
|
|||||||
Reference in New Issue
Block a user