onesecondtrader 0.40.0__py3-none-any.whl → 0.41.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/__init__.py +2 -0
- onesecondtrader/connectors/datafeeds/simulated.py +21 -6
- onesecondtrader/core/datafeeds/base.py +3 -0
- onesecondtrader/core/models/__init__.py +2 -0
- onesecondtrader/core/models/params.py +21 -0
- onesecondtrader/core/strategies/base.py +9 -3
- onesecondtrader/core/strategies/examples.py +15 -7
- onesecondtrader/dashboard/__init__.py +3 -0
- onesecondtrader/dashboard/app.py +1677 -0
- onesecondtrader/dashboard/registry.py +100 -0
- onesecondtrader/orchestrator/__init__.py +7 -0
- onesecondtrader/orchestrator/orchestrator.py +105 -0
- onesecondtrader/orchestrator/recorder.py +196 -0
- onesecondtrader/orchestrator/schema.sql +208 -0
- onesecondtrader/secmaster/schema.sql +48 -0
- onesecondtrader/secmaster/utils.py +90 -0
- {onesecondtrader-0.40.0.dist-info → onesecondtrader-0.41.0.dist-info}/METADATA +3 -1
- {onesecondtrader-0.40.0.dist-info → onesecondtrader-0.41.0.dist-info}/RECORD +20 -13
- {onesecondtrader-0.40.0.dist-info → onesecondtrader-0.41.0.dist-info}/WHEEL +0 -0
- {onesecondtrader-0.40.0.dist-info → onesecondtrader-0.41.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -187,6 +187,8 @@ def ingest_dbzip(zip_path: pathlib.Path, db_path: pathlib.Path) -> tuple[int, in
|
|
|
187
187
|
_disable_bulk_loading(connection)
|
|
188
188
|
connection.close()
|
|
189
189
|
|
|
190
|
+
update_meta(db_path)
|
|
191
|
+
update_symbol_coverage(db_path)
|
|
190
192
|
return dbn_count, symbology_count
|
|
191
193
|
|
|
192
194
|
|
|
@@ -217,6 +219,8 @@ def ingest_dbn(dbn_path: pathlib.Path, db_path: pathlib.Path) -> int:
|
|
|
217
219
|
finally:
|
|
218
220
|
_disable_bulk_loading(connection)
|
|
219
221
|
connection.close()
|
|
222
|
+
update_meta(db_path)
|
|
223
|
+
update_symbol_coverage(db_path)
|
|
220
224
|
return count
|
|
221
225
|
|
|
222
226
|
|
|
@@ -645,3 +649,89 @@ def _instrument_to_tuple(record: databento.InstrumentDefMsg) -> tuple:
|
|
|
645
649
|
record.group,
|
|
646
650
|
record.ts_recv,
|
|
647
651
|
)
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
def update_meta(db_path: pathlib.Path) -> None:
|
|
655
|
+
"""
|
|
656
|
+
Compute and store aggregate statistics in the meta table.
|
|
657
|
+
|
|
658
|
+
This function runs expensive COUNT/MIN/MAX queries once and stores the results
|
|
659
|
+
in the meta table for fast retrieval by the dashboard.
|
|
660
|
+
|
|
661
|
+
Args:
|
|
662
|
+
db_path: Path to the secmaster SQLite database.
|
|
663
|
+
"""
|
|
664
|
+
import time
|
|
665
|
+
|
|
666
|
+
connection = sqlite3.connect(str(db_path))
|
|
667
|
+
cursor = connection.cursor()
|
|
668
|
+
|
|
669
|
+
cursor.execute("SELECT COUNT(DISTINCT instrument_id) FROM symbology")
|
|
670
|
+
symbol_count = cursor.fetchone()[0]
|
|
671
|
+
|
|
672
|
+
cursor.execute("SELECT COUNT(*) FROM ohlcv")
|
|
673
|
+
ohlcv_count = cursor.fetchone()[0]
|
|
674
|
+
|
|
675
|
+
cursor.execute("SELECT MIN(ts_event), MAX(ts_event) FROM ohlcv")
|
|
676
|
+
row = cursor.fetchone()
|
|
677
|
+
min_ts, max_ts = row[0] or 0, row[1] or 0
|
|
678
|
+
|
|
679
|
+
cursor.execute("SELECT DISTINCT rtype FROM ohlcv ORDER BY rtype")
|
|
680
|
+
rtypes = ",".join(str(r[0]) for r in cursor.fetchall())
|
|
681
|
+
|
|
682
|
+
stats = [
|
|
683
|
+
("symbol_count", str(symbol_count)),
|
|
684
|
+
("ohlcv_record_count", str(ohlcv_count)),
|
|
685
|
+
("ohlcv_min_ts", str(min_ts)),
|
|
686
|
+
("ohlcv_max_ts", str(max_ts)),
|
|
687
|
+
("ohlcv_schemas", rtypes),
|
|
688
|
+
("last_updated", str(int(time.time()))),
|
|
689
|
+
]
|
|
690
|
+
|
|
691
|
+
cursor.executemany(
|
|
692
|
+
"INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)",
|
|
693
|
+
stats,
|
|
694
|
+
)
|
|
695
|
+
|
|
696
|
+
connection.commit()
|
|
697
|
+
connection.close()
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
def update_symbol_coverage(db_path: pathlib.Path) -> int:
|
|
701
|
+
"""
|
|
702
|
+
Compute and store per-symbol coverage statistics in the symbol_coverage table.
|
|
703
|
+
|
|
704
|
+
This function aggregates OHLCV data per instrument_id/rtype first (fast, uses
|
|
705
|
+
primary key), then joins with symbology to get symbols.
|
|
706
|
+
|
|
707
|
+
Args:
|
|
708
|
+
db_path: Path to the secmaster SQLite database.
|
|
709
|
+
|
|
710
|
+
Returns:
|
|
711
|
+
The number of symbol/rtype combinations stored.
|
|
712
|
+
"""
|
|
713
|
+
connection = sqlite3.connect(str(db_path))
|
|
714
|
+
cursor = connection.cursor()
|
|
715
|
+
|
|
716
|
+
cursor.execute("DELETE FROM symbol_coverage")
|
|
717
|
+
|
|
718
|
+
cursor.execute(
|
|
719
|
+
"""
|
|
720
|
+
INSERT INTO symbol_coverage (symbol, rtype, min_ts, max_ts, record_count)
|
|
721
|
+
SELECT s.symbol, agg.rtype, MIN(agg.min_ts), MAX(agg.max_ts), SUM(agg.cnt)
|
|
722
|
+
FROM (
|
|
723
|
+
SELECT instrument_id, rtype, MIN(ts_event) as min_ts, MAX(ts_event) as max_ts, COUNT(*) as cnt
|
|
724
|
+
FROM ohlcv
|
|
725
|
+
GROUP BY instrument_id, rtype
|
|
726
|
+
) agg
|
|
727
|
+
JOIN (
|
|
728
|
+
SELECT DISTINCT instrument_id, symbol FROM symbology
|
|
729
|
+
) s ON agg.instrument_id = s.instrument_id
|
|
730
|
+
GROUP BY s.symbol, agg.rtype
|
|
731
|
+
"""
|
|
732
|
+
)
|
|
733
|
+
|
|
734
|
+
count = cursor.rowcount
|
|
735
|
+
connection.commit()
|
|
736
|
+
connection.close()
|
|
737
|
+
return count
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: onesecondtrader
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.41.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
|
|
@@ -12,12 +12,14 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.13
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.14
|
|
14
14
|
Requires-Dist: databento (>=0.69.0,<0.70.0)
|
|
15
|
+
Requires-Dist: fastapi (>=0.128.0,<0.129.0)
|
|
15
16
|
Requires-Dist: ib-async (>=2.1.0,<3.0.0)
|
|
16
17
|
Requires-Dist: matplotlib (>=3.10.7,<4.0.0)
|
|
17
18
|
Requires-Dist: mplfinance (>=0.12.10b0,<0.13.0)
|
|
18
19
|
Requires-Dist: pandas (>=2.3.1,<3.0.0)
|
|
19
20
|
Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
|
|
20
21
|
Requires-Dist: tqdm (>=4.67.1,<5.0.0)
|
|
22
|
+
Requires-Dist: uvicorn (>=0.40.0,<0.41.0)
|
|
21
23
|
Description-Content-Type: text/markdown
|
|
22
24
|
|
|
23
25
|
# OneSecondTrader
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
onesecondtrader/__init__.py,sha256=
|
|
1
|
+
onesecondtrader/__init__.py,sha256=_jslG2TQRbaiUCQe5LZrmP4tuvpaULdxX2SK2x4cHUc,1228
|
|
2
2
|
onesecondtrader/connectors/__init__.py,sha256=rAbQCRdwxk3gkZ8QgMHPzcZXsS7a5rIj3F0rV6PqjDM,180
|
|
3
3
|
onesecondtrader/connectors/brokers/__init__.py,sha256=CpZQ04U8t-KlFb4oePcdJ8W8djaBIoBe8ZOlyg7_S1A,107
|
|
4
4
|
onesecondtrader/connectors/brokers/ib.py,sha256=KSldO_ZXWDHu56F5TVizvFlevhLl1gbyFzBHH35vXE0,15244
|
|
5
5
|
onesecondtrader/connectors/brokers/simulated.py,sha256=Jhq8YfskEkV0rePLp8nGFI4oG_Kb_vbhMzJiWOgj-q0,12767
|
|
6
6
|
onesecondtrader/connectors/datafeeds/__init__.py,sha256=ChSoiZQGN4E8p_TX0AgwNFFsE4b63ef2e6QhsTBkdLE,115
|
|
7
7
|
onesecondtrader/connectors/datafeeds/ib.py,sha256=Ba4WWJXEt9SMUzFUStpfqE9aOFawOBgnfr0XexBlMuc,10353
|
|
8
|
-
onesecondtrader/connectors/datafeeds/simulated.py,sha256=
|
|
8
|
+
onesecondtrader/connectors/datafeeds/simulated.py,sha256=jQSjmsZDpnbjNZsbBHEHFci6W4El2TiZD6lKK4kYnJo,5408
|
|
9
9
|
onesecondtrader/connectors/gateways/__init__.py,sha256=K80iGnZeJFMhtD9HnEz1B4YWwgkRCQX4pNTYl2QZ-wU,83
|
|
10
10
|
onesecondtrader/connectors/gateways/ib.py,sha256=XnjiUc0Z99JD09Ou90ctCVEAKfYLCKNGoWicyEvnk4s,10819
|
|
11
11
|
onesecondtrader/core/__init__.py,sha256=Yde6Vy8osWbc2Du__VmC0AhD_bQ5-qSdt3VXFkCS6YM,380
|
|
12
12
|
onesecondtrader/core/brokers/__init__.py,sha256=mC-nNPdaT17oy-rjluwNvbKzxi5q8xxZ4mAkU7aJU0Y,55
|
|
13
13
|
onesecondtrader/core/brokers/base.py,sha256=NNcYWYYRPrvreCmn6TwFymEnIrfMLCyLFyaGXYy0UAw,1478
|
|
14
14
|
onesecondtrader/core/datafeeds/__init__.py,sha256=grSCxzBCmYau1BgA9Kyj2zeK8afoBlHzpN3JqInNtTs,59
|
|
15
|
-
onesecondtrader/core/datafeeds/base.py,sha256=
|
|
15
|
+
onesecondtrader/core/datafeeds/base.py,sha256=kgCgKRsF0AyJRy-WTaYcr_hzJjnQUDJ8BP9ZWOnYATY,762
|
|
16
16
|
onesecondtrader/core/events/__init__.py,sha256=IOlFRdiOXz93SpvkpKL8wr1954d_8olKSB1n9mlTL3Y,898
|
|
17
17
|
onesecondtrader/core/events/bases.py,sha256=g-ykq2jgcitIAueRurUlqAq0jINQwuhSWi_khAniPHw,662
|
|
18
18
|
onesecondtrader/core/events/market.py,sha256=UY04TH6G-98NgYPEvBQSY92_ddeiT4yNwaUXnHdongQ,514
|
|
@@ -25,18 +25,25 @@ onesecondtrader/core/indicators/base.py,sha256=_2pJ7PS0MRUz85UT0YpvzJ5V6ce60koT8
|
|
|
25
25
|
onesecondtrader/core/messaging/__init__.py,sha256=vMRDabHBgse_vZRTRFtnU8M8v2sY_o4pHjGzgu3hp3E,115
|
|
26
26
|
onesecondtrader/core/messaging/eventbus.py,sha256=SaXLRoqz9tWBBlyEo0ry1HHr_8azj2U2dEaQEnr3PNo,1581
|
|
27
27
|
onesecondtrader/core/messaging/subscriber.py,sha256=Sp77pB6bGyW57FlV0rdzAWy1Jv_nHA77YEtN64spZjs,2111
|
|
28
|
-
onesecondtrader/core/models/__init__.py,sha256=
|
|
28
|
+
onesecondtrader/core/models/__init__.py,sha256=w-Gi7_NciopNJu3kvsmgIbPrjmJofVmjynJ6v8SOfSc,296
|
|
29
29
|
onesecondtrader/core/models/data.py,sha256=fBmddVl6EXYC5u2UnvQ59DXAXeZeIb48KP1ZdeTL52A,322
|
|
30
30
|
onesecondtrader/core/models/orders.py,sha256=y6Ar-6fMqaOd_hRnRGvfWUF0Z13H_2hfTOW3ROOk0A8,254
|
|
31
|
+
onesecondtrader/core/models/params.py,sha256=8hZNcQ2NF4tH4gVaYvWJgdLjs_hfA2kduw2B3hcgzNw,540
|
|
31
32
|
onesecondtrader/core/models/records.py,sha256=vdCWBtoDQs5R4iB_8_3fXkxWEvoCxOssk9XBnS4l7Vk,599
|
|
32
33
|
onesecondtrader/core/strategies/__init__.py,sha256=Nq1n6HCdZ-GKkpn4WAlKxconPnOmeVKo0nhTk0J1ybA,121
|
|
33
|
-
onesecondtrader/core/strategies/base.py,sha256=
|
|
34
|
-
onesecondtrader/core/strategies/examples.py,sha256=
|
|
35
|
-
onesecondtrader/dashboard/__init__.py,sha256=
|
|
34
|
+
onesecondtrader/core/strategies/base.py,sha256=SJ-9rEq4Y4x_rRcC0mPyr8RbZ00OoYaXO9SVw7WisRQ,11409
|
|
35
|
+
onesecondtrader/core/strategies/examples.py,sha256=tkEX5oRifts7uUis4uO4cE8TckXU2SwJD17m5-JDPvo,1593
|
|
36
|
+
onesecondtrader/dashboard/__init__.py,sha256=vJRSXOvmNoEQ2_az79gFCRkgA1IYuQshNc6M0H3ljd4,40
|
|
37
|
+
onesecondtrader/dashboard/app.py,sha256=OvbNtGoAHl0S56-Dh_-6t7wnGT-Ecsavysol-YtxK6o,60468
|
|
38
|
+
onesecondtrader/dashboard/registry.py,sha256=MWnfks7K_5_ndi-6YYYbX2Lm5xhak62fomgLkjCAsvw,2734
|
|
39
|
+
onesecondtrader/orchestrator/__init__.py,sha256=M0m9QP0g_2qpma4EYiG2DJF7lXQbHrAda8N30Db-V0Y,127
|
|
40
|
+
onesecondtrader/orchestrator/orchestrator.py,sha256=okSsvIiUPXsOTwIVnSTxSCP-p3GPpaKvr-418mo4r0A,3681
|
|
41
|
+
onesecondtrader/orchestrator/recorder.py,sha256=WtfNgStskCKweKqCCD28sDFxsT4vHlX_1es-loiQquI,7166
|
|
42
|
+
onesecondtrader/orchestrator/schema.sql,sha256=0nY_jqwfypkTrVoqC4IsNXbn7DM5_WpjfZnQF6YgH9k,10350
|
|
36
43
|
onesecondtrader/secmaster/__init__.py,sha256=0vKGVhRXEDMx_UoH1SIDe-ZlwGt28leslZQ8y7gr-Rs,136
|
|
37
|
-
onesecondtrader/secmaster/schema.sql,sha256=
|
|
38
|
-
onesecondtrader/secmaster/utils.py,sha256=
|
|
39
|
-
onesecondtrader-0.
|
|
40
|
-
onesecondtrader-0.
|
|
41
|
-
onesecondtrader-0.
|
|
42
|
-
onesecondtrader-0.
|
|
44
|
+
onesecondtrader/secmaster/schema.sql,sha256=E2nIu3jotjJOjP4LIUEvT2upzviqq4G94ZahHuDafpc,55438
|
|
45
|
+
onesecondtrader/secmaster/utils.py,sha256=4rIBxnS9tQSrMPTLfMcktIL3TwHE82oNmCSnyeTT9p8,23941
|
|
46
|
+
onesecondtrader-0.41.0.dist-info/METADATA,sha256=85O_TKyRPvTSjn4-2X95XnY0bY1KvS8xZuBs-CRcGOE,9939
|
|
47
|
+
onesecondtrader-0.41.0.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
|
|
48
|
+
onesecondtrader-0.41.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
49
|
+
onesecondtrader-0.41.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|