Compare commits

...

1 Commits

Author SHA1 Message Date
Oleg Sheynin 9d553dcf1a Release v1.0.3 2026-07-29 01:01:08 +00:00
5 changed files with 34 additions and 8 deletions
+7
View File
@@ -6,6 +6,13 @@ All notable changes to this project are documented in this file.
No unreleased changes yet.
## 2026-07-29 v1.0.3
- Removed invalid fixed sizing mode from Panel Tabulator grids to avoid Bokeh
layout warnings while preserving compact table layout.
- Changed the Panel Calculate action to refresh the result-file list before
loading data and removed the standalone Panel Refresh button.
## 2026-07-29 v1.0.2
- Added a Panel application for single-day SPBT result analysis with result-file
+6 -5
View File
@@ -45,7 +45,6 @@ class SpbtDayPanelApp:
value=str(self.repo_root / "data"),
)
self.show_all_files = pn.widgets.Checkbox(label="Show all files", value=False)
self.refresh_button = pn.widgets.Button(label="Refresh")
self.file_select = pn.widgets.Select(
label="SQLite result file",
options={},
@@ -85,7 +84,6 @@ class SpbtDayPanelApp:
sizing_mode="stretch_width",
)
self.refresh_button.on_click(self.refresh_files)
self.calculate_button.on_click(self.calculate)
self.directory_input.param.watch(self.refresh_files, "value")
self.show_all_files.param.watch(self.refresh_files, "value")
@@ -111,7 +109,7 @@ class SpbtDayPanelApp:
raise ValueError(f"Selected database path is not a file: {db_path}")
return db_path
def refresh_files(self, *_events: Any) -> None:
def refresh_files(self, *_events: Any) -> bool:
"""Refresh selectable SQLite files from the configured directory."""
try:
directory = spbt_day.normalize_directory(
@@ -126,7 +124,7 @@ class SpbtDayPanelApp:
self.file_select.options = {}
self.file_select.value = None
self.set_status(str(exc), error=True)
return
return False
options = {path.name: str(path) for path in candidates}
previous_value = self.file_select.value
@@ -142,11 +140,14 @@ class SpbtDayPanelApp:
self.set_status(f"Found {len(options):,} file(s) in {directory}.")
else:
self.set_status(f"No selectable files found in {directory}.")
return True
def calculate(self, *_events: Any) -> None:
"""Load selected data and calculate all-pair TheoRet."""
self.calculate_button.loading = True
try:
if not self.refresh_files():
return
db_path = self.selected_database_path()
self.min_pctg_change = float(self.min_pctg_change_input.value)
@@ -260,7 +261,7 @@ class SpbtDayPanelApp:
"""Return the app layout."""
controls = pn.Column(
"## Inputs",
pn.Row(self.directory_input, self.refresh_button),
self.directory_input,
self.show_all_files,
self.file_select,
self.min_pctg_change_input,
-2
View File
@@ -1137,7 +1137,6 @@ def create_pair_theo_ret_analyze_grid(
pagination=None,
layout="fit_data_table",
height=height,
sizing_mode="fixed",
selectable=False,
)
@@ -1161,7 +1160,6 @@ def create_selected_pair_executions_grid(
pagination=None,
layout="fit_data_table",
height=height,
sizing_mode="fixed",
selectable=False,
)
+1 -1
View File
@@ -1023,7 +1023,7 @@ def test_create_panel_grids_use_analyze_button_and_hidden_pair_column():
assert pair_grid.disabled is False
assert pair_grid.pagination is None
assert pair_grid.layout == "fit_data_table"
assert pair_grid.sizing_mode == "fixed"
assert pair_grid.sizing_mode is None
assert executions_grid.value.columns.tolist() == [
"time",
"asset",
+20
View File
@@ -166,6 +166,7 @@ def test_panel_app_uses_fast_list_template(tmp_path):
app = module.SpbtDayPanelApp(repo_root=tmp_path)
view = app.view
assert not hasattr(app, "refresh_button")
assert isinstance(view, module.pn.template.FastListTemplate)
assert view.title == module.APP_TITLE
assert view.sidebar_width == 430
@@ -216,3 +217,22 @@ def test_panel_app_calculates_pairs_and_selected_pair_outputs(tmp_path):
"CLOSE",
]
assert app.selected_pair_market_plot.object is not None
def test_calculate_refreshes_file_list_before_loading(tmp_path):
module = load_panel_app_module()
data_dir = tmp_path / "data"
data_dir.mkdir()
app = module.SpbtDayPanelApp(repo_root=tmp_path)
app.directory_input.value = str(data_dir)
app.refresh_files()
assert app.file_select.value is None
db_path = data_dir / "20260617.spbt_results.db"
create_panel_fixture_db(db_path)
app.calculate()
assert app.file_select.value == str(db_path)
assert app.pair_theo_ret_table.value["pair_name"].tolist() == ["AAA-BBB"]