def get_contracts(params: List[Dict[str, Any]], ib: IB, ) -> List[Dict[str, Any]]: contract_list = [] for candle in params: for contract in candle.contract_fields: contract_list.append(getattr(candle, contract)) ib.qualifyContracts(*contract_list) log.debug(f'contracts qualified: {contract_list}') return params
def get_contracts( candles: List[Candle], ib: IB, ) -> List[Candle]: contract_list = [] for candle in candles: for contract in candle.contract_fields: contract_list.append(getattr(candle, contract)) ib.qualifyContracts(*contract_list) log.debug(f'contracts qualified: {contract_list}') return candles
def update_details(ib: IB, store: AbstractBaseStore, keys: Optional[Union[str, List[str]]] = None) -> None: """ Pull contract details from ib and update metadata in store. Args: ib: connected IB instance store: datastore instance, for which data will be updated keys (Optional): keys in datastore, for which data is to be updated, if not given, update all keys """ if keys is None: keys = store.keys() elif isinstance(keys, str): keys = [keys] contracts = {} for key in keys: try: contract = eval(store.read_metadata(key)['repr']) except TypeError: log.error(f'Metadata missing for {key}') continue contract.update(includeExpired=True) contracts[key] = contract ib.qualifyContracts(*contracts.values()) details = {} for k, v in contracts.copy().items(): try: details[k] = ib.reqContractDetails(v)[0] except IndexError: log.error(f'Contract unavailable: {k}') del contracts[k] # get commission levels order = MarketOrder('BUY', 1) commissions = {} for k, v in contracts.items(): try: commissions[k] = ib.whatIfOrder(v, order).commission except AttributeError: log.error(f'Commission unavailable for: {k}') commissions[k] = np.nan for c, d in details.items(): _d = {'name': d.longName, 'min_tick': d.minTick, 'commission': commissions[c] } store.write_metadata(c, _d) log.info('Data written to store.')
class Window(qt.QWidget): def __init__(self, host, port, clientId): qt.QWidget.__init__(self) self.edit = qt.QLineEdit('', self) self.edit.editingFinished.connect(self.add) self.table = TickerTable() self.connectButton = qt.QPushButton('Connect') self.connectButton.clicked.connect(self.onConnectButtonClicked) layout = qt.QVBoxLayout(self) layout.addWidget(self.edit) layout.addWidget(self.table) layout.addWidget(self.connectButton) self.connectInfo = (host, port, clientId) self.ib = IB() self.ib.pendingTickersEvent += self.table.onPendingTickers def add(self, text=''): text = text or self.edit.text() if text: contract = eval(text) if (contract and self.ib.qualifyContracts(contract) and contract not in self.table): ticker = self.ib.reqMktData(contract, '', False, False, None) self.table.addTicker(ticker) self.edit.setText(text) def onConnectButtonClicked(self, _): if self.ib.isConnected(): self.ib.disconnect() self.table.clearTickers() self.connectButton.setText('Connect') else: self.ib.connect(*self.connectInfo) self.ib.reqMarketDataType(2) self.connectButton.setText('Disonnect') for symbol in ('EURUSD', 'USDJPY', 'EURGBP', 'USDCAD', 'EURCHF', 'AUDUSD', 'NZDUSD'): self.add(f"Forex('{symbol}')") self.add("Stock('TSLA', 'SMART', 'USD')") def closeEvent(self, ev): asyncio.get_event_loop().stop()
class Window(QWidget): def __init__(self, host, port, clientId): QWidget.__init__(self) self.edit = QLineEdit('', self) self.edit.editingFinished.connect(self.add) self.connectButton = QPushButton('Connect') self.connectButton.clicked.connect(self.onConnectButtonClicked) layout = QVBoxLayout(self) layout.addWidget(self.edit) layout.addWidget(self.connectButton) self.graph = TickerGraph(self, width=5, height=4) self.graph.move(0, 0) layout.addWidget(self.graph) self.connectInfo = (host, port, clientId) self.ib = IB() def add(self, text=''): text = text #or self.edit.text() if text: contract = eval(text) if (contract and self.ib.qualifyContracts(contract)): data = self.ib.reqHistoricalData(contract, endDateTime='', durationStr='30 D', barSizeSetting='4 hours', whatToShow='MIDPOINT', useRTH=True) df = util.df(data) print(df["close"]) self.graph.plot(df["close"]) self.edit.setText(text) def onConnectButtonClicked(self, _): if self.ib.isConnected(): self.ib.disconnect() self.connectButton.setText('Connect') else: self.ib.connect(*self.connectInfo) self.connectButton.setText('Disconnect') self.add(f"Forex('" + str(self.edit.text()) + "')") def closeEvent(self, ev): asyncio.get_event_loop().stop()
class BrokerConnection(metaclass=Singleton): def __init__(self): self.ib = IB() def connect(self, host, port, client_id, callback=None): self.ib.connect(host, port, clientId=client_id) if callback: self.ib.connectedEvent += callback def disconnect(self): self.ib.disconnect() def isConnected(self): return self.ib.isConnected() def positions(self): return [ pos for pos in self.ib.positions() if pos.contract.secType == 'OPT' ] def reqMatchingSymbols(self, text_to_search): ''' Function IBApi::EClient::reqMatchingSymbols is available to search for stock contracts. The input can be either the first few letters of the ticker symbol, or for longer strings, a character sequence matching a word in the security name. https://interactivebrokers.github.io/tws-api/matching_symbols.html ''' return self.ib.reqMatchingSymbols(text_to_search) def getOptionChainContracts(self, contract): chain = self.ib.reqSecDefOptParams(contract.symbol, contract.exchange, contract.secType, contract.conId) qChain = self.ib.qualifyContracts(chain) #return util.df(qChain) return qChain
class Window(qt.QWidget): def __init__(self, host, port, clientId): qt.QWidget.__init__(self) self.vxxbLabel = qt.QLabel('VXXB') self.vxxbButton = qt.QPushButton('VXXB') self.tltLabel = qt.QLabel('TLT') self.tltButton = qt.QPushButton('TLT') self.gldLabel = qt.QLabel('GLD') self.gldButton = qt.QPushButton('GLD') self.vxxbButton.clicked.connect(self.onVXXBButtonClicked) self.gldButton.clicked.connect(self.onGLDButtonClicked) self.tltButton.clicked.connect(self.onTLTButtonClicked) self.pricedic = {} # self.edit = qt.QLineEdit('', self) # self.edit.editingFinished.connect(self.add) self.table = TickerTable() self.connectButton = qt.QPushButton('Connect') self.connectButton.clicked.connect(self.onConnectButtonClicked) layout = qt.QGridLayout(self)#qt.QVBoxLayout(self) layout.addWidget(self.vxxbLabel,0,0,1,2) layout.addWidget(self.vxxbButton,1,0,1,2) layout.addWidget(self.tltLabel,0,2,1,2) layout.addWidget(self.tltButton,1,2,1,2) layout.addWidget(self.gldLabel,0,4,1,2) layout.addWidget(self.gldButton,1,4,1,2) # layout.addWidget(self.edit) layout.addWidget(self.table,2,0,6,6) layout.addWidget(self.connectButton,9,2,1,2) self.connectInfo = (host, port, clientId) self.ib = IB() self.ib.pendingTickersEvent += self.table.onPendingTickers self.ib.pendingTickersEvent += self.onPendingTickersForLabels def add(self, contract): if (contract and self.ib.qualifyContracts(contract) and contract not in self.table): ticker = self.ib.reqMktData(contract, '', False, False, None) self.table.addTicker(ticker) def onConnectButtonClicked(self, _): if self.ib.isConnected(): self.ib.disconnect() self.table.clearTickers() self.connectButton.setText('Connect') else: self.ib.connect(*self.connectInfo) self.connectButton.setText('Disonnect') self.vxxb = Stock('VXXB',exchange='SMART') self.ib.qualifyContracts(self.vxxb) self.table.vxxbticker = self.ib.reqMktData(self.vxxb, '', False, False, None) self.tlt = Stock('TLT',exchange='ARCA') self.ib.qualifyContracts(self.tlt) self.table.tltticker = self.ib.reqMktData(self.tlt, '', False, False, None) self.gld = Stock('GLD',exchange='ARCA') self.ib.qualifyContracts(self.gld) self.table.gldticker = self.ib.reqMktData(self.gld, '', False, False, None) def closeEvent(self, ev): asyncio.get_event_loop().stop() def onPendingTickersForLabels(self, tickers): for ticker in tickers: if type(getattr(ticker,'contract'))==Stock: if ticker.contract.symbol=='VXXB': self.vxxbprice = ticker.marketPrice() self.vxxbLabel.setText('{0:0.2f}'.format(self.vxxbprice)) self.table.vxxbprice = self.vxxbprice self.pricedic['VXXB'] = self.vxxbprice # print('vxxb:'+str(ticker.marketPrice())) elif ticker.contract.symbol=='GLD': self.gldprice = ticker.marketPrice() self.gldLabel.setText('{0:0.2f}'.format(self.gldprice)) self.table.gldprice=self.gldprice self.pricedic['GLD'] = self.gldprice # print('gld:'+str(ticker.marketPrice())) else: self.tltprice = ticker.marketPrice() self.tltLabel.setText('{0:0.2f}'.format(self.tltprice)) self.table.tltprice=self.tltprice self.pricedic['TLT'] = self.tltprice # print('tlt:'+str(ticker.marketPrice())) def prepareOptionContract(self,stockcontract): contractPrice = self.pricedic[stockcontract.symbol] chains = self.ib.reqSecDefOptParams(stockcontract.symbol, '', stockcontract.secType,stockcontract.conId) chain = next(c for c in chains if c.exchange == 'SMART') # print(chain) strikes = sorted([strike for strike in chain.strikes if contractPrice - 2 < strike < contractPrice + 2]) expirations = sorted(exp for exp in chain.expirations)[:2] contracts = [Option(stockcontract.symbol, expiration, strike, 'P','SMART') for expiration in expirations for strike in strikes] # print(contracts) self.ib.qualifyContracts(*contracts) for ac in contracts: self.add(contract=ac) def onVXXBButtonClicked(self, _): if self.ib.isConnected(): self.table.clearTickers() self.prepareOptionContract(self.vxxb) self.table.symbolofticker = 'VXXB' def onGLDButtonClicked(self, _): if self.ib.isConnected(): self.table.clearTickers() self.prepareOptionContract(self.gld) self.table.symbolofticker = 'GLD' def onTLTButtonClicked(self, _): print('TLT') if self.ib.isConnected(): self.table.clearTickers() self.prepareOptionContract(self.tlt) self.table.symbolofticker = 'TLT'
str(datetime.datetime.now())) logs.write(str(zs[:2] + [ccl]) + '\n') ccl = 0 else: ccl += zs[2] xiadan(zs[1], zs[2]) print(zs, '下单时间:', str(datetime.datetime.now())) logs.write(str(zs) + '\n') logs.flush() print(f'持仓:{ccl}') # print(data[-2:]) # time.sleep(0.05) time.sleep(30) ib = IB() CODE = 'HSIH9' ib.connect('192.168.2.204', 7496, clientId=8, timeout=3) hsi = Future(localSymbol=CODE) ib.qualifyContracts(hsi) if __name__ == '__main__': argv = sys.argv ccl = 0 # 持仓量 if len(argv) > 1: try: ccl = int(argv[1]) except: pass main(ccl)
class trade_ES(): def __init__(self): self.ib = IB() self.ib.connect('127.0.0.1', 7497, clientId=np.random.randint(10, 1000)) self.tickers_ret = {} self.endDateTime = '' self.No_days = '43200 S' self.interval = '30 secs' self.tickers_signal = "Hold" self.ES = Future(symbol='ES', lastTradeDateOrContractMonth='20200619', exchange='GLOBEX', currency='USD') self.ib.qualifyContracts(self.ES) self.ES_df = self.ib.reqHistoricalData(contract=self.ES, endDateTime=self.endDateTime, durationStr=self.No_days, barSizeSetting=self.interval, whatToShow='TRADES', useRTH=False, keepUpToDate=True) self.tickers_ret = [] self.options_ret = [] self.option = {'call': FuturesOption, 'put': FuturesOption} self.options_history = {} self.trade_options = {'call': [], 'put': []} self.price = 0 self.i = -1 self.ES_df.updateEvent += self.make_clean_df self.Buy = True self.Sell = False self.ib.positionEvent += self.order_verify self.waitTimeInSeconds = 220 self.tradeTime = 0 self.mySemaphore = asyncio.Semaphore(1) def run(self): self.make_clean_df(self.ES_df) def next_exp_weekday(self): weekdays = {2: [6, 0], 4: [0, 1, 2], 0: [3, 4]} today = datetime.date.today().weekday() for exp, day in weekdays.items(): if today in day: return exp def next_weekday(self, d, weekday): days_ahead = weekday - d.weekday() if days_ahead <= 0: # Target day already happened this week days_ahead += 7 date_to_return = d + datetime.timedelta( days_ahead) # 0 = Monday, 1=Tuself.ESday, 2=Wednself.ESday... return date_to_return.strftime('%Y%m%d') def get_strikes_and_expiration(self): expiration = self.next_weekday(datetime.date.today(), self.next_exp_weekday()) chains = self.ib.reqSecDefOptParams(underlyingSymbol='ES', futFopExchange='GLOBEX', underlyingSecType='FUT', underlyingConId=self.ES.conId) chain = util.df(chains) strikes = chain[chain['expirations'].astype(str).str.contains( expiration)].loc[:, 'strikes'].values[0] [ESValue] = self.ib.reqTickers(self.ES) ES_price = ESValue.marketPrice() strikes = [ strike for strike in strikes if strike % 5 == 0 and ES_price - 10 < strike < ES_price + 10 ] return strikes, expiration def get_contract(self, right, net_liquidation): strikes, expiration = self.get_strikes_and_expiration() for strike in strikes: contract = FuturesOption(symbol='ES', lastTradeDateOrContractMonth=expiration, strike=strike, right=right, exchange='GLOBEX') self.ib.qualifyContracts(contract) self.price = self.ib.reqMktData(contract, "", False, False) if float(self.price.last) * 50 >= net_liquidation: continue else: return contract def make_clean_df(self, ES_df, hashbar=None): ES_df = util.df(ES_df) ES_df['RSI'] = ta.RSI(ES_df['close']) ES_df['macd'], ES_df['macdsignal'], ES_df['macdhist'] = ta.MACD( ES_df['close'], fastperiod=12, slowperiod=26, signalperiod=9) ES_df['MA_9'] = ta.MA(ES_df['close'], timeperiod=9) ES_df['MA_21'] = ta.MA(ES_df['close'], timeperiod=21) ES_df['MA_200'] = ta.MA(ES_df['close'], timeperiod=200) ES_df['EMA_9'] = ta.EMA(ES_df['close'], timeperiod=9) ES_df['EMA_21'] = ta.EMA(ES_df['close'], timeperiod=21) ES_df['EMA_200'] = ta.EMA(ES_df['close'], timeperiod=200) ES_df['ATR'] = ta.ATR(ES_df['high'], ES_df['low'], ES_df['close']) ES_df['roll_max_cp'] = ES_df['high'].rolling(20).max() ES_df['roll_min_cp'] = ES_df['low'].rolling(20).min() ES_df['roll_max_vol'] = ES_df['volume'].rolling(20).max() ES_df.dropna(inplace=True) self.loop_function(ES_df) def placeOrder(self, contract, order): trade = self.ib.placeOrder(contract, order) tradeTime = datetime.datetime.now() return ([trade, contract, tradeTime]) def sell(self, contract, position): self.ib.qualifyContracts(contract) if position.position > 0: order = 'Sell' else: order = 'Buy' marketorder = MarketOrder(order, abs(position.position)) marketTrade, contract, tradeTime = self.placeOrder( contract, marketorder) while self.ib.position.position != 0: self.ib.sleep(1) self.mySemaphore.release() async def buy(self, contract): await self.semaphore.acquire() self.ib.qualifyContracts(contract) marketorder = MarketOrder('Buy', 1) marketTrade = self.ib.placeOrder(contract, marketorder) def order_verify(self, order): if order.position == 0.0 or order.position < 0: self.Buy = True self.Sell = False elif order.position > 0: self.Buy = False self.Sell = True else: self.Buy = False self.Sell = False print(f'Buy= {self.Buy}, sell = {self.Sell}') def loop_function(self, ES_df): df = ES_df[[ 'high', 'low', 'volume', 'close', 'RSI', 'ATR', 'roll_max_cp', 'roll_min_cp', 'roll_max_vol', 'EMA_9', 'EMA_21', 'macd', 'macdsignal' ]] if self.tickers_signal == "Hold": print('Hold') if df["high"].iloc[self.i] >= df["roll_max_cp"].iloc[self.i] and \ df["volume"].iloc[self.i] > df["roll_max_vol"].iloc[self.i - 1] and df['RSI'].iloc[self.i] > 30 \ and df['macd'].iloc[self.i] > df['macdsignal'].iloc[self.i] : self.tickers_signal = "Buy" return elif df["low"].iloc[self.i] <= df["roll_min_cp"].iloc[self.i] and \ df["volume"].iloc[self.i] > df["roll_max_vol"].iloc[self.i - 1] and df['RSI'].iloc[self.i] < 70 \ and df['macd'].iloc[self.i] < df['macdsignal'].iloc[self.i]: self.tickers_signal = "Sell" return else: self.tickers_signal = "Hold" return elif self.tickers_signal == "Buy": print('BUY SIGNAL') if df["close"].iloc[self.i] > df["close"].iloc[self.i - 1] - ( 0.75 * df["ATR"].iloc[self.i - 1]) and len( self.ib.positions()) != 0: print( f'{df["close"].iloc[self.i]} > {df["close"].iloc[self.i - 1] - (0.75 * df["ATR"].iloc[self.i - 1])}' ) print('first buy condition') positions = self.ib.positions() for position in positions: if position.contract.right == 'C': self.sell(position.contract, position) self.tickers_signal = "Hold" return elif df["low"].iloc[self.i] <= df["roll_min_cp"].iloc[self.i] and \ df["volume"].iloc[self.i] > df["roll_max_vol"].iloc[self.i - 1] and df['RSI'].iloc[self.i] < 70 \ and df['macd'].iloc[self.i] < df['macdsignal'].iloc[self.i] and len(self.ib.positions())!=0: self.tickers_signal = "Sell" print('sell') positions = self.ib.positions() for position in positions: if position.contract.right == 'C': self.sell(position.contract, position) self.tickers_signal == "Sell" return else: if len(self.ib.positions()) == 0: self.option['call'] = self.get_contract( right="C", net_liquidation=2000) self.buy(self.option['call']) self.tickers_signal = "Hold" else: self.tickers_signal = "Hold" elif self.tickers_signal == "Sell": print('SELL SIGNAL') if df["close"].iloc[self.i] < df["close"].iloc[self.i - 1] + ( 0.75 * df["ATR"].iloc[self.i - 1]) and len( self.ib.positions()) != 0: print('first sell condition') print( f'{df["close"].iloc[self.i]} < {df["close"].iloc[self.i - 1] - (0.75 * df["ATR"].iloc[self.i - 1])}' ) print('sell') positions = self.ib.positions() for position in positions: if position.contract.right == 'P': self.sell(position.contract, position) self.tickers_signal = "Hold" return elif df["high"].iloc[self.i] >= df["roll_max_cp"].iloc[self.i] and \ df["volume"].iloc[self.i] > df["roll_max_vol"].iloc[self.i - 1] and df['RSI'].iloc[self.i] > 30 \ and df['macd'].iloc[self.i] > df['macdsignal'].iloc[self.i] and len(self.ib.positions())!=0: self.tickers_signal = "Buy" print('sell') positions = self.ib.positions() for position in positions: if position.contract.right == 'P': self.sell(position.contract, position) self.tickers_signal == "Buy" return else: if len(self.ib.positions()) == 0: self.option['put'] = self.get_contract( right="P", net_liquidation=2000) self.buy(self.option['put']) self.tickers_signal = "Hold" else: self.tickers_signal = "Hold" def checkError(self, errCode, errString): print('Error Callback', errCode, errString) if errCode == 2104: print('re-connect after 5 secs') self.ib.sleep(5) self.ib.disconnect() self.ib.connect('127.0.0.1', 7497, clientId=np.random.randint(10, 1000)) self.make_clean_df(self.ES)
def runProg(): """run program""" util.patchAsyncio() # log to a file utils.logToFile(f'getRecentHistoricalData4.log', level=logging.INFO) # utils.logToConsole() # set pandas option pd.set_option('display.width', 200) # specify connection details host = '127.0.0.1' port = 4002 ibcIni = '/home/bn/IBController/configPaper.ini' tradingMode = 'paper' clientId = 12 # start watchdog ibc = IBC(970, gateway=True, tradingMode=tradingMode, ibcIni=ibcIni) ib = IB() watchdogApp = ibcontroller.Watchdog(ibc, ib=ib,appStartupTime=15, host=host, port=port, clientId=clientId) watchdogApp.start() # create some contracts qcs = [] c = Contract(symbol='EUR',currency='CHF',exchange='IDEALPRO',secType='CASH') qc = ib.qualifyContracts(c)[0] qcs.append(qc) c = Contract(symbol='EUR',currency='CNH',exchange='IDEALPRO',secType='CASH') qc = ib.qualifyContracts(c)[0] qcs.append(qc) c = Contract(symbol='EUR',currency='GBP',exchange='IDEALPRO',secType='CASH') qc = ib.qualifyContracts(c)[0] qcs.append(qc) c = Contract(symbol='EUR', currency='JPY', exchange='IDEALPRO', secType='CASH') qc = ib.qualifyContracts(c)[0] qcs.append(qc) c = Contract(symbol='EUR', currency='RUB', exchange='IDEALPRO', secType='CASH') qc = ib.qualifyContracts(c)[0] qcs.append(qc) c = Contract(symbol='EUR', currency='USD', exchange='IDEALPRO', secType='CASH') qc = ib.qualifyContracts(c)[0] qcs.append(qc) c = Contract(symbol='IBDE30',currency='EUR',exchange='SMART',secType='CFD') qc = ib.qualifyContracts(c)[0] qcs.append(qc) c = Contract(symbol='DAX',currency='EUR',exchange='DTB',secType='IND') qc = ib.qualifyContracts(c)[0] qcs.append(qc) c = Contract(symbol='HSC50',currency='HKD',exchange='HKFE',secType='IND') qc = ib.qualifyContracts(c)[0] qcs.append(qc) c = Contract(symbol='INDU',currency='USD',exchange='CME',secType='IND') qc = ib.qualifyContracts(c)[0] qcs.append(qc) c = Contract(symbol='N225',currency='JPY',exchange='OSE.JPN',secType='IND') qc = ib.qualifyContracts(c)[0] qcs.append(qc) c = Contract(symbol='SPX',currency='USD',exchange='CBOE',secType='IND') qc = ib.qualifyContracts(c)[0] qcs.append(qc) # qcs = [qc for qc in qcs if qc.localSymbol in ['N225','EUR.USD','IBDE30','DJI']] # qcs = [qc for qc in qcs if qc.localSymbol in ['N225','DJI']] qcs = [qc for qc in qcs if qc.localSymbol in ['N225','DAX','DJI']] # function to request historical bars def requestHistoricalBars(qcs): # request historical bars barss = [] for qc in qcs: whatToShow = 'TRADES' if qc.secType == 'IND' else 'MIDPOINT' bars = ib.reqHistoricalData( qc, endDateTime='', durationStr='1 W', barSizeSetting='1 min', whatToShow=whatToShow, useRTH=False, formatDate=2, keepUpToDate=True) barss.append(bars) pass return barss barss = requestHistoricalBars(qcs) print('er', barss[0][-1]) print('er2', barss[1][-1]) print('er2', barss[2][-1]) def requestMarketData(qcs): for qc in qcs: ib.reqMktData(contract=qc, genericTickList='', snapshot=False, regulatorySnapshot=False, mktDataOptions=None) pass pass def requestRealTimeBars(qcs): barss = [] for qc in qcs: bars = ib.reqRealTimeBars(contract=qc, barSize='', whatToShow='MIDPOINT', useRTH=False, realTimeBarsOptions=None) barss.append(bars) pass return (barss) # define some callback def onBarUpdate(bars, hasNewBar): localSymbol = bars.contract.localSymbol secType = bars.contract.secType b0 = bars[0] if isinstance(b0, objects.RealTimeBar): dateTimeAttributeName = 'time' barType = 'RealTimeBar' else: dateTimeAttributeName = 'date' barType = 'BarData' pass dt0 = pd.to_datetime(getattr(b0,dateTimeAttributeName)).tz_localize(None) bm1 = bars[-1] dtm1 = pd.to_datetime(getattr(bm1,dateTimeAttributeName)).tz_localize(None) nowUTC = pd.to_datetime(pd.datetime.utcnow()).tz_localize(None) diffDateTIme = (nowUTC - dtm1) / pd.Timedelta('1 sec') if (hasNewBar or localSymbol in ['N225','DAX']): print(f'local Symbol: {localSymbol}, hasNewBar: {hasNewBar}; barType: {barType}, nBars: {len(bars)}, diffDateTime: {diffDateTIme}, close: {bm1.close}') def onPendingTickers(tickers): for t in tickers: localSymbol = t.contract.localSymbol if localSymbol == "EUR.USD": nowUTC = pd.to_datetime(pd.datetime.utcnow()).tz_localize(None) nowUTCRounded = nowUTC.floor('1 min') dateTime = pd.to_datetime(t.time).tz_localize(None) print(localSymbol, nowUTCRounded, ((dateTime - nowUTCRounded)/pd.Timedelta('1 sec')),t.close) pass pass pass def myErrorCallback(reqId, errorCode, errorString, contract): print("myErrorCallback", reqId,errorCode,errorString,contract) if False: # if errorCode == 322: print("myErrorCallback", reqId, errorCode, errorString, contract) # more than 50 simultaneous historical data requests app.ib.client.cancelHistoricalData(reqId) def onConnectedCallback(): print('connected') barss = requestHistoricalBars(qcs) # barss = requestRealTimeBars(qcs) ib.barUpdateEvent.clear() ib.barUpdateEvent += onBarUpdate print('connected 2') # requestMarketData(qcs) # ib.pendingTickersEvent.clear() # ib.pendingTickersEvent += onPendingTickers print('connected 3') pass def onDisconnectedCallback(): print ('disconnected') def myTimeoutCallback(timeout): print (f'timeout {timeout}') # request the bars barss = requestHistoricalBars(qcs) # request market data # requestMarketData(qcs) # request real time bars # requestRealTimeBars(qcs) # register the callbacks with ib ib.connectedEvent.clear() ib.connectedEvent += onConnectedCallback ib.disconnectedEvent.clear ib.disconnectedEvent = onDisconnectedCallback ib.barUpdateEvent.clear() ib.barUpdateEvent += onBarUpdate ib.pendingTickersEvent.clear() # ib.pendingTickersEvent += onPendingTickers ib.errorEvent.clear() ib.errorEvent += myErrorCallback ib.timeoutEvent.clear() ib.timeoutEvent += myTimeoutCallback def mySoftTimeoutCallback(watchdogApp): print (f'soft time out {watchdogApp}') def myHardTimeoutCallback(watchdogApp): print (f'hard time out {watchdogApp}') watchdogApp.flush() # def myStoppingCallback(sthg): # print (f'Stopping Event {sthg}') # def myStoppedCallback(sthg): # print (f'Stopped Event {sthg}') # watchdogApp.softTimeoutEvent.clear() watchdogApp.softTimeoutEvent += mySoftTimeoutCallback # watchdogApp.hardTimeoutEvent.clear() watchdogApp.hardTimeoutEvent += myHardTimeoutCallback # watchdogApp.stoppingEvent.clear() # watchdogApp.stoppingEvent += myStoppingCallback # # watchdogApp.stoppedEvent.clear() # watchdogApp.stoppedEvent += myStoppedCallback # run and never stop ib.run()
def findConIds(**kwargs): """prints a list of conIds for a hard-coded list of currencies""" ib = IB() ib.errorEvent += myErrorCallback clientId = kwargs.get('clientId'.lower()) ib.connect('127.0.0.1', 4002, clientId=clientId) # build a list of valid contracts # define contracts ForexStrs = [ # 'AUD', # 'CAD', 'CHF', 'CNH', 'GBP', 'JPY', 'USD', 'RUB', # 'CZK', # 'DKK', # 'HUF', # 'ILS', # 'MXN', # 'NOK', # 'NZD', # 'PLN', # 'SEK', # 'SGD', # 'TRY', # 'ZAR', ] # Indices and CFDs others = [ # { # 'secType': 'IND', # 'symbol': 'DAX', # 'exchange': 'DTB', # 'currency': 'EUR' # }, # { # 'secType': 'IND', # 'symbol': 'INDU', # 'exchange': 'CME', # 'currency': 'USD' # }, # { # 'secType': 'IND', # 'symbol': 'HSC50', # 'exchange': 'HKFE', # 'currency': 'HKD' # }, # { # 'secType': 'IND', # 'symbol': 'N225', # 'exchange': 'OSE.JPN', # 'currency': 'JPY' # }, # { # 'secType': 'IND', # 'symbol': 'SPX', # 'exchange': 'CBOE', # 'currency': 'USD' # }, { 'secType': 'CFD', 'symbol': 'IBCH20', 'exchange': 'SMART', 'currency': 'CHF' }, { 'secType': 'CFD', 'symbol': 'IBDE30', 'exchange': 'SMART', 'currency': 'EUR' }, { 'secType': 'CFD', 'symbol': 'IBEU50', 'exchange': 'SMART', 'currency': 'EUR' }, { 'secType': 'CFD', 'symbol': 'IBFR40', 'exchange': 'SMART', 'currency': 'EUR' }, { 'secType': 'CFD', 'symbol': 'IBGB100', 'exchange': 'SMART', 'currency': 'GBP' }, { 'secType': 'CFD', 'symbol': 'IBJP225', 'exchange': 'SMART', 'currency': 'JPY' }, { 'secType': 'CFD', 'symbol': 'IBHK50', 'exchange': 'SMART', 'currency': 'HKD' }, { 'secType': 'CFD', 'symbol': 'IBUS30', 'exchange': 'SMART', 'currency': 'USD' }, { 'secType': 'CFD', 'symbol': 'IBUS500', 'exchange': 'SMART', 'currency': 'USD' }, ] contractsQualified = [] # Forex for s in ForexStrs: try: contractsQualified.append( ib.qualifyContracts( Contract(secType='CASH', symbol='EUR', exchange='IDEALPRO', currency=s))[0]) pass except: print('could not qualify the contract for {}'.format(s)) pass pass # others for d in others: try: contractsQualified.append(ib.qualifyContracts(Contract(**d))[0]) pass except: print('could not qualify the contract for {}'.format(s)) pass pass # get contract information conIds = [] for c in contractsQualified: if c.secType in ['CASH', 'CFD']: whatToShow = 'MIDPOINT' else: whatToShow = 'TRADES' eDT = None try: req = ib.reqHeadTimeStampAsync(c, whatToShow=whatToShow, useRTH=False, formatDate=2) try: eDT = ib.run(asyncio.wait_for(req, 10)) except asyncio.TimeoutError: print('timeout') pass pass except: pass print(c.symbol, c.currency, c.localSymbol, c.exchange, c.conId, c.secType, eDT) # cD = ib.reqContractDetails(c)[0] # secType=cD.summary.secType # print (c.symbol, c.currency, c.localSymbol, c.exchange, c.conId, eDT, c.secType) conIds.append(c.conId) print(conIds)
parser = argparse.ArgumentParser(description="Calculate option chain profits.") parser.add_argument('symbol', type=str, help="The stock symbol (eg: GOOG) to use.") parser.add_argument('-e', '--expirations', metavar="YYYYMMDD", type=str, nargs="+", help="Option expiration date(s).", required=True) parser.add_argument('-f', '--future_prices', type=float, nargs="+", help="Future price(s) for computing profit.", required=True) parser.add_argument('-m', '--strike_modulus', type=int, help="Modulus value for strike prices", required=False) parser.add_argument('--contract_per_price', dest="contract_per_price", type=int, default=3) args = parser.parse_args() pd.set_option("display.max_rows", None) ib = IB() ib.connect() contract = Stock(args.symbol, "SMART", "USD") ib.reqMarketDataType(1) ib.qualifyContracts(contract) [ticker] = ib.reqTickers(contract) current_price = ticker.marketPrice() strike_min=min(current_price * 0.9, min(args.future_prices)) strike_max=max(current_price * 1.1, max(args.future_prices)) strike_modulus = args.strike_modulus or None option_chain = get_option_chain(ib, contract, args.expirations, strike_min=strike_min, strike_max=strike_max, strike_modulus=strike_modulus) for future_price in args.future_prices: df = option_chain.copy() print("\n\n") print(f"For: {contract.symbol} with future price of {future_price}") df["Price"] = df["Ask"] * df["Multiplier"] df["ProfitPerContract"] = calc_option_contract_profit(df["Ask"], df["Strike"], df["Multiplier"], df["Right"], future_price) df["ProfitPerDollar"] = df["ProfitPerContract"] / (df["Ask"] * df["Multiplier"])
from ib_insync import IB, Option, Stock # For this example, must have TWS running ib = IB() ib.connect("127.0.0.1", 7497, clientId=1) ib.reqMarketDataType(4) # get SPY option chain symbol = "SPY" stock = Stock(symbol, "SMART", currency="USD") contracts = ib.qualifyContracts(stock) [ticker] = ib.reqTickers(stock) tickerValue = ticker.marketPrice() print(tickerValue) chains = ib.reqSecDefOptParams(stock.symbol, "", stock.secType, stock.conId) chain = next(c for c in chains if c.exchange == "SMART") print(chain) # get call options for all expirations and strikes within range strikes = [ strike for strike in chain.strikes if strike % 5 == 0 and tickerValue - 20 < strike < tickerValue + 20 ] contracts = [ Option(symbol, expiration, strike, "C", "SMART", tradingClass=chain.tradingClass) for expiration in chain.expirations
def main(symbol): # util.logToConsole(logging.DEBUG) util.logToFile('log.txt') s = symbol.upper() click.echo("Options for {} Loading: ".format(s), nl=False) ib = IB() ib.connect('127.0.0.1', 7497, clientId=3, readonly=True) contract = Stock(s, 'SMART', 'USD') ib.qualifyContracts(contract) click.echo('Chains ', nl=False) chains = ib.reqSecDefOptParams(contract.symbol, '', contract.secType, contract.conId) chain = next(c for c in chains if c.exchange == 'SMART') click.echo('Price '.format(s), nl=False) ib.reqMarketDataType(1) [ticker] = ib.reqTickers(contract) value = ticker.marketPrice() strikes = [ strike for strike in chain.strikes if value * 0.90 < strike < value * 1.0 ] expirations = sorted(exp for exp in chain.expirations)[:2] rights = ['P', 'C'] click.echo("Option Contracts {}@{} ".format(s, value), nl=False) contracts = [ Option(s, expiration, strike, right, 'SMART', tradingClass=s) for right in rights for expiration in expirations for strike in strikes ] click.echo('Validate ', nl=False) contracts = ib.qualifyContracts(*contracts) click.echo(len(contracts), nl=False) ib.reqMarketDataType(4) click.echo(' Ticker') tickers = ib.reqTickers(*contracts) options = [] for t in tickers: # click.echo(t) # calc = ib.calculateOptionPrice( # t.contract, volatility=0.14, underPrice=value) # print(calc) options.append(OptionData(t)) df = util.df(options, [ 'symbol', 'lastTradeDateOrContractMonth', 'strike', 'right', 'marketPrice', 'optionYield', 'timeToExpiration', 'spread', 'bid', 'ask', 'impliedVol', 'delta', 'gamma', 'vega' ]) click.echo(df) currentWeekPut = df[(df['right'] == 'P') & (df['lastTradeDateOrContractMonth'] == expirations[0])] click.echo(currentWeekPut.loc[(abs(abs(currentWeekPut.delta) - 0.2)).sort_values().index].head(2)) ib.disconnect()
def runProg(): """run program""" util.patchAsyncio() # log to a file util.logToFile(f'getRecentHistoricalData2.log') # util.logToConsole() # set pandas option pd.set_option('display.width', 200) # specify connection details host = '127.0.0.1' port = 4002 ibcIni = '/home/bn/IBController/configPaper.ini' tradingMode = 'paper' clientId = 12 # start watchdog ibc = IBC(970, gateway=True, tradingMode=tradingMode, ibcIni=ibcIni) ib = IB() watchdogApp = ibcontroller.Watchdog(ibc, ib=ib, appStartupTime=15, host=host, port=port, clientId=clientId) watchdogApp.start() pass # create some contracts qcs = [] c = Contract(symbol='EUR', currency='USD', exchange='IDEALPRO', secType='CASH') qc = ib.qualifyContracts(c)[0] qcs.append(qc) # request market data for qc in qcs: ib.reqMktData(contract=qc, genericTickList='', snapshot=False, regulatorySnapshot=False, mktDataOptions=None) pass # define some callback def onPendingTickers(tickers): for t in tickers: localSymbol = t.contract.localSymbol if localSymbol == "EUR.USD": nowUTC = pd.to_datetime(pd.datetime.utcnow()).tz_localize(None) nowUTCRounded = nowUTC.floor('1 min') dateTime = pd.to_datetime(t.time).tz_localize(None) print(localSymbol, nowUTCRounded, ((dateTime - nowUTCRounded) / pd.Timedelta('1 sec')), t.close) pass pass pass def myErrorCallback(reqId, errorCode, errorString, contract): # print("myErrorCallback", reqId,errorCode,errorString,contract) if errorCode == 322: print("myErrorCallback", reqId, errorCode, errorString, contract) # more than 50 simultaneous historical data requests app.ib.client.cancelHistoricalData(reqId) # register the callbacks with ib ib.setCallback('error', myErrorCallback) ib.setCallback('pendingTickers', onPendingTickers) # run and never stop ib.run()
"FXI", "EWZ", "FB", "AAPL", "NFLX", "MSFT", "BABA", "INTC", "TSLA", ] FUTURES = [ "ES", "NQ", "RTY", "CL", "NG", "ZB", "ZN", "GC", "MXP", "EUR", "JPY", "GBP" ] stockContracts = [Stock(s, "SMART", "USD") for s in STOCK] ib.qualifyContracts(*stockContracts) futures = [ib.reqContractDetails(Future(f)) for f in FUTURES] futuresContracts = [c.contract for f in futures for c in f] futuresContracts = [ c for c in futuresContracts if c.tradingClass == c.symbol and c.lastTradeDateOrContractMonth.startswith("2019") ] for contract in stockContracts + futuresContracts: ib.reqMktData(contract, "", False, False) def onPendingTickers(tickers): ticks = [] for t in tickers:
def get_option_chain( ib: IB, qualified_contract: Contract, expirations: str, use_delayed_data=False, strike_min=None, strike_max=None, strike_modulus=None, rights=["P", "C"], ) -> pd.DataFrame: """ TODO: Write documentation """ if use_delayed_data: ib.reqMarketDataType(3) [ticker] = ib.reqTickers(qualified_contract) current_price = ticker.marketPrice() strike_min = strike_min or current_price * 0.90 strike_max = strike_max or current_price * 1.10 chains = ib.reqSecDefOptParams(qualified_contract.symbol, '', qualified_contract.secType, qualified_contract.conId) chain = next(c for c in chains if c.tradingClass == qualified_contract.symbol and c.exchange == qualified_contract.exchange) if strike_modulus: strikes = [ strike for strike in chain.strikes if strike_min < strike < strike_max and strike % strike_modulus == 0 ] else: strikes = [ strike for strike in chain.strikes if strike_min < strike < strike_max ] contracts = [ Option(qualified_contract.symbol, expiration, strike, right, qualified_contract.exchange, tradingClass=qualified_contract.symbol) for right in rights for expiration in expirations for strike in strikes ] if use_delayed_data: ib.reqMarketDataType(3) ib.qualifyContracts(*contracts) contracts = [contract for contract in contracts if contract.multiplier] if use_delayed_data: ib.reqMarketDataType(3) tickers = ib.reqTickers(*contracts) d = { "Expiration": [ str(ticker.contract.lastTradeDateOrContractMonth) for ticker in tickers ], "Strike": [ticker.contract.strike for ticker in tickers], "Right": [str(ticker.contract.right) for ticker in tickers], "Ask": [ticker.ask for ticker in tickers], "Multiplier": [int(ticker.contract.multiplier) for ticker in tickers], } return pd.DataFrame(data=d)
strikes = [ strike for strike in chain.strikes if strike % 5 == 0 and xValue - 2 < strike < xValue + 2 ] expirations = sorted(exp for exp in chain.expirations)[:3] rights = ["P", "C"] contracts = [ Option("SPY", expiration, strike, right, "SMART", tradingClass="SPY") for right in rights for expiration in expirations for strike in strikes ] contracts = ib.qualifyContracts(*contracts) # 2) ricevi tickers # 3) calcola hedge basato su greeks start = datetime.datetime(2020, 4, 14, 13, 30).replace(tzinfo=pytz.utc) allticks: List = [] ticks = ib.reqHistoricalTicks( contracts[0], startDateTime=start, endDateTime=None, numberOfTicks=1000, whatToShow="TRADES", ignoreSize=True, useRth=True, ) while 1: