Пример #1
0
    def run(self):
        """
˜       Function to run the bot
        """
        if self.hyperopt:
            logger.info(f"Bot Mode : Hyperopt")
            self.params_search()
            return

        elif self.stub_test:
            logger.info(f"Bot Mode : Stub")
            self.exchange = BitMexStub()
        elif self.back_test:
            logger.info(f"Bot Mode : Back test")
            self.exchange = BitMexBackTest()
        else:
            logger.info(f"Bot Mode : Trade")
            self.exchange = BitMex(demo=self.test_net)

        self.exchange.ohlcv_len = self.ohlcv_len()
        self.exchange.on_update(self.bin_size, self.strategy)

        logger.info(f"Starting Bot")
        logger.info(f"Strategy : {type(self).__name__}")
        logger.info(f"Balance : {self.exchange.get_balance()}")

        self.exchange.show_result()
Пример #2
0
    def test_fetch_ohlcv_11m(self):
        ohlcv_len = 100
        bin_size = '11m'
        bitmex = BitMex(threading=False)

        end_time = datetime.now(timezone.utc)
        start_time = end_time - ohlcv_len * delta(bin_size)
        d1 = bitmex.fetch_ohlcv(bin_size, start_time, end_time)
        print(f"{d1}")
Пример #3
0
    def run(self):
        if self.hyperopt:
            raise Exception(
                "Trading View Strategy dose not support hyperopt Mode.")
        elif self.back_test:
            raise Exception(
                "Trading View Strategy dose not support backtest Mode.")
        elif self.stub_test:
            # if you want to use binance futures
            # self.exchange = BinanceFuturesStub(account=self.account, pair=self.pair)
            self.exchange = BitMexStub(account=self.account, pair=self.pair)
            logger.info(f"Bot Mode : Stub")
        else:
            # if you want to use binance
            #self.exchange = BinanceFutures(account=self.account, pair=self.pair, demo=self.test_net)
            self.exchange = BitMex(account=self.account,
                                   pair=self.pair,
                                   demo=self.test_net)
            logger.info(f"Bot Mode : Trade")

        logger.info(f"Starting Bot")
        logger.info(f"Strategy : {type(self).__name__}")
        logger.info(f"Balance : {self.exchange.get_balance()}")

        notify(f"Starting Bot\n"
               f"Strategy : {type(self).__name__}\n"
               f"Balance : {self.exchange.get_balance()/100000000} XBT")

        self.subscriber.on_message(self.__on_message)
Пример #4
0
    def on_update(self, bin_size, strategy):
        """
        Register function of strategy.
        :param strategy:
        """
        def __override_strategy(open, close, high, low, volume):
            new_open_orders = []

            if self.get_position_size() > 0 and low[-1] > self.get_trail_price():
                self.set_trail_price(low[-1])
            if self.get_position_size() < 0 and high[-1] < self.get_trail_price():
                self.set_trail_price(high[-1])

            for _, order in enumerate(self.open_orders):
                id = order["id"]
                long = order["long"]
                qty = order["qty"]
                limit = order["limit"]
                stop = order["stop"]
                post_only = order["post_only"]

                if limit > 0 and stop > 0:
                    if (long and high[-1] > stop and close[-1] < limit) or (not long and low[-1] < stop and close[-1] > limit):
                        self.commit(id, long, qty, limit, False)
                        continue
                    elif (long and high[-1] > stop) or (not long and low[-1] < stop):
                        new_open_orders.append(
                            {"id": id, "long": long, "qty": qty, "limit": limit, "stop": 0})
                        continue
                elif limit > 0:
                    if (long and low[-1] < limit) or (not long and high[-1] > limit):
                        self.commit(id, long, qty, limit, False)
                        continue
                elif stop > 0:
                    if (long and high[-1] > stop) or (not long and low[-1] < stop):
                        self.commit(id, long, qty, stop, False)
                        continue

                new_open_orders.append(order)

            self.open_orders = new_open_orders
            strategy(open, close, high, low, volume)
            self.eval_exit()

        BitMex.on_update(self, bin_size, __override_strategy)
Пример #5
0
    def __init__(self, account, pair, threading=True):
        """
        constructor
        :account:
        :pair:
        :param threading:
        """        
        BitMex.__init__(self, account, pair, threading=threading)        
        # Pair
        self.pair = pair
        # Balance all time high
        self.balance_ath = self.balance
        # Current Pos Size
        self.position_size = 0
        # Current AVG Price
        self.position_avg_price = 0
        # Current Order Count
        self.order_count = 0
        # Current Winning Count
        self.win_count = 0
        # Current Lose Count
        self.lose_count = 0
        # Win Profit
        self.win_profit = 0
        # Lose Loss
        self.lose_loss = 0
        #Drawdown from peak
        self.drawdown = 0
        # Max Loss Rate
        self.max_draw_down = 0
        # max drawdown for the session
        self.max_draw_down_session = 0
        # max drawdown session %
        self.max_draw_down_session_perc = 0
        # orders
        self.open_orders = []
        # Warmup long and short entry lists for tp_next_candle option for sltp()
        self.isLongEntry = [False, False]
        self.isShortEntry = [False,False]        

        self.order_log = open("orders.csv", "w")
        self.order_log.write("time,type,id,price,quantity,av_price,position,pnl,balance,drawdown\n") #header
Пример #6
0
    def run(self):
        """
˜       Function to run the bot
        """
        if self.hyperopt:
            logger.info(f"Bot Mode : Hyperopt")
            self.params_search()
            return

        elif self.stub_test:
            logger.info(f"Bot Mode : Stub")
            if self.exchange_arg == "binance":
                self.exchange = BinanceFuturesStub(account=self.account,
                                                   pair=self.pair)
            elif self.exchange_arg == "bitmex":
                self.exchange = BitMexStub(account=self.account,
                                           pair=self.pair)
            else:
                logger.info(f"--exchange argument missing or invalid")
                return
        elif self.back_test:
            logger.info(f"Bot Mode : Back test")
            if self.exchange_arg == "binance":
                self.exchange = BinanceFuturesBackTest(account=self.account,
                                                       pair=self.pair)
            elif self.exchange_arg == "bitmex":
                self.exchange = BitMexBackTest(account=self.account,
                                               pair=self.pair)
            else:
                logger.info(f"--exchange argument missing or invalid")
                return
        else:
            logger.info(f"Bot Mode : Trade")
            if self.exchange_arg == "binance":
                self.exchange = BinanceFutures(account=self.account,
                                               pair=self.pair,
                                               demo=self.test_net)
            elif self.exchange_arg == "bitmex":
                self.exchange = BitMex(account=self.account,
                                       pair=self.pair,
                                       demo=self.test_net)
            else:
                logger.info(f"--exchange argument missing or invalid")
                return
        self.exchange.ohlcv_len = self.ohlcv_len()
        self.exchange.on_update(self.bin_size, self.strategy)

        logger.info(f"Starting Bot")
        logger.info(f"Strategy : {type(self).__name__}")
        logger.info(f"Balance : {self.exchange.get_balance()}")

        notify(f"Starting Bot\n"
               f"Strategy : {type(self).__name__}\n"
               f"Balance : {self.exchange.get_balance()}")

        self.exchange.show_result()
Пример #7
0
        def objective(args):
            logger.info(f"Params : {args}")
            try:
                self.params = args
                self.exchange = BitMexBackTest()
                self.exchange.on_update(self.bin_size, self.strategy)
                profit_factor = self.exchange.win_profit / self.exchange.lose_loss
                logger.info(f"Profit Factor : {profit_factor}")
                ret = {'status': STATUS_OK, 'loss': 1 / profit_factor}
            except Exception as e:
                ret = {'status': STATUS_FAIL}

            return ret
Пример #8
0
        def objective(args):
            logger.info(f"Params : {args}")
            try:
                if self.exchange_arg == "bitmex":
                    self.params = args
                    self.exchange = BitMexBackTest(account=self.account,
                                                   pair=self.pair)
                    self.exchange.on_update(self.bin_size, self.strategy)
                    profit_factor = self.exchange.win_profit / self.exchange.lose_loss
                    logger.info(f"Profit Factor : {profit_factor}")
                    ret = {'status': STATUS_OK, 'loss': 1 / profit_factor}
                if self.exchange_arg == 'binance':
                    self.params = args
                    self.exchange = BinanceFuturesBackTest(
                        account=self.account, pair=self.pair)
                    self.exchange.on_update(self.bin_size, self.strategy)
                    profit_factor = self.exchange.win_profit / self.exchange.lose_loss
                    logger.info(f"Profit Factor : {profit_factor}")
                    ret = {'status': STATUS_OK, 'loss': 1 / profit_factor}
            except Exception as e:
                ret = {'status': STATUS_FAIL}

            return ret
Пример #9
0
 def __init__(self, threading=True):
     """
     constructor
     :param threading:
     """
     BitMex.__init__(self, threading=threading)
Пример #10
0
class Bot:
    params = {}
    exchange = None
    bin_size = '1h'
    periods = 20
    test_net = False
    back_test = False
    stub_test = False
    hyperopt = False

    def __init__(self, bin_size):
        """
        constructor
        :param bin_size: time_frame
        :param periods: period
        """
        self.bin_size = bin_size

    def options(self):
        """
        Function to obtain value for searching for a parameter.
        """
        pass

    def ohlcv_len(self):
        """
        The length of the OHLC to the strategy
        """
        return 100

    def input(self, title, type, defval):
        """
        function to get param
        :param title: title of the parm
        :param defval: default value
        :return value
        """
        p = {} if self.params is None else self.params
        if title in p:
            return type(p[title])
        else:
            return defval

    def strategy(self, open, close, high, low, volume):
        """
        Strategy function, when creating a bot please inherit this and implement this fn. 
        :param open: open price
        :param close: close price
        :param high: high price
        :param low: low price
        :param volume: volume
        """
        pass

    def params_search(self):
        """
 ˜      function to search params
        """
        def objective(args):
            logger.info(f"Params : {args}")
            try:
                self.params = args
                self.exchange = BitMexBackTest()
                self.exchange.on_update(self.bin_size, self.strategy)
                profit_factor = self.exchange.win_profit / self.exchange.lose_loss
                logger.info(f"Profit Factor : {profit_factor}")
                ret = {'status': STATUS_OK, 'loss': 1 / profit_factor}
            except Exception as e:
                ret = {'status': STATUS_FAIL}

            return ret

        trials = Trials()
        best_params = fmin(objective,
                           self.options(),
                           algo=tpe.suggest,
                           trials=trials,
                           max_evals=200)
        logger.info(f"Best params is {best_params}")
        logger.info(
            f"Best profit factor is {1/trials.best_trial['result']['loss']}")

    def run(self):
        """
˜       Function to run the bot
        """
        if self.hyperopt:
            logger.info(f"Bot Mode : Hyperopt")
            self.params_search()
            return

        elif self.stub_test:
            logger.info(f"Bot Mode : Stub")
            self.exchange = BitMexStub()
        elif self.back_test:
            logger.info(f"Bot Mode : Back test")
            self.exchange = BitMexBackTest()
        else:
            logger.info(f"Bot Mode : Trade")
            self.exchange = BitMex(demo=self.test_net)

        self.exchange.ohlcv_len = self.ohlcv_len()
        self.exchange.on_update(self.bin_size, self.strategy)

        logger.info(f"Starting Bot")
        logger.info(f"Strategy : {type(self).__name__}")
        logger.info(f"Balance : {self.exchange.get_balance()}")

        self.exchange.show_result()

    def stop(self):
        """
˜       Function that stops the bot and cancel all trades.
        """
        if self.exchange is None:
            return

        logger.info(f"Stopping Bot")

        self.exchange.stop()
        self.exchange.cancel_all()
        sys.exit()
Пример #11
0
    def on_update(self, bin_size, strategy):
        """
        Register function of strategy.
        :param strategy:
        """
        def __override_strategy(action, open, close, high, low, volume):
            new_open_orders = []

            self.OHLC = {
                        'open': open,
                        'high': high,
                        'low': low,
                        'close': close
                        }

            if self.get_position_size() > 0 and low[-1] > self.get_trail_price():
                self.set_trail_price(low[-1])
            if self.get_position_size() < 0 and high[-1] < self.get_trail_price():
                self.set_trail_price(high[-1])

            index=0

            while(True):
                
                if index < len(self.open_orders):
                    order = self.open_orders[index]
                    index += 1
                else:
                    break

                id = order["id"]
                long = order["long"]
                qty = order["qty"]
                limit = order["limit"]
                stop = order["stop"]
                post_only = order["post_only"]
                reduce_only = order["reduce_only"]
                callback = order["callback"]

                if reduce_only == True and (self.position_size == 0 or (long and self.get_position_size() > 0) or (not long and self.get_position_size() < 0)):
                    new_open_orders.append({"id": id, "long": long, "qty": qty, "limit": limit, "stop": 0, "post_only": post_only, "reduce_only": reduce_only, "callback": callback})
                    continue

                if limit > 0 and stop > 0:
                    if (long and high[-1] > stop and close[-1] < limit) or (not long and low[-1] < stop and close[-1] > limit):
                        self.commit(id, long, qty, limit, True, callback)
                        continue
                    elif (long and high[-1] > stop) or (not long and low[-1] < stop):
                        new_open_orders.append({"id": id, "long": long, "qty": qty, "limit": limit, "stop": 0, "post_only": post_only, "reduce_only": reduce_only, "callback": callback})
                        continue
                elif limit > 0:
                    if (long and low[-1] < limit) or (not long and high[-1] > limit):
                        self.commit(id, long, qty, limit, True, callback)
                        continue
                elif stop > 0:
                    if (long and high[-1] > stop) or (not long and low[-1] < stop):
                        self.commit(id, long, qty, stop, True, callback)
                        continue

                new_open_orders.append(order)

            self.open_orders = new_open_orders
            self.eval_exit()
            self.eval_sltp()
            strategy(action, open, close, high, low, volume)

        BitMex.on_update(self, bin_size, __override_strategy)
Пример #12
0
class Bot:
    # Parameters
    params = {}
    # Account
    account = None
    # Exchange
    exchange_arg = None
    # Time Frame
    bin_size = '1h'
    # Pair
    pair = 'BTCUSDT'
    # Periods
    periods = 20
    # Run on test net?
    test_net = False
    # Back test?
    back_test = False
    # Stub Test(paper trading)?
    stub_test = False
    # Parameter optimization?
    hyperopt = False
    # Session Persistence
    session = Session()
    # session = type("Session", (object,), {})()
    session_file = None
    session_file_name = None

    def __init__(self, bin_size):
        """
        constructor
        :param bin_size: time_frame
        :param periods: period
        """
        self.bin_size = bin_size

    def __del__(self):
        self.stop()

    def get_session(self):
        return self.session

    def set_session(self, session):
        self.session.load(session)

    def options(self):
        """
        Function to get values for parameter optimization
        """
        pass

    def ohlcv_len(self):
        """
        The length of the OHLC to the strategy
        """
        return 100

    def input(self, title, type, defval):
        """
        function to get param
        :param title: title of the parm
        :param defval: default value
        :return value
        """
        p = {} if self.params is None else self.params
        if title in p:
            return type(p[title])
        else:
            return defval

    def strategy(self, open, close, high, low, volume):
        """
        Strategy function, when creating a bot please inherit and implement this fn. 
        :param open: open price
        :param close: close price
        :param high: high price
        :param low: low price
        :param volume: volume
        """
        pass

    def params_search(self):
        """
 ˜      function to search params
        """
        def objective(args):
            logger.info(f"Params : {args}")
            try:
                if self.exchange_arg == "bitmex":
                    self.params = args
                    self.exchange = BitMexBackTest(account=self.account,
                                                   pair=self.pair)
                    self.exchange.on_update(self.bin_size, self.strategy)
                    profit_factor = self.exchange.win_profit / self.exchange.lose_loss
                    logger.info(f"Profit Factor : {profit_factor}")
                    ret = {'status': STATUS_OK, 'loss': 1 / profit_factor}
                if self.exchange_arg == 'binance':
                    self.params = args
                    self.exchange = BinanceFuturesBackTest(
                        account=self.account, pair=self.pair)
                    self.exchange.on_update(self.bin_size, self.strategy)
                    profit_factor = self.exchange.win_profit / self.exchange.lose_loss
                    logger.info(f"Profit Factor : {profit_factor}")
                    ret = {'status': STATUS_OK, 'loss': 1 / profit_factor}
            except Exception as e:
                ret = {'status': STATUS_FAIL}

            return ret

        trials = Trials()
        best_params = fmin(objective,
                           self.options(),
                           algo=tpe.suggest,
                           trials=trials,
                           max_evals=200)
        logger.info(f"Best params is {best_params}")
        logger.info(
            f"Best profit factor is {1/trials.best_trial['result']['loss']}")

    def run(self):
        """
˜       Function to run the bot
        """
        if self.hyperopt:
            logger.info(f"Bot Mode : Hyperopt")
            self.params_search()
            return

        elif self.stub_test:
            logger.info(f"Bot Mode : Stub")
            if self.exchange_arg == "binance":
                self.exchange = BinanceFuturesStub(account=self.account,
                                                   pair=self.pair)
            elif self.exchange_arg == "bitmex":
                self.exchange = BitMexStub(account=self.account,
                                           pair=self.pair)
            else:
                logger.info(f"--exchange argument missing or invalid")
                return
        elif self.back_test:
            logger.info(f"Bot Mode : Back test")
            if self.exchange_arg == "binance":
                self.exchange = BinanceFuturesBackTest(account=self.account,
                                                       pair=self.pair)
            elif self.exchange_arg == "bitmex":
                self.exchange = BitMexBackTest(account=self.account,
                                               pair=self.pair)
            else:
                logger.info(f"--exchange argument missing or invalid")
                return
        else:
            logger.info(f"Bot Mode : Trade")
            if self.exchange_arg == "binance":
                self.exchange = BinanceFutures(account=self.account,
                                               pair=self.pair,
                                               demo=self.test_net)
            elif self.exchange_arg == "bitmex":
                self.exchange = BitMex(account=self.account,
                                       pair=self.pair,
                                       demo=self.test_net)
            else:
                logger.info(f"--exchange argument missing or invalid")
                return
        self.exchange.ohlcv_len = self.ohlcv_len()
        self.exchange.on_update(self.bin_size, self.strategy)

        logger.info(f"Starting Bot")
        logger.info(f"Strategy : {type(self).__name__}")
        logger.info(f"Balance : {self.exchange.get_balance()}")

        notify(f"Starting Bot\n"
               f"Strategy : {type(self).__name__}\n"
               f"Balance : {self.exchange.get_balance()}")

        self.exchange.show_result()

    def stop(self):
        """
˜       Function that stops the bot and cancel all trades.
        """
        if self.exchange is None:
            return

        logger.info(f"Stopping Bot")

        if self.session_file != None:
            self.session_file.truncate(0)
            self.session_file.seek(0)
            # pickle.dump(self.session, self.session_file)
            json.dump(self.session,
                      self.session_file,
                      default=vars,
                      indent=True)
            # self.session_file.write(jsonpickle.encode(self.session))
            self.session_file.close()
            logger.info(f"Saved Session to {self.session_file_name}")

        self.exchange.stop()
        self.exchange.cancel_all()
        sys.exit(0)
Пример #13
0
    def test_entry_cancel(self):
        bitmex = BitMex()
        bitmex.demo = True

        # close current orders
        bitmex.close_all()

        price = bitmex.get_market_price()

        # TEST: CANCELLATION
        id = "Long"
        bitmex.entry(id, True, 1, limit=price - 1000)
        assert bitmex.get_open_order(id) is not None
        bitmex.cancel(id)
        assert bitmex.get_open_order(id) is None

        # TEST: UPDATE ORDER
        id = "Long"
        bitmex.entry(id, True, 1, limit=price - 1000)
        order = bitmex.get_open_order(id)
        assert order["orderQty"] == 1
        assert order["price"] == price - 1000
        bitmex.entry(id, True, 2, limit=price - 900)
        order = bitmex.get_open_order(id)
        assert order["orderQty"] == 2
        assert order["price"] == price - 900
        bitmex.cancel(id)
        assert bitmex.get_open_order(id) is None
Пример #14
0
 def test_fetch_ohlc_2h(self):
     bitmex = BitMex(threading=False)
     end_time = datetime.now(timezone.utc)
     start_time = end_time - 5 * timedelta(hours=2)
     source = bitmex.fetch_ohlcv('2h', start_time, end_time)
     assert len(source) > 1
Пример #15
0
 def test_fetch_ohlcv_5m(self):
     bitmex = BitMex(threading=False)
     end_time = datetime.now(timezone.utc)
     start_time = end_time - 5 * timedelta(minutes=5)
     source = bitmex.fetch_ohlcv('5m', start_time, end_time)
     assert len(source) > 1