feat(hedge): replace OO breakout targets with premium profit RR
期期改用盈亏比×权利金止盈(默认2);不达标持有至到期。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -102,8 +102,7 @@ class TestHedgePlanCalc(unittest.TestCase):
|
||||
a = {"opt_type": "C", "strike": 3300, "sheets": 1, "ct_mult": 0.01, "premium_paid": 5}
|
||||
b = {"opt_type": "P", "strike": 3100, "sheets": 1, "ct_mult": 0.01, "premium_paid": 5}
|
||||
p = build_options_options_preview(
|
||||
target_price_up=3500,
|
||||
target_price_down=3000,
|
||||
profit_rr=2,
|
||||
index_px=3200,
|
||||
leg_a=a,
|
||||
leg_b=b,
|
||||
@@ -111,11 +110,11 @@ class TestHedgePlanCalc(unittest.TestCase):
|
||||
self.assertEqual(p["summary"]["premium_paid"], 10)
|
||||
self.assertTrue(p["summary"]["expiry_is_loss"])
|
||||
self.assertEqual(p["summary"]["rr_risk_premium"], 10)
|
||||
self.assertIsNotNone(p["summary"]["rr_at_up"])
|
||||
self.assertAlmostEqual(p["summary"]["rr_at_up"], p["summary"]["at_target_up_total"] / 10, places=4)
|
||||
self.assertEqual(len(p["scenarios"]), 4)
|
||||
self.assertEqual(p["scenarios"][0]["id"], "target_up")
|
||||
self.assertEqual(p["scenarios"][1]["id"], "target_down")
|
||||
self.assertEqual(p["summary"]["oo_profit_rr"], 2)
|
||||
self.assertAlmostEqual(p["summary"]["target_profit"], 20.0, places=4)
|
||||
self.assertEqual(len(p["scenarios"]), 3)
|
||||
self.assertEqual(p["scenarios"][0]["id"], "rr_target")
|
||||
self.assertEqual(p["scenarios"][1]["id"], "expiry_flat")
|
||||
|
||||
def test_oo_legacy_single_target_still_works(self):
|
||||
a = {"opt_type": "C", "strike": 3300, "sheets": 1, "ct_mult": 0.01, "premium_paid": 5}
|
||||
@@ -124,6 +123,21 @@ class TestHedgePlanCalc(unittest.TestCase):
|
||||
self.assertEqual(p["target_price_up"], 3500)
|
||||
self.assertEqual(p["target_price_down"], 3500)
|
||||
|
||||
def test_oo_legacy_up_down_rr_fields(self):
|
||||
a = {"opt_type": "C", "strike": 3300, "sheets": 1, "ct_mult": 0.01, "premium_paid": 5}
|
||||
b = {"opt_type": "P", "strike": 3100, "sheets": 1, "ct_mult": 0.01, "premium_paid": 5}
|
||||
p = build_options_options_preview(
|
||||
target_price_up=3500,
|
||||
target_price_down=3000,
|
||||
index_px=3200,
|
||||
leg_a=a,
|
||||
leg_b=b,
|
||||
)
|
||||
self.assertIsNotNone(p["summary"]["rr_at_up"])
|
||||
self.assertAlmostEqual(p["summary"]["rr_at_up"], p["summary"]["at_target_up_total"] / 10, places=4)
|
||||
self.assertEqual(p["scenarios"][0]["id"], "target_up")
|
||||
self.assertEqual(p["scenarios"][1]["id"], "target_down")
|
||||
|
||||
def test_perp_short_pnl(self):
|
||||
self.assertEqual(
|
||||
perp_pnl(direction="short", entry=100, exit_px=90, contracts=1, contract_size=1),
|
||||
|
||||
@@ -155,6 +155,32 @@ class TestHedgeHistoryStats(unittest.TestCase):
|
||||
self.assertEqual(targets["ETH-USD_UM-260719-1850-P"]["target_index"], 1800)
|
||||
self.assertEqual(targets["ETH-USD_UM-260719-1890-C"]["managed_by"], "hedge_plan")
|
||||
|
||||
def test_active_options_targets_rr_mode_marks_managed(self):
|
||||
conn = _mem()
|
||||
pid = insert_plan(
|
||||
conn,
|
||||
{
|
||||
"plan_type": "options_options",
|
||||
"status": "active",
|
||||
"underlying": "ETH",
|
||||
"oo_profit_rr": 2,
|
||||
},
|
||||
)
|
||||
insert_leg(
|
||||
conn,
|
||||
{
|
||||
"plan_id": pid,
|
||||
"leg_role": "option_a",
|
||||
"inst_id": "ETH-USD_UM-260719-1890-C",
|
||||
"opt_type": "C",
|
||||
"status": "open",
|
||||
},
|
||||
)
|
||||
targets = active_options_targets_by_inst(conn)
|
||||
self.assertEqual(targets["ETH-USD_UM-260719-1890-C"]["managed_by"], "hedge_plan")
|
||||
self.assertIsNone(targets["ETH-USD_UM-260719-1890-C"]["target_index"])
|
||||
self.assertEqual(targets["ETH-USD_UM-260719-1890-C"]["oo_profit_rr"], 2.0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user