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
16 changes: 11 additions & 5 deletions docs/runtime-target-manifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,20 @@ Kelly scaling, catch-up, anchor acceleration or synthetic fill. All four preview
flags remain enforced. The adapter neither claims periods nor reserves cash, so
it makes no exactly-once or multi-process order-execution claim.

The current locked UES package does not supply `plain_dca`. Until a separately
reviewed compatible pin is adopted, a valid binding still fails with
`plain_dca_api_unavailable`. This patch does not change shared dependency pins or
other strategy bindings. It also does not authenticate the readback source or
credentials: deployed PAPER account/state/schedule isolation, authentic safety
The locked UES package supplies `plain_dca`. The dependency adoption tests check
the installed VCS revision against all three source declarations and exercise
both baseline families through the real preview adapter with synthetic facts.
A missing or incompatible installation still fails with
`plain_dca_api_unavailable`. Installing the package does not authenticate the
readback source or credentials: deployed PAPER account/state/schedule isolation, authentic safety
readback, durable fencing/reconciliation, setup decisions and Phase 2 execution
remain separate prerequisites. Unit fixtures cannot prove those runtime facts.

The existing V7 PAPER approval remains bound to its original UES revision.
The plain-DCA dependency adoption does not renew or broaden that approval:
V7 loaded-version admission rejects the new installed revision. No V7 approval
constant, approved candidate or protected application binding is changed.

### Protected plain-DCA observation

The existing PAPER metadata workflow has a `plain-dca` mode. It uses only the
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ dependencies = [
"google-auth",
"longport==3.0.23",
"quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@350dd38ece0952beef096893a7dcf8ae3871609a",
"us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@c16c81bdf21824615f7280554559adc6c721917c",
"us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@1d087fa424972d5d5ab02c4650ce9f039cb6711f",
"hk-equity-strategies @ git+https://github.com/QuantStrategyLab/HkEquityStrategies.git@fe0c32e09d454ca4388c3372bf3874097b1bbaf0",
]

Expand Down
2 changes: 1 addition & 1 deletion qsl.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ allow_legacy = false

[qsl.requires]
quant_platform_kit = "350dd38ece0952beef096893a7dcf8ae3871609a"
us_equity_strategies = "8412d8338879f335ef8830678c2733e02e53e7c7"
us_equity_strategies = "1d087fa424972d5d5ab02c4650ce9f039cb6711f"
hk_equity_strategies = "cc3045689ae9d76eb97b9e1aa3b8fb6288ee1bcc"

[qsl.compat]
Expand Down
119 changes: 119 additions & 0 deletions tests/test_plain_dca_dependency.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
"""Exercise the installed UES package with synthetic facts, never a broker."""
import json
import tomllib
from datetime import date, datetime, time, timedelta
from decimal import Decimal as D
from importlib import metadata
from pathlib import Path
from zoneinfo import ZoneInfo

import pytest


def test_installed_ues_matches_all_source_declarations():
root = Path(__file__).resolve().parents[1]
lock = tomllib.loads((root / "uv.lock").read_text())
package, = [p for p in lock["package"] if p["name"] == "us-equity-strategies"]
revision = package["source"]["git"].rsplit("#", 1)[1]
project = tomllib.loads((root / "pyproject.toml").read_text())
requirement, = [d for d in project["project"]["dependencies"]
if d.startswith("us-equity-strategies @")]
assert requirement.endswith("@" + revision)
assert tomllib.loads((root / "qsl.toml").read_text())["qsl"]["requires"]["us_equity_strategies"] == revision
installed = json.loads(metadata.distribution("us-equity-strategies").read_text("direct_url.json"))
assert installed["vcs_info"]["commit_id"] == revision


@pytest.fixture(params=[("nasdaq100_buy_and_hold", "QQQ"),
("sp500_buy_and_hold", "SPY")])
def installed_dca_case(request):
from us_equity_strategies import buy_and_hold as p1
from us_equity_strategies import plain_dca as api

profile, symbol = request.param
zone = ZoneInfo("America/New_York")
now = datetime(2026, 11, 3, 11, tzinfo=zone)
fresh = {"observed_at": now, "valid_until": now + timedelta(minutes=1)}
instrument = p1.InstrumentBinding(symbol, symbol, "fake-contract", "XNAS", "USD",
D(1), D(1), True)
binding = p1.PlanBinding(profile, instrument, "fake-paper-account", "fake-mandate",
"fake-release", "fake-owner", "paper")
mandate = p1.Mandate(binding, now-timedelta(days=1), now+timedelta(days=1),
D(100), D(10000), "CAPITAL_PRESERVATION", True)
plan = api.DcaPlan(mandate, "fake-plan", 1, api.ScheduleSpec(anchor=3),
D(100), D(100), D(200))
start, end = date(2026, 1, 1), date(2027, 2, 1)
days = (start + timedelta(days=i) for i in range((end-start).days+1))
sessions = tuple(api.ExchangeSession(day, datetime.combine(day, time(9, 30), zone),
datetime.combine(day, time(16), zone))
for day in days if day.weekday() < 5)
calendar = api.ExchangeCalendar("fake-calendar", "XNAS", "America/New_York", start,
end, now-timedelta(days=1), now+timedelta(days=1),
True, sessions, zone)
period = api.PeriodFacts(binding, "fake-plan", 1, "2026-11", **fresh, records=(),
funded_carry=D(0), carry_verified=True,
year_new_headroom=D(1000), lifetime_new_headroom=D(1000),
year_spend_headroom=D(1000), lifetime_spend_headroom=D(1000))
facts = p1.PortfolioFacts(binding, **fresh, reconciled=True, exclusive_ownership=True,
unrelated_exposure=False, holdings_adopted=True,
held_quantity=D(0), settled_cash_after_reservations=D(1000),
account_risk_capital=D(20000), risk_headroom=D(1000),
risk_approved=True, principal_spent_and_reserved=D(0),
contribution_ref="fake-contribution", allowance_revision=1)
quote = p1.Quote(instrument, **fresh, mark_price=D(70), limit_price=D(70), fee_buffer=D(0))
capabilities = p1.Capabilities(binding, verified=True, fractional_verified=False)
return {"plan": plan, "calendar": calendar, "period": period, "facts": facts, "quote": quote,
"capabilities": capabilities, "now": now}


def test_installed_api_preserves_final_tranche_and_preview_only(installed_dca_case):
from us_equity_strategies.plain_dca import PeriodPreview, evaluate_dca_period

result = evaluate_dca_period(**installed_dca_case)
assert isinstance(result, PeriodPreview)
assert result.status == "DUE"
assert result.new_tranche == D(100) # Already approved; never apply the tier twice.
assert result.period_key == "2026-11"
assert result.no_order is True and result.no_execute is True
assert result.preview_only is True and result.live_ready is False
assert result.decision.budgets == ()
assert evaluate_dca_period(**installed_dca_case) == result


def test_adapter_consumes_installed_api_and_rejects_sg(installed_dca_case):
from us_equity_strategies.plain_dca import evaluate_dca_period

from application.plain_dca_paper_adapter import (
PlainDcaPaperError,
consume_plain_dca_preview,
)
from application.runtime_target_manifest import load_runtime_target_manifest

service, = [t.service for t in load_runtime_target_manifest().targets if t.id == "paper"]
now = installed_dca_case["now"]
readback = {"observed_at": now, "valid_until": now+timedelta(minutes=1),
"target_id": "paper", "environment": "longbridge-paper",
"live_enabled": False, "kelly_enabled": False, "stop_loss_enabled": False,
"protected_env": {
"CLOUD_RUN_SERVICE": service, "RUNTIME_TARGET_ENABLED": "false",
"LONGBRIDGE_DRY_RUN_ONLY": "false",
"LONGBRIDGE_PHYSICAL_ACCOUNT_ID": "fake-paper-account",
"RUNTIME_TARGET_JSON": json.dumps({
"platform_id": "longbridge", "service_name": service,
"execution_environment": "paper", "execution_mode": "live", "dry_run_only": False,
"account_scope": "PAPER", "account_selector": ["PAPER"], "deployment_selector": "PAPER"}),
}}
assert consume_plain_dca_preview(read_binding=lambda: readback, **installed_dca_case) == evaluate_dca_period(**installed_dca_case)
with pytest.raises(PlainDcaPaperError, match="paper_target_environment_required"):
consume_plain_dca_preview(read_binding=lambda: {**readback, "environment": "longbridge-sg"},
**installed_dca_case)


def test_installed_api_rejects_missing_facts(installed_dca_case):
from us_equity_strategies.plain_dca import evaluate_dca_period

result = evaluate_dca_period(**{**installed_dca_case, "facts": None})
assert result.status == "BLOCKED"
assert result.decision.positions == result.decision.budgets == ()
assert result.no_order and result.no_execute and result.preview_only
assert result.live_ready is False
2 changes: 1 addition & 1 deletion tests/test_ues_revision.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import pytest

ROOT = Path(__file__).resolve().parents[1]
PIN = "c16c81bdf21824615f7280554559adc6c721917c"
PIN = "1d087fa424972d5d5ab02c4650ce9f039cb6711f"
OTHER = "a" * 40


Expand Down
17 changes: 17 additions & 0 deletions tests/test_v7_paper_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,13 @@ def _loaded_v7_readback(monkeypatch):


def test_loaded_version_readback_uses_process_identity_and_stays_paused(monkeypatch) -> None:
from application import v7_paper_application

original = v7_paper_application._installed_revision
monkeypatch.setattr(
v7_paper_application, "_installed_revision",
lambda name: V7_APPROVED_UES_REVISION if name == "us-equity-strategies" else original(name),
)
readback = _loaded_v7_readback(monkeypatch)
assert readback["activation_state"] == "applied_paused"
assert readback["runtime_target_enabled"] is False
Expand All @@ -422,6 +429,16 @@ def test_loaded_version_readback_uses_process_identity_and_stays_paused(monkeypa
assert readback["runtime_loaded_receipt"]["schema_version"] == "runtime_loaded_receipt.v1"


def test_plain_dca_installed_pin_does_not_renew_v7_approval(monkeypatch) -> None:
from application import v7_paper_application

# Exercise the real installed package: M03 adoption cannot alter V7 authority.
assert v7_paper_application._installed_revision("us-equity-strategies") == "1d087fa424972d5d5ab02c4650ce9f039cb6711f"
assert V7_APPROVED_UES_REVISION == "c16c81bdf21824615f7280554559adc6c721917c"
with pytest.raises(V7PaperApplicationError, match="loaded UES revision"):
_loaded_v7_readback(monkeypatch)


@pytest.mark.parametrize("observed_revision", [
"8412d8338879f335ef8830678c2733e02e53e7c7", "a" * 40, "", None,
])
Expand Down
6 changes: 3 additions & 3 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading