コード例 #1
0
def test_ibgw_restart(ib_docker):

    subprocess.check_output(
        ['docker', 'container', 'stop', ib_docker]).decode().strip()
    subprocess.check_output(
        ['docker', 'container', 'start', ib_docker]).decode().strip()
    
    ib = IB()
    wait = 60
    while not ib.isConnected():
        try:
            IB.sleep(1)
            ib.connect('localhost', 4002, clientId=999)
        except:
            pass
        wait -= 1
        if wait <= 0:
            break
    
    contract = Forex('EURUSD')
    bars = ib.reqHistoricalData(
        contract, endDateTime='', durationStr='30 D',
        barSizeSetting='1 hour', whatToShow='MIDPOINT', useRTH=True)

    # convert to pandas dataframe:
    df = util.df(bars)
    print(df)
コード例 #2
0
class IbGateway:
    """Interactive Brokers functions to fetch data"""
    def __init__(self, host, port, clientId=0):
        self.ib_gateway = IB()
        self.ib_gateway.connect(host, port, clientId=clientId)

    def fundamental_data(self, contract):
        """Load fundamental data from Interactive Brokers"""
        ib_contract = Contract(**contract)
        fundamental_data = self.ib_gateway.reqFundamentalData(
            ib_contract, reportType="ReportsFinStatements")
        return xmltodict.parse(fundamental_data)

    def flush(self, tablename):
        """Remove all data from the table"""

    def ipmort_data(self, tablename, data):
        """Write data into the table"""

    def ping(self):
        """Pings Interactive Brokers gateway"""
        return self.ib_gateway.isConnected()

    def disconnect(self):
        """Disconnect from Interactive Brokers"""
        self.ib_gateway.disconnect()
コード例 #3
0
def ping():
    def timeout_handler(signum, frame):
        signal.alarm(0)
        raise TimeoutError('IB gateway timed out, please check your account & password')
    signal.signal(signal.SIGALRM, timeout_handler)
    signal.alarm(120)

    ib = IB()
    while not ib.isConnected():
        try:
            IB.sleep(1)
            ib.connect('localhost', 4001, clientId=1)
        except (ConnectionRefusedError, OSError) as e:
            if type(e) is TimeoutError:
                raise e
            logging.warning('Still waiting gateway connection..({})'.format(e))
    
    ib.disconnect()
コード例 #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
def test_ibgw_interactive(ib_docker):
    ib = IB()
    wait = 120
    while not ib.isConnected():
        try:
            IB.sleep(1)
            ib.connect('localhost', 4002, clientId=999)
        except:
            pass
        wait -= 1
        if wait <= 0:
            break
    
    contract = Forex('EURUSD')
    bars = ib.reqHistoricalData(
        contract, endDateTime='', durationStr='30 D',
        barSizeSetting='1 hour', whatToShow='MIDPOINT', useRTH=True)

    # convert to pandas dataframe:
    df = util.df(bars)
    print(df)
コード例 #7
0
def ping():
    def timeout_handler(signum, frame):
        signal.alarm(0)
        raise TimeoutError(
            'IB gateway timed out, please check your account & password')

    signal.signal(signal.SIGALRM, timeout_handler)
    signal.alarm(120)

    ib = IB()
    pingClientId = int(os.environ['IB_GATEWAY_PING_CLIENT_ID'])
    maxRetryCount = int(os.environ['ibAccMaxRetryCount'])
    retryCount = 0
    while not ib.isConnected():
        try:
            IB.sleep(1)
            ib.connect('localhost', 4001, clientId=pingClientId)
        except (ConnectionRefusedError, OSError) as e:
            retryCount += 1
            if retryCount >= 30:
                raise ValueError("Invalid ib account")
            logging.warning('Still waiting gateway connection..({})'.format(e))

    ib.disconnect()
コード例 #8
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
コード例 #9
0
    def init_ticker(self):
        self.ticker = self.ticker_in.text().upper()
        self.ticker_in.setText(self.ticker)
        # self.spot = Ydata_feed.get_latest(self.ticker)
        # self.spot_in.setText(str(self.spot['close']))
        # if spot == None:
        print(self.ticker)
        self.spot = data_feed.get_data(
            self.ticker,
            'STK',
            'SMART',
            'USD',
            duration="1 D",
            enddate=datetime.today().strftime("%Y%m%d %H:%M:%S %Z"),
            barsize='1 day')
        sleep(5)
        self.spot_in.setText(str(self.spot['close'][0]))

        self.div_in.setText(str(0))
        # self.div_in.setText(str(Ydata_feed.get_div_yield(ticker)))

        exps(self.ticker)
        with open(tmp_file, newline='') as f:
            reader = csv.reader(f)
            self.exp_list = (datetime.strptime(i, "%Y%m%d")
                             for i in list(reader)[0])

            self.formatted_exp_list = list(
                (datetime.strftime(i, "%m-%d-%Y") for i in self.exp_list))
            print(list(self.formatted_exp_list),
                  len(list(self.formatted_exp_list)))

        d0 = datetime.today()  #.strftime('%Y%m%d')

        dds = []
        x = 0
        for iii in self.formatted_exp_list:
            d1 = datetime.strptime(iii, '%m-%d-%Y')  #.strftime('%Y%m%d')

            delta = d1 - d0
            dd = delta.days
            dds.append(str(dd))

            self.formatted_exp_list[x] = str(
                self.formatted_exp_list[x]) + " [" + str(dd) + "] "
            x += 1

        print(dds, len(dds))

        print(self.formatted_exp_list)

        self.comboBox_2.addItems(self.formatted_exp_list)
        for row in self.row_dic:
            # print(row,self.row_dic[row])
            self.row_dic[row]['exp'].addItems(self.formatted_exp_list)

        if self.fill_pos == None:
            self.fill_pos = QPushButton('Fill Positions', self)
            self.horizontalLayout.addWidget(self.fill_pos)
            self.fill_pos.clicked.connect(self.fill_positions)

        ib = IB().connect('127.0.0.1', port, clientId=20)
        ib.disconnect()
        ib.waitOnUpdate(timeout=0.1)
        print('disconnected')
        print(ib.isConnected())
コード例 #10
0
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'
コード例 #11
0
    async def asyncioJobGetRecentData(ib: IB,
                                      mydb: database.tradingDB,
                                      qc,
                                      additionalArgs={}):
        """get recent historical data for the contract specified in qc"""
        success = False
        a = (
            f'attempting to get recent historical data chunk: {qc.symbol}, {qc.currency}'
        )
        _logger.info(a)

        if not (isinstance(ib, IB) and ib.isConnected()):
            return success

        conId = qc.conId

        tableORM = utils.getValueFromDataFrame(
            mydb.MarketDataInfoTableDataFrame,
            whereColumn='conId',
            whereValue=conId,
            getColumn='tableORM')

        lastDateTimeOnDiskUTC = getLastDateTimeOnDiskUTC(
            mydb, tableORM.__table__)
        earliestDateTimeUTCAccordingToIB = getEarliestDateTimeUTCFromDataFrame(
            mydb, conId)

        # if there is no earliestDateTime according to IB, it makes no sense to try to retrieve data
        if pd.isnull(earliestDateTimeUTCAccordingToIB):
            success = True
            return (success)

        # duration time delta
        durationMaximumPandasTimeDeltaDefault = pd.Timedelta(weeks=4)
        # bar size delta
        barSizePandasTimeDeltaDefault = pd.Timedelta(minutes=1)

        # override defaults if values have been passed in additionalArgs
        durationMaximumPandasTimeDelta = additionalArgs.get(
            'durationMaximumPandasTimeDelta',
            durationMaximumPandasTimeDeltaDefault)
        barSizePandasTimeDelta = additionalArgs.get(
            'barSizePandasTimeDelta', barSizePandasTimeDeltaDefault)
        timeOutTimeHistoricalBars = additionalArgs.get(
            'timeOutTimeHistoricalBars', 600)

        # we wish to get the most recent historical data
        # the end time is therefore utcnow
        nowUTC = pd.to_datetime(
            pd.datetime.utcnow()).tz_localize('UTC').floor('1 Min')
        endDateTimeUTC = nowUTC

        # the earliest possible start date time is endtime minus the maximum allowed time delta
        earliestStartDateTimeUTC = endDateTimeUTC - durationMaximumPandasTimeDelta

        # by default, the startDateTime is this earliest possible datetime
        startDateTimeUTC = earliestStartDateTimeUTC

        # if we found a lastDateTime on Disk, the startDateTime is modified
        if not pd.isnull(lastDateTimeOnDiskUTC):
            startDateTimeUTC = max(lastDateTimeOnDiskUTC,
                                   earliestStartDateTimeUTC)
            pass

        # for some reason, it is possible that the time on disk is in the future.
        # we therefore determine the startDateTime as the minimum between the startDateTime as calculated before
        # and the endDateTime
        startDateTimeUTC = min(startDateTimeUTC, endDateTimeUTC)

        # we can now calculate the time delta that we actually want to fetch
        durationPandasTimeDelta = endDateTimeUTC - startDateTimeUTC

        # define the objects used to calculate the IB strings for time deltas and bar size settings
        dTD = utils.CTimeDelta(durationPandasTimeDelta)
        bTD = utils.CTimeDelta(barSizePandasTimeDelta)

        # log info about the start of bar data retrieval
        tStart2 = pd.datetime.now()
        if not pd.isnull(earliestDateTimeUTCAccordingToIB):
            a = (
                f'attempting to get recent historical data chunk: {qc.symbol}, {qc.currency}; startDT: {startDateTimeUTC} (durationString: {dTD.IB_Duration_String}); time: {tStart2}'
            )
        else:
            a = (
                f'attempting to get recent historical data chunk: {qc.symbol}, {qc.currency}; not performed because earliestDateTime is not given by IB; time: {tStart2}'
            )
            pass
        _logger.info(a)

        # get the historical data bars
        # only get bars if the last value on disk is not utcnow
        bars = None
        timeOutOccured = None
        if not (nowUTC == lastDateTimeOnDiskUTC):
            [bars, timeOutOccured
             ] = getHistoricalDataBars(ib,
                                       qc,
                                       endDateTime='',
                                       durationStr=dTD.IB_Duration_String,
                                       barSizeSetting=bTD.IB_Bar_Size_String,
                                       timeOutTime=timeOutTimeHistoricalBars)

        if timeOutOccured is not None and timeOutOccured:
            a = (f'Timeout while requesting historical bars for contract {qc}')
            _logger.warn(a)
            pass

        # calculate the number of rows that have been retrieved
        nRows = 0
        if bars is not None:
            nRows = len(bars)
            pass

        # persist result on disk
        # upsert the data
        persistMarketDataBarsOnDisk(bars,
                                    mydb,
                                    tableORM.__table__,
                                    doCorrection=True)

        # calculate the total number of rows on disk
        ssn = mydb.Session()
        nRowsTotal = ssn.query(tableORM.__table__).count()
        ssn.close()

        # log info about the end of bar data retrieval
        tEnd2 = pd.datetime.now()
        tDelta2 = tEnd2 - tStart2
        a = (
            f'finished to get recent historical data chunk: {qc.symbol}, {qc.currency}; startDT: {startDateTimeUTC} (durationString: {dTD.IB_Duration_String}); time: {tEnd2}; elapsedTime: {tDelta2}; rows: {nRows}; rowsTotal: {nRowsTotal}'
        )
        _logger.info(a)
        success = True
        ssn.close()
        return success
コード例 #12
0
class IBDataService:

    ip = "127.0.0.1"
    port = 4002  # 4001 for real trading

    def __init__(self):
        self.uid = random.randint(1000, 10000)
        print(f"init - UID: {str(self.uid)}")
        self.ib = IB()
        self.connect()

    def connect(self, *args):
        print(f"connectToIB - UID: {str(self.uid)}")

        if self.ib.isConnected() is False:
            print("CONNECTING ...")
            self.ib.connect("127.0.0.1", 4002, clientId=self.uid)
            print("CONNECTED")

    def disconnect(self, *args):
        print(f"connectToIB - UID: {str(self.uid)}")

        if self.ib.isConnected():
            print("DISCONNECTING ...")
            self.ib.disconnect()
            print("DISCONNECTED ...")

    def getContractDetail(self, contract):
        print(f"getContractDetail - UID: {str(self.uid)}")
        data = self.ib.reqContractDetails(contract)

        # print(data)

        if len(data) > 0:
            return data[0]
        else:
            return None

    def getFuturesContractDetail(self, contract):
        print(f"getFuturesContractDetail - UID: {str(self.uid)}")
        data = self.ib.reqContractDetails(contract)
        if len(data) > 0:
            return data
        else:
            return None

    def getHistoricalData(self,
                          contract,
                          endDate="",
                          duration="1 Y",
                          barSize="1 day",
                          price="MIDPOINT"):
        print(f"getHistoricalData - UID: {str(self.uid)}")
        data = self.ib.reqHistoricalData(contract, endDate, duration, barSize,
                                         price, 1, 1, False, [])
        return data

    async def startRealtimeData(self, contract, method):
        print(f"startRealtimeData - UID: {str(self.uid)}")

        self.ib.reqMktData(contract, "233", False, False)

        ticker = self.ib.reqTickByTickData(contract, TickDataType.LAST.value)
        ticker.updateEvent += method

        print(f"ENDS - startRealtimeData - UID: {str(self.uid)}")

    def stopRealtimeData(self, contract):
        print(f"stopRealtimeData - UID: {str(self.uid)}")

        self.ib.cancelMktData(contract)
        self.ib.cancelTickByTickData(contract, TickDataType.LAST.value)

        print(f"ENDS - stopRealtimeData - UID: {str(self.uid)}")
コード例 #13
0
ファイル: ib_manager.py プロジェクト: albertadulf/ib_insync
class IbManager(object):
    log_file = 'ib_manager'

    def __init__(self, ip: str, port: int, client_id: int):
        self._ib = IB()
        self._ib_ip: str = ip
        self._ib_port: int = port
        self._client_id: int = client_id
        self._subscribed_mkt_contracts: List[str] = []
        self._subscribed_mkt_depth_contracts: List[str] = []
        self._log: Log = Log.create(Log.path(self.log_file))
        self._logger = self._log.get_logger('ibmanager')
        self._recorder: Recorder = Recorder(self._log)
        self._market_recorder: MarketRecorder = MarketRecorder(
            self._ib, self._recorder)
        self._account_recorder: AccountRecorder = AccountRecorder(
            self._ib, self._recorder)
        self._keep_connection_task: asyncio.Task = None
        self._ib.connectedEvent += self.on_ib_connected
        self._ib.disconnectedEvent += self.on_ib_disconnected
        self._reconnect_flag: bool = False

    def on_ib_connected(self) -> None:
        self._logger.info('connected with ib')
        self._reconnect_flag = False
        self._recover_subscriptions()

    def on_ib_disconnected(self) -> None:
        self._logger.warning('disconnected with ib')
        self._reconnect_flag = True
        if self._keep_connection_task is None:
            self._keep_connection_task = asyncio.create_task(self._reconnect())

    async def _reconnect(self) -> None:
        while self._reconnect_flag:
            await asyncio.sleep(20)
            self._logger.info('try to reconnect ib gateway')
            await self.initialize()
        self._keep_connection_task = None

    def _recover_subscriptions(self) -> None:
        for contract in self._subscribed_mkt_contracts:
            self._logger.info(f'recover subscribe {str(contract)}')
            self._ib.reqMktData(contract)
        for contract in self._subscribed_mkt_depth_contracts:
            self._logger.info(f'recover subscribe depth {str(contract)}')
            self._ib.reqMktDepth(contract)

    async def initialize(self):
        if self._ib.isConnected():
            return
        try:
            await self._ib.connectAsync(self._ib_ip,
                                        self._ib_port,
                                        clientId=self._client_id)
            accounts = self._ib.managedAccounts()
            if len(accounts) > 0:
                self._account_recorder.update_account(accounts[0])
                self.update_account()
        except Exception:
            pass

    def update_account(self):
        self._ib.reqAccountSummaryAsync()

    async def find_symbols(self, pattern: str) -> List[str]:
        symbols = await self._ib.reqMatchingSymbolsAsync(pattern)
        contracts = [symbol.contract.nonDefaults() for symbol in symbols]
        return contracts

    def make_contract(self, **kwargs) -> Contract:
        return Contract.create(**kwargs)

    def sub_market(self, contract: Contract) -> str:
        if contract in self._subscribed_mkt_contracts:
            return 'already subscribe {}'.format(str(contract))
        self._subscribed_mkt_contracts.append(contract)
        self._ib.reqMktData(contract)
        return 'subscribe {} success'.format(str(contract))

    def unsub_market(self, contract: Contract) -> str:
        if contract not in self._subscribed_mkt_contracts:
            return 'not ever subscribe {}'.format(str(contract))
        self._subscribed_mkt_contracts.append(contract)
        self._ib.cancelMktData(contract)
        return 'unsubscribe {} success'.format(str(contract))

    def sub_market_depth(self, contract: Contract) -> str:
        if contract in self._subscribed_mkt_depth_contracts:
            return 'already subscribe depth {}'.format(str(contract))
        self._subscribed_mkt_depth_contracts.append(contract)
        self._ib.reqMktDepth(contract)
        return 'subscribe depth {} success'.format(str(contract))

    def unsub_market_depth(self, contract: Contract) -> str:
        if contract not in self._subscribed_mkt_depth_contracts:
            return 'not ever subscribe depth {}'.format(str(contract))
        self._subscribed_mkt_contracts.remove(contract)
        self._ib.cancelMktDepth(contract)
        return 'unsubscribe depth {} success'.format(str(contract))

    def place_order(self, contract: Contract, side: str, size: int,
                    price: float) -> str:
        trade = self._place_order(contract, side, size, price)
        return str(trade)

    def _place_order(self, contract: Contract, side: str, size: int,
                     price: float) -> Trade:
        side = side.upper()
        if side not in ('SELL', 'BUY'):
            return [f'invalid order type: {side}']
        price = float(f'{round(float(price), 3):.3f}')
        order = LimitOrder(side, size, price, tif='GTC')
        trade = self._ib.placeOrder(contract, order)
        return trade

    def cancel_order(self, order_id: int) -> str:
        order_id = int(order_id)
        order = Order(orderId=order_id)
        trade = self._ib.cancelOrder(order)
        return str(trade)

    async def orders(self) -> List[str]:
        orders = await self._ib.reqOpenOrdersAsync()
        return [str(order) for order in orders]

    def portfolio(self) -> List[str]:
        results = self._ib.portfolio()
        return [str(value) for value in results]
コード例 #14
0
ファイル: data_request.py プロジェクト: aestrad494/kafka
class request(IB):
    def __init__(self, symbol, temp, client):
        self.symbol = symbol
        self.temp = temp
        instruments = pd.read_csv('instruments.csv').set_index('symbol')
        self.params = instruments.loc[self.symbol]
        self.market = str(self.params.market)
        self.exchange = str(self.params.exchange)
        self.tick_size = float(self.params.tick_size)
        self.digits = int(self.params.digits)
        self.leverage = int(self.params.leverage)
        self.client = client
        self.current_date()
        self._sundays_activation()
        self.ib = IB()
        print(self.ib.connect('127.0.0.1', 7497, self.client))
        self.connected = self.ib.isConnected()  #######
        self.get_contract()
        self.interrumption = False
        #self.data = self.download_data(tempo=temp, duration='1 D')
        #self.ib.reqMktData(self.contract, '', False, False); self.ticker = self.ib.ticker(self.contract)  #########
        #self.ticker = self.ib.reqTickByTickData(self.contract, 'Last', 0)
        self.bars = self.ib.reqRealTimeBars(self.contract, 5, 'MIDPOINT',
                                            False)
        self.operable = True

    def operable_schedule(self):
        if self.weekday == 4 and pd.to_datetime(
                self.hour).time() > pd.to_datetime('18:00:00').time():
            print('%s %s | Today is Friday and Market has Closed!' %
                  (self.date, self.hour))
            self.operable = False
        elif self.weekday == 5:
            print('%s %s | Today is Saturday and market is not Opened' %
                  (self.date, self.hour))
            self.operable = False
        else:
            self.operable = True

    def current_date(self):
        self.date = datetime.now().strftime('%Y-%m-%d')
        self.weekday = datetime.now().weekday()
        self.hour = datetime.now().strftime('%H:%M:%S')

    def _sundays_activation(self):
        hour = '18:00:05'
        if self.weekday == 6:
            if pd.to_datetime(self.hour).time() < pd.to_datetime(hour).time():
                print('Today is Sunday. Bot activation is at 18:00:00')
                while True:
                    self.current_date()
                    if pd.to_datetime(
                            self.hour).time() >= pd.to_datetime(hour).time():
                        print('Activation Done')
                        self.send_telegram_message(
                            '%s %s | Bot Activation Done' %
                            (self.date, self.hour))
                        break

    def continuous_check_message(self, message):
        if datetime.now().minute == 0 and datetime.now().second == 0:
            self.send_telegram_message(message, type='info')

    def reconnection(self):
        if self.hour == '23:44:30' or self.hour == '16:59:30':
            self.interrumption = True
            self.ib.disconnect()
            self.connected = self.ib.isConnected()
            print('%s %s | Ib disconnection' % (self.date, self.hour))
            print('Connected: %s' % self.connected)
        if self.hour == '23:46:00' or self.hour == '18:00:05':
            self.interrumption = False
            print('%s %s | Reconnecting...' % (self.date, self.hour))
            while not self.connected:
                try:
                    self.ib.connect('127.0.0.1', 7497, self.client)
                    self.connected = self.ib.isConnected()
                    if self.connected:
                        print('%s %s | Connection reestablished!' %
                              (self.date, self.hour))
                        print('Requesting Market Data...')
                        self.bars = self.ib.reqRealTimeBars(
                            self.contract, 5, 'MIDPOINT', False)
                        print('Last Close of %s: %.2f' %
                              (self.symbol, self.bars[-1].close))
                        print('%s Data has been Updated!' % self.symbol)
                except:
                    print(
                        '%s %s | Connection Failed! Trying to reconnect in 10 seconds...'
                        % (self.date, self.hour))
                    self.ib.sleep(10)
            print('%s %s | %s Data has been Updated!' %
                  (self.date, self.hour, self.symbol))

    def _local_symbol_selection(self):
        '''Selects local symbol according to symbol and current date'''
        current_date = datetime.now().date()
        # csv file selection according to symbol
        if self.symbol in ['ES', 'RTY', 'NQ', 'MES', 'MNQ', 'M2K']:
            contract_dates = pd.read_csv(
                'D:/Archivos/futuro/Algorithmics/Codes/My_Bots/Hermes/contract_dates/indexes_globex.txt',
                parse_dates=True)
        elif self.symbol in ['YM', 'MYM', 'DAX']:
            contract_dates = pd.read_csv(
                'D:/Archivos/futuro/Algorithmics/Codes/My_Bots/Hermes/contract_dates/indexes_ecbot_dtb.txt',
                parse_dates=True)
        elif self.symbol in ['QO', 'MGC']:
            contract_dates = pd.read_csv(
                'D:/Archivos/futuro/Algorithmics/Codes/My_Bots/Hermes/contract_dates/QO_MGC.txt',
                parse_dates=True)
        elif self.symbol in ['CL', 'QM']:
            contract_dates = pd.read_csv(
                'D:/Archivos/futuro/Algorithmics/Codes/My_Bots/Hermes/contract_dates/CL_QM.txt',
                parse_dates=True)
        else:
            contract_dates = pd.read_csv(
                'D:/Archivos/futuro/Algorithmics/Codes/My_Bots/Hermes/contract_dates/%s.txt'
                % symbol,
                parse_dates=True)

        # Current contract selection according to current date
        for i in range(len(contract_dates)):
            initial_date = pd.to_datetime(
                contract_dates.iloc[i].initial_date).date()
            final_date = pd.to_datetime(
                contract_dates.iloc[i].final_date).date()
            if initial_date <= current_date <= final_date:
                current_contract = contract_dates.iloc[i].contract
                break

        # local symbol selection
        local = current_contract
        if self.symbol in [
                'ES', 'RTY', 'NQ', 'MES', 'MNQ', 'M2K', 'QO', 'CL', 'MGC', 'QM'
        ]:
            local = '%s%s' % (self.symbol, current_contract)
        if self.symbol in ['YM', 'ZS']:
            local = '%s   %s' % (self.symbol, current_contract)
        if self.symbol == 'MYM':
            local = '%s  %s' % (self.symbol, current_contract)
        if self.symbol == 'DAX': local = 'FDAX %s' % current_contract

        return local

    def get_contract(self):
        if self.market == 'futures':
            local = self._local_symbol_selection()
            self.contract = Future(symbol=self.symbol,
                                   exchange=self.exchange,
                                   localSymbol=local)
            print(
                self.ib.reqContractDetails(
                    self.contract)[0].contract.lastTradeDateOrContractMonth)
            '''expiration = self.ib.reqContractDetails(Future(self.symbol,self.exchange))[0].contract.lastTradeDateOrContractMonth
            self.contract = Future(symbol=self.symbol, exchange=self.exchange, lastTradeDateOrContractMonth=expiration)'''
        elif self.market == 'forex':
            self.contract = Forex(self.symbol)
        elif self.market == 'stocks':
            self.contract = Stock(symbol=self.symbol,
                                  exchange=self.exchange,
                                  currency='USD')

    def download_data(self, tempo, duration):
        pr = (lambda market: 'MIDPOINT'
              if market == 'forex' else 'TRADES')(self.market)
        historical = self.ib.reqHistoricalData(self.contract,
                                               endDateTime='',
                                               durationStr=duration,
                                               barSizeSetting=tempo,
                                               whatToShow=pr,
                                               useRTH=False,
                                               keepUpToDate=False)
        return historical

    def send_telegram_message(self, message, type='trades'):
        bot_token = '1204313430:AAGonra1LaFhyI1gCVOHsz8yAohJUeFgplo'
        bot_chatID = '-499850995' if type == 'trades' else '-252750334'
        url = 'https://api.telegram.org/bot%s/sendMessage?chat_id=%s&text=%s' % (
            bot_token, bot_chatID, message)

        requests.get(url)
コード例 #15
0
class AsyncIBDataProvider(GenericDataProvider):

    logger = logging.getLogger(__name__)

    def __init__(self,
                 verbose: int,
                 host: str,
                 port: int,
                 timeout: int,
                 chunk_size: int,
                 id=0,
                 tz='America/New_York',
                 **kwargs):
        super(AsyncIBDataProvider, self).__init__(self.logger,
                                                  verbose,
                                                  tz,
                                                  chunk_size=chunk_size,
                                                  **kwargs)
        self.port = port
        self.host = host
        self.timeout = timeout
        self.keep_alive = False
        if 'keep_alive' in kwargs:
            self.keep_alive = kwargs['keep_alive']
        self.ib = IB()
        self.id = id

    def disconnect(self):
        self.ib.disconnect()

    def connect(self):
        if self.id == 0:
            id = int(random.uniform(1, 1000))
        else:
            id = self.id
        self.logger.info(
            f"IBAsync: {self.host}:{self.port}, timeout={self.timeout}, id={id}"
        )
        self.ib.connect(self.host,
                        self.port,
                        clientId=id,
                        timeout=self.timeout,
                        readonly=True)

    def _initialize(self):
        if not self.ib.isConnected():
            self.connect()

    def _finish(self):
        if not self.keep_alive:
            self.disconnect()

    async def _get_data_internal_async(self, symbol_data: SymbolData,
                                       **kwargs) -> pd.DataFrame:
        return self._get_data_internal(symbol_data)

    def _get_data_internal(self, symbol_data: SymbolData) -> pd.DataFrame:
        self.logger.info(f"Getting symbol data: {symbol_data}")

        if symbol_data.timeframe == 'day':
            symbol, bars = self._get_daily(symbol_data.start,
                                           symbol_data.symbol, symbol_data.end)
            symbol = symbol_data.symbol.split('-')[0]
            dataframe = self._to_dataframe(bars)

        elif symbol_data.timeframe == '60min':
            now = f"{(datetime.now()):%Y-%m-%d %H:%M}"
            duration = '365 D'
            if symbol_data.start:
                diff = datetime.strptime(
                    now, '%Y-%m-%d %H:%M') - datetime.strptime(
                        symbol_data.start, '%Y-%m-%d %H:%M')
                if diff.days < 365:
                    duration = f"{diff.days} D"
            symbol, bars = self._get_intraday(symbol_data.symbol, now,
                                              duration, '1 hour',
                                              symbol_data.rth_only)
            symbol = symbol_data.symbol.split('-')[0]
            dataframe = self._to_dataframe(bars, tz_fix=True)

        elif symbol_data.timeframe == '5min':
            now = f"{(datetime.now()):%Y-%m-%d %H:%M}"
            duration = '30 D'
            if symbol_data.start:
                diff = datetime.strptime(
                    now, '%Y-%m-%d %H:%M') - datetime.strptime(
                        symbol_data.start, '%Y-%m-%d %H:%M')
                if diff.days < 30:
                    duration = f"{diff.days} D"

            symbol, bars = self._get_intraday(symbol_data.symbol, now,
                                              duration, '5 mins',
                                              symbol_data.rth_only)
            symbol = symbol_data.symbol.split('-')[0]
            dataframe = self._to_dataframe(bars, tz_fix=True)

        elif symbol_data.timeframe == '15min':
            now = f"{(datetime.now()):%Y-%m-%d %H:%M}"
            duration = '60 D'
            if symbol_data.start:
                diff = datetime.strptime(
                    now, '%Y-%m-%d %H:%M') - datetime.strptime(
                        symbol_data.start, '%Y-%m-%d %H:%M')
                if diff.days < 60:
                    duration = f"{diff.days} D"
            symbol, bars = self._get_intraday(symbol_data.symbol, now,
                                              duration, '15 mins',
                                              symbol_data.rth_only)
            symbol = symbol_data.symbol.split('-')[0]
            dataframe = self._to_dataframe(bars, tz_fix=True)

        else:
            raise Exception(f"{symbol_data.timeframe} not implemented!")

        df = dataframe
        if dataframe.empty:
            self.logger.warning(f"Got empty df for {symbol_data}")
        else:
            df = self._post_process(dataframe, symbol, symbol_data.start,
                                    symbol_data.end, symbol_data.timeframe,
                                    symbol_data.transform)

        return df

    @staticmethod
    def exctract_symbol(ticker: str,
                        type: str = 'STK',
                        exchange: str = 'ARCA',
                        currency: str = 'USD',
                        expire='',
                        multiplier='') -> tuple:
        if ticker.count('-') == 4:
            symbol, type, exchange, currency, multiplier = ticker.split('-')
            if type.isdigit():
                expire = type
                type = "FUT"

        elif ticker.count('-') == 3:
            symbol, type, exchange, currency = ticker.split('-')
            if type.isdigit():
                expire = type
                type = "FUT"

        elif ticker.count('-') == 2:
            if ticker.find('CASH') > -1:
                symbol, currency, exchange = ticker.split('-')
                symbol = symbol.replace('.', '')
                type = 'FX'
            else:
                a, b, c = ticker.split('-')
                if b.isdigit():
                    type = 'FUT'
                    symbol = a
                    exchange = c
                    expire = b
                else:
                    symbol = a
                    exchange = b
                    currency = c

        elif ticker.count('-') == 1:
            symbol, exchange = ticker.split('-')
        else:
            symbol = ticker

        return type, symbol, exchange, currency, expire, multiplier

    @staticmethod
    def parse_contract(ticker):
        """
        Backtrader contract specification (https://www.backtrader.com/docu/live/ib/ib.html):

        TICKER # Stock type and SMART exchange

        TICKER-STK # Stock and SMART exchange

        TICKER-STK-EXCHANGE # Stock

        TICKER-STK-EXCHANGE-CURRENCY # Stock

        TICKER-CFD # CFD and SMART exchange

        TICKER-CFD-EXCHANGE # CFD

        TICKER-CDF-EXCHANGE-CURRENCY # Stock

        TICKER-IND-EXCHANGE # Index

        TICKER-IND-EXCHANGE-CURRENCY # Index

        TICKER-YYYYMM-EXCHANGE # Future

        TICKER-YYYYMM-EXCHANGE-CURRENCY # Future

        TICKER-YYYYMM-EXCHANGE-CURRENCY-MULT # Future

        TICKER-FUT-EXCHANGE-CURRENCY-YYYYMM-MULT # Future

        TICKER-YYYYMM-EXCHANGE-CURRENCY-STRIKE-RIGHT # FOP

        TICKER-YYYYMM-EXCHANGE-CURRENCY-STRIKE-RIGHT-MULT # FOP

        TICKER-FOP-EXCHANGE-CURRENCY-YYYYMM-STRIKE-RIGHT # FOP

        TICKER-FOP-EXCHANGE-CURRENCY-YYYYMM-STRIKE-RIGHT-MULT # FOP

        CUR1.CUR2-CASH-IDEALPRO # Forex

        TICKER-YYYYMMDD-EXCHANGE-CURRENCY-STRIKE-RIGHT # OPT

        TICKER-YYYYMMDD-EXCHANGE-CURRENCY-STRIKE-RIGHT-MULT # OPT

        TICKER-OPT-EXCHANGE-CURRENCY-YYYYMMDD-STRIKE-RIGHT # OPT

        TICKER-OPT-EXCHANGE-CURRENCY-YYYYMMDD-STRIKE-RIGHT-MULT # OPT

        :return: 
        """
        contract_type, symbol, exchange, currency, expire, multiplier = \
            AsyncIBDataProvider.exctract_symbol(ticker)

        if contract_type == 'FX':
            return Forex(pair=symbol)
        if contract_type == 'IND':
            return Index(symbol, exchange, currency)
        if contract_type == 'FUT':
            return Future(symbol,
                          expire,
                          exchange,
                          currency=currency,
                          multiplier=multiplier)
        else:
            return Stock(symbol, exchange, currency)

    def _get_intraday(self, ticker: str, to_date: str, duration: str,
                      barsize: str, rth_only: bool) -> (str, [BarData]):
        to_dt = datetime.strptime(f"{to_date}", '%Y-%m-%d %H:%M')
        contract = AsyncIBDataProvider.parse_contract(ticker)
        whatToShow = 'MIDPOINT' if isinstance(contract,
                                              (Forex, CFD,
                                               Commodity)) else 'TRADES'
        bars = self.ib.reqHistoricalData(contract,
                                         endDateTime=to_dt,
                                         durationStr=duration,
                                         barSizeSetting=barsize,
                                         whatToShow=whatToShow,
                                         useRTH=rth_only,
                                         formatDate=2)
        return contract.symbol, bars

    def _get_daily(self, from_date: str, ticker: str,
                   to_date: str) -> (str, [BarData]):
        #TODO: strip HH:MM from start/end dates?
        from_dt = datetime.strptime(from_date, "%Y-%m-%d")
        today = datetime.strptime(to_date, "%Y-%m-%d")
        to_dt = datetime(today.year, today.month, today.day, 23, 59, 59)
        days = (to_dt - from_dt).days
        if days > 365:
            self.logger.warning(f"Historical data is limited to 365 Days. "
                                f"Only requesting for year '{from_dt.year}'")
            days = 365
            to_dt = datetime(from_dt.year, 12, 31, 23, 59, 59)
        if to_dt > datetime.today():
            to_dt = None

        contract = AsyncIBDataProvider.parse_contract(ticker)
        whatToShow = 'MIDPOINT' if isinstance(contract,
                                              (Forex, CFD,
                                               Commodity)) else 'TRADES'
        # bars = self.ib.reqDailyBars(contract, 2016)
        bars = self.ib.reqHistoricalData(contract,
                                         endDateTime=to_dt,
                                         durationStr=F"{days} D",
                                         barSizeSetting='1 day',
                                         whatToShow=whatToShow,
                                         useRTH=True,
                                         formatDate=1)
        return contract.symbol, bars

    def _to_dataframe(self, bars, tz_fix=False):
        if tz_fix:
            data = [{
                'Date':
                pd.to_datetime(
                    b.date.astimezone(self.tz).replace(tzinfo=None)),
                'Open':
                b.open,
                'High':
                b.high,
                'Low':
                b.low,
                'Close':
                b.close,
                'Volume':
                b.volume
            } for b in bars]
        else:
            data = [{
                'Date': pd.to_datetime(b.date),
                'Open': b.open,
                'High': b.high,
                'Low': b.low,
                'Close': b.close,
                'Volume': b.volume
            } for b in bars]

        if len(data) > 0:
            return pd.DataFrame(data).set_index('Date')
        else:
            return pd.DataFrame()

    def add_quotes(self, data, ticker):
        return data
コード例 #16
0
ファイル: is_ibgw_running.py プロジェクト: kvokka/docker-ibgw
import os
import sys
import time
import logging
import json
import base64
from ib_insync import ibcontroller
from ib_insync import IB
from ib_insync.ibcontroller import Watchdog
import ib_insync.util as util
from updateConfig import updateIbcConfig, updateTwsConfig

util.logToConsole(logging.DEBUG)
logger = logging.getLogger(name=__name__)
twsPort = os.getenv("TWS_PORT", "4001")

if __name__ == "__main__":

    ib = IB()

    ib.connect('127.0.0.1', twsPort, clientId=10)
    time.sleep(5)

    if not ib.isConnected():
        logging.debug('HEALTHCHECK: ib is not connected')
        sys.exit(1)
    else:
        logging.debug('HEALTHCHECK: ib is connected')
        sys.exit(0)
コード例 #17
0
class Window(qt.QWidget):
    def __init__(self, host, port, clientId):
        qt.QWidget.__init__(self)
        self.setWindowTitle("Giulio's App")
        self.canvas = MplCanvas()
        # self.edit = qt.QLineEdit('', self)
        # self.edit.editingFinished.connect(self.add)
        self.table = HistoricalTable()
        self.MAList = []
        self.MADict = {}

        self.connectButton = qt.QPushButton('Connect')
        self.connectButton.setStyleSheet(
            "border: 1px solid black; background: white")
        self.connectButton.resize(100, 32)
        self.connectButton.setGeometry(200, 150, 100, 40)
        self.connectButton.clicked.connect(self.onConnectButtonClicked)
        self.displayButton = qt.QPushButton('Display values')
        self.displayButton.setStyleSheet(
            "border: 1px solid black; background: white")
        self.displayButton.resize(100, 32)
        self.displayButton.clicked.connect(self.onDisplayButtonClicked)
        self.cancelAllButton = qt.QPushButton('CancelAll')
        self.cancelAllButton.setStyleSheet(
            "border: 1px solid black; background: white")
        self.cancelAllButton.resize(100, 32)
        self.cancelAllButton.setGeometry(200, 150, 100, 40)
        self.cancelAllButton.clicked.connect(self.onCancelAllButtonClicked)

        layout = qt.QVBoxLayout(self)
        # layout.addWidget(self.edit)
        layout.addWidget(self.table)
        #layout.addWidget(self.canvas)
        layout.addWidget(self.connectButton)
        layout.addWidget(self.cancelAllButton)
        # layout.addStretch(1)
        # self.fig = plt.figure()
        # self.ax = self.fig.add_subplot(1, 1, 1)
        self.xs = []
        self.ys = []
        # layout.addWidget(self.fig)
        self.connectInfo = (host, port, clientId)
        self.ib = IB()
        self.headers = [
            'symbol', 'bidSize', 'bid', 'ask', 'askSize', 'last', 'lastSize',
            'close'
        ]
        self.id = 1
        self.firstSignal = True
        self.isConnectionBroken = False
        self.firstma50 = 0
        self.firstma200 = 0
        self.availableCash = 0
        self.ib.orderStatusEvent += self.order_status_cb
        self.ib.execDetailsEvent += self.exec_details_cb
        self.ib.errorEvent += self.error_cb
        self.ib.accountSummaryEvent += self.accountSummary
        self.ib.pendingTickersEvent += self.onPendingTickers

        # self.ib.pendingTickersEvent += self.table.onPendingTickers

    async def accountSummaryAsync(self, account: str = '') -> \
            List[AccountValue]:
        if not self.wrapper.acctSummary:
            # loaded on demand since it takes ca. 250 ms
            await self.reqAccountSummaryAsync()
        if account:
            return [
                v for v in self.wrapper.acctSummary.values()
                if v.account == account
            ]
        else:
            return list(self.wrapper.acctSummary.values())

    def accountSummary(self, account: str = '') -> List[AccountValue]:
        if (account.tag == 'BuyingPower'):
            logging.info('account buying power - ' + account.value)
            accVal: float = 0.0
            accVal = account.value
            self.availableCash = float(accVal)
            self.availableCash = round(self.availableCash, 2)
            logging.info('available cash - ' + str(self.availableCash))
        logging.info("account summary:: " + str(account.account) + " " +
                     account.tag + " " + account.value)

        return []  #self._run(self.accountSummaryAsync(account))

    def error_cb(self, reqId, errorCode, errorString, contract):
        logging.error("error: " + str(reqId) + " , " + str(errorCode) + " , " +
                      str(errorString))
        logging.error("string - " + str(errorString))
        """if(errorCode == 1100):
            logging.error("Connectivity between IB and TWS has been lost")
            self.isConnectionBroken = True
        if (errorCode == 1300):
            logging.error("socket connection dropped")
            self.isConnectionBroken = True
        if(errorCode == 2105):
            logging.error("HMDS data farm connection is broken")
        if ((errorCode == 2104 or errorCode == 2106) and self.isConnectionBroken == True):
            logging.info("HMDS data farm connection has been restored")
            self.reqData()"""

    def reqGlobalCancel(self):
        """
        Cancel all active trades including those placed by other
        clients or TWS/IB gateway.
        """
        self.ib.reqGlobalCancel()
        logging.info('reqGlobalCancel')

    def order_status_cb(self, trade):
        logging.info("order status for " + str(trade.order.orderId))
        logging.info("Status filled and remaining - " +
                     trade.orderStatus.status + " " +
                     str(trade.orderStatus.filled) + " " +
                     str(trade.orderStatus.remaining))

    def exec_details_cb(self, trade, fill):
        logging.info("exec details for " + fill.contract.symbol +
                     " with orderid " + str(fill.execution.orderId))
        if (fill.execution.side == "Sell"):
            self.availableCash += fill.execution.price

    def onPendingTickers(self, tickers):
        for ticker in tickers:
            logging.info("ticker - " + str(ticker.contract.conId) + " " +
                         str(ticker.contract.secType) + " " +
                         ticker.contract.symbol + " " +
                         ticker.contract.currency)
            for col, header in enumerate(self.headers):
                if col == 0:
                    continue
                val = getattr(ticker, header)
                symbol = ticker.contract.symbol + (ticker.contract.currency
                                                   if ticker.contract.secType
                                                   == 'CASH' else '')
                ma = self.MADict[symbol]
                logging.info("Values - " + str(ticker.contract.secType) + " " +
                             str(ticker.contract.conId) + " " + symbol + " " +
                             str(header) + " " + str(col) + " val- " +
                             str(val))
                if (str(header) == 'bid'):
                    ma.bid = val
                if (str(header) == 'ask'):
                    ma.ask = val

    def onBarUpdate(self, bars, hasNewBar):
        self.xs.append(dt.datetime.now().strftime('%H:%M:%S.%f'))
        # logging.debug("bar update " + str(hasNewBar) + " for " + str(bars.reqId))
        logging.info(bars[-1])
        symbol = bars.contract.symbol + (
            bars.contract.currency if bars.contract.secType == 'CASH' else '')
        ma = self.MADict[symbol]
        logging.info("update for " + ma.symbol)
        df = util.df(bars)
        # logging.debug(df)
        ma.setMAs(df)
        ma50 = ta.MA(df['close'], 50)
        ma200 = ta.MA(df['close'], 200)
        self.ys.append(ma50)

        self.xs = self.xs[-50:]
        self.ys = self.ys[-50:]

        # self.ax.clear()
        # self.ax.plot(self.xs, self.ys)
        plt.xticks(rotation=45, ha='right')
        plt.subplots_adjust(bottom=0.30)
        plt.title('50MA')
        plt.ylabel('MA')
        """logging.debug("ma50")
        logging.debug(ma50)
        logging.debug("ma200")
        logging.debug(ma200)
        logging.debug("last items")
        logging.debug(ma50.tail(1).item())
        logging.debug(ma200.tail(1).item())"""
        orderList = ma.checkGCDC()
        if (orderList is not None):
            orderQuantity = 0
            for order in orderList:
                if (order.orderType == "LMT"):
                    if (order.action == "Buy"):
                        order.totalQuantity = 1000  #(self.availableCash/ma.bid) * .01
                        self.availableCash -= (order.totalQuantity *
                                               order.trailStopPrice)
                        logging.info("Placing buy order for " + ma.symbol +
                                     " " + str(ma.bid) + " with orderId " +
                                     str(order.orderId))
                    else:
                        order.totalQuantity = 1000  #(self.availableCash/ma.ask) * .01
                        logging.info("Placing sell order for " + ma.symbol +
                                     " at " + str(ma.ask) + " with orderId " +
                                     str(order.orderId))
                    orderQuantity = order.totalQuantity
                else:
                    if (order.orderType == "TRAIL"):
                        order.totalQuantity = orderQuantity
                        if (order.action == "Buy"):
                            #order.totalQuantity = (self.availableCash / ma.bid) * .01
                            self.availableCash -= (order.totalQuantity *
                                                   order.trailStopPrice)
                            logging.info("Placing buy order for " + ma.symbol +
                                         " " + str(ma.bid) + " with orderId " +
                                         str(order.orderId))
                        else:
                            #order.totalQuantity = (self.availableCash / ma.ask) * .01
                            logging.info("Placing sell order for " +
                                         ma.symbol + " at " + str(ma.ask) +
                                         " with orderId " + str(order.orderId))

                        logging.info("Placing " + order.action +
                                     " order for " + ma.symbol + " at " +
                                     str(order.trailStopPrice) + " " +
                                     str(ma.ask) + " with orderId " +
                                     str(order.orderId) + " " +
                                     str(trade.order.orderId))
                trade = self.ib.placeOrder(bars.contract, order)

        if (ma.isOrderActive == False and ma.GCCheck == True):
            logging.info("order is not active and gccheck is true")
        self.MADict[symbol] = ma
        """if (ma.firstSignal == True):
            ma.firstma50 = round(ma50.tail(1).item(), 6)
            ma.firstma200 = round(ma200.tail(1).item(), 6)
            ma.firstSignal = False
            if (ma.firstma50 < ma.firstma200):
                logging.info("checking golden cross for " + ma.symbol + " : mas - " + str(ma.firstma50) + " " + str(ma.firstma200))
            else:
                logging.info("checking death cross for " + ma.symbol + " : mas - " + str(ma.firstma50) + " " + str(ma.firstma200))
                ma.GCCheck = False
                self.MADict[symbol] = ma
        else:
            prevma50 = ma.getMa50()
            prevma200 = ma.getMa200()
            currma50 = round(ma50.tail(1).item(), 6)
            currma200 = round(ma200.tail(1).item(), 6)
            if(ma.isOrderActive == False):
                if(ma.GCCheck == True):
                    logging.info("golden cross check for " + ma.symbol)
                    logging.info("prev mas - " + str(prevma50) + " " + str(prevma200))
                    logging.info("curr mas - " + str(currma50) + " " + str(currma200))
                    logging.info("curr bid and ask vals - " + str(ma.bid) + " " + str(ma.ask))
                    if((prevma50 <= prevma200) and (currma50 > currma200)):
                        logging.info(("golden cross occured for " + ma.symbol))
                        ma.GCCheck = False
                        if(ma.isOrderActive == False):
                            ma.isOrderActive = True
                            order = TrailOrder("Buy", 1000, ma.ask, 20)
                            trade = self.ib.placeOrder(bars.contract, order)
                            logging.info("Placing buy order for " + ma.symbol + " at " + str(order.trailStopPrice) + " " + str(ma.ask) + " with orderId " + str(order.orderId) + " " + str(trade.order.orderId))
                        self.MADict[symbol] = ma

                else:
                    logging.info("death cross check for " + ma.symbol)
                    logging.info("prev mas - " + str(prevma50) + " " + str(prevma200))
                    logging.info("curr mas - " + str(currma50) + " " + str(currma200))
                    if ((prevma50 >= prevma200) and (currma50 < currma200)):
                        logging.info(("death cross occured for " + ma.symbol))
                        ma.GCCheck = True
                        if (ma.isOrderActive == False):
                            ma.isOrderActive = True
                            order = TrailOrder("Sell", 1000, ma.bid, 20)
                            trade = self.ib.placeOrder(bars.contract, order)
                            logging.info("Placing sell order for " + ma.symbol + " at " + str(ma.bid) + " with orderId " + str(trade.order.orderId))
                        self.MADict[symbol] = ma """

        ma.setMa50(round(ma50.tail(1).item(), 6))
        ma.setMa200(round(ma200.tail(1).item(), 6))
        self.MADict[symbol] = ma

        logging.debug("MAs for " + str(bars.contract.secType) + " " +
                      str(bars.contract.symbol) + " " +
                      bars.contract.currency + " , reqid: " + str(bars.reqId) +
                      " " + str(ma50.values[-1]) + " " +
                      str(ma200.values[-1]) + " : " +
                      str(ma50.tail(1).item()) + " " +
                      str(ma200.tail(1).item()))
        self.table.updateData(bars.reqId, round(ma50.tail(1).item(), 6),
                              round(ma200.tail(1).item(), 6))
        # logging.debug(ma50.values[-1])
        # plt.close()
        # plot = util.barplot(bars)
        # clear_output(wait=True)
        # display(plot)

    def add_historical(self, text=''):
        logging.debug("text - " + text)
        logger.debug("logging")
        text = text or self.edit.text()
        if text:
            logging.debug('eval text ')  # + eval(text))
            contract = eval(text)
            logging.debug("requesting historical and mkt data for " + text)
            bars = self.ib.reqHistoricalData(contract,
                                             endDateTime='',
                                             durationStr='2000 S',
                                             barSizeSetting='10 secs',
                                             whatToShow='MIDPOINT',
                                             useRTH=True,
                                             formatDate=1,
                                             keepUpToDate=True)
            ticker = self.ib.reqMktData(contract, '', False, False, None)
            logging.info(bars[-1])
            logging.debug("sectype " + str(bars.reqId) + " " +
                          str(bars.contract.conId) + " " +
                          bars.contract.secType + " " + bars.contract.symbol +
                          " " + bars.contract.currency)
            self.table.addHistoricalData(bars.reqId, contract)
            df = util.df(bars)
            # with pd.option_context('display.max_rows', None, 'display.max_columns',
            #                       None):  # more options can be specified also
            #    logging.debug(df)
            close = pd.DataFrame(df, columns=['close'])
            logging.debug("close ")
            logging.debug(close)
            # df['pandas_SMA_3'] = df.iloc[:, 1].rolling(window=3).mean()
            # df.head()

            #ma50 = ta.MA(df['close'], 50)
            #ma200 = ta.MA(df['close'], 200)
            symbol = bars.contract.symbol + (bars.contract.currency
                                             if bars.contract.secType == 'CASH'
                                             else '')
            logging.info("symbol - " + symbol)
            ma = MovingAverages(
                self.ib, symbol, bars.reqId
            )  #, round(ma50.tail(1).item(), 6), round(ma200.tail(1).item(), 6))
            ma.setMAs(df)
            self.MAList.append(ma)
            self.MADict[symbol] = ma
            """logging.debug("ma50")
            logging.debug(ma50)
            logging.debug("ma200")
            logging.debug(ma200)
            logging.debug("initial ma vals for " + symbol)
            logging.debug(ma50.tail(1).item())
            logging.debug(ma200.tail(1).item())"""
            self.table.updateData(bars.reqId, round(ma.ma50.tail(1).item(), 6),
                                  round(ma.ma200.tail(1).item(), 6))
            # sma = pd.SMA(df['close'].values, timeperiod=4)
            """portfolio = self.ib.portfolio()#.wrapper.portfolio.cash = 10000
            logging.debug("portfolio")
            logging.debug(portfolio)
            positions = self.ib.positions()
            logging.debug("positions")
            for x in range(len(positions)):
                logging.debug(positions[x].contract.symbol)
                logging.debug(positions[x].position)"""
            # logging.debug(positions)
            bars.updateEvent += self.onBarUpdate
            logging.debug("reqid is " + str(bars.reqId) + " for " +
                          bars.contract.symbol + " " + bars.contract.currency +
                          " , sectype - " + bars.contract.secType)

    def onDisplayButtonClicked(self, _):
        logging.debug("MA values")
        for ma in self.MAList:
            logging.debug("symbol - " + " " + ma.symbol)
            logging.debug(
                str(ma.firstma50) + " " + str(ma.firstma200) + " " +
                str(ma.firstSignal) + " " + str(ma.ma50) + " " + str(ma.ma200))
        for x in self.MADict:
            logging.debug(x)
        for x in self.MADict.values():
            logging.debug("dict values - " + str(x.firstSignal) + " " +
                          x.symbol + " " + str(x.firstma50) + " " +
                          str(x.firstma200) + " " + str(x.ma50) + " " +
                          str(x.ma200))

    def onConnectButtonClicked(self, _):
        logging.debug("isconnected: " + str(self.ib.isConnected()))
        if self.ib.isConnected():
            self.ib.disconnect()
            logging.debug("clearing data")
            self.table.clearData()
            self.connectButton.setText('Connect')
            logging.debug("done")
        else:
            logging.debug("trying to connect")
            # ib = IB()
            # ib.connect('127.0.0.1', 7497, clientId=3)
            self.ib.connect('127.0.0.1', 7497,
                            clientId=2)  # *self.connectInfo)
            logging.debug("connected - ")  # + self.ib.isConnected())
            # self.ib.reqMarketDataType(2)
            self.connectButton.setText('Disconnect')
            self.ib.reqAccountSummary()
            self.reqData()

    def onCancelAllButtonClicked(self):
        logging.info("Cancelling all open orders")
        #self.ib.connect('127.0.0.1', 7497, clientId=2)  # *self.connectInfo)
        self.reqGlobalCancel()

    def reqData(self):
        #self.reqGlobalCancel()
        """for symbol in ('EURUSD', 'USDJPY', 'EURGBP', 'USDCAD',
                       'EURCHF', 'AUDUSD', 'NZDUSD'):
            logging.debug("requesting for " + symbol)
            self.add_historical(f"Forex('{symbol}')")"""
        #self.add_historical("Stock('TSLA', 'SMART', 'USD')")
        #self.add_historical("Stock('IBM', 'SMART', 'USD')")
        #self.add_historical("Stock('MSFT', 'SMART', 'USD')")
        self.add_historical("Stock('FB', 'SMART', 'USD')")

    def closeEvent(self, ev):
        logging.debug("closing")
        asyncio.get_event_loop().stop()