bullishpy 0.55.0__py3-none-any.whl → 0.75.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.

@@ -0,0 +1,43 @@
1
+ """
2
+
3
+ Revision ID: cc28171c21a4
4
+ Revises: 260fcff7212e
5
+ Create Date: 2025-08-15 17:04:59.467407
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 = "cc28171c21a4"
17
+ down_revision: Union[str, None] = "260fcff7212e"
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("adx_14", sa.Date(), nullable=True))
26
+ batch_op.add_column(sa.Column("adx_14_overbought", sa.Date(), nullable=True))
27
+ batch_op.create_index("ix_analysis_adx_14", ["adx_14"], unique=False)
28
+ batch_op.create_index(
29
+ "ix_analysis_adx_14_overbought", ["adx_14_overbought"], unique=False
30
+ )
31
+
32
+ # ### end Alembic commands ###
33
+
34
+
35
+ def downgrade() -> None:
36
+ # ### commands auto generated by Alembic - please adjust! ###
37
+ with op.batch_alter_table("analysis", schema=None) as batch_op:
38
+ batch_op.drop_index("ix_analysis_adx_14_overbought")
39
+ batch_op.drop_index("ix_analysis_adx_14")
40
+ batch_op.drop_column("adx_14_overbought")
41
+ batch_op.drop_column("adx_14")
42
+
43
+ # ### end Alembic commands ###
bullish/database/crud.py CHANGED
@@ -3,7 +3,7 @@ import logging
3
3
  from datetime import date
4
4
  from functools import cached_property
5
5
  from pathlib import Path
6
- from typing import TYPE_CHECKING, Any, List, Optional
6
+ from typing import TYPE_CHECKING, Any, List, Optional, Dict
7
7
 
8
8
  import pandas as pd
9
9
  from bearish.database.crud import BearishDb # type: ignore
@@ -22,6 +22,7 @@ from bullish.analysis.constants import Industry, IndustryGroup, Sector, Country
22
22
  from bullish.analysis.filter import FilteredResults
23
23
  from bullish.analysis.indicators import SignalSeries
24
24
  from bullish.analysis.industry_views import Type, IndustryView
25
+
25
26
  from bullish.database.schemas import (
26
27
  AnalysisORM,
27
28
  JobTrackerORM,
@@ -29,6 +30,7 @@ from bullish.database.schemas import (
29
30
  IndustryViewORM,
30
31
  SignalSeriesORM,
31
32
  BacktestResultORM,
33
+ OpenAINewsORM,
32
34
  )
33
35
  from bullish.database.scripts.upgrade import upgrade
34
36
  from bullish.exceptions import DatabaseFileNotFoundError
@@ -38,6 +40,7 @@ from tickermood.database.scripts.upgrade import upgrade as tickermood_upgrade #
38
40
 
39
41
  if TYPE_CHECKING:
40
42
  from bullish.analysis.backtest import BacktestResult, BacktestResultQuery
43
+ from bullish.analysis.openai import OpenAINews
41
44
 
42
45
  logger = logging.getLogger(__name__)
43
46
 
@@ -71,7 +74,11 @@ class BullishDb(BearishDb, BullishDbBase): # type: ignore
71
74
  logger.info(
72
75
  "Running tickermood upgrade to create the subject table in the database."
73
76
  )
74
- tickermood_upgrade(database_url=database_url, no_migration=True)
77
+ try:
78
+ tickermood_upgrade(database_url=database_url, no_migration=True)
79
+ except Exception as e:
80
+ logger.error(f"failed to update database: {e}")
81
+ print(f"failed to update database: {e}")
75
82
  return engine
76
83
 
77
84
  def model_post_init(self, __context: Any) -> None:
@@ -358,11 +365,53 @@ class BullishDb(BearishDb, BullishDbBase): # type: ignore
358
365
  LIMIT 1
359
366
  """
360
367
  )
368
+ sql_oai = text(
369
+ """
370
+ SELECT *
371
+ FROM openai
372
+ WHERE symbol = :symbol
373
+ ORDER BY news_date DESC
374
+ LIMIT 1
375
+ """
376
+ )
361
377
 
362
378
  with Session(self._engine) as session:
363
379
  row = session.execute(sql, {"symbol": symbol}).mappings().one_or_none()
380
+ row_oai = (
381
+ session.execute(sql_oai, {"symbol": symbol}).mappings().one_or_none()
382
+ )
383
+ row_dict = {}
364
384
  if row:
365
385
  row_dict = dict(row)
366
386
  row_dict = row_dict | {"news_date": row_dict["date"]}
367
- return SubjectAnalysis.model_validate(row_dict)
368
- return None
387
+ if row_oai:
388
+ row_dict_oai = dict(row_oai)
389
+ row_dict = row_dict | {
390
+ "oai_news_date": row_dict_oai.get("news_date"),
391
+ "oai_recent_news": row_dict_oai.get("recent_news"),
392
+ "oai_recommendation": row_dict_oai.get("recommendation"),
393
+ "oai_explanation": row_dict_oai.get("explanation"),
394
+ "oai_high_price_target": row_dict_oai.get("high_price_target"),
395
+ "oai_low_price_target": row_dict_oai.get("low_price_target"),
396
+ "oai_moat": row_dict_oai.get("moat"),
397
+ }
398
+
399
+ return SubjectAnalysis.model_validate(row_dict)
400
+
401
+ def write_many_openai_news(self, openai_news: List["OpenAINews"]) -> None:
402
+ with Session(self._engine) as session:
403
+ stmt = (
404
+ insert(OpenAINewsORM)
405
+ .prefix_with("OR REPLACE")
406
+ .values([a.model_dump() for a in openai_news])
407
+ )
408
+ session.exec(stmt) # type: ignore
409
+ session.commit()
410
+
411
+ def update_analysis(self, symbol: str, fields: Dict[str, Any]) -> None:
412
+ with Session(self._engine) as session:
413
+ stmt = (
414
+ update(AnalysisORM).where(AnalysisORM.symbol == symbol).values(**fields) # type: ignore
415
+ )
416
+ session.exec(stmt) # type: ignore
417
+ session.commit()
@@ -1,3 +1,4 @@
1
+ from datetime import date
1
2
  from typing import Dict, Any, List, Optional
2
3
 
3
4
  from sqlmodel import Field, SQLModel
@@ -7,6 +8,7 @@ from bullish.analysis.backtest import BacktestResult
7
8
  from bullish.analysis.filter import FilteredResults
8
9
  from bullish.analysis.indicators import SignalSeries
9
10
  from bullish.analysis.industry_views import IndustryView
11
+ from bullish.analysis.openai import OpenAINews
10
12
 
11
13
  from bullish.jobs.models import JobTracker
12
14
  from sqlalchemy import Index
@@ -22,6 +24,13 @@ dynamic_indexes = tuple(
22
24
  )
23
25
 
24
26
 
27
+ class OpenAINewsORM(SQLModel, OpenAINews, table=True):
28
+ __tablename__ = "openai"
29
+ __table_args__ = {"extend_existing": True} # noqa:RUF012
30
+ symbol: str = Field(primary_key=True)
31
+ news_date: date = Field(primary_key=True)
32
+
33
+
25
34
  class AnalysisORM(BaseTable, Analysis, table=True):
26
35
  __tablename__ = "analysis"
27
36
  __table_args__ = {"extend_existing": True} # noqa:RUF012
@@ -5,7 +5,10 @@ import pandas as pd
5
5
  import plotly.graph_objects as go
6
6
  from plotly.subplots import make_subplots
7
7
 
8
- from bullish.analysis.functions import add_indicators
8
+ from bullish.analysis.functions import (
9
+ add_indicators,
10
+ support_resistance,
11
+ )
9
12
  from datetime import date
10
13
 
11
14
 
@@ -17,6 +20,8 @@ def plot(
17
20
  industry_data: Optional[pd.DataFrame] = None,
18
21
  ) -> go.Figure:
19
22
  data = add_indicators(data)
23
+ supports = support_resistance(data)
24
+
20
25
  fig = make_subplots(
21
26
  rows=7,
22
27
  cols=1,
@@ -36,8 +41,8 @@ def plot(
36
41
  f"RSI ({symbol} [{name}])",
37
42
  f"MACD ({symbol} [{name}])",
38
43
  f"ADX ({symbol} [{name}])",
39
- f"OBV ({symbol} [{name}])",
40
- f"Industry ({symbol} [{name}])",
44
+ f"ATR ({symbol} [{name}])",
45
+ f"ADOSC ({symbol} [{name}])",
41
46
  ),
42
47
  )
43
48
  # Row 1: Candlestick + SMAs
@@ -114,28 +119,15 @@ def plot(
114
119
  col=1,
115
120
  )
116
121
  fig.add_trace(
117
- go.Scatter(x=data.index, y=data.OBV, name="OBV", mode="lines"),
122
+ go.Scatter(x=data.index, y=data.ATR, name="ATR", mode="lines"),
118
123
  row=6,
119
124
  col=1,
120
125
  )
121
126
  fig.add_trace(
122
127
  go.Scatter(x=data.index, y=data.ADOSC, name="ADOSC", mode="lines"),
123
- row=6,
128
+ row=7,
124
129
  col=1,
125
130
  )
126
- if industry_data is not None and not industry_data.empty:
127
- for c in industry_data.columns:
128
- fig.add_trace(
129
- go.Scatter(
130
- x=industry_data.index,
131
- y=industry_data[c],
132
- name=c,
133
- mode="lines",
134
- opacity=0.5 if c != "symbol" else 1.0,
135
- ),
136
- row=7,
137
- col=1,
138
- )
139
131
 
140
132
  if dates is not None and dates:
141
133
  for date in dates:
@@ -166,5 +158,23 @@ def plot(
166
158
  fig.add_hline(y=70, line_dash="dash", line_color="red", row=3, col=1)
167
159
  fig.add_hline(y=30, line_dash="dash", line_color="green", row=3, col=1)
168
160
  fig.add_hline(y=25, line_dash="dash", line_color="red", row=5, col=1)
161
+ fig.add_hline(
162
+ y=supports.support.value,
163
+ line_dash="dash",
164
+ line_color="rgba(26, 188, 156, 1)", # teal, fully opaque
165
+ annotation_text=f"Support ({supports.support.value:.2f})",
166
+ line_width=0.75,
167
+ row=1,
168
+ col=1,
169
+ )
170
+ fig.add_hline(
171
+ y=supports.resistance.value,
172
+ line_dash="dash",
173
+ line_color="rgba(230, 126, 34, 1)", # orange, fully opaque
174
+ annotation_text=f"Resistance ({supports.resistance.value:.2f})",
175
+ line_width=0.75,
176
+ row=1,
177
+ col=1,
178
+ )
169
179
 
170
180
  return fig
@@ -1,7 +1,7 @@
1
1
  import abc
2
2
  import logging
3
3
  from datetime import date
4
- from typing import List, Optional
4
+ from typing import List, Optional, Dict, Any
5
5
 
6
6
  import pandas as pd
7
7
  from bearish.interface.interface import BearishDbBase # type: ignore
@@ -15,6 +15,7 @@ from bullish.analysis.constants import Industry, Sector, IndustryGroup, Country
15
15
  from bullish.analysis.filter import FilterQuery, FilteredResults
16
16
  from bullish.analysis.indicators import SignalSeries
17
17
  from bullish.analysis.industry_views import Type, IndustryView
18
+ from bullish.analysis.openai import OpenAINews
18
19
  from bullish.jobs.models import JobTracker, JobTrackerStatus, add_icons
19
20
 
20
21
  logger = logging.getLogger(__name__)
@@ -155,3 +156,8 @@ class BullishDbBase(BearishDbBase): # type: ignore
155
156
 
156
157
  @abc.abstractmethod
157
158
  def read_subject(self, symbol: str) -> Optional[SubjectAnalysis]: ...
159
+ @abc.abstractmethod
160
+ def write_many_openai_news(self, openai_news: List[OpenAINews]) -> None: ...
161
+
162
+ @abc.abstractmethod
163
+ def update_analysis(self, symbol: str, fields: Dict[str, Any]) -> None: ...
bullish/jobs/tasks.py CHANGED
@@ -4,6 +4,7 @@ from typing import Optional, Any, Callable, List
4
4
 
5
5
  import pandas as pd
6
6
  from bearish.main import Bearish # type: ignore
7
+ from bearish.models.sec.sec import Secs # type: ignore
7
8
  from tickermood.main import get_news # type: ignore
8
9
  from tickermood.types import DatabaseConfig # type: ignore
9
10
 
@@ -15,6 +16,7 @@ from .models import JobTrackerStatus, JobTracker, JobType
15
16
  from ..analysis.analysis import run_analysis, run_signal_series_analysis
16
17
  from ..analysis.backtest import run_many_tests, BackTestConfig
17
18
  from ..analysis.industry_views import compute_industry_view
19
+ from ..analysis.openai import get_open_ai_news
18
20
  from ..analysis.predefined_filters import predefined_filters, load_custom_filters
19
21
  from ..database.crud import BullishDb
20
22
  from bullish.analysis.filter import FilterUpdate
@@ -83,6 +85,9 @@ def _base_update(
83
85
  series_length=update_query.window_size,
84
86
  delay=update_query.data_age_in_days,
85
87
  )
88
+ bearish.get_prices_index(series_length=update_query.window_size)
89
+ Secs.upload(bearish._bearish_db)
90
+ Secs.update_values(bearish._secs_db)
86
91
  if update_query.update_financials:
87
92
  bearish.update_financials()
88
93
  bullish_db = BullishDb(database_path=database_path)
@@ -125,6 +130,21 @@ def cron_update(
125
130
  )
126
131
 
127
132
 
133
+ @huey.periodic_task(crontab(day_of_week=0, hour=9, minute=0), context=True) # type: ignore
134
+ def cron_financial_update(
135
+ task: Optional[Task] = None,
136
+ ) -> None:
137
+ database = DataBaseSingleTon()
138
+ if database.valid():
139
+ job_tracker(_base_update)(
140
+ database.path,
141
+ "Update data",
142
+ [],
143
+ FilterUpdate(update_financials=True),
144
+ task=task,
145
+ )
146
+
147
+
128
148
  @huey.task(context=True) # type: ignore
129
149
  @job_tracker
130
150
  def analysis(
@@ -171,16 +191,31 @@ def news(
171
191
  headless: bool = True,
172
192
  task: Optional[Task] = None,
173
193
  ) -> None:
174
- base_news(
175
- database_path=database_path,
176
- job_type=job_type,
177
- symbols=symbols,
178
- headless=headless,
179
- task=task,
180
- )
181
-
182
-
183
- @huey.periodic_task(crontab(minute="0", hour="3"), context=True) # type: ignore
194
+ bullish_db = BullishDb(database_path=database_path)
195
+ if get_open_ai_news(bullish_db, symbols):
196
+ for symbol in symbols:
197
+ subject = bullish_db.read_subject(symbol)
198
+ if subject:
199
+ logger.debug(
200
+ f"extracting news for {symbol} subject: {subject.model_dump()}"
201
+ )
202
+ try:
203
+ bullish_db.update_analysis(
204
+ symbol,
205
+ subject.model_dump(
206
+ exclude_none=True,
207
+ exclude_unset=True,
208
+ exclude_defaults=True,
209
+ exclude={"symbol"},
210
+ ),
211
+ )
212
+ except Exception as e:
213
+ logger.error(f"failed to extract news for {symbol}: {e}")
214
+ print(f"failed to extract news for {symbol}: {e}")
215
+ continue
216
+
217
+
218
+ @huey.periodic_task(crontab(minute="0", hour="8"), context=True) # type: ignore
184
219
  def cron_news(
185
220
  task: Optional[Task] = None,
186
221
  ) -> None:
@@ -1,23 +1,25 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: bullishpy
3
- Version: 0.55.0
3
+ Version: 0.75.0
4
4
  Summary:
5
+ License-File: LICENSE
5
6
  Author: aan
6
7
  Author-email: andoludovic.andriamamonjy@gmail.com
7
8
  Requires-Python: >=3.12,<3.13
8
9
  Classifier: Programming Language :: Python :: 3
9
10
  Classifier: Programming Language :: Python :: 3.12
10
- Requires-Dist: bearishpy (>=0.26.0,<0.27.0)
11
+ Requires-Dist: bearishpy (>=0.35.0,<0.36.0)
11
12
  Requires-Dist: click (>=7.0,<=8.1)
12
13
  Requires-Dist: huey (>=2.5.3,<3.0.0)
13
14
  Requires-Dist: joblib (>=1.5.1,<2.0.0)
14
- Requires-Dist: pandas-ta (>=0.3.14b0,<0.4.0)
15
+ Requires-Dist: mysec (>=0.3.0,<0.4.0)
16
+ Requires-Dist: pandas-ta (>=0.4.71b0,<0.5.0)
15
17
  Requires-Dist: plotly (>=4.12.0,<6.0.0)
16
18
  Requires-Dist: streamlit (>=1.45.1,<2.0.0)
17
19
  Requires-Dist: streamlit-file-browser (>=3.2.22,<4.0.0)
18
20
  Requires-Dist: streamlit-pydantic (>=v0.6.1-rc.3,<0.7.0)
19
21
  Requires-Dist: ta-lib (>=0.6.4,<0.7.0)
20
- Requires-Dist: tickermood (>=0.14.0,<0.15.0)
22
+ Requires-Dist: tickermood (>=0.29.0,<0.30.0)
21
23
  Requires-Dist: vectorbt (>=0.28.0,<0.29.0)
22
24
  Description-Content-Type: text/markdown
23
25
 
@@ -51,7 +53,7 @@ See the [TA-Lib installation guide](https://ta-lib.org/) for instructions.
51
53
 
52
54
  ## Installation
53
55
  ```bash
54
- pip install bullish
56
+ pip install bullishpy
55
57
  ```
56
58
 
57
59
  ---
@@ -1,15 +1,16 @@
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=Bcupt-qROPddj1hGTNAY8vhu0pnFqNvXoDtUNhRXErY,24217
3
+ bullish/analysis/analysis.py,sha256=3lZSLpTe4lFBGNrCpXmYBZhwD7o0rXSbQEkLpxJLylA,25130
4
4
  bullish/analysis/backtest.py,sha256=x91ek5kOzJHvYq0TmJh1Q8wBDDduIaieE0zDaoZFXew,14325
5
- bullish/analysis/constants.py,sha256=X3oCyYNA6B-jsZSYJLeGQ94S453Z7jIVNPmv3lMPp8Q,9922
6
- bullish/analysis/filter.py,sha256=LKmsO3ei7Eo_SJsEVbZqETyIdOpW55xVheO6_GNoA0s,9286
7
- bullish/analysis/functions.py,sha256=CuMgOjpQeg4KsDMUBdHRlxL1dRlos16KRyLhQe8PYUQ,14819
8
- bullish/analysis/indicators.py,sha256=f5FReOeM1qgs_v3yEFp2ebPYqIQNib_4tftG0WDkhRQ,27648
5
+ bullish/analysis/constants.py,sha256=j3vQwjGhY-4dEEV-TkeKMDUTo2GM7M97Hcpi19LDcFQ,11458
6
+ bullish/analysis/filter.py,sha256=VvQALnYNyYylXkorYR3oGhsF4L_sAUSE7-aop4Trp9o,9326
7
+ bullish/analysis/functions.py,sha256=jw1Tc-YtoyobYhC6AWJH-xXgaczwDZMTfQIES6Y_8qM,15780
8
+ bullish/analysis/indicators.py,sha256=CcDu8mu1jOOS5-3gNHYA9qDA3Ua-6PGUyoio2bDIe48,28435
9
9
  bullish/analysis/industry_views.py,sha256=-B4CCAYz2arGQtWTXLLMpox0loO_MGdVQd2ycCRMOQQ,6799
10
- bullish/analysis/predefined_filters.py,sha256=LD_68Gi84gGifT4I4Vgz6VN8y8o1hFBKyQBbpE1i9Bo,12340
10
+ bullish/analysis/openai.py,sha256=Fw7A8lFMgSEQFA48Q9GjVpEC3oiBgSHUFi7YO5rzhAc,3444
11
+ bullish/analysis/predefined_filters.py,sha256=E65qrTSaDFuUxoaeZ8D72K5AobumobpQdpcTIF308D4,14053
11
12
  bullish/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- bullish/app/app.py,sha256=oF0ew2TtWSZ9iIsBK7H0Dy-FvOCjzSA4MdEsBzeRI9g,16630
13
+ bullish/app/app.py,sha256=FLWwhjGwMVXYfA9EI5RUeQRQGf9Qu7up0ypJgS4FTFE,17367
13
14
  bullish/cli.py,sha256=yYqiEQAvOIQ-pTn77RPuE449gwaEGBeQwNHHAJ5yQDM,2739
14
15
  bullish/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
16
  bullish/database/alembic/README,sha256=heMzebYwlGhnE8_4CWJ4LS74WoEZjBy-S-mIJRxAEKI,39
@@ -27,37 +28,42 @@ bullish/database/alembic/versions/49c83f9eb5ac_.py,sha256=kCBItp7KmqpJ03roy5ikQj
27
28
  bullish/database/alembic/versions/4b0a2f40b7d3_.py,sha256=G0K7w7pOPYjPZkXTB8LWhxoxuWBPcPwOfnubTBtdeEY,1827
28
29
  bullish/database/alembic/versions/4ee82b171449_.py,sha256=QtPy5VyZPyZxS7MVkk_wGi3C44PVDoHyJ-9m9fWdqqc,1047
29
30
  bullish/database/alembic/versions/5b10ee7604c1_.py,sha256=YlqaagPasR3RKASv7acME1jPS8p26VoTE2BvpOwdCpY,1463
31
+ bullish/database/alembic/versions/65662e214031_.py,sha256=Yq3lOW6liYTYiBaPRcFqVjn3k5z1mWIUXT17bv9ZroY,1596
32
+ bullish/database/alembic/versions/660897c02c00_.py,sha256=Sc_4uJAGheebijw3WzFNHclcWz0YF8vaZKEmVBwglDc,1033
30
33
  bullish/database/alembic/versions/6d252e23f543_.py,sha256=izF-ejdXk733INkAokGqjA2U_M0_c1f_ruihZ-cgP7s,1525
31
34
  bullish/database/alembic/versions/73564b60fe24_.py,sha256=MTlDRDNHj3E9gK7IMeAzv2UxxxYtWiu3gI_9xTLE-wg,1008
32
35
  bullish/database/alembic/versions/79bc71ec6f9e_.py,sha256=4nShut2NEd1F3piSckIIBtke0GEsFAxYw5TZl5YYRzc,1140
33
36
  bullish/database/alembic/versions/ae444f338124_.py,sha256=u8RphcniLCQce-HvN666QgCJpLsv6A91-a4R-Nif4bU,3672
37
+ bullish/database/alembic/versions/b36c310f49ec_.py,sha256=L0B3wyo9i0R14_H5fcDAxAm_5P1zIFsHUY888Do-pbI,1379
34
38
  bullish/database/alembic/versions/b76079e9845f_.py,sha256=W8eeTABjI9tT1dp3hlK7g7tiKqDhmA8AoUX9Sw-ykLI,1165
35
39
  bullish/database/alembic/versions/bf6b86dd5463_.py,sha256=fKB8knCprGmiL6AEyFdhybVmB7QX_W4MPFF9sPzUrSM,1094
40
+ bullish/database/alembic/versions/c828e29e1105_.py,sha256=rO9qwNay8HohSVHIJgYq7VWhtgn-jpF10h98WCu-wjU,3052
41
+ bullish/database/alembic/versions/cc28171c21a4_.py,sha256=ZsHFzqo6cfTXDodxaXRzkoKl0zK2TR15nD4SJeDlRi0,1401
36
42
  bullish/database/alembic/versions/d0e58e050845_.py,sha256=x_LS3J27FNyy_WD99uvZzNehly-jpgn9abOYN-VjjZc,1164
37
43
  bullish/database/alembic/versions/d663166c531d_.py,sha256=U92l6QXqPniAYrPeu2Bt77ReDbXveLj4aGXtgd806JY,1915
38
44
  bullish/database/alembic/versions/ec25c8fa449f_.py,sha256=8Yts74KEjK4jg20zIo90_0atw-sOBuE3hgCKl-rfS5E,2271
39
45
  bullish/database/alembic/versions/ee5baabb35f8_.py,sha256=nBMEY-_C8AsSXVPyaDdUkwrFFo2gxShzJhmrjejDwtc,1632
40
46
  bullish/database/alembic/versions/fc191121f522_.py,sha256=0sstF6TpAJ09-Mt-Vek9SdSWksvi4C58a5D92rBtuY8,1894
41
47
  bullish/database/alembic/versions/ff0cc4ba40ec_.py,sha256=74lxga54ig_LoNZYK9toJL9iRwGbNRezh1zvO1YI40U,2719
42
- bullish/database/crud.py,sha256=69dq-vvhPQI3aopGIwaBSowBW37EGUnN0f7olVbOmEM,14180
43
- bullish/database/schemas.py,sha256=fQ4RZeOjlFoIor7rjwpisbHRNDd7-zbyDdzNKaiNGQQ,3637
48
+ bullish/database/crud.py,sha256=-pncRg_YA5y2wE2HELJHiGbeTzmaGF7LjMC8be10qwA,16123
49
+ bullish/database/schemas.py,sha256=HudFJ9lsIkVaEYjQUWammrsDnYSmEe4hOCbim3dN_4A,3946
44
50
  bullish/database/scripts/create_revision.py,sha256=rggIf-3koPqJNth8FIg89EOfnIM7a9QrvL8X7UJsP0g,628
45
51
  bullish/database/scripts/stamp.py,sha256=PWgVUEBumjNUMjTnGw46qmU3p221LeN-KspnW_gFuu4,839
46
52
  bullish/database/scripts/upgrade.py,sha256=-Gz7aFNPEt9y9e1kltqXE76-j_8QeNtet_VlwY5AWjo,806
47
53
  bullish/database/settings.py,sha256=nMudufmF7iC_62_PHrGSMjlqDLN2I0qTbtz9JKZHSko,164
48
54
  bullish/exceptions.py,sha256=4z_i-dD-CDz1bkGmZH9DOf1L_awlCPCgdUDPF7dhWAI,106
49
55
  bullish/figures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
- bullish/figures/figures.py,sha256=EpJQOiSqSp7cHvZoGlZrF6UVpyv-fFyDApAfskqdUkU,4562
56
+ bullish/figures/figures.py,sha256=aeMAZGr8HkcF6CIf8ed4cnxJ1YkOY2-euP5egwm0ELk,4750
51
57
  bullish/interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
- bullish/interface/interface.py,sha256=R2qVEMyBl9mBlPUO40zXp4vhfLKH7pgl_u2BmAVlD4w,5250
58
+ bullish/interface/interface.py,sha256=6uZAY19WNtDRKdOitqzqMEo6JTep2M3HC8iFUKYntHA,5518
53
59
  bullish/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
60
  bullish/jobs/app.py,sha256=5MJ5KXUo7JSNAvOPgkpIMasD11VTrjQvGzM7vmCY65E,77
55
61
  bullish/jobs/models.py,sha256=rBXxtGFBpgZprrxq5_X2Df-bh8BLYEfw-VLMRucrqa8,784
56
- bullish/jobs/tasks.py,sha256=vmglWAADUUkhc_2ArzgAGdjtWotkYymvK6LQt08vGo4,6096
62
+ bullish/jobs/tasks.py,sha256=PBi5kzXgX800pmBtwypHJoKIW0V3vYIPf4EDh-FJ6os,7563
57
63
  bullish/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
64
  bullish/utils/checks.py,sha256=g-5QXNWNe1_BwHKrc2PtvPiLraL0tqGgxnzG7u-Wkgo,2189
59
- bullishpy-0.55.0.dist-info/LICENSE,sha256=nYb7AJFegu6ndlQhbbk54MjT-GH-0x9RF6Ls-ggJ_g4,1075
60
- bullishpy-0.55.0.dist-info/METADATA,sha256=9yDejzNOweXc-j2EfqA1vLpcli2CGVDOqSNUTqtmyso,3007
61
- bullishpy-0.55.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
62
- bullishpy-0.55.0.dist-info/entry_points.txt,sha256=eaPpmL6vmSBFo0FBtwibCXGqAW4LFJ83whJzT1VjD-0,43
63
- bullishpy-0.55.0.dist-info/RECORD,,
65
+ bullishpy-0.75.0.dist-info/METADATA,sha256=1uDs1Zxem_Xo3ZsJBulRJeOEBl3WlyWT1bNDVekid7I,3069
66
+ bullishpy-0.75.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
67
+ bullishpy-0.75.0.dist-info/entry_points.txt,sha256=eaPpmL6vmSBFo0FBtwibCXGqAW4LFJ83whJzT1VjD-0,43
68
+ bullishpy-0.75.0.dist-info/licenses/LICENSE,sha256=nYb7AJFegu6ndlQhbbk54MjT-GH-0x9RF6Ls-ggJ_g4,1075
69
+ bullishpy-0.75.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.1.3
2
+ Generator: poetry-core 2.2.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any