bullishpy 0.11.0__tar.gz → 0.12.0__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.
- {bullishpy-0.11.0 → bullishpy-0.12.0}/PKG-INFO +3 -2
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/analysis/analysis.py +24 -3
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/crud.py +10 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/interface/interface.py +6 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/pyproject.toml +3 -2
- {bullishpy-0.11.0 → bullishpy-0.12.0}/README.md +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/__init__.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/analysis/__init__.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/analysis/filter.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/analysis/functions.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/analysis/indicators.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/analysis/predefined_filters.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/app/__init__.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/app/app.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/cli.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/__init__.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/alembic/README +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/alembic/alembic.ini +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/alembic/env.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/alembic/script.py.mako +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/alembic/versions/037dbd721317_.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/alembic/versions/08ac1116e055_.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/alembic/versions/11d35a452b40_.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/alembic/versions/17e51420e7ad_.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/alembic/versions/49c83f9eb5ac_.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/alembic/versions/4b0a2f40b7d3_.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/alembic/versions/73564b60fe24_.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/alembic/versions/d663166c531d_.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/alembic/versions/ee5baabb35f8_.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/alembic/versions/fc191121f522_.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/schemas.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/scripts/create_revision.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/scripts/stamp.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/scripts/upgrade.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/database/settings.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/exceptions.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/figures/__init__.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/figures/figures.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/interface/__init__.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/jobs/__init__.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/jobs/app.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/jobs/models.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/jobs/tasks.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/utils/__init__.py +0 -0
- {bullishpy-0.11.0 → bullishpy-0.12.0}/bullish/utils/checks.py +0 -0
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: bullishpy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.12.0
|
|
4
4
|
Summary:
|
|
5
5
|
Author: aan
|
|
6
6
|
Author-email: andoludovic.andriamamonjy@gmail.com
|
|
7
7
|
Requires-Python: >=3.12,<3.13
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.12
|
|
10
|
-
Requires-Dist: bearishpy (>=0.
|
|
10
|
+
Requires-Dist: bearishpy (>=0.22.0,<0.23.0)
|
|
11
11
|
Requires-Dist: click (>=7.0,<=8.1)
|
|
12
12
|
Requires-Dist: huey (>=2.5.3,<3.0.0)
|
|
13
|
+
Requires-Dist: joblib (>=1.5.1,<2.0.0)
|
|
13
14
|
Requires-Dist: pandas-ta (>=0.3.14b0,<0.4.0)
|
|
14
15
|
Requires-Dist: plotly (>=6.1.2,<7.0.0)
|
|
15
16
|
Requires-Dist: streamlit (>=1.45.1,<2.0.0)
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
import time
|
|
3
|
+
from itertools import batched
|
|
4
|
+
from pathlib import Path
|
|
2
5
|
from typing import (
|
|
3
6
|
Annotated,
|
|
4
7
|
Any,
|
|
@@ -40,6 +43,7 @@ from bearish.types import TickerOnlySources # type: ignore
|
|
|
40
43
|
from pydantic import BaseModel, BeforeValidator, Field, create_model
|
|
41
44
|
|
|
42
45
|
from bullish.analysis.indicators import Indicators, IndicatorModels
|
|
46
|
+
from joblib import Parallel, delayed # type: ignore
|
|
43
47
|
|
|
44
48
|
if TYPE_CHECKING:
|
|
45
49
|
from bullish.database.crud import BullishDb
|
|
@@ -482,10 +486,27 @@ class Analysis(AnalysisView, BaseEquity, TechnicalAnalysis, FundamentalAnalysis)
|
|
|
482
486
|
)
|
|
483
487
|
|
|
484
488
|
|
|
489
|
+
def compute_analysis(database_path: Path, ticker: Ticker) -> Analysis:
|
|
490
|
+
from bullish.database.crud import BullishDb
|
|
491
|
+
|
|
492
|
+
bullish_db = BullishDb(database_path=database_path)
|
|
493
|
+
return Analysis.from_ticker(bullish_db, ticker)
|
|
494
|
+
|
|
495
|
+
|
|
485
496
|
def run_analysis(bullish_db: "BullishDb") -> None:
|
|
486
497
|
price_trackers = set(bullish_db._read_tracker(TrackerQuery(), PriceTracker))
|
|
487
498
|
finance_trackers = set(bullish_db._read_tracker(TrackerQuery(), FinancialsTracker))
|
|
488
499
|
tickers = list(price_trackers.intersection(finance_trackers))
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
500
|
+
parallel = Parallel(n_jobs=-1)
|
|
501
|
+
|
|
502
|
+
for batch_ticker in batched(tickers, 1000):
|
|
503
|
+
start = time.perf_counter()
|
|
504
|
+
many_analysis = parallel(
|
|
505
|
+
delayed(compute_analysis)(bullish_db.database_path, ticker)
|
|
506
|
+
for ticker in batch_ticker
|
|
507
|
+
)
|
|
508
|
+
bullish_db.write_many_analysis(many_analysis)
|
|
509
|
+
elapsed_time = time.perf_counter() - start
|
|
510
|
+
print(
|
|
511
|
+
f"Computed analysis for {len(batch_ticker)} tickers in {elapsed_time:.2f} seconds."
|
|
512
|
+
)
|
|
@@ -67,6 +67,16 @@ class BullishDb(BearishDb, BullishDbBase): # type: ignore
|
|
|
67
67
|
session.exec(stmt) # type: ignore
|
|
68
68
|
session.commit()
|
|
69
69
|
|
|
70
|
+
def _write_many_analysis(self, many_analysis: List[Analysis]) -> None:
|
|
71
|
+
with Session(self._engine) as session:
|
|
72
|
+
stmt = (
|
|
73
|
+
insert(AnalysisORM)
|
|
74
|
+
.prefix_with("OR REPLACE")
|
|
75
|
+
.values([a.model_dump() for a in many_analysis])
|
|
76
|
+
)
|
|
77
|
+
session.exec(stmt) # type: ignore
|
|
78
|
+
session.commit()
|
|
79
|
+
|
|
70
80
|
def _read_analysis(self, ticker: Ticker) -> Optional[Analysis]:
|
|
71
81
|
with Session(self._engine) as session:
|
|
72
82
|
query = select(AnalysisORM).where(AnalysisORM.symbol == ticker.symbol)
|
|
@@ -19,6 +19,9 @@ class BullishDbBase(BearishDbBase): # type: ignore
|
|
|
19
19
|
def write_analysis(self, analysis: "Analysis") -> None:
|
|
20
20
|
return self._write_analysis(analysis)
|
|
21
21
|
|
|
22
|
+
def write_many_analysis(self, many_analysis: List["Analysis"]) -> None:
|
|
23
|
+
return self._write_many_analysis(many_analysis)
|
|
24
|
+
|
|
22
25
|
def read_analysis(self, ticker: Ticker) -> Optional["Analysis"]:
|
|
23
26
|
return self._read_analysis(ticker)
|
|
24
27
|
|
|
@@ -62,6 +65,9 @@ class BullishDbBase(BearishDbBase): # type: ignore
|
|
|
62
65
|
@abc.abstractmethod
|
|
63
66
|
def _write_analysis(self, analysis: "Analysis") -> None: ...
|
|
64
67
|
|
|
68
|
+
@abc.abstractmethod
|
|
69
|
+
def _write_many_analysis(self, many_analysis: List["Analysis"]) -> None: ...
|
|
70
|
+
|
|
65
71
|
@abc.abstractmethod
|
|
66
72
|
def _read_analysis(self, ticker: Ticker) -> Optional["Analysis"]: ...
|
|
67
73
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "bullishpy"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.12.0"
|
|
4
4
|
description = ""
|
|
5
5
|
authors = ["aan <andoludovic.andriamamonjy@gmail.com>"]
|
|
6
6
|
readme = "README.md"
|
|
7
7
|
packages = [{ include = "bullish" }]
|
|
8
8
|
[tool.poetry.dependencies]
|
|
9
9
|
python = ">=3.12,<3.13"
|
|
10
|
-
bearishpy = "^0.
|
|
10
|
+
bearishpy = "^0.22.0"
|
|
11
11
|
tickermood = "^0.4.0"
|
|
12
12
|
streamlit = "^1.45.1"
|
|
13
13
|
streamlit-pydantic = "^v0.6.1-rc.3"
|
|
@@ -17,6 +17,7 @@ pandas-ta = "^0.3.14b0"
|
|
|
17
17
|
plotly = "^6.1.2"
|
|
18
18
|
ta-lib = "^0.6.4"
|
|
19
19
|
click = ">=7.0,<=8.1"
|
|
20
|
+
joblib = "^1.5.1"
|
|
20
21
|
|
|
21
22
|
[tool.poetry.scripts]
|
|
22
23
|
bullish = "bullish.cli:app"
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|