pybinbot 2.0.0__tar.gz → 2.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. {pybinbot-2.0.0/pybinbot.egg-info → pybinbot-2.1.1}/PKG-INFO +7 -7
  2. {pybinbot-2.0.0 → pybinbot-2.1.1}/README.md +4 -4
  3. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/__init__.py +2 -24
  4. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/apis/kucoin/rest.py +1 -1
  5. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/models/bot_base.py +31 -1
  6. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/shared/candles.py +2 -2
  7. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/shared/enums.py +5 -0
  8. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/shared/maths.py +1 -1
  9. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/streaming/binance/socket_manager.py +3 -3
  10. {pybinbot-2.0.0 → pybinbot-2.1.1/pybinbot.egg-info}/PKG-INFO +7 -7
  11. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot.egg-info/SOURCES.txt +1 -0
  12. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot.egg-info/requires.txt +1 -1
  13. {pybinbot-2.0.0 → pybinbot-2.1.1}/pyproject.toml +3 -3
  14. pybinbot-2.1.1/tests/test_conditional_entry.py +45 -0
  15. {pybinbot-2.0.0 → pybinbot-2.1.1}/LICENSE +0 -0
  16. {pybinbot-2.0.0 → pybinbot-2.1.1}/MANIFEST.in +0 -0
  17. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/apis/binance/base.py +0 -0
  18. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/apis/binance/exceptions.py +0 -0
  19. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/apis/binbot/base.py +0 -0
  20. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/apis/binbot/exceptions.py +0 -0
  21. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/apis/coingecko.py +0 -0
  22. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/apis/kucoin/base.py +0 -0
  23. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/apis/kucoin/exceptions.py +0 -0
  24. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/apis/kucoin/futures.py +0 -0
  25. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/apis/kucoin/market.py +0 -0
  26. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/apis/kucoin/orders.py +0 -0
  27. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/models/__init__.py +0 -0
  28. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/models/autotrade_settings.py +0 -0
  29. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/models/bot.py +0 -0
  30. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/models/deal.py +0 -0
  31. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/models/derivatives.py +0 -0
  32. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/models/grid_ladder.py +0 -0
  33. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/models/order.py +0 -0
  34. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/models/routes.py +0 -0
  35. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/models/signals.py +0 -0
  36. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/models/symbol.py +0 -0
  37. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/py.typed +0 -0
  38. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/shared/__init__.py +0 -0
  39. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/shared/beta.py +0 -0
  40. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/shared/breadth.py +0 -0
  41. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/shared/cache.py +0 -0
  42. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/shared/handlers.py +0 -0
  43. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/shared/heikin_ashi.py +0 -0
  44. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/shared/indicators.py +0 -0
  45. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/shared/logging_config.py +0 -0
  46. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/shared/price_crossings.py +0 -0
  47. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/shared/telegram_delivery.py +0 -0
  48. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/shared/timestamps.py +0 -0
  49. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/shared/types.py +0 -0
  50. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/shared/utils.py +0 -0
  51. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/streaming/binance/async_socket_client.py +0 -0
  52. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/streaming/binance/socket_client.py +0 -0
  53. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot/streaming/kucoin/kucoin_async_client.py +0 -0
  54. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot.egg-info/dependency_links.txt +0 -0
  55. {pybinbot-2.0.0 → pybinbot-2.1.1}/pybinbot.egg-info/top_level.txt +0 -0
  56. {pybinbot-2.0.0 → pybinbot-2.1.1}/setup.cfg +0 -0
  57. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_beta.py +0 -0
  58. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_binbot_api.py +0 -0
  59. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_bot_futures_leverage.py +0 -0
  60. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_breadth.py +0 -0
  61. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_candles.py +0 -0
  62. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_coingecko.py +0 -0
  63. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_conditional_futures_orders.py +0 -0
  64. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_deal_model.py +0 -0
  65. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_derivatives_api.py +0 -0
  66. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_futures_place_order.py +0 -0
  67. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_grid_ladder.py +0 -0
  68. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_handlers.py +0 -0
  69. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_heikin_ashi.py +0 -0
  70. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_indicators.py +0 -0
  71. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_kucoin_api.py +0 -0
  72. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_logging_config.py +0 -0
  73. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_matching_engine.py +0 -0
  74. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_maths.py +0 -0
  75. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_price_crossings.py +0 -0
  76. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_symbol_model.py +0 -0
  77. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_telegram_delivery.py +0 -0
  78. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_timestamps.py +0 -0
  79. {pybinbot-2.0.0 → pybinbot-2.1.1}/tests/test_utils.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pybinbot
3
- Version: 2.0.0
3
+ Version: 2.1.1
4
4
  Summary: Utility functions for the binbot project.
5
5
  Author-email: Carlos Wu <carkodw@gmail.com>
6
- Requires-Python: >=3.12
6
+ Requires-Python: >=3.15
7
7
  Description-Content-Type: text/markdown
8
8
  License-File: LICENSE
9
9
  Requires-Dist: pydantic[email]>=2.0.0
@@ -11,7 +11,7 @@ Requires-Dist: numpy==2.5.4
11
11
  Requires-Dist: pandas==3.1.1
12
12
  Requires-Dist: pandas-stubs==3.1.0.261029
13
13
  Requires-Dist: requests>=2.32.5
14
- Requires-Dist: kucoin-universal-sdk>=1.3.0
14
+ Requires-Dist: kucoin-universal-sdk>=1.3.2
15
15
  Requires-Dist: aiohttp<3.15,>=3.14.1
16
16
  Requires-Dist: websocket-client>=1.9.0
17
17
  Requires-Dist: python-dotenv>=1.2.1
@@ -37,12 +37,12 @@ This module re-exports the internal ``shared`` and ``models`` packages and the m
37
37
 
38
38
  from pybinbot import round_numbers, ExchangeId
39
39
 
40
- Python 3.12 or newer is required. Pandas and NumPy versions are pinned in
41
- pybinbot so applications using the same pybinbot release share the same numerical
42
- dependencies. Consumers can import the modules or commonly used types and functions:
40
+ Python 3.15 or newer is required. Pandas and NumPy use matching version pins in
41
+ pybinbot, binbot, and binquant. Import these libraries directly:
43
42
 
44
43
  ```python
45
- from pybinbot import DataFrame, Series, numpy as np, pandas as pd
44
+ import numpy as np
45
+ import pandas as pd
46
46
  ```
47
47
 
48
48
 
@@ -8,12 +8,12 @@ This module re-exports the internal ``shared`` and ``models`` packages and the m
8
8
 
9
9
  from pybinbot import round_numbers, ExchangeId
10
10
 
11
- Python 3.12 or newer is required. Pandas and NumPy versions are pinned in
12
- pybinbot so applications using the same pybinbot release share the same numerical
13
- dependencies. Consumers can import the modules or commonly used types and functions:
11
+ Python 3.15 or newer is required. Pandas and NumPy use matching version pins in
12
+ pybinbot, binbot, and binquant. Import these libraries directly:
14
13
 
15
14
  ```python
16
- from pybinbot import DataFrame, Series, numpy as np, pandas as pd
15
+ import numpy as np
16
+ import pandas as pd
17
17
  ```
18
18
 
19
19
 
@@ -5,18 +5,6 @@ models, while still allowing access to the structured subpackages via
5
5
  ``pybinbot.shared`` and ``pybinbot.models``.
6
6
  """
7
7
 
8
- import numpy as numpy
9
- import pandas as pandas
10
- from numpy import isnan as isnan, log as log, nan as nan
11
- from pandas import (
12
- DataFrame as DataFrame,
13
- Series as Series,
14
- concat as concat,
15
- to_datetime as to_datetime,
16
- to_numeric as to_numeric,
17
- )
18
- from pandas.api.types import is_numeric_dtype as is_numeric_dtype
19
-
20
8
  from pybinbot.shared.maths import (
21
9
  STOP_LIMIT_OFFSET_RATIO,
22
10
  ceil_price_to_tick,
@@ -50,6 +38,7 @@ from pybinbot.shared.enums import (
50
38
  BinanceOrderModel,
51
39
  CloseConditions,
52
40
  DealType,
41
+ EntryMode,
53
42
  ExchangeId,
54
43
  KucoinKlineIntervals,
55
44
  MarketDominance,
@@ -185,18 +174,6 @@ from . import models, shared, apis
185
174
  configure_logging()
186
175
 
187
176
  __all__ = [
188
- # Numerical dependencies shared by binbot and binquant.
189
- "numpy",
190
- "pandas",
191
- "DataFrame",
192
- "Series",
193
- "concat",
194
- "to_datetime",
195
- "to_numeric",
196
- "is_numeric_dtype",
197
- "isnan",
198
- "log",
199
- "nan",
200
177
  "BinanceFundingRate",
201
178
  "BinanceFundingRatesResponse",
202
179
  "FundingRateHistoryPoint",
@@ -306,6 +283,7 @@ __all__ = [
306
283
  # enums
307
284
  "CloseConditions",
308
285
  "DealType",
286
+ "EntryMode",
309
287
  "BinanceOrderModel",
310
288
  "Status",
311
289
  "Position",
@@ -27,7 +27,7 @@ class KucoinRest:
27
27
  """Log a warning or briefly sleep when the KuCoin rate-limit bucket runs low."""
28
28
  try:
29
29
  remaining_int = int(remaining)
30
- except (TypeError, ValueError):
30
+ except TypeError, ValueError:
31
31
  return
32
32
  if remaining_int < 0:
33
33
  return
@@ -1,11 +1,12 @@
1
1
  from typing import Literal
2
2
  from uuid import UUID
3
3
 
4
- from pydantic import BaseModel, Field, field_validator, model_validator
4
+ from pydantic import BaseModel, Field, ValidationInfo, field_validator, model_validator
5
5
 
6
6
  from pybinbot.shared.enums import (
7
7
  BinanceKlineIntervals,
8
8
  CloseConditions,
9
+ EntryMode,
9
10
  MarketType,
10
11
  Position,
11
12
  QuoteAssets,
@@ -46,6 +47,14 @@ class BotBase(BaseModel):
46
47
  )
47
48
  created_at: float = Field(default_factory=timestamp)
48
49
  updated_at: float = Field(default_factory=timestamp)
50
+ entry_mode: EntryMode = Field(default=EntryMode.immediate, validate_default=True)
51
+ entry_price: float | None = Field(default=None, ge=0, allow_inf_nan=False)
52
+ entry_expires_at: float = Field(
53
+ default_factory=lambda data: data["created_at"] + 6 * 60 * 60 * 1000,
54
+ gt=0,
55
+ allow_inf_nan=False,
56
+ description="Absolute entry deadline in Unix milliseconds; defaults to creation + 6 hours",
57
+ )
49
58
  dynamic_trailing: bool = Field(default=False)
50
59
  dynamic_position_sizing: bool = Field(default=False)
51
60
  logs: list = Field(default=[])
@@ -104,6 +113,27 @@ class BotBase(BaseModel):
104
113
  },
105
114
  }
106
115
 
116
+ @field_validator("entry_mode", mode="before")
117
+ @classmethod
118
+ def default_entry_mode(cls, value):
119
+ return EntryMode.immediate if value is None else value
120
+
121
+ @field_validator("entry_expires_at", mode="before")
122
+ @classmethod
123
+ def default_entry_expiry(cls, value, info: ValidationInfo):
124
+ return info.data["created_at"] + 6 * 60 * 60 * 1000 if value is None else value
125
+
126
+ @model_validator(mode="after")
127
+ def validate_conditional_entry(self):
128
+ if self.entry_mode == EntryMode.conditional_limit:
129
+ if self.entry_price is None or self.entry_price <= 0:
130
+ raise ValueError(
131
+ "Conditional limit entry requires a positive entry_price"
132
+ )
133
+ if self.market_type != MarketType.FUTURES:
134
+ raise ValueError("Conditional limit entry currently requires futures")
135
+ return self
136
+
107
137
  @model_validator(mode="after")
108
138
  def validate_dynamic_position_sizing(self):
109
139
  if self.dynamic_position_sizing:
@@ -126,7 +126,7 @@ class Candles:
126
126
  continue
127
127
  try:
128
128
  open_time = float(open_time_value)
129
- except (TypeError, ValueError):
129
+ except TypeError, ValueError:
130
130
  continue
131
131
  if not isfinite(open_time):
132
132
  continue
@@ -140,7 +140,7 @@ class Candles:
140
140
  continue
141
141
  try:
142
142
  close_time = float(close_time_value)
143
- except (TypeError, ValueError):
143
+ except TypeError, ValueError:
144
144
  continue
145
145
  if not isfinite(close_time):
146
146
  continue
@@ -60,6 +60,11 @@ class Status(str, Enum):
60
60
  error = "error"
61
61
 
62
62
 
63
+ class EntryMode(str, Enum):
64
+ immediate = "immediate"
65
+ conditional_limit = "conditional_limit"
66
+
67
+
63
68
  class Position(str, Enum):
64
69
  long = "long"
65
70
  short = "short"
@@ -14,7 +14,7 @@ STOP_LIMIT_OFFSET_RATIO = 0.005 # 0.5% of the stop price
14
14
  def coerce_number(value: Any) -> float | None:
15
15
  try:
16
16
  parsed = float(value)
17
- except (TypeError, ValueError):
17
+ except TypeError, ValueError:
18
18
  return None
19
19
  if not math.isfinite(parsed):
20
20
  return None
@@ -1,7 +1,7 @@
1
1
  import json
2
2
  import logging
3
- import threading
4
3
  import time
4
+ from threading import Thread
5
5
 
6
6
  from websocket import (
7
7
  ABNF,
@@ -11,7 +11,7 @@ from websocket import (
11
11
  )
12
12
 
13
13
 
14
- class BinanceSocketManager(threading.Thread):
14
+ class BinanceSocketManager(Thread):
15
15
  def __init__(
16
16
  self,
17
17
  stream_url,
@@ -23,7 +23,7 @@ class BinanceSocketManager(threading.Thread):
23
23
  on_pong=None,
24
24
  logger=None,
25
25
  ):
26
- threading.Thread.__init__(self)
26
+ Thread.__init__(self)
27
27
  if not logger:
28
28
  logger = logging.getLogger(__name__)
29
29
  self.logger = logger
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pybinbot
3
- Version: 2.0.0
3
+ Version: 2.1.1
4
4
  Summary: Utility functions for the binbot project.
5
5
  Author-email: Carlos Wu <carkodw@gmail.com>
6
- Requires-Python: >=3.12
6
+ Requires-Python: >=3.15
7
7
  Description-Content-Type: text/markdown
8
8
  License-File: LICENSE
9
9
  Requires-Dist: pydantic[email]>=2.0.0
@@ -11,7 +11,7 @@ Requires-Dist: numpy==2.5.4
11
11
  Requires-Dist: pandas==3.1.1
12
12
  Requires-Dist: pandas-stubs==3.1.0.261029
13
13
  Requires-Dist: requests>=2.32.5
14
- Requires-Dist: kucoin-universal-sdk>=1.3.0
14
+ Requires-Dist: kucoin-universal-sdk>=1.3.2
15
15
  Requires-Dist: aiohttp<3.15,>=3.14.1
16
16
  Requires-Dist: websocket-client>=1.9.0
17
17
  Requires-Dist: python-dotenv>=1.2.1
@@ -37,12 +37,12 @@ This module re-exports the internal ``shared`` and ``models`` packages and the m
37
37
 
38
38
  from pybinbot import round_numbers, ExchangeId
39
39
 
40
- Python 3.12 or newer is required. Pandas and NumPy versions are pinned in
41
- pybinbot so applications using the same pybinbot release share the same numerical
42
- dependencies. Consumers can import the modules or commonly used types and functions:
40
+ Python 3.15 or newer is required. Pandas and NumPy use matching version pins in
41
+ pybinbot, binbot, and binquant. Import these libraries directly:
43
42
 
44
43
  ```python
45
- from pybinbot import DataFrame, Series, numpy as np, pandas as pd
44
+ import numpy as np
45
+ import pandas as pd
46
46
  ```
47
47
 
48
48
 
@@ -57,6 +57,7 @@ tests/test_bot_futures_leverage.py
57
57
  tests/test_breadth.py
58
58
  tests/test_candles.py
59
59
  tests/test_coingecko.py
60
+ tests/test_conditional_entry.py
60
61
  tests/test_conditional_futures_orders.py
61
62
  tests/test_deal_model.py
62
63
  tests/test_derivatives_api.py
@@ -3,7 +3,7 @@ numpy==2.5.4
3
3
  pandas==3.1.1
4
4
  pandas-stubs==3.1.0.261029
5
5
  requests>=2.32.5
6
- kucoin-universal-sdk>=1.3.0
6
+ kucoin-universal-sdk>=1.3.2
7
7
  aiohttp<3.15,>=3.14.1
8
8
  websocket-client>=1.9.0
9
9
  python-dotenv>=1.2.1
@@ -22,20 +22,20 @@ build-backend = "setuptools.build_meta"
22
22
 
23
23
  [project]
24
24
  name = "pybinbot"
25
- version = "2.0.0"
25
+ version = "2.1.1"
26
26
  description = "Utility functions for the binbot project."
27
27
  authors = [
28
28
  { name="Carlos Wu", email="carkodw@gmail.com" }
29
29
  ]
30
30
  readme = "README.md"
31
- requires-python = ">=3.12"
31
+ requires-python = ">=3.15"
32
32
  dependencies = [
33
33
  "pydantic[email]>=2.0.0",
34
34
  "numpy==2.5.4",
35
35
  "pandas==3.1.1",
36
36
  "pandas-stubs==3.1.0.261029",
37
37
  "requests>=2.32.5",
38
- "kucoin-universal-sdk>=1.3.0",
38
+ "kucoin-universal-sdk>=1.3.2",
39
39
  "aiohttp>=3.14.1,<3.15",
40
40
  "websocket-client>=1.9.0",
41
41
  "python-dotenv>=1.2.1",
@@ -0,0 +1,45 @@
1
+ import pytest
2
+ from pydantic import ValidationError
3
+
4
+ from pybinbot import BotBase, EntryMode, MarketType
5
+
6
+
7
+ @pytest.mark.parametrize(
8
+ "overrides",
9
+ [{}, {"entry_mode": None, "entry_expires_at": None, "entry_price": None}],
10
+ )
11
+ def test_omitted_or_null_entry_fields_default_to_immediate_and_six_hours(overrides):
12
+ bot = BotBase(pair="XBTUSDTM", created_at=1000, **overrides)
13
+ assert bot.entry_mode == EntryMode.immediate
14
+ assert bot.entry_expires_at == 21_601_000
15
+ assert bot.entry_price is None
16
+ assert bot.model_dump(mode="json")["entry_price"] is None
17
+
18
+
19
+ def test_conditional_entry_serializes_strings_and_preserves_deadline():
20
+ bot = BotBase(
21
+ pair="XBTUSDTM",
22
+ market_type=MarketType.FUTURES,
23
+ entry_mode="conditional_limit",
24
+ entry_price=100,
25
+ entry_expires_at=9000,
26
+ )
27
+ assert bot.model_dump(mode="json")["entry_mode"] == "conditional_limit"
28
+ assert bot.entry_expires_at == 9000
29
+
30
+
31
+ @pytest.mark.parametrize(
32
+ "values",
33
+ [
34
+ {"entry_mode": "unknown"},
35
+ {"entry_mode": "conditional_limit"},
36
+ {"entry_mode": "conditional_limit", "entry_price": None},
37
+ {"entry_mode": "conditional_limit", "entry_price": 0},
38
+ {"entry_mode": "conditional_limit", "entry_price": -1},
39
+ {"entry_mode": "conditional_limit", "entry_price": float("inf")},
40
+ {"entry_expires_at": float("nan")},
41
+ ],
42
+ )
43
+ def test_invalid_entry_configuration_is_rejected(values):
44
+ with pytest.raises(ValidationError):
45
+ BotBase(pair="XBTUSDTM", market_type=MarketType.FUTURES, **values)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes