97 lines
3.0 KiB
Python
97 lines
3.0 KiB
Python
from __future__ import annotations
|
|
|
|
import pandas as pd
|
|
|
|
from web_core.charting import _missing_calendar_day_values, build_figure
|
|
from web_core.constants import TREND_NEUTRAL
|
|
|
|
|
|
def _make_daily_df(days: list[str]) -> pd.DataFrame:
|
|
index = pd.DatetimeIndex([pd.Timestamp(day, tz="UTC") for day in days])
|
|
count = len(index)
|
|
return pd.DataFrame(
|
|
{
|
|
"Open": [100 + i for i in range(count)],
|
|
"High": [101 + i for i in range(count)],
|
|
"Low": [99 + i for i in range(count)],
|
|
"Close": [100.5 + i for i in range(count)],
|
|
"Volume": [1000 + i for i in range(count)],
|
|
"classification": ["fake"] * count,
|
|
"trend_state": [TREND_NEUTRAL] * count,
|
|
},
|
|
index=index,
|
|
)
|
|
|
|
|
|
def _make_intraday_df(days: list[str]) -> pd.DataFrame:
|
|
index_values: list[pd.Timestamp] = []
|
|
for day in days:
|
|
session = pd.date_range(
|
|
start=f"{day} 09:30:00",
|
|
end=f"{day} 15:45:00",
|
|
freq="15min",
|
|
tz="America/New_York",
|
|
)
|
|
index_values.extend(session.to_list())
|
|
|
|
index = pd.DatetimeIndex(index_values)
|
|
count = len(index)
|
|
return pd.DataFrame(
|
|
{
|
|
"Open": [100 + i for i in range(count)],
|
|
"High": [101 + i for i in range(count)],
|
|
"Low": [99 + i for i in range(count)],
|
|
"Close": [100.5 + i for i in range(count)],
|
|
"Volume": [1000 + i for i in range(count)],
|
|
"classification": ["fake"] * count,
|
|
"trend_state": [TREND_NEUTRAL] * count,
|
|
},
|
|
index=index,
|
|
)
|
|
|
|
|
|
def test_missing_calendar_day_values_include_weekday_holidays_only() -> None:
|
|
df = _make_daily_df(["2026-02-13", "2026-02-17"])
|
|
missing = _missing_calendar_day_values(df)
|
|
|
|
assert "2026-02-15" not in missing
|
|
assert "2026-02-16" in missing
|
|
|
|
|
|
def test_build_figure_adds_missing_day_rangebreak_values() -> None:
|
|
df = _make_daily_df(["2026-02-13", "2026-02-17"])
|
|
fig = build_figure(
|
|
df,
|
|
gray_fake=False,
|
|
interval="1d",
|
|
hide_market_closed_gaps=True,
|
|
display_timezone="America/Chicago",
|
|
use_24h_time=False,
|
|
)
|
|
|
|
rangebreak_values: list[str] = []
|
|
for rb in fig.layout.xaxis.rangebreaks:
|
|
values = list(getattr(rb, "values", ()) or ())
|
|
rangebreak_values.extend(str(v) for v in values)
|
|
|
|
assert "2026-02-16" in rangebreak_values
|
|
assert "2026-02-15" not in rangebreak_values
|
|
|
|
|
|
def test_build_figure_intraday_uses_category_axis_when_hiding_gaps() -> None:
|
|
df = _make_intraday_df(["2026-02-13", "2026-02-17"])
|
|
fig = build_figure(
|
|
df,
|
|
gray_fake=False,
|
|
interval="15m",
|
|
hide_market_closed_gaps=True,
|
|
display_timezone="America/Chicago",
|
|
use_24h_time=False,
|
|
)
|
|
|
|
assert fig.layout.xaxis.type == "category"
|
|
assert len(fig.layout.xaxis.rangebreaks) == 0
|
|
assert fig.layout.xaxis.tickmode == "array"
|
|
assert list(fig.layout.xaxis.ticktext) == ["2/13", "2/17"]
|
|
assert len(fig.layout.xaxis.tickvals) == 2
|