📝 docs(tsl-api): resolve backtesting return contract

This commit is contained in:
csh
2026-08-25 13:16:45 +08:00
parent d1568c02cd
commit 9c8d77e1c4
7 changed files with 834 additions and 56 deletions
+128 -7
View File
@@ -633,7 +633,7 @@ class TslApiFrameworkTests(unittest.TestCase):
packet = json.loads(result.stdout)
self.assertEqual("resolved", packet["profile_status"])
self.assertEqual("resolved", packet["profile"]["scaffold_status"])
self.assertEqual("incomplete", packet["profile"]["contract_status"])
self.assertEqual("resolved", packet["profile"]["contract_status"])
self.assertEqual(
["construct", "configure", "schedule", "callback", "execute", "inspect"],
[phase["phase"] for phase in packet["profile"]["lifecycle"]],
@@ -770,7 +770,7 @@ class TslApiFrameworkTests(unittest.TestCase):
packet = json.loads(result.stdout)
profile = packet["profile"]
self.assertEqual("resolved", profile["scaffold_status"])
self.assertEqual("incomplete", profile["contract_status"])
self.assertEqual("resolved", profile["contract_status"])
self.assertEqual(
["construct", "configure", "schedule", "callback", "execute", "inspect"],
[phase["phase"] for phase in profile["lifecycle"]],
@@ -779,12 +779,21 @@ class TslApiFrameworkTests(unittest.TestCase):
["tsBackTesting.GetTradeOrder"],
[hook["api"] for hook in profile["hooks"] if hook["required"]],
)
self.assertEqual([], profile["diagnostics"])
self.assertEqual(
"CONTRACT_INCOMPLETE",
profile["diagnostics"][0]["code"],
["tsBackTesting.GetTradeOrder"],
[contract["callback"] for contract in profile["contracts"]],
)
self.assertEqual(
{
"api": "tsBackTesting.FGroupType",
"field": "FGroupType",
"values": ["1", "2"],
},
profile["contracts"][0]["mode_discriminator"],
)
def test_candidate_discriminator_does_not_invent_a_mode(self):
def test_candidate_discriminator_resolves_ratio_schema(self):
result = run_script(
CLASS_LOOKUP,
"--class",
@@ -799,12 +808,124 @@ class TslApiFrameworkTests(unittest.TestCase):
packet = json.loads(result.stdout)
profile = packet["profile"]
self.assertEqual({"FGroupType": "1"}, profile["configured_values"])
self.assertEqual("incomplete", profile["contract_status"])
self.assertEqual("resolved", profile["contract_status"])
self.assertEqual([], profile["diagnostics"])
schema = profile["contracts"][0]["selected_return_schema"]
self.assertEqual("1", schema["when"]["FGroupType"])
self.assertEqual(
["截止日", "代码"],
[field["name"] for field in schema["fields"] if field.get("required")],
)
self.assertEqual(
[-1, 1],
schema["alternate_returns"][1]["documented_examples"],
)
self.assertTrue(
all(
field.get("pdf_non_empty")
for field in schema["fields"]
if field["name"] in {"截止日", "代码", "方向", "比例(%)"}
)
)
self.assertEqual(
"FRateType",
next(
field["required_when"]
for field in schema["fields"]
if field["name"] == "比例(%)"
)[0]["field"],
)
def test_candidate_discriminator_resolves_quantity_schema(self):
result = run_script(
CLASS_LOOKUP,
"--class",
"tsBackTesting",
"--config",
"FGroupType=2",
"--format",
"json",
)
self.assertEqual(0, result.returncode, result.stderr)
profile = json.loads(result.stdout)["profile"]
self.assertEqual("resolved", profile["contract_status"])
self.assertEqual([], profile["diagnostics"])
schema = profile["contracts"][0]["selected_return_schema"]
self.assertEqual("2", schema["when"]["FGroupType"])
self.assertIn(
"CONTRACT_MODE_UNRESOLVED",
"动作",
[field["name"] for field in schema["fields"] if field.get("required")],
)
self.assertEqual(
["empty_array"],
[item["type"] for item in schema["alternate_returns"]],
)
self.assertEqual(
{"组 ID", "组合类型"},
{
field["name"]
for field in schema["fields"]
if field["name"] in {"组 ID", "组合类型"}
},
)
action = next(field for field in schema["fields"] if field["name"] == "动作")
self.assertEqual("0", action["compat_default"])
volume = next(field for field in schema["fields"] if field["name"] == "成交量")
self.assertEqual(
["32", "33"],
volume["record_required_when"]["动作"],
)
self.assertEqual(
"FOpenVolType",
next(
field["required_when"]
for field in schema["fields"]
if field["name"] == "资金"
)[0]["field"],
)
def test_unknown_discriminator_value_is_reported(self):
result = run_script(
CLASS_LOOKUP,
"--class",
"tsBackTesting",
"--config",
"FGroupType=3",
"--format",
"json",
)
self.assertEqual(0, result.returncode, result.stderr)
profile = json.loads(result.stdout)["profile"]
self.assertEqual("incomplete", profile["contract_status"])
self.assertIsNone(profile["contracts"][0]["selected_return_schema"])
self.assertIn(
"CONTRACT_MODE_UNKNOWN",
{item["code"] for item in profile["diagnostics"]},
)
def test_get_trade_order_reference_records_mode_specific_fields(self):
result = run_script(
API_LOOKUP,
"--name",
"tsBackTesting.GetTradeOrder",
)
self.assertEqual(0, result.returncode, result.stderr)
self.assertIn("FGroupType := 1", result.stdout)
self.assertIn("FGroupType := 2", result.stdout)
self.assertIn("`比例(%)`", result.stdout)
self.assertIn("`剩余资金占比(%)`", result.stdout)
self.assertIn("非数组", result.stdout)
def test_quantity_mode_discriminators_are_indexed_members(self):
for name in ("tsBackTesting.FOpenVolType", "tsBackTesting.FCloseVolType"):
with self.subTest(name=name):
result = run_script(API_LOOKUP, "--name", name)
self.assertEqual(0, result.returncode, result.stderr)
self.assertNotIn("No TSL API named", result.stdout)
def test_unknown_configuration_is_reported(self):
result = run_script(
CLASS_LOOKUP,