def get_valid_spy_contract(idx) -> OptionContract:
    from ib_insync import IB, Stock

    ib = IB()
    ib.connect(clientId=idx + 1)
    ib_stk_con = Stock(symbol="SPY", exchange="SMART", currency="USD")
    ib_details = ib.reqContractDetails(ib_stk_con)[0]
    ib.reqMarketDataType(4)
    tick = ib.reqMktData(contract=ib_stk_con, snapshot=True)
    while np.isnan(tick.ask):
        ib.sleep()
    ask = tick.ask
    ib_con_id = ib_details.contract.conId
    ib_chains = ib.reqSecDefOptParams(
        underlyingSymbol="SPY",
        futFopExchange="",
        underlyingSecType="STK",
        underlyingConId=ib_con_id,
    )
    ib_chain = ib_chains[0]
    ib_chain.strikes.sort(key=lambda s: abs(s - ask))
    strike = ib_chain.strikes[0]
    expiration_str = ib_chain.expirations[idx]
    expiration_date = datetime.strptime(expiration_str, "%Y%m%d")
    spy_contract = OptionContract(
        symbol="SPY",
        strike=strike,
        right=Right.CALL,
        multiplier=int(ib_chain.multiplier),
        last_trade_date=expiration_date,
    )
    ib.disconnect()

    return spy_contract
Esempio n. 2
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()
Esempio n. 3
0
]
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:
        encodedTick = json.dumps(util.tree(t))
        ticks.append({"Data": encodedTick})
    firehose.put_record_batch(DeliveryStreamName=firehoseStream, Records=ticks)


ib.pendingTickersEvent += onPendingTickers

IB.run()
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'
Esempio n. 5
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)}")
Esempio n. 6
0
    lista2.append(contract.conId)
    lista2.append(contract.localSymbol)
    lista2.append(contract.lastTradeDateOrContractMonth)
    lista1.append(lista2)

lista1.sort(key=lambda x: x[2])
futuros2 = lista1[:primerosN]
'''MEJORAR: Estoy dando por supuesto que los N primeros de las dos listas corresponden a los mismos meses'''
'''Esto no será siempre cierto, hay que mejorar este proceso para que tenga en cuenta los meses'''

df = pd.DataFrame(columns=('MES', 'CL', 'BZ', 'DIFF1', 'DIFF2', 'DIF'))
midF1ant = 0
midF2ant = 0
for i in range(0, len(futuros1)):
    contract = Future(localSymbol=futuros1[i][1], exchange=exchange1)
    ticker = ib.reqMktData(contract)
    ib.sleep(2)
    ib.cancelMktData(contract)
    midF1 = round((ticker.bid + ticker.ask) / 2, 3)
    if i == 0:
        difF1 = 0
    else:
        difF1 = midF1 - midF1ant
    midF1ant = midF1

    contract = Future(localSymbol=futuros2[i][1], exchange=exchange2)
    ticker = ib.reqMktData(contract)
    ib.sleep(2)
    ib.cancelMktData(contract)
    midF2 = round((ticker.bid + ticker.ask) / 2, 3)
    if i == 0:
Esempio n. 7
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)
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()
Esempio n. 9
0
def runProg(args):
    """run program"""

    util.patchAsyncio()

    # log to a file
    utils.logToFile(f'getRecentHistoricalData.log')
    # utils.logToConsole()

    apschedulerLogger = logging.getLogger('apscheduler')
    apschedulerLogger.setLevel(logging.ERROR)
    tradingLogger = logging.getLogger('trading')
    tradingLogger.setLevel(logging.WARNING)

    pd.set_option('display.width', 200)

    # load the config file
    configFile = args.configFile
    config = ConfigParser(interpolation=ExtendedInterpolation(),
                          defaults=os.environ)
    config.read(configFile)

    # load data from configFile
    host = config.get('InteractiveBrokers', 'host')
    port = config.getint('InteractiveBrokers', 'port')
    DBType = config.get('DataBase', 'DBType')
    DBFileName = config.get('DataBase', 'DBFileName')
    clientId = config.get('InteractiveBrokers', 'clientId')

    # for production mode: watchdog
    if 1:
        # start watchdog
        # ibc = IBC(963, gateway=True, tradingMode='paper',ibcIni='/home/bn/IBController/configPaper.ini')
        ibcIni = config.get('InteractiveBrokers', 'ibcIni')
        tradingMode = config.get('InteractiveBrokers', 'tradingMode')
        ibc = IBC(970, gateway=True, tradingMode=tradingMode, ibcIni=ibcIni)
        myWatchdogapp = myWatchdog.myWatchdog(ibc,
                                              appStartupTime=15,
                                              port=4002)
        myWatchdogapp.start()
        ib = myWatchdogapp.ib
        pass

    if 0:
        # faster way for now
        ib = IB()
        ib.connect(host=host, port=port, clientId=clientId)
        pass

    pass

    # create database class
    mydb = database.tradingDB(DBType=DBType, DBFileName=DBFileName)
    # load existing database
    mydb.instantiateExistingTablesAndClasses(ib=ib)
    # set log level of sqlalchemy
    mydb._loggerSQLAlchemy.setLevel(logging.WARNING)

    qcs = mydb.MarketDataInfoTableDataFrame.qualifiedContract
    for qc in qcs:
        print(qc, type(qc))
        ib.reqMktData(contract=qc,
                      genericTickList='',
                      snapshot=False,
                      regulatorySnapshot=False,
                      mktDataOptions=None)

        pass

    df = pd.DataFrame(
        columns='symbol bidSize bid ask askSize high low close'.split())
    df['symbol'] = [qc.localSymbol for qc in qcs]
    contract2Row = {qc: i for (i, qc) in enumerate(qcs)}
    pprint.pprint(contract2Row)

    def onPendingTickers(tickers):
        for t in tickers:
            iRow = contract2Row[t.contract]
            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)

    #         df.iloc[iRow, 1:] = (t.bidSize, t.bid, t.ask, t.askSize, t.high, t.low, t.close)
    #     print(df)

    ib.setCallback('pendingTickers', onPendingTickers)

    # ib.sleep(300)

    if 1:
        util.allowCtrlC()
        # Execution will block here until Ctrl+C (Ctrl+Break on Windows) is pressed.
        try:
            asyncio.get_event_loop().run_forever()
        except (KeyboardInterrupt, SystemExit):
            pass
Esempio n. 10
0
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]
Esempio n. 11
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()