onesecondtrader 0.11.0__tar.gz → 0.12.1__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.11.0 → onesecondtrader-0.12.1}/PKG-INFO +4 -2
- {onesecondtrader-0.11.0 → onesecondtrader-0.12.1}/pyproject.toml +1 -1
- onesecondtrader-0.12.1/src/onesecondtrader/indicators/base_indicator.py +136 -0
- onesecondtrader-0.12.1/src/onesecondtrader/monitoring/py.typed +0 -0
- onesecondtrader-0.12.1/src/onesecondtrader/py.typed +0 -0
- onesecondtrader-0.11.0/src/onesecondtrader/datafeeds/__init__.py +0 -2
- {onesecondtrader-0.11.0 → onesecondtrader-0.12.1}/LICENSE +0 -0
- {onesecondtrader-0.11.0 → onesecondtrader-0.12.1}/README.md +0 -0
- {onesecondtrader-0.11.0 → onesecondtrader-0.12.1}/src/onesecondtrader/__init__.py +0 -0
- {onesecondtrader-0.11.0 → onesecondtrader-0.12.1}/src/onesecondtrader/core/__init__.py +0 -0
- {onesecondtrader-0.11.0 → onesecondtrader-0.12.1}/src/onesecondtrader/core/models.py +0 -0
- {onesecondtrader-0.11.0 → onesecondtrader-0.12.1}/src/onesecondtrader/core/py.typed +0 -0
- {onesecondtrader-0.11.0/src/onesecondtrader/monitoring → onesecondtrader-0.12.1/src/onesecondtrader/datafeeds}/__init__.py +0 -0
- {onesecondtrader-0.11.0 → onesecondtrader-0.12.1}/src/onesecondtrader/datafeeds/base_datafeed.py +0 -0
- {onesecondtrader-0.11.0 → onesecondtrader-0.12.1}/src/onesecondtrader/datafeeds/csv_datafeed.py +0 -0
- /onesecondtrader-0.11.0/src/onesecondtrader/monitoring/py.typed → /onesecondtrader-0.12.1/src/onesecondtrader/indicators/__init__.py +0 -0
- {onesecondtrader-0.11.0 → onesecondtrader-0.12.1}/src/onesecondtrader/messaging/__init__.py +0 -0
- {onesecondtrader-0.11.0 → onesecondtrader-0.12.1}/src/onesecondtrader/messaging/eventbus.py +0 -0
- {onesecondtrader-0.11.0 → onesecondtrader-0.12.1}/src/onesecondtrader/messaging/events.py +0 -0
- /onesecondtrader-0.11.0/src/onesecondtrader/py.typed → /onesecondtrader-0.12.1/src/onesecondtrader/monitoring/__init__.py +0 -0
- {onesecondtrader-0.11.0 → onesecondtrader-0.12.1}/src/onesecondtrader/monitoring/console.py +0 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: onesecondtrader
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.12.1
|
|
4
4
|
Summary: The Trading Infrastructure Toolkit for Python. Research, simulate, and deploy algorithmic trading strategies — all in one place.
|
|
5
|
+
License-File: LICENSE
|
|
5
6
|
Author: Nils P. Kujath
|
|
6
7
|
Author-email: 63961429+NilsKujath@users.noreply.github.com
|
|
7
8
|
Requires-Python: >=3.11
|
|
@@ -9,6 +10,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
9
10
|
Classifier: Programming Language :: Python :: 3.11
|
|
10
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
11
12
|
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
12
14
|
Requires-Dist: pandas (>=2.3.1,<3.0.0)
|
|
13
15
|
Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
|
|
14
16
|
Description-Content-Type: text/markdown
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "onesecondtrader"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.12.1"
|
|
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,136 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module provides the base class for all indicators.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import abc
|
|
6
|
+
import collections
|
|
7
|
+
import threading
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
from onesecondtrader.core import models
|
|
11
|
+
from onesecondtrader.monitoring import console
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BaseIndicator(abc.ABC):
|
|
15
|
+
"""
|
|
16
|
+
Base class for all indicators.
|
|
17
|
+
|
|
18
|
+
If new market data is received, the indicator is updated by calling the
|
|
19
|
+
`update(incoming_bar)` method.
|
|
20
|
+
When programming a new indicator, only the `name` property and the
|
|
21
|
+
`_compute_indicator()` method need to be implemented.
|
|
22
|
+
|
|
23
|
+
Examples:
|
|
24
|
+
>>> from onesecondtrader.indicators import base_indicator
|
|
25
|
+
>>> from onesecondtrader.core import models
|
|
26
|
+
>>> class DummyCloseIndicator(base_indicator.BaseIndicator):
|
|
27
|
+
... @property
|
|
28
|
+
... def name(self) -> str:
|
|
29
|
+
... return "dummy_close_indicator"
|
|
30
|
+
... def _compute_indicator(self, incoming_bar: models.Bar):
|
|
31
|
+
... return incoming_bar.close
|
|
32
|
+
...
|
|
33
|
+
>>> dummy_close_indicator = DummyCloseIndicator(max_history=10)
|
|
34
|
+
>>> incoming_bar = models.Bar(
|
|
35
|
+
... open=100.0, high=101.0, low=99.0, close=100.5, volume=10000
|
|
36
|
+
... )
|
|
37
|
+
>>> dummy_close_indicator.update(incoming_bar)
|
|
38
|
+
>>> dummy_close_indicator[0]
|
|
39
|
+
100.5
|
|
40
|
+
>>> dummy_close_indicator[-1]
|
|
41
|
+
nan
|
|
42
|
+
>>> next_incoming_bar = models.Bar(
|
|
43
|
+
... open=100.0, high=101.0, low=99.0, close=101.0, volume=10000
|
|
44
|
+
... )
|
|
45
|
+
>>> dummy_close_indicator.update(next_incoming_bar)
|
|
46
|
+
>>> dummy_close_indicator[0]
|
|
47
|
+
101.0
|
|
48
|
+
>>> dummy_close_indicator[-1]
|
|
49
|
+
100.5
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
def __init__(self, max_history: int = 100) -> None:
|
|
53
|
+
"""
|
|
54
|
+
Initialize the indicator with a maximum lookback history length.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
max_history (int): Maximum lookback history length as number of periods.
|
|
58
|
+
Defaults to 100.
|
|
59
|
+
|
|
60
|
+
Attributes:
|
|
61
|
+
self._lock (threading.Lock): Lock to protect concurrent access to the
|
|
62
|
+
indicator's state.
|
|
63
|
+
self._history (collections.deque): Deque to store the lookback history.
|
|
64
|
+
"""
|
|
65
|
+
if max_history < 1:
|
|
66
|
+
console.logger.warning(
|
|
67
|
+
f"max_history must be >= 1, got {max_history}; defaulting to 1"
|
|
68
|
+
)
|
|
69
|
+
max_history = 1
|
|
70
|
+
self._lock: threading.Lock = threading.Lock()
|
|
71
|
+
|
|
72
|
+
self._history: collections.deque[float] = collections.deque(maxlen=max_history)
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
@abc.abstractmethod
|
|
76
|
+
def name(self) -> str:
|
|
77
|
+
"""
|
|
78
|
+
Name of the indicator.
|
|
79
|
+
This property must be implemented by subclasses.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
str: Name of the indicator.
|
|
83
|
+
"""
|
|
84
|
+
pass
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def latest(self) -> float:
|
|
88
|
+
"""
|
|
89
|
+
The latest (most recent) indicator value.
|
|
90
|
+
|
|
91
|
+
Equivalent to self[0]. Returns numpy.nan when no value is available yet.
|
|
92
|
+
"""
|
|
93
|
+
return self[0]
|
|
94
|
+
|
|
95
|
+
def update(self, incoming_bar: models.Bar) -> None:
|
|
96
|
+
"""
|
|
97
|
+
Updates the indicator based on an incoming closed bar by calling
|
|
98
|
+
`self._compute_indicator()`.
|
|
99
|
+
"""
|
|
100
|
+
new_value = self._compute_indicator(incoming_bar)
|
|
101
|
+
with self._lock:
|
|
102
|
+
self._history.append(new_value)
|
|
103
|
+
|
|
104
|
+
@abc.abstractmethod
|
|
105
|
+
def _compute_indicator(self, incoming_bar: models.Bar) -> float:
|
|
106
|
+
"""
|
|
107
|
+
Computes the new indicator value based on an incoming closed bar.
|
|
108
|
+
This method must be implemented by subclasses.
|
|
109
|
+
"""
|
|
110
|
+
pass
|
|
111
|
+
|
|
112
|
+
def __getitem__(self, index: int) -> float:
|
|
113
|
+
"""
|
|
114
|
+
Return the indicator value at the given index with tolerant indexing.
|
|
115
|
+
|
|
116
|
+
Indexing rules:
|
|
117
|
+
|
|
118
|
+
- `0` returns the current (most recent) value
|
|
119
|
+
- `-1` returns the previous value, `-2` two periods back, and so on
|
|
120
|
+
- For convenience, a positive `k` behaves like `-k` (e.g., `1 == -1`,
|
|
121
|
+
`2 == -2`)
|
|
122
|
+
- Out-of-range indices return `np.nan` instead of raising an `IndexError`.
|
|
123
|
+
"""
|
|
124
|
+
normalized: int
|
|
125
|
+
if index == 0:
|
|
126
|
+
normalized = -1
|
|
127
|
+
elif index > 0:
|
|
128
|
+
normalized = -(index + 1)
|
|
129
|
+
else:
|
|
130
|
+
normalized = index - 1
|
|
131
|
+
|
|
132
|
+
with self._lock:
|
|
133
|
+
try:
|
|
134
|
+
return self._history[normalized]
|
|
135
|
+
except IndexError:
|
|
136
|
+
return np.nan
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{onesecondtrader-0.11.0 → onesecondtrader-0.12.1}/src/onesecondtrader/datafeeds/base_datafeed.py
RENAMED
|
File without changes
|
{onesecondtrader-0.11.0 → onesecondtrader-0.12.1}/src/onesecondtrader/datafeeds/csv_datafeed.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|