Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions src/nexa_backtest/engines/backtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,7 @@ def run(self) -> BacktestResult:
registry.register(provider)

# Determine the zone (first product wins)
zone = self._parse_zone()
zone = _parse_zone(self._products[0])

all_fills: list[Fill] = []
equity_snapshots: list[EquitySnapshot] = []
Expand Down Expand Up @@ -1315,10 +1315,6 @@ def _auction_time(delivery_date: date) -> datetime:
delivery_dt = datetime.combine(delivery_date, time(0, 0), tzinfo=UTC)
return delivery_dt + _AUCTION_OFFSET

def _parse_zone(self) -> str:
"""Extract zone from the first product spec."""
return _parse_zone(self._products[0])


def _mtu_to_product_id(mtu_start: datetime, zone: str) -> str:
"""Convert an MTU start time to a Nord Pool IDC product ID.
Expand Down
10 changes: 10 additions & 0 deletions src/nexa_backtest/validation/_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Shared utilities for validation check modules."""

from __future__ import annotations

import time


def _elapsed_ms(start: float) -> int:
"""Return milliseconds elapsed since ``start`` (from :func:`time.monotonic`)."""
return int((time.monotonic() - start) * 1000)
5 changes: 1 addition & 4 deletions src/nexa_backtest/validation/feature_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from pathlib import Path

from nexa_backtest.exchanges.base import ExchangeCapabilities
from nexa_backtest.validation._utils import _elapsed_ms
from nexa_backtest.validation.runner import StepResult

# Map exchange name → capabilities factory.
Expand Down Expand Up @@ -229,7 +230,3 @@ def _extract_numeric(node: ast.expr) -> float | int | None:
):
return -node.operand.value
return None


def _elapsed_ms(start: float) -> int:
return int((time.monotonic() - start) * 1000)
5 changes: 1 addition & 4 deletions src/nexa_backtest/validation/interface_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import time
from pathlib import Path

from nexa_backtest.validation._utils import _elapsed_ms
from nexa_backtest.validation.runner import StepResult

# Expected hook signatures for SimpleAlgo methods.
Expand Down Expand Up @@ -309,7 +310,3 @@ def _check_multiple_definitions(
f"{filename}: Multiple algo definitions found: {', '.join(names)}. "
"Place each algo in its own file. Ambiguous file cannot be loaded."
)


def _elapsed_ms(start: float) -> int:
return int((time.monotonic() - start) * 1000)
5 changes: 1 addition & 4 deletions src/nexa_backtest/validation/lookahead_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import time
from pathlib import Path

from nexa_backtest.validation._utils import _elapsed_ms
from nexa_backtest.validation.runner import StepResult

# Large lookback threshold for get_signal_history() in number of MTUs.
Expand Down Expand Up @@ -222,7 +223,3 @@ def _check_sort_iloc(
"rows that are chronologically in the future after sorting. "
"Verify this does not introduce look-ahead bias."
)


def _elapsed_ms(start: float) -> int:
return int((time.monotonic() - start) * 1000)
5 changes: 1 addition & 4 deletions src/nexa_backtest/validation/mypy_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import time
from pathlib import Path

from nexa_backtest.validation._utils import _elapsed_ms
from nexa_backtest.validation.runner import StepResult

# mypy output line pattern: filename:line: severity: message [error-code]
Expand Down Expand Up @@ -109,7 +110,3 @@ def run(self, algo_path: str) -> StepResult:
messages=messages,
duration_ms=duration,
)


def _elapsed_ms(start: float) -> int:
return int((time.monotonic() - start) * 1000)
5 changes: 1 addition & 4 deletions src/nexa_backtest/validation/resource_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import time
from pathlib import Path

from nexa_backtest.validation._utils import _elapsed_ms
from nexa_backtest.validation.runner import StepResult

# Methods/attributes that indicate time.sleep or asyncio.sleep.
Expand Down Expand Up @@ -338,7 +339,3 @@ def _check_mutable_globals(
"({}) may leak state between backtest runs. "
"Move state into the algo class or function.".format(type(val).__name__.lower())
)


def _elapsed_ms(start: float) -> int:
return int((time.monotonic() - start) * 1000)
5 changes: 1 addition & 4 deletions src/nexa_backtest/validation/ruff_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import time
from pathlib import Path

from nexa_backtest.validation._utils import _elapsed_ms
from nexa_backtest.validation.runner import StepResult

# Ruff rule codes that indicate hard errors (not merely style issues).
Expand Down Expand Up @@ -148,10 +149,6 @@ def run(self, algo_path: str) -> StepResult:
)


def _elapsed_ms(start: float) -> int:
return int((time.monotonic() - start) * 1000)


def _build_config_args() -> list[str]:
"""Return CLI args that apply the bundled nexa ruff config.

Expand Down
Loading