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)
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