walrasquant-lib 0.4.26__tar.gz → 0.4.28__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 (115) hide show
  1. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/PKG-INFO +2 -2
  2. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/pyproject.toml +2 -2
  3. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/base/ems.py +36 -47
  4. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/config.py +8 -0
  5. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/constants.py +1 -0
  6. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/core/nautilius_core.py +5 -2
  7. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/engine.py +1 -0
  8. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/__init__.py +2 -0
  9. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bitget/ems.py +6 -37
  10. walrasquant_lib-0.4.28/src/walrasquant/exchange/deribit/__init__.py +26 -0
  11. walrasquant_lib-0.4.28/src/walrasquant/exchange/deribit/connector.py +439 -0
  12. walrasquant_lib-0.4.28/src/walrasquant/exchange/deribit/constants.py +112 -0
  13. walrasquant_lib-0.4.28/src/walrasquant/exchange/deribit/ems.py +66 -0
  14. walrasquant_lib-0.4.28/src/walrasquant/exchange/deribit/exchange.py +86 -0
  15. walrasquant_lib-0.4.28/src/walrasquant/exchange/deribit/factory.py +101 -0
  16. walrasquant_lib-0.4.28/src/walrasquant/exchange/deribit/oms.py +670 -0
  17. walrasquant_lib-0.4.28/src/walrasquant/exchange/deribit/rest_api.py +106 -0
  18. walrasquant_lib-0.4.28/src/walrasquant/exchange/deribit/schema.py +41 -0
  19. walrasquant_lib-0.4.28/src/walrasquant/exchange/deribit/websockets.py +184 -0
  20. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/README.md +0 -0
  21. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/__init__.py +0 -0
  22. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/aggregation.py +0 -0
  23. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/backends/__init__.py +0 -0
  24. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/backends/db.py +0 -0
  25. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/backends/db_memory.py +0 -0
  26. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/backends/db_postgresql.py +0 -0
  27. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/backends/db_sqlite.py +0 -0
  28. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/base/__init__.py +0 -0
  29. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/base/api_client.py +0 -0
  30. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/base/connector.py +0 -0
  31. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/base/exchange.py +0 -0
  32. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/base/oms.py +0 -0
  33. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/base/retry.py +0 -0
  34. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/base/sms.py +0 -0
  35. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/base/ws_client.py +0 -0
  36. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/core/__init__.py +0 -0
  37. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/core/cache.py +0 -0
  38. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/core/clock.py +0 -0
  39. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/core/connection.py +0 -0
  40. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/core/entity.py +0 -0
  41. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/core/registry.py +0 -0
  42. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/error.py +0 -0
  43. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/base_factory.py +0 -0
  44. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/binance/__init__.py +0 -0
  45. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/binance/connector.py +0 -0
  46. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/binance/constants.py +0 -0
  47. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/binance/ems.py +0 -0
  48. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/binance/error.py +0 -0
  49. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/binance/exchange.py +0 -0
  50. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/binance/factory.py +0 -0
  51. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/binance/oms.py +0 -0
  52. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/binance/rest_api.py +0 -0
  53. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/binance/schema.py +0 -0
  54. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/binance/websockets.py +0 -0
  55. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bitget/__init__.py +0 -0
  56. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bitget/connector.py +0 -0
  57. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bitget/constants.py +0 -0
  58. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bitget/error.py +0 -0
  59. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bitget/exchange.py +0 -0
  60. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bitget/factory.py +0 -0
  61. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bitget/oms.py +0 -0
  62. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bitget/rest_api.py +0 -0
  63. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bitget/schema.py +0 -0
  64. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bitget/websockets.py +0 -0
  65. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bybit/__init__.py +0 -0
  66. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bybit/connector.py +0 -0
  67. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bybit/constants.py +0 -0
  68. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bybit/ems.py +0 -0
  69. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bybit/error.py +0 -0
  70. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bybit/exchange.py +0 -0
  71. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bybit/factory.py +0 -0
  72. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bybit/oms.py +0 -0
  73. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bybit/rest_api.py +0 -0
  74. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bybit/schema.py +0 -0
  75. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/bybit/websockets.py +0 -0
  76. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/hyperliquid/__init__.py +0 -0
  77. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/hyperliquid/connector.py +0 -0
  78. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/hyperliquid/constants.py +0 -0
  79. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/hyperliquid/ems.py +0 -0
  80. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/hyperliquid/error.py +0 -0
  81. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/hyperliquid/exchange.py +0 -0
  82. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/hyperliquid/factory.py +0 -0
  83. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/hyperliquid/oms.py +0 -0
  84. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/hyperliquid/rest_api.py +0 -0
  85. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/hyperliquid/schema.py +0 -0
  86. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/hyperliquid/signing.py +0 -0
  87. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/hyperliquid/websockets.py +0 -0
  88. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/okx/__init__.py +0 -0
  89. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/okx/connector.py +0 -0
  90. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/okx/constants.py +0 -0
  91. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/okx/ems.py +0 -0
  92. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/okx/error.py +0 -0
  93. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/okx/exchange.py +0 -0
  94. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/okx/factory.py +0 -0
  95. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/okx/oms.py +0 -0
  96. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/okx/rest_api.py +0 -0
  97. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/okx/schema.py +0 -0
  98. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/okx/websockets.py +0 -0
  99. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/exchange/registry.py +0 -0
  100. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/execution/__init__.py +0 -0
  101. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/execution/algorithm.py +0 -0
  102. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/execution/algorithms/__init__.py +0 -0
  103. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/execution/algorithms/twap.py +0 -0
  104. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/execution/config.py +0 -0
  105. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/execution/constants.py +0 -0
  106. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/execution/schema.py +0 -0
  107. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/indicator.py +0 -0
  108. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/push.py +0 -0
  109. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/schema.py +0 -0
  110. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/strategy.py +0 -0
  111. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/tools/__init__.py +0 -0
  112. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/tools/pm2_wrapper.py +0 -0
  113. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/web/__init__.py +0 -0
  114. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/web/app.py +0 -0
  115. {walrasquant_lib-0.4.26 → walrasquant_lib-0.4.28}/src/walrasquant/web/server.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: walrasquant-lib
3
- Version: 0.4.26
3
+ Version: 0.4.28
4
4
  Summary: fastest python trading bot
5
5
  Author: River-Shi
6
6
  Author-email: River-Shi <nachuan.shi.quant@gmail.com>
@@ -25,7 +25,7 @@ Requires-Dist: rich>=14.0.0
25
25
  Requires-Dist: picows>=2.1.1
26
26
  Requires-Dist: nexuscore-lib>=0.2.1
27
27
  Requires-Dist: flashduty-lib>=0.2.0
28
- Requires-Dist: nexuslog-lib>=0.8.0
28
+ Requires-Dist: nexuslog-lib>=0.9.0
29
29
  Requires-Dist: msgspec>=0.21.1
30
30
  Requires-Dist: pandas<3.0.0
31
31
  Requires-Dist: numpy>=2.2.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "walrasquant-lib"
3
- version = "0.4.26"
3
+ version = "0.4.28"
4
4
  description = "fastest python trading bot"
5
5
  authors = [
6
6
  {name = "River-Shi",email = "nachuan.shi.quant@gmail.com"}
@@ -29,7 +29,7 @@ dependencies = [
29
29
  "picows>=2.1.1",
30
30
  "nexuscore-lib>=0.2.1",
31
31
  "flashduty-lib>=0.2.0",
32
- "nexuslog-lib>=0.8.0",
32
+ "nexuslog-lib>=0.9.0",
33
33
  "msgspec>=0.21.1",
34
34
  "pandas<3.0.0",
35
35
  "numpy>=2.2.0",
@@ -168,6 +168,40 @@ class ExecutionManagementSystem(ABC):
168
168
  self._build_order_submit_queues()
169
169
  self._set_account_type()
170
170
 
171
+ @staticmethod
172
+ def _quantize_step(
173
+ value: float,
174
+ step: float | str,
175
+ mode: Literal["round", "ceil", "floor"] = "round",
176
+ ) -> Decimal:
177
+ """
178
+ Snap ``value`` to the nearest integer multiple of ``step``.
179
+
180
+ Unlike ``Decimal.quantize`` (which aligns to a number of decimal
181
+ places), this aligns to the actual step value, so it is correct for
182
+ arbitrary steps such as tick sizes of 0.5 or 0.2 as well as the usual
183
+ powers of ten. The result is normalized to the number of decimal places
184
+ implied by ``step`` so its string form matches decimal-place rounding
185
+ for power-of-ten / integer steps (no spurious trailing zeros).
186
+
187
+ ``step`` arrives either as a float (ccxt ``market.precision``) or a str
188
+ (exchange-native tick fields); both are normalized via ``Decimal(str())``
189
+ to avoid binary-float error.
190
+ """
191
+ rounding = {
192
+ "round": ROUND_HALF_UP,
193
+ "ceil": ROUND_CEILING,
194
+ "floor": ROUND_FLOOR,
195
+ }[mode]
196
+ value_decimal = Decimal(str(value))
197
+ step_decimal = Decimal(str(step))
198
+ multiples = (value_decimal / step_decimal).quantize(
199
+ Decimal("1"), rounding=rounding
200
+ )
201
+ result = multiples * step_decimal
202
+ ndigits = max(0, -step_decimal.normalize().as_tuple().exponent)
203
+ return result.quantize(Decimal(1).scaleb(-ndigits))
204
+
171
205
  def _amount_to_precision(
172
206
  self,
173
207
  symbol: str,
@@ -178,29 +212,7 @@ class ExecutionManagementSystem(ABC):
178
212
  Convert the amount to the precision of the market
179
213
  """
180
214
  market = self._market[symbol]
181
- amount_decimal: Decimal = Decimal(str(amount))
182
- precision = market.precision.amount
183
-
184
- if precision >= 1:
185
- exp = Decimal(int(precision))
186
- precision_decimal = Decimal("1")
187
- else:
188
- exp = Decimal("1")
189
- precision_decimal = Decimal(str(precision))
190
-
191
- if mode == "round":
192
- format_amount = (amount_decimal / exp).quantize(
193
- precision_decimal, rounding=ROUND_HALF_UP
194
- ) * exp
195
- elif mode == "ceil":
196
- format_amount = (amount_decimal / exp).quantize(
197
- precision_decimal, rounding=ROUND_CEILING
198
- ) * exp
199
- elif mode == "floor":
200
- format_amount = (amount_decimal / exp).quantize(
201
- precision_decimal, rounding=ROUND_FLOOR
202
- ) * exp
203
- return format_amount
215
+ return self._quantize_step(amount, market.precision.amount, mode)
204
216
 
205
217
  def _price_to_precision(
206
218
  self,
@@ -212,30 +224,7 @@ class ExecutionManagementSystem(ABC):
212
224
  Convert the price to the precision of the market
213
225
  """
214
226
  market = self._market[symbol]
215
- price_decimal: Decimal = Decimal(str(price))
216
-
217
- decimal = market.precision.price
218
-
219
- if decimal >= 1:
220
- exp = Decimal(int(decimal))
221
- precision_decimal = Decimal("1")
222
- else:
223
- exp = Decimal("1")
224
- precision_decimal = Decimal(str(decimal))
225
-
226
- if mode == "round":
227
- format_price = (price_decimal / exp).quantize(
228
- precision_decimal, rounding=ROUND_HALF_UP
229
- ) * exp
230
- elif mode == "ceil":
231
- format_price = (price_decimal / exp).quantize(
232
- precision_decimal, rounding=ROUND_CEILING
233
- ) * exp
234
- elif mode == "floor":
235
- format_price = (price_decimal / exp).quantize(
236
- precision_decimal, rounding=ROUND_FLOOR
237
- ) * exp
238
- return format_price
227
+ return self._quantize_step(price, market.precision.price, mode)
239
228
 
240
229
  @abstractmethod
241
230
  def _instrument_id_to_account_type(
@@ -21,6 +21,8 @@ class LogConfig:
21
21
  color: ANSI colorization of log output. "auto" colors only when writing
22
22
  to a color-capable terminal, "off" disables it, "always" forces it
23
23
  even for files and pipes.
24
+ format: Output line format. "logfmt" (default) or "json" (NDJSON,
25
+ recommended for shipping logs to Vector/Fluentd -> a DB).
24
26
  """
25
27
 
26
28
  filename: Literal["auto"] | str | None = None
@@ -29,6 +31,7 @@ class LogConfig:
29
31
  unix_ts: bool = False
30
32
  batch_size: int = 1
31
33
  color: Literal["auto", "off", "always"] = "auto"
34
+ format: Literal["logfmt", "json"] = "logfmt"
32
35
 
33
36
  def __post_init__(self):
34
37
  if self.level not in ["TRACE", "DEBUG", "INFO", "WARNING", "ERROR"]:
@@ -48,6 +51,11 @@ class LogConfig:
48
51
  f"Invalid color: {self.color}. Must be one of auto, off, always."
49
52
  )
50
53
 
54
+ if self.format not in ["logfmt", "json"]:
55
+ raise ValueError(
56
+ f"Invalid format: {self.format}. Must be one of logfmt, json."
57
+ )
58
+
51
59
 
52
60
  @dataclass
53
61
  class BasicConfig:
@@ -225,6 +225,7 @@ class ExchangeType(Enum):
225
225
  BYBIT = "bybit"
226
226
  HYPERLIQUID = "hyperliquid"
227
227
  BITGET = "bitget"
228
+ DERIBIT = "deribit"
228
229
 
229
230
 
230
231
  class AccountType(Enum):
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from importlib import import_module
4
- from typing import Any, Mapping
4
+ from typing import Any, Literal, Mapping
5
5
 
6
6
  import nexuslog as logging
7
7
  from walrasquant.constants import settings
@@ -54,7 +54,8 @@ def setup_nexus_core(
54
54
  name_levels: Mapping[str | None, str] | None = None,
55
55
  unix_ts: bool = False,
56
56
  batch_size: int | None = None,
57
- color: str = "auto",
57
+ color: Literal["auto", "off", "always"] = "auto",
58
+ format: Literal["logfmt", "json"] = "logfmt",
58
59
  ) -> tuple[Any, Any]:
59
60
  """
60
61
  Setup logging for the application using nexuslog and initialize MessageBus and Clock.
@@ -65,6 +66,7 @@ def setup_nexus_core(
65
66
  level: Minimum log level to record (TRACE, DEBUG, INFO, WARNING, ERROR)
66
67
  unix_ts: If True, emit unix timestamps instead of formatted local time.
67
68
  color: ANSI colorization mode ("auto", "off", "always").
69
+ format: Output line format ("logfmt" or "json").
68
70
 
69
71
  Returns:
70
72
  tuple: (msgbus, clock) - MessageBus and LiveClock instances
@@ -101,6 +103,7 @@ def setup_nexus_core(
101
103
  unix_ts=unix_ts,
102
104
  batch_size=batch_size,
103
105
  color=color,
106
+ format=format,
104
107
  )
105
108
 
106
109
  return msgbus, clock
@@ -75,6 +75,7 @@ class Engine:
75
75
  unix_ts=self._config.log_config.unix_ts,
76
76
  batch_size=self._config.log_config.batch_size,
77
77
  color=self._config.log_config.color,
78
+ format=self._config.log_config.format,
78
79
  )
79
80
 
80
81
  # Create logger instance for Engine
@@ -3,6 +3,7 @@ from walrasquant.exchange.bybit import BybitAccountType
3
3
  from walrasquant.exchange.okx import OkxAccountType
4
4
  from walrasquant.exchange.hyperliquid import HyperLiquidAccountType
5
5
  from walrasquant.exchange.bitget import BitgetAccountType
6
+ from walrasquant.exchange.deribit import DeribitAccountType
6
7
 
7
8
  __all__ = [
8
9
  "BinanceAccountType",
@@ -10,4 +11,5 @@ __all__ = [
10
11
  "OkxAccountType",
11
12
  "HyperLiquidAccountType",
12
13
  "BitgetAccountType",
14
+ "DeribitAccountType",
13
15
  ]
@@ -1,7 +1,6 @@
1
1
  from typing import Dict, cast
2
2
  from decimal import Decimal
3
3
  from typing import Literal
4
- from decimal import ROUND_HALF_UP, ROUND_CEILING, ROUND_FLOOR
5
4
 
6
5
  from walrasquant.constants import AccountType
7
6
  from walrasquant.schema import (
@@ -124,26 +123,11 @@ class BitgetExecutionManagementSystem(ExecutionManagementSystem):
124
123
  mode: Literal["round", "ceil", "floor"] = "round",
125
124
  ) -> Decimal:
126
125
  market = self._market[symbol]
126
+ # Spot amount precision is a plain ccxt step handled by the base class;
127
+ # derivatives quantize to the contract sizeMultiplier.
127
128
  if market.spot:
128
129
  return super()._amount_to_precision(symbol, amount, mode)
129
- else:
130
- amount: Decimal = Decimal(str(amount))
131
- amount_multiplier = Decimal(market.info.sizeMultiplier or "1")
132
- multiplier_count = amount / amount_multiplier
133
-
134
- if mode == "round":
135
- amount = (
136
- multiplier_count.quantize(Decimal("1"), rounding=ROUND_HALF_UP)
137
- ) * amount_multiplier
138
- elif mode == "ceil":
139
- amount = (
140
- multiplier_count.quantize(Decimal("1"), rounding=ROUND_CEILING)
141
- ) * amount_multiplier
142
- elif mode == "floor":
143
- amount = (
144
- multiplier_count.quantize(Decimal("1"), rounding=ROUND_FLOOR)
145
- ) * amount_multiplier
146
- return amount
130
+ return self._quantize_step(amount, market.info.sizeMultiplier or "1", mode)
147
131
 
148
132
  def _price_to_precision(
149
133
  self,
@@ -152,26 +136,11 @@ class BitgetExecutionManagementSystem(ExecutionManagementSystem):
152
136
  mode: Literal["round", "ceil", "floor"] = "round",
153
137
  ) -> Decimal:
154
138
  market = self._market[symbol]
139
+ # Spot price precision is a plain ccxt step handled by the base class;
140
+ # derivatives quantize to the priceEndStep tick.
155
141
  if market.spot:
156
142
  return super()._price_to_precision(symbol, price, mode)
157
- else:
158
- price: Decimal = Decimal(str(price))
159
- price_multiplier = Decimal(market.info.priceEndStep or "1")
160
- multiplier_count = price / price_multiplier
161
-
162
- if mode == "round":
163
- price = (
164
- multiplier_count.quantize(Decimal("1"), rounding=ROUND_HALF_UP)
165
- ) * price_multiplier
166
- elif mode == "ceil":
167
- price = (
168
- multiplier_count.quantize(Decimal("1"), rounding=ROUND_CEILING)
169
- ) * price_multiplier
170
- elif mode == "floor":
171
- price = (
172
- multiplier_count.quantize(Decimal("1"), rounding=ROUND_FLOOR)
173
- ) * price_multiplier
174
- return price
143
+ return self._quantize_step(price, market.info.priceEndStep or "1", mode)
175
144
 
176
145
  async def _cancel_all_orders(
177
146
  self, order_submit: CancelAllOrderSubmit, account_type: AccountType
@@ -0,0 +1,26 @@
1
+ from walrasquant.exchange.deribit.constants import DeribitAccountType
2
+ from walrasquant.exchange.deribit.connector import (
3
+ DeribitPrivateConnector,
4
+ DeribitPublicConnector,
5
+ )
6
+ from walrasquant.exchange.deribit.ems import DeribitExecutionManagementSystem
7
+ from walrasquant.exchange.deribit.exchange import DeribitExchangeManager
8
+ from walrasquant.exchange.deribit.factory import DeribitFactory
9
+ from walrasquant.exchange.deribit.oms import DeribitOrderManagementSystem
10
+
11
+ try:
12
+ from walrasquant.exchange.registry import register_factory
13
+
14
+ register_factory(DeribitFactory())
15
+ except ImportError:
16
+ pass
17
+
18
+ __all__ = [
19
+ "DeribitAccountType",
20
+ "DeribitExchangeManager",
21
+ "DeribitPublicConnector",
22
+ "DeribitPrivateConnector",
23
+ "DeribitOrderManagementSystem",
24
+ "DeribitExecutionManagementSystem",
25
+ "DeribitFactory",
26
+ ]