onesecondtrader 0.35.0__py3-none-any.whl → 0.36.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.
Files changed (39) hide show
  1. onesecondtrader/connectors/__init__.py +2 -0
  2. onesecondtrader/connectors/brokers/__init__.py +3 -0
  3. onesecondtrader/connectors/brokers/simulated.py +346 -0
  4. onesecondtrader/connectors/datafeeds/__init__.py +4 -0
  5. onesecondtrader/connectors/datafeeds/base.py +19 -0
  6. onesecondtrader/connectors/datafeeds/simulated.py +99 -0
  7. onesecondtrader/core/__init__.py +6 -0
  8. onesecondtrader/core/brokers/__init__.py +3 -0
  9. onesecondtrader/core/brokers/base.py +39 -0
  10. onesecondtrader/core/events/__init__.py +33 -0
  11. onesecondtrader/core/events/bases.py +29 -0
  12. onesecondtrader/core/events/market.py +22 -0
  13. onesecondtrader/core/events/requests.py +31 -0
  14. onesecondtrader/core/events/responses.py +54 -0
  15. onesecondtrader/core/indicators/__init__.py +13 -0
  16. onesecondtrader/core/indicators/averages.py +56 -0
  17. onesecondtrader/core/indicators/bar.py +47 -0
  18. onesecondtrader/core/indicators/base.py +60 -0
  19. onesecondtrader/core/messaging/__init__.py +7 -0
  20. onesecondtrader/core/messaging/eventbus.py +47 -0
  21. onesecondtrader/core/messaging/subscriber.py +69 -0
  22. onesecondtrader/core/models/__init__.py +12 -0
  23. onesecondtrader/core/models/data.py +18 -0
  24. onesecondtrader/core/models/orders.py +15 -0
  25. onesecondtrader/core/models/records.py +32 -0
  26. onesecondtrader/core/strategies/__init__.py +7 -0
  27. onesecondtrader/core/strategies/base.py +318 -0
  28. onesecondtrader/core/strategies/examples.py +35 -0
  29. onesecondtrader/dashboard/__init__.py +0 -0
  30. onesecondtrader/secmaster/__init__.py +5 -0
  31. onesecondtrader/secmaster/schema.sql +46 -0
  32. onesecondtrader/secmaster/utils.py +26 -0
  33. {onesecondtrader-0.35.0.dist-info → onesecondtrader-0.36.0.dist-info}/METADATA +1 -1
  34. onesecondtrader-0.36.0.dist-info/RECORD +62 -0
  35. onesecondtrader/observers/__init__.py +0 -5
  36. onesecondtrader/observers/csvbookkeeper.py +0 -180
  37. onesecondtrader-0.35.0.dist-info/RECORD +0 -32
  38. {onesecondtrader-0.35.0.dist-info → onesecondtrader-0.36.0.dist-info}/WHEEL +0 -0
  39. {onesecondtrader-0.35.0.dist-info → onesecondtrader-0.36.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,180 +0,0 @@
1
- import pathlib
2
-
3
- import pandas as pd
4
-
5
- from onesecondtrader import events, messaging
6
-
7
-
8
- class CSVBookkeeper(messaging.Subscriber):
9
- BATCH_SIZE: int = 1000
10
-
11
- def __init__(
12
- self, event_bus: messaging.EventBus, results_path: pathlib.Path
13
- ) -> None:
14
- self._results_path = results_path
15
- self._bars_buffer: list[dict] = []
16
- self._fills_buffer: list[dict] = []
17
- self._orders_buffer: list[dict] = []
18
-
19
- super().__init__(event_bus)
20
- self._subscribe(
21
- events.BarProcessed,
22
- events.OrderFilled,
23
- events.OrderSubmission,
24
- events.OrderModification,
25
- events.OrderCancellation,
26
- events.OrderSubmissionAccepted,
27
- events.OrderModificationAccepted,
28
- events.OrderCancellationAccepted,
29
- events.OrderSubmissionRejected,
30
- events.OrderModificationRejected,
31
- events.OrderCancellationRejected,
32
- events.OrderExpired,
33
- )
34
-
35
- def _on_event(self, event: events.EventBase) -> None:
36
- match event:
37
- case events.BarProcessed() as e:
38
- self._on_processed_bar(e)
39
- case events.OrderFilled() as e:
40
- self._on_fill(e)
41
- case events.OrderSubmission() as e:
42
- self._on_order_event(e, "submission_requested")
43
- case events.OrderModification() as e:
44
- self._on_order_event(e, "modification_requested")
45
- case events.OrderCancellation() as e:
46
- self._on_order_event(e, "cancellation_requested")
47
- case events.OrderSubmissionAccepted() as e:
48
- self._on_order_event(e, "submission_accepted")
49
- case events.OrderModificationAccepted() as e:
50
- self._on_order_event(e, "modification_accepted")
51
- case events.OrderCancellationAccepted() as e:
52
- self._on_order_event(e, "cancellation_accepted")
53
- case events.OrderSubmissionRejected() as e:
54
- self._on_order_event(e, "submission_rejected")
55
- case events.OrderModificationRejected() as e:
56
- self._on_order_event(e, "modification_rejected")
57
- case events.OrderCancellationRejected() as e:
58
- self._on_order_event(e, "cancellation_rejected")
59
- case events.OrderExpired() as e:
60
- self._on_order_event(e, "expired")
61
-
62
- def _on_processed_bar(self, event: events.BarProcessed) -> None:
63
- record = {
64
- "ts_event": event.ts_event,
65
- "symbol": event.symbol,
66
- "bar_period": event.bar_period.name,
67
- "open": event.open,
68
- "high": event.high,
69
- "low": event.low,
70
- "close": event.close,
71
- "volume": event.volume,
72
- }
73
- record.update(event.indicators)
74
- self._bars_buffer.append(record)
75
- if len(self._bars_buffer) >= self.BATCH_SIZE:
76
- self._flush_bars()
77
-
78
- def _on_fill(self, event: events.OrderFilled) -> None:
79
- self._fills_buffer.append(
80
- {
81
- "ts_event": event.ts_event,
82
- "fill_id": str(event.fill_id),
83
- "broker_fill_id": event.broker_fill_id,
84
- "order_id": str(event.associated_order_id),
85
- "symbol": event.symbol,
86
- "side": event.side.name,
87
- "quantity": event.quantity_filled,
88
- "price": event.fill_price,
89
- "commission": event.commission,
90
- "exchange": event.exchange,
91
- }
92
- )
93
- if len(self._fills_buffer) >= self.BATCH_SIZE:
94
- self._flush_fills()
95
-
96
- def _on_order_event(self, event: events.EventBase, event_type: str) -> None:
97
- record: dict = {
98
- "ts_event": event.ts_event,
99
- "event_type": event_type,
100
- }
101
- match event:
102
- case events.OrderSubmission():
103
- record.update(
104
- {
105
- "order_id": str(event.system_order_id),
106
- "symbol": event.symbol,
107
- "order_type": event.order_type.name,
108
- "side": event.side.name,
109
- "quantity": event.quantity,
110
- "limit_price": event.limit_price,
111
- "stop_price": event.stop_price,
112
- }
113
- )
114
- case events.OrderModification():
115
- record.update(
116
- {
117
- "order_id": str(event.system_order_id),
118
- "symbol": event.symbol,
119
- "quantity": event.quantity,
120
- "limit_price": event.limit_price,
121
- "stop_price": event.stop_price,
122
- }
123
- )
124
- case events.OrderCancellation():
125
- record.update(
126
- {
127
- "order_id": str(event.system_order_id),
128
- "symbol": event.symbol,
129
- }
130
- )
131
- case events.OrderSubmissionAccepted() | events.OrderModificationAccepted():
132
- record.update(
133
- {
134
- "order_id": str(event.associated_order_id),
135
- "broker_order_id": event.broker_order_id,
136
- }
137
- )
138
- case events.OrderCancellationAccepted():
139
- record.update({"order_id": str(event.associated_order_id)})
140
- case (
141
- events.OrderSubmissionRejected()
142
- | events.OrderModificationRejected()
143
- | events.OrderCancellationRejected()
144
- ):
145
- record.update({"order_id": str(event.associated_order_id)})
146
- case events.OrderExpired():
147
- record.update({"order_id": str(event.associated_order_id)})
148
-
149
- self._orders_buffer.append(record)
150
- if len(self._orders_buffer) >= self.BATCH_SIZE:
151
- self._flush_orders()
152
-
153
- def _flush_bars(self) -> None:
154
- if not self._bars_buffer:
155
- return
156
- df = pd.DataFrame(self._bars_buffer)
157
- path = self._results_path / "processed_bars.csv"
158
- df.to_csv(path, mode="a", header=not path.exists(), index=False)
159
- self._bars_buffer.clear()
160
-
161
- def _flush_fills(self) -> None:
162
- if not self._fills_buffer:
163
- return
164
- df = pd.DataFrame(self._fills_buffer)
165
- path = self._results_path / "fills.csv"
166
- df.to_csv(path, mode="a", header=not path.exists(), index=False)
167
- self._fills_buffer.clear()
168
-
169
- def _flush_orders(self) -> None:
170
- if not self._orders_buffer:
171
- return
172
- df = pd.DataFrame(self._orders_buffer)
173
- path = self._results_path / "orders.csv"
174
- df.to_csv(path, mode="a", header=not path.exists(), index=False)
175
- self._orders_buffer.clear()
176
-
177
- def _cleanup(self) -> None:
178
- self._flush_bars()
179
- self._flush_fills()
180
- self._flush_orders()
@@ -1,32 +0,0 @@
1
- onesecondtrader/__init__.py,sha256=bzV-SaWcDnq7os8pUtsaq8GAsBWjxBDhkFvRs3Z9FJw,1008
2
- onesecondtrader/brokers/__init__.py,sha256=YofzD0qlrfo_BzL6gwiHb9by7Webp36TQ_1O5EV0uzY,124
3
- onesecondtrader/brokers/base.py,sha256=b6Xq2gBUdy3RTpnUfpUiNSXwbuq_bRIjXJ-s89Xu7nE,1345
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
8
- onesecondtrader/events/__init__.py,sha256=IOlFRdiOXz93SpvkpKL8wr1954d_8olKSB1n9mlTL3Y,898
9
- onesecondtrader/events/bases.py,sha256=g-ykq2jgcitIAueRurUlqAq0jINQwuhSWi_khAniPHw,662
10
- onesecondtrader/events/market.py,sha256=IfHuIGfp_IUiw-dFay4c4RYmkoNzshxbhuWTglBqfN0,509
11
- onesecondtrader/events/requests.py,sha256=2KXwSckiar9-fy8wkN3vcSIeOkeBfeo_XhUhrNKEd2Q,831
12
- onesecondtrader/events/responses.py,sha256=w_BH1nkkPyxQjh30EXEVFcUGDoMprFc2PuAaqpVrQ8A,1436
13
- onesecondtrader/indicators/__init__.py,sha256=hRg3FCP1FT7LYOLzztybWn48gTR5QvewzzdELPYbdoY,239
14
- onesecondtrader/indicators/averages.py,sha256=DpRRdY5G5ze3jwNOV19PPjV6slA0IEeOOla67yChi2Y,1900
15
- onesecondtrader/indicators/bar.py,sha256=0H07mKNiUx5cE1fQvx1oPVY0R_MXcmAAgsLek175vTk,1115
16
- onesecondtrader/indicators/base.py,sha256=64HJD8JWBnUdR7PLd02N3hbNrRfKMjWHEKGeSyMRms8,1889
17
- onesecondtrader/messaging/__init__.py,sha256=vMRDabHBgse_vZRTRFtnU8M8v2sY_o4pHjGzgu3hp3E,115
18
- onesecondtrader/messaging/eventbus.py,sha256=Y8VbDZlEz8Q6KcCkfXRKsVIixsctBMRW1a5ANw297Ls,1576
19
- onesecondtrader/messaging/subscriber.py,sha256=ImpFmu5IstLXLoKVMaebmLp5MXN6225vHLdTL1ZOPvw,2106
20
- onesecondtrader/models/__init__.py,sha256=7amHCQ6BAhHKps0ke63E-zh8IJNmkdDogZq-PfBukMs,249
21
- onesecondtrader/models/data.py,sha256=fBmddVl6EXYC5u2UnvQ59DXAXeZeIb48KP1ZdeTL52A,322
22
- onesecondtrader/models/orders.py,sha256=y6Ar-6fMqaOd_hRnRGvfWUF0Z13H_2hfTOW3ROOk0A8,254
23
- onesecondtrader/models/records.py,sha256=vdCWBtoDQs5R4iB_8_3fXkxWEvoCxOssk9XBnS4l7Vk,599
24
- onesecondtrader/observers/__init__.py,sha256=fYF9tUW4H7L6Iueqkn2wnBf2LpXZtfdppqG4RkZCi2M,77
25
- onesecondtrader/observers/csvbookkeeper.py,sha256=hTRHhithHY4r2bjgroO2DchvTDOM6DEO3m6jdvWeUeM,7021
26
- onesecondtrader/strategies/__init__.py,sha256=5TlEckz3RnwZTs1Isj0wJ_9Og5R9MMXBL90Vu9b45io,126
27
- onesecondtrader/strategies/base.py,sha256=kIi6by4Y8YuB9gPMPMr2Unm5_i9SGAANyiW2UaHiRO0,11206
28
- onesecondtrader/strategies/sma_crossover.py,sha256=s2u_uL_D5CrZTACiAbojnrLrLf4jqIPdfOCiNDEIsDA,1119
29
- onesecondtrader-0.35.0.dist-info/METADATA,sha256=3qckSVPhiHalNJt8HeQSto06RfjM3Af84DtXgJ9m5lo,9682
30
- onesecondtrader-0.35.0.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
31
- onesecondtrader-0.35.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
32
- onesecondtrader-0.35.0.dist-info/RECORD,,