onesecondtrader 0.12.1__py3-none-any.whl → 0.13.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/core/models.py +27 -6
- onesecondtrader/indicators/moving_averages.py +132 -0
- {onesecondtrader-0.12.1.dist-info → onesecondtrader-0.13.0.dist-info}/METADATA +1 -1
- {onesecondtrader-0.12.1.dist-info → onesecondtrader-0.13.0.dist-info}/RECORD +6 -5
- {onesecondtrader-0.12.1.dist-info → onesecondtrader-0.13.0.dist-info}/WHEEL +0 -0
- {onesecondtrader-0.12.1.dist-info → onesecondtrader-0.13.0.dist-info}/licenses/LICENSE +0 -0
onesecondtrader/core/models.py
CHANGED
|
@@ -63,8 +63,7 @@ class TimeInForce(enum.Enum):
|
|
|
63
63
|
| `FOK` | `enum.auto()` | Fill entire order immediately or cancel (Fill-or-Kill) |
|
|
64
64
|
| `GTC` | `enum.auto()` | Active until explicitly cancelled (Good-Till-Cancelled) |
|
|
65
65
|
| `GTD` | `enum.auto()` | Active until specified date (Good-Till-Date) |
|
|
66
|
-
| `IOC` | `enum.auto()` | Execute available quantity immediately, cancel rest
|
|
67
|
-
(Immediate-or-Cancel) |
|
|
66
|
+
| `IOC` | `enum.auto()` | Execute available quantity immediately, cancel rest (Immediate-or-Cancel) |
|
|
68
67
|
"""
|
|
69
68
|
|
|
70
69
|
DAY = enum.auto()
|
|
@@ -102,10 +101,8 @@ class OrderLifecycleState(enum.Enum):
|
|
|
102
101
|
|
|
103
102
|
| Enum | Value | Description |
|
|
104
103
|
|------|-------|-------------|
|
|
105
|
-
| `PENDING` | `enum.auto()` | Order has been submitted, but not yet acknowledged by
|
|
106
|
-
|
|
107
|
-
| `OPEN` | `enum.auto()` | Order has been acknowledged by the broker, but not yet
|
|
108
|
-
filled or cancelled |
|
|
104
|
+
| `PENDING` | `enum.auto()` | Order has been submitted, but not yet acknowledged by the broker |
|
|
105
|
+
| `OPEN` | `enum.auto()` | Order has been acknowledged by the broker, but not yet filled or cancelled |
|
|
109
106
|
| `FILLED` | `enum.auto()` | Order has been filled |
|
|
110
107
|
| `CANCELLED` | `enum.auto()` | Order has been cancelled |
|
|
111
108
|
"""
|
|
@@ -165,3 +162,27 @@ class RecordType(enum.Enum):
|
|
|
165
162
|
return "daily bars"
|
|
166
163
|
case _:
|
|
167
164
|
return f"unknown ({rtype})"
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class XMAMode(enum.Enum):
|
|
168
|
+
"""
|
|
169
|
+
Enum for moving average modes.
|
|
170
|
+
|
|
171
|
+
**Attributes:**
|
|
172
|
+
|
|
173
|
+
| Enum | Value | Description |
|
|
174
|
+
|------|-------|-------------|
|
|
175
|
+
| `OPEN` | `enum.auto()` | Open price |
|
|
176
|
+
| `HIGH` | `enum.auto()` | High price |
|
|
177
|
+
| `LOW` | `enum.auto()` | Low price |
|
|
178
|
+
| `CLOSE` | `enum.auto()` | Close price |
|
|
179
|
+
| `TYPICAL_PRICE` | `enum.auto()` | Typical price ((H+ L + C) / 3) |
|
|
180
|
+
| `WEIGHTED_CLOSE` | `enum.auto()` | Weighted close price ((H + L + 2*C) / 4) |
|
|
181
|
+
"""
|
|
182
|
+
|
|
183
|
+
OPEN = enum.auto()
|
|
184
|
+
HIGH = enum.auto()
|
|
185
|
+
LOW = enum.auto()
|
|
186
|
+
CLOSE = enum.auto()
|
|
187
|
+
TYPICAL_PRICE = enum.auto()
|
|
188
|
+
WEIGHTED_CLOSE = enum.auto()
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module provides various moving average indicators.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import collections
|
|
7
|
+
from onesecondtrader.indicators import base_indicator
|
|
8
|
+
from onesecondtrader.core import models
|
|
9
|
+
from onesecondtrader.monitoring import console
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SimpleMovingAverage(base_indicator.BaseIndicator):
|
|
13
|
+
"""
|
|
14
|
+
Simple Moving Average (SMA) indicator for different OHLC-data related time series,
|
|
15
|
+
the possible modes for the SMA calculation are indicated in the
|
|
16
|
+
`core.models.XMAMode` enum (currently: `open`, `high`, `low`, `close`,
|
|
17
|
+
`typical_price`, `weighted close`).
|
|
18
|
+
|
|
19
|
+
Examples:
|
|
20
|
+
>>> from onesecondtrader.indicators import moving_averages
|
|
21
|
+
>>> from onesecondtrader.core import models
|
|
22
|
+
>>> sma = moving_averages.SimpleMovingAverage(
|
|
23
|
+
... period=3, mode=models.XMAMode.CLOSE
|
|
24
|
+
... )
|
|
25
|
+
>>> bar1 = models.Bar(
|
|
26
|
+
... open=100.0, high=101.0, low=99.0, close=100.0, volume=1000
|
|
27
|
+
... )
|
|
28
|
+
>>> sma.update(bar1)
|
|
29
|
+
>>> import numpy as np
|
|
30
|
+
>>> np.isnan(sma.latest)
|
|
31
|
+
True
|
|
32
|
+
>>> bar2 = models.Bar(
|
|
33
|
+
... open=100.0, high=102.0, low=100.0, close=101.0, volume=1500
|
|
34
|
+
... )
|
|
35
|
+
>>> sma.update(bar2)
|
|
36
|
+
>>> np.isnan(sma.latest)
|
|
37
|
+
True
|
|
38
|
+
>>> bar3 = models.Bar(
|
|
39
|
+
... open=101.0, high=103.0, low=101.0, close=102.0, volume=2000
|
|
40
|
+
... )
|
|
41
|
+
>>> sma.update(bar3)
|
|
42
|
+
>>> np.isnan(sma.latest)
|
|
43
|
+
False
|
|
44
|
+
>>> sma.latest
|
|
45
|
+
101.0
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
def __init__(
|
|
49
|
+
self,
|
|
50
|
+
period: int,
|
|
51
|
+
mode: models.XMAMode = models.XMAMode.CLOSE,
|
|
52
|
+
max_history: int = 100,
|
|
53
|
+
) -> None:
|
|
54
|
+
"""
|
|
55
|
+
Initialize the indicator with a period and a mode.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
period (int): Period of the moving average. Will be set to 1 if < 1.
|
|
59
|
+
mode (models.XMAMode): Mode of the moving average. Defaults to `CLOSE`.
|
|
60
|
+
max_history (int): Maximum lookback history length. Defaults to 100.
|
|
61
|
+
|
|
62
|
+
Attributes:
|
|
63
|
+
self.period (int): Period of the moving average.
|
|
64
|
+
self.mode (models.XMAMode): Mode of the moving average.
|
|
65
|
+
"""
|
|
66
|
+
if period < 1:
|
|
67
|
+
console.logger.warning(
|
|
68
|
+
f"Period must be >= 1, got {period}; defaulting to 1"
|
|
69
|
+
)
|
|
70
|
+
period = 1
|
|
71
|
+
|
|
72
|
+
super().__init__(max_history=max_history)
|
|
73
|
+
self.period: int = period
|
|
74
|
+
self.mode: models.XMAMode = mode
|
|
75
|
+
self._window: collections.deque[float] = collections.deque(maxlen=self.period)
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def name(self) -> str:
|
|
79
|
+
return f"SMA_{self.period}_{self.mode.name}"
|
|
80
|
+
|
|
81
|
+
def _compute_indicator(self, incoming_bar: models.Bar) -> float:
|
|
82
|
+
"""
|
|
83
|
+
Compute the specified simple moving average based on the incoming bar.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
incoming_bar (models.Bar): Incoming bar with OHLCV data.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
float: Simple moving average value, or np.nan if insufficient data or
|
|
90
|
+
errors occur.
|
|
91
|
+
"""
|
|
92
|
+
try:
|
|
93
|
+
mode = self.mode
|
|
94
|
+
if mode is models.XMAMode.OPEN:
|
|
95
|
+
current_value = incoming_bar.open
|
|
96
|
+
elif mode is models.XMAMode.HIGH:
|
|
97
|
+
current_value = incoming_bar.high
|
|
98
|
+
elif mode is models.XMAMode.LOW:
|
|
99
|
+
current_value = incoming_bar.low
|
|
100
|
+
elif mode is models.XMAMode.CLOSE:
|
|
101
|
+
current_value = incoming_bar.close
|
|
102
|
+
elif mode is models.XMAMode.TYPICAL_PRICE:
|
|
103
|
+
current_value = (
|
|
104
|
+
incoming_bar.high + incoming_bar.low + incoming_bar.close
|
|
105
|
+
) / 3.0
|
|
106
|
+
elif mode is models.XMAMode.WEIGHTED_CLOSE:
|
|
107
|
+
current_value = (
|
|
108
|
+
incoming_bar.high + incoming_bar.low + 2.0 * incoming_bar.close
|
|
109
|
+
) / 4.0
|
|
110
|
+
else:
|
|
111
|
+
console.logger.warning(
|
|
112
|
+
f"Unsupported XMAMode: {mode}; using close price"
|
|
113
|
+
)
|
|
114
|
+
current_value = incoming_bar.close
|
|
115
|
+
|
|
116
|
+
if not np.isfinite(current_value):
|
|
117
|
+
console.logger.warning(
|
|
118
|
+
f"Invalid value extracted: {current_value} (mode={mode.name}); "
|
|
119
|
+
f"using np.nan"
|
|
120
|
+
)
|
|
121
|
+
return np.nan
|
|
122
|
+
|
|
123
|
+
with self._lock:
|
|
124
|
+
self._window.append(current_value)
|
|
125
|
+
if len(self._window) < self.period:
|
|
126
|
+
return np.nan
|
|
127
|
+
sma_value = sum(self._window) / self.period
|
|
128
|
+
return sma_value
|
|
129
|
+
|
|
130
|
+
except Exception as e:
|
|
131
|
+
console.logger.warning(f"SMA calculation failed: {e}; returning np.nan")
|
|
132
|
+
return np.nan
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: onesecondtrader
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.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,12 +1,13 @@
|
|
|
1
1
|
onesecondtrader/__init__.py,sha256=TNqlT20sH46-J7F6giBxwWYG1-wFZZt7toDbZeQK6KQ,210
|
|
2
2
|
onesecondtrader/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
onesecondtrader/core/models.py,sha256=
|
|
3
|
+
onesecondtrader/core/models.py,sha256=253_5DtMS4mQA1IAVrEbw-rpCcyyKtB3HaORFyF2jdU,4823
|
|
4
4
|
onesecondtrader/core/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
onesecondtrader/datafeeds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
onesecondtrader/datafeeds/base_datafeed.py,sha256=QGXtkVUVN7PsDYeIH8h7Hi_kiDDFcqRyW8K8LzZkRTk,1394
|
|
7
7
|
onesecondtrader/datafeeds/csv_datafeed.py,sha256=WMoZpoian_93CdAzo36hJoF15T0ywRADfuFQcfsPQNc,10957
|
|
8
8
|
onesecondtrader/indicators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
onesecondtrader/indicators/base_indicator.py,sha256=eGv5_WYOSsuLXX8MbnyE3_Y8owH-2bpUT_GczOXDHVE,4359
|
|
10
|
+
onesecondtrader/indicators/moving_averages.py,sha256=h6lKaIgpILF0zrvU17Ml4xo_WnhzoK2StFCw46YWKWU,4674
|
|
10
11
|
onesecondtrader/messaging/__init__.py,sha256=9GBHlh6pXweknEacXVBvzpdoTJgVyb3ROLqe1Fhz2ww,179
|
|
11
12
|
onesecondtrader/messaging/eventbus.py,sha256=R2K85INeYVwJ1tMOybC3WpRraK0ZKVe8WehCbAzzznU,19359
|
|
12
13
|
onesecondtrader/messaging/events.py,sha256=eaWXQQIUnRNOR-9n5-6lyLbZ6bUtzjD4GI567U_vh4g,23625
|
|
@@ -14,7 +15,7 @@ onesecondtrader/monitoring/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
|
14
15
|
onesecondtrader/monitoring/console.py,sha256=1mrojXkyL4ro7ebkvDMGNQiCL-93WEylRuwnfmEKzVs,299
|
|
15
16
|
onesecondtrader/monitoring/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
17
|
onesecondtrader/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
-
onesecondtrader-0.
|
|
18
|
-
onesecondtrader-0.
|
|
19
|
-
onesecondtrader-0.
|
|
20
|
-
onesecondtrader-0.
|
|
18
|
+
onesecondtrader-0.13.0.dist-info/METADATA,sha256=4dSKCGtQCOiEiG4y06SVtaYNY9epLoNPfv1QWtj9T2g,9638
|
|
19
|
+
onesecondtrader-0.13.0.dist-info/WHEEL,sha256=M5asmiAlL6HEcOq52Yi5mmk9KmTVjY2RDPtO4p9DMrc,88
|
|
20
|
+
onesecondtrader-0.13.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
21
|
+
onesecondtrader-0.13.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|