Exemple #1
0
    def add_candle(self,
                   candle: np.ndarray,
                   exchange: str,
                   symbol: str,
                   timeframe: str,
                   with_execution: bool = True,
                   with_generation: bool = True) -> None:
        if jh.is_collecting_data():
            # make sure it's a complete (and not a forming) candle
            if jh.now_to_timestamp() >= (candle[0] + 60000):
                store_candle_into_db(exchange, symbol, candle)
            return

        arr: DynamicNumpyArray = self.get_storage(exchange, symbol, timeframe)

        if jh.is_live():
            self.update_position(exchange, symbol, candle)

            # ignore new candle at the time of execution because it messes
            # the count of candles without actually having an impact
            if candle[0] >= jh.now():
                return

        # initial
        if len(arr) == 0:
            arr.append(candle)

        # if it's new, add
        elif candle[0] > arr[-1][0]:
            # in paper mode, check to see if the new candle causes any active orders to be executed
            if with_execution and jh.is_paper_trading():
                self.simulate_order_execution(exchange, symbol, timeframe,
                                              candle)

            arr.append(candle)

            # generate other timeframes
            if with_generation and timeframe == '1m':
                self.generate_bigger_timeframes(candle, exchange, symbol,
                                                with_execution)

        # if it's the last candle again, update
        elif candle[0] == arr[-1][0]:
            # in paper mode, check to see if the new candle causes any active orders to get executed
            if with_execution and jh.is_paper_trading():
                self.simulate_order_execution(exchange, symbol, timeframe,
                                              candle)

            arr[-1] = candle

            # regenerate other timeframes
            if with_generation and timeframe == '1m':
                self.generate_bigger_timeframes(candle, exchange, symbol,
                                                with_execution)

        # past candles will be ignored (dropped)
        elif candle[0] < arr[-1][0]:
            return
Exemple #2
0
    def handle_exception(exc_type, exc_value, exc_traceback) -> None:
        if issubclass(exc_type, KeyboardInterrupt):
            sys.excepthook(exc_type, exc_value, exc_traceback)
            return

        # handle Breaking exceptions
        if exc_type in [
            exceptions.InvalidConfig, exceptions.RouteNotFound, exceptions.InvalidRoutes,
            exceptions.CandleNotFoundInDatabase
        ]:
            click.clear()
            print(f"{'=' * 30} EXCEPTION TRACEBACK:")
            traceback.print_tb(exc_traceback, file=sys.stdout)
            print("=" * 73)
            print(
                '\n',
                jh.color('Uncaught Exception:', 'red'),
                jh.color(f'{exc_type.__name__}: {exc_value}', 'yellow')
            )
            return

        # send notifications if it's a live session
        if jh.is_live():
            jesse_logger.error(
                f'{exc_type.__name__}: {exc_value}'
            )

        if jh.is_live() or jh.is_collecting_data():
            logging.error("Uncaught Exception:", exc_info=(exc_type, exc_value, exc_traceback))
        else:
            print(f"{'=' * 30} EXCEPTION TRACEBACK:")
            traceback.print_tb(exc_traceback, file=sys.stdout)
            print("=" * 73)
            print(
                '\n',
                jh.color('Uncaught Exception:', 'red'),
                jh.color(f'{exc_type.__name__}: {exc_value}', 'yellow')
            )

        if jh.is_paper_trading():
            print(
                jh.color(
                    'An uncaught exception was raised. Check the log file at:\nstorage/logs/paper-trade.txt',
                    'red'
                )
            )
        elif jh.is_livetrading():
            print(
                jh.color(
                    'An uncaught exception was raised. Check the log file at:\nstorage/logs/live-trade.txt',
                    'red'
                )
            )
        elif jh.is_collecting_data():
            print(
                jh.color(
                    'An uncaught exception was raised. Check the log file at:\nstorage/logs/collect.txt',
                    'red'
                )
            )
Exemple #3
0
        def handle_thread_exception(args):
            """

            :param args:
            :return:
            """
            if args.exc_type == SystemExit:
                return

            # handle Breaking exceptions
            if args.exc_type in [
                    exceptions.ConfigException, exceptions.RouteNotFound,
                    exceptions.InvalidRoutes,
                    exceptions.CandleNotFoundInDatabase
            ]:
                click.clear()
                print('=' * 30 + ' EXCEPTION TRACEBACK:')
                traceback.print_tb(args.exc_traceback, file=sys.stdout)
                print("=" * 73)
                print(
                    '\n', jh.color('Uncaught Exception:', 'red'),
                    jh.color(
                        '{}: {}'.format(args.exc_type.__name__,
                                        args.exc_value), 'yellow'))
                return

            # send notifications if it's a live session
            if jh.is_live():
                jesse_logger.error('{}: {}'.format(args.exc_type.__name__,
                                                   args.exc_value))

            if jh.is_live() or jh.is_collecting_data():
                logging.error("Uncaught Exception:",
                              exc_info=(args.exc_type, args.exc_value,
                                        args.exc_traceback))
            else:
                print('=' * 30 + ' EXCEPTION TRACEBACK:')
                traceback.print_tb(args.exc_traceback, file=sys.stdout)
                print("=" * 73)
                print(
                    '\n', jh.color('Uncaught Exception:', 'red'),
                    jh.color(
                        '{}: {}'.format(args.exc_type.__name__,
                                        args.exc_value), 'yellow'))

            if jh.is_paper_trading():
                print(
                    jh.color(
                        'An uncaught exception was raised. Check the log file at:\n{}'
                        .format('storage/logs/paper-trade.txt'), 'red'))
            elif jh.is_livetrading():
                print(
                    jh.color(
                        'An uncaught exception was raised. Check the log file at:\n{}'
                        .format('storage/logs/live-trade.txt'), 'red'))
            elif jh.is_collecting_data():
                print(
                    jh.color(
                        'An uncaught exception was raised. Check the log file at:\n{}'
                        .format('storage/logs/collect.txt'), 'red'))
Exemple #4
0
def livetrade():
    # TODO: for now, we assume that we trade on one exchange only. Later, we need to support for more than one exchange at a time
    # sum up balance of all trading exchanges
    starting_balance = 0
    current_balance = 0
    for e in store.exchanges.storage:
        starting_balance += store.exchanges.storage[e].starting_assets[
            jh.app_currency()]
        current_balance += store.exchanges.storage[e].assets[jh.app_currency()]
    starting_balance = round(starting_balance, 2)
    current_balance = round(current_balance, 2)

    # short trades summary
    if len(store.completed_trades.trades):
        df = pd.DataFrame.from_records(
            [t.to_dict() for t in store.completed_trades.trades])
        total = len(df)
        winning_trades = len(df.loc[df['PNL'] > 0])
        losing_trades = len(df.loc[df['PNL'] < 0])
        pnl = round(df['PNL'].sum(), 2)
        pnl_perc = round((pnl / starting_balance) * 100, 2)
    else:
        pnl, pnl_perc, total, winning_trades, losing_trades = 0, 0, 0, 0, 0

    routes = [{
        'exchange': r.exchange,
        'symbol': r.symbol,
        'timeframe': r.timeframe,
        'strategy': r.strategy_name
    } for r in router.routes]

    return {
        'session_id': store.app.session_id,
        'started_at': str(store.app.starting_time),
        'current_time': str(jh.now_to_timestamp()),
        'started_balance': str(starting_balance),
        'current_balance': str(current_balance),
        'debug_mode': str(config['app']['debug_mode']),
        'paper_mode': str(jh.is_paper_trading()),
        'count_error_logs': str(len(store.logs.errors)),
        'count_info_logs': str(len(store.logs.info)),
        'count_active_orders': str(store.orders.count_all_active_orders()),
        'open_positions': str(store.positions.count_open_positions()),
        'pnl': str(pnl),
        'pnl_perc': str(pnl_perc),
        'count_trades': str(total),
        'count_winning_trades': str(winning_trades),
        'count_losing_trades': str(losing_trades),
        'routes': routes
    }
Exemple #5
0
def test_is_paper_trading():
    assert jh.is_paper_trading() is False
Exemple #6
0
def register_custom_exception_handler() -> None:
    import sys
    import threading
    import traceback
    import logging
    from jesse.services import logger as jesse_logger
    import click
    from jesse import exceptions

    log_format = "%(message)s"

    os.makedirs('./storage/logs', exist_ok=True)

    if jh.is_livetrading():
        logging.basicConfig(filename='storage/logs/live-trade.txt',
                            level=logging.INFO,
                            filemode='w',
                            format=log_format)
    elif jh.is_paper_trading():
        logging.basicConfig(filename='storage/logs/paper-trade.txt',
                            level=logging.INFO,
                            filemode='w',
                            format=log_format)
    elif jh.is_collecting_data():
        logging.basicConfig(filename='storage/logs/collect.txt',
                            level=logging.INFO,
                            filemode='w',
                            format=log_format)
    elif jh.is_optimizing():
        logging.basicConfig(filename='storage/logs/optimize.txt',
                            level=logging.INFO,
                            filemode='w',
                            format=log_format)
    else:
        logging.basicConfig(level=logging.INFO)

    # main thread
    def handle_exception(exc_type, exc_value, exc_traceback) -> None:
        if issubclass(exc_type, KeyboardInterrupt):
            sys.excepthook(exc_type, exc_value, exc_traceback)
            return

        # handle Breaking exceptions
        if exc_type in [
                exceptions.InvalidConfig, exceptions.RouteNotFound,
                exceptions.InvalidRoutes, exceptions.CandleNotFoundInDatabase
        ]:
            click.clear()
            print(f"{'=' * 30} EXCEPTION TRACEBACK:")
            traceback.print_tb(exc_traceback, file=sys.stdout)
            print("=" * 73)
            print('\n', jh.color('Uncaught Exception:', 'red'),
                  jh.color(f'{exc_type.__name__}: {exc_value}', 'yellow'))
            return

        # send notifications if it's a live session
        if jh.is_live():
            jesse_logger.error(f'{exc_type.__name__}: {exc_value}')

        if jh.is_live() or jh.is_collecting_data():
            logging.error("Uncaught Exception:",
                          exc_info=(exc_type, exc_value, exc_traceback))
        else:
            print(f"{'=' * 30} EXCEPTION TRACEBACK:")
            traceback.print_tb(exc_traceback, file=sys.stdout)
            print("=" * 73)
            print('\n', jh.color('Uncaught Exception:', 'red'),
                  jh.color(f'{exc_type.__name__}: {exc_value}', 'yellow'))

        if jh.is_paper_trading():
            print(
                jh.color(
                    'An uncaught exception was raised. Check the log file at:\nstorage/logs/paper-trade.txt',
                    'red'))
        elif jh.is_livetrading():
            print(
                jh.color(
                    'An uncaught exception was raised. Check the log file at:\nstorage/logs/live-trade.txt',
                    'red'))
        elif jh.is_collecting_data():
            print(
                jh.color(
                    'An uncaught exception was raised. Check the log file at:\nstorage/logs/collect.txt',
                    'red'))

    sys.excepthook = handle_exception

    # other threads
    if jh.python_version() >= (3, 8):

        def handle_thread_exception(args) -> None:
            if args.exc_type == SystemExit:
                return

            # handle Breaking exceptions
            if args.exc_type in [
                    exceptions.InvalidConfig, exceptions.RouteNotFound,
                    exceptions.InvalidRoutes,
                    exceptions.CandleNotFoundInDatabase
            ]:
                click.clear()
                print(f"{'=' * 30} EXCEPTION TRACEBACK:")
                traceback.print_tb(args.exc_traceback, file=sys.stdout)
                print("=" * 73)
                print(
                    '\n', jh.color('Uncaught Exception:', 'red'),
                    jh.color(f'{args.exc_type.__name__}: {args.exc_value}',
                             'yellow'))
                return

            # send notifications if it's a live session
            if jh.is_live():
                jesse_logger.error(
                    f'{args.exc_type.__name__}: { args.exc_value}')

            if jh.is_live() or jh.is_collecting_data():
                logging.error("Uncaught Exception:",
                              exc_info=(args.exc_type, args.exc_value,
                                        args.exc_traceback))
            else:
                print(f"{'=' * 30} EXCEPTION TRACEBACK:")
                traceback.print_tb(args.exc_traceback, file=sys.stdout)
                print("=" * 73)
                print(
                    '\n', jh.color('Uncaught Exception:', 'red'),
                    jh.color(f'{args.exc_type.__name__}: {args.exc_value}',
                             'yellow'))

            if jh.is_paper_trading():
                print(
                    jh.color(
                        'An uncaught exception was raised. Check the log file at:\nstorage/logs/paper-trade.txt',
                        'red'))
            elif jh.is_livetrading():
                print(
                    jh.color(
                        'An uncaught exception was raised. Check the log file at:\nstorage/logs/live-trade.txt',
                        'red'))
            elif jh.is_collecting_data():
                print(
                    jh.color(
                        'An uncaught exception was raised. Check the log file at:\nstorage/logs/collect.txt',
                        'red'))

        threading.excepthook = handle_thread_exception
Exemple #7
0
    def add_candle(self,
                   candle: np.ndarray,
                   exchange: str,
                   symbol: str,
                   timeframe: str,
                   with_execution=True,
                   with_generation=True,
                   is_forming_candle=False):
        """

        :param candle:
        :param exchange:
        :param symbol:
        :param timeframe:
        :param with_execution:
        :param with_generation:
        :param is_forming_candle:
        :return:
        """
        if jh.is_collecting_data():
            # make sure it's a complete (and not a forming) candle
            if jh.now() >= (candle[0] + 60000):
                store_candle_into_db(exchange, symbol, candle)
            return

        arr: DynamicNumpyArray = self.get_storage(exchange, symbol, timeframe)

        if jh.is_live():
            self.update_position(exchange, symbol, candle)

        # initial
        if len(arr) == 0:
            arr.append(candle)

        # if it's new, add
        elif candle[0] > arr[-1][0]:
            # in paper mode, check to see if the new candle causes any active orders to be executed
            if with_execution and jh.is_paper_trading():
                self.simulate_order_execution(exchange, symbol, timeframe,
                                              candle)

            arr.append(candle)

            # generate other timeframes
            if with_generation and timeframe == '1m':
                self.generate_bigger_timeframes(candle, exchange, symbol,
                                                with_execution,
                                                is_forming_candle)

        # if it's the last candle again, update
        elif candle[0] == arr[-1][0]:
            # in paper mode, check to see if the new candle causes any active orders to get executed
            if with_execution and jh.is_paper_trading():
                self.simulate_order_execution(exchange, symbol, timeframe,
                                              candle)

            arr[-1] = candle

            # regenerate other timeframes
            if with_generation and timeframe == '1m':
                self.generate_bigger_timeframes(candle, exchange, symbol,
                                                with_execution,
                                                is_forming_candle)

        # past candles will be ignored (dropped)
        elif candle[0] < arr[-1][0]:
            return