test_glued_followthrough_shadow_reentry.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. from __future__ import annotations
  2. import json
  3. import unittest
  4. from pathlib import Path
  5. import pandas as pd
  6. from dragon_branch_configs import (
  7. alpha_first_glued_followthrough_probe_config,
  8. alpha_first_glued_refined_hot_cap_config,
  9. )
  10. from dragon_rc1_golden_baseline import (
  11. EVENTS_CORE_COLUMNS,
  12. MANIFEST_OUTPUT,
  13. TRADES_CORE_COLUMNS,
  14. _df_sha256,
  15. _load_indicator_snapshot,
  16. )
  17. from dragon_shared import END_DATE, START_DATE
  18. from dragon_strategy import DragonRuleEngine
  19. class TestGluedFollowthroughShadowReentry(unittest.TestCase):
  20. def setUp(self) -> None:
  21. self.base_dir = Path(__file__).resolve().parents[1]
  22. self.manifest_path = self.base_dir / MANIFEST_OUTPUT
  23. self.manifest = json.loads(self.manifest_path.read_text(encoding="utf-8"))
  24. indexed, _ = _load_indicator_snapshot(self.base_dir)
  25. self.indexed = indexed
  26. def _release_window_trades(self, trades: pd.DataFrame) -> pd.DataFrame:
  27. return trades[
  28. (trades["buy_date"] >= START_DATE)
  29. & (trades["buy_date"] <= END_DATE)
  30. & (trades["sell_date"] >= START_DATE)
  31. & (trades["sell_date"] <= END_DATE)
  32. ].copy()
  33. def test_default_branch_full_snapshot_hashes_stay_stable(self) -> None:
  34. events, trades = DragonRuleEngine(config=alpha_first_glued_refined_hot_cap_config()).run(self.indexed)
  35. events.sort_values(["date", "side", "layer", "reason"], inplace=True)
  36. trades.sort_values(["buy_date", "sell_date", "buy_reason", "sell_reason"], inplace=True)
  37. self.assertEqual(len(events), 296)
  38. self.assertEqual(len(trades), 98)
  39. self.assertEqual(
  40. _df_sha256(events[EVENTS_CORE_COLUMNS]),
  41. "5636adc78212aad094ac57e45d44ecb230e59287a58569d94d2a82ddd148b600",
  42. )
  43. self.assertEqual(
  44. _df_sha256(trades[TRADES_CORE_COLUMNS]),
  45. "1d419aafd7cbb4a88091b4a1b217d9e3ea806607c73f34650fd3b686790093ff",
  46. )
  47. def test_default_branch_release_hashes_stay_stable(self) -> None:
  48. events, trades = DragonRuleEngine(config=alpha_first_glued_refined_hot_cap_config()).run(self.indexed)
  49. events = events[(events["date"] >= START_DATE) & (events["date"] <= END_DATE)].copy()
  50. trades = self._release_window_trades(trades)
  51. events.sort_values(["date", "side", "layer", "reason"], inplace=True)
  52. trades.sort_values(["buy_date", "sell_date", "buy_reason", "sell_reason"], inplace=True)
  53. self.assertEqual(
  54. _df_sha256(events[EVENTS_CORE_COLUMNS]),
  55. self.manifest["artifacts"]["events"]["core_sha256"],
  56. )
  57. self.assertEqual(
  58. _df_sha256(trades[TRADES_CORE_COLUMNS]),
  59. self.manifest["artifacts"]["trades"]["core_sha256"],
  60. )
  61. def test_probe_branch_adds_expected_single_trade_fixture(self) -> None:
  62. _, base_trades = DragonRuleEngine(config=alpha_first_glued_refined_hot_cap_config()).run(self.indexed)
  63. _, probe_trades = DragonRuleEngine(config=alpha_first_glued_followthrough_probe_config()).run(self.indexed)
  64. base_trades = self._release_window_trades(base_trades)
  65. probe_trades = self._release_window_trades(probe_trades)
  66. base_keys = {
  67. (row.buy_date, row.sell_date, row.buy_reason, row.sell_reason)
  68. for row in base_trades.itertuples()
  69. }
  70. extra = probe_trades[
  71. ~probe_trades.apply(
  72. lambda row: (
  73. row["buy_date"],
  74. row["sell_date"],
  75. row["buy_reason"],
  76. row["sell_reason"],
  77. )
  78. in base_keys,
  79. axis=1,
  80. )
  81. ].copy()
  82. self.assertEqual(len(base_trades), 91)
  83. self.assertEqual(len(probe_trades), 92)
  84. self.assertEqual(len(extra), 1)
  85. row = extra.iloc[0]
  86. self.assertEqual(row["buy_date"], "2020-12-01")
  87. self.assertEqual(
  88. row["buy_reason"],
  89. "glued_followthrough_reentry_buy:confirmed_mid_zone_very_weak_b1",
  90. )
  91. self.assertEqual(row["sell_date"], "2020-12-09")
  92. self.assertEqual(row["sell_reason"], "knife_take_profit_2_glued")
  93. self.assertEqual(int(row["holding_days"]), 8)
  94. self.assertAlmostEqual(float(row["return_pct"]), -0.0024350630226196435, places=12)
  95. if __name__ == "__main__":
  96. unittest.main()