def email_trade_reports(self): self.__email_handler.send_email_with_attachment( email_subject= f"{self.__exchange_name}: Trade Number {trading_cache.successful_trades}", email_message=f'Review logs', attachment_file_paths=[ TradeBotUtils.get_generated_file_path( f"{self.__exchange_name.lower()}_successful_trade_log.csv" ), TradeBotUtils.get_generated_file_path( f"{self.__exchange_name.lower()}_trade_report.html") ])
def __run_setup_tasks(self): self.__live_run_checker() TradeBotUtils.create_target_folder() if self.__configs.reset_database: self.__database_service.drop_schema_tables( schema=self.__database_schema) self.__database_service.run_queries_from_file( file_path=TradeBotUtils.get_template_file_path( "algorithmic_trading_database_schema.sql")) if self.__configs.is_reset_logs: TradeBotUtils.reset_logs(self.__configs.exchange)
def get_accrued_account_fees(self, exchange: str, cash_currency: str, crypto_currency: str, is_live: bool) -> float: accrued_fee = 0 for currency in TradeBotUtils.get_permitted_cash_currencies(): query = "SELECT SUM(fee) from trade_data.report" \ " WHERE live = %s" \ " AND exchange = %s" \ " AND cash_currency = %s" \ " AND crypto_currency = %s;" data = [ is_live, exchange.lower(), currency.lower(), crypto_currency.lower() ] result = self.read_query(query=query, data=data)[0][0] if result: accrued_fee += self._currency_converter.convert_currency_from_api( value=float(result), from_currency=currency, to_currency=cash_currency) PrinterUtils.console_log( message=f'Query Executed: Get Accrued Account Fees') return float(accrued_fee)
def __init_cache(self, initial_value: float, account_bid_price: float, account_ask_price: float): trading_cache.initial_value = initial_value trading_cache.cash_value = initial_value trading_cache.interest = self._configs.interest trading_cache.account_bid_price = account_bid_price trading_cache.account_ask_price = account_ask_price trading_cache.sell_quantity = initial_value / ( (1 - TradeBotUtils.get_exchange_fee(self._configs.exchange)) * (account_ask_price / (1 + self._configs.interest)) ) if not account_ask_price == 0 else 0 trading_cache.exchange_fee = TradeBotUtils.get_exchange_fee( self._configs.exchange) trading_cache.accrued_fee = 0 trading_cache.successful_trades = 0 trading_cache.successful_cycles = 0
def run(self): start_time = datetime.now() PrinterUtils.console_log( message= f"Started trading at {start_time} and will ended at {self.__run_stop_time}" ) delta_minutes = start_time while not TradeBotUtils.is_run_time_passed( current_time=datetime.now(), run_stop_time=self.__run_stop_time): delta_minutes = self.__print_trading_data(delta_minutes) try: if self.__trade_bot.is_account_order_matching_market_order(): order_id = self.__trade_bot.execute_order() if self.__trade_bot.is_order_executed(order_id): self.__trade_bot.run_post_trade_tasks(order_id) self.__switch_trader() except (websockets.exceptions.ConnectionClosedError, websockets.exceptions.ConnectionClosedOK, websockets.exceptions.InvalidStatusCode) as e: self.__reconnect_websocket() PrinterUtils.console_log( message= f"Started trading at {start_time} and ended at {datetime.now()}")
def __save_report(self, fig1: Figure, fig2: Figure): with open( TradeBotUtils.get_generated_file_path( f"{self.__exchange.lower()}_trade_report.html"), 'w+') as f: f.write(fig1.to_html(full_html=False, include_plotlyjs='cdn')) f.write(fig2.to_html(full_html=False, include_plotlyjs='cdn'))
def __log_trading_data(self, is_buy: bool, headers: list, output: list): headers[1] = "Account Trade Price" headers[2] = "Market Trade Price" headers.insert(1, "Is Buy") output.insert(1, is_buy) PrinterUtils.log_data( headers=headers, output=output, file_path=TradeBotUtils.get_generated_file_path( f"{self.__exchange_name.lower()}_trading_data_log.csv"))
def __get_exchange_api(self) -> ExchangeApi: PrinterUtils.console_log(message=f"Exchange {self._configs.exchange} Api is being used for trading {self._configs.crypto_currency}" f" in {self._configs.cash_currency} with interest: {self._configs.interest * 100}%") if self._configs.exchange == 'bitstamp': exchange_api = BitstampApi(cash_currency=self._configs.cash_currency, crypto_currency=self._configs.crypto_currency, customer_id=TradeBotUtils.get_bitstamp_customer_id(), api_key=TradeBotUtils.get_bitstamp_api_key(), api_secret=TradeBotUtils.get_bitstamp_api_secret()) else: exchange_api = KrakenApi(cash_currency=self._configs.cash_currency, crypto_currency=self._configs.crypto_currency, api_key=TradeBotUtils.get_kraken_api_key(), api_secret=TradeBotUtils.get_kraken_api_secret()) if self._configs.init_database_from_exchange: exchange_api.init_trades_to_database_from_exchange(database_service=self._database_service) return exchange_api
def __init__(self, exchange: str, cash_currency: str, crypto_currency: str, database_service: DatabaseService, is_live: bool, initial_value: float): self.__exchange = exchange self.__cash_currency = cash_currency self.__crypto_currency = crypto_currency self.__database_service = database_service self.__is_live = is_live self.__initial_value = initial_value self.__currency_symbols = TradeBotUtils.get_cash_currency_symbols() self.__subplot_rows = 3 self.__subplot_columns = 1
def __init__(self, is_live: bool, exchange_name: str, database_service: DatabaseService, cash_currency: str, crypto_currency: str): self.__is_live = is_live self.__exchange_name = exchange_name self.__database_service = database_service self.__cash_currency = cash_currency self.__crypto_currency = crypto_currency self.__email_handler = EmailHandler() self.__plot_handler = PlotHandler(exchange_name, cash_currency, crypto_currency, database_service, is_live, trading_cache.initial_value) self.__currency_symbols = TradeBotUtils.get_cash_currency_symbols()
def __init_cache(self, initial_value: float, exchange_api: ExchangeApi, account_bid_price: float, account_ask_price: float): trading_cache.initial_value = initial_value trading_cache.cash_value = exchange_api.get_account_cash_value() trading_cache.interest = self._configs.interest trading_cache.account_bid_price = account_bid_price trading_cache.account_ask_price = account_ask_price trading_cache.sell_quantity = exchange_api.get_account_quantity() trading_cache.exchange_fee = TradeBotUtils.get_exchange_fee(self._configs.exchange) trading_cache.accrued_fee = self._database_service.get_accrued_account_fees(self._configs.exchange, self._configs.cash_currency, self._configs.crypto_currency, self._configs.is_live) trading_cache.successful_trades = self._database_service.get_nr_successful_trades(self._configs.exchange, self._configs.crypto_currency, self._configs.is_live) trading_cache.successful_cycles = self._database_service.get_nr_successful_cycles(self._configs.exchange, self._configs.crypto_currency, self._configs.is_live)
def __init__(self): with open(TradeBotUtils.get_config_file_path("strategy-configs.yaml"), "r") as f: volatility_configs = yaml.safe_load(f) self.__is_sell = volatility_configs['volatility']['is_sell']['custom'] \ if volatility_configs['volatility']['is_sell']['custom'] \ else volatility_configs['volatility']['is_sell']['default'] self.__is_reset_logs = volatility_configs['volatility']['is_reset_logs']['custom'] \ if volatility_configs['volatility']['is_reset_logs']['custom'] \ else volatility_configs['volatility']['is_reset_logs']['default'] self.__init_database_from_exchange = volatility_configs['volatility']['init_database_from_exchange']['custom'] \ if volatility_configs['volatility']['init_database_from_exchange']['custom'] \ else volatility_configs['volatility']['init_database_from_exchange']['default'] self.__reset_database = volatility_configs['volatility']['reset_database']['custom'] \ if volatility_configs['volatility']['reset_database']['custom'] \ else volatility_configs['volatility']['reset_database']['default'] self.__is_live = volatility_configs['volatility']['is_live']['custom'] \ if volatility_configs['volatility']['is_live']['custom'] \ else volatility_configs['volatility']['is_live']['default'] self.__override_initial_value = volatility_configs['volatility'][ 'override_initial_value']['custom'] self.__print_interval = volatility_configs['volatility']['print_interval']['custom'] \ if volatility_configs['volatility']['print_interval']['custom'] else \ volatility_configs['volatility']['print_interval']['default'] self.__interest = volatility_configs['volatility']['interest']['custom'] \ if volatility_configs['volatility']['interest']['custom'] \ else volatility_configs['volatility']['interest']['default'] self.__exchange = volatility_configs['volatility']['exchange']['custom'] \ if volatility_configs['volatility']['exchange']['custom'] \ else volatility_configs['volatility']['exchange']['default'] self.__cash_currency = volatility_configs['volatility']['cash_currency']['custom'] \ if volatility_configs['volatility']['cash_currency']['custom'] \ else volatility_configs['volatility']['cash_currency']['default'] self.__crypto_currency = volatility_configs['volatility']['crypto_currency']['custom'] \ if volatility_configs['volatility']['crypto_currency']['custom'] \ else volatility_configs['volatility']['crypto_currency']['default'] self.validate_configs()
def __get_initial_value(self, exchange_websocket: ExchangeWebsocket, exchange_api: ExchangeApi) -> float: if self._configs.override_initial_value: self._database_service.insert_or_update_initial_account_value(self._configs.exchange, self._configs.is_live, self._configs.override_initial_value, self._configs.cash_currency) return self._configs.override_initial_value initial_value = self._database_service.get_initial_account_value(self._configs.exchange, self._configs.is_live, self._configs.cash_currency) if initial_value == 0: initial_value = exchange_api.get_account_cash_value() + ( exchange_api.get_account_quantity() * exchange_websocket.get_market_bid_price()) * ( 1 - TradeBotUtils.get_exchange_fee(self._configs.exchange)) self._database_service.insert_or_update_initial_account_value(self._configs.exchange, self._configs.is_live, initial_value, self._configs.cash_currency) return initial_value
def print_and_store_trade_report(self, is_buy: bool, fee: float, order_id: str): if is_buy: value = trading_cache.cash_value quantity = trading_cache.buy_quantity price = trading_cache.market_ask_price else: value = trading_cache.gross_position_value quantity = trading_cache.sell_quantity price = trading_cache.market_bid_price headers = [ 'Timestamp', 'is_live', 'exchanges', 'Trade Number', 'Is Buy', f'Price [{self.__currency_symbols[self.__cash_currency]}]', f'Quantity {self.__crypto_currency.upper()}', f'Gross Trade Value [{self.__currency_symbols[self.__cash_currency]}]', f'Net Trade Value [{self.__currency_symbols[self.__cash_currency]}]', f'Fee [{self.__currency_symbols[self.__cash_currency]}]' ] output = [ datetime.now(), self.__is_live, self.__exchange_name, trading_cache.successful_trades, is_buy, price, quantity, value, value - fee, fee ] PrinterUtils.print_data_as_tabulate(headers, output) PrinterUtils.log_data( headers=headers, output=output, file_path=TradeBotUtils.get_generated_file_path( f"{self.__exchange_name.lower()}_successful_trade_log.csv")) self.__database_service.insert_trade_report( order_id=order_id, is_live=self.__is_live, exchange=self.__exchange_name, trade_number=trading_cache.successful_trades, timestamp=datetime.now(), buy=is_buy, price=price, quantity=quantity, cash_currency=self.__cash_currency, crypto_currency=self.__crypto_currency, gross_trade_value=value, net_trade_value=value - fee, fee=fee)
def get_transaction_timestamp(self, transaction: dict) -> datetime: return TradeBotUtils.convert_epoch_time_to_timestamp( transaction['closetm'])
def __init__(self): self.__email_source = TradeBotUtils.get_email_source() self.__email_source_password = TradeBotUtils.get_email_source_password( ) self.__email_target = TradeBotUtils.get_email_target()