|
9 | 9 | Underlying, |
10 | 10 | calculate_margin, |
11 | 11 | ) |
| 12 | +from margin_estimator.margin import ZERO |
| 13 | +from margin_estimator.models import MarginRequirements |
12 | 14 |
|
13 | 15 |
|
14 | 16 | def test_long_option(): |
@@ -914,3 +916,32 @@ def test_complex_multi_strategy_position(): |
914 | 916 | underlying, |
915 | 917 | ) |
916 | 918 | assert total == vertical + orphan_spread + strangle + mismatched_spread |
| 919 | + |
| 920 | + |
| 921 | +def test_cancel_opposing_positions(): |
| 922 | + underlying = Underlying(price=500) |
| 923 | + long = Option( |
| 924 | + expiration=date.today(), price=10, quantity=1, strike=510, type=OptionType.CALL |
| 925 | + ) |
| 926 | + short = Option( |
| 927 | + expiration=date.today(), price=10, quantity=-1, strike=510, type=OptionType.CALL |
| 928 | + ) |
| 929 | + nothing = MarginRequirements(cash_requirement=ZERO, margin_requirement=ZERO) |
| 930 | + assert calculate_margin([long, short], underlying) == nothing |
| 931 | + assert calculate_margin([long, short, short, long], underlying) == nothing |
| 932 | + assert ( |
| 933 | + calculate_margin([short, long, long, short, long, short], underlying) == nothing |
| 934 | + ) |
| 935 | + |
| 936 | + |
| 937 | +def test_cancel_some_opposing_positions(): |
| 938 | + underlying = Underlying(price=500) |
| 939 | + long = Option( |
| 940 | + expiration=date.today(), price=10, quantity=1, strike=510, type=OptionType.CALL |
| 941 | + ) |
| 942 | + short = Option( |
| 943 | + expiration=date.today(), price=10, quantity=-2, strike=510, type=OptionType.CALL |
| 944 | + ) |
| 945 | + assert calculate_margin([long, short], underlying) == calculate_margin( |
| 946 | + [short.model_copy(update={"quantity": -1})], underlying |
| 947 | + ) |
0 commit comments