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
70 changes: 67 additions & 3 deletions application/execution_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ def has_prior_execution_report(
effective = _first_non_empty(effective_date)
if not signal and not effective:
return False
month_segment = _month_segment(signal, effective)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid scanning the signal month as the only report month

This narrows prior-report fallback to the signal month, but runtime reports are persisted under the run started_at month, not necessarily the signal snapshot month. For monthly snapshots whose signal date is from the previous month but the execution/report is produced during the next month's execution window, this searches the previous-month prefix and misses the successful current-month report, allowing a duplicate execution attempt despite the fallback.

Useful? React with 👍 / 👎.

bucket_name, prefix = _parse_gcs_uri(str(self.gcs_prefix_uri or ""))
object_prefix = "/".join(
part.strip("/")
Expand All @@ -160,6 +161,7 @@ def has_prior_execution_report(
_runtime_report_segment(platform),
_runtime_report_segment(strategy_profile),
_runtime_report_segment(account_scope),
month_segment,
)
if part and part.strip("/")
)
Expand Down Expand Up @@ -247,9 +249,16 @@ def resolve_execution_dedup_enabled(
*,
env_reader: Callable[[str, str | None], str | None],
dry_run_only: bool,
account_scope: object = None,
) -> bool:
raw_value = env_reader("LONGBRIDGE_EXECUTION_DEDUP_ENABLED", None)
return _env_bool(raw_value, default=bool(dry_run_only))
if raw_value is not None and str(raw_value).strip():
return _env_bool(raw_value, default=bool(dry_run_only))
return bool(dry_run_only) or _is_paper_account_scope(account_scope)


def _is_paper_account_scope(value: object) -> bool:
return str(value or "").strip().upper() == "PAPER"


def _runtime_report_segment(value: object) -> str:
Expand All @@ -258,6 +267,14 @@ def _runtime_report_segment(value: object) -> str:
return safe or "unknown"


def _month_segment(*values: object) -> str:
for value in values:
text = _optional_str(value)
if len(text) >= 7 and text[4] == "-" and text[:4].isdigit() and text[5:7].isdigit():
return text[:7]
return ""


def _optional_str(value: object) -> str:
return str(value or "").strip()

Expand All @@ -282,12 +299,59 @@ def _report_matches_execution(
if bool(report.get("dry_run")) != bool(dry_run_only):
return False
summary = dict(report.get("summary") or {})
if signal_date and _optional_str(summary.get("signal_date")) != signal_date:
if signal_date and _date_key(signal_date) not in _report_signal_date_keys(report, summary):
return False
if effective_date and _optional_str(summary.get("effective_date")) != effective_date:
if effective_date and _date_key(effective_date) not in _report_effective_date_keys(report, summary):
return False
return (
bool(summary.get("action_done"))
or int(float(summary.get("orders_previewed_count") or 0)) > 0
or int(float(summary.get("order_events_count") or 0)) > 0
or _is_successful_no_action_report(report, summary)
)


def _is_successful_no_action_report(report: Mapping[str, Any], summary: Mapping[str, Any]) -> bool:
if _optional_str(report.get("status")).lower() != "ok":
return False
if int(float(summary.get("orders_skipped_count") or 0)) > 0:
return False
return bool("action_done" in summary and not summary.get("action_done"))


def _report_signal_date_keys(report: Mapping[str, Any], summary: Mapping[str, Any]) -> set[str]:
signal_snapshot = _report_signal_snapshot(report)
return _date_keys(
summary.get("signal_date"),
signal_snapshot.get("signal_as_of"),
signal_snapshot.get("market_date"),
signal_snapshot.get("price_as_of"),
signal_snapshot.get("snapshot_as_of"),
)


def _report_effective_date_keys(report: Mapping[str, Any], summary: Mapping[str, Any]) -> set[str]:
signal_snapshot = _report_signal_snapshot(report)
return _date_keys(
summary.get("effective_date"),
signal_snapshot.get("effective_date"),
)


def _report_signal_snapshot(report: Mapping[str, Any]) -> dict[str, Any]:
diagnostics = report.get("diagnostics")
if not isinstance(diagnostics, Mapping):
return {}
signal_snapshot = diagnostics.get("signal_snapshot")
return dict(signal_snapshot) if isinstance(signal_snapshot, Mapping) else {}


def _date_keys(*values: object) -> set[str]:
return {key for value in values if (key := _date_key(value))}


def _date_key(value: object) -> str:
text = _optional_str(value)
if len(text) >= 10 and text[4] == "-" and text[7] == "-":
return text[:10]
return text
1 change: 1 addition & 0 deletions application/runtime_composer.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ def build_rebalance_config(self, *, strategy_plugin_signals=()) -> LongBridgeReb
execution_dedup_enabled=resolve_execution_dedup_enabled(
env_reader=self.env_reader,
dry_run_only=self.dry_run_only,
account_scope=self.account_region,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use the runtime target account scope for PAPER defaults

When a deployment is described by RUNTIME_TARGET_JSON with account_scope: "PAPER" but keeps ACCOUNT_REGION as a market/region such as HK or US, this passes the region into resolve_execution_dedup_enabled, so the new PAPER default never activates for live paper-account runs. The runtime target already carries the account-scope field, so the default should be based on that value (falling back to the region only when no target scope exists) to match the intended PAPER account scope behavior.

Useful? React with 👍 / 👎.

),
execution_state_store=build_execution_marker_store_from_env(
env_reader=self.env_reader,
Expand Down
154 changes: 154 additions & 0 deletions tests/test_execution_state.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import sys
from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))

from application.execution_state import ( # noqa: E402
ExecutionMarkerStore,
_report_matches_execution,
resolve_execution_dedup_enabled,
)


def _env_with_dedup(raw_value):
def reader(name, default=None):
if name == "LONGBRIDGE_EXECUTION_DEDUP_ENABLED":
return raw_value
return default

return reader


def test_execution_dedup_defaults_to_enabled_for_paper_account_scope():
assert (
resolve_execution_dedup_enabled(
env_reader=_env_with_dedup(None),
dry_run_only=False,
account_scope="PAPER",
)
is True
)


def test_execution_dedup_defaults_to_disabled_for_live_non_paper_scope():
assert (
resolve_execution_dedup_enabled(
env_reader=_env_with_dedup(None),
dry_run_only=False,
account_scope="HK",
)
is False
)


def test_execution_dedup_env_override_wins_for_paper_scope():
assert (
resolve_execution_dedup_enabled(
env_reader=_env_with_dedup("false"),
dry_run_only=False,
account_scope="PAPER",
)
is False
)


def test_prior_report_match_treats_successful_no_action_as_completed():
payload = {
"platform": "longbridge",
"strategy_profile": "mega_cap_leader_rotation_top50_balanced",
"account_scope": "PAPER",
"dry_run": False,
"status": "ok",
"summary": {
"signal_date": "2026-06-04",
"action_done": False,
"orders_previewed_count": 0,
"order_events_count": 0,
"orders_skipped_count": 0,
},
"diagnostics": {
"signal_snapshot": {
"signal_as_of": "2026-06-01",
"market_date": "2026-06-01",
},
},
}

assert (
_report_matches_execution(
payload,
platform="longbridge",
strategy_profile="mega_cap_leader_rotation_top50_balanced",
account_scope="PAPER",
signal_date="2026-06-01",
effective_date="",
dry_run_only=False,
)
is True
)


def test_prior_report_match_does_not_treat_blocked_no_action_as_completed():
payload = {
"platform": "longbridge",
"strategy_profile": "mega_cap_leader_rotation_top50_balanced",
"account_scope": "PAPER",
"dry_run": False,
"status": "ok",
"summary": {
"signal_date": "2026-06-04",
"action_done": False,
"orders_skipped_count": 1,
},
}

assert (
_report_matches_execution(
payload,
platform="longbridge",
strategy_profile="mega_cap_leader_rotation_top50_balanced",
account_scope="PAPER",
signal_date="2026-06-04",
effective_date="",
dry_run_only=False,
)
is False
)


def test_prior_report_scan_is_scoped_to_signal_month():
observed = {}

class FakeClient:
def list_blobs(self, bucket_name, *, prefix):
observed["bucket_name"] = bucket_name
observed["prefix"] = prefix
return ()

store = ExecutionMarkerStore(
local_dir=None,
gcs_prefix_uri="gs://bucket/execution-reports",
client_factory=lambda **_kwargs: FakeClient(),
)

assert (
store.has_prior_execution_report(
platform="longbridge",
strategy_profile="mega_cap_leader_rotation_top50_balanced",
account_scope="PAPER",
signal_date="2026-06-04",
effective_date="",
dry_run_only=False,
)
is False
)
assert observed == {
"bucket_name": "bucket",
"prefix": (
"execution-reports/longbridge/"
"mega_cap_leader_rotation_top50_balanced/PAPER/2026-06"
),
}