def saveCSV(self, filename: str='tradingdata.csv') -> None: """Saves the DataFrame to an uncompressed CSV.""" p = compile(r"^[\w\-. ]+$") if not p.match(filename): raise TypeError('Filename required.') if not isinstance(self.df, DataFrame): raise TypeError('Pandas DataFrame required.') try: self.df.to_csv(filename) except OSError: Logger.critical(f'Unable to save: {filename}')
def _write_data(self, name: str = "") -> bool: file = self.filename if name == "" else name try: with open( os.path.join(self.app.telegramdatafolder, "telegram_data", file), "w", encoding="utf8", ) as outfile: json.dump(self.data, outfile, indent=4) return True except JSONDecodeError as err: Logger.critical(str(err)) return False
def _read_data(self, name: str = "") -> None: file = self.filename if name == "" else name try: with open( os.path.join(self.app.telegramdatafolder, "telegram_data", file), "r", encoding="utf8", ) as json_file: self.data = json.load(json_file) except (JSONDecodeError, Exception) as err: Logger.critical(str(err)) with open( os.path.join(self.app.telegramdatafolder, "telegram_data", file), "r", encoding="utf8", ) as json_file: self.data = json.load(json_file)
def marketBuy(self, market: str = "", quote_quantity: float = 0) -> pd.DataFrame: """Executes a market buy providing a funding amount""" # validates the market is syntactically correct if not self._isMarketValid(market): raise ValueError("Coinbase Pro market is invalid.") # validates quote_quantity is either an integer or float if not isinstance(quote_quantity, int) and not isinstance( quote_quantity, float): Logger.critical("Please report this to Michael Whittle: " + str(quote_quantity) + " " + str(type(quote_quantity))) raise TypeError("The funding amount is not numeric.") # funding amount needs to be greater than 10 if quote_quantity < MINIMUM_TRADE_AMOUNT: Logger.warning( f"Trade amount is too small (>= {MINIMUM_TRADE_AMOUNT}).") return pd.DataFrame() # raise ValueError(f"Trade amount is too small (>= {MINIMUM_TRADE_AMOUNT}).") try: order = { "product_id": market, "type": "market", "side": "buy", "funds": self.marketQuoteIncrement(market, quote_quantity), } Logger.debug(order) # connect to authenticated coinbase pro api model = AuthAPI(self._api_key, self._api_secret, self._api_passphrase, self._api_url) # place order and return result return model.authAPI("POST", "orders", order) except: return pd.DataFrame()
def marketBuy(self, market: str = "", quote_quantity: float = 0) -> pd.DataFrame: """Executes a market buy providing a funding amount""" # validates the market is syntactically correct if not self._isMarketValid(market): raise ValueError("Kucoin market is invalid.") # validates quote_quantity is either an integer or float if not isinstance(quote_quantity, int) and not isinstance( quote_quantity, float): Logger.critical("Please report this to Michael Whittle: " + str(quote_quantity) + " " + str(type(quote_quantity))) raise TypeError("The funding amount is not numeric.") # funding amount needs to be greater than 10 if quote_quantity < MINIMUM_TRADE_AMOUNT: raise ValueError( f"Trade amount is too small (>= {MINIMUM_TRADE_AMOUNT}).") dt_obj = datetime.strptime(str(datetime.now()), "%Y-%m-%d %H:%M:%S.%f") millisec = dt_obj.timestamp() * 1000 order = { "clientOid": str(millisec), "symbol": market, "type": "market", "side": "buy", "funds": self.marketQuoteIncrement(market, quote_quantity), } # Logger.debug(order) # connect to authenticated Kucoin api model = AuthAPI(self._api_key, self._api_secret, self._api_passphrase, self._api_url) # place order and return result return model.authAPI("POST", "api/v1/orders", order)
def marketBuy(self, market: str = '', quote_quantity: float = 0) -> pd.DataFrame: """Executes a market buy providing a funding amount""" # validates the market is syntactically correct if not self._isMarketValid(market): raise ValueError('Coinbase Pro market is invalid.') # validates quote_quantity is either an integer or float if not isinstance(quote_quantity, int) and not isinstance( quote_quantity, float): Logger.critical('Please report this to Michael Whittle: ' + str(quote_quantity) + ' ' + str(type(quote_quantity))) raise TypeError('The funding amount is not numeric.') # funding amount needs to be greater than 10 if quote_quantity < MINIMUM_TRADE_AMOUNT: raise ValueError( f"Trade amount is too small (>= {MINIMUM_TRADE_AMOUNT}).") order = { 'product_id': market, 'type': 'market', 'side': 'buy', 'funds': self.marketQuoteIncrement(market, quote_quantity) } Logger.debug(order) # connect to authenticated coinbase pro api model = AuthAPI(self._api_key, self._api_secret, self._api_passphrase, self._api_url) # place order and return result return model.authAPI('POST', 'orders', order)
def main(): try: message = 'Starting ' if app.getExchange() == 'coinbasepro': message += 'Coinbase Pro bot' elif app.getExchange() == 'binance': message += 'Binance bot' smartSwitchStatus = 'enabled' if app.getSmartSwitch() else 'disabled' message += ' for ' + app.getMarket( ) + ' using granularity ' + app.printGranularity( ) + '. Smartswitch ' + smartSwitchStatus app.notifyTelegram(message) # initialise and start application trading_data = app.startApp(account, state.last_action) def runApp(): # run the first job immediately after starting if app.isSimulation(): executeJob(s, app, state, trading_data) else: executeJob(s, app, state) s.run() try: runApp() except KeyboardInterrupt: raise except (BaseException, Exception) as e: if app.autoRestart(): # Wait 30 second and try to relaunch application time.sleep(30) Logger.critical('Restarting application after exception: ' + repr(e)) app.notifyTelegram('Auto restarting bot for ' + app.getMarket() + ' after exception: ' + repr(e)) # Cancel the events queue map(s.cancel, s.queue) # Restart the app runApp() else: raise # catches a keyboard break of app, exits gracefully except KeyboardInterrupt: Logger.warning( str(datetime.now()) + ' bot is closed via keyboard interrupt...') try: sys.exit(0) except SystemExit: os._exit(0) except (BaseException, Exception) as e: # catch all not managed exceptions and send a Telegram message if configured app.notifyTelegram('Bot for ' + app.getMarket() + ' got an exception: ' + repr(e)) Logger.critical(repr(e)) raise