bullishpy 0.10.0__py3-none-any.whl → 0.12.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.
- bullish/analysis/analysis.py +24 -3
- bullish/analysis/predefined_filters.py +132 -15
- bullish/app/app.py +20 -6
- bullish/database/crud.py +10 -0
- bullish/interface/interface.py +6 -0
- {bullishpy-0.10.0.dist-info → bullishpy-0.12.0.dist-info}/METADATA +3 -2
- {bullishpy-0.10.0.dist-info → bullishpy-0.12.0.dist-info}/RECORD +9 -9
- {bullishpy-0.10.0.dist-info → bullishpy-0.12.0.dist-info}/WHEEL +0 -0
- {bullishpy-0.10.0.dist-info → bullishpy-0.12.0.dist-info}/entry_points.txt +0 -0
bullish/analysis/analysis.py
CHANGED
|
@@ -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
|
+
)
|
|
@@ -70,15 +70,61 @@ SHOOTING_STARS = NamedFilterQuery(
|
|
|
70
70
|
order_by_asc="last_price",
|
|
71
71
|
)
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
RSI_CROSSOVER_TECH = NamedFilterQuery(
|
|
74
74
|
name="RSI cross-over",
|
|
75
75
|
cash_flow=["positive_free_cash_flow"],
|
|
76
76
|
properties=["operating_cash_flow_is_higher_than_net_income"],
|
|
77
77
|
return_after_rsi_crossover_45_period_90=[0.0, 100],
|
|
78
78
|
rsi_bullish_crossover_45=DATE_THRESHOLD,
|
|
79
|
-
market_capitalization=[
|
|
79
|
+
market_capitalization=[5e8, 1e11], # 1 billion to 1 trillion
|
|
80
|
+
order_by_desc="market_capitalization",
|
|
81
|
+
country=["Germany", "United states", "France", "United kingdom", "Canada", "Japan"],
|
|
82
|
+
industry=[
|
|
83
|
+
"Semiconductors",
|
|
84
|
+
"Software - Application",
|
|
85
|
+
"Software - Infrastructure",
|
|
86
|
+
"Biotechnology",
|
|
87
|
+
"Diagnostics & Research",
|
|
88
|
+
"Medical Devices",
|
|
89
|
+
"Health Information Services",
|
|
90
|
+
"Internet Retail",
|
|
91
|
+
"Electronic Gaming & Multimedia",
|
|
92
|
+
"Internet Content & Information",
|
|
93
|
+
"Solar",
|
|
94
|
+
"Information Technology Services",
|
|
95
|
+
"Scientific & Technical Instruments",
|
|
96
|
+
"Semiconductor Equipment & Materials",
|
|
97
|
+
"Diagnostics & Research",
|
|
98
|
+
],
|
|
99
|
+
)
|
|
100
|
+
RSI_CROSSOVER_TECH_PE = NamedFilterQuery(
|
|
101
|
+
name="RSI cross-over P/E",
|
|
102
|
+
cash_flow=["positive_free_cash_flow"],
|
|
103
|
+
properties=["operating_cash_flow_is_higher_than_net_income"],
|
|
104
|
+
price_per_earning_ratio=[5, 30], # P/E ratio between 10 and 100
|
|
105
|
+
rsi_bullish_crossover_45=DATE_THRESHOLD,
|
|
106
|
+
market_capitalization=[5e8, 1e12], # 1 billion to 1 trillion
|
|
80
107
|
order_by_desc="market_capitalization",
|
|
108
|
+
country=["Germany", "United states", "France", "United kingdom", "Canada", "Japan"],
|
|
109
|
+
industry=[
|
|
110
|
+
"Semiconductors",
|
|
111
|
+
"Software - Application",
|
|
112
|
+
"Software - Infrastructure",
|
|
113
|
+
"Biotechnology",
|
|
114
|
+
"Diagnostics & Research",
|
|
115
|
+
"Medical Devices",
|
|
116
|
+
"Health Information Services",
|
|
117
|
+
"Internet Retail",
|
|
118
|
+
"Electronic Gaming & Multimedia",
|
|
119
|
+
"Internet Content & Information",
|
|
120
|
+
"Solar",
|
|
121
|
+
"Information Technology Services",
|
|
122
|
+
"Scientific & Technical Instruments",
|
|
123
|
+
"Semiconductor Equipment & Materials",
|
|
124
|
+
"Diagnostics & Research",
|
|
125
|
+
],
|
|
81
126
|
)
|
|
127
|
+
|
|
82
128
|
MICRO_CAP_EVENT_SPECULATION = NamedFilterQuery(
|
|
83
129
|
name="Micro-Cap Event Speculation",
|
|
84
130
|
description="seeks tiny names where unusual volume and price gaps hint at "
|
|
@@ -185,23 +231,94 @@ OVERSOLD_MEAN_REVERSION = NamedFilterQuery(
|
|
|
185
231
|
mfi_oversold=DATE_THRESHOLD,
|
|
186
232
|
lower_than_200_day_high=DATE_THRESHOLD,
|
|
187
233
|
)
|
|
234
|
+
RSI_CROSSOVER_30_GROWTH_STOCK_STRONG_FUNDAMENTAL = NamedFilterQuery(
|
|
235
|
+
name="RSI cross-over 30 growth stock strong fundamental",
|
|
236
|
+
income=[
|
|
237
|
+
"positive_operating_income",
|
|
238
|
+
"growing_operating_income",
|
|
239
|
+
"positive_net_income",
|
|
240
|
+
"growing_net_income",
|
|
241
|
+
],
|
|
242
|
+
cash_flow=["positive_free_cash_flow"],
|
|
243
|
+
properties=["operating_cash_flow_is_higher_than_net_income"],
|
|
244
|
+
price_per_earning_ratio=[20, 40],
|
|
245
|
+
rsi_bullish_crossover_30=DATE_THRESHOLD,
|
|
246
|
+
market_capitalization=[5e8, 1e12],
|
|
247
|
+
order_by_desc="market_capitalization",
|
|
248
|
+
country=["Germany", "United states", "France", "United kingdom", "Canada", "Japan"],
|
|
249
|
+
)
|
|
250
|
+
RSI_CROSSOVER_40_GROWTH_STOCK_STRONG_FUNDAMENTAL = NamedFilterQuery(
|
|
251
|
+
name="RSI cross-over 40 growth stock strong fundamental",
|
|
252
|
+
income=[
|
|
253
|
+
"positive_operating_income",
|
|
254
|
+
"growing_operating_income",
|
|
255
|
+
"positive_net_income",
|
|
256
|
+
"growing_net_income",
|
|
257
|
+
],
|
|
258
|
+
cash_flow=["positive_free_cash_flow"],
|
|
259
|
+
properties=["operating_cash_flow_is_higher_than_net_income"],
|
|
260
|
+
price_per_earning_ratio=[20, 40],
|
|
261
|
+
rsi_bullish_crossover_40=DATE_THRESHOLD,
|
|
262
|
+
market_capitalization=[5e8, 1e12],
|
|
263
|
+
order_by_desc="market_capitalization",
|
|
264
|
+
country=["Germany", "United states", "France", "United kingdom", "Canada", "Japan"],
|
|
265
|
+
)
|
|
266
|
+
RSI_CROSSOVER_45_GROWTH_STOCK_STRONG_FUNDAMENTAL = NamedFilterQuery(
|
|
267
|
+
name="RSI cross-over 45 growth stock strong fundamental",
|
|
268
|
+
income=[
|
|
269
|
+
"positive_operating_income",
|
|
270
|
+
"growing_operating_income",
|
|
271
|
+
"positive_net_income",
|
|
272
|
+
"growing_net_income",
|
|
273
|
+
],
|
|
274
|
+
cash_flow=["positive_free_cash_flow"],
|
|
275
|
+
properties=["operating_cash_flow_is_higher_than_net_income"],
|
|
276
|
+
price_per_earning_ratio=[20, 40],
|
|
277
|
+
rsi_bullish_crossover_45=DATE_THRESHOLD,
|
|
278
|
+
market_capitalization=[5e8, 1e12],
|
|
279
|
+
order_by_desc="market_capitalization",
|
|
280
|
+
country=["Germany", "United states", "France", "United kingdom", "Canada", "Japan"],
|
|
281
|
+
)
|
|
282
|
+
RSI_CROSSOVER_30_GROWTH_STOCK = NamedFilterQuery(
|
|
283
|
+
name="RSI cross-over 30 growth stock",
|
|
284
|
+
cash_flow=["positive_free_cash_flow"],
|
|
285
|
+
properties=["operating_cash_flow_is_higher_than_net_income"],
|
|
286
|
+
price_per_earning_ratio=[20, 40],
|
|
287
|
+
rsi_bullish_crossover_30=DATE_THRESHOLD,
|
|
288
|
+
market_capitalization=[5e8, 1e12],
|
|
289
|
+
order_by_desc="market_capitalization",
|
|
290
|
+
country=["Germany", "United states", "France", "United kingdom", "Canada", "Japan"],
|
|
291
|
+
)
|
|
292
|
+
RSI_CROSSOVER_40_GROWTH_STOCK = NamedFilterQuery(
|
|
293
|
+
name="RSI cross-over 40 growth stock",
|
|
294
|
+
cash_flow=["positive_free_cash_flow"],
|
|
295
|
+
properties=["operating_cash_flow_is_higher_than_net_income"],
|
|
296
|
+
price_per_earning_ratio=[20, 40],
|
|
297
|
+
rsi_bullish_crossover_40=DATE_THRESHOLD,
|
|
298
|
+
market_capitalization=[5e8, 1e12],
|
|
299
|
+
order_by_desc="market_capitalization",
|
|
300
|
+
country=["Germany", "United states", "France", "United kingdom", "Canada", "Japan"],
|
|
301
|
+
)
|
|
302
|
+
RSI_CROSSOVER_45_GROWTH_STOCK = NamedFilterQuery(
|
|
303
|
+
name="RSI cross-over 45 growth stock",
|
|
304
|
+
cash_flow=["positive_free_cash_flow"],
|
|
305
|
+
properties=["operating_cash_flow_is_higher_than_net_income"],
|
|
306
|
+
price_per_earning_ratio=[20, 40],
|
|
307
|
+
rsi_bullish_crossover_45=DATE_THRESHOLD,
|
|
308
|
+
market_capitalization=[5e8, 1e12],
|
|
309
|
+
order_by_desc="market_capitalization",
|
|
310
|
+
country=["Germany", "United states", "France", "United kingdom", "Canada", "Japan"],
|
|
311
|
+
)
|
|
188
312
|
|
|
189
313
|
|
|
190
314
|
def predefined_filters() -> list[NamedFilterQuery]:
|
|
191
315
|
return [
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
HIGH_QUALITY_CASH_GENERATOR,
|
|
199
|
-
EARNINGS_ACCELERATION_TREND_CONFIRMATION,
|
|
200
|
-
DIVIDEND_GROWTH_COMPOUNDER,
|
|
201
|
-
BREAK_OUT_MOMENTUM,
|
|
202
|
-
OVERSOLD_MEAN_REVERSION,
|
|
203
|
-
SHOOTING_STARS,
|
|
204
|
-
RSI_CROSSOVER,
|
|
316
|
+
RSI_CROSSOVER_30_GROWTH_STOCK_STRONG_FUNDAMENTAL,
|
|
317
|
+
RSI_CROSSOVER_40_GROWTH_STOCK_STRONG_FUNDAMENTAL,
|
|
318
|
+
RSI_CROSSOVER_45_GROWTH_STOCK_STRONG_FUNDAMENTAL,
|
|
319
|
+
RSI_CROSSOVER_30_GROWTH_STOCK,
|
|
320
|
+
RSI_CROSSOVER_40_GROWTH_STOCK,
|
|
321
|
+
RSI_CROSSOVER_45_GROWTH_STOCK,
|
|
205
322
|
]
|
|
206
323
|
|
|
207
324
|
|
bullish/app/app.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
import shelve
|
|
2
3
|
import uuid
|
|
3
4
|
from pathlib import Path
|
|
@@ -37,6 +38,7 @@ CACHE_SHELVE = "user_cache"
|
|
|
37
38
|
DB_KEY = "db_path"
|
|
38
39
|
|
|
39
40
|
st.set_page_config(layout="wide")
|
|
41
|
+
logger = logging.getLogger(__name__)
|
|
40
42
|
|
|
41
43
|
|
|
42
44
|
@st.cache_resource
|
|
@@ -146,10 +148,11 @@ def build_filter(model: Type[BaseModel], data: Dict[str, Any]) -> Dict[str, Any]
|
|
|
146
148
|
key=hash((model.__name__, field)),
|
|
147
149
|
)
|
|
148
150
|
elif info.annotation == Optional[str]: # type: ignore
|
|
151
|
+
options = ["", *groups_mapping()[field]]
|
|
149
152
|
data[field] = st.selectbox(
|
|
150
153
|
name,
|
|
151
|
-
|
|
152
|
-
index=0 if not default else
|
|
154
|
+
options,
|
|
155
|
+
index=0 if not default else options.index(default),
|
|
153
156
|
key=hash((model.__name__, field)),
|
|
154
157
|
)
|
|
155
158
|
|
|
@@ -162,11 +165,22 @@ def build_filter(model: Type[BaseModel], data: Dict[str, Any]) -> Dict[str, Any]
|
|
|
162
165
|
(item.le for item in info.metadata if hasattr(item, "le")),
|
|
163
166
|
info.default[1] if info.default and len(info.default) == 2 else None,
|
|
164
167
|
)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
+
if info.annotation == Optional[List[float]]: # type: ignore
|
|
169
|
+
ge = int(ge) # type: ignore
|
|
170
|
+
le = int(le) # type: ignore
|
|
171
|
+
default = [int(d) for d in default]
|
|
172
|
+
try:
|
|
173
|
+
data[field] = list(
|
|
174
|
+
st.slider( # type: ignore
|
|
175
|
+
name, ge, le, tuple(default), key=hash((model.__name__, field))
|
|
176
|
+
)
|
|
168
177
|
)
|
|
169
|
-
|
|
178
|
+
except Exception as e:
|
|
179
|
+
logger.error(
|
|
180
|
+
f"Error building filter for {model.__name__}.{field} "
|
|
181
|
+
f"with the parameters {(info.annotation, name, ge, le, tuple(default))}: {e}"
|
|
182
|
+
)
|
|
183
|
+
raise e
|
|
170
184
|
return data
|
|
171
185
|
|
|
172
186
|
|
bullish/database/crud.py
CHANGED
|
@@ -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)
|
bullish/interface/interface.py
CHANGED
|
@@ -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,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,12 +1,12 @@
|
|
|
1
1
|
bullish/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
bullish/analysis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
bullish/analysis/analysis.py,sha256=
|
|
3
|
+
bullish/analysis/analysis.py,sha256=v5MFGhQUpMwGAVE0dg2293ldRSgQmqy5CiF8MQFTibM,19165
|
|
4
4
|
bullish/analysis/filter.py,sha256=S8TuxoTAUY0U8ARPjNHE0tSSE_ToWkfZazAgnfgswk4,18136
|
|
5
5
|
bullish/analysis/functions.py,sha256=KKz_0C7maQmcGu2tGwZvioxzmh-JcB-YNpPQGjyyheA,13825
|
|
6
6
|
bullish/analysis/indicators.py,sha256=hZgzTq-80XPP6x7dXGhxd-Zzgra-6D-g3pVxUBYOW44,20167
|
|
7
|
-
bullish/analysis/predefined_filters.py,sha256=
|
|
7
|
+
bullish/analysis/predefined_filters.py,sha256=3O244FCZkbnTSaReh6w6cwEIXdLzQZmbkBS0uRW-Y0M,12391
|
|
8
8
|
bullish/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
bullish/app/app.py,sha256=
|
|
9
|
+
bullish/app/app.py,sha256=E0H78LOODl1H6s308jXpQGTUoFPoLOJkPBXOLQGLCeA,13331
|
|
10
10
|
bullish/cli.py,sha256=uYLZmGDAolZKWzduZ58bP-xul1adg0oKfeUQtZMXTvA,1958
|
|
11
11
|
bullish/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
bullish/database/alembic/README,sha256=heMzebYwlGhnE8_4CWJ4LS74WoEZjBy-S-mIJRxAEKI,39
|
|
@@ -23,7 +23,7 @@ bullish/database/alembic/versions/73564b60fe24_.py,sha256=MTlDRDNHj3E9gK7IMeAzv2
|
|
|
23
23
|
bullish/database/alembic/versions/d663166c531d_.py,sha256=U92l6QXqPniAYrPeu2Bt77ReDbXveLj4aGXtgd806JY,1915
|
|
24
24
|
bullish/database/alembic/versions/ee5baabb35f8_.py,sha256=nBMEY-_C8AsSXVPyaDdUkwrFFo2gxShzJhmrjejDwtc,1632
|
|
25
25
|
bullish/database/alembic/versions/fc191121f522_.py,sha256=0sstF6TpAJ09-Mt-Vek9SdSWksvi4C58a5D92rBtuY8,1894
|
|
26
|
-
bullish/database/crud.py,sha256=
|
|
26
|
+
bullish/database/crud.py,sha256=0AMrs07MMeDq5AVft_pf43KWPFOusMNzUmxuXwMX6K4,7400
|
|
27
27
|
bullish/database/schemas.py,sha256=bU-DW49NqpBp--1VN486LUdDmLeScrI8TF69afzjoTc,1507
|
|
28
28
|
bullish/database/scripts/create_revision.py,sha256=rggIf-3koPqJNth8FIg89EOfnIM7a9QrvL8X7UJsP0g,628
|
|
29
29
|
bullish/database/scripts/stamp.py,sha256=PWgVUEBumjNUMjTnGw46qmU3p221LeN-KspnW_gFuu4,839
|
|
@@ -33,14 +33,14 @@ bullish/exceptions.py,sha256=4z_i-dD-CDz1bkGmZH9DOf1L_awlCPCgdUDPF7dhWAI,106
|
|
|
33
33
|
bullish/figures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
34
|
bullish/figures/figures.py,sha256=SWTTiEoVyWMZeIIxg0ERi23v7s4tySB5BLKyPu12jC4,4193
|
|
35
35
|
bullish/interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
|
-
bullish/interface/interface.py,sha256
|
|
36
|
+
bullish/interface/interface.py,sha256=6HXSK-N-vOuOGVserizknP4CeUGbUhB8P642oZmgpk0,3252
|
|
37
37
|
bullish/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
38
|
bullish/jobs/app.py,sha256=5MJ5KXUo7JSNAvOPgkpIMasD11VTrjQvGzM7vmCY65E,77
|
|
39
39
|
bullish/jobs/models.py,sha256=ndrGTMP08S57yGLGEG9TQt8Uw2slc4HvbG-TZtEEuN0,744
|
|
40
40
|
bullish/jobs/tasks.py,sha256=V_b0c8_GQC0-KIxaHDlLFhtkclQJOsck0gXaW6OlC_w,3055
|
|
41
41
|
bullish/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
42
|
bullish/utils/checks.py,sha256=Va10_xDVVnxYkOD2hafvyQ-TFV8FQpOkr4huJ7XgpDM,2188
|
|
43
|
-
bullishpy-0.
|
|
44
|
-
bullishpy-0.
|
|
45
|
-
bullishpy-0.
|
|
46
|
-
bullishpy-0.
|
|
43
|
+
bullishpy-0.12.0.dist-info/METADATA,sha256=hmEQ5ZWQ8ROXE5_Vm0l3npGSM6BfuBQD1-glStH16us,784
|
|
44
|
+
bullishpy-0.12.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
45
|
+
bullishpy-0.12.0.dist-info/entry_points.txt,sha256=eaPpmL6vmSBFo0FBtwibCXGqAW4LFJ83whJzT1VjD-0,43
|
|
46
|
+
bullishpy-0.12.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|