fix(trader): replay and catch-up trade each day's point-in-time index members
Replaying live books over past sessions used today's constituent list for every day, so US books bought names (BE, MRVL, ILMN, FLEX, P) before they joined the S&P 500. session_universes/session_signals now compute each past session on that day's members (S&P change log, CSI 300 snapshots); the latest session keeps the live list. Used by auto/monitor catch-up, replay and simulate. _run_session takes precomputed targets only. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -174,6 +174,23 @@ class MembershipTests(unittest.TestCase):
|
||||
# Never-member columns (benchmarks) are not masked.
|
||||
self.assertTrue(mask["510300.SS"].all())
|
||||
|
||||
def test_past_sessions_never_hold_a_name_before_it_joined_the_index(self):
|
||||
bars = _bars()
|
||||
bars["close"]["S00"] *= np.exp(np.linspace(0, 3, len(bars["close"]))) # the best momentum
|
||||
bars["open"]["S00"] = bars["close"]["S00"]
|
||||
days = bars["close"].index[-5:]
|
||||
others = [c for c in bars["close"].columns if c != "S00"]
|
||||
members = pd.DataFrame(True, index=days[:-1], columns=bars["close"].columns)
|
||||
members["S00"] = False # joins the index on the last day
|
||||
with mock.patch.object(trader, "index_members", lambda m, d: members.loc[d]):
|
||||
runs = trader.session_universes("us", "momentum", others + ["S00"], days)
|
||||
weights = trader.session_signals("us", "momentum", others + ["S00"], days,
|
||||
bars["close"], bars["open"])
|
||||
self.assertEqual([len(r) for _, r in runs], [4, 1])
|
||||
self.assertNotIn("S00", runs[0][0])
|
||||
self.assertTrue((weights.loc[days[:-1], "S00"] == 0).all())
|
||||
self.assertGreater(weights.loc[days[-1], "S00"], 0)
|
||||
|
||||
def test_changes_table_with_two_level_headers_is_found(self):
|
||||
cols = pd.MultiIndex.from_tuples([("Effective Date", "Effective Date"), ("Added", "Ticker"),
|
||||
("Removed", "Ticker"), ("Reason", "Reason")])
|
||||
|
||||
Reference in New Issue
Block a user