"""对冲计划虚实值选约与校验.""" import unittest from lib.hedge_plan.hedge_plan_moneyness_lib import ( is_atm_or_otm, is_itm_or_atm, parse_strike_from_inst, pick_itm_or_atm_contract, recommend_oo_legs, validate_oo_legs_moneyness, validate_po_option_moneyness, ) from lib.hedge_plan.hedge_plan_orders_lib import validate_start_body class TestHedgeMoneyness(unittest.TestCase): def test_parse_strike(self): self.assertEqual(parse_strike_from_inst("ETH-USD-260731-1800-P"), 1800.0) self.assertIsNone(parse_strike_from_inst("bad")) def test_po_geometry(self): # Call: K<=S 实/平 self.assertTrue(is_itm_or_atm(opt_type="C", strike=3500, index_px=3510)) self.assertFalse(is_itm_or_atm(opt_type="C", strike=3600, index_px=3510)) # Put: K>=S self.assertTrue(is_itm_or_atm(opt_type="P", strike=3600, index_px=3510)) self.assertFalse(is_itm_or_atm(opt_type="P", strike=3400, index_px=3510)) def test_oo_geometry(self): self.assertTrue(is_atm_or_otm(opt_type="C", strike=3600, index_px=3510)) self.assertFalse(is_atm_or_otm(opt_type="C", strike=3400, index_px=3510)) self.assertTrue(is_atm_or_otm(opt_type="P", strike=3400, index_px=3510)) self.assertFalse(is_atm_or_otm(opt_type="P", strike=3600, index_px=3510)) def test_validate_po_rejects_otm(self): err = validate_po_option_moneyness(opt_type="P", strike=1700, index_px=1800) self.assertIsNotNone(err) self.assertIn("虚值", err) self.assertIsNone( validate_po_option_moneyness(opt_type="P", strike=1800, index_px=1800) ) def test_validate_oo_rejects_itm(self): err = validate_oo_legs_moneyness( {"opt_type": "C", "strike": 1700}, {"opt_type": "P", "strike": 1900}, index_px=1800, ) self.assertIsNotNone(err) self.assertIn("实值", err) self.assertIsNone( validate_oo_legs_moneyness( {"opt_type": "C", "strike": 1850}, {"opt_type": "P", "strike": 1750}, index_px=1800, ) ) def test_pick_itm_or_atm(self): contracts = [ {"inst_id": "E-C-3600", "opt_type": "C", "strike": 3600}, {"inst_id": "E-C-3500", "opt_type": "C", "strike": 3500}, {"inst_id": "E-C-3400", "opt_type": "C", "strike": 3400}, ] picked = pick_itm_or_atm_contract( contracts, opt_type="C", index_px=3510, itm_max_dist=200 ) self.assertIsNotNone(picked) self.assertEqual(picked["strike"], 3500) def test_recommend_oo(self): contracts = [ {"inst_id": "E-C-1800", "opt_type": "C", "strike": 1800}, {"inst_id": "E-P-1800", "opt_type": "P", "strike": 1800}, {"inst_id": "E-C-1900", "opt_type": "C", "strike": 1900}, {"inst_id": "E-P-1700", "opt_type": "P", "strike": 1700}, ] pair = recommend_oo_legs(contracts, index_px=1800, template="atm_straddle") self.assertIsNotNone(pair) self.assertEqual(pair[0]["opt_type"], "C") self.assertEqual(pair[1]["opt_type"], "P") def test_validate_start_body_po_otm(self): err = validate_start_body( "perp_options", { "direction": "long", "entry": 1800, "tp": 1900, "sl": 1700, "contracts": 1, "opt_inst_id": "ETH-USD-260731-1700-P", "opt_type": "P", "strike": 1700, "index_px": 1800, "sheets": 1, "exchange_symbol": "ETH/USDT:USDT", }, ) self.assertIsNotNone(err) self.assertIn("虚值", err) def test_validate_start_body_oo_itm(self): err = validate_start_body( "options_options", { "target_price_up": 1900, "target_price_down": 1700, "index_px": 1800, "leg_a": {"inst_id": "ETH-USD-260731-1700-C", "opt_type": "C", "strike": 1700}, "leg_b": {"inst_id": "ETH-USD-260731-1900-P", "opt_type": "P", "strike": 1900}, }, ) self.assertIsNotNone(err) self.assertIn("实值", err) if __name__ == "__main__": unittest.main()