def Main(): # backtests a bot using the same config that can run a bot # For the backtester, we initialise the exchange exchange = CcxtExchange('kucoin') # we then initialize the backtester using the config dict bt = Backtester(bot_config) for symbol in bot_config['symbols']: # and download the data df = exchange.getOHLCV(symbol, '1m', 1000) # and run it on the data downloaded before bt.backtest(df) # we then retreive and print the results results = bt.return_results() print(symbol) pprint(results) # and we also Plot OHLCV, indicators & signals PlotData(df, plot_indicators=[ dict(name='slow_ma', title='SLOW HMA'), dict(name='fast_ma', title='FAST HMA'), ], signals=[ dict(name='entry orders', points=bt.entries), dict(name='exit orders', points=bt.exits), ], title=symbol, show_plot=True)
def Main(): exchange = CcxtExchange('okex', { 'apiKey': getenv('OKEX_API_KEY'), 'secret': getenv('OKEX_API_SECRET'), 'password': getenv('OKEX_PASSWORD'), 'timeout': 30000, # 'verbose': True, 'enableRateLimit': True, }) exchange.placeStopLossMarketOrder('ETH/BTC', 'sell', 0.08, 0.025, custom_id='your_custom_id_here')
def Main(): exchange = CcxtExchange('binance') symbol = "BTC/USDT" interval = "4h" df = exchange.getOHLCVHistory(symbol, interval, 8000) start_time = df['time'][0] end_time = df['time'][len(df) - 1] price_min = df['close'].min() price_max = df['close'].max() diff = price_max - price_min level1 = price_max - 0.236 * diff level2 = price_max - 0.382 * diff level3 = price_max - 0.618 * diff lines = [] lines.append( horizontal_line(start_time, end_time, price_max, color="rgba(255, 0, 0, 255)")) lines.append( horizontal_line(start_time, end_time, level1, color="rgba(255, 255, 0, 255)")) lines.append( horizontal_line(start_time, end_time, level2, color="rgba(0, 255, 0, 255)")) lines.append( horizontal_line(start_time, end_time, level3, color="rgba(0, 255, 255, 255)")) lines.append( horizontal_line(start_time, end_time, price_min, color="rgba(0, 0, 255, 255)")) PlotData(df, add_candles=False, plot_shapes=lines, plot_title="fib_levels_" + symbol.replace('/', '').lower() + "_" + interval, show_plot=True)
def __init__(self, name=None): self.sp = False self.screen = False if name == None: pass # print('GridBot is nonexistent, ' # 'please call self.create() ' # 'with the required parameters') else: session = getSession('sqlite:///{}.db'.format(name)) bot = session.query(GridBotModel).first() if bot == None: pass # print('GridBot is nonexistent, ' # 'please call self.create() ' # 'with the required parameters') else: # print('GridBot found!') self.bot = bot self.name = name self.session = session self.symbol = bot.symbol self.total_amount = bot.starting_balance self.trade_amount = bot.trade_amount self.trade_step = bot.trade_step self.test_mode = bot.test_run self.exchange_name = bot.exchange.upper() self.exchange = CcxtExchange( bot.exchange.lower(), { 'apiKey': getenv('{}_API_KEY'.format(self.exchange_name)), 'secret': getenv('{}_API_SECRET'.format(self.exchange_name)), 'password': getenv('{}_PASSWORD'.format(self.exchange_name)), 'timeout': 30000, # 'verbose': True, 'enableRateLimit': True, })
def Main(): resetOrdersPairs = False session = getSession('sqlite:///pyjuque_ccxt_binance_live_1.db') exchange = CcxtExchange( 'binance', { 'apiKey': getenv('BINANCE_API_KEY'), 'secret': getenv('BINANCE_API_SECRET'), # 'password': getenv('OKEX_PASSWORD'), 'timeout': 30000, 'verbose': True, 'enableRateLimit': True, }) symbols = ['TRX/ETH', 'XRP/ETH'] # for symbol in exchange.SYMBOL_DATAS.keys(): # if exchange.SYMBOL_DATAS[symbol]["status"] == "TRADING" \ # and exchange.SYMBOL_DATAS[symbol]["quoteAsset"] == "BTC": # symbols.append(symbol) # First time you run this, uncomment the next line # initialize_database(session, symbols) bot = session.query(Bot).filter_by(name='test_bot_ccxt_tudor').first() # input your path to credentials here. strategy = AlwaysBuyStrategy() # strategy = BBRSIStrategy(13, 40, 70, 30) bot_controller = BotController(session, bot, exchange, strategy) sp = yaspin() bot_controller.sp = sp bot_controller.sp_on = True while True: try: bot_controller.executeBot() except KeyboardInterrupt: return bot_controller.sp.start() left_to_sleep = time_to_sleep while left_to_sleep > 0: bot_controller.sp.text = "Waiting for {} more seconds...".format( left_to_sleep) time.sleep(1) left_to_sleep -= 1
def Main(): bot_config = getYamlConfig(bot_name) db_url = None if bot_config.__contains__('db_url'): db_url = bot_config['db_url'] session = getSession(db_url) exchange = CcxtExchange( 'binance', { 'apiKey': getenv('BINANCE_API_KEY'), 'secret': getenv('BINANCE_API_SECRET'), 'timeout': 30000, 'enableRateLimit': True, }) Strategies = getStrategies() bot = session.query(Bot).filter_by(name=bot_name).first() if bot is None: print('No bot found by name: {}. Creating...'.format(bot_name)) InitializeDatabase(session, bot_config) Main() symbols = [] if bot_config.__contains__('symbols') is not None: symbols = bot_config['symbols'] strategy = Strategies[bot_config['strategy']['name']]( **bot_config['strategy']['params']) bot_controller = BotController(session, bot, exchange, strategy) sp = yaspin() bot_controller.sp = sp bot_controller.sp_on = True while True: try: bot_controller.executeBot() except KeyboardInterrupt: return bot_controller.sp.start() left_to_sleep = bot_config['time_to_sleep'] while left_to_sleep > 0: bot_controller.sp.text = "Waiting for {} more seconds...".format( left_to_sleep) time.sleep(1) left_to_sleep -= 1
for char in line: if char != chr(bot.screen.inch(k, q)): bot.screen.addch(k, q, char, curses.color_pair(3)) q += 1 k += 1 bot.screen.refresh() # bot.sp.start() if __name__ == '__main__': okex = CcxtExchange( 'okex', { 'apiKey': getenv('OKEX_API_KEY'), 'secret': getenv('OKEX_API_SECRET'), 'password': getenv('OKEX_PASSWORD'), 'timeout': 30000, # 'verbose': True, 'enableRateLimit': True, }) symbol = 'LTC/USDT' total_amount = 200 # We are trading in total 1000 units of quote asset trade_amount = 0.05 # For each trade we are placing 10% of total amount trade_step = 0.003 # 0.3% space between trades and 2 * 0.3% profit per trade total_trades = 1 time_to_sleep = 10 sp = yaspin() screen = curses.initscr() bot = GridBotController() #('GridBot_OKEX_LTCUSDT_300_15_0point5_live')
import datetime import websocket import threading from pprint import pprint from decimal import Decimal, Context from pyjuque.Exchanges.Binance import Binance from pyjuque.Exchanges.CcxtExchange import CcxtExchange ############## GLOBAL VARIABLES ############## ws = None # Websocket Object exchange = CcxtExchange( 'binance', { 'apiKey': getenv('BINANCE_API_KEY'), 'secret': getenv('BINANCE_API_SECRET'), 'timeout': 30000, 'enableRateLimit': True, }) # The exchange order_book = dict(counter=0) # The (per-symbol) order book order_book_lock = threading.Lock() # Order book threading lock order_book_initialized = dict() # Whether the (per-symbol) local # order book was initialized buffered_events = dict(counter=0) # Buffers events before local # order book initialization ############## FOR COUNTING ############## buffered_events_count = 0 unbuffered_events_count = 0
def _defineTaBot(bot_config): session = getSession(bot_config['db_url']) bot_name = bot_config['name'] exchange_name = bot_config['exchange']['name'] exchange_params = bot_config['exchange']['params'] exchange = CcxtExchange(exchange_name, exchange_params) bot_model = session.query(TABotModel).filter_by(name=bot_name).first() if bot_model is None: print('No bot found by name: {}. Creating...'.format(bot_name)) InitializeDatabaseTaBot(session, bot_config) return _defineTaBot(bot_config) # print('Bot model before init bot_controller', bot_model) timeframe = '5m' if bot_config.__contains__('timeframe'): timeframe = bot_config['timeframe'] bot_controller = BotController(session, bot_model, exchange, None) if bot_config.__contains__('display_status'): if bot_config['display_status']: status_printer = yaspin() bot_controller.status_printer = status_printer else: status_printer = yaspin() bot_controller.status_printer = status_printer if bot_config.__contains__('strategy'): found = False if bot_config['strategy'].__contains__('custom'): if bot_config['strategy']['custom'] == True: found = True def nothing(self, symbol): return False, None entry_function = nothing exit_function = nothing if bot_config['strategy'].__contains__('entry_function'): if bot_config['strategy']['entry_function'] not in [ None, False ]: entry_function = bot_config['strategy'][ 'entry_function'] if bot_config['strategy'].__contains__('exit_function'): if bot_config['strategy']['exit_function'] not in [ None, False ]: exit_function = bot_config['strategy']['exit_function'] bot_controller.checkEntryStrategy = functools.partial( entry_function, bot_controller) bot_controller.checkExitStrategy = functools.partial( exit_function, bot_controller) if not found and bot_config['strategy'].__contains__('class'): bot_controller.strategy = bot_config['strategy']['class']( **bot_config['strategy']['params']) return bot_controller # def Main(): # for key in ['db_url', 'name', 'symbols', 'exchange', 'type']: # assert key in bot_config.keys(), '{} should be inside the config object'.format(key) # for key in ['name', 'params']: # assert key in bot_config['exchange'].keys(), '{} should be inside the exchange config object'.format(key) # session = getSession(bot_config['db_url']) # bot_name = bot_config['name'] # exchange_name = bot_config['exchange']['name'] # exchange_params = bot_config['exchange']['params'] # exchange = CcxtExchange(exchange_name, exchange_params) # symbols = bot_config['symbols'] # bot_type = bot_config['type'] # bot_model = session.query(Bot).filter_by(name=bot_name).first() # if bot_model is None: # print('No bot found by name: {}. Creating...'.format(bot_name)) # if bot_type == 'ta': # InitializeDatabaseTaBot(session, bot_config) # elif bot_ta == 'grid': # InitializeDatabaseGridBot(session, bot_config) # Main() # strategy = None # if bot_config.__contains__('entry_strategy'): # if bot_config.__contains__('class'): # strategy = bot_config['entry_strategy']['class'](**bot_config['entry_strategy']['params']) # bot_controller = None # if bot_type == 'ta': # bot_controller = BotController(session, bot_model, exchange, strategy) # elif bot_type == 'grid': # bot_controller = GridBotController(name) # bot.create(exchange, symbols[0], total_amount, trade_amount, trade_step, total_trades) # if bot_config.__contains__('display_status'): # if bot_config['display_status']: # status_printer = yaspin() # bot_controller.status_printer = status_printer # while True: # try: # bot_controller.executeBot() # except KeyboardInterrupt: # return # bot_controller.status_printer.start() # left_to_sleep = bot_config['sleep'] # while left_to_sleep > 0: # if bot_controller.status_printer != None: # open_orders = bot_controller.bot_model.getOpenOrders(bot_controller.session) # bot_controller.status_printer.text = 'Open Orders: {} | Checking signals in {} |'.format( # len(open_orders), # left_to_sleep) # time.sleep(1) # left_to_sleep -= 1 # if __name__ == '__main__': # Main()
class GridBotController: def __init__(self, name=None): self.sp = False self.screen = False if name == None: pass # print('GridBot is nonexistent, ' # 'please call self.create() ' # 'with the required parameters') else: session = getSession('sqlite:///{}.db'.format(name)) bot = session.query(GridBotModel).first() if bot == None: pass # print('GridBot is nonexistent, ' # 'please call self.create() ' # 'with the required parameters') else: # print('GridBot found!') self.bot = bot self.name = name self.session = session self.symbol = bot.symbol self.total_amount = bot.starting_balance self.trade_amount = bot.trade_amount self.trade_step = bot.trade_step self.test_mode = bot.test_run self.exchange_name = bot.exchange.upper() self.exchange = CcxtExchange( bot.exchange.lower(), { 'apiKey': getenv('{}_API_KEY'.format(self.exchange_name)), 'secret': getenv('{}_API_SECRET'.format(self.exchange_name)), 'password': getenv('{}_PASSWORD'.format(self.exchange_name)), 'timeout': 30000, # 'verbose': True, 'enableRateLimit': True, }) def create(self, exchange, symbol, total_amount, trade_amount, trade_step, total_trades, test_mode=False): self.exchange = exchange self.exchange_name = self.exchange.exchange_id.upper() self.symbol = symbol self.total_amount = total_amount self.trade_amount = trade_amount self.trade_step = trade_step self.total_trades = total_trades self.test_mode = test_mode self.name = 'GridBot_{}_{}_{}_{}_{}'.format( self.exchange_name, symbol.replace('/', ''), str(int(total_amount)), str(int(trade_amount * total_amount)), str(trade_step * 100).replace('.', 'point')) if test_mode: self.name = self.name + '_test' raise NotImplementedError('Test Mode not implemented for GridBot') else: self.name = self.name + '_live' # print('Bot name is {}'.format(self.name)) self.session = getSession('sqlite:///{}.db'.format(self.name)) bot = self.session.query(GridBotModel).first() if bot == None: self._initializeDatabase() else: self.bot = bot def _initializeDatabase(self): """ Function that initializes the database by creating a bot with two pairs. """ self.bot = GridBotModel(name=self.name, symbol=self.symbol, exchange=self.exchange.exchange_id, starting_balance=self.total_amount, current_balance=self.total_amount, trade_amount=self.trade_amount, trade_step=self.trade_step, test_run=self.test_mode) self.session.add(self.bot) self.session.commit() def tradingLoop(self): ticker = self.exchange.exchange.fetchTicker(self.symbol) last_price = Decimal(ticker['last']) open_orders = self.bot.getOpenOrders(self.session) if len(open_orders) == 0: # Place Initial Buy Orders self.sp.text = 'Palcing Initial Orders' self.placeInitialOrders(last_price) open_orders = self.bot.getOpenOrders(self.session) for order in open_orders: self.sp.text = 'Checking Placed Orders' self.updateOpenOrder(order, last_price) self.updateLastOrder(last_price) self.session.commit() def placeInitialOrders(self, last_price): for i in range(self.total_trades): buy_price = last_price - last_price * Decimal(i + 1) * Decimal( self.trade_step) order = self.placeOrder(symbol=self.symbol, side='buy', price=buy_price, quantity=self.trade_amount, order_type='limit', is_entry=True) order.position_id = i self.session.commit() def updateOpenOrder(self, order, last_price): if not self.test_mode: # try: exchange_order_info = self.exchange.getOrder(order.symbol, order.id, is_custom_id=True) # except Exception: # self.toLog('Error getting data from the exchange for updating open order on {}.'.format(self.symbol), should_print=True) # self.toLog(sys.exc_info(), should_print=True) # return else: raise NotImplementedError('Test Mode not implemented for GridBot') # print('Order Info:') # pprint(exchange_order_info) order.side = exchange_order_info['side'] order.status = exchange_order_info['status'] order.executed_quantity = exchange_order_info['filled'] if exchange_order_info['fee'] != None: order.executed_quantity = exchange_order_info[ 'filled'] + exchange_order_info['fee']['cost'] if (order.side == 'buy'): # buy order was filled, place exit order. if (order.status == 'closed'): self.screen.clear() self.screen.refresh() # pprint(exchange_order_info) self.toLog('Buy order at {} filled, place exit.'.format( order.price)) self.placeExitOrder(order) self.placeFarthestEntryOrder(last_price) elif (order.status in ['canceled', 'expired', 'rejected']): if order.executed_quantity > 0: self.toLog( 'Buy order at {} canceled, but partially filled, place exit.' .format(order.price)) self.placeExitOrder(order) self.placeFarthestEntryOrder(last_price) else: order.is_closed = True # sell order if (order.side == 'sell'): # sell order was filled if (order.status == 'closed'): self.screen.clear() self.screen.refresh() # pprint(exchange_order_info) self.toLog( 'Sell order at {} filled, cancel farthest buy order and replace with new buy order.' .format(order.price)) self.cancelFarthestEntryOrder(last_price) self.placeEntryOrder(order) order.is_closed = True # sell order was rejected by engine of exchange # if (order.status in ['rejected', 'expired', 'canceled']): # original_buy_order = self.reviveOriginalBuyOrder(order) # self.placeExitOrder(original_buy_order) def placeEntryOrder(self, exit_order): # entry_order = self.session.query(Order).filter_by(matched_order_id=exit_order.id) buy_price = exit_order.price * Decimal(1 - self.trade_step) self.placeOrder(symbol=self.symbol, price=buy_price, quantity=exit_order.executed_quantity, side='buy', order_type='limit', is_entry=True) def placeExitOrder(self, entry_order): sell_price = entry_order.price * Decimal(1 + 2 * self.trade_step) self.placeOrder(symbol=self.symbol, entry_order=entry_order, price=sell_price, quantity=entry_order.executed_quantity, side='sell', order_type='limit') def updateLastOrder(self, last_price): open_orders = [ order for order in self.bot.getOpenOrders(self.session) if order.side == 'buy' ] if len(open_orders) == 0: return farthest_order = None closest_order = None max_difference = 0 min_difference = 10000 for order in open_orders: difference = last_price - order.price if difference > max_difference: max_difference = difference farthest_order = order if difference < min_difference: min_difference = difference closest_order = order if min_difference > last_price * Decimal(2 * self.trade_step): order_result = self.exchange.cancelOrder(farthest_order.symbol, farthest_order.id, is_custom_id=True) farthest_order.status = 'canceled' farthest_order.is_closed = True buy_price = closest_order.price * Decimal(1 + self.trade_step) self.placeOrder(symbol=self.symbol, price=buy_price, quantity=farthest_order.original_quantity, side='buy', order_type='limit', is_entry=True) def cancelFarthestEntryOrder(self, last_price): open_orders = [ order for order in self.bot.getOpenOrders(self.session) if order.side == 'buy' ] if len(open_orders) == 0: return farthest_order = None max_difference = 0 for order in open_orders: difference = last_price - order.price if difference > max_difference: max_difference = difference farthest_order = order order_result = self.exchange.cancelOrder(farthest_order.symbol, farthest_order.id, is_custom_id=True) farthest_order.status = 'canceled' farthest_order.is_closed = True def placeFarthestEntryOrder(self, last_price): open_orders = [ order for order in self.bot.getOpenOrders(self.session) if order.side == 'buy' ] if len(open_orders) == 0: buy_price = last_price * Decimal(1 - self.trade_step) self.placeOrder(symbol=self.symbol, price=buy_price, quantity=self.trade_amount, side='buy', order_type='limit', is_entry=True) return farthest_order = None max_difference = 0 for order in open_orders: difference = last_price - order.price if difference > max_difference: max_difference = difference farthest_order = order buy_price = farthest_order.price * Decimal(1 - self.trade_step) self.placeOrder(symbol=self.symbol, price=buy_price, quantity=self.trade_amount, side='buy', order_type='limit', is_entry=True) def placeOrder(self, entry_order=None, **order_params): """ Create Order model and place order to exchange. """ order_params['bot_id'] = self.bot.id new_order = placeNewOrder(exchange=self.exchange, symbol=self.symbol, order=entry_order, test_mode=self.test_mode, order_params=order_params) if new_order != None: self.syncModels(entry_order, new_order) self.session.add(new_order) return new_order def syncModels(self, entry_order, new_order): """ Sync orders to new status """ if entry_order is not None: new_order.matched_order_id = entry_order.id entry_order.is_closed = True entry_order.matched_order_id = new_order.id else: self.bot.current_balance = self.bot.current_balance \ - Decimal(self.trade_amount) * Decimal(self.bot.starting_balance) def toLog(self, message, should_print=False): # if self.screen: # self.screen.clear() # self.screen.refresh() if self.sp: self.sp.stop() if should_print: logger.info(message) else: self.sp.text = message self.sp.start() elif should_print: logger.info(message)