onesecondtrader 0.46.0__py3-none-any.whl → 0.48.0__py3-none-any.whl

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 (28) hide show
  1. onesecondtrader/events/__init__.py +2 -1
  2. onesecondtrader/events/market/__init__.py +7 -0
  3. onesecondtrader/events/market/bar_processed.py +29 -0
  4. onesecondtrader/events/market/bar_received.py +34 -0
  5. onesecondtrader/events/orders/__init__.py +9 -0
  6. onesecondtrader/events/orders/base.py +30 -0
  7. onesecondtrader/events/orders/expirations.py +23 -0
  8. onesecondtrader/events/orders/fills.py +41 -0
  9. onesecondtrader/events/requests/__init__.py +2 -0
  10. onesecondtrader/events/requests/base.py +25 -0
  11. onesecondtrader/events/requests/order_cancellation.py +9 -11
  12. onesecondtrader/events/requests/order_modification.py +2 -5
  13. onesecondtrader/events/requests/order_submission.py +6 -4
  14. onesecondtrader/events/responses/__init__.py +14 -0
  15. onesecondtrader/events/responses/base.py +26 -0
  16. onesecondtrader/events/responses/cancellations.py +42 -0
  17. onesecondtrader/events/responses/modifications.py +43 -0
  18. onesecondtrader/events/responses/orders.py +42 -0
  19. onesecondtrader/indicators/__init__.py +9 -0
  20. onesecondtrader/indicators/base.py +142 -0
  21. onesecondtrader/models/__init__.py +14 -1
  22. onesecondtrader/models/rejection_reasons.py +48 -0
  23. onesecondtrader/models/trade_sides.py +1 -1
  24. {onesecondtrader-0.46.0.dist-info → onesecondtrader-0.48.0.dist-info}/METADATA +1 -1
  25. onesecondtrader-0.48.0.dist-info/RECORD +32 -0
  26. onesecondtrader-0.46.0.dist-info/RECORD +0 -16
  27. {onesecondtrader-0.46.0.dist-info → onesecondtrader-0.48.0.dist-info}/WHEEL +0 -0
  28. {onesecondtrader-0.46.0.dist-info → onesecondtrader-0.48.0.dist-info}/licenses/LICENSE +0 -0
@@ -3,5 +3,6 @@ Defines the event message objects propagated through the system.
3
3
  """
4
4
 
5
5
  from .base import EventBase
6
+ from . import market, orders, requests, responses
6
7
 
7
- __all__ = ["EventBase"]
8
+ __all__ = ["EventBase", "market", "orders", "requests", "responses"]
@@ -0,0 +1,7 @@
1
+ from .bar_received import BarReceived
2
+ from .bar_processed import BarProcessed
3
+
4
+ __all__ = [
5
+ "BarReceived",
6
+ "BarProcessed",
7
+ ]
@@ -0,0 +1,29 @@
1
+ from __future__ import annotations
2
+
3
+ import dataclasses
4
+
5
+ from onesecondtrader.events.market.bar_received import BarReceived
6
+
7
+
8
+ @dataclasses.dataclass(kw_only=True, frozen=True)
9
+ class BarProcessed(BarReceived):
10
+ """
11
+ Event representing a market data bar with computed indicator values.
12
+
13
+ This event extends `BarReceived` by attaching indicator values derived from the bar data.
14
+
15
+ | Field | Type | Semantics |
16
+ |-----------------|-------------------------|----------------------------------------------------------------------------|
17
+ | `ts_event_ns` | `int` | Time at which the bar was observed by the system, as UTC epoch nanoseconds.|
18
+ | `ts_created_ns` | `int` | Time at which the event object was created, as UTC epoch nanoseconds. |
19
+ | `symbol` | `str` | Identifier of the traded instrument. |
20
+ | `bar_period` | `models.data.BarPeriod` | Time interval represented by the bar. |
21
+ | `open` | `float` | Opening price of the bar period. |
22
+ | `high` | `float` | Highest traded price during the bar period. |
23
+ | `low` | `float` | Lowest traded price during the bar period. |
24
+ | `close` | `float` | Closing price of the bar period. |
25
+ | `volume` | `int` or `None` | Traded volume during the bar period, if available. |
26
+ | `indicators` | `dict[str, float]` | Mapping of indicator names to computed indicator values. |
27
+ """
28
+
29
+ indicators: dict[str, float] = dataclasses.field(default_factory=dict)
@@ -0,0 +1,34 @@
1
+ from __future__ import annotations
2
+
3
+ import dataclasses
4
+
5
+ from onesecondtrader import events, models
6
+
7
+
8
+ @dataclasses.dataclass(kw_only=True, frozen=True)
9
+ class BarReceived(events.EventBase):
10
+ """
11
+ Event representing the reception of a completed market data bar.
12
+
13
+ This event represents a time-aggregated bar as received from a market data source or produced by a resampling process.
14
+
15
+ | Field | Type | Semantics |
16
+ |-----------------|--------------------------|-----------------------------------------------------------------------------|
17
+ | `ts_event_ns` | `int` | Time at which the bar was observed by the system, as UTC epoch nanoseconds. |
18
+ | `ts_created_ns` | `int` | Time at which the event object was created, as UTC epoch nanoseconds. |
19
+ | `symbol` | `str` | Identifier of the traded instrument. |
20
+ | `bar_period` | `models.data.BarPeriod` | Time interval represented by the bar. |
21
+ | `open` | `float` | Opening price of the bar period. |
22
+ | `high` | `float` | Highest traded price during the bar period. |
23
+ | `low` | `float` | Lowest traded price during the bar period. |
24
+ | `close` | `float` | Closing price of the bar period. |
25
+ | `volume` | `int` or `None` | Traded volume during the bar period, if available. |
26
+ """
27
+
28
+ symbol: str
29
+ bar_period: models.BarPeriod
30
+ open: float
31
+ high: float
32
+ low: float
33
+ close: float
34
+ volume: int | None = None
@@ -0,0 +1,9 @@
1
+ from .base import OrderBase
2
+ from .expirations import OrderExpired
3
+ from .fills import FillEvent
4
+
5
+ __all__ = [
6
+ "OrderBase",
7
+ "OrderExpired",
8
+ "FillEvent",
9
+ ]
@@ -0,0 +1,30 @@
1
+ from __future__ import annotations
2
+
3
+ import dataclasses
4
+ import uuid
5
+
6
+ from onesecondtrader import events
7
+
8
+
9
+ @dataclasses.dataclass(kw_only=True, frozen=True, slots=True)
10
+ class OrderBase(events.EventBase):
11
+ """
12
+ Base class for broker-originated order events.
13
+
14
+ Order events are broker-originated facts about the state or execution of an order.
15
+ Each order event is correlated to a system order identifier via `associated_order_id`.
16
+
17
+ | Field | Type | Semantics |
18
+ |-----------------------|-----------------|---------------------------------------------------------------------------------------|
19
+ | `ts_event_ns` | `int` | Time at which the response event was observed by the system, as UTC epoch nanoseconds.|
20
+ | `ts_created_ns` | `int` | Time at which the event object was created, as UTC epoch nanoseconds. |
21
+ | `ts_broker_ns` | `int` | Time reported by the broker for the response, as UTC epoch nanoseconds. |
22
+ | `associated_order_id` | `uuid.UUID`. | Identifier of the order associated with the broker response. |
23
+ | `broker_order_id` | `str` or `None` | Broker-assigned identifier of the order, if reported. |
24
+ | `symbol` | `str` | Identifier of the traded instrument. |
25
+ """
26
+
27
+ ts_broker_ns: int
28
+ associated_order_id: uuid.UUID
29
+ broker_order_id: str | None = None
30
+ symbol: str
@@ -0,0 +1,23 @@
1
+ from __future__ import annotations
2
+
3
+ import dataclasses
4
+
5
+ from onesecondtrader.events.orders.base import OrderBase
6
+
7
+
8
+ @dataclasses.dataclass(kw_only=True, frozen=True, slots=True)
9
+ class OrderExpired(OrderBase):
10
+ """
11
+ Event indicating that the order is no longer active at the venue due to expiration according to broker- or venue-specific rules (e.g. time-in-force constraints).
12
+
13
+ | Field | Type | Semantics |
14
+ |-----------------------|-----------------|------------------------------------------------------------------------------------|
15
+ | `ts_event_ns` | `int` | Time at which the expiration was observed by the system, as UTC epoch nanoseconds. |
16
+ | `ts_created_ns` | `int` | Time at which the event object was created, as UTC epoch nanoseconds. |
17
+ | `ts_broker_ns` | `int` | Time reported by the broker for the expiration, as UTC epoch nanoseconds. |
18
+ | `associated_order_id` | `uuid.UUID` | Identifier of the expired order. |
19
+ | `broker_order_id` | `str` or `None` | Broker-assigned identifier of the expired order, if reported. |
20
+ | `symbol` | `str` | Identifier of the traded instrument. |
21
+ """
22
+
23
+ pass
@@ -0,0 +1,41 @@
1
+ from __future__ import annotations
2
+
3
+ import dataclasses
4
+ import uuid
5
+
6
+ from onesecondtrader import models
7
+ from onesecondtrader.events.orders.base import OrderBase
8
+
9
+
10
+ @dataclasses.dataclass(kw_only=True, frozen=True, slots=True)
11
+ class FillEvent(OrderBase):
12
+ """
13
+ Event representing the execution of a trade resulting in a fill.
14
+
15
+ A fill event records the execution of a quantity of an order at a specific price.
16
+ Multiple fill events may be associated with the same order in the case of partial execution.
17
+
18
+ | Field | Type | Semantics |
19
+ |-----------------------|---------------------|---------------------------------------------------------------------------------|
20
+ | `ts_event_ns` | `int` | Time at which the fill was observed by the system, as UTC epoch nanoseconds. |
21
+ | `ts_created_ns` | `int` | Time at which the event object was created, as UTC epoch nanoseconds. |
22
+ | `ts_broker_ns` | `int` | Time reported by the broker for the fill, as UTC epoch nanoseconds. |
23
+ | `associated_order_id` | `uuid.UUID` | Identifier of the order associated with the fill. |
24
+ | `broker_order_id` | `str` or `None` | Broker-assigned identifier of the order associated with the fill, if available. |
25
+ | `symbol` | `str` | Identifier of the traded instrument. |
26
+ | `fill_id` | `uuid.UUID` | System-assigned unique identifier of the fill event. |
27
+ | `broker_fill_id` | `str` or `None` | Broker-assigned identifier of the execution record, if available. |
28
+ | `side` | `models.TradeSide` | Trade direction of the executed quantity. |
29
+ | `quantity_filled` | `float` | Quantity executed in this fill. |
30
+ | `fill_price` | `float` | Execution price of the fill. |
31
+ | `commission` | `float` | Commission or fee associated with the fill. |
32
+ | `exchange` | `str` | Identifier of the execution venue. |
33
+ """
34
+
35
+ fill_id: uuid.UUID = dataclasses.field(default_factory=uuid.uuid4)
36
+ broker_fill_id: str | None = None
37
+ side: models.TradeSide
38
+ quantity_filled: float
39
+ fill_price: float
40
+ commission: float
41
+ exchange: str = "SIMULATED"
@@ -1,8 +1,10 @@
1
+ from .base import RequestBase
1
2
  from .order_submission import OrderSubmissionRequest
2
3
  from .order_cancellation import OrderCancellationRequest
3
4
  from .order_modification import OrderModificationRequest
4
5
 
5
6
  __all__ = [
7
+ "RequestBase",
6
8
  "OrderSubmissionRequest",
7
9
  "OrderCancellationRequest",
8
10
  "OrderModificationRequest",
@@ -0,0 +1,25 @@
1
+ from __future__ import annotations
2
+
3
+ import dataclasses
4
+ import uuid
5
+
6
+ from onesecondtrader import events
7
+
8
+
9
+ @dataclasses.dataclass(kw_only=True, frozen=True, slots=True)
10
+ class RequestBase(events.EventBase):
11
+ """
12
+ Base class for request events.
13
+
14
+ This class defines attributes common to all requests issued to a broker.
15
+
16
+ | Field | Type | Semantics |
17
+ |-------------------|-------------|----------------------------------------------------------------------------|
18
+ | `ts_event_ns` | `int` | Time at which the request was issued, as UTC epoch nanoseconds. |
19
+ | `ts_created_ns` | `int` | Time at which the event object was created, as UTC epoch nanoseconds. |
20
+ | `system_order_id` | `uuid.UUID` | System-assigned identifier of the order associated with the request. |
21
+ | `symbol` | `str` | Identifier of the traded instrument. |
22
+ """
23
+
24
+ system_order_id: uuid.UUID
25
+ symbol: str
@@ -1,23 +1,21 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import dataclasses
4
- import uuid
5
4
 
6
- from onesecondtrader import events
5
+ from onesecondtrader.events.requests.base import RequestBase
7
6
 
8
7
 
9
8
  @dataclasses.dataclass(kw_only=True, frozen=True, slots=True)
10
- class OrderCancellationRequest(events.EventBase):
9
+ class OrderCancellationRequest(RequestBase):
11
10
  """
12
11
  Event representing a request to cancel an existing order.
13
12
 
14
- | Field | Type | Semantics |
15
- |-------------------|-------------|---------------------------------------------------------------------|
16
- | `ts_event_ns` | `int` | Time at which the cancellation request was issued, as UTC epoch ns. |
17
- | `ts_created_ns` | `int` | Time at which the event object was created, as UTC epoch ns. |
18
- | `system_order_id` | `uuid.UUID` | System-assigned identifier of the order to be cancelled. |
19
- | `symbol` | `str` | Identifier of the traded instrument. |
13
+ | Field | Type | Semantics |
14
+ |-------------------|-------------|------------------------------------------------------------------------------|
15
+ | `ts_event_ns` | `int` | Time at which the cancellation request was issued, as UTC epoch nanoseconds. |
16
+ | `ts_created_ns` | `int` | Time at which the event object was created, as UTC epoch nanoseconds. |
17
+ | `system_order_id` | `uuid.UUID` | System-assigned identifier of the order to be cancelled. |
18
+ | `symbol` | `str` | Identifier of the traded instrument. |
20
19
  """
21
20
 
22
- system_order_id: uuid.UUID
23
- symbol: str
21
+ pass
@@ -1,13 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import dataclasses
4
- import uuid
5
4
 
6
- from onesecondtrader import events
5
+ from onesecondtrader.events.requests.base import RequestBase
7
6
 
8
7
 
9
8
  @dataclasses.dataclass(kw_only=True, frozen=True, slots=True)
10
- class OrderModificationRequest(events.EventBase):
9
+ class OrderModificationRequest(RequestBase):
11
10
  """
12
11
  Event representing a request to modify an existing order.
13
12
 
@@ -22,8 +21,6 @@ class OrderModificationRequest(events.EventBase):
22
21
  | `stop_price` | `float` or `None` | Updated stop price, if modified. |
23
22
  """
24
23
 
25
- system_order_id: uuid.UUID
26
- symbol: str
27
24
  quantity: float | None = None
28
25
  limit_price: float | None = None
29
26
  stop_price: float | None = None
@@ -3,19 +3,22 @@ from __future__ import annotations
3
3
  import dataclasses
4
4
  import uuid
5
5
 
6
- from onesecondtrader import events, models
6
+ from onesecondtrader import models
7
+ from onesecondtrader.events.requests.base import RequestBase
7
8
 
8
9
 
9
10
  @dataclasses.dataclass(kw_only=True, frozen=True, slots=True)
10
- class OrderSubmissionRequest(events.EventBase):
11
+ class OrderSubmissionRequest(RequestBase):
11
12
  """
12
13
  Event representing a request to submit a new order to a broker.
13
14
 
15
+ The `system_order_id` is a unique identifier assigned by the system to the order submission request by default at object creation.
16
+
14
17
  | Field | Type | Semantics |
15
18
  |-------------------|--------------------------|----------------------------------------------------------------------------|
16
19
  | `ts_event_ns` | `int` | Time at which the submission request was issued, as UTC epoch nanoseconds. |
17
20
  | `ts_created_ns` | `int` | Time at which the event object was created, as UTC epoch nanoseconds. |
18
- | `system_order_id` | `uuid.UUID` | System-assigned unique identifier for the order submission. |
21
+ | `system_order_id` | `uuid.UUID` | System-assigned unique identifier for the order submission. |
19
22
  | `symbol` | `str` | Identifier of the traded instrument. |
20
23
  | `order_type` | `models.OrderType` | Execution constraint of the order. |
21
24
  | `side` | `models.TradeSide` | Direction of the trade. |
@@ -25,7 +28,6 @@ class OrderSubmissionRequest(events.EventBase):
25
28
  """
26
29
 
27
30
  system_order_id: uuid.UUID = dataclasses.field(default_factory=uuid.uuid4)
28
- symbol: str
29
31
  order_type: models.OrderType
30
32
  side: models.TradeSide
31
33
  quantity: float
@@ -0,0 +1,14 @@
1
+ from .base import ResponseBase
2
+ from .orders import OrderAccepted, OrderRejected
3
+ from .modifications import ModificationAccepted, ModificationRejected
4
+ from .cancellations import CancellationAccepted, CancellationRejected
5
+
6
+ __all__ = [
7
+ "ResponseBase",
8
+ "OrderAccepted",
9
+ "OrderRejected",
10
+ "ModificationAccepted",
11
+ "ModificationRejected",
12
+ "CancellationAccepted",
13
+ "CancellationRejected",
14
+ ]
@@ -0,0 +1,26 @@
1
+ from __future__ import annotations
2
+
3
+ import dataclasses
4
+ import uuid
5
+
6
+
7
+ from onesecondtrader import events
8
+
9
+
10
+ @dataclasses.dataclass(kw_only=True, frozen=True, slots=True)
11
+ class ResponseBase(events.EventBase):
12
+ """
13
+ Base class for broker response events.
14
+
15
+ This class defines attributes common to all responses received from a broker in reaction to previously issued requests.
16
+
17
+ | Field | Type | Semantics |
18
+ |-----------------------|-------------|---------------------------------------------------------------------------------------|
19
+ | `ts_event_ns` | `int` | Time at which the response event was observed by the system, as UTC epoch nanoseconds.|
20
+ | `ts_created_ns` | `int` | Time at which the event object was created, as UTC epoch nanoseconds. |
21
+ | `ts_broker_ns` | `int` | Time reported by the broker for the response, as UTC epoch nanoseconds. |
22
+ | `associated_order_id` | `uuid.UUID` | Identifier of the order associated with the broker response. |
23
+ """
24
+
25
+ ts_broker_ns: int
26
+ associated_order_id: uuid.UUID
@@ -0,0 +1,42 @@
1
+ from __future__ import annotations
2
+
3
+ import dataclasses
4
+
5
+ from onesecondtrader import models
6
+ from onesecondtrader.events.responses.base import ResponseBase
7
+
8
+
9
+ @dataclasses.dataclass(kw_only=True, frozen=True, slots=True)
10
+ class CancellationAccepted(ResponseBase):
11
+ """
12
+ Event indicating that the order cancellation has been acknowledged by the broker and the order is no longer active at the execution venue.
13
+
14
+ | Field | Type | Semantics |
15
+ |-----------------------|-----------------|----------------------------------------------------------------------------------------|
16
+ | `ts_event_ns` | `int` | Time at which the cancellation was observed by the system, as UTC epoch nanoseconds. |
17
+ | `ts_created_ns` | `int` | Time at which the event object was created, as UTC epoch nanoseconds. |
18
+ | `ts_broker_ns` | `int` | Time reported by the broker for the cancellation, as UTC epoch nanoseconds. |
19
+ | `associated_order_id` | `uuid.UUID` | Identifier of the cancelled order. |
20
+ | `broker_order_id` | `str` or `None` | Broker-assigned identifier of the cancelled order, if reported. |
21
+ """
22
+
23
+ broker_order_id: str | None = None
24
+
25
+
26
+ @dataclasses.dataclass(kw_only=True, frozen=True, slots=True)
27
+ class CancellationRejected(ResponseBase):
28
+ """
29
+ Event indicating that the order cancellation has been rejected by the broker.
30
+
31
+ | Field | Type | Semantics |
32
+ |-----------------------|--------------------------------------|------------------------------------------------------------------------------------|
33
+ | `ts_event_ns` | `int` | Time at which the rejection was observed by the system, as UTC epoch nanoseconds. |
34
+ | `ts_created_ns` | `int` | Time at which the event object was created, as UTC epoch nanoseconds. |
35
+ | `ts_broker_ns` | `int` | Time reported by the broker for the rejection, as UTC epoch nanoseconds. |
36
+ | `associated_order_id` | `uuid.UUID` | Identifier of the order associated with the rejected cancellation. |
37
+ | `rejection_reason` | `models.CancellationRejectionReason` | Canonical classification of the cancellation rejection cause. |
38
+ | `rejection_message` | `str` | Human-readable explanation provided by the broker. |
39
+ """
40
+
41
+ rejection_reason: models.CancellationRejectionReason
42
+ rejection_message: str
@@ -0,0 +1,43 @@
1
+ from __future__ import annotations
2
+
3
+ import dataclasses
4
+
5
+ from onesecondtrader import models
6
+ from onesecondtrader.events.responses.base import ResponseBase
7
+
8
+
9
+ @dataclasses.dataclass(kw_only=True, frozen=True, slots=True)
10
+ class ModificationAccepted(ResponseBase):
11
+ """
12
+ Event indicating that the requested modification has been acknowledged by
13
+ the broker and that the updated order parameters are active at the execution venue.
14
+
15
+ | Field | Type | Semantics |
16
+ |-----------------------|-----------------|----------------------------------------------------------------------------------------|
17
+ | `ts_event_ns` | `int` | Time at which the acceptance was observed by the system, as UTC epoch nanoseconds. |
18
+ | `ts_created_ns` | `int` | Time at which the event object was created, as UTC epoch nanoseconds. |
19
+ | `ts_broker_ns` | `int` | Time reported by the broker for the modification acceptance, as UTC epoch nanoseconds. |
20
+ | `associated_order_id` | `uuid.UUID` | Identifier of the modified order. |
21
+ | `broker_order_id` | `str` or `None` | Broker-assigned identifier of the order after modification, if reported. |
22
+ """
23
+
24
+ broker_order_id: str | None = None
25
+
26
+
27
+ @dataclasses.dataclass(kw_only=True, frozen=True, slots=True)
28
+ class ModificationRejected(ResponseBase):
29
+ """
30
+ Event indicating that the requested modification has been rejected by the broker.
31
+
32
+ | Field | Type | Semantics |
33
+ |-----------------------|--------------------------------------|------------------------------------------------------------------------------------|
34
+ | `ts_event_ns` | `int` | Time at which the rejection was observed by the system, as UTC epoch nanoseconds. |
35
+ | `ts_created_ns` | `int` | Time at which the event object was created, as UTC epoch nanoseconds. |
36
+ | `ts_broker_ns` | `int` | Time reported by the broker for the rejection, as UTC epoch nanoseconds. |
37
+ | `associated_order_id` | `uuid.UUID` | Identifier of the order associated with the rejected modification. |
38
+ | `rejection_reason` | `models.ModificationRejectionReason` | Canonical classification of the modification rejection cause. |
39
+ | `rejection_message` | `str` | Human-readable explanation provided by the broker. |
40
+ """
41
+
42
+ rejection_reason: models.ModificationRejectionReason
43
+ rejection_message: str
@@ -0,0 +1,42 @@
1
+ from __future__ import annotations
2
+
3
+ import dataclasses
4
+
5
+ from onesecondtrader import models
6
+ from onesecondtrader.events.responses.base import ResponseBase
7
+
8
+
9
+ @dataclasses.dataclass(kw_only=True, frozen=True, slots=True)
10
+ class OrderAccepted(ResponseBase):
11
+ """
12
+ Event indicating that the order has been accepted by the broker and is active at the execution venue.
13
+
14
+ | Field | Type | Semantics |
15
+ |-----------------------|-----------------|------------------------------------------------------------------------------------|
16
+ | `ts_event_ns` | `int` | Time at which the acceptance was observed by the system, as UTC epoch nanoseconds. |
17
+ | `ts_created_ns` | `int` | Time at which the event object was created, as UTC epoch nanoseconds. |
18
+ | `ts_broker_ns` | `int` | Time reported by the broker for the acceptance, as UTC epoch nanoseconds. |
19
+ | `associated_order_id` | `uuid.UUID` | Identifier of the accepted order. |
20
+ | `broker_order_id` | `str` or `None` | Broker-assigned identifier of the accepted order. |
21
+ """
22
+
23
+ broker_order_id: str | None = None
24
+
25
+
26
+ @dataclasses.dataclass(kw_only=True, frozen=True, slots=True)
27
+ class OrderRejected(ResponseBase):
28
+ """
29
+ Event indicating that the order has been rejected by the broker.
30
+
31
+ | Field | Type | Semantics |
32
+ |-----------------------|-------------------------------|------------------------------------------------------------------------------------|
33
+ | `ts_event_ns` | `int` | Time at which the rejection was observed by the system, as UTC epoch nanoseconds. |
34
+ | `ts_created_ns` | `int` | Time at which the event object was created, as UTC epoch nanoseconds. |
35
+ | `ts_broker_ns` | `int` | Time reported by the broker for the rejection, as UTC epoch nanoseconds. |
36
+ | `associated_order_id` | `uuid.UUID` | Identifier of the rejected order. |
37
+ | `rejection_reason` | `models.OrderRejectionReason` | Canonical classification of the rejection cause. |
38
+ | `rejection_message` | `str` | Human-readable explanation provided by the broker. |
39
+ """
40
+
41
+ rejection_reason: models.OrderRejectionReason
42
+ rejection_message: str
@@ -0,0 +1,9 @@
1
+ """
2
+ Provides a library of common technical indicators and a base class for creating custom ones.
3
+ """
4
+
5
+ from .base import Indicator
6
+
7
+ __all__ = [
8
+ "Indicator",
9
+ ]
@@ -0,0 +1,142 @@
1
+ from __future__ import annotations
2
+
3
+ import abc
4
+ import collections
5
+ import threading
6
+
7
+ import numpy as np
8
+
9
+ from onesecondtrader import events
10
+
11
+
12
+ class Indicator(abc.ABC):
13
+ """
14
+ Base class for scalar technical indicators with per-symbol history.
15
+
16
+ The class provides a thread-safe mechanism for storing and retrieving indicator values computed from incoming market bars, keyed by symbol.
17
+ It does not manage input windows or rolling computation state.
18
+
19
+ Subclasses define a stable indicator identifier via the `name` property and implement `_compute_indicator`, which computes a single scalar value per incoming bar.
20
+ Indicators with multiple conceptual outputs must be implemented as multiple single-output indicators (e.g. Bollinger Bands must be implemented via three separate indicators `BBUpper`, `BBMiddle`, and `BBLower`).
21
+
22
+ The update mechanism is thread-safe.
23
+ Indicator computation is performed outside the internal lock.
24
+ Subclasses that maintain internal state are responsible for ensuring its thread safety and must not access `_history_data`.
25
+
26
+ Indicator values are stored per symbol in bounded FIFO buffers.
27
+ Missing data and out-of-bounds access yield `numpy.nan`.
28
+
29
+ The `plot_at` attribute is an opaque identifier forwarded to the charting backend and has no intrinsic meaning within the indicator subsystem.
30
+ """
31
+
32
+ def __init__(self, max_history: int = 100, plot_at: int = 99) -> None:
33
+ """
34
+ Parameters:
35
+ max_history:
36
+ Maximum number of indicator values retained per symbol.
37
+ Cannot be less than 1.
38
+ plot_at:
39
+ Opaque plotting identifier forwarded to the charting backend.
40
+ """
41
+ self._lock = threading.Lock()
42
+ self._max_history = max(1, int(max_history))
43
+ self._history_data: dict[str, collections.deque[float]] = {}
44
+ self._plot_at = plot_at
45
+
46
+ @property
47
+ @abc.abstractmethod
48
+ def name(self) -> str:
49
+ """
50
+ Canonical indicator name.
51
+
52
+ Returns:
53
+ Stable identifier used for charting and downstream integration.
54
+ """
55
+ pass
56
+
57
+ @abc.abstractmethod
58
+ def _compute_indicator(self, incoming_bar: events.market.BarReceived) -> float:
59
+ """
60
+ Compute the indicator value for a single market bar.
61
+
62
+ This method is executed outside the internal lock.
63
+ Implementations must not access `_history_data` and must ensure thread safety of any internal computation state.
64
+
65
+ Parameters:
66
+ incoming_bar:
67
+ Market bar used as input for indicator computation.
68
+
69
+ Returns:
70
+ Computed indicator value.
71
+ """
72
+ pass
73
+
74
+ def update(self, incoming_bar: events.market.BarReceived) -> None:
75
+ """
76
+ Update the indicator with a new market bar.
77
+
78
+ The computed value is appended to the per-symbol history buffer.
79
+
80
+ Parameters:
81
+ incoming_bar:
82
+ Market bar triggering the update.
83
+ """
84
+ symbol = incoming_bar.symbol
85
+
86
+ value = self._compute_indicator(incoming_bar)
87
+
88
+ with self._lock:
89
+ if symbol not in self._history_data:
90
+ self._history_data[symbol] = collections.deque(maxlen=self._max_history)
91
+
92
+ self._history_data[symbol].append(value)
93
+
94
+ def latest(self, symbol: str) -> float:
95
+ """
96
+ Return the most recent indicator value for a symbol.
97
+
98
+ Parameters:
99
+ symbol:
100
+ Symbol identifier.
101
+
102
+ Returns:
103
+ Most recent value, or `numpy.nan` if unavailable.
104
+ """
105
+ return self[symbol, -1]
106
+
107
+ def __getitem__(self, key: tuple[str, int]) -> float:
108
+ """
109
+ Retrieve an indicator value by symbol and index.
110
+
111
+ Indexing follows standard Python sequence semantics.
112
+ Negative indices refer to positions relative to the most recent value.
113
+
114
+ Parameters:
115
+ key:
116
+ `(symbol, index)` pair specifying the symbol and history offset.
117
+
118
+ Returns:
119
+ Indicator value at the specified position, or `numpy.nan` if unavailable.
120
+ """
121
+ symbol, index = key
122
+
123
+ with self._lock:
124
+ history = self._history_data.get(symbol)
125
+
126
+ if history is None:
127
+ return np.nan
128
+
129
+ try:
130
+ return history[index]
131
+ except IndexError:
132
+ return np.nan
133
+
134
+ @property
135
+ def plot_at(self) -> int:
136
+ """
137
+ Plotting identifier.
138
+
139
+ Returns:
140
+ Opaque identifier consumed by the charting backend.
141
+ """
142
+ return self._plot_at
@@ -5,6 +5,19 @@ Defines the fundamental domain concepts used throughout the trading system.
5
5
  from .bar_fields import BarField
6
6
  from .bar_period import BarPeriod
7
7
  from .order_types import OrderType
8
+ from .rejection_reasons import (
9
+ OrderRejectionReason,
10
+ CancellationRejectionReason,
11
+ ModificationRejectionReason,
12
+ )
8
13
  from .trade_sides import TradeSide
9
14
 
10
- __all__ = ["BarField", "BarPeriod", "OrderType", "TradeSide"]
15
+ __all__ = [
16
+ "BarField",
17
+ "BarPeriod",
18
+ "OrderType",
19
+ "TradeSide",
20
+ "OrderRejectionReason",
21
+ "CancellationRejectionReason",
22
+ "ModificationRejectionReason",
23
+ ]
@@ -0,0 +1,48 @@
1
+ from __future__ import annotations
2
+
3
+ import enum
4
+
5
+
6
+ class OrderRejectionReason(enum.Enum):
7
+ """
8
+ Enumeration of canonical order rejection reasons.
9
+
10
+ This enumeration defines the system-level classification of order rejection causes.
11
+ It provides a stable, broker-agnostic taxonomy for programmatic handling of rejected orders.
12
+
13
+ | Value | Semantics |
14
+ |-----------|---------------------------------------------------------------------------|
15
+ | `UNKNOWN` | The rejection reason could not be classified into a known category. |
16
+ """
17
+
18
+ UNKNOWN = enum.auto()
19
+
20
+
21
+ class ModificationRejectionReason(enum.Enum):
22
+ """
23
+ Enumeration of canonical order modification rejection reasons.
24
+
25
+ This enumeration defines the system-level classification of reasons for which an order modification request may be rejected by a broker.
26
+ It provides a stable, broker-agnostic taxonomy intended for programmatic handling and observability of modification rejections.
27
+
28
+ | Value | Semantics |
29
+ |-----------|----------------------------------------------------------------------------------|
30
+ | `UNKNOWN` | The modification rejection reason could not be classified into a known category. |
31
+ """
32
+
33
+ UNKNOWN = enum.auto()
34
+
35
+
36
+ class CancellationRejectionReason(enum.Enum):
37
+ """
38
+ Enumeration of canonical order cancellation rejection reasons.
39
+
40
+ This enumeration defines the system-level classification of reasons for which an order cancellation request may be rejected by a broker.
41
+ It provides a stable, broker-agnostic taxonomy intended for programmatic handling and observability of cancellation rejections.
42
+
43
+ | Value | Semantics |
44
+ |-----------|----------------------------------------------------------------------------------|
45
+ | `UNKNOWN` | The cancellation rejection reason could not be classified into a known category. |
46
+ """
47
+
48
+ UNKNOWN = enum.auto()
@@ -7,7 +7,7 @@ class TradeSide(enum.Enum):
7
7
  """
8
8
  Enumeration of trade direction.
9
9
 
10
- `OrderSide` specifies the direction of change applied to the (net) signed position
10
+ `TradeSide` specifies the direction of change applied to the (net) signed position
11
11
  quantity from the perspective of the trading account.
12
12
 
13
13
  | Value | Semantics |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: onesecondtrader
3
- Version: 0.46.0
3
+ Version: 0.48.0
4
4
  Summary: The Trading Infrastructure Toolkit for Python. Research, simulate, and deploy algorithmic trading strategies — all in one place.
5
5
  License-File: LICENSE
6
6
  Author: Nils P. Kujath
@@ -0,0 +1,32 @@
1
+ onesecondtrader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ onesecondtrader/events/__init__.py,sha256=1T7hJA6afxClEXvvnbXtHu9iMyhduRdJZWlg4ObWaKE,222
3
+ onesecondtrader/events/base.py,sha256=WpLo1bSKJe7Poh2IuDDCiBYZo9vE8mkq3cQlUpyTXsY,850
4
+ onesecondtrader/events/market/__init__.py,sha256=49z6maexBIDkAjIfkLbYzSZWEbyTpQ_HEEgT0eacrDo,132
5
+ onesecondtrader/events/market/bar_processed.py,sha256=NsCDGC21ykmioJoITspoAuz5mesKP0_hkM4UumWk1eU,1993
6
+ onesecondtrader/events/market/bar_received.py,sha256=_LJEZ7P-AfYQEIkXYNt-toO9_WG_XTS2Y86tb-qdOVU,1961
7
+ onesecondtrader/events/orders/__init__.py,sha256=IgVmiVUGMwDlFnL1ItAgvPwmkqEMJDLgQK8aJIKQ1Ic,164
8
+ onesecondtrader/events/orders/base.py,sha256=3zTY8JMkXiOV35k0tp6rZZ9X7pDN40Btm0SFT5Mq3nw,1650
9
+ onesecondtrader/events/orders/expirations.py,sha256=nW_28REmNNyxLpKzkAhwnC_mMqw00SqRediiZW8Zyz8,1465
10
+ onesecondtrader/events/orders/fills.py,sha256=IDSCR7__AAPWm69noV9TeE2C8LukZv-ju8yjDfgmA9w,2772
11
+ onesecondtrader/events/requests/__init__.py,sha256=PWVAjNdgHWZArWXz9HU7E-6ZgMdfCpn4wAJiM9a5q6E,325
12
+ onesecondtrader/events/requests/base.py,sha256=XXdiOy946hW3LmF7lMShi10kPtGftl928aPMDwEdnao,1084
13
+ onesecondtrader/events/requests/order_cancellation.py,sha256=X_ZMOx09gz0Hf8hvDE1OahqK1SoH4nw9IOMJIdbbTKs,1029
14
+ onesecondtrader/events/requests/order_modification.py,sha256=Tks2mXn1bkuOVLsk98tTk3E2CTld6SF1IwmkCvGvsc8,1538
15
+ onesecondtrader/events/requests/order_submission.py,sha256=ejLBEWJ7pzhXWcTncK1x_ZJfcaC21CnuEz00wvi1q-8,2155
16
+ onesecondtrader/events/responses/__init__.py,sha256=ihg3zxjygLi-sA6wIbsm163ic8346WiAVtztb6ONy_4,409
17
+ onesecondtrader/events/responses/base.py,sha256=tXOP3lvd6EqpC7NbfIJinUCI-KMz6xsR1YSQw5qNddk,1241
18
+ onesecondtrader/events/responses/cancellations.py,sha256=HWF15Flz2JNOaZvArAjl9jLAt1NrQxB3MASG-0A2Z2Y,2941
19
+ onesecondtrader/events/responses/modifications.py,sha256=ZQyehdwgAIg6HMmpQ5T_bWZ7yc4nfSeVwAGQ3T2O5-A,2968
20
+ onesecondtrader/events/responses/orders.py,sha256=enkIUYRw9G3bzAq-it20XvXBew2gLg1mAm44m-12bns,2786
21
+ onesecondtrader/indicators/__init__.py,sha256=UZtt1iBm6MHCpycM1WyFMIrc_h5JaPazWkXtcOugzbk,162
22
+ onesecondtrader/indicators/base.py,sha256=G6z5H2k6KdrwMgjP7ARMom994rYy_1vJE4o0y0eQhl4,4649
23
+ onesecondtrader/models/__init__.py,sha256=XWL6aNLwAA2JQMoqK2PY-_CwigV0ighx4zwGQVdmtCs,529
24
+ onesecondtrader/models/bar_fields.py,sha256=GnLBL08ueUr35w2dAbKwOBWrdBS98OC9r0T2NifwTH8,646
25
+ onesecondtrader/models/bar_period.py,sha256=J8ncVtcAxR52uD0nbC8Knds_GUP5wiuNj5rAKq4vv-4,475
26
+ onesecondtrader/models/order_types.py,sha256=SiJamarLQ7zkHzHLLbd86I_TeZrQJ4QEIMqNHj4dxXU,737
27
+ onesecondtrader/models/rejection_reasons.py,sha256=BToLmPholsP9GcLGZ874nQJpehZ1yB1SFyYqlf3AOwc,2127
28
+ onesecondtrader/models/trade_sides.py,sha256=Pf9BpxoUxqgKC_EKAExfSqgfIIK9NW-RpJES0XHRF-8,583
29
+ onesecondtrader-0.48.0.dist-info/METADATA,sha256=Wyw2QP6Lxi8aW2XgCxI38tKsRnj5GHUs6SpJ3X-J2r0,9951
30
+ onesecondtrader-0.48.0.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
31
+ onesecondtrader-0.48.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
32
+ onesecondtrader-0.48.0.dist-info/RECORD,,
@@ -1,16 +0,0 @@
1
- onesecondtrader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- onesecondtrader/events/__init__.py,sha256=CTGyob-p2-VbvRZo4u21LbSYfk0cs78eEBRNsjW_CcE,127
3
- onesecondtrader/events/base.py,sha256=WpLo1bSKJe7Poh2IuDDCiBYZo9vE8mkq3cQlUpyTXsY,850
4
- onesecondtrader/events/requests/__init__.py,sha256=efXBe231UVtO7K5nMDP-MInG2aOTCDqkkCdjUhXwdKg,276
5
- onesecondtrader/events/requests/order_cancellation.py,sha256=bycQlLJ4GvOtpeRGbIy5munH8cGZrJUaCLdahA9UesE,1004
6
- onesecondtrader/events/requests/order_modification.py,sha256=eHwelFaLb_62n0riR_DTRXIFrYZpug-j0-jJCo-K2XQ,1576
7
- onesecondtrader/events/requests/order_submission.py,sha256=wUFJXlF5EcP14nQKPBoqO_yIfnCEko7Pb1NpNG2dNgQ,1987
8
- onesecondtrader/models/__init__.py,sha256=8eqxqKF49g_dgTG9EqT2czd_jnSafIG6wyniXPYFvF8,285
9
- onesecondtrader/models/bar_fields.py,sha256=GnLBL08ueUr35w2dAbKwOBWrdBS98OC9r0T2NifwTH8,646
10
- onesecondtrader/models/bar_period.py,sha256=J8ncVtcAxR52uD0nbC8Knds_GUP5wiuNj5rAKq4vv-4,475
11
- onesecondtrader/models/order_types.py,sha256=SiJamarLQ7zkHzHLLbd86I_TeZrQJ4QEIMqNHj4dxXU,737
12
- onesecondtrader/models/trade_sides.py,sha256=FPnkNeNm70fpkB4HxzYo0PwR6n_T6qdWXMINU0KR6Po,583
13
- onesecondtrader-0.46.0.dist-info/METADATA,sha256=FX8ZKVZ5usN_7qPS1ZK7y_-rxnKazdTqVEarrAihdrc,9951
14
- onesecondtrader-0.46.0.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
15
- onesecondtrader-0.46.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
16
- onesecondtrader-0.46.0.dist-info/RECORD,,