progress
This commit is contained in:
+150
-11
@@ -148,7 +148,7 @@ def test_load_pair_market_data_maps_selector_instruments_and_relative_close():
|
||||
)
|
||||
conn.execute(
|
||||
"""
|
||||
CREATE TABLE ohlcv_1min (
|
||||
CREATE TABLE market (
|
||||
tstamp TEXT,
|
||||
tstamp_ns INTEGER,
|
||||
exch_acct TEXT,
|
||||
@@ -166,7 +166,7 @@ def test_load_pair_market_data_maps_selector_instruments_and_relative_close():
|
||||
),
|
||||
)
|
||||
conn.executemany(
|
||||
"INSERT INTO ohlcv_1min VALUES (?, ?, ?, ?, ?)",
|
||||
"INSERT INTO market VALUES (?, ?, ?, ?, ?)",
|
||||
[
|
||||
("pre", 9, "EXCH_A", "PAIR-AAA-USD", 90.0),
|
||||
("t0", 10, "EXCH_A", "PAIR-AAA-USD", 100.0),
|
||||
@@ -239,7 +239,7 @@ def test_load_pair_market_data_requires_market_rows_for_both_assets():
|
||||
)
|
||||
conn.execute(
|
||||
"""
|
||||
CREATE TABLE ohlcv_1min (
|
||||
CREATE TABLE market (
|
||||
tstamp TEXT,
|
||||
tstamp_ns INTEGER,
|
||||
exch_acct TEXT,
|
||||
@@ -257,13 +257,13 @@ def test_load_pair_market_data_requires_market_rows_for_both_assets():
|
||||
),
|
||||
)
|
||||
conn.execute(
|
||||
"INSERT INTO ohlcv_1min VALUES (?, ?, ?, ?, ?)",
|
||||
"INSERT INTO market VALUES (?, ?, ?, ?, ?)",
|
||||
("t1", 1, "EXCH_A", "PAIR-AAA-USD", 100.0),
|
||||
)
|
||||
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match=r"ohlcv_1min does not contain market data for asset\(s\): BBB",
|
||||
match=r"market does not contain data for asset\(s\): BBB",
|
||||
):
|
||||
load_pair_market_data(
|
||||
conn,
|
||||
@@ -286,7 +286,7 @@ def test_load_pair_market_data_requires_time_zero_close_for_each_asset():
|
||||
)
|
||||
conn.execute(
|
||||
"""
|
||||
CREATE TABLE ohlcv_1min (
|
||||
CREATE TABLE market (
|
||||
tstamp TEXT,
|
||||
tstamp_ns INTEGER,
|
||||
exch_acct TEXT,
|
||||
@@ -304,7 +304,7 @@ def test_load_pair_market_data_requires_time_zero_close_for_each_asset():
|
||||
),
|
||||
)
|
||||
conn.executemany(
|
||||
"INSERT INTO ohlcv_1min VALUES (?, ?, ?, ?, ?)",
|
||||
"INSERT INTO market VALUES (?, ?, ?, ?, ?)",
|
||||
[
|
||||
("t1", 1, "EXCH_A", "PAIR-AAA-USD", None),
|
||||
("t2", 2, "EXCH_A", "PAIR-AAA-USD", 110.0),
|
||||
@@ -314,7 +314,7 @@ def test_load_pair_market_data_requires_time_zero_close_for_each_asset():
|
||||
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match=r"ohlcv_1min initial close must be positive for asset\(s\): AAA",
|
||||
match=r"market initial close must be positive for asset\(s\): AAA",
|
||||
):
|
||||
load_pair_market_data(
|
||||
conn,
|
||||
@@ -337,7 +337,7 @@ def test_load_pair_market_data_requires_exact_trading_day_start_row():
|
||||
)
|
||||
conn.execute(
|
||||
"""
|
||||
CREATE TABLE ohlcv_1min (
|
||||
CREATE TABLE market (
|
||||
tstamp TEXT,
|
||||
tstamp_ns INTEGER,
|
||||
exch_acct TEXT,
|
||||
@@ -355,7 +355,7 @@ def test_load_pair_market_data_requires_exact_trading_day_start_row():
|
||||
),
|
||||
)
|
||||
conn.executemany(
|
||||
"INSERT INTO ohlcv_1min VALUES (?, ?, ?, ?, ?)",
|
||||
"INSERT INTO market VALUES (?, ?, ?, ?, ?)",
|
||||
[
|
||||
("t1", 11, "EXCH_A", "PAIR-AAA-USD", 110.0),
|
||||
("t0", 10, "EXCH_B", "PAIR-BBB-USD", 50.0),
|
||||
@@ -365,7 +365,7 @@ def test_load_pair_market_data_requires_exact_trading_day_start_row():
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match=(
|
||||
"ohlcv_1min does not contain trading-day start close for "
|
||||
"market does not contain trading-day start close for "
|
||||
r"asset\(s\): AAA"
|
||||
),
|
||||
):
|
||||
@@ -891,6 +891,143 @@ def test_load_trading_instructions_validates_required_table():
|
||||
load_trading_instructions(conn)
|
||||
|
||||
|
||||
def test_load_trading_instructions_requires_sp_quant_metric_columns():
|
||||
conn = sqlite3.connect(":memory:")
|
||||
conn.execute(
|
||||
"""
|
||||
CREATE TABLE trading_instructions (
|
||||
tstamp TEXT,
|
||||
tstamp_ns INTEGER,
|
||||
action TEXT,
|
||||
quote_asset TEXT,
|
||||
assets TEXT
|
||||
)
|
||||
"""
|
||||
)
|
||||
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match=r"SP Quant column\(s\) \[beta, scaled_disequilibrium\]",
|
||||
):
|
||||
load_trading_instructions(conn)
|
||||
|
||||
|
||||
def test_load_trading_instructions_reads_sp_quant_schema_with_time_alias():
|
||||
conn = sqlite3.connect(":memory:")
|
||||
conn.execute(
|
||||
"""
|
||||
CREATE TABLE trading_instructions (
|
||||
tstamp TEXT,
|
||||
tstamp_ns INTEGER,
|
||||
type TEXT,
|
||||
book_id TEXT,
|
||||
strategy_id TEXT,
|
||||
action TEXT,
|
||||
quote_asset TEXT,
|
||||
assets TEXT,
|
||||
scaled_disequilibrium REAL,
|
||||
beta REAL
|
||||
)
|
||||
"""
|
||||
)
|
||||
conn.executemany(
|
||||
"INSERT INTO trading_instructions VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
[
|
||||
(
|
||||
"t2",
|
||||
2,
|
||||
"CLOSE_POSITION",
|
||||
"book",
|
||||
"strategy",
|
||||
"CLOSE",
|
||||
"USD",
|
||||
'{"AAA":{"reference_price":"110"},"BBB":{"reference_price":"45"}}',
|
||||
-0.5,
|
||||
0.75,
|
||||
),
|
||||
(
|
||||
"t1",
|
||||
1,
|
||||
"TARGET_POSITION",
|
||||
"book",
|
||||
"strategy",
|
||||
"TARGET",
|
||||
"USD",
|
||||
(
|
||||
'{"AAA":{"reference_price":"100","strength":"0.5"},'
|
||||
'"BBB":{"reference_price":"50","strength":"-0.5"}}'
|
||||
),
|
||||
-1.25,
|
||||
0.75,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
trading_instructions = load_trading_instructions(conn)
|
||||
|
||||
assert trading_instructions["tstamp_ns"].tolist() == [1, 2]
|
||||
assert trading_instructions["time_ns"].tolist() == [1, 2]
|
||||
assert trading_instructions["action"].tolist() == ["TARGET", "CLOSE"]
|
||||
assert trading_instructions["scaled_disequilibrium"].tolist() == [-1.25, -0.5]
|
||||
assert trading_instructions["beta"].tolist() == [0.75, 0.75]
|
||||
|
||||
|
||||
def test_calculate_pair_theo_executions_reads_sp_quant_instruction_columns():
|
||||
trd_inst_df = pd.DataFrame(
|
||||
{
|
||||
"tstamp_ns": [1, 2],
|
||||
"time_ns": [1, 2],
|
||||
"tstamp": ["t1", "t2"],
|
||||
"action": ["TARGET", "CLOSE"],
|
||||
"quote_asset": ["USD", "USD"],
|
||||
"assets": [
|
||||
(
|
||||
'{"AAA":{"reference_price":"100","strength":"0.5"},'
|
||||
'"BBB":{"reference_price":"50","strength":"-0.5"}}'
|
||||
),
|
||||
'{"AAA":{"reference_price":"110"},"BBB":{"reference_price":"45"}}',
|
||||
],
|
||||
"scaled_disequilibrium": [-1.25, -0.5],
|
||||
"beta": [0.75, 0.75],
|
||||
}
|
||||
)
|
||||
|
||||
executions = calculate_pair_theo_executions("AAA:USD-BBB:USD", trd_inst_df)
|
||||
|
||||
assert executions[
|
||||
["time", "asset", "action", "scaled_disequilibrium", "beta"]
|
||||
].to_dict("records") == [
|
||||
{
|
||||
"time": "t1",
|
||||
"asset": "AAA",
|
||||
"action": "TARGET",
|
||||
"scaled_disequilibrium": -1.25,
|
||||
"beta": 0.75,
|
||||
},
|
||||
{
|
||||
"time": "t1",
|
||||
"asset": "BBB",
|
||||
"action": "TARGET",
|
||||
"scaled_disequilibrium": -1.25,
|
||||
"beta": 0.75,
|
||||
},
|
||||
{
|
||||
"time": "t2",
|
||||
"asset": "AAA",
|
||||
"action": "CLOSE",
|
||||
"scaled_disequilibrium": -0.5,
|
||||
"beta": 0.75,
|
||||
},
|
||||
{
|
||||
"time": "t2",
|
||||
"asset": "BBB",
|
||||
"action": "CLOSE",
|
||||
"scaled_disequilibrium": -0.5,
|
||||
"beta": 0.75,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def test_find_repo_root_and_normalize_directory():
|
||||
repo_root = find_repo_root(Path("notebooks").resolve())
|
||||
|
||||
@@ -1030,6 +1167,8 @@ def test_create_panel_grids_use_analyze_button_and_hidden_pair_column():
|
||||
"action",
|
||||
"side",
|
||||
"strength",
|
||||
"scaled_disequilibrium",
|
||||
"beta",
|
||||
"size",
|
||||
"price",
|
||||
"usd_value",
|
||||
|
||||
@@ -33,24 +33,26 @@ def create_panel_fixture_db(db_path: Path) -> None:
|
||||
conn.execute(
|
||||
"""
|
||||
CREATE TABLE trading_instructions (
|
||||
time_ns INTEGER,
|
||||
tstamp TEXT,
|
||||
tstamp_ns INTEGER,
|
||||
type TEXT,
|
||||
book_id TEXT,
|
||||
strategy_id TEXT,
|
||||
type TEXT,
|
||||
data TEXT
|
||||
action TEXT,
|
||||
quote_asset TEXT,
|
||||
assets TEXT,
|
||||
scaled_disequilibrium REAL,
|
||||
beta REAL
|
||||
)
|
||||
"""
|
||||
)
|
||||
conn.execute(
|
||||
"""
|
||||
CREATE TABLE ohlcv_1min (
|
||||
CREATE TABLE market (
|
||||
tstamp TEXT,
|
||||
tstamp_ns INTEGER,
|
||||
exch_acct TEXT,
|
||||
exchange_id TEXT,
|
||||
instrument_id TEXT,
|
||||
interval_sec INTEGER,
|
||||
open REAL,
|
||||
high REAL,
|
||||
low REAL,
|
||||
@@ -73,44 +75,44 @@ def create_panel_fixture_db(db_path: Path) -> None:
|
||||
),
|
||||
)
|
||||
conn.executemany(
|
||||
"INSERT INTO trading_instructions VALUES (?, ?, ?, ?, ?, ?)",
|
||||
"INSERT INTO trading_instructions VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
[
|
||||
(
|
||||
trading_day_start_ns,
|
||||
"2026-06-17T00:00:00Z",
|
||||
trading_day_start_ns,
|
||||
"TARGET_POSITION",
|
||||
"book",
|
||||
"strategy-AAA:USD-BBB:USD",
|
||||
"TARGET_POSITION",
|
||||
(
|
||||
'{"action":"TARGET","quote_asset":"USD","assets":'
|
||||
'{"AAA":{"reference_price":"100","strength":"0.5"},'
|
||||
'"BBB":{"reference_price":"50","strength":"-0.5"}}}'
|
||||
),
|
||||
"TARGET",
|
||||
"USD",
|
||||
'{"AAA":{"reference_price":"100","strength":"0.5"},'
|
||||
'"BBB":{"reference_price":"50","strength":"-0.5"}}',
|
||||
-1.25,
|
||||
0.75,
|
||||
),
|
||||
(
|
||||
trading_day_start_ns + 60_000_000_000,
|
||||
"2026-06-17T00:01:00Z",
|
||||
trading_day_start_ns + 60_000_000_000,
|
||||
"CLOSE_POSITION",
|
||||
"book",
|
||||
"strategy-AAA:USD-BBB:USD",
|
||||
"CLOSE_POSITION",
|
||||
(
|
||||
'{"action":"CLOSE","quote_asset":"USD","assets":'
|
||||
'{"AAA":{"reference_price":"110"},'
|
||||
'"BBB":{"reference_price":"45"}}}'
|
||||
),
|
||||
"CLOSE",
|
||||
"USD",
|
||||
'{"AAA":{"reference_price":"110"},'
|
||||
'"BBB":{"reference_price":"45"}}',
|
||||
-0.5,
|
||||
0.75,
|
||||
),
|
||||
],
|
||||
)
|
||||
conn.executemany(
|
||||
"INSERT INTO ohlcv_1min VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
"INSERT INTO market VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
[
|
||||
(
|
||||
"2026-06-17T00:00:00Z",
|
||||
trading_day_start_ns,
|
||||
"EXCH",
|
||||
"EXCH",
|
||||
"PAIR-AAA-USD",
|
||||
60,
|
||||
100.0,
|
||||
100.0,
|
||||
100.0,
|
||||
@@ -123,9 +125,7 @@ def create_panel_fixture_db(db_path: Path) -> None:
|
||||
"2026-06-17T00:00:00Z",
|
||||
trading_day_start_ns,
|
||||
"EXCH",
|
||||
"EXCH",
|
||||
"PAIR-BBB-USD",
|
||||
60,
|
||||
50.0,
|
||||
50.0,
|
||||
50.0,
|
||||
@@ -169,7 +169,8 @@ def test_panel_app_uses_fast_list_template(tmp_path):
|
||||
assert not hasattr(app, "refresh_button")
|
||||
assert isinstance(view, module.pn.template.FastListTemplate)
|
||||
assert view.title == module.APP_TITLE
|
||||
assert view.sidebar_width == 430
|
||||
assert view.theme is module.pn.template.DarkTheme
|
||||
assert view.sidebar_width == module.APP_SIDEBAR_WIDTH
|
||||
assert view.accent_base_color == module.APP_ACCENT_COLOR
|
||||
assert view.header_background == module.APP_HEADER_COLOR
|
||||
assert len(view.sidebar) == 1
|
||||
@@ -191,8 +192,12 @@ def test_panel_app_calculates_pairs_and_selected_pair_outputs(tmp_path):
|
||||
app.calculate()
|
||||
|
||||
assert app.file_select.value == str(db_path)
|
||||
assert app.file_select.width == 360
|
||||
assert app.min_pctg_change_input.width == 220
|
||||
assert app.directory_input.sizing_mode == "stretch_width"
|
||||
assert app.directory_input.width is None
|
||||
assert app.file_select.sizing_mode == "stretch_width"
|
||||
assert app.file_select.width is None
|
||||
assert app.min_pctg_change_input.sizing_mode == "stretch_width"
|
||||
assert app.min_pctg_change_input.width is None
|
||||
assert app.calculate_button.width == 110
|
||||
assert app.total_pnl_histogram.sizing_mode == "stretch_width"
|
||||
assert app.selected_pair_market_plot.sizing_mode == "stretch_width"
|
||||
|
||||
Reference in New Issue
Block a user