onesecondtrader 0.40.0__py3-none-any.whl → 0.43.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.
@@ -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.40.0
3
+ Version: 0.43.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,22 +1,22 @@
1
- onesecondtrader/__init__.py,sha256=wjmgVokbQRI14CMcxZlD60vHUsj0dX3R4byyOjPOkmg,1196
1
+ onesecondtrader/__init__.py,sha256=P_y66jKuddhkWfnrs0RmR29ZA5IfWtY_hLGT1al_CO0,1262
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=hztC-u9-C_rdwZMselMY1Ko3Od5OkatGFp0GQAPHpUw,4966
8
+ onesecondtrader/connectors/datafeeds/simulated.py,sha256=W5wLH4YufxNMR3luRNFCSX3-9mYvdBzljQzHmBfEUgs,6493
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=nQgdGH77DwkeqsFSq1gsGqXbehyMrRU83-vlIyUC2so,705
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
19
- onesecondtrader/core/events/requests.py,sha256=7cnt7TiuE7yl9ezFruIixY0v5A-mzZDWdoTBkAcVff0,836
19
+ onesecondtrader/core/events/requests.py,sha256=QSUzT_fI4xlf981aumB9If01mItVXu1oeQKdr_Ppm3Q,917
20
20
  onesecondtrader/core/events/responses.py,sha256=biHIFa6usnsgSEX9bh2zOs1zB00I7HVSS01Dh_pZISE,1441
21
21
  onesecondtrader/core/indicators/__init__.py,sha256=hRg3FCP1FT7LYOLzztybWn48gTR5QvewzzdELPYbdoY,239
22
22
  onesecondtrader/core/indicators/averages.py,sha256=sCAIJrOYhtkwO5MkS2vx-4CfzHIVLJZpwYDzwv1GZ7Y,1905
@@ -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=7amHCQ6BAhHKps0ke63E-zh8IJNmkdDogZq-PfBukMs,249
28
+ onesecondtrader/core/models/__init__.py,sha256=GyA5SrxgFBrpFqhaofwhO_Vmz9Sxg2d5qnHdB9F_wdc,326
29
29
  onesecondtrader/core/models/data.py,sha256=fBmddVl6EXYC5u2UnvQ59DXAXeZeIb48KP1ZdeTL52A,322
30
- onesecondtrader/core/models/orders.py,sha256=y6Ar-6fMqaOd_hRnRGvfWUF0Z13H_2hfTOW3ROOk0A8,254
31
- onesecondtrader/core/models/records.py,sha256=vdCWBtoDQs5R4iB_8_3fXkxWEvoCxOssk9XBnS4l7Vk,599
30
+ onesecondtrader/core/models/orders.py,sha256=uYLYfx7fmMTTi_pJC3M4b8-xhBuovoy_4QNHHMgggyQ,521
31
+ onesecondtrader/core/models/params.py,sha256=8hZNcQ2NF4tH4gVaYvWJgdLjs_hfA2kduw2B3hcgzNw,540
32
+ onesecondtrader/core/models/records.py,sha256=Wof3POMPNYtkiOKSYX9EC0EtIiI1tWQ-NJJ3svUw96c,673
32
33
  onesecondtrader/core/strategies/__init__.py,sha256=Nq1n6HCdZ-GKkpn4WAlKxconPnOmeVKo0nhTk0J1ybA,121
33
- onesecondtrader/core/strategies/base.py,sha256=wZMjPu4sSMclvoyMptIZKllaqFkRrA06CZ5EG7uQ-Uo,11211
34
- onesecondtrader/core/strategies/examples.py,sha256=j4K092_qt0bcvajp-i4ugrGqzbaFebYX6rBbtZawtvE,1124
35
- onesecondtrader/dashboard/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ onesecondtrader/core/strategies/base.py,sha256=mnrLirY3ps7bzaVvsfiZEXu9vZvMrRkuvgv1etiseTo,11589
35
+ onesecondtrader/core/strategies/examples.py,sha256=8HRDugPfFqxKZY_aUx_f4xX32yD-Lwb-TX0Glm4fFq8,1776
36
+ onesecondtrader/dashboard/__init__.py,sha256=vJRSXOvmNoEQ2_az79gFCRkgA1IYuQshNc6M0H3ljd4,40
37
+ onesecondtrader/dashboard/app.py,sha256=CoBofJF4RoyzcyZVHaMgyZ-gL92vNo-QMgap9mTRpiI,106979
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=7VMmR3FuPum-zZMshVrDN6LNMJr-GfRoDwwy0ZM-mE4,7333
42
+ onesecondtrader/orchestrator/schema.sql,sha256=Q5t8q06p1lpOyNS6NHYBPlOrEAXWIJ05_u7WQEofinM,10582
36
43
  onesecondtrader/secmaster/__init__.py,sha256=0vKGVhRXEDMx_UoH1SIDe-ZlwGt28leslZQ8y7gr-Rs,136
37
- onesecondtrader/secmaster/schema.sql,sha256=6UP4DgNhWteP9EmgRNFXogJG__UBdgRwa6RiqTrbnhQ,53306
38
- onesecondtrader/secmaster/utils.py,sha256=r3DJ95ZoPQEagPEOCXq-fMZ3Dx0K9QCaAdHgTXzkyfE,21223
39
- onesecondtrader-0.40.0.dist-info/METADATA,sha256=JN1VOjGYiJ3KqcYWtta2kvW_1uoUnIVhRNInRCyZl9g,9853
40
- onesecondtrader-0.40.0.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
41
- onesecondtrader-0.40.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
42
- onesecondtrader-0.40.0.dist-info/RECORD,,
44
+ onesecondtrader/secmaster/schema.sql,sha256=E2nIu3jotjJOjP4LIUEvT2upzviqq4G94ZahHuDafpc,55438
45
+ onesecondtrader/secmaster/utils.py,sha256=4rIBxnS9tQSrMPTLfMcktIL3TwHE82oNmCSnyeTT9p8,23941
46
+ onesecondtrader-0.43.0.dist-info/METADATA,sha256=PUl4B1NVqVKgzsOqw3BdHYk7GP8aSIilzUM2mYoE1T0,9939
47
+ onesecondtrader-0.43.0.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
48
+ onesecondtrader-0.43.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
49
+ onesecondtrader-0.43.0.dist-info/RECORD,,