From 4c6c24bfd9baeae3e4f8d27b9e52f0b34851027d Mon Sep 17 00:00:00 2001 From: moshferatu Date: Tue, 19 Sep 2023 08:52:03 -0700 Subject: [PATCH] Add logic for placing the appropriate orders to enter the iron condor --- iron_condor.py | 64 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/iron_condor.py b/iron_condor.py index cd7986d..f4878a9 100644 --- a/iron_condor.py +++ b/iron_condor.py @@ -1,9 +1,11 @@ from datetime import datetime from dotenv import load_dotenv from ibkr import Client -from ibkr.option_type import CALL, PUT +from option_type import CALL, PUT from os import getenv from tastytrade import Tastytrade +from tastytrade.order import create_credit_spread +from tastytrade.symbology import zero_dte_spx_contract as contract load_dotenv() @@ -31,31 +33,59 @@ def contract_filter(contract): option_chain = ibkr_client.get_option_chain('SPX', datetime.now(), sub_symbol = 'SPXW', contract_filter = contract_filter) print(option_chain) -target_delta = 0.10 +target_delta = 0.20 -def closest_strike_by_delta(target_delta, option_chain, option_type): +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 * (1 if option_type == CALL else -1))) + 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. -closest_call_strike = closest_strike_by_delta(target_delta, option_chain, CALL) -closest_put_strike = closest_strike_by_delta(target_delta, option_chain, PUT) +short_put_contract = closest_contract_by_delta(-target_delta, option_chain, PUT) +short_call_contract = closest_contract_by_delta(target_delta, option_chain, CALL) -# Do the same for the long strikes. -target_long_call_strike = closest_call_strike['Strike'] + 50 -target_long_put_strike = closest_put_strike['Strike'] - 50 +# 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_strike_by_strike(target_strike, option_chain, option_type): +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()] -closest_long_call_strike = closest_strike_by_strike(target_long_call_strike, option_chain, CALL) -closest_long_put_strike = closest_strike_by_strike(target_long_put_strike, option_chain, PUT) +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) -# The requested iron condor. -print('Short Call Strike:', closest_call_strike['Strike']) -print('Long Call Strike:', closest_long_call_strike['Strike']) -print("Short Put Strike:", closest_put_strike['Strike']) -print('Long Put Strike:', closest_long_put_strike['Strike']) \ No newline at end of file +# Build the iron condor. +short_put_strike = float(short_put_contract['Strike']) +long_put_strike = float(long_put_contract['Strike']) +short_call_strike = float(short_call_contract['Strike']) +long_call_strike = float(long_call_contract['Strike']) + +put_spread_limit_price = short_put_contract['Bid'] - long_put_contract['Ask'] +call_spread_limit_price = short_call_contract['Bid'] - long_call_contract['Ask'] + +print("Short Put Strike:", short_put_strike) +print('Long Put Strike:', long_put_strike) +print('Put Spread Limit Price:', put_spread_limit_price) +print('Short Call Strike:', short_call_strike) +print('Long Call Strike:', long_call_strike) +print('Call Spread Limit Price:', call_spread_limit_price) + +put_credit_spread = create_credit_spread( + contract(PUT, short_put_strike), + contract(PUT, long_put_strike), + put_spread_limit_price, 1 +) +call_credit_spread = create_credit_spread( + contract(CALL, short_call_strike), + contract(CALL, long_call_strike), + call_spread_limit_price, 1 +) + +put_spread_result = tastytrade_client.submit_order(tastytrade_account, put_credit_spread) +call_spread_result = tastytrade_client.submit_order(tastytrade_account, call_credit_spread) + +print(put_spread_result) +print(call_spread_result) \ No newline at end of file