bullishpy 0.30.0__py3-none-any.whl → 0.32.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.

@@ -214,6 +214,12 @@ class FilterQuery(GeneralFilter, *TechnicalAnalysisFilters, *FundamentalAnalysis
214
214
  order_by_asc = f"ORDER BY {value} ASC"
215
215
  elif isinstance(value, str) and bool(value) and parameter == "limit":
216
216
  limit = f" LIMIT {int(value)}"
217
+ elif (
218
+ isinstance(value, list)
219
+ and len(value) == SIZE_RANGE
220
+ and all(isinstance(item, (int, float)) for item in value)
221
+ ):
222
+ query.append(f"{parameter} BETWEEN {value[0]} AND {value[1]}")
217
223
  elif (
218
224
  (
219
225
  isinstance(value, list)
@@ -224,14 +230,8 @@ class FilterQuery(GeneralFilter, *TechnicalAnalysisFilters, *FundamentalAnalysis
224
230
  or (
225
231
  isinstance(value, list)
226
232
  and len(value) == SIZE_RANGE
227
- and all(isinstance(item, (int, float)) for item in value)
233
+ and all(isinstance(item, date) for item in value)
228
234
  )
229
- ):
230
- query.append(f"{parameter} BETWEEN {value[0]} AND {value[1]}")
231
- elif (
232
- isinstance(value, list)
233
- and len(value) == SIZE_RANGE
234
- and all(isinstance(item, date) for item in value)
235
235
  ):
236
236
  query.append(f"{parameter} BETWEEN '{value[0]}' AND '{value[1]}'")
237
237
  elif (
@@ -242,7 +242,7 @@ class FilterQuery(GeneralFilter, *TechnicalAnalysisFilters, *FundamentalAnalysis
242
242
  general_filters = [f"'{v}'" for v in value]
243
243
  query.append(f"{parameter} IN ({', '.join(general_filters)})")
244
244
  else:
245
- raise NotImplementedError
245
+ raise NotImplementedError(f"with value {value}")
246
246
  query_ = " AND ".join(query)
247
247
  query__ = f"{query_} {order_by_desc.strip()} {order_by_asc.strip()}".strip()
248
248
  if limit is not None:
@@ -108,10 +108,36 @@ class NamedFilterQuery(FilterQuery):
108
108
  | {"name": f"{self.name} ({suffix})", "country": countries}
109
109
  )
110
110
 
111
+ def update_indicator_filter(
112
+ self, suffix: str, rsi_parameter_name: str
113
+ ) -> "NamedFilterQuery":
114
+ return NamedFilterQuery.model_validate(
115
+ self.model_dump()
116
+ | {"name": f"{self.name} ({suffix})", rsi_parameter_name: DATE_THRESHOLD}
117
+ )
118
+
111
119
  def variants(self) -> List["NamedFilterQuery"]:
112
120
  return [
113
121
  self.country_variant("Europe", list(get_args(Europe))),
114
122
  self.country_variant("Us", list(get_args(Us))),
123
+ self.country_variant("Europe", list(get_args(Europe)))
124
+ .update_indicator_filter("RSI 30", "rsi_bullish_crossover_30")
125
+ .update_indicator_filter("MACD", "macd_12_26_9_bullish_crossover"),
126
+ self.country_variant("Europe", list(get_args(Europe)))
127
+ .update_indicator_filter("RSI 40", "rsi_bullish_crossover_40")
128
+ .update_indicator_filter("MACD", "macd_12_26_9_bullish_crossover"),
129
+ self.country_variant("Europe", list(get_args(Europe)))
130
+ .update_indicator_filter("RSI Neutral", "rsi_neutral")
131
+ .update_indicator_filter("MACD", "macd_12_26_9_bullish_crossover"),
132
+ self.country_variant("Us", list(get_args(Us)))
133
+ .update_indicator_filter("RSI 30", "rsi_bullish_crossover_30")
134
+ .update_indicator_filter("MACD", "macd_12_26_9_bullish_crossover"),
135
+ self.country_variant("Us", list(get_args(Us)))
136
+ .update_indicator_filter("RSI 40", "rsi_bullish_crossover_40")
137
+ .update_indicator_filter("MACD", "macd_12_26_9_bullish_crossover"),
138
+ self.country_variant("Us", list(get_args(Us)))
139
+ .update_indicator_filter("RSI Neutral", "rsi_neutral")
140
+ .update_indicator_filter("MACD", "macd_12_26_9_bullish_crossover"),
115
141
  ]
116
142
 
117
143
 
@@ -126,6 +152,18 @@ SMALL_CAP = NamedFilterQuery(
126
152
 
127
153
  TOP_PERFORMERS = NamedFilterQuery(
128
154
  name="Top Performers",
155
+ volume_above_average=DATE_THRESHOLD,
156
+ sma_50_above_sma_200=[
157
+ datetime.date.today() - datetime.timedelta(days=5000),
158
+ datetime.date.today() - datetime.timedelta(days=10),
159
+ ],
160
+ weekly_growth=[1, 100],
161
+ monthly_growth=[8, 100],
162
+ order_by_desc="market_capitalization",
163
+ ).variants()
164
+
165
+ TOP_PERFORMERS_YEARLY = NamedFilterQuery(
166
+ name="Top Performers Yearly",
129
167
  sma_50_above_sma_200=[
130
168
  datetime.date.today() - datetime.timedelta(days=5000),
131
169
  datetime.date.today() - datetime.timedelta(days=10),
@@ -137,6 +175,7 @@ TOP_PERFORMERS = NamedFilterQuery(
137
175
  volume_above_average=DATE_THRESHOLD,
138
176
  weekly_growth=[1, 100],
139
177
  monthly_growth=[8, 100],
178
+ yearly_growth=[30, 100],
140
179
  order_by_desc="market_capitalization",
141
180
  ).variants()
142
181
 
@@ -155,31 +194,14 @@ NEXT_EARNINGS_DATE = NamedFilterQuery(
155
194
  ],
156
195
  ).variants()
157
196
 
158
- RSI_CROSSOVER_40 = NamedFilterQuery(
159
- name="RSI cross-over 40",
160
- rsi_bullish_crossover_40=DATE_THRESHOLD,
161
- market_capitalization=[5e8, 1e13],
162
- order_by_desc="market_capitalization",
163
- country=["Germany", "United states", "France", "United kingdom", "Canada", "Japan"],
164
- ).variants()
165
-
166
- RSI_CROSSOVER_30 = NamedFilterQuery(
167
- name="RSI cross-over 30",
168
- price_per_earning_ratio=[10, 500],
169
- rsi_bullish_crossover_30=DATE_THRESHOLD,
170
- market_capitalization=[5e8, 1e13],
171
- order_by_desc="market_capitalization",
172
- ).variants()
173
-
174
197
 
175
198
  def predefined_filters() -> list[NamedFilterQuery]:
176
199
  return [
177
200
  *SMALL_CAP,
178
201
  *TOP_PERFORMERS,
202
+ *TOP_PERFORMERS_YEARLY,
179
203
  *LARGE_CAPS,
180
204
  *NEXT_EARNINGS_DATE,
181
- *RSI_CROSSOVER_40,
182
- *RSI_CROSSOVER_30,
183
205
  ]
184
206
 
185
207
 
bullish/jobs/tasks.py CHANGED
@@ -111,4 +111,4 @@ def news(
111
111
  task: Optional[Task] = None,
112
112
  ) -> None:
113
113
  database_config = DatabaseConfig(database_path=database_path, no_migration=True)
114
- get_news(symbols, database_config, headless=headless, model_name="gpt-4o-mini")
114
+ get_news(symbols, database_config, headless=headless)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bullishpy
3
- Version: 0.30.0
3
+ Version: 0.32.0
4
4
  Summary:
5
5
  Author: aan
6
6
  Author-email: andoludovic.andriamamonjy@gmail.com
@@ -17,7 +17,7 @@ Requires-Dist: streamlit (>=1.45.1,<2.0.0)
17
17
  Requires-Dist: streamlit-file-browser (>=3.2.22,<4.0.0)
18
18
  Requires-Dist: streamlit-pydantic (>=v0.6.1-rc.3,<0.7.0)
19
19
  Requires-Dist: ta-lib (>=0.6.4,<0.7.0)
20
- Requires-Dist: tickermood (>=0.12.0,<0.13.0)
20
+ Requires-Dist: tickermood (>=0.13.0,<0.14.0)
21
21
  Requires-Dist: vectorbt (>=0.28.0,<0.29.0)
22
22
  Description-Content-Type: text/markdown
23
23
 
@@ -3,11 +3,11 @@ bullish/analysis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
3
3
  bullish/analysis/analysis.py,sha256=nCb___Tb2aOFIu1wWtPwS1VVZfXOSCp5zUWaIOCdvl4,22345
4
4
  bullish/analysis/backtest.py,sha256=x91ek5kOzJHvYq0TmJh1Q8wBDDduIaieE0zDaoZFXew,14325
5
5
  bullish/analysis/constants.py,sha256=X3oCyYNA6B-jsZSYJLeGQ94S453Z7jIVNPmv3lMPp8Q,9922
6
- bullish/analysis/filter.py,sha256=0h4wfAuZ-ohhACPhOjZrNEV17gbZ7FopNv0k0HBtIWE,9262
6
+ bullish/analysis/filter.py,sha256=mGWizTda_QHEmusDmB_xvOhjlsOKcbILfKLjJLAnCnE,9285
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=RZe3lk1pLnQ7lZkTK7hC5Hh8GhaZ1-9fqy-D1A_3aR8,6657
10
+ bullish/analysis/predefined_filters.py,sha256=O_elRTipLcL3leo0RWkhs3bEU-1_Rszx4MCTv27TPTg,8089
11
11
  bullish/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  bullish/app/app.py,sha256=9zxskm5gHt2uDGn59vL4ltI2zgrIBGhavp7jogt1us0,14411
13
13
  bullish/cli.py,sha256=azhVLwOUrmwrtFAJSgva8-UFgNgkepXhjp7DxQNc-yw,2427
@@ -50,10 +50,10 @@ bullish/interface/interface.py,sha256=dFQW0tMYbFL-gWrlWTWP1qKKSzqlrhz6-T_lLqhILy
50
50
  bullish/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
51
  bullish/jobs/app.py,sha256=5MJ5KXUo7JSNAvOPgkpIMasD11VTrjQvGzM7vmCY65E,77
52
52
  bullish/jobs/models.py,sha256=S2yvBf69lmt4U-5OU5CjXCMSw0s9Ubh9xkrB3k2qOZo,764
53
- bullish/jobs/tasks.py,sha256=5dGWT7uZlirlQsqvI2BR9V3ywbt8yD0s-jaNiTFaIAg,3717
53
+ bullish/jobs/tasks.py,sha256=vXPbISYFUZlrYkMVUb7y-g-z0BBi91wQLm8RbYqR4I0,3691
54
54
  bullish/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
55
  bullish/utils/checks.py,sha256=Va10_xDVVnxYkOD2hafvyQ-TFV8FQpOkr4huJ7XgpDM,2188
56
- bullishpy-0.30.0.dist-info/METADATA,sha256=9WAIcyoEhmc6lRgp9WoIu8xhjEOyDJD-st2OB4T0ExE,830
57
- bullishpy-0.30.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
58
- bullishpy-0.30.0.dist-info/entry_points.txt,sha256=eaPpmL6vmSBFo0FBtwibCXGqAW4LFJ83whJzT1VjD-0,43
59
- bullishpy-0.30.0.dist-info/RECORD,,
56
+ bullishpy-0.32.0.dist-info/METADATA,sha256=eqQ22h8IXWTm9MrZuO0zQCQBC--Yo1J6YoHywBRE_Wc,830
57
+ bullishpy-0.32.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
58
+ bullishpy-0.32.0.dist-info/entry_points.txt,sha256=eaPpmL6vmSBFo0FBtwibCXGqAW4LFJ83whJzT1VjD-0,43
59
+ bullishpy-0.32.0.dist-info/RECORD,,