From b5168bd92d0529eb442c88d9fb9f3eed1637866e Mon Sep 17 00:00:00 2001 From: moshferatu Date: Tue, 13 Feb 2024 08:49:02 -0800 Subject: [PATCH] Select short strikes based on target credit --- iron_condor.py | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/iron_condor.py b/iron_condor.py index dce4054..799d705 100644 --- a/iron_condor.py +++ b/iron_condor.py @@ -10,9 +10,10 @@ from dotenv import load_dotenv from ibkr import Client, OptionLeg from ibkr.option_type import CALL, PUT from ibkr.order_action import BUY, SELL +from options_chain import OptionsChain +from option_type import OptionType from os import getenv from pytz import timezone -from tradestation import TradeStationClient load_dotenv() @@ -96,35 +97,21 @@ def _enter_iron_condor(): # The weekly symbol for SPX (SPXW) is required in order to distinguish from monthly options. symbol, sub_symbol = 'SPX', 'SPXW' expiration = datetime.now() - - tradestation_client = TradeStationClient(getenv('TRADESTATION_REFRESH_TOKEN')) - option_chain = tradestation_client.get_options_chain('$SPXW.X', expiration) - logging.info(option_chain) + options_chain = OptionsChain('$SPXW.X', datetime.now()) + logging.info(options_chain) - target_delta = 0.10 - - def closest_contract_by_delta(target_delta, option_chain, option_type): - options = option_chain[option_chain['Type'] == option_type].copy() - options['Delta Distance'] = abs(options['Delta'] - target_delta) - return options.loc[options['Delta Distance'].idxmin()] - - # Find the strikes that minimize the distance to the target delta. - short_put_contract = closest_contract_by_delta(-target_delta, option_chain, 'PUT') - short_call_contract = closest_contract_by_delta(target_delta, option_chain, 'CALL') + credit_target = float(getenv('CREDIT_TARGET')) + short_put_contract = options_chain.closest_contract_by_credit(credit_target, OptionType.PUT) + short_call_contract = options_chain.closest_contract_by_credit(credit_target, OptionType.CALL) # When selecting long strikes, minimize the distance to a 50 point spread. # TODO: Select long strike based on preferred price. target_long_put_strike = short_put_contract['Strike'] - 50 target_long_call_strike = short_call_contract['Strike'] + 50 - def closest_contract_by_strike(target_strike, option_chain, option_type): - options = option_chain[option_chain['Type'] == option_type].copy() - options['Strike Distance'] = abs(options['Strike'] - target_strike) - return options.loc[options['Strike Distance'].idxmin()] - - long_put_contract = closest_contract_by_strike(target_long_put_strike, option_chain, 'PUT') - long_call_contract = closest_contract_by_strike(target_long_call_strike, option_chain, 'CALL') + long_put_contract = options_chain.closest_contract_by_strike(target_long_put_strike, OptionType.PUT) + long_call_contract = options_chain.closest_contract_by_strike(target_long_call_strike, OptionType.CALL) # Build the iron condor. short_put_strike = float(short_put_contract['Strike']) @@ -188,7 +175,7 @@ def _enter_iron_condor(): trade_records.append({ 'Date': now.date(), 'Symbol': symbol, - 'Strategy': f'{int(target_delta * 100)} Delta Iron Condor', + 'Strategy': f'${credit_target:.2f} Iron Condor', 'Entry Time': now, 'Exit Time': None, 'Spreads': [call_spread_details, put_spread_details],