bullishpy 0.69.0__tar.gz → 0.71.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.
Potentially problematic release.
This version of bullishpy might be problematic. Click here for more details.
- {bullishpy-0.69.0 → bullishpy-0.71.0}/PKG-INFO +5 -4
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/analysis/analysis.py +12 -2
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/analysis/functions.py +4 -4
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/analysis/indicators.py +7 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/analysis/openai.py +2 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/app/app.py +1 -1
- bullishpy-0.71.0/bullish/database/alembic/versions/65662e214031_.py +48 -0
- bullishpy-0.71.0/bullish/database/alembic/versions/660897c02c00_.py +36 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/crud.py +6 -1
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/jobs/tasks.py +14 -16
- {bullishpy-0.69.0 → bullishpy-0.71.0}/pyproject.toml +3 -3
- {bullishpy-0.69.0 → bullishpy-0.71.0}/LICENSE +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/README.md +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/__init__.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/analysis/__init__.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/analysis/backtest.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/analysis/constants.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/analysis/filter.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/analysis/industry_views.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/analysis/predefined_filters.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/app/__init__.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/cli.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/__init__.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/README +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/alembic.ini +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/env.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/script.py.mako +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/037dbd721317_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/040b15fba458_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/08ac1116e055_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/11d35a452b40_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/12889a2cbd7d_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/17e51420e7ad_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/260fcff7212e_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/49c83f9eb5ac_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/4b0a2f40b7d3_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/4ee82b171449_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/5b10ee7604c1_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/6d252e23f543_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/73564b60fe24_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/79bc71ec6f9e_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/ae444f338124_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/b36c310f49ec_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/b76079e9845f_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/bf6b86dd5463_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/c828e29e1105_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/cc28171c21a4_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/d0e58e050845_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/d663166c531d_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/ec25c8fa449f_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/ee5baabb35f8_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/fc191121f522_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/alembic/versions/ff0cc4ba40ec_.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/schemas.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/scripts/create_revision.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/scripts/stamp.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/scripts/upgrade.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/database/settings.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/exceptions.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/figures/__init__.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/figures/figures.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/interface/__init__.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/interface/interface.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/jobs/__init__.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/jobs/app.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/jobs/models.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/utils/__init__.py +0 -0
- {bullishpy-0.69.0 → bullishpy-0.71.0}/bullish/utils/checks.py +0 -0
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: bullishpy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.71.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.
|
|
11
|
+
Requires-Dist: bearishpy (>=0.29.0,<0.30.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.
|
|
15
|
+
Requires-Dist: pandas-ta (>=0.4.71b0,<0.5.0)
|
|
15
16
|
Requires-Dist: plotly (>=4.12.0,<6.0.0)
|
|
16
17
|
Requires-Dist: streamlit (>=1.45.1,<2.0.0)
|
|
17
18
|
Requires-Dist: streamlit-file-browser (>=3.2.22,<4.0.0)
|
|
@@ -499,7 +499,9 @@ class AnalysisView(BaseModel):
|
|
|
499
499
|
upside: Optional[float] = None
|
|
500
500
|
oai_high_price_target: Optional[float] = None
|
|
501
501
|
oai_low_price_target: Optional[float] = None
|
|
502
|
+
rsi: Optional[float] = None
|
|
502
503
|
oai_recommendation: Optional[str] = None
|
|
504
|
+
oai_moat: Optional[bool] = None
|
|
503
505
|
|
|
504
506
|
|
|
505
507
|
def json_loads(value: Any) -> Any:
|
|
@@ -530,6 +532,7 @@ class SubjectAnalysis(BaseModel):
|
|
|
530
532
|
] = None
|
|
531
533
|
summary: Annotated[Optional[Dict[str, Any]], BeforeValidator(json_loads)] = None
|
|
532
534
|
upside: Optional[float] = None
|
|
535
|
+
downside: Optional[float] = None
|
|
533
536
|
|
|
534
537
|
oai_high_price_target: Optional[float] = None
|
|
535
538
|
oai_low_price_target: Optional[float] = None
|
|
@@ -537,11 +540,18 @@ class SubjectAnalysis(BaseModel):
|
|
|
537
540
|
oai_recent_news: Optional[str] = None
|
|
538
541
|
oai_recommendation: Optional[str] = None
|
|
539
542
|
oai_explanation: Optional[str] = None
|
|
543
|
+
oai_moat: Optional[bool] = None
|
|
540
544
|
|
|
541
545
|
def compute_upside(self, last_price: float) -> None:
|
|
542
|
-
if self.
|
|
546
|
+
if self.oai_high_price_target is not None:
|
|
543
547
|
self.upside = (
|
|
544
|
-
(float(self.
|
|
548
|
+
(float(self.oai_high_price_target) - float(last_price))
|
|
549
|
+
* 100
|
|
550
|
+
/ float(last_price)
|
|
551
|
+
)
|
|
552
|
+
if self.oai_low_price_target is not None:
|
|
553
|
+
self.downside = (
|
|
554
|
+
(float(last_price) - float(self.oai_low_price_target))
|
|
545
555
|
* 100
|
|
546
556
|
/ float(last_price)
|
|
547
557
|
)
|
|
@@ -4,7 +4,7 @@ from typing import Optional, Callable, cast
|
|
|
4
4
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
import pandas as pd
|
|
7
|
-
import pandas_ta as ta
|
|
7
|
+
import pandas_ta as ta
|
|
8
8
|
|
|
9
9
|
from pydantic import BaseModel
|
|
10
10
|
|
|
@@ -18,7 +18,7 @@ except Exception:
|
|
|
18
18
|
def cross_simple(
|
|
19
19
|
series_a: pd.Series, series_b: pd.Series, above: bool = True
|
|
20
20
|
) -> pd.Series:
|
|
21
|
-
crossing = ta.cross(
|
|
21
|
+
crossing = ta.cross(x=series_a, y=series_b, above=above) # type: ignore
|
|
22
22
|
return crossing # type: ignore
|
|
23
23
|
|
|
24
24
|
|
|
@@ -466,6 +466,6 @@ def bollinger_bands(
|
|
|
466
466
|
data: pd.DataFrame, window: int = 20, std_dev: float = 2.0
|
|
467
467
|
) -> pd.DataFrame:
|
|
468
468
|
bbands = ta.bbands(
|
|
469
|
-
data.close, timeperiod=window, nbdevup=std_dev, nbdevdn=std_dev, matype=0
|
|
469
|
+
data.close, timeperiod=window, nbdevup=std_dev, nbdevdn=std_dev, matype=0 # type: ignore
|
|
470
470
|
)
|
|
471
|
-
return bbands
|
|
471
|
+
return bbands
|
|
@@ -297,6 +297,13 @@ def indicators_factory() -> List[Indicator]:
|
|
|
297
297
|
type=Optional[date],
|
|
298
298
|
function=lambda d: (d.RSI < 60) & (d.RSI > 30),
|
|
299
299
|
),
|
|
300
|
+
Signal(
|
|
301
|
+
name="RSI",
|
|
302
|
+
description="RSI value",
|
|
303
|
+
type_info="Overbought",
|
|
304
|
+
type=Optional[float],
|
|
305
|
+
function=lambda d: d.RSI,
|
|
306
|
+
),
|
|
300
307
|
],
|
|
301
308
|
),
|
|
302
309
|
Indicator(
|
|
@@ -31,6 +31,7 @@ fences, no extra text:
|
|
|
31
31
|
"recommendation": str, // One of: "Strong Buy", "Buy", "Hold", "Sell", "Strong Sell"
|
|
32
32
|
"explanation": str // Concise explanation for the recommendation above, covering key pros/cons
|
|
33
33
|
for investors
|
|
34
|
+
"moat": bool // Give as a boolean true or false if the company has a strong economic moat
|
|
34
35
|
}}
|
|
35
36
|
|
|
36
37
|
Formatting rules:
|
|
@@ -49,6 +50,7 @@ class OpenAINews(BaseModel):
|
|
|
49
50
|
recent_news: Optional[str] = None
|
|
50
51
|
recommendation: Optional[str] = None
|
|
51
52
|
explanation: Optional[str] = None
|
|
53
|
+
moat: Optional[bool] = None
|
|
52
54
|
|
|
53
55
|
def valid(self) -> bool:
|
|
54
56
|
return bool(
|
|
@@ -123,7 +123,7 @@ def dialog_pick_database() -> None:
|
|
|
123
123
|
f"The database {db_path} has not the necessary data to run this application. "
|
|
124
124
|
"A backround job will be started to update the data."
|
|
125
125
|
)
|
|
126
|
-
analysis(db_path)
|
|
126
|
+
analysis(db_path, "Update analysis")
|
|
127
127
|
st.rerun()
|
|
128
128
|
if event is None:
|
|
129
129
|
st.stop()
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""
|
|
2
|
+
|
|
3
|
+
Revision ID: 65662e214031
|
|
4
|
+
Revises: 660897c02c00
|
|
5
|
+
Create Date: 2025-08-20 17:30:47.973725
|
|
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 = "65662e214031"
|
|
17
|
+
down_revision: Union[str, None] = "660897c02c00"
|
|
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
|
+
|
|
25
|
+
with op.batch_alter_table("analysis", schema=None) as batch_op:
|
|
26
|
+
batch_op.add_column(sa.Column("downside", sa.Float(), nullable=True))
|
|
27
|
+
batch_op.add_column(sa.Column("oai_moat", sa.Boolean(), nullable=True))
|
|
28
|
+
batch_op.create_index("ix_analysis_downside", ["downside"], unique=False)
|
|
29
|
+
batch_op.create_index("ix_analysis_oai_moat", ["oai_moat"], unique=False)
|
|
30
|
+
|
|
31
|
+
with op.batch_alter_table("openai", schema=None) as batch_op:
|
|
32
|
+
batch_op.add_column(sa.Column("moat", sa.Boolean(), nullable=True))
|
|
33
|
+
|
|
34
|
+
# ### end Alembic commands ###
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def downgrade() -> None:
|
|
38
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
39
|
+
with op.batch_alter_table("openai", schema=None) as batch_op:
|
|
40
|
+
batch_op.drop_column("moat")
|
|
41
|
+
|
|
42
|
+
with op.batch_alter_table("analysis", schema=None) as batch_op:
|
|
43
|
+
batch_op.drop_index("ix_analysis_oai_moat")
|
|
44
|
+
batch_op.drop_index("ix_analysis_downside")
|
|
45
|
+
batch_op.drop_column("oai_moat")
|
|
46
|
+
batch_op.drop_column("downside")
|
|
47
|
+
|
|
48
|
+
# ### end Alembic commands ###
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""
|
|
2
|
+
|
|
3
|
+
Revision ID: 660897c02c00
|
|
4
|
+
Revises: c828e29e1105
|
|
5
|
+
Create Date: 2025-08-20 17:19:05.423318
|
|
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 = "660897c02c00"
|
|
17
|
+
down_revision: Union[str, None] = "c828e29e1105"
|
|
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
|
+
|
|
25
|
+
with op.batch_alter_table("analysis", schema=None) as batch_op:
|
|
26
|
+
batch_op.add_column(sa.Column("rsi", sa.Float(), nullable=True))
|
|
27
|
+
batch_op.create_index("ix_analysis_rsi", ["rsi"], unique=False)
|
|
28
|
+
|
|
29
|
+
# ### end Alembic commands ###
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def downgrade() -> None:
|
|
33
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
34
|
+
with op.batch_alter_table("analysis", schema=None) as batch_op:
|
|
35
|
+
batch_op.drop_index("ix_analysis_rsi")
|
|
36
|
+
batch_op.drop_column("rsi")
|
|
@@ -74,7 +74,11 @@ class BullishDb(BearishDb, BullishDbBase): # type: ignore
|
|
|
74
74
|
logger.info(
|
|
75
75
|
"Running tickermood upgrade to create the subject table in the database."
|
|
76
76
|
)
|
|
77
|
-
|
|
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}")
|
|
78
82
|
return engine
|
|
79
83
|
|
|
80
84
|
def model_post_init(self, __context: Any) -> None:
|
|
@@ -389,6 +393,7 @@ class BullishDb(BearishDb, BullishDbBase): # type: ignore
|
|
|
389
393
|
"oai_explanation": row_dict_oai.get("explanation"),
|
|
390
394
|
"oai_high_price_target": row_dict_oai.get("high_price_target"),
|
|
391
395
|
"oai_low_price_target": row_dict_oai.get("low_price_target"),
|
|
396
|
+
"oai_moat": row_dict_oai.get("moat"),
|
|
392
397
|
}
|
|
393
398
|
|
|
394
399
|
return SubjectAnalysis.model_validate(row_dict)
|
|
@@ -195,22 +195,20 @@ def news(
|
|
|
195
195
|
logger.debug(
|
|
196
196
|
f"extracting news for {symbol} subject: {subject.model_dump()}"
|
|
197
197
|
)
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
task=task,
|
|
213
|
-
)
|
|
198
|
+
try:
|
|
199
|
+
bullish_db.update_analysis(
|
|
200
|
+
symbol,
|
|
201
|
+
subject.model_dump(
|
|
202
|
+
exclude_none=True,
|
|
203
|
+
exclude_unset=True,
|
|
204
|
+
exclude_defaults=True,
|
|
205
|
+
exclude={"symbol"},
|
|
206
|
+
),
|
|
207
|
+
)
|
|
208
|
+
except Exception as e:
|
|
209
|
+
logger.error(f"failed to extract news for {symbol}: {e}")
|
|
210
|
+
print(f"failed to extract news for {symbol}: {e}")
|
|
211
|
+
continue
|
|
214
212
|
|
|
215
213
|
|
|
216
214
|
@huey.periodic_task(crontab(minute="0", hour="8"), context=True) # type: ignore
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "bullishpy"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.71.0"
|
|
4
4
|
description = ""
|
|
5
5
|
authors = ["aan <andoludovic.andriamamonjy@gmail.com>"]
|
|
6
6
|
readme = "README.md"
|
|
7
7
|
packages = [{ include = "bullish" }]
|
|
8
8
|
[tool.poetry.dependencies]
|
|
9
9
|
python = ">=3.12,<3.13"
|
|
10
|
-
bearishpy = "^0.
|
|
10
|
+
bearishpy = "^0.29.0"
|
|
11
11
|
tickermood = "^0.29.0"
|
|
12
12
|
streamlit = "^1.45.1"
|
|
13
13
|
streamlit-pydantic = "^v0.6.1-rc.3"
|
|
14
14
|
streamlit-file-browser = "^3.2.22"
|
|
15
15
|
huey = "^2.5.3"
|
|
16
|
-
pandas-ta = "^0.
|
|
16
|
+
pandas-ta = "^0.4.71b0"
|
|
17
17
|
plotly = ">=4.12.0,<6.0.0"
|
|
18
18
|
ta-lib = "^0.6.4"
|
|
19
19
|
click = ">=7.0,<=8.1"
|
|
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
|
|
File without changes
|
|
File without changes
|