feat: preserve Quant OS target-package vertical slice

This commit is contained in:
2026-07-30 21:27:44 +08:00
parent 00efeb7ec2
commit 919c64c679
42 changed files with 15454 additions and 404 deletions
+332
View File
@@ -1,16 +1,99 @@
import ast
import copy
import hashlib
import unittest
from pathlib import Path
from quant60.ledger import canonical_json
from quant60.portable_core import (
TargetPackageLookupMiss,
_any_true,
build_rebalance_plan,
build_target_weight_plan,
capped_target_weights,
lookup_target_package_exact,
momentum_score,
normalize_symbol,
order_deltas,
target_package_tape_sha256,
target_quantities,
verify_target_package,
)
from quant60.target_package import seal_target_package
def sealed_target_package(
package_id="TP-20260724-A",
decision_id="D-20260724-A",
signal_as_of="2026-07-24T15:00:00+08:00",
next_session="2026-07-27",
):
return seal_target_package(
{
"schema_version": "1.0",
"package_type": "TargetPackageV1",
"package_id": package_id,
"decision_id": decision_id,
"release": "quant60-baseline-60-v1",
"evidence_class": "provider-snapshot-local",
"model_id": "alpha158-lightgbm-v1",
"signal_as_of": signal_as_of,
"next_session": next_session,
"model_sha256": "1" * 64,
"data_sha256": "2" * 64,
"feature_sha256": "3" * 64,
"risk_sha256": "4" * 64,
"cost_sha256": "5" * 64,
"optimizer_sha256": "6" * 64,
"config_sha256": "7" * 64,
"source_sha256": "8" * 64,
"target_weights": {
"000001.XSHE": 0.30,
"600000.XSHG": 0.20,
},
"universe": {
"000001.XSHE": {
"state": "openable",
"reasons": ["ELIGIBLE"],
},
"600000.XSHG": {
"state": "hold_only",
"reasons": ["LIQUIDITY_BELOW_FLOOR"],
},
},
"constraints": {
"constraint_state": "FEASIBLE",
"long_only": True,
"max_single_weight": 0.40,
"max_gross_weight": 0.80,
"max_one_way_turnover": 0.20,
"actual_gross_weight": 0.50,
},
}
)
class PortableCoreTests(unittest.TestCase):
def test_private_any_true_preserves_builtin_semantics(self):
for values in (
[],
[False, 0, None, ""],
[False, 0, "truthy"],
[1],
):
with self.subTest(values=values):
self.assertEqual(_any_true(iter(values)), any(values))
visited = []
def values():
for value in (False, True, "must-not-be-read"):
visited.append(value)
yield value
self.assertTrue(_any_true(values()))
self.assertEqual(visited, [False, True])
def test_symbol_round_trip(self):
inputs = [
("600000.XSHG", "600000.SH", "SH600000"),
@@ -166,6 +249,255 @@ class PortableCoreTests(unittest.TestCase):
build_rebalance_plan(**arguments),
)
def test_target_weight_plan_is_causal_and_preserves_lineage(self):
common = {
"prices": {
"600000.SH": 10.0,
"000001.SZ": 10.0,
},
"current": {},
"sellable": {},
"equity": 100_000,
"cash_buffer": 0.02,
"lot_size": 100,
"decision_id": "D-20260724-A",
"package_sha256": "a" * 64,
}
first = build_target_weight_plan(
{
"600000.XSHG": 0.60,
"000001.XSHE": 0.20,
},
**common
)
second = build_target_weight_plan(
{
"600000.XSHG": 0.20,
"000001.XSHE": 0.60,
},
**common
)
self.assertNotEqual(first["targets"], second["targets"])
self.assertNotEqual(first["orders"], second["orders"])
self.assertEqual(first["decision_id"], "D-20260724-A")
self.assertEqual(first["package_sha256"], "a" * 64)
self.assertNotIn("scores", first)
def test_target_weight_plan_rejects_alias_duplicates_and_bad_weights(self):
common = {
"prices": {"600000.XSHG": 10.0},
"current": {},
"sellable": {},
"equity": 100_000,
}
with self.assertRaisesRegex(ValueError, "duplicate normalized"):
build_target_weight_plan(
{
"600000.SH": 0.20,
"600000.XSHG": 0.20,
},
**common
)
for weights in (
{"600000.XSHG": -0.1},
{"600000.XSHG": float("nan")},
{"600000.XSHG": 1.01},
):
with self.subTest(weights=weights):
with self.assertRaises(ValueError):
build_target_weight_plan(weights, **common)
with self.assertRaisesRegex(ValueError, "gross"):
build_target_weight_plan(
{
"600000.XSHG": 0.60,
"000001.XSHE": 0.50,
},
prices={
"600000.XSHG": 10.0,
"000001.XSHE": 10.0,
},
current={},
sellable={},
equity=100_000,
)
def test_target_weight_plan_respects_t1_and_odd_lot_liquidation(self):
t1_limited = build_target_weight_plan(
{},
{"600000.XSHG": 10.0},
{"600000.XSHG": 1050},
{"600000.XSHG": 250},
equity=100_000,
)
self.assertEqual(t1_limited["weights"], {"600000.XSHG": 0.0})
self.assertEqual(t1_limited["targets"], {"600000.XSHG": 0})
self.assertEqual(t1_limited["orders"], {"600000.XSHG": -200})
complete = build_target_weight_plan(
{},
{"600000.XSHG": 10.0},
{"600000.XSHG": 1050},
{"600000.XSHG": 1050},
equity=100_000,
)
self.assertEqual(complete["orders"], {"600000.XSHG": -1050})
unsellable = build_target_weight_plan(
{},
{"600000.XSHG": 10.0},
{"600000.XSHG": 1050},
{},
equity=100_000,
)
self.assertEqual(unsellable["orders"], {})
def test_target_weight_plan_requires_exact_managed_price_coverage(self):
with self.assertRaisesRegex(KeyError, "missing"):
build_target_weight_plan(
{"600000.XSHG": 0.20},
{"600000.XSHG": 10.0},
{"000001.XSHE": 100},
{"000001.XSHE": 100},
equity=100_000,
)
with self.assertRaisesRegex(ValueError, "unmanaged"):
build_target_weight_plan(
{"600000.XSHG": 0.20},
{
"600000.XSHG": 10.0,
"000001.XSHE": 10.0,
},
{},
{},
equity=100_000,
)
def test_portable_target_package_verifier_matches_local_seal(self):
package = sealed_target_package()
self.assertEqual(verify_target_package(package), package)
self.assertEqual(
verify_target_package(
package,
expected_signal_as_of=package["signal_as_of"],
expected_next_session=package["next_session"],
expected_decision_id=package["decision_id"],
expected_package_sha256=package["package_sha256"],
),
package,
)
tampered = copy.deepcopy(package)
tampered["target_weights"]["000001.XSHE"] = 0.29
tampered["constraints"]["actual_gross_weight"] = 0.49
with self.assertRaisesRegex(ValueError, "hash mismatch"):
verify_target_package(tampered)
quantity_injected = copy.deepcopy(package)
quantity_injected["target_quantity"] = 100
with self.assertRaisesRegex(ValueError, "quantities do not belong"):
verify_target_package(quantity_injected)
noncanonical = copy.deepcopy(package)
noncanonical["target_weights"]["000001.SZ"] = noncanonical[
"target_weights"
].pop("000001.XSHE")
with self.assertRaisesRegex(ValueError, "must be canonical"):
verify_target_package(noncanonical)
def test_target_package_tape_is_pinned_and_exact_only(self):
first = sealed_target_package()
second = sealed_target_package(
package_id="TP-20260731-B",
decision_id="D-20260731-B",
signal_as_of="2026-07-31T15:00:00+08:00",
next_session="2026-08-03",
)
packages = [first, second]
tape_hash = target_package_tape_sha256(packages)
self.assertEqual(
tape_hash,
hashlib.sha256(
canonical_json(packages).encode("utf-8")
).hexdigest(),
)
found = lookup_target_package_exact(
packages,
signal_as_of=second["signal_as_of"],
next_session=second["next_session"],
decision_id=second["decision_id"],
expected_tape_sha256=tape_hash,
expected_count=2,
)
self.assertEqual(found, second)
found["release"] = "mutated"
self.assertEqual(packages[1]["release"], second["release"])
with self.assertRaises(TargetPackageLookupMiss):
lookup_target_package_exact(
packages,
signal_as_of="2026-07-30T15:00:00+08:00",
next_session="2026-07-31",
expected_tape_sha256=tape_hash,
expected_count=2,
)
with self.assertRaisesRegex(ValueError, "decision_id mismatch"):
lookup_target_package_exact(
packages,
signal_as_of=first["signal_as_of"],
next_session=first["next_session"],
decision_id="D-WRONG",
)
with self.assertRaisesRegex(ValueError, "count mismatch"):
lookup_target_package_exact(
packages[:1],
signal_as_of=first["signal_as_of"],
next_session=first["next_session"],
expected_count=2,
)
with self.assertRaisesRegex(ValueError, "digest mismatch"):
lookup_target_package_exact(
packages[:1],
signal_as_of=first["signal_as_of"],
next_session=first["next_session"],
expected_tape_sha256=tape_hash,
)
def test_target_package_tape_rejects_duplicates_and_unmatched_tamper(self):
first = sealed_target_package()
duplicate_clock = sealed_target_package(
package_id="TP-20260724-B",
decision_id="D-20260724-B",
)
with self.assertRaisesRegex(ValueError, "duplicate target package clock"):
lookup_target_package_exact(
[first, duplicate_clock],
signal_as_of=first["signal_as_of"],
next_session=first["next_session"],
)
later = sealed_target_package(
package_id="TP-20260731-B",
decision_id="D-20260731-B",
signal_as_of="2026-07-31T15:00:00+08:00",
next_session="2026-08-03",
)
later["release"] = "tampered"
with self.assertRaisesRegex(ValueError, "hash mismatch"):
lookup_target_package_exact(
[first, later],
signal_as_of=first["signal_as_of"],
next_session=first["next_session"],
)
def test_portable_core_parses_as_python_36(self):
source = (
Path(__file__).parents[1]
/ "src"
/ "quant60"
/ "portable_core.py"
).read_text(encoding="utf-8")
ast.parse(source, feature_version=(3, 6))
if __name__ == "__main__":
unittest.main()