예제 #1
0
파일: trader.py 프로젝트: FinTrek/ib_tools
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
예제 #2
0
파일: manager.py 프로젝트: t1user/ib_tools
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
예제 #3
0
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.')
예제 #4
0
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()
예제 #5
0
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()
예제 #6
0
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'
예제 #8
0
                              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)
예제 #9
0
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)
예제 #10
0
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()
예제 #11
0
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)
예제 #12
0
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"])
예제 #13
0
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
예제 #14
0
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()
예제 #15
0
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()
예제 #16
0
    "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:
예제 #17
0
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)
예제 #18
0
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: