def __init__(self, input_handler: Callable, bindings: KeyBindings, completer: Completer): self.search_field = create_search_field() self.input_field = create_input_field(completer=completer) self.output_field = create_output_field() self.log_field = create_log_field(self.search_field) self.timer = create_timer() self.process_usage = create_process_monitor() self.trade_monitor = create_trade_monitor() self.layout = generate_layout(self.input_field, self.output_field, self.log_field, self.search_field, self.timer, self.process_usage, self.trade_monitor) # add self.to_stop_config to know if cancel is triggered self.to_stop_config: bool = False self.live_updates = False self.bindings = bindings self.input_handler = input_handler self.input_field.accept_handler = self.accept self.app: Optional[Application] = None # settings self.prompt_text = ">>> " self.pending_input = None self.input_event = None self.hide_input = False # start ui tasks loop = asyncio.get_event_loop() loop.create_task(start_timer(self.timer)) loop.create_task(start_process_monitor(self.process_usage)) loop.create_task(start_trade_monitor(self.trade_monitor))
def test_start_trade_monitor_loop_continues_on_failure(self, mock_hb_app, mock_sleep): mock_result = MagicMock() mock_app = mock_hb_app.main_application() mock_app.strategy_task.done.side_effect = [RuntimeError(), asyncio.CancelledError()] with self.assertRaises(asyncio.CancelledError): self.async_run_with_timeout(start_trade_monitor(mock_result)) self.assertEqual(2, mock_app.strategy_task.done.call_count) # was called again after exception
def test_sstart_trade_monitor_multi_pairs_diff_quotes( self, mock_hb_app, mock_perf, mock_sleep): mock_result = MagicMock() mock_app = mock_hb_app.main_application() mock_app.strategy_task.done.return_value = False mock_app.markets.return_values = {"a": MagicMock(ready=True)} mock_app._get_trades_from_session.return_value = [ MagicMock(market="ExchangeA", symbol="HBOT-USDT"), MagicMock(market="ExchangeA", symbol="HBOT-BTC") ] mock_app.get_current_balances = AsyncMock() mock_perf.side_effect = [ MagicMock(return_pct=Decimal("0.01"), total_pnl=Decimal("2")), MagicMock(return_pct=Decimal("0.02"), total_pnl=Decimal("3")) ] mock_sleep.side_effect = Exception("returns") with self.assertRaises(Exception) as context: asyncio.get_event_loop().run_until_complete( start_trade_monitor(mock_result)) self.assertEqual('returns', str(context.exception)) self.assertEqual(2, mock_result.log.call_count) self.assertEqual('Trades: 0, Total P&L: 0.00, Return %: 0.00%', mock_result.log.call_args_list[0].args[0]) self.assertEqual('Trades: 2, Total P&L: N/A, Return %: 1.50%', mock_result.log.call_args_list[1].args[0])
def test_start_trade_monitor_market_not_ready(self, mock_hb_app, mock_sleep): mock_result = MagicMock() mock_app = mock_hb_app.main_application() mock_app.strategy_task.done.return_value = False mock_app.markets.return_values = {"a": MagicMock(ready=False)} mock_sleep.side_effect = asyncio.CancelledError() with self.assertRaises(asyncio.CancelledError): self.async_run_with_timeout(start_trade_monitor(mock_result)) self.assertEqual(1, mock_result.log.call_count) self.assertEqual('Trades: 0, Total P&L: 0.00, Return %: 0.00%', mock_result.log.call_args_list[0].args[0])
def test_start_trade_monitor_market_not_ready(self, mock_hb_app, mock_sleep): mock_result = MagicMock() mock_app = mock_hb_app.main_application() mock_app.strategy_task.done.return_value = False mock_app.markets.return_values = {"a": MagicMock(ready=False)} mock_sleep.side_effect = Exception("returns") with self.assertRaises(Exception) as context: asyncio.get_event_loop().run_until_complete( start_trade_monitor(mock_result)) self.assertEqual('returns', str(context.exception)) self.assertEqual(1, mock_result.log.call_count) self.assertEqual('Trades: 0, Total P&L: 0.00, Return %: 0.00%', mock_result.log.call_args_list[0].args[0])
def test_start_trade_monitor_multi_loops(self, mock_hb_app, mock_perf, mock_sleep): mock_result = MagicMock() mock_app = mock_hb_app.main_application() mock_app.strategy_task.done.return_value = False mock_app.markets.return_values = {"a": MagicMock(ready=True)} mock_app._get_trades_from_session.return_value = [MagicMock(market="ExchangeA", symbol="HBOT-USDT")] mock_app.get_current_balances = AsyncMock() mock_perf.side_effect = [MagicMock(return_pct=Decimal("0.01"), total_pnl=Decimal("2")), MagicMock(return_pct=Decimal("0.02"), total_pnl=Decimal("2"))] mock_sleep.side_effect = [None, asyncio.CancelledError()] with self.assertRaises(asyncio.CancelledError): self.async_run_with_timeout(start_trade_monitor(mock_result)) self.assertEqual(3, mock_result.log.call_count) self.assertEqual('Trades: 0, Total P&L: 0.00, Return %: 0.00%', mock_result.log.call_args_list[0].args[0]) self.assertEqual('Trades: 1, Total P&L: 2.00 USDT, Return %: 1.00%', mock_result.log.call_args_list[1].args[0]) self.assertEqual('Trades: 1, Total P&L: 2.00 USDT, Return %: 2.00%', mock_result.log.call_args_list[2].args[0])
def __init__(self, client_config_map: ClientConfigAdapter, input_handler: Callable, bindings: KeyBindings, completer: Completer, command_tabs: Dict[str, CommandTab]): super().__init__() self.client_config_map: Union[ClientConfigAdapter, ClientConfigMap] = client_config_map self.command_tabs = command_tabs self.search_field = create_search_field() self.input_field = create_input_field(completer=completer) self.output_field = create_output_field(client_config_map) self.log_field = create_log_field(self.search_field) self.right_pane_toggle = create_log_toggle(self.toggle_right_pane) self.live_field = create_live_field() self.log_field_button = create_tab_button("Log-pane", self.log_button_clicked) self.timer = create_timer() self.process_usage = create_process_monitor() self.trade_monitor = create_trade_monitor() self.layout, self.layout_components = generate_layout( self.input_field, self.output_field, self.log_field, self.right_pane_toggle, self.log_field_button, self.search_field, self.timer, self.process_usage, self.trade_monitor, self.command_tabs) # add self.to_stop_config to know if cancel is triggered self.to_stop_config: bool = False self.live_updates = False self.bindings = bindings self.input_handler = input_handler self.input_field.accept_handler = self.accept self.app: Optional[Application] = None # settings self.prompt_text = ">>> " self.pending_input = None self.input_event = None self.hide_input = False # stdout redirection stack self._stdout_redirect_context: ExitStack = ExitStack() # start ui tasks loop = asyncio.get_event_loop() loop.create_task(start_timer(self.timer)) loop.create_task(start_process_monitor(self.process_usage)) loop.create_task(start_trade_monitor(self.trade_monitor))
def __init__(self, input_handler: Callable, bindings: KeyBindings, completer: Completer): self.search_field = create_search_field() self.input_field = create_input_field(completer=completer) self.output_field = create_output_field() self.log_field = create_log_field(self.search_field) self.timer = create_timer() self.process_usage = create_process_monitor() self.trade_monitor = create_trade_monitor() self.layout = generate_layout(self.input_field, self.output_field, self.log_field, self.search_field, self.timer, self.process_usage, self.trade_monitor) # add self.to_stop_config to know if cancel is triggered self.to_stop_config: bool = False self.live_updates = False self.bindings = bindings self.input_handler = input_handler self.input_field.accept_handler = self.accept self.app = Application(layout=self.layout, full_screen=True, key_bindings=self.bindings, style=load_style(), mouse_support=True, clipboard=PyperclipClipboard()) # settings self.prompt_text = ">>> " self.pending_input = None self.input_event = None self.hide_input = False # start ui tasks loop = asyncio.get_event_loop() loop.create_task(start_timer(self.timer)) loop.create_task(start_process_monitor(self.process_usage)) loop.create_task(start_trade_monitor(self.trade_monitor))