bullishpy 0.46.0__tar.gz → 0.48.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.46.0 → bullishpy-0.48.0}/PKG-INFO +1 -1
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/analysis/analysis.py +10 -0
- bullishpy-0.48.0/bullish/database/alembic/versions/4ee82b171449_.py +35 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/jobs/tasks.py +5 -5
- {bullishpy-0.46.0 → bullishpy-0.48.0}/pyproject.toml +1 -1
- {bullishpy-0.46.0 → bullishpy-0.48.0}/README.md +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/__init__.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/analysis/__init__.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/analysis/backtest.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/analysis/constants.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/analysis/filter.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/analysis/functions.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/analysis/indicators.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/analysis/industry_views.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/analysis/predefined_filters.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/app/__init__.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/app/app.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/cli.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/__init__.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/README +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/alembic.ini +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/env.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/script.py.mako +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/037dbd721317_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/040b15fba458_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/08ac1116e055_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/11d35a452b40_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/12889a2cbd7d_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/17e51420e7ad_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/49c83f9eb5ac_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/4b0a2f40b7d3_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/5b10ee7604c1_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/6d252e23f543_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/73564b60fe24_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/79bc71ec6f9e_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/ae444f338124_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/b76079e9845f_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/bf6b86dd5463_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/d0e58e050845_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/d663166c531d_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/ec25c8fa449f_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/ee5baabb35f8_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/fc191121f522_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/alembic/versions/ff0cc4ba40ec_.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/crud.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/schemas.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/scripts/create_revision.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/scripts/stamp.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/scripts/upgrade.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/database/settings.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/exceptions.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/figures/__init__.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/figures/figures.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/interface/__init__.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/interface/interface.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/jobs/__init__.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/jobs/app.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/jobs/models.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/utils/__init__.py +0 -0
- {bullishpy-0.46.0 → bullishpy-0.48.0}/bullish/utils/checks.py +0 -0
|
@@ -496,6 +496,7 @@ class AnalysisView(BaseModel):
|
|
|
496
496
|
yearly_growth: Optional[float] = None
|
|
497
497
|
weekly_growth: Optional[float] = None
|
|
498
498
|
monthly_growth: Optional[float] = None
|
|
499
|
+
upside: Optional[float] = None
|
|
499
500
|
|
|
500
501
|
|
|
501
502
|
def json_loads(value: Any) -> Any:
|
|
@@ -525,6 +526,13 @@ class SubjectAnalysis(BaseModel):
|
|
|
525
526
|
Optional[List[Dict[str, Any]]], BeforeValidator(json_loads)
|
|
526
527
|
] = None
|
|
527
528
|
summary: Annotated[Optional[Dict[str, Any]], BeforeValidator(json_loads)] = None
|
|
529
|
+
upside: Optional[float] = None
|
|
530
|
+
|
|
531
|
+
def compute_upside(self, last_price: float) -> None:
|
|
532
|
+
if self.high_price_target is not None:
|
|
533
|
+
self.upside = (float(self.high_price_target) - float(last_price)) / float(
|
|
534
|
+
last_price
|
|
535
|
+
)
|
|
528
536
|
|
|
529
537
|
def to_news(self) -> Optional[str]:
|
|
530
538
|
if not self.news_summary:
|
|
@@ -556,6 +564,8 @@ class Analysis(SubjectAnalysis, AnalysisEarningsDate, AnalysisView, BaseEquity,
|
|
|
556
564
|
technical_analysis = TechnicalAnalysis.from_data(prices.to_dataframe(), ticker)
|
|
557
565
|
next_earnings_date = bearish_db.read_next_earnings_date(ticker.symbol)
|
|
558
566
|
subject = bearish_db.read_subject(ticker.symbol)
|
|
567
|
+
if subject:
|
|
568
|
+
subject.compute_upside(technical_analysis.last_price)
|
|
559
569
|
|
|
560
570
|
return cls.model_validate(
|
|
561
571
|
equity.model_dump()
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""
|
|
2
|
+
|
|
3
|
+
Revision ID: 4ee82b171449
|
|
4
|
+
Revises: ae444f338124
|
|
5
|
+
Create Date: 2025-08-10 12:16:03.791151
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Sequence, Union
|
|
10
|
+
|
|
11
|
+
from alembic import op
|
|
12
|
+
import sqlalchemy as sa
|
|
13
|
+
from sqlalchemy.dialects import sqlite
|
|
14
|
+
|
|
15
|
+
# revision identifiers, used by Alembic.
|
|
16
|
+
revision: str = "4ee82b171449"
|
|
17
|
+
down_revision: Union[str, None] = "ae444f338124"
|
|
18
|
+
branch_labels: Union[str, Sequence[str], None] = None
|
|
19
|
+
depends_on: Union[str, Sequence[str], None] = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def upgrade() -> None:
|
|
23
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
24
|
+
with op.batch_alter_table("analysis", schema=None) as batch_op:
|
|
25
|
+
batch_op.add_column(sa.Column("upside", sa.Float(), nullable=True))
|
|
26
|
+
batch_op.create_index("ix_analysis_upside", ["upside"], unique=False)
|
|
27
|
+
|
|
28
|
+
# ### end Alembic commands ###
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def downgrade() -> None:
|
|
32
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
33
|
+
with op.batch_alter_table("analysis", schema=None) as batch_op:
|
|
34
|
+
batch_op.drop_index("ix_analysis_upside")
|
|
35
|
+
batch_op.drop_column("upside")
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
import logging
|
|
3
|
-
import random
|
|
4
3
|
from typing import Optional, Any, Callable, List
|
|
5
4
|
|
|
5
|
+
import pandas as pd
|
|
6
6
|
from bearish.main import Bearish # type: ignore
|
|
7
7
|
from tickermood.main import get_news # type: ignore
|
|
8
8
|
from tickermood.types import DatabaseConfig # type: ignore
|
|
@@ -15,7 +15,7 @@ from .models import JobTrackerStatus, JobTracker, JobType
|
|
|
15
15
|
from ..analysis.analysis import run_analysis, run_signal_series_analysis
|
|
16
16
|
from ..analysis.backtest import run_many_tests, BackTestConfig
|
|
17
17
|
from ..analysis.industry_views import compute_industry_view
|
|
18
|
-
from ..analysis.predefined_filters import predefined_filters
|
|
18
|
+
from ..analysis.predefined_filters import predefined_filters, load_custom_filters
|
|
19
19
|
from ..database.crud import BullishDb
|
|
20
20
|
from bullish.analysis.filter import FilterUpdate
|
|
21
21
|
from ..utils.checks import DataBaseSingleTon
|
|
@@ -157,11 +157,11 @@ def news(
|
|
|
157
157
|
def cron_news(
|
|
158
158
|
task: Optional[Task] = None,
|
|
159
159
|
) -> None:
|
|
160
|
-
|
|
160
|
+
filters = load_custom_filters()
|
|
161
161
|
database = DataBaseSingleTon()
|
|
162
|
-
if database.valid():
|
|
162
|
+
if database.valid() and filters:
|
|
163
163
|
bullish_db = BullishDb(database_path=database.path)
|
|
164
|
-
data = bullish_db.read_filter_query(
|
|
164
|
+
data = pd.concat([bullish_db.read_filter_query(f) for f in filters])
|
|
165
165
|
if not data.empty and "symbol" in data.columns:
|
|
166
166
|
job_tracker(base_news)(
|
|
167
167
|
database_path=database.path,
|
|
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
|
|
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
|