diff --git a/combo_option_order_example.py b/combo_option_order_example.py new file mode 100644 index 0000000..c9195fa --- /dev/null +++ b/combo_option_order_example.py @@ -0,0 +1,13 @@ +from datetime import datetime +from ibkr import Client as IBKR, OptionLeg +from ibkr.option_type import CALL, PUT +from ibkr.order_action import BUY, SELL + +client = IBKR() + +symbol, sub_symbol = 'SPX', 'SPXW' +expiration = datetime.now() +short_leg = OptionLeg(symbol, expiration, 4525.0, CALL, SELL, sub_symbol) +long_leg = OptionLeg(symbol, expiration, 4550.0, CALL, BUY, sub_symbol) + +client.submit_combo_option_order([short_leg, long_leg], 1) \ No newline at end of file diff --git a/ibkr/__init__.py b/ibkr/__init__.py index 3ead93a..10a2b98 100644 --- a/ibkr/__init__.py +++ b/ibkr/__init__.py @@ -1 +1,2 @@ -from .client import Client \ No newline at end of file +from .client import Client +from .option_leg import OptionLeg \ No newline at end of file diff --git a/ibkr/client.py b/ibkr/client.py index c2cc8d0..c2f07d7 100644 --- a/ibkr/client.py +++ b/ibkr/client.py @@ -1,15 +1,18 @@ import pandas as pd from datetime import datetime -from .exchange import SMART -from ib_insync import Contract, IB, Index, Option +from ib_insync import ComboLeg, Contract, IB, Index, Option, Order from ib_insync.util import isNan +from typing import Callable, List + +from .currency import USD +from .exchange import SMART from .market_data_type import LIVE -from typing import Callable +from .option_leg import OptionLeg class Client: - def __init__(self, host: str, port: int, client_id = 1) -> None: + def __init__(self, host: str = '127.0.0.1', port: int = 7497, client_id = 1) -> None: self.ib = IB() self.ib.connect(host, port, clientId = client_id) self.ib.reqMarketDataType(LIVE) @@ -57,4 +60,45 @@ class Client: 'Delta': option.modelGreeks.delta, }) - return pd.DataFrame(option_chain) \ No newline at end of file + return pd.DataFrame(option_chain) + + def get_option_contract(self, option_leg: OptionLeg) -> Option: + expiration_date = option_leg.expiration.strftime('%Y%m%d') + option_contract = Option( + option_leg.symbol, + expiration_date, + option_leg.strike, + option_leg.option_type, + exchange = SMART, + currency = USD + ) + if option_leg.sub_symbol: + option_contract.tradingClass = option_leg.sub_symbol + self.ib.qualifyContracts(option_contract) + return option_contract + + def submit_combo_option_order(self, legs: List[OptionLeg], quantity: int) -> None: + combo_legs = [] + for leg in legs: + option_contract = self.get_option_contract(leg) + combo_leg = ComboLeg() + combo_leg.conId = option_contract.conId + combo_leg.ratio = 1 + combo_leg.action = leg.action + combo_leg.exchange = SMART + combo_legs.append(combo_leg) + + combo_contract = Contract() + combo_contract.symbol = legs[0].symbol # Assuming all legs are for the same symbol. + combo_contract.secType = 'BAG' + combo_contract.currency = USD + combo_contract.exchange = SMART + combo_contract.comboLegs = combo_legs + + combo_order = Order() + combo_order.action = 'BUY' # TODO: Document the logic behind this. + combo_order.orderType = 'MKT' # TODO: Limit order support. + combo_order.totalQuantity = quantity + combo_order.transmit = True + + self.ib.placeOrder(combo_contract, combo_order) \ No newline at end of file diff --git a/ibkr/currency.py b/ibkr/currency.py new file mode 100644 index 0000000..07ce77d --- /dev/null +++ b/ibkr/currency.py @@ -0,0 +1 @@ +USD = 'USD' \ No newline at end of file diff --git a/ibkr/option_leg.py b/ibkr/option_leg.py new file mode 100644 index 0000000..4641cb1 --- /dev/null +++ b/ibkr/option_leg.py @@ -0,0 +1,12 @@ +from dataclasses import dataclass +from datetime import datetime +from typing import Literal + +@dataclass +class OptionLeg: + symbol: str + expiration: datetime + strike: float + option_type: Literal['C', 'P'] + action: Literal['BUY', 'SELL'] + sub_symbol: str = None \ No newline at end of file diff --git a/ibkr/option_type.py b/ibkr/option_type.py new file mode 100644 index 0000000..79eb23f --- /dev/null +++ b/ibkr/option_type.py @@ -0,0 +1,2 @@ +CALL = 'C' +PUT = 'P' \ No newline at end of file diff --git a/ibkr/order_action.py b/ibkr/order_action.py new file mode 100644 index 0000000..7622746 --- /dev/null +++ b/ibkr/order_action.py @@ -0,0 +1,2 @@ +BUY = 'BUY' +SELL = 'SELL' \ No newline at end of file