onesecondtrader 0.47.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.
- onesecondtrader/events/__init__.py +2 -1
- onesecondtrader/indicators/__init__.py +9 -0
- onesecondtrader/indicators/base.py +142 -0
- {onesecondtrader-0.47.0.dist-info → onesecondtrader-0.48.0.dist-info}/METADATA +1 -1
- {onesecondtrader-0.47.0.dist-info → onesecondtrader-0.48.0.dist-info}/RECORD +7 -5
- {onesecondtrader-0.47.0.dist-info → onesecondtrader-0.48.0.dist-info}/WHEEL +0 -0
- {onesecondtrader-0.47.0.dist-info → onesecondtrader-0.48.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: onesecondtrader
|
|
3
|
-
Version: 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
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
onesecondtrader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
onesecondtrader/events/__init__.py,sha256=
|
|
2
|
+
onesecondtrader/events/__init__.py,sha256=1T7hJA6afxClEXvvnbXtHu9iMyhduRdJZWlg4ObWaKE,222
|
|
3
3
|
onesecondtrader/events/base.py,sha256=WpLo1bSKJe7Poh2IuDDCiBYZo9vE8mkq3cQlUpyTXsY,850
|
|
4
4
|
onesecondtrader/events/market/__init__.py,sha256=49z6maexBIDkAjIfkLbYzSZWEbyTpQ_HEEgT0eacrDo,132
|
|
5
5
|
onesecondtrader/events/market/bar_processed.py,sha256=NsCDGC21ykmioJoITspoAuz5mesKP0_hkM4UumWk1eU,1993
|
|
@@ -18,13 +18,15 @@ onesecondtrader/events/responses/base.py,sha256=tXOP3lvd6EqpC7NbfIJinUCI-KMz6xsR
|
|
|
18
18
|
onesecondtrader/events/responses/cancellations.py,sha256=HWF15Flz2JNOaZvArAjl9jLAt1NrQxB3MASG-0A2Z2Y,2941
|
|
19
19
|
onesecondtrader/events/responses/modifications.py,sha256=ZQyehdwgAIg6HMmpQ5T_bWZ7yc4nfSeVwAGQ3T2O5-A,2968
|
|
20
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
|
|
21
23
|
onesecondtrader/models/__init__.py,sha256=XWL6aNLwAA2JQMoqK2PY-_CwigV0ighx4zwGQVdmtCs,529
|
|
22
24
|
onesecondtrader/models/bar_fields.py,sha256=GnLBL08ueUr35w2dAbKwOBWrdBS98OC9r0T2NifwTH8,646
|
|
23
25
|
onesecondtrader/models/bar_period.py,sha256=J8ncVtcAxR52uD0nbC8Knds_GUP5wiuNj5rAKq4vv-4,475
|
|
24
26
|
onesecondtrader/models/order_types.py,sha256=SiJamarLQ7zkHzHLLbd86I_TeZrQJ4QEIMqNHj4dxXU,737
|
|
25
27
|
onesecondtrader/models/rejection_reasons.py,sha256=BToLmPholsP9GcLGZ874nQJpehZ1yB1SFyYqlf3AOwc,2127
|
|
26
28
|
onesecondtrader/models/trade_sides.py,sha256=Pf9BpxoUxqgKC_EKAExfSqgfIIK9NW-RpJES0XHRF-8,583
|
|
27
|
-
onesecondtrader-0.
|
|
28
|
-
onesecondtrader-0.
|
|
29
|
-
onesecondtrader-0.
|
|
30
|
-
onesecondtrader-0.
|
|
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,,
|
|
File without changes
|
|
File without changes
|