Exemplo n.º 1
0
    def process_ibkr_cycle(self):
        self.ibkrworker = IBKRWorker(self.settings)
        self.ibkrworker.stocks_data_from_server = self.stocks_data_from_server
        self.ibkrworker.positions_open_on_server = self.positions_open_on_server
        successfull_cycle = self.ibkrworker.run_full_cycle()
        if not successfull_cycle:
            restart_tws_and_trader()
        print("Worker finished reporting to the server........")

        self.report_to_server()
Exemplo n.º 2
0
    def __init__(self, settings):
        # mandatory
        QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.trading_session_state = "TBD"
        self.est = timezone('US/Eastern')
        self.settingsWindow = SettingsWindow()
        self.setupUi(self)
        self.settings = settings
        self.ibkrworker = IBKRWorker(self.settings)
        self.threadpool = QThreadPool()
        self.setWindowTitle("Algo Traider v 2.0")

        sys.stderr = open('LOG/errorLog.txt', 'w')

        self.create_open_positions_grid()

        # setting a timer for Worker

        self.uiTimer = QTimer()
        self.uiTimer.timeout.connect(self.update_ui)

        self.workerTimer = QTimer()
        self.workerTimer.timeout.connect(self.run_worker)

        self.server_timer = QTimer()
        self.server_timer.timeout.connect(self.report_to_server)
        self.server_timer.start(int(self.settings.INTERVALSERVER) * 1000)

        # connecting a buttons
        self.chbxProcess.stateChanged.connect(self.process_checked)
        self.btnSettings.pressed.connect(self.show_settings)

        self.statusbar.showMessage("Ready")

        stock_names = [o.ticker for o in self.settings.CANDIDATES]
        self.ibkrworker.stocks_data_from_server = get_market_data_from_server(
            self.settings, stock_names)
        self.update_console("Market data for " + str(len(stock_names)) +
                            " Candidates received from Server")
        self.start_updating_candidates_and_connect()

        StyleSheet = '''
        #lcdPNLgreen {
            border: 3px solid green;
        }
        #lcdPNLred {
            border: 3px solid red;
        }
        '''
        self.setStyleSheet(StyleSheet)
Exemplo n.º 3
0
    def __init__(self, settings):
        # mandatory
        QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.settingsWindow = SettingsWindow()
        self.setupUi(self)
        self.settings = settings
        self.ibkrworker = IBKRWorker(self.settings)
        self.threadpool = QThreadPool()
        self.setWindowTitle("Algo Traider v 2.0")

        sys.stderr = open('LOG/errorLog.txt', 'w')

        self.create_open_positions_grid()

        # # redirecting Cosole to UI and Log
        # sys.stdout = OutLog(self.consoleOut, sys.stdout)
        # sys.stderr = OutLog(self.consoleOut, sys.stderr)

        # setting a timer for Worker

        self.uiTimer = QTimer()
        self.uiTimer.timeout.connect(self.update_ui)

        self.workerTimer = QTimer()
        self.workerTimer.timeout.connect(self.run_worker)

        # connecting a buttons
        self.chbxProcess.stateChanged.connect(self.process_checked)
        self.btnSettings.pressed.connect(self.show_settings)

        self.statusbar.showMessage("Ready")
        # self.update_session_state()

        # self.connect_to_ibkr()

        if not self.settings.UIDEBUG:
            self.connect_to_ibkr()
        else:
            self.btnSettings.setEnabled(True)

        StyleSheet = '''
        #lcdPNLgreen {
            border: 3px solid green;
        }
        #lcdPNLred {
            border: 3px solid red;
        }
        '''
        self.setStyleSheet(StyleSheet)
Exemplo n.º 4
0
    def restart_all(self):
        """
Restarts everything after Save
        """
        self.threadpool.waitForDone()
        self.update_console("UI paused- for restart")
        self.uiTimer.stop()

        self.workerTimer.stop()
        self.update_console("Configuration changed - restarting everything")
        self.chbxProcess.setEnabled(False)
        self.chbxProcess.setChecked(False)
        self.btnSettings.setEnabled(False)
        self.ibkrworker.app.disconnect()
        while self.ibkrworker.app.isConnected():
            print("waiting for disconnect")
            time.sleep(1)

        self.ibkrworker = None
        self.ibkrworker = IBKRWorker(self.settings)
        self.connect_to_ibkr()

        i = 4
Exemplo n.º 5
0
 def process_close_all_cycle(self):
     self.ibkrworker = IBKRWorker(self.settings)
     self.ibkrworker.close_all_positions_cycle()
     print("Worker finished reporting to the server........")
Exemplo n.º 6
0
class Algotrader:
    def __init__(self):
        self.trading_session_state = "TBD"
        self.trading_time_zone = timezone('US/Eastern')

        self.settings = None
        self.stocks_data_from_server = None
        self.positions_open_on_server = None
        self.started_time = datetime.now()

    def get_settings(self):
        print('Connecting to server - to get settings.')
        self.settings = None
        try:
            self.settings = TraderSettings()
        except Exception as e:
            if hasattr(e, 'message'):
                print("Error in getting Settings: " + str(e.message))

            else:
                print("Error in getting Settings: " + str(e))
        print('Settings received.')
        if self.settings is not None:
            return True
        else:
            return False

    def start_processing(self):
        self.process_worker()
        threading.Timer(self.settings.INTERVALSERVER,
                        self.start_processing).start()

    def process_worker(self):
        print("Requesting Command from server......")

        result = self.get_settings()  # to not fall on server restarts
        while result == False:
            time.sleep(10)
            result = self.get_settings()
        if self.settings is not None:
            server_command = get_command_from_server(self.settings)
            self.process_server_command_response(server_command)

    def process_server_command_response(self, r):
        response = json.loads(r)
        self.stocks_data_from_server = response['candidates']
        self.positions_open_on_server = response['open_positions']
        self.settings.MARKETEMOTION = int(response['market_emotion'])
        command = response['command']
        print('Received command : ' + command)

        if command == 'restart_worker':
            print(
                'Restart command received- doing restart for Algotrader and TWS'
            )

            restart_tws_and_trader()
        elif command == 'close_all_positions':
            print("Closing all open positions")

            self.process_close_all_cycle()
            self.get_settings()  # to refresh a settings and cancell a BUY
        else:
            self.process_ibkr_cycle()

    def process_close_all_cycle(self):
        self.ibkrworker = IBKRWorker(self.settings)
        self.ibkrworker.close_all_positions_cycle()
        print("Worker finished reporting to the server........")

    def process_ibkr_cycle(self):
        self.ibkrworker = IBKRWorker(self.settings)
        self.ibkrworker.stocks_data_from_server = self.stocks_data_from_server
        self.ibkrworker.positions_open_on_server = self.positions_open_on_server
        successfull_cycle = self.ibkrworker.run_full_cycle()
        if not successfull_cycle:
            restart_tws_and_trader()
        print("Worker finished reporting to the server........")

        self.report_to_server()

    def report_to_server(self):
        net_liquidation = self.ibkrworker.app.netLiquidation
        if hasattr(self.ibkrworker.app, 'smaWithSafety'):
            remaining_sma_with_safety = self.ibkrworker.app.smaWithSafety
        else:
            remaining_sma_with_safety = self.ibkrworker.app.sMa
        excess_liquidity = self.ibkrworker.app.excessLiquidity
        remaining_trades = self.ibkrworker.app.tradesRemaining
        all_positions_value = 0
        open_positions = self.ibkrworker.app.openPositions
        open_orders = self.ibkrworker.app.openOrders
        candidates_live = self.ibkrworker.app.candidatesLive
        dailyPnl = self.ibkrworker.app.dailyPnl
        tradinng_session_state = self.ibkrworker.trading_session_state
        worker_last_execution = self.ibkrworker.last_worker_execution_time
        api_connected = self.ibkrworker.api_connected
        market_data_error = self.ibkrworker.app.market_data_error
        data_for_report = [
            self.settings, net_liquidation, remaining_sma_with_safety,
            remaining_trades, all_positions_value, open_positions, open_orders,
            candidates_live, dailyPnl, worker_last_execution,
            datetime.now(self.trading_time_zone), tradinng_session_state,
            excess_liquidity, self.started_time, api_connected,
            market_data_error, client_version
        ]
        report_snapshot_to_server(self.settings, data_for_report)
        self.ibkrworker.app.disconnect()

    def start_tws(self, settings):
        tws_running = checkIfProcessRunning('JavaApplicationStub')
        user = str(os.environ._data)
        if 'colakamornik' not in user and 'lilia' not in user:
            print('Starting TWS configured in INI file')
            cmd = settings.TWSSTARTCOMMAND
            os.system(cmd)
            while not checkIfProcessRunning('pxgsettings'):
                print('Waiting for login Screen')
                time.sleep(1)
            print("TWS process found starting login")
            login_tws_user(settings)
Exemplo n.º 7
0
class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, settings):
        # mandatory
        QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.trading_session_state = "TBD"
        self.est = timezone('US/Eastern')
        self.settingsWindow = SettingsWindow()
        self.setupUi(self)
        self.settings = settings
        self.ibkrworker = IBKRWorker(self.settings)
        self.threadpool = QThreadPool()
        self.setWindowTitle("Algo Traider v 2.0")

        sys.stderr = open('LOG/errorLog.txt', 'w')

        self.create_open_positions_grid()

        # setting a timer for Worker

        self.uiTimer = QTimer()
        self.uiTimer.timeout.connect(self.update_ui)

        self.workerTimer = QTimer()
        self.workerTimer.timeout.connect(self.run_worker)

        self.server_timer = QTimer()
        self.server_timer.timeout.connect(self.report_to_server)
        self.server_timer.start(int(self.settings.INTERVALSERVER) * 1000)

        # connecting a buttons
        self.chbxProcess.stateChanged.connect(self.process_checked)
        self.btnSettings.pressed.connect(self.show_settings)

        self.statusbar.showMessage("Ready")

        stock_names = [o.ticker for o in self.settings.CANDIDATES]
        self.ibkrworker.stocks_data_from_server = get_market_data_from_server(
            self.settings, stock_names)
        self.update_console("Market data for " + str(len(stock_names)) +
                            " Candidates received from Server")
        self.start_updating_candidates_and_connect()

        StyleSheet = '''
        #lcdPNLgreen {
            border: 3px solid green;
        }
        #lcdPNLred {
            border: 3px solid red;
        }
        '''
        self.setStyleSheet(StyleSheet)

    def update_candidates_info(self, status_callback, notification_callback):
        today_dt = date.today()
        for c in self.ibkrworker.stocks_data_from_server:
            updated_dt = c['tiprank_updated'].date()
            if today_dt != updated_dt:
                # yahoo
                notification_callback.emit('Update for ' + c['ticker'] +
                                           ' needed:')
                notification_callback.emit('Checking for Yahoo statisticks...')
                drop, change = get_yahoo_stats_for_candidate(
                    c['ticker'], notification_callback)
                c['yahoo_avdropP'] = drop
                c['yahoo_avspreadP'] = change
                notification_callback.emit('Got ' + str(drop) +
                                           ' average daily drop and ' +
                                           str(change) +
                                           ' average daily change.')
                # tipranks
                notification_callback.emit('Checking for Tiprank...')
                rank = get_tiprank_rating_for_ticker(
                    c['ticker'], self.settings.PATHTOWEBDRIVER)
                notification_callback.emit('Got rank of :' + str(rank))
                c['tipranks'] = rank
                c['tiprank_updated'] = today_dt
            else:
                notification_callback.emit(
                    'Data for ' + c['ticker'] +
                    ' is up to the date,no update needed')
        report_market_data_to_server(self.settings,
                                     self.ibkrworker.stocks_data_from_server)

        return 'done'

    def start_updating_candidates_and_connect(self):

        cand = Worker(self.update_candidates_info)
        cand.signals.result.connect(self.connect_to_ibkr)
        # connector.signals.status.connect(self.update_status)
        cand.signals.notification.connect(self.update_console)
        # Execute
        self.threadpool.start(cand)

    def connect_to_ibkr(self):
        """
Starts the connection to the IBKR terminal in separate thread
        """

        self.update_console("Reporting connection to the server...")
        print("Reporting connection to the server...")
        result = report_login_to_server(self.settings)
        self.update_console(result)
        connector = Worker(self.ibkrworker.prepare_and_connect)
        connector.signals.result.connect(self.connection_done)
        connector.signals.status.connect(self.update_status)
        connector.signals.notification.connect(self.update_console)
        # Execute
        self.threadpool.start(connector)

    def process_checked(self):
        """
Starts the Timer with interval from Config file
        """
        if self.chbxProcess.isChecked():
            self.run_worker()
            self.workerTimer.start(int(self.settings.INTERVALWORKER) * 1000)
        else:
            self.workerTimer.stop()

    # noinspection PyUnresolvedReferences
    def run_worker(self):
        """
Executed the Worker in separate thread
        """

        # exec(open('restarter.py').read())
        # sys.exit()
        self.update_session_state()
        currentTime = QTime().currentTime()
        fromTime = QTime(int(self.settings.TECHFROMHOUR),
                         int(self.settings.TECHFROMMIN))
        toTime = QTime(int(self.settings.TECHTOHOUR),
                       int(self.settings.TECHTOMIN))
        sessionState = self.lblMarket.text()

        if fromTime < currentTime < toTime:
            print("Worker skept-Technical break : ",
                  fromTime.toString("hh:mm"), " to ", toTime.toString("hh:mm"))
            self.update_console("Technical break untill " +
                                toTime.toString("hh:mm"))

        else:
            self.update_console("Starting Worker- UI Paused")
            self.uiTimer.stop(
            )  # to not cause an errors when lists will be resetted
            worker = Worker(
                self.ibkrworker.process_positions_candidates
            )  # Any other args, kwargs are passed to the run function
            worker.signals.result.connect(self.update_ui)
            worker.signals.status.connect(self.update_status)
            worker.signals.notification.connect(self.update_console)
            # Execute
            self.threadpool.start(worker)

    def connection_done(self):
        # add processing
        self.update_ui()
        if self.settings.AUTOSTART:
            self.chbxProcess.setChecked(True)

        # # report market data to server
        # if self.settings.USESERVER:
        #     print("Reporting market data to the server...")
        #     result = report_market_data_to_server(self.settings, self.ibkrworker.app.candidatesLive)
        #     self.update_console(result)

    def report_to_server(self):
        """
       reports to the server
        """

        if self.settings.USESERVER:
            net_liquidation = self.ibkrworker.app.netLiquidation
            if hasattr(self.ibkrworker.app, 'smaWithSafety'):
                remaining_sma_with_safety = self.ibkrworker.app.smaWithSafety
            else:
                remaining_sma_with_safety = self.ibkrworker.app.sMa
            excess_liquidity = self.ibkrworker.app.excessLiquidity
            remaining_trades = self.ibkrworker.app.tradesRemaining
            all_positions_value = 0
            open_positions = self.ibkrworker.app.openPositions
            open_orders = self.ibkrworker.app.openOrders
            dailyPnl = self.ibkrworker.app.dailyPnl
            tradinng_session_state = self.trading_session_state
            data_for_report = [
                self.settings, net_liquidation, remaining_sma_with_safety,
                remaining_trades, all_positions_value, open_positions,
                open_orders, dailyPnl,
                self.ibkrworker.last_worker_execution_time,
                datetime.now(self.est), self.trading_session_state,
                excess_liquidity
            ]

            worker = Worker(report_snapshot_to_server, self.settings,
                            data_for_report)

            worker.signals.result.connect(self.process_server_response)
            # Execute
            self.threadpool.start(worker)

    def process_server_response(self, r):
        # trying to restart
        if '$restart$' in r:
            restart()
        self.update_console(r)

    def update_ui(self):
        """
Updates UI after connection/worker execution
        """
        # main data
        self.lAcc.setText(self.settings.ACCOUNT)
        # self.lExcessLiquidity.setText(str(self.ibkrworker.app.excessLiquidity))
        # self.lSma.setText(str(self.ibkrworker.app.sMa))
        if hasattr(self.ibkrworker.app, 'smaWithSafety'):
            self.lSma.setText(str(round(self.ibkrworker.app.smaWithSafety, 1)))
        else:
            self.lSma.setText(str(round(self.ibkrworker.app.sMa, 1)))
        self.lMarketValue.setText(str(self.ibkrworker.app.netLiquidation))
        self.lblAvailTrades.setText(str(self.ibkrworker.app.tradesRemaining))
        self.lcdPNL.display(self.ibkrworker.app.dailyPnl)
        if self.ibkrworker.app.dailyPnl > 0:
            palette = self.lcdPNL.palette()
            palette.setColor(palette.WindowText, QtGui.QColor(51, 153, 51))
            self.lcdPNL.setPalette(palette)
        elif self.ibkrworker.app.dailyPnl < 0:
            palette = self.lcdPNL.palette()
            palette.setColor(palette.WindowText, QtGui.QColor(255, 0, 0))
            self.lcdPNL.setPalette(palette)

        total_positions_value = 0
        for p in self.ibkrworker.app.openPositions.values():
            if hasattr(p, 'Value'):
                total_positions_value += p["Value"]
        self.lPositionsTotalValue.setText(str(round(total_positions_value, 1)))

        self.update_open_positions()
        self.update_live_candidates()
        self.update_open_orders()

        # everything disabled for safety - is now enabled
        self.chbxProcess.setEnabled(True)
        self.btnSettings.setEnabled(True)

        self.update_session_state()

        if not self.uiTimer.isActive():
            self.update_console("UI resumed.")
        self.uiTimer.start(int(self.settings.INTERVALUI) *
                           1000)  # reset the ui timer

    def update_session_state(self):
        fmt = '%Y-%m-%d %H:%M:%S'
        self.est_dateTime = datetime.now(self.est)
        self.est_current_time = QTime(self.est_dateTime.hour,
                                      self.est_dateTime.minute,
                                      self.est_dateTime.second)
        self.lblTime.setText(self.est_current_time.toString())
        dStart = QTime(4, 00)
        dEnd = QTime(20, 00)
        tStart = QTime(9, 30)
        tEnd = QTime(16, 0)
        self.ibkrworker.check_if_holiday()
        if not self.ibkrworker.trading_session_holiday:
            if self.est_current_time > dStart and self.est_current_time <= tStart:
                self.ibkrworker.trading_session_state = "Pre Market"
                self.lblMarket.setText("Pre Market")
            elif self.est_current_time > tStart and self.est_current_time <= tEnd:
                self.ibkrworker.trading_session_state = "Open"
                self.lblMarket.setText("Open")
            elif self.est_current_time > tEnd and self.est_current_time <= dEnd:
                self.ibkrworker.trading_session_state = "After Market"
                self.lblMarket.setText("After Market")
            else:
                self.ibkrworker.trading_session_state = "Closed"
                self.lblMarket.setText("Closed")
        else:
            self.ibkrworker.trading_session_state = "Holiday"
            self.lblMarket.setText("Holiday")
        self.trading_session_state = self.ibkrworker.trading_session_state

    def progress_fn(self, n):
        msgBox = QMessageBox()
        msgBox.setText(str(n))
        retval = msgBox.exec_()

    def update_status(self, s):
        """
Updates StatusBar on event of Status
        :param s:
        """
        self.statusbar.showMessage(s)

    def update_console(self, n):
        """
Adds Message to console- upon event
        :param n:
        """
        self.consoleOut.append(n)
        self.log_message(n)

    def log_message(self, message):
        """
Adds message to the standard log
        :param message:
        """
        with open(LOGFILE, "a") as f:
            currentDt = datetime.now().strftime("%d-%b-%Y (%H:%M:%S.%f)")
            message = "\n" + currentDt + '---' + message
            f.write(message)

    def update_live_candidates(self):
        """
Updates Candidates table
        """

        liveCandidates = self.ibkrworker.app.candidatesLive
        try:
            line = 0
            self.tCandidates.setRowCount(len(liveCandidates))
            for k, v in liveCandidates.items():
                self.tCandidates.setItem(line, 0, QTableWidgetItem(v['Stock']))
                self.tCandidates.setItem(line, 1,
                                         QTableWidgetItem(str(v['Open'])))
                self.tCandidates.setItem(line, 2,
                                         QTableWidgetItem(str(v['Close'])))
                self.tCandidates.setItem(line, 3,
                                         QTableWidgetItem(str(v['Bid'])))
                self.tCandidates.setItem(line, 4,
                                         QTableWidgetItem(str(v['Ask'])))
                if v['Ask'] < v['target_price'] and v['Ask'] != -1:
                    self.tCandidates.item(line, 4).setBackground(
                        QtGui.QColor(0, 255, 0))
                if v['target_price'] is float:
                    self.tCandidates.setItem(
                        line, 5,
                        QTableWidgetItem(str(round(v['target_price'], 2))))
                else:
                    self.tCandidates.setItem(
                        line, 5, QTableWidgetItem(str(v['target_price'])))
                self.tCandidates.setItem(
                    line, 6,
                    QTableWidgetItem(str(round(v['averagePriceDropP'], 2))))
                if v['tipranksRank'] == '':
                    v['tipranksRank'] = 0
                self.tCandidates.setItem(
                    line, 7, QTableWidgetItem(str(v['tipranksRank'])))
                if int(v['tipranksRank']) > 7:
                    self.tCandidates.item(line, 7).setBackground(
                        QtGui.QColor(0, 255, 0))
                self.tCandidates.setItem(
                    line, 8, QTableWidgetItem(str(v['LastUpdate'])))

                line += 1
        except Exception as e:
            if hasattr(e, 'message'):
                self.update_console("Error in updating Candidates: " +
                                    str(e.message))
            else:
                self.update_console("Error in updating Candidates: " + str(e))

    def update_open_positions(self):
        """
Updates Positions grid
        """
        open_positions = self.ibkrworker.app.openPositions
        allKeys = [*open_positions]
        lastUpdatedWidget = 0
        try:
            for i in range(len(open_positions)):  # Update positions Panels

                widget = self.gp.itemAt(i).widget()
                key = allKeys[i]
                values = open_positions[key]
                if 'stocks' in values.keys():
                    if values['stocks'] != 0:
                        candidate = next((x for x in self.settings.CANDIDATES
                                          if x.ticker == key), None)
                        reason_of_candidate = "Bought manually"
                        if candidate is not None:
                            reason_of_candidate = candidate.reason
                        widget.update_view(key, values, reason_of_candidate)
                        widget.show()
                        lastUpdatedWidget = i
                    else:
                        widgetToRemove = self.gp.itemAt(i).widget()
                        widgetToRemove.hide()
                else:
                    print("value not yet received")

            for i in range(self.gp.count()):  # Hide the rest of the panels
                if i > lastUpdatedWidget:
                    widgetToRemove = self.gp.itemAt(i).widget()
                    widgetToRemove.hide()
        except Exception as e:
            if hasattr(e, 'message'):
                self.update_console("Error in refreshing Positions: " +
                                    str(e.message))
            else:
                self.update_console("Error in refreshing Positions: " + str(e))

    def create_open_positions_grid(self):
        """
Creates Open positions grid with 99 Positions widgets
        """

        counter = 0
        col = 0
        row = 0

        for i in range(0, 99):
            if counter % 3 == 0:
                col = 0
                row += 1
            self.gp.addWidget(PositionPanel(), row, col)
            counter += 1
            col += 1

    def update_open_orders(self):
        """
Updates Positions table
        """
        openOrders = self.ibkrworker.app.openOrders
        try:
            line = 0
            self.tOrders.setRowCount(len(openOrders))
            for k, v in openOrders.items():
                self.tOrders.setItem(line, 0, QTableWidgetItem(k))
                self.tOrders.setItem(line, 1, QTableWidgetItem(v['Action']))
                self.tOrders.setItem(line, 2, QTableWidgetItem(v['Type']))
                line += 1
        except Exception as e:
            if hasattr(e, 'message'):
                self.update_console("Error in Updating open Orders : " +
                                    str(e.message))
            else:
                self.update_console("Error in Updating open Orders : " +
                                    str(e))

    def thread_complete(self):
        """
After threaded task finished
        """
        print("TREAD COMPLETE (good or bad)!")

    def show_settings(self):

        # self.settingsWindow = SettingsWindowO(self.settings)
        # self.settingsWindow.show()  # Показываем окно
        # # maybe not needed
        # self.settingsWindow.changedSettings = False
        self.settingsWindow.existingSettings = copy.deepcopy(self.settings)
        self.settingsWindow.changedSettings = False
        self.settingsWindow.ibkrClient = self.ibkrworker
        if self.settingsWindow.exec_():
            self.settings = self.settingsWindow.existingSettings
            self.settings.write_config()
            self.restart_all()
        else:
            print("Settings window Canceled")
        self.settingsWindow = SettingsWindow()

    def restart_all(self):
        """
Restarts everything after Save
        """
        self.threadpool.waitForDone()
        self.update_console("UI paused- for restart")
        self.uiTimer.stop()

        self.workerTimer.stop()
        self.update_console("Configuration changed - restarting everything")
        self.chbxProcess.setEnabled(False)
        self.chbxProcess.setChecked(False)
        self.btnSettings.setEnabled(False)
        self.ibkrworker.app.disconnect()
        while self.ibkrworker.app.isConnected():
            print("waiting for disconnect")
            time.sleep(1)

        self.ibkrworker = None
        self.ibkrworker = IBKRWorker(self.settings)
        self.connect_to_ibkr()

        i = 4