onesecondtrader 0.33.0__py3-none-any.whl → 0.34.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.
@@ -4,6 +4,7 @@ __all__ = [
4
4
  "BarReceived",
5
5
  "BrokerBase",
6
6
  "Close",
7
+ "Datafeed",
7
8
  "FillRecord",
8
9
  "High",
9
10
  "Indicator",
@@ -15,14 +16,16 @@ __all__ = [
15
16
  "OrderSide",
16
17
  "OrderSubmission",
17
18
  "OrderType",
18
- "SimpleMovingAverage",
19
19
  "SimulatedBroker",
20
+ "SimulatedDatafeed",
21
+ "SimpleMovingAverage",
20
22
  "SMACrossover",
21
23
  "StrategyBase",
22
24
  "Volume",
23
25
  ]
24
26
 
25
27
  from onesecondtrader.brokers import BrokerBase, SimulatedBroker
28
+ from onesecondtrader.datafeeds import Datafeed, SimulatedDatafeed
26
29
  from onesecondtrader.events import (
27
30
  BarProcessed,
28
31
  BarReceived,
@@ -0,0 +1,7 @@
1
+ __all__ = [
2
+ "Datafeed",
3
+ "SimulatedDatafeed",
4
+ ]
5
+
6
+ from .base import Datafeed
7
+ from .simulated import SimulatedDatafeed
@@ -0,0 +1,19 @@
1
+ import abc
2
+
3
+ from onesecondtrader import events, messaging, models
4
+
5
+
6
+ class Datafeed(abc.ABC):
7
+ def __init__(self, event_bus: messaging.EventBus) -> None:
8
+ self._event_bus = event_bus
9
+
10
+ def _publish(self, event: events.EventBase) -> None:
11
+ self._event_bus.publish(event)
12
+
13
+ @abc.abstractmethod
14
+ def stream(self, symbols: list[str], bar_period: models.BarPeriod) -> None:
15
+ pass
16
+
17
+ @abc.abstractmethod
18
+ def shutdown(self) -> None:
19
+ pass
@@ -0,0 +1,99 @@
1
+ import pathlib
2
+ import threading
3
+
4
+ import pandas as pd
5
+
6
+ from onesecondtrader import events, messaging, models
7
+ from .base import Datafeed
8
+
9
+ _RTYPE_MAP = {
10
+ models.BarPeriod.SECOND: 32,
11
+ models.BarPeriod.MINUTE: 33,
12
+ models.BarPeriod.HOUR: 34,
13
+ models.BarPeriod.DAY: 35,
14
+ }
15
+
16
+
17
+ class SimulatedDatafeed(Datafeed):
18
+ csv_path: str = ""
19
+
20
+ def __init__(self, event_bus: messaging.EventBus) -> None:
21
+ super().__init__(event_bus)
22
+ self._thread: threading.Thread | None = None
23
+ self._stop_event = threading.Event()
24
+
25
+ def stream(self, symbols: list[str], bar_period: models.BarPeriod) -> None:
26
+ csv_path = pathlib.Path(self.csv_path)
27
+ if self._thread and self._thread.is_alive():
28
+ raise RuntimeError("Already streaming")
29
+ if not csv_path.exists():
30
+ raise FileNotFoundError(f"CSV file not found: {csv_path}")
31
+ if not symbols:
32
+ raise ValueError("symbols list cannot be empty")
33
+
34
+ self._stop_event.clear()
35
+ self._thread = threading.Thread(
36
+ target=self._stream,
37
+ args=(symbols, bar_period),
38
+ name=self.__class__.__name__,
39
+ daemon=False,
40
+ )
41
+ self._thread.start()
42
+
43
+ def wait(self) -> None:
44
+ if self._thread:
45
+ self._thread.join()
46
+
47
+ def shutdown(self) -> None:
48
+ self._stop_event.set()
49
+ if self._thread and self._thread.is_alive():
50
+ self._thread.join()
51
+
52
+ def _stream(self, symbols: list[str], bar_period: models.BarPeriod) -> None:
53
+ symbols_set = set(symbols)
54
+ rtype = _RTYPE_MAP[bar_period]
55
+
56
+ for chunk in pd.read_csv(
57
+ self.csv_path,
58
+ usecols=[
59
+ "ts_event",
60
+ "rtype",
61
+ "open",
62
+ "high",
63
+ "low",
64
+ "close",
65
+ "volume",
66
+ "symbol",
67
+ ],
68
+ dtype={
69
+ "ts_event": int,
70
+ "rtype": int,
71
+ "open": int,
72
+ "high": int,
73
+ "low": int,
74
+ "close": int,
75
+ "volume": int,
76
+ "symbol": str,
77
+ },
78
+ chunksize=10_000,
79
+ ):
80
+ for row in chunk.itertuples():
81
+ if self._stop_event.is_set():
82
+ return
83
+
84
+ if row.symbol not in symbols_set or row.rtype != rtype:
85
+ continue
86
+
87
+ self._publish(
88
+ events.BarReceived(
89
+ ts_event=pd.Timestamp(row.ts_event, unit="ns", tz="UTC"),
90
+ symbol=row.symbol,
91
+ bar_period=bar_period,
92
+ open=row.open / 1e9,
93
+ high=row.high / 1e9,
94
+ low=row.low / 1e9,
95
+ close=row.close / 1e9,
96
+ volume=row.volume,
97
+ )
98
+ )
99
+ self._event_bus.wait_until_system_idle()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: onesecondtrader
3
- Version: 0.33.0
3
+ Version: 0.34.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,7 +1,10 @@
1
- onesecondtrader/__init__.py,sha256=CLUi62mHp8tBzp-58mig3M4SEhPELPihHfQQzcD9Nz8,901
1
+ onesecondtrader/__init__.py,sha256=bzV-SaWcDnq7os8pUtsaq8GAsBWjxBDhkFvRs3Z9FJw,1008
2
2
  onesecondtrader/brokers/__init__.py,sha256=YofzD0qlrfo_BzL6gwiHb9by7Webp36TQ_1O5EV0uzY,124
3
3
  onesecondtrader/brokers/base.py,sha256=b6Xq2gBUdy3RTpnUfpUiNSXwbuq_bRIjXJ-s89Xu7nE,1345
4
4
  onesecondtrader/brokers/simulated.py,sha256=pJvZ7b76xAs-NBbOX_v78IJgVrdnuTLCadqj8kYQ5sg,12694
5
+ onesecondtrader/datafeeds/__init__.py,sha256=zSj1cQhBS-Z5271ICsmGc_zq-1fOd8yLQ7c4F0oJIVk,124
6
+ onesecondtrader/datafeeds/base.py,sha256=bSIHBlZ8kbJ4rTZrUMiMgl8_j0Kqe6Eh2hNX5E3DhHU,477
7
+ onesecondtrader/datafeeds/simulated.py,sha256=mbnEh0jjgZWRDhRLIASMbUpV1ybQktBA8opTv6nj33s,3006
5
8
  onesecondtrader/events/__init__.py,sha256=IOlFRdiOXz93SpvkpKL8wr1954d_8olKSB1n9mlTL3Y,898
6
9
  onesecondtrader/events/bases.py,sha256=g-ykq2jgcitIAueRurUlqAq0jINQwuhSWi_khAniPHw,662
7
10
  onesecondtrader/events/market.py,sha256=IfHuIGfp_IUiw-dFay4c4RYmkoNzshxbhuWTglBqfN0,509
@@ -21,7 +24,7 @@ onesecondtrader/models/records.py,sha256=vdCWBtoDQs5R4iB_8_3fXkxWEvoCxOssk9XBnS4
21
24
  onesecondtrader/strategies/__init__.py,sha256=5TlEckz3RnwZTs1Isj0wJ_9Og5R9MMXBL90Vu9b45io,126
22
25
  onesecondtrader/strategies/base.py,sha256=kIi6by4Y8YuB9gPMPMr2Unm5_i9SGAANyiW2UaHiRO0,11206
23
26
  onesecondtrader/strategies/sma_crossover.py,sha256=s2u_uL_D5CrZTACiAbojnrLrLf4jqIPdfOCiNDEIsDA,1119
24
- onesecondtrader-0.33.0.dist-info/METADATA,sha256=U06iSqkTLBBhLzZCiIl5r-f4-FjpVPF6Qimcgq_kunk,9682
25
- onesecondtrader-0.33.0.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
26
- onesecondtrader-0.33.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
27
- onesecondtrader-0.33.0.dist-info/RECORD,,
27
+ onesecondtrader-0.34.0.dist-info/METADATA,sha256=N-0PPAPIFmnllV7fvuNLRNJSrRfyWoHT3SIVDOSPOU8,9682
28
+ onesecondtrader-0.34.0.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
29
+ onesecondtrader-0.34.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
30
+ onesecondtrader-0.34.0.dist-info/RECORD,,