diff --git a/backtester/backtester.py b/backtester/backtester.py index 61e4f37..51fad0b 100644 --- a/backtester/backtester.py +++ b/backtester/backtester.py @@ -193,8 +193,13 @@ class Backtest: sold = 0 total_costs = sum([current_options[i]['cost'] for i in range(len(current_options))]) for (exit_cost, (row_index, inventory_row)) in zip(total_costs, self._options_inventory.iterrows()): - if (to_sell - sold < -exit_cost * inventory_row['totals']['qty']) and (to_sell - sold) > 0: + if (to_sell - sold > -exit_cost) and (to_sell - sold) > 0: qty_to_sell = (to_sell - sold) // exit_cost + if -qty_to_sell <= inventory_row['totals']['qty']: + qty_to_sell = (to_sell - sold) // exit_cost + else: + if qty_to_sell != 0: + qty_to_sell = -inventory_row['totals']['qty'] if qty_to_sell != 0: trade_log_append = self._options_inventory.loc[row_index].copy() trade_log_append['totals', 'qty'] = -qty_to_sell diff --git a/backtester/test/backtester/test_buy_options.py b/backtester/test/backtester/test_buy_options.py index f4cf70d..7b9acaa 100644 --- a/backtester/test/backtester/test_buy_options.py +++ b/backtester/test/backtester/test_buy_options.py @@ -63,6 +63,20 @@ def test_sell_some_options_2leg_buy_sell(options_data_buy_and_sell_2legs, ivy_po assert np.allclose(bt.trade_log['totals']['cost'].values, [200, 300, -200], rtol=tolerance) +def test_sell_some_options_1leg_buy_sell_all(options_data_1put_buy_sell_all, ivy_portfolio_5assets_datahandler, + ivy_5assets_portfolio): + options_data = options_data_1put_buy_sell_all + bt = run_backtest(ivy_5assets_portfolio, ivy_portfolio_5assets_datahandler, options_data, + options_1leg_buy_strategy(options_data)) + tolerance = 0.0001 + assert np.allclose(bt.trade_log['totals']['qty'].values, [ + 300, ((970000 + 300 * 25) * 0.03 - 300 * 25) // 100, 300, + math.ceil((1000 * 218 - (((970000 + 300 * 25) * 0.97 + 300 * 150 + 218 * 1000) * 0.03)) / 1000) + ], + rtol=tolerance) + assert np.allclose(bt.trade_log['totals']['cost'].values, [100, 100, -150, -1000], rtol=tolerance) + + def run_backtest(stocks, stock_data, options_data, diff --git a/backtester/test/conftest.py b/backtester/test/conftest.py index 0044d36..8e7292e 100644 --- a/backtester/test/conftest.py +++ b/backtester/test/conftest.py @@ -157,3 +157,21 @@ def options_data_buy_and_sell_2legs(): data._data.at[204, 'bid'] = 1. # SPX6500 call 2015-03-02 data._data.at[205, 'bid'] = 1.5 # SPX7000 call 2015-03-02 return data + + +@pytest.fixture(scope='module') +def options_data_1put_buy_sell_all(): + data = HistoricalOptionsData(TWO_PUTS_TWO_CALLS_DATA) + data._data.at[2, 'ask'] = 1 # SPX6500 put 2014-12-15 + data._data.at[2, 'bid'] = 0.5 # SPX6500 put 2014-12-15 + + data._data.at[50, 'ask'] = 0.25 # SPX6500 put 2015-01-02 + data._data.at[50, 'bid'] = 0.25 # SPX6500 put 2015-01-02 + data._data.at[51, 'ask'] = 1 # SPX6500 put 2015-01-02 + + data._data.at[131, 'bid'] = 10 # SPX7000 put 2015-02-02 + data._data.at[130, 'bid'] = 1.5 # SPX6500 put 2015-02-02 + + data._data.at[206, 'bid'] = 2 # SPX6500 put 2015-03-02 + data._data.at[206, 'ask'] = 2.5 # SPX6500 put 2015-03-02 + return data