def _log_global_report(self, exchange_manager): _, profitability, _, market_average_profitability, _ = trading_api.get_profitability_stats( exchange_manager) reference_market = trading_api.get_reference_market( self.backtesting_config) end_portfolio = trading_api.get_portfolio(exchange_manager) end_portfolio_value = trading_api.get_current_portfolio_value( exchange_manager) starting_portfolio = trading_api.get_origin_portfolio(exchange_manager) starting_portfolio_value = trading_api.get_origin_portfolio_value( exchange_manager) self.logger.info( f"[End portfolio] value {round(end_portfolio_value, 5)} {reference_market} " f"Holdings: {pretty_printer.global_portfolio_pretty_print(end_portfolio, ' | ')}" ) self.logger.info( f"[Starting portfolio] value {round(starting_portfolio_value, 5)} {reference_market} " f"Holdings: {pretty_printer.global_portfolio_pretty_print(starting_portfolio, ' | ')}" ) self.logger.info( f"Global market profitability (vs {reference_market}) : " f"{market_average_profitability}% | Octobot : {profitability}%") self.logger.info( f"Simulation lasted " f"{round(backtesting_api.get_backtesting_duration(self.octobot_backtesting.backtesting), 3)} sec" )
async def _handle_order_notification(self, dict_order, linked_notification, order_identifier, exchange_manager, exchange): notification = None order_status = trading_api.parse_order_status(dict_order) if order_status is trading_enums.OrderStatus.OPEN: notification = notifications.OrderCreationNotification(linked_notification, dict_order, exchange) # update last notification for this order self.previous_notifications_by_identifier[order_identifier] = notification else: is_simulated = trading_api.is_trader_simulated(exchange_manager) if order_status is trading_enums.OrderStatus.CANCELED or \ (order_status is trading_enums.OrderStatus.CLOSED and dict_order[trading_enums.ExchangeConstantsOrderColumns.FILLED.value] == 0): notification = notifications.OrderEndNotification(linked_notification, None, exchange, [dict_order], None, None, None, False, is_simulated) elif order_status in (trading_enums.OrderStatus.CLOSED, trading_enums.OrderStatus.FILLED): _, profitability_percent, profitability_diff, _, _ = \ trading_api.get_profitability_stats(exchange_manager) order_profitability = trading_api.get_order_profitability( exchange_manager, dict_order[trading_enums.ExchangeConstantsOrderColumns.ID.value]) notification = notifications.OrderEndNotification(linked_notification, dict_order, exchange, [], order_profitability, profitability_percent, profitability_diff, True, is_simulated) # remove order from previous_notifications_by_identifier: no more notification from it to be received if order_identifier in self.previous_notifications_by_identifier: self.previous_notifications_by_identifier.pop(order_identifier) await self._notification_callback(notification)
def _handle_results(self, independent_backtesting, profitability): trades_count = 0 profitability_result = None skip_this_run = False if independent_backtesting is not None: exchange_manager_ids = octobot_backtesting_api.get_independent_backtesting_exchange_manager_ids( independent_backtesting) try: for exchange_manager in trading_api.get_exchange_managers_from_exchange_ids( exchange_manager_ids): _, profitability, _, market_average_profitability, _ = \ trading_api.get_profitability_stats(exchange_manager) # Only one exchange manager per run profitability_result = (profitability, market_average_profitability) trades_count += len( trading_api.get_trade_history(exchange_manager)) except (AttributeError, KeyError): skip_this_run = True if not skip_this_run: if profitability_result is None: raise RuntimeError( "Error with independent backtesting: no available exchange manager" ) self._profitability_results.append(profitability_result) self._trades_counts.append(trades_count)
def _get_exchanges_report(self, reference_market, trading_mode): SYMBOL_REPORT = "symbol_report" BOT_REPORT = "bot_report" CHART_IDENTIFIERS = "chart_identifiers" ERRORS_COUNT = "errors_count" report = { SYMBOL_REPORT: [], BOT_REPORT: {}, CHART_IDENTIFIERS: [], ERRORS_COUNT: logging.get_backtesting_errors_count() } profitabilities = {} market_average_profitabilities = {} starting_portfolios = {} end_portfolios = {} for exchange_id in self.octobot_backtesting.exchange_manager_ids: exchange_manager = trading_api.get_exchange_manager_from_exchange_id( exchange_id) _, profitability, _, market_average_profitability, _ = trading_api.get_profitability_stats( exchange_manager) min_timeframe = time_frame_manager.find_min_time_frame( trading_api.get_watched_timeframes(exchange_manager)) exchange_name = trading_api.get_exchange_name(exchange_manager) for symbol in self.symbols_to_create_exchange_classes[ exchange_name]: market_delta = self._get_market_delta(symbol, exchange_manager, min_timeframe) report[SYMBOL_REPORT].append({symbol: market_delta * 100}) report[CHART_IDENTIFIERS].append({ "symbol": symbol, "exchange_id": exchange_id, "exchange_name": exchange_name, "time_frame": min_timeframe.value }) profitabilities[exchange_name] = profitability market_average_profitabilities[ exchange_name] = market_average_profitability starting_portfolios[ exchange_name] = trading_api.get_origin_portfolio( exchange_manager) end_portfolios[exchange_name] = trading_api.get_portfolio( exchange_manager) report[BOT_REPORT] = { "profitability": profitabilities, "market_average_profitability": market_average_profitabilities, "reference_market": reference_market, "end_portfolio": end_portfolios, "starting_portfolio": starting_portfolios, "trading_mode": trading_mode } return report
def _handle_results(self, independent_backtesting, profitability): exchange_manager_ids = octobot_api.get_independent_backtesting_exchange_manager_ids( independent_backtesting) for exchange_manager in trading_api.get_exchange_managers_from_exchange_ids( exchange_manager_ids): _, run_profitability, _, market_average_profitability, _ = trading_api.get_profitability_stats( exchange_manager) actual = round(run_profitability, 3) # uncomment this print for building tests # print(f"results: rounded run profitability {actual} market profitability: {market_average_profitability}" # f" expected: {profitability} [result: {actual == profitability}]") assert actual == profitability
def _get_profitability(self): total_origin_values = 0 total_profitability = 0 for exchange_manager in self.exchange_managers: profitability, _, _, _, _ = trading_api.get_profitability_stats( exchange_manager) total_profitability += float(profitability) total_origin_values += float( trading_api.get_current_portfolio_value(exchange_manager)) return total_profitability * 100 / total_origin_values if total_origin_values > 0 else 0
def get_global_profitability(): simulated_global_profitability = 0 real_global_profitability = 0 simulated_no_trade_profitability = 0 real_no_trade_profitability = 0 simulated_full_origin_value = 0 real_full_origin_value = 0 market_average_profitability = None has_real_trader = False has_simulated_trader = False for exchange_manager in interfaces.get_exchange_managers(): if trading_api.is_trader_existing_and_enabled(exchange_manager): current_value, _, _, market_average_profitability, initial_portfolio_current_profitability = \ trading_api.get_profitability_stats(exchange_manager) if trading_api.is_trader_simulated(exchange_manager): simulated_full_origin_value += trading_api.get_origin_portfolio_value( exchange_manager) simulated_global_profitability += current_value simulated_no_trade_profitability += initial_portfolio_current_profitability has_simulated_trader = True else: real_full_origin_value += trading_api.get_origin_portfolio_value( exchange_manager) real_global_profitability += current_value real_no_trade_profitability += initial_portfolio_current_profitability has_real_trader = True simulated_percent_profitability = simulated_global_profitability * 100 / simulated_full_origin_value \ if simulated_full_origin_value > 0 else 0 real_percent_profitability = real_global_profitability * 100 / real_full_origin_value \ if real_full_origin_value > 0 else 0 return has_real_trader, has_simulated_trader, \ real_global_profitability, simulated_global_profitability, \ real_percent_profitability, simulated_percent_profitability, \ real_no_trade_profitability, simulated_no_trade_profitability, \ market_average_profitability