bullishpy 0.44.0__py3-none-any.whl → 0.46.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.

Potentially problematic release.


This version of bullishpy might be problematic. Click here for more details.

@@ -1,5 +1,8 @@
1
1
  import datetime
2
+ import json
3
+ import os
2
4
  from datetime import timedelta
5
+ from pathlib import Path
3
6
  from typing import Dict, Any, Optional, List, Union, get_args
4
7
 
5
8
  from bullish.analysis.analysis import AnalysisView
@@ -141,6 +144,20 @@ class NamedFilterQuery(FilterQuery):
141
144
  ]
142
145
 
143
146
 
147
+ def load_custom_filters() -> List[NamedFilterQuery]:
148
+ if "CUSTOM_FILTERS_PATH" in os.environ:
149
+ custom_filters_path = os.environ["CUSTOM_FILTERS_PATH"]
150
+ return read_custom_filters(Path(custom_filters_path))
151
+ return []
152
+
153
+
154
+ def read_custom_filters(custom_filters_path: Path) -> List[NamedFilterQuery]:
155
+ if custom_filters_path.exists():
156
+ filters = json.loads(custom_filters_path.read_text())
157
+ return [NamedFilterQuery.model_validate(filter) for filter in filters]
158
+ return []
159
+
160
+
144
161
  SMALL_CAP = NamedFilterQuery(
145
162
  name="Small Cap",
146
163
  last_price=[1, 20],
@@ -193,11 +210,6 @@ NEXT_EARNINGS_DATE = NamedFilterQuery(
193
210
  datetime.date.today() + timedelta(days=20),
194
211
  ],
195
212
  ).variants()
196
- SOLD_POSITIONS = NamedFilterQuery(
197
- name="Sold Positions",
198
- order_by_desc="market_capitalization",
199
- symbol=["R3NK.DE", "VKTX", "RHM.DE", "IQV", "DAL"],
200
- ).variants()
201
213
 
202
214
 
203
215
  def predefined_filters() -> list[NamedFilterQuery]:
@@ -207,7 +219,7 @@ def predefined_filters() -> list[NamedFilterQuery]:
207
219
  *TOP_PERFORMERS_YEARLY,
208
220
  *LARGE_CAPS,
209
221
  *NEXT_EARNINGS_DATE,
210
- *SOLD_POSITIONS,
222
+ *load_custom_filters(),
211
223
  ]
212
224
 
213
225
 
bullish/cli.py CHANGED
@@ -19,17 +19,24 @@ STREAMLIT_FILE = Path(__file__).parent.joinpath("app", "app.py")
19
19
 
20
20
 
21
21
  @app.command()
22
- def serve(
22
+ def serve( # noqa: C901
23
23
  host: str = typer.Option("0.0.0.0", help="Streamlit host"), # noqa: S104
24
24
  port: int = typer.Option(8501, help="Streamlit port"),
25
25
  env_vars: Path = typer.Option( # noqa: B008
26
26
  None, help="Environment variables file"
27
27
  ),
28
+ custom_filters: Path = typer.Option( # noqa: B008
29
+ None, help="Environment variables file"
30
+ ),
28
31
  ) -> None:
29
32
  if env_vars:
30
33
  env_vars_path = Path(env_vars)
31
34
  if env_vars_path.exists():
32
35
  load_dotenv(dotenv_path=env_vars_path)
36
+ if custom_filters:
37
+ custom_filters_path = Path(custom_filters)
38
+ if custom_filters_path.exists():
39
+ os.environ["CUSTOM_FILTERS_PATH"] = str(custom_filters_path)
33
40
  children: list[subprocess.Popen] = [] # type: ignore
34
41
 
35
42
  def _shutdown(*_: Any) -> None:
bullish/jobs/tasks.py CHANGED
@@ -1,5 +1,6 @@
1
1
  import functools
2
2
  import logging
3
+ import random
3
4
  from typing import Optional, Any, Callable, List
4
5
 
5
6
  from bearish.main import Bearish # type: ignore
@@ -14,7 +15,7 @@ from .models import JobTrackerStatus, JobTracker, JobType
14
15
  from ..analysis.analysis import run_analysis, run_signal_series_analysis
15
16
  from ..analysis.backtest import run_many_tests, BackTestConfig
16
17
  from ..analysis.industry_views import compute_industry_view
17
- from ..analysis.predefined_filters import predefined_filters, NEXT_EARNINGS_DATE
18
+ from ..analysis.predefined_filters import predefined_filters
18
19
  from ..database.crud import BullishDb
19
20
  from bullish.analysis.filter import FilterUpdate
20
21
  from ..utils.checks import DataBaseSingleTon
@@ -91,9 +92,10 @@ def cron_update(
91
92
  task: Optional[Task] = None,
92
93
  ) -> None:
93
94
  database = DataBaseSingleTon()
94
- job_tracker(_base_update)(
95
- database.path, "Update data", [], FilterUpdate(), task=task
96
- )
95
+ if database.valid():
96
+ job_tracker(_base_update)(
97
+ database.path, "Update data", [], FilterUpdate(), task=task
98
+ )
97
99
 
98
100
 
99
101
  @huey.task(context=True) # type: ignore
@@ -155,14 +157,16 @@ def news(
155
157
  def cron_news(
156
158
  task: Optional[Task] = None,
157
159
  ) -> None:
158
- earnings_date = NEXT_EARNINGS_DATE[1]
160
+ filter = random.choice(predefined_filters()) # noqa: S311
159
161
  database = DataBaseSingleTon()
160
- bullish_db = BullishDb(database_path=database.path)
161
- data = bullish_db.read_filter_query(earnings_date)
162
- job_tracker(base_news)(
163
- database_path=database.path,
164
- job_type="Fetching news",
165
- symbols=data["symbol"].unique().tolist(),
166
- headless=False,
167
- task=task,
168
- )
162
+ if database.valid():
163
+ bullish_db = BullishDb(database_path=database.path)
164
+ data = bullish_db.read_filter_query(filter)
165
+ if not data.empty and "symbol" in data.columns:
166
+ job_tracker(base_news)(
167
+ database_path=database.path,
168
+ job_type="Fetching news",
169
+ symbols=data["symbol"].unique().tolist(),
170
+ headless=False,
171
+ task=task,
172
+ )
bullish/utils/checks.py CHANGED
@@ -77,3 +77,6 @@ class DataBaseSingleTon:
77
77
  def __init__(self, path: Optional[Path] = None) -> None:
78
78
  if not hasattr(self, "path"): # Only set once
79
79
  self.path = path
80
+
81
+ def valid(self) -> bool:
82
+ return hasattr(self, "path")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bullishpy
3
- Version: 0.44.0
3
+ Version: 0.46.0
4
4
  Summary:
5
5
  Author: aan
6
6
  Author-email: andoludovic.andriamamonjy@gmail.com
@@ -7,10 +7,10 @@ bullish/analysis/filter.py,sha256=LKmsO3ei7Eo_SJsEVbZqETyIdOpW55xVheO6_GNoA0s,92
7
7
  bullish/analysis/functions.py,sha256=CuMgOjpQeg4KsDMUBdHRlxL1dRlos16KRyLhQe8PYUQ,14819
8
8
  bullish/analysis/indicators.py,sha256=XsMHc4-hEZwxFpI3JI-s4C2hcg0eCQLWcAQ8P46dtL8,26812
9
9
  bullish/analysis/industry_views.py,sha256=-B4CCAYz2arGQtWTXLLMpox0loO_MGdVQd2ycCRMOQQ,6799
10
- bullish/analysis/predefined_filters.py,sha256=kx3vhtvGu_0ySWsWPzkqXONmB7COWgMowv3TEVrk1Uc,8198
10
+ bullish/analysis/predefined_filters.py,sha256=0HHEvy8fpLq2Ub3Hh23J7_V35bIPdsJNMu2jNo998Oc,8589
11
11
  bullish/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  bullish/app/app.py,sha256=WUyM51r57BEmoXkn1Y4Sy1nGqYZ4L3kJkZkhuNK_h6Y,16839
13
- bullish/cli.py,sha256=azhVLwOUrmwrtFAJSgva8-UFgNgkepXhjp7DxQNc-yw,2427
13
+ bullish/cli.py,sha256=yYqiEQAvOIQ-pTn77RPuE449gwaEGBeQwNHHAJ5yQDM,2739
14
14
  bullish/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  bullish/database/alembic/README,sha256=heMzebYwlGhnE8_4CWJ4LS74WoEZjBy-S-mIJRxAEKI,39
16
16
  bullish/database/alembic/alembic.ini,sha256=VuwqBJV5ObTyyRNrqv8Xr-TDIRfqPjP9R1mqewYM_xE,3695
@@ -51,10 +51,10 @@ bullish/interface/interface.py,sha256=R2qVEMyBl9mBlPUO40zXp4vhfLKH7pgl_u2BmAVlD4
51
51
  bullish/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
52
  bullish/jobs/app.py,sha256=5MJ5KXUo7JSNAvOPgkpIMasD11VTrjQvGzM7vmCY65E,77
53
53
  bullish/jobs/models.py,sha256=S2yvBf69lmt4U-5OU5CjXCMSw0s9Ubh9xkrB3k2qOZo,764
54
- bullish/jobs/tasks.py,sha256=fs6QuO9rXsj-Ncrvq1oDH1VF3KOMEH4vfghm444_8E8,5156
54
+ bullish/jobs/tasks.py,sha256=XO8Pa6MoYeJQ4uvD3OYStEOh7l5zTK7hUFKvZksvpOM,5346
55
55
  bullish/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
- bullish/utils/checks.py,sha256=M5FJr9IJ0NFriSixSwPvHok34vpfotgDhabZ8jth6L4,2566
57
- bullishpy-0.44.0.dist-info/METADATA,sha256=KihJwkFRxKf--RFVxDDBgdv8KfoaCBVj_t2DzFmVcMw,830
58
- bullishpy-0.44.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
59
- bullishpy-0.44.0.dist-info/entry_points.txt,sha256=eaPpmL6vmSBFo0FBtwibCXGqAW4LFJ83whJzT1VjD-0,43
60
- bullishpy-0.44.0.dist-info/RECORD,,
56
+ bullish/utils/checks.py,sha256=jolHOnxkc5GvVuvVzlwHhM6EO-Y-eC0q3rXlHE-UG9Y,2633
57
+ bullishpy-0.46.0.dist-info/METADATA,sha256=Q_g58-6l-nKyulwuC8HfMF-fS6VN5_kZY1MM8me7nSU,830
58
+ bullishpy-0.46.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
59
+ bullishpy-0.46.0.dist-info/entry_points.txt,sha256=eaPpmL6vmSBFo0FBtwibCXGqAW4LFJ83whJzT1VjD-0,43
60
+ bullishpy-0.46.0.dist-info/RECORD,,