Skip to content

Commit 0b211e2

Browse files
committed
[TradingView] interrupt signal exec on invalid signal value
1 parent afe7fa0 commit 0b211e2

File tree

3 files changed

+35
-16
lines changed

3 files changed

+35
-16
lines changed

Trading/Exchange/binance/binance_exchange.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ async def set_symbol_margin_type(self, symbol: str, isolated: bool, **kwargs: di
241241
:return: the update result
242242
"""
243243
try:
244-
return await super(). set_symbol_margin_type(symbol, isolated, **kwargs)
244+
return await super().set_symbol_margin_type(symbol, isolated, **kwargs)
245245
except ccxt.ExchangeError as err:
246246
raise errors.NotSupported() from err
247247

Trading/Mode/trading_view_signals_trading_mode/tests/test_trading_view_signals_trading.py

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -195,19 +195,20 @@ async def test_trading_view_signal_callback(tools):
195195
context = script_keywords.get_base_context(producer.trading_mode)
196196
with mock.patch.object(script_keywords, "get_base_context", mock.Mock(return_value=context)) \
197197
as get_base_context_mock:
198-
# ensure exception is caught
199-
with mock.patch.object(
200-
producer, "signal_callback", mock.AsyncMock(side_effect=errors.MissingFunds)
201-
) as signal_callback_mock:
202-
signal = f"""
203-
EXCHANGE={exchange_manager.exchange_name}
204-
SYMBOL={symbol}
205-
SIGNAL=BUY
206-
"""
207-
await mode._trading_view_signal_callback({"metadata": signal})
208-
signal_callback_mock.assert_awaited_once()
209-
get_base_context_mock.assert_called_once()
210-
get_base_context_mock.reset_mock()
198+
for exception in (errors.MissingFunds, errors.InvalidArgumentError):
199+
# ensure exception is caught
200+
with mock.patch.object(
201+
producer, "signal_callback", mock.AsyncMock(side_effect=exception)
202+
) as signal_callback_mock:
203+
signal = f"""
204+
EXCHANGE={exchange_manager.exchange_name}
205+
SYMBOL={symbol}
206+
SIGNAL=BUY
207+
"""
208+
await mode._trading_view_signal_callback({"metadata": signal})
209+
signal_callback_mock.assert_awaited_once()
210+
get_base_context_mock.assert_called_once()
211+
get_base_context_mock.reset_mock()
211212

212213
with mock.patch.object(producer, "signal_callback", mock.AsyncMock()) as signal_callback_mock:
213214
# invalid data
@@ -427,6 +428,23 @@ async def test_signal_callback(tools):
427428
}, context)
428429
_set_state_mock.assert_not_called()
429430

431+
with pytest.raises(errors.InvalidArgumentError):
432+
await producer.signal_callback({
433+
mode.EXCHANGE_KEY: exchange_manager.exchange_name,
434+
mode.SYMBOL_KEY: "unused",
435+
mode.SIGNAL_KEY: "DSDSDDSS",
436+
mode.PRICE_KEY: "123000q", # price = 123
437+
mode.VOLUME_KEY: "11111b", # base amount: not enough funds
438+
mode.REDUCE_ONLY_KEY: True,
439+
mode.ORDER_TYPE_SIGNAL: "LiMiT",
440+
mode.STOP_PRICE_KEY: "-10%", # price - 10%
441+
mode.TAKE_PROFIT_PRICE_KEY: "120.333333333333333d", # price + 120.333333333333333
442+
mode.EXCHANGE_ORDER_IDS: ["ab1", "aaaaa"],
443+
"PARAM_TAG_1": "ttt",
444+
"PARAM_Plop": False,
445+
}, context)
446+
_set_state_mock.assert_not_called()
447+
430448

431449
def compare_dict_with_nan(d_1, d_2):
432450
try:

Trading/Mode/trading_view_signals_trading_mode/trading_view_signals_trading.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ async def _trading_view_signal_callback(self, data):
176176
(parsed_data[self.SYMBOL_KEY] == self.merged_simple_symbol or
177177
parsed_data[self.SYMBOL_KEY] == self.str_symbol):
178178
await self.producers[0].signal_callback(parsed_data, script_keywords.get_base_context(self))
179+
except trading_errors.InvalidArgumentError as e:
180+
self.logger.error(f"Error when handling trading view signal: {e}")
179181
except trading_errors.MissingFunds as e:
180182
self.logger.error(f"Error when handling trading view signal: not enough funds: {e}")
181183
except KeyError as e:
@@ -261,10 +263,9 @@ async def _parse_order_details(self, ctx, parsed_data):
261263
elif side == TradingViewSignalsTradingMode.CANCEL_SIGNAL:
262264
state = trading_enums.EvaluatorStates.NEUTRAL
263265
else:
264-
self.logger.error(
266+
raise trading_errors.InvalidArgumentError(
265267
f"Unknown signal: {parsed_data[TradingViewSignalsTradingMode.SIGNAL_KEY]}, full data= {parsed_data}"
266268
)
267-
state = trading_enums.EvaluatorStates.NEUTRAL
268269
target_price = 0 if order_type == TradingViewSignalsTradingMode.MARKET_SIGNAL else (
269270
await self._parse_price(ctx, parsed_data, TradingViewSignalsTradingMode.PRICE_KEY, 0))
270271
stop_price = await self._parse_price(

0 commit comments

Comments
 (0)