"""hub_calculator_lib 测算逻辑。""" from hub_calculator_lib import ( calc_initial_roll_qty, calc_roll_calculator, calc_trend_calculator, ) def test_trend_calculator_long_basic(): data, err = calc_trend_calculator( direction="long", capital_usdt=1000, risk_percent=5, leverage=5, entry_price=100, stop_loss=95, add_upper=110, take_profit=120, dca_legs=3, contract_size=1, ) assert err is None assert data is not None assert data["risk_budget_u"] == 50.0 assert len(data["rows"]) >= 2 assert data["rows"][0]["label"] == "首仓" def test_trend_calculator_short_rejects_bad_bounds(): data, err = calc_trend_calculator( direction="short", capital_usdt=1000, risk_percent=5, leverage=5, entry_price=100, stop_loss=90, add_upper=110, take_profit=80, dca_legs=3, ) assert data is None assert err is not None def test_roll_calculator_first_leg_auto(): data, err = calc_roll_calculator( direction="long", capital_usdt=1000, risk_percent=5, entry_price=100, stop_loss=95, take_profit=120, add_legs=[], legs_done=0, ) assert err is None assert data is not None assert data["first_contracts"] == 10.0 assert len(data["rows"]) == 1 assert data["rows"][0]["loss_at_sl_u"] == 50.0 assert data["rows"][0]["profit_at_tp_u"] == 200.0 def test_roll_calculator_chain_two_legs(): data, err = calc_roll_calculator( direction="long", capital_usdt=1000, risk_percent=5, entry_price=100, stop_loss=95, take_profit=120, add_legs=[ {"add_price": 105, "new_stop_loss": 98}, {"add_price": 108, "new_stop_loss": 101}, ], legs_done=0, ) assert err is None assert data is not None assert len(data["rows"]) == 3 assert data["rows"][0]["label"] == "首仓" assert data["rows"][1]["label"] == "滚仓1" assert data["rows"][2]["label"] == "滚仓2" assert float(data["final_contracts"]) > float(data["first_contracts"]) def test_roll_calculator_rejects_too_many_legs(): data, err = calc_roll_calculator( direction="long", capital_usdt=1000, risk_percent=5, entry_price=100, stop_loss=95, take_profit=120, add_legs=[ {"add_price": 105, "new_stop_loss": 98}, {"add_price": 108, "new_stop_loss": 101}, {"add_price": 110, "new_stop_loss": 103}, {"add_price": 112, "new_stop_loss": 105}, ], legs_done=0, ) assert data is None assert err is not None def test_initial_roll_qty(): qty, err = calc_initial_roll_qty("long", 100, 95, 50) assert err is None assert qty == 10.0