Add weekend filter, take-profit, and profit column to amp stats.
Long-straddle effective move uses TP on path hit (>=) else abs change; mark Sat/Sun on settlement days. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -114,6 +114,83 @@ class AmpStatsLibTests(unittest.TestCase):
|
||||
self.assertIn("买跨对照", csv_text)
|
||||
self.assertIn("买跨点数盈亏合计", csv_text)
|
||||
|
||||
def test_take_profit_and_weekend(self):
|
||||
from lib.hub.amp_stats_lib import (
|
||||
enrich_rows_pnl,
|
||||
filter_weekend_rows,
|
||||
reframe_amp_stats,
|
||||
)
|
||||
|
||||
# Sat 2026-07-18, Sun 2026-07-19, Mon 2026-07-20
|
||||
rows = [
|
||||
{
|
||||
"settlement_day": "2026-07-18",
|
||||
"is_weekend": True,
|
||||
"weekday_label": "六",
|
||||
"up_points": 100,
|
||||
"down_points": 10,
|
||||
"change": -5,
|
||||
"amplitude": 110,
|
||||
},
|
||||
{
|
||||
"settlement_day": "2026-07-19",
|
||||
"is_weekend": True,
|
||||
"weekday_label": "日",
|
||||
"up_points": 20,
|
||||
"down_points": 15,
|
||||
"change": 12,
|
||||
"amplitude": 35,
|
||||
},
|
||||
{
|
||||
"settlement_day": "2026-07-20",
|
||||
"is_weekend": False,
|
||||
"weekday_label": "",
|
||||
"up_points": 50,
|
||||
"down_points": 40,
|
||||
"change": 8,
|
||||
"amplitude": 90,
|
||||
},
|
||||
]
|
||||
excl = filter_weekend_rows(rows, "exclude")
|
||||
self.assertEqual(len(excl), 1)
|
||||
self.assertEqual(excl[0]["settlement_day"], "2026-07-20")
|
||||
only = filter_weekend_rows(rows, "only")
|
||||
self.assertEqual(len(only), 2)
|
||||
|
||||
# TP=80: day1 hit → move 80; day2 no → |12|; day3 no → 8
|
||||
enriched = enrich_rows_pnl(rows, straddle_premium=10, take_profit=80)
|
||||
self.assertTrue(enriched[0]["take_profit_hit"])
|
||||
self.assertEqual(enriched[0]["effective_move"], 80)
|
||||
self.assertEqual(enriched[0]["profit"], 70)
|
||||
self.assertFalse(enriched[1]["take_profit_hit"])
|
||||
self.assertEqual(enriched[1]["effective_move"], 12)
|
||||
self.assertEqual(enriched[1]["profit"], 2)
|
||||
# TP empty → use |change|
|
||||
no_tp = enrich_rows_pnl(rows[:1], straddle_premium=10, take_profit=None)
|
||||
self.assertEqual(no_tp[0]["effective_move"], 5)
|
||||
self.assertEqual(no_tp[0]["profit"], -5)
|
||||
|
||||
# TP boundary >= : up=80 counts as hit
|
||||
edge = enrich_rows_pnl(
|
||||
[{"up_points": 80, "down_points": 1, "change": 2, "settlement_day": "2026-07-20", "is_weekend": False}],
|
||||
straddle_premium=10,
|
||||
take_profit=80,
|
||||
)
|
||||
self.assertTrue(edge[0]["take_profit_hit"])
|
||||
self.assertEqual(edge[0]["profit"], 70)
|
||||
|
||||
reframed = reframe_amp_stats(
|
||||
rows_all=rows,
|
||||
symbol="eth",
|
||||
weekend_filter="exclude",
|
||||
straddle_premium=10,
|
||||
take_profit=80,
|
||||
)
|
||||
self.assertEqual(reframed["summary"]["sample_count"], 1)
|
||||
# Mon: 未触达止盈 → |8|-10
|
||||
self.assertEqual(reframed["rows"][0]["profit"], -2)
|
||||
self.assertIn("收益", build_export_csv(reframed))
|
||||
|
||||
def test_compute_with_mock_fetch(self):
|
||||
now = datetime(2026, 7, 22, 18, 0, tzinfo=TZ)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user