onesecondtrader 0.48.0__tar.gz → 0.49.0__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.
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/PKG-INFO +1 -1
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/pyproject.toml +1 -1
- onesecondtrader-0.49.0/src/onesecondtrader/indicators/__init__.py +17 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/indicators/base.py +1 -1
- onesecondtrader-0.49.0/src/onesecondtrader/indicators/market_fields.py +166 -0
- onesecondtrader-0.49.0/src/onesecondtrader/indicators/moving_averages.py +104 -0
- onesecondtrader-0.48.0/src/onesecondtrader/indicators/__init__.py +0 -9
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/LICENSE +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/README.md +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/__init__.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/__init__.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/base.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/market/__init__.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/market/bar_processed.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/market/bar_received.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/orders/__init__.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/orders/base.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/orders/expirations.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/orders/fills.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/requests/__init__.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/requests/base.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/requests/order_cancellation.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/requests/order_modification.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/requests/order_submission.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/responses/__init__.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/responses/base.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/responses/cancellations.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/responses/modifications.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/responses/orders.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/models/__init__.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/models/bar_fields.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/models/bar_period.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/models/order_types.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/models/rejection_reasons.py +0 -0
- {onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/models/trade_sides.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: onesecondtrader
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.49.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,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "onesecondtrader"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.49.0"
|
|
4
4
|
description = "The Trading Infrastructure Toolkit for Python. Research, simulate, and deploy algorithmic trading strategies — all in one place."
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Nils P. Kujath",email = "63961429+NilsKujath@users.noreply.github.com"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Provides a library of common technical indicators and a base class for creating custom ones.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .base import IndicatorBase
|
|
6
|
+
from .moving_averages import SimpleMovingAverage
|
|
7
|
+
from .market_fields import Open, High, Low, Close, Volume
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"IndicatorBase",
|
|
11
|
+
"SimpleMovingAverage",
|
|
12
|
+
"Open",
|
|
13
|
+
"High",
|
|
14
|
+
"Low",
|
|
15
|
+
"Close",
|
|
16
|
+
"Volume",
|
|
17
|
+
]
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from onesecondtrader import events, indicators
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Open(indicators.IndicatorBase):
|
|
9
|
+
"""
|
|
10
|
+
Open price indicator.
|
|
11
|
+
|
|
12
|
+
This indicator exposes the open price of each incoming market bar as a scalar time series.
|
|
13
|
+
Values are stored per symbol and can be accessed historically via the indicator interface.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def name(self) -> str:
|
|
18
|
+
"""
|
|
19
|
+
Canonical indicator name.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
Fixed identifier for the open price indicator.
|
|
23
|
+
"""
|
|
24
|
+
return "OPEN"
|
|
25
|
+
|
|
26
|
+
def _compute_indicator(self, incoming_bar: events.market.BarReceived) -> float:
|
|
27
|
+
"""
|
|
28
|
+
Extract the open price from an incoming market bar.
|
|
29
|
+
|
|
30
|
+
Parameters:
|
|
31
|
+
incoming_bar:
|
|
32
|
+
Market bar used as input.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
Open price of the bar.
|
|
36
|
+
"""
|
|
37
|
+
return incoming_bar.open
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class High(indicators.IndicatorBase):
|
|
41
|
+
"""
|
|
42
|
+
High price indicator.
|
|
43
|
+
|
|
44
|
+
This indicator exposes the high price of each incoming market bar as a scalar time series.
|
|
45
|
+
Values are stored per symbol and can be accessed historically via the indicator interface.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def name(self) -> str:
|
|
50
|
+
"""
|
|
51
|
+
Canonical indicator name.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
Fixed identifier for the high price indicator.
|
|
55
|
+
"""
|
|
56
|
+
return "HIGH"
|
|
57
|
+
|
|
58
|
+
def _compute_indicator(self, incoming_bar: events.market.BarReceived) -> float:
|
|
59
|
+
"""
|
|
60
|
+
Extract the high price from an incoming market bar.
|
|
61
|
+
|
|
62
|
+
Parameters:
|
|
63
|
+
incoming_bar:
|
|
64
|
+
Market bar used as input.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
High price of the bar.
|
|
68
|
+
"""
|
|
69
|
+
return incoming_bar.high
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class Low(indicators.IndicatorBase):
|
|
73
|
+
"""
|
|
74
|
+
Low price indicator.
|
|
75
|
+
|
|
76
|
+
This indicator exposes the low price of each incoming market bar as a scalar time series.
|
|
77
|
+
Values are stored per symbol and can be accessed historically via the indicator interface.
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def name(self) -> str:
|
|
82
|
+
"""
|
|
83
|
+
Canonical indicator name.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
Fixed identifier for the low price indicator.
|
|
87
|
+
"""
|
|
88
|
+
return "LOW"
|
|
89
|
+
|
|
90
|
+
def _compute_indicator(self, incoming_bar: events.market.BarReceived) -> float:
|
|
91
|
+
"""
|
|
92
|
+
Extract the low price from an incoming market bar.
|
|
93
|
+
|
|
94
|
+
Parameters:
|
|
95
|
+
incoming_bar:
|
|
96
|
+
Market bar used as input.
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
Low price of the bar.
|
|
100
|
+
"""
|
|
101
|
+
return incoming_bar.low
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class Close(indicators.IndicatorBase):
|
|
105
|
+
"""
|
|
106
|
+
Close price indicator.
|
|
107
|
+
|
|
108
|
+
This indicator exposes the close price of each incoming market bar as a scalar time series.
|
|
109
|
+
Values are stored per symbol and can be accessed historically via the indicator interface.
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
@property
|
|
113
|
+
def name(self) -> str:
|
|
114
|
+
"""
|
|
115
|
+
Canonical indicator name.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
Fixed identifier for the close price indicator.
|
|
119
|
+
"""
|
|
120
|
+
return "CLOSE"
|
|
121
|
+
|
|
122
|
+
def _compute_indicator(self, incoming_bar: events.market.BarReceived) -> float:
|
|
123
|
+
"""
|
|
124
|
+
Extract the close price from an incoming market bar.
|
|
125
|
+
|
|
126
|
+
Parameters:
|
|
127
|
+
incoming_bar:
|
|
128
|
+
Market bar used as input.
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
Close price of the bar.
|
|
132
|
+
"""
|
|
133
|
+
return incoming_bar.close
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class Volume(indicators.IndicatorBase):
|
|
137
|
+
"""
|
|
138
|
+
Volume indicator.
|
|
139
|
+
|
|
140
|
+
This indicator exposes the traded volume of each incoming market bar as a scalar time series.
|
|
141
|
+
Values are stored per symbol and can be accessed historically via the indicator interface.
|
|
142
|
+
Missing volume values yield `numpy.nan`.
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
@property
|
|
146
|
+
def name(self) -> str:
|
|
147
|
+
"""
|
|
148
|
+
Canonical indicator name.
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
Fixed identifier for the volume indicator.
|
|
152
|
+
"""
|
|
153
|
+
return "VOLUME"
|
|
154
|
+
|
|
155
|
+
def _compute_indicator(self, incoming_bar: events.market.BarReceived) -> float:
|
|
156
|
+
"""
|
|
157
|
+
Extract the volume from an incoming market bar.
|
|
158
|
+
|
|
159
|
+
Parameters:
|
|
160
|
+
incoming_bar:
|
|
161
|
+
Market bar used as input.
|
|
162
|
+
|
|
163
|
+
Returns:
|
|
164
|
+
Volume of the bar, or `numpy.nan` if unavailable.
|
|
165
|
+
"""
|
|
166
|
+
return float(incoming_bar.volume) if incoming_bar.volume is not None else np.nan
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import collections
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
from onesecondtrader import events, indicators, models
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SimpleMovingAverage(indicators.IndicatorBase):
|
|
10
|
+
"""
|
|
11
|
+
Simple Moving Average (SMA) indicator.
|
|
12
|
+
|
|
13
|
+
This indicator computes the arithmetic mean of a selected bar field over a fixed rolling window.
|
|
14
|
+
One scalar value is produced per incoming bar and stored per symbol.
|
|
15
|
+
|
|
16
|
+
The rolling window is maintained independently for each symbol.
|
|
17
|
+
Until the window is fully populated, the indicator yields `numpy.nan`.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
period: int = 200,
|
|
23
|
+
max_history: int = 100,
|
|
24
|
+
bar_field: models.BarField = models.BarField.CLOSE,
|
|
25
|
+
plot_at: int = 0,
|
|
26
|
+
) -> None:
|
|
27
|
+
"""
|
|
28
|
+
Parameters:
|
|
29
|
+
period:
|
|
30
|
+
Window size used to compute the moving average.
|
|
31
|
+
max_history:
|
|
32
|
+
Maximum number of computed indicator values retained per symbol.
|
|
33
|
+
bar_field:
|
|
34
|
+
Bar field used as the input series.
|
|
35
|
+
plot_at:
|
|
36
|
+
Opaque plotting identifier forwarded to the charting backend.
|
|
37
|
+
"""
|
|
38
|
+
super().__init__(max_history=max_history, plot_at=plot_at)
|
|
39
|
+
|
|
40
|
+
self.period: int = max(1, int(period))
|
|
41
|
+
self.bar_field: models.BarField = bar_field
|
|
42
|
+
self._window: dict[str, collections.deque[float]] = {}
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def name(self) -> str:
|
|
46
|
+
"""
|
|
47
|
+
Canonical indicator name.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
Identifier encoding the indicator type, period, and bar field.
|
|
51
|
+
"""
|
|
52
|
+
return f"SMA_{self.period}_{self.bar_field.name}"
|
|
53
|
+
|
|
54
|
+
def _compute_indicator(self, incoming_bar: events.market.BarReceived) -> float:
|
|
55
|
+
"""
|
|
56
|
+
Compute the simple moving average for a single received bar.
|
|
57
|
+
|
|
58
|
+
Parameters:
|
|
59
|
+
incoming_bar:
|
|
60
|
+
Market bar used as input for the computation.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
Simple moving average value, or `numpy.nan` if the rolling window is not yet fully populated.
|
|
64
|
+
"""
|
|
65
|
+
symbol = incoming_bar.symbol
|
|
66
|
+
if symbol not in self._window:
|
|
67
|
+
self._window[symbol] = collections.deque(maxlen=self.period)
|
|
68
|
+
|
|
69
|
+
window = self._window[symbol]
|
|
70
|
+
value = self._extract_field(incoming_bar)
|
|
71
|
+
window.append(value)
|
|
72
|
+
|
|
73
|
+
if len(window) < self.period:
|
|
74
|
+
return np.nan
|
|
75
|
+
return sum(window) / self.period
|
|
76
|
+
|
|
77
|
+
def _extract_field(self, incoming_bar: events.market.BarReceived) -> float:
|
|
78
|
+
"""
|
|
79
|
+
Extract the configured bar field from an incoming bar.
|
|
80
|
+
|
|
81
|
+
Parameters:
|
|
82
|
+
incoming_bar:
|
|
83
|
+
Market bar providing the input data.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
Extracted field value, or `numpy.nan` if unavailable.
|
|
87
|
+
"""
|
|
88
|
+
match self.bar_field:
|
|
89
|
+
case models.BarField.OPEN:
|
|
90
|
+
return incoming_bar.open
|
|
91
|
+
case models.BarField.HIGH:
|
|
92
|
+
return incoming_bar.high
|
|
93
|
+
case models.BarField.LOW:
|
|
94
|
+
return incoming_bar.low
|
|
95
|
+
case models.BarField.CLOSE:
|
|
96
|
+
return incoming_bar.close
|
|
97
|
+
case models.BarField.VOLUME:
|
|
98
|
+
return (
|
|
99
|
+
float(incoming_bar.volume)
|
|
100
|
+
if incoming_bar.volume is not None
|
|
101
|
+
else np.nan
|
|
102
|
+
)
|
|
103
|
+
case _:
|
|
104
|
+
return incoming_bar.close
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/market/__init__.py
RENAMED
|
File without changes
|
{onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/market/bar_processed.py
RENAMED
|
File without changes
|
{onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/market/bar_received.py
RENAMED
|
File without changes
|
{onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/orders/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/orders/expirations.py
RENAMED
|
File without changes
|
{onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/orders/fills.py
RENAMED
|
File without changes
|
{onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/requests/__init__.py
RENAMED
|
File without changes
|
{onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/requests/base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/responses/__init__.py
RENAMED
|
File without changes
|
{onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/responses/base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/events/responses/orders.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{onesecondtrader-0.48.0 → onesecondtrader-0.49.0}/src/onesecondtrader/models/rejection_reasons.py
RENAMED
|
File without changes
|
|
File without changes
|