Esempio n. 1
0
class SsrmBot:
    def __init__(self, symbol, min_amount, API_KEY, API_SECRET):
        self.symbol = symbol

        self.api_key = API_KEY
        self.api_secret = API_SECRET
        self.bclient = Client(api_key=self.api_key, api_secret=self.api_secret)
        self.bot_ping = True

        self.rsi_signal = None

        self.main_data = []
        self.main_data_hour = []
        self.trade = 0
        # self.my_bid = 0
        self.my_price = 0

        self.status = False
        self.min_amount = min_amount * 50
        self.amount = 0

        self.main_direction = None
        self.new_side = None

        self.order = False
        self.order_id = False

        self.order_id_tp = False
        self.order_id_sl = False

        self.my_tp = 0
        self.my_sl = 0

        self.my_Stoch = False
        self.my_RSI = False

        self.binance_websocket_api_manager = None

    def new_data_1_min(self):
        print("New data 1 min START:")
        para = self.bclient.get_historical_klines(
            f"{self.symbol}usdt".upper(), Client.KLINE_INTERVAL_1MINUTE,
            "1 day ago UTC")
        self.main_data = para
        print("================== new_data_1_min")

    def new_data_1_hour(self):
        print("New data 1 hour START:")
        para = self.bclient.get_historical_klines(f"{self.symbol}usdt".upper(),
                                                  Client.KLINE_INTERVAL_1HOUR,
                                                  "2 days ago UTC")
        self.main_data_hour = para
        print("================== new_data_1_hour")

    def place_new_order(self):

        if self.main_direction == 1:
            self.new_side = "LONG"
        else:
            self.new_side = "SHORT"

        self.order = self.main_direction

        reponse = Orders.my_order_future(
            client=self.bclient,
            symbol=f"{self.symbol.upper()}USDT",
            side=self.main_direction,
            amount=round(self.amount,
                         n_rools[self.symbol.upper()]["decimals"]))

        if reponse['error']:
            self.bot_ping = False
            logging.info(f"New order Error:\n {reponse}")
            bot_sendtext(f"New order Error:\n {reponse}")
        else:
            self.order_id = reponse['result']['orderId']
            logging.info(f"New order:\n {reponse}")
            dbrools.insert_history_new(data=reponse)

            time.sleep(1)

            my_orders = self.bclient.futures_get_order(
                symbol=f"{self.symbol.upper()}USDT", orderId=self.order_id)
            self.my_price = float(my_orders['avgPrice'])

            if self.order == 1:
                self.my_sl = self.my_price / 1.009
                self.my_tp = self.my_price * 1.022
            else:
                self.my_sl = self.my_price * 1.009
                self.my_tp = self.my_price / 1.022

            data = {
                "symbol":
                f"{self.symbol} ({self.new_side})",
                "side":
                f"{self.new_side}",
                "amount":
                round(self.amount, n_rools[self.symbol.upper()]["decimals"]),
                "price":
                float(
                    round(self.my_price,
                          n_rools[self.symbol.upper()]['price'])),
                "direct":
                'BUY',
                "result":
                0,
                "date":
                f"{datetime.now().strftime('%d.%m.%Y')}"
            }
            dbrools.insert_history(data=data)

            bot_message = f"Added {self.symbol} ({self.new_side}), \n{round(self.amount, n_rools[self.symbol.upper()]['decimals'])}, \n{round(self.my_price, n_rools[self.symbol.upper()]['price'])},\n SL {round(self.my_sl, n_rools[self.symbol.upper()]['price'])} / TP {round(self.my_tp, n_rools[self.symbol.upper()]['price'])}"
            bot_sendtext(bot_message)
            print("\n", bot_message)

            self.place_tp_order()

    def place_tp_order(self):
        reponse = Orders.tp_future(
            client=self.bclient,
            symbol=f"{self.symbol.upper()}USDT",
            side=self.main_direction,
            price=str(round(self.my_tp,
                            n_rools[self.symbol.upper()]['price'])),
            amount=round(self.amount,
                         n_rools[self.symbol.upper()]["decimals"]))
        if reponse['error']:
            self.bot_ping = False
            logging.info(f"TP order Error:\n {reponse}")
            bot_sendtext(f"TP order Error:\n {reponse}")
        else:
            self.order_id_tp = reponse['result']['clientOrderId']
            self.place_sl_order()

    def place_sl_order(self):
        reponse = Orders.sl_future(
            client=self.bclient,
            symbol=f"{self.symbol.upper()}USDT",
            side=self.main_direction,
            price=str(round(self.my_sl,
                            n_rools[self.symbol.upper()]['price'])),
            amount=round(self.amount,
                         n_rools[self.symbol.upper()]["decimals"]))
        if reponse['error']:
            self.bot_ping = False
            logging.info(f"TP order Error:\n {reponse}")
            bot_sendtext(f"TP order Error:\n {reponse}")
        else:
            self.order_id_sl = reponse['result']['clientOrderId']

    def close_tp_order(self):
        bot_message = f"QUIT {self.symbol.upper()} ({self.new_side}), \n{round(self.amount, n_rools[self.symbol.upper()]['decimals'])}, \n{round(self.my_tp, n_rools[self.symbol.upper()]['price'])}, \n TAKE PROFIT"
        bot_sendtext(bot_message)
        print("\n", bot_message)
        data = {
            "symbol": f"{self.symbol} ({self.new_side})",
            "amount": round(self.amount,
                            n_rools[self.symbol.upper()]['decimals']),
            "price": round(self.my_tp, n_rools[self.symbol.upper()]['price']),
            "direct": 'SELL',
            "result": 2,
            "date": f"{datetime.now().strftime('%d.%m.%Y')}"
        }
        dbrools.insert_history(data=data)

        self.bclient.futures_cancel_order(symbol=f"{self.symbol.upper()}USDT",
                                          origClientOrderId=self.order_id_sl)

        self.my_Stoch = False
        self.my_RSI = False
        self.order = False
        self.order_id = False

    def close_sl_order(self):
        bot_message = f"QUIT {self.symbol.upper()} ({self.new_side}), \n{round(self.amount, n_rools[self.symbol.upper()]['decimals'])}, \n{round(self.my_tp, n_rools[self.symbol.upper()]['price'])}, \n STOP LOSS"
        bot_sendtext(bot_message)
        print("\n", bot_message)
        data = {
            "symbol": f"{self.symbol} ({self.new_side})",
            "amount": round(self.amount,
                            n_rools[self.symbol.upper()]['decimals']),
            "price": round(self.my_sl, n_rools[self.symbol.upper()]['price']),
            "direct": 'SELL',
            "result": 1,
            "date": f"{datetime.now().strftime('%d.%m.%Y')}"
        }
        dbrools.insert_history(data=data)

        self.bclient.futures_cancel_order(symbol=f"{self.symbol.upper()}USDT",
                                          origClientOrderId=self.order_id_tp)
        self.my_Stoch = False
        self.my_RSI = False
        self.order = False
        self.order_id = False

    def algorithm(self):
        if not self.order:
            df = pd.DataFrame(self.main_data,
                              columns=[
                                  'timestamp', 'open', 'high', 'low', 'close',
                                  'volume', 'close_time', 'quote_av', 'trades',
                                  'tb_base_av', 'tb_quote_av', 'ignore'
                              ])
            df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
            df.set_index('timestamp', inplace=True)

            df['close'] = pd.to_numeric(df['close'])
            df['close'] = pd.to_numeric(df['close'])
            df["high"] = pd.to_numeric(df["high"])
            df["low"] = pd.to_numeric(df["low"])

            df['rsi'] = ta.RSI(df['close'].values, timeperiod=12)
            df["slowk"], df["slowd"] = ta.STOCH(df['high'].values,
                                                df['low'].values,
                                                df['close'].values, 14, 3, 0,
                                                3, 0)
            df["macd"], df["line"], df["hist"] = ta.MACD(df['close'],
                                                         fastperiod=12,
                                                         slowperiod=26,
                                                         signalperiod=9)

            if df["slowk"].iloc[-1] <= 20 and df["slowd"].iloc[-1] <= 20:
                self.my_Stoch = 1
            elif df["slowk"].iloc[-1] >= 80 and df["slowd"].iloc[-1] >= 80:
                self.my_Stoch = 2

            if self.my_Stoch == 1 and df["slowk"].iloc[-1] >= 80:
                self.my_Stoch = False
            elif self.my_Stoch == 2 and df["slowk"].iloc[-1] <= 20:
                self.my_Stoch = False

            if df["rsi"].iloc[-1] >= 50:
                self.my_RSI = 1
            else:
                self.my_RSI = 2

            if self.my_Stoch == 1 and self.my_RSI == 1:
                if df["hist"].iloc[-1] > 0 > df["hist"].iloc[
                        -2] and self.rsi_signal > 70:
                    self.main_direction = self.my_RSI
                    self.place_new_order()
            elif self.my_Stoch == 2 and self.my_RSI == 2:
                if df["hist"].iloc[-1] < 0 < df["hist"].iloc[
                        -2] and self.rsi_signal < 30:
                    self.main_direction = self.my_RSI
                    self.place_new_order()

    def algorithm_rsi(self):
        data = pd.DataFrame(self.main_data_hour,
                            columns=[
                                'timestamp', 'open', 'high', 'low', 'close',
                                'volume', 'close_time', 'quote_av', 'trades',
                                'tb_base_av', 'tb_quote_av', 'ignore'
                            ])
        data['timestamp'] = pd.to_datetime(data['timestamp'], unit='ms')
        data.set_index('timestamp', inplace=True)

        data['close'] = pd.to_numeric(data['close'])
        data["high"] = pd.to_numeric(data["high"])
        data["low"] = pd.to_numeric(data["low"])

        data.reset_index(inplace=True, drop=True)
        data["RSID"] = ta.RSI(data['close'].values, timeperiod=12)
        self.rsi_signal = data["RSID"].iloc[-1]

    def run(self):
        bot_sendtext(f"FUTURE START {self.symbol.upper()}USDT")
        self.binance_websocket_api_manager = BinanceWebSocketApiManager(
            exchange="binance.com-futures", output_default="dict")
        self.binance_websocket_api_manager.create_stream(
            ['kline_1m', 'kline_1h'], [f'{self.symbol}usdt'],
            stream_label="UnicornFy",
            output="UnicornFy")
        self.binance_websocket_api_manager.create_stream(
            ['trade'], [f'{self.symbol}usdt'], output="UnicornFy")

        self.binance_websocket_api_manager.create_stream(
            'arr',
            '!userData',
            api_key=self.api_key,
            api_secret=self.api_secret,
            output="dict")

        while self.bot_ping:
            if self.status:
                self.status = False
                self.binance_websocket_api_manager.create_stream(
                    ['kline_1m', 'kline_1h'], [f'{self.symbol}usdt'],
                    stream_label="UnicornFy",
                    output="UnicornFy")

                self.binance_websocket_api_manager.create_stream(
                    ['trade'], [f'{self.symbol}usdt'], output="UnicornFy")

                self.binance_websocket_api_manager.create_stream(
                    'arr',
                    '!userData',
                    api_key=self.api_key,
                    api_secret=self.api_secret,
                    output="dict")

                print(
                    f"PARSER RESTART at {datetime.now().strftime('%H:%M:%S')}")
            else:
                try:
                    if self.binance_websocket_api_manager.is_manager_stopping(
                    ):
                        exit(0)
                        self.status = True
                    stream_buffer = self.binance_websocket_api_manager.pop_stream_data_from_stream_buffer(
                    )
                    if stream_buffer:
                        try:
                            if "e" in stream_buffer:
                                if stream_buffer['e'] == 'ACCOUNT_UPDATE':
                                    if stream_buffer['a']['P'][0][
                                            's'] == f'{self.symbol}usdt'.upper(
                                            ) and stream_buffer['a']['P'][0][
                                                'pa'] == "0":
                                        if self.order == 1:
                                            if self.trade >= self.my_price:
                                                self.close_tp_order()
                                            if self.trade < self.my_price:
                                                self.close_sl_order()
                                        elif self.order == 2:
                                            if self.trade > self.my_price:
                                                self.close_sl_order()
                                            if self.trade <= self.my_price:
                                                self.close_tp_order()
                            elif stream_buffer['event_type'] == "trade":
                                self.trade = float(stream_buffer['price'])
                                self.amount = self.min_amount / self.trade
                            else:
                                if stream_buffer['kline']['interval'] == "1m":
                                    if stream_buffer[
                                            'event_time'] >= stream_buffer[
                                                'kline']['kline_close_time']:
                                        new_row = [
                                            stream_buffer['kline']
                                            ['kline_start_time'],
                                            stream_buffer['kline']
                                            ['open_price'],
                                            stream_buffer['kline']
                                            ['high_price'],
                                            stream_buffer['kline']
                                            ['low_price'],
                                            stream_buffer['kline']
                                            ['close_price'],
                                            stream_buffer['kline']
                                            ['base_volume'],
                                            stream_buffer['kline']
                                            ['kline_close_time'], None, None,
                                            None, None, None
                                        ]
                                        self.main_data.append(new_row)
                                        del self.main_data[0]
                                        self.algorithm()
                                elif stream_buffer['kline'][
                                        'interval'] == "1h":
                                    if stream_buffer[
                                            'event_time'] >= stream_buffer[
                                                'kline']['kline_close_time']:
                                        new_row = [
                                            stream_buffer['kline']
                                            ['kline_start_time'],
                                            stream_buffer['kline']
                                            ['open_price'],
                                            stream_buffer['kline']
                                            ['high_price'],
                                            stream_buffer['kline']
                                            ['low_price'],
                                            stream_buffer['kline']
                                            ['close_price'],
                                            stream_buffer['kline']
                                            ['base_volume'],
                                            stream_buffer['kline']
                                            ['kline_close_time'], None, None,
                                            None, None, None
                                        ]
                                        self.main_data_hour.append(new_row)
                                        del self.main_data_hour[0]
                                        self.algorithm_rsi()
                            time.sleep(0.1)
                        except KeyError:
                            print(f"Exception :\n {stream_buffer}")
                            time.sleep(0.5)
                    else:
                        time.sleep(0.01)
                except Exception as exc:
                    self.status = True
                    traceback.print_exc()
                    time.sleep(30)
Esempio n. 2
0
def main():

    arg = docopt(__doc__, version=version)
    api_key = getenv('BINANCE_FUTURES_API')
    sec_key = getenv('BINANCE_FUTURES_SEC')
    if not api_key and not sec_key:
        print('please set these environment variables:\n'\
              '    BINANCE_FUTURES_API\n'\
              '    BINANCE_FUTURES_SEC', file=stderr)
        return 1
    if not api_key:
        print('environment variable not found: BINANCE_FUTURES_API',
              file=stderr)
        return 1
    if not sec_key:
        print('environment variable not found: BINANCE_FUTURES_SEC',
              file=stderr)
        return 1
    client = Client(api_key, sec_key)
    sides = {
        'buy': Client.SIDE_BUY,
        'long': Client.SIDE_BUY,
        'sell': Client.SIDE_SELL,
        'short': Client.SIDE_SELL,
    }
    types = {
        'limit': Client.ORDER_TYPE_LIMIT,
        'market': Client.ORDER_TYPE_MARKET
    }
    tifs = {
        'gtc': Client.TIME_IN_FORCE_GTC,
        'ioc': Client.TIME_IN_FORCE_IOC,
        'fok': Client.TIME_IN_FORCE_FOK
    }

    if arg['--verbose']:
        print(arg, file=stderr)
    else:
        sys.tracebacklimit = 0

    if arg['--help']:
        print(__doc__, file=stderr)
        return 0

    elif arg['status']:
        return client.get_system_status()['status']

    elif arg['balance']:
        if arg['futures']:
            print(dumps(client.futures_account_balance()))
        elif arg['spot']:
            print(dumps(client.get_account()['balances']))
        elif arg['coin']:
            print(dumps(client.futures_coin_account_balance()))
        return 0

    elif arg['show']:
        if arg['spot']:
            if arg['orders']:
                # if arg['--all']:
                #     print(dumps(client.get_all_orders()))
                # else:
                print(dumps(client.get_open_orders()))

    elif arg['order']:
        symbol = arg['<symbol>'].upper()
        if arg['futures'] and not symbol.endswith('USDT'):
            symbol += 'USDT'
        if arg['cancel']:
            if arg['futures']:
                print(
                    client.futures_cancel_order(symbol=symbol,
                                                orderid=arg['<orderid>'],
                                                timestamp=timemilli()))
            elif arg['spot']:
                print('not implemented', file=stderr)
        else:  # create order
            tif = tifs[arg['--tif']]
            if arg['<side>'].strip().lower() in sides:
                side = sides[arg['<side>'].strip().lower()]
            else:  # side is wrong
                print('error: side should be either "buy|long" or "sell|short"'\
                      ' not', arg['side'], file=stderr)
            quantity = float(arg['<quantity>'])
            if arg['--limit']:
                if arg['--limit']:
                    price = float(arg['--limit'])
                    type_ = types['limit']
                    if arg['--test']:
                        print(
                            client.create_test_order(symbol=symbol,
                                                     side=side,
                                                     quantity=quantity,
                                                     price=price,
                                                     timeInForce=tif,
                                                     type=type_))
                    else:  # actually send the order
                        if arg['futures']:
                            print(
                                client.futures_create_order(
                                    symbol=symbol,
                                    side=side,
                                    quantity=quantity,
                                    price=price,
                                    timeInForce=tif,
                                    reduceOnly=arg['--reduce-only'],
                                    timestamp=timemilli(),
                                    type=type_))
                        elif arg['spot']:
                            print(
                                client.create_order(symbol=symbol,
                                                    side=side,
                                                    quantity=quantity,
                                                    price=price,
                                                    timeInForce=tif,
                                                    type=type_))
                else:  # limit given but price not
                    print('please provide --limit \033[33m<price>\033[0m.')
            elif arg['--market']:
                type_ = types['market']
                if arg['--test']:
                    print(
                        client.create_test_order(symbol=symbol,
                                                 side=side,
                                                 quantity=quantity,
                                                 type=type_))
                else:  # actually send the order
                    if arg['futures']:
                        print(
                            client.futures_create_order(
                                symbol=symbol,
                                side=side,
                                quantity=quantity,
                                timestamp=timemilli(),
                                reduceOnly=arg['--reduce-only'],
                                type=type_))
                    elif arg['spot']:
                        print(
                            client.create_order(symbol=symbol,
                                                side=side,
                                                quantity=quantity,
                                                price=price,
                                                type=type_))
            else:  # limit or market not given
                print('please provide either '\
                      '\033[33m --limit <price>\033[0m '\
                      'or \033[33m--market\033[0m', file=stderr)

    else:  # no arguments given
        print(__doc__, file=stderr)
        return 1