mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-11-04 08:22:26 +00:00
Merge branch 'develop' into feature/reference-generator-package-builder
This commit is contained in:
6
.github/labeler.yml
vendored
6
.github/labeler.yml
vendored
@@ -23,4 +23,8 @@ labels:
|
||||
|
||||
- label: "excel"
|
||||
files:
|
||||
- "website/content/excel/.*"
|
||||
- "website/content/excel/.*"
|
||||
|
||||
- label: "breaking_change"
|
||||
files:
|
||||
- "openbb_platform/core/openbb_core/provider/standard_models/.*"
|
||||
|
||||
3
.github/release-drafter.yml
vendored
3
.github/release-drafter.yml
vendored
@@ -8,6 +8,9 @@ categories:
|
||||
- title: 🐛 OpenBB Platform Bug Fixes
|
||||
labels:
|
||||
- 'bug'
|
||||
- title: 🚨 OpenBB Platform Breaking Changes
|
||||
labels:
|
||||
- 'breaking_change'
|
||||
- title: 📚 OpenBB Documentation Changes
|
||||
labels:
|
||||
- 'docs'
|
||||
|
||||
@@ -51,6 +51,7 @@ def update_extension_dependencies(path: Path):
|
||||
|
||||
def bump_version(path: Path):
|
||||
"""Bump the version of the package"""
|
||||
print(f"\n> {path.parent.stem}") # noqa: T201
|
||||
subprocess.run(CMD + VERSION_BUMP_CMD, cwd=path.parent, check=True) # noqa: S603
|
||||
|
||||
|
||||
@@ -77,7 +78,9 @@ def publish(dry_run: bool = False, core: bool = False, extensions: bool = False)
|
||||
# Publish (if not dry run)
|
||||
if not dry_run:
|
||||
subprocess.run(
|
||||
CMD + PUBLISH_CMD, cwd=path.parent, check=True # noqa: S603
|
||||
CMD + PUBLISH_CMD, # noqa: S603
|
||||
cwd=path.parent,
|
||||
check=True, # noqa: S603
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error publishing {path.parent}:\n{e}") # noqa: T201
|
||||
|
||||
34
openbb_platform/README.md
vendored
34
openbb_platform/README.md
vendored
@@ -4,9 +4,9 @@
|
||||
[](https://github.com/OpenBB-finance/OpenBBTerminal)
|
||||
|
||||
| OpenBB is committed to build the future of investment research by focusing on an open source infrastructure accessible to everyone, everywhere. |
|
||||
|:--:|
|
||||
|  |
|
||||
| Check our website at [openbb.co](www.openbb.co) |
|
||||
| :---------------------------------------------------------------------------------------------------------------------------------------------: |
|
||||
|  |
|
||||
| Check our website at [openbb.co](www.openbb.co) |
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -22,21 +22,19 @@ pip install openbb
|
||||
|
||||
This will install the following data providers:
|
||||
|
||||
| Extension Name | Description | Installation Command | Minimum Subscription Type Required |
|
||||
|----------------|-------------|----------------------|------------------------------------|
|
||||
| openbb-benzinga | [Benzinga](https://www.benzinga.com/apis/en-ca/) data connector | pip install openbb-benzinga | Paid |
|
||||
| openbb-biztoc | [Biztoc](https://api.biztoc.com/#biztoc-default) News data connector | pip install openbb-biztoc | Free |
|
||||
| openbb-ecb | [ECB](https://data.ecb.europa.eu/) data connector | pip install openbb-ecb | Free |
|
||||
| openbb-finra | [FINRA](https://www.finra.org/finra-data) data connector | pip install openbb-finra | Free |
|
||||
| openbb-finviz | [Finviz](https://finviz.com) data connector | pip install openbb-finra | Free |
|
||||
| openbb-fmp | [FMP](https://site.financialmodelingprep.com/developer/) data connector | pip install openbb-fmp | Free |
|
||||
| openbb-fred | [FRED](https://fred.stlouisfed.org/) data connector | pip install openbb-fred | Free |
|
||||
| openbb-intrinio | [Intrinio](https://intrinio.com/pricing) data connector | pip install openbb-intrinio | Paid |
|
||||
| openbb-oecd | [OECD](https://data.oecd.org/) data connector | pip install openbb-oecd | Free |
|
||||
| openbb-polygon | [Polygon](https://polygon.io/) data connector | pip install openbb-polygon | Free |
|
||||
| openbb-sec | [SEC](https://www.sec.gov/edgar/sec-api-documentation) data connector | pip install openbb-sec | Free |
|
||||
| openbb-tiingo | [Tiingo](https://www.tiingo.com/about/pricing) data connector | pip install openbb-tiingo | Free |
|
||||
| openbb-tradingeconomics | [TradingEconomics](https://tradingeconomics.com/api) data connector | pip install openbb-tradingeconomics | Paid |
|
||||
| Extension Name | Description | Installation Command | Minimum Subscription Type Required |
|
||||
| ----------------------- | ------------------------------------------------------------------------- | ----------------------------------- | ---------------------------------- |
|
||||
| openbb-benzinga | [Benzinga](https://www.benzinga.com/apis/en-ca/) data connector | pip install openbb-benzinga | Paid |
|
||||
| openbb-federal-reserve | [FederalReserve](https://www.federalreserve.gov/data.html) data connector | pip install openbb-federal-reserve | Free |
|
||||
| openbb-fmp | [FMP](https://site.financialmodelingprep.com/developer/) data connector | pip install openbb-fmp | Free |
|
||||
| openbb-fred | [FRED](https://fred.stlouisfed.org/) data connector | pip install openbb-fred | Free |
|
||||
| openbb-intrinio | [Intrinio](https://intrinio.com/pricing) data connector | pip install openbb-intrinio | Paid |
|
||||
| openbb-oecd | [OECD](https://data.oecd.org/) data connector | pip install openbb-oecd | Free |
|
||||
| openbb-polygon | [Polygon](https://polygon.io/) data connector | pip install openbb-polygon | Free |
|
||||
| openbb-sec | [SEC](https://www.sec.gov/edgar/sec-api-documentation) data connector | pip install openbb-sec | Free |
|
||||
| openbb-tiingo | [Tiingo](https://www.tiingo.com/about/pricing) data connector | pip install openbb-tiingo | Free |
|
||||
| openbb-tradingeconomics | [TradingEconomics](https://tradingeconomics.com/api) data connector | pip install openbb-tradingeconomics | Paid |
|
||||
| openbb-yahoo-finance | [Yahoo Finance](https://finance.yahoo.com/) data connector | pip install openbb-yfinance | Free |
|
||||
|
||||
To install extensions that expand the core functionalities specify the extension name or use `all` to install all.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Key Metrics Standard Model."""
|
||||
|
||||
from typing import List, Literal, Optional, Set, Union
|
||||
from typing import Literal, Optional
|
||||
|
||||
from pydantic import Field, field_validator
|
||||
|
||||
@@ -48,11 +48,3 @@ class KeyMetricsData(Data):
|
||||
pe_ratio: Optional[float] = Field(
|
||||
default=None, description="Price-to-earnings ratio (P/E ratio)"
|
||||
)
|
||||
|
||||
@field_validator("symbol", mode="before", check_fields=False)
|
||||
@classmethod
|
||||
def to_upper(cls, v: Union[str, List[str], Set[str]]):
|
||||
"""Convert field to uppercase."""
|
||||
if isinstance(v, str):
|
||||
return v.upper()
|
||||
return ",".join([symbol.upper() for symbol in list(v)]) if v else None
|
||||
|
||||
@@ -346,12 +346,6 @@ def residual_autocorrelation(
|
||||
'obb.econometrics.cointegration(data=stock_data, columns=["open", "close"])',
|
||||
],
|
||||
),
|
||||
APIEx(
|
||||
parameters={
|
||||
"columns": ["open", "close"],
|
||||
"data": APIEx.mock_data("timeseries"),
|
||||
}
|
||||
),
|
||||
],
|
||||
)
|
||||
def cointegration(
|
||||
|
||||
@@ -189,7 +189,7 @@ def test_etf_search(params, headers):
|
||||
(
|
||||
{
|
||||
"provider": "tradier",
|
||||
"symbol": "AAPL,MSFT",
|
||||
"symbol": "SPY",
|
||||
"start_date": "2023-01-01",
|
||||
"end_date": "2023-06-06",
|
||||
"interval": "1M",
|
||||
@@ -199,7 +199,7 @@ def test_etf_search(params, headers):
|
||||
(
|
||||
{
|
||||
"provider": "tradier",
|
||||
"symbol": "AAPL,MSFT",
|
||||
"symbol": "SPY,DJIA",
|
||||
"start_date": None,
|
||||
"end_date": None,
|
||||
"interval": "15m",
|
||||
|
||||
@@ -187,7 +187,7 @@ def test_etf_search(params, obb):
|
||||
(
|
||||
{
|
||||
"provider": "tradier",
|
||||
"symbol": "AAPL,MSFT",
|
||||
"symbol": "SPY",
|
||||
"start_date": "2023-01-01",
|
||||
"end_date": "2023-06-06",
|
||||
"interval": "1M",
|
||||
@@ -197,7 +197,7 @@ def test_etf_search(params, obb):
|
||||
(
|
||||
{
|
||||
"provider": "tradier",
|
||||
"symbol": "AAPL,MSFT",
|
||||
"symbol": "SPY,DJIA",
|
||||
"start_date": None,
|
||||
"end_date": None,
|
||||
"interval": "15m",
|
||||
|
||||
@@ -206,7 +206,13 @@ def test_quantitative_unitroot_test(params, data_type):
|
||||
"params, data_type",
|
||||
[
|
||||
(
|
||||
{"data": "", "target": "close", "rfr": "", "window": "", "index": "date"},
|
||||
{
|
||||
"data": "",
|
||||
"target": "close",
|
||||
"rfr": "",
|
||||
"window": "100",
|
||||
"index": "date",
|
||||
},
|
||||
"equity",
|
||||
),
|
||||
(
|
||||
@@ -214,7 +220,7 @@ def test_quantitative_unitroot_test(params, data_type):
|
||||
"data": "",
|
||||
"target": "high",
|
||||
"rfr": "0.5",
|
||||
"window": "250",
|
||||
"window": "150",
|
||||
"index": "date",
|
||||
},
|
||||
"crypto",
|
||||
@@ -243,7 +249,7 @@ def test_quantitative_performance_sharpe_ratio(params, data_type):
|
||||
"data": "",
|
||||
"target": "close",
|
||||
"target_return": "",
|
||||
"window": "",
|
||||
"window": "100",
|
||||
"adjusted": "",
|
||||
"index": "date",
|
||||
},
|
||||
|
||||
@@ -327,7 +327,6 @@ def test_quantitative_summary(params, data_type, obb):
|
||||
"data": "",
|
||||
"target": "close",
|
||||
"window": "10",
|
||||
"quantile_pct": "",
|
||||
"index": "date",
|
||||
},
|
||||
"equity",
|
||||
@@ -337,7 +336,6 @@ def test_quantitative_summary(params, data_type, obb):
|
||||
"data": "",
|
||||
"target": "high",
|
||||
"window": "50",
|
||||
"quantile_pct": "0.6",
|
||||
"index": "date",
|
||||
},
|
||||
"crypto",
|
||||
@@ -363,7 +361,6 @@ def test_quantitative_rolling_stdev(params, data_type, obb):
|
||||
"data": "",
|
||||
"target": "close",
|
||||
"window": "10",
|
||||
"quantile_pct": "",
|
||||
"index": "date",
|
||||
},
|
||||
"equity",
|
||||
@@ -373,7 +370,6 @@ def test_quantitative_rolling_stdev(params, data_type, obb):
|
||||
"data": "",
|
||||
"target": "high",
|
||||
"window": "50",
|
||||
"quantile_pct": "0.6",
|
||||
"index": "date",
|
||||
},
|
||||
"crypto",
|
||||
@@ -399,7 +395,6 @@ def test_quantitative_rolling_mean(params, data_type, obb):
|
||||
"data": "",
|
||||
"target": "close",
|
||||
"window": "10",
|
||||
"quantile_pct": "",
|
||||
"index": "date",
|
||||
},
|
||||
"equity",
|
||||
@@ -409,7 +404,6 @@ def test_quantitative_rolling_mean(params, data_type, obb):
|
||||
"data": "",
|
||||
"target": "high",
|
||||
"window": "50",
|
||||
"quantile_pct": "0.6",
|
||||
"index": "date",
|
||||
},
|
||||
"crypto",
|
||||
|
||||
@@ -931,7 +931,6 @@ def donchian(
|
||||
"ichimoku_data = obb.technical.ichimoku(data=stock_data.results, conversion=9, base=26, lookahead=False)",
|
||||
],
|
||||
),
|
||||
APIEx(parameters={"data": APIEx.mock_data("timeseries")}),
|
||||
],
|
||||
)
|
||||
def ichimoku(
|
||||
@@ -973,6 +972,7 @@ def ichimoku(
|
||||
OBBject[List[Data]]
|
||||
The calculated data.
|
||||
"""
|
||||
validate_data(data, [conversion, base, lagging])
|
||||
df = basemodel_to_df(data, index=index)
|
||||
df_target = get_target_columns(df, ["high", "low", "close"])
|
||||
df_ichimoku, df_span = df_target.ta.ichimoku(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Custom pytest configuration for the extensions."""
|
||||
|
||||
from typing import Dict, List
|
||||
from typing import Any, Dict, List, Tuple
|
||||
|
||||
import pytest
|
||||
from openbb_core.app.router import CommandMap
|
||||
@@ -13,7 +13,7 @@ commands = list(cm.map.keys())
|
||||
# ruff: noqa: SIM114
|
||||
|
||||
|
||||
def parametrize(argnames: str, argvalues: List[Dict], **kwargs):
|
||||
def parametrize(argnames: str, argvalues: List[Tuple[Any, ...]], **kwargs):
|
||||
"""Custom parametrize decorator that filters test cases based on the environment."""
|
||||
|
||||
routers, providers, obbject_ext = list_openbb_extensions()
|
||||
|
||||
@@ -2412,7 +2412,7 @@ class ROUTER_equity_fundamental(Container):
|
||||
symbol: Annotated[
|
||||
Union[str, List[str]],
|
||||
OpenBBCustomParameter(
|
||||
description="Symbol to get data for. Multiple items allowed for provider(s): fmp, yfinance."
|
||||
description="Symbol to get data for. Multiple items allowed for provider(s): fmp, intrinio, yfinance."
|
||||
),
|
||||
],
|
||||
period: Annotated[
|
||||
@@ -2436,7 +2436,7 @@ class ROUTER_equity_fundamental(Container):
|
||||
Parameters
|
||||
----------
|
||||
symbol : Union[str, List[str]]
|
||||
Symbol to get data for. Multiple items allowed for provider(s): fmp, yfinance.
|
||||
Symbol to get data for. Multiple items allowed for provider(s): fmp, intrinio, yfinance.
|
||||
period : Optional[Literal['annual', 'quarter']]
|
||||
Time period of the data to return.
|
||||
limit : Optional[int]
|
||||
@@ -2451,7 +2451,7 @@ class ROUTER_equity_fundamental(Container):
|
||||
Returns
|
||||
-------
|
||||
OBBject
|
||||
results : Union[List[KeyMetrics], KeyMetrics]
|
||||
results : List[KeyMetrics]
|
||||
Serializable results.
|
||||
provider : Optional[Literal['fmp', 'intrinio', 'yfinance']]
|
||||
Provider name.
|
||||
@@ -2494,8 +2494,8 @@ class ROUTER_equity_fundamental(Container):
|
||||
Shareholders equity per share (provider: fmp)
|
||||
interest_debt_per_share : Optional[float]
|
||||
Interest debt per share (provider: fmp)
|
||||
enterprise_value : Optional[Union[float, int]]
|
||||
Enterprise value (provider: fmp, yfinance)
|
||||
enterprise_value : Optional[int]
|
||||
Enterprise value (provider: fmp, intrinio, yfinance)
|
||||
price_to_sales_ratio : Optional[float]
|
||||
Price-to-sales ratio (provider: fmp)
|
||||
pocf_ratio : Optional[float]
|
||||
@@ -2515,7 +2515,8 @@ class ROUTER_equity_fundamental(Container):
|
||||
ev_to_free_cash_flow : Optional[float]
|
||||
Enterprise value-to-free cash flow ratio (provider: fmp)
|
||||
earnings_yield : Optional[float]
|
||||
Earnings yield (provider: fmp)
|
||||
Earnings yield (provider: fmp);
|
||||
Earnings yield, as a normalized percent. (provider: intrinio)
|
||||
free_cash_flow_yield : Optional[float]
|
||||
Free cash flow yield (provider: fmp)
|
||||
debt_to_equity : Optional[float]
|
||||
@@ -2586,15 +2587,73 @@ class ROUTER_equity_fundamental(Container):
|
||||
Return on equity (provider: fmp)
|
||||
capex_per_share : Optional[float]
|
||||
Capital expenditures per share (provider: fmp)
|
||||
price_to_book : Optional[float]
|
||||
Price to book ratio. (provider: intrinio, yfinance)
|
||||
price_to_tangible_book : Optional[float]
|
||||
Price to tangible book ratio. (provider: intrinio)
|
||||
price_to_revenue : Optional[float]
|
||||
Price to revenue ratio. (provider: intrinio)
|
||||
quick_ratio : Optional[float]
|
||||
Quick ratio. (provider: intrinio, yfinance)
|
||||
gross_margin : Optional[float]
|
||||
Gross margin, as a normalized percent. (provider: intrinio, yfinance)
|
||||
ebit_margin : Optional[float]
|
||||
EBIT margin, as a normalized percent. (provider: intrinio)
|
||||
profit_margin : Optional[float]
|
||||
Profit margin, as a normalized percent. (provider: intrinio, yfinance)
|
||||
eps : Optional[float]
|
||||
Basic earnings per share. (provider: intrinio)
|
||||
eps_growth : Optional[float]
|
||||
EPS growth, as a normalized percent. (provider: intrinio)
|
||||
revenue_growth : Optional[float]
|
||||
Revenue growth, as a normalized percent. (provider: intrinio, yfinance)
|
||||
ebitda_growth : Optional[float]
|
||||
EBITDA growth, as a normalized percent. (provider: intrinio)
|
||||
ebit_growth : Optional[float]
|
||||
EBIT growth, as a normalized percent. (provider: intrinio)
|
||||
net_income_growth : Optional[float]
|
||||
Net income growth, as a normalized percent. (provider: intrinio)
|
||||
free_cash_flow_to_firm_growth : Optional[float]
|
||||
Free cash flow to firm growth, as a normalized percent. (provider: intrinio)
|
||||
invested_capital_growth : Optional[float]
|
||||
Invested capital growth, as a normalized percent. (provider: intrinio)
|
||||
return_on_assets : Optional[float]
|
||||
Return on assets, as a normalized percent. (provider: intrinio, yfinance)
|
||||
return_on_equity : Optional[float]
|
||||
Return on equity, as a normalized percent. (provider: intrinio, yfinance)
|
||||
return_on_invested_capital : Optional[float]
|
||||
Return on invested capital, as a normalized percent. (provider: intrinio)
|
||||
ebitda : Optional[int]
|
||||
Earnings before interest, taxes, depreciation, and amortization. (provider: intrinio)
|
||||
ebit : Optional[int]
|
||||
Earnings before interest and taxes. (provider: intrinio)
|
||||
long_term_debt : Optional[int]
|
||||
Long-term debt. (provider: intrinio)
|
||||
total_debt : Optional[int]
|
||||
Total debt. (provider: intrinio)
|
||||
total_capital : Optional[int]
|
||||
The sum of long-term debt and total shareholder equity. (provider: intrinio)
|
||||
free_cash_flow_to_firm : Optional[int]
|
||||
Free cash flow to firm. (provider: intrinio)
|
||||
altman_z_score : Optional[float]
|
||||
Altman Z-score. (provider: intrinio)
|
||||
beta : Optional[float]
|
||||
Beta relative to the broad market calculated on a rolling three-year basis. (provider: intrinio);
|
||||
Beta relative to the broad market (rolling three-year). (provider: intrinio);
|
||||
Beta relative to the broad market (5-year monthly). (provider: yfinance)
|
||||
volume : Optional[float]
|
||||
Volume (provider: intrinio)
|
||||
fifty_two_week_high : Optional[float]
|
||||
last_price : Optional[float]
|
||||
Last price of the stock. (provider: intrinio)
|
||||
year_high : Optional[float]
|
||||
52 week high (provider: intrinio)
|
||||
fifty_two_week_low : Optional[float]
|
||||
year_low : Optional[float]
|
||||
52 week low (provider: intrinio)
|
||||
volume_avg : Optional[int]
|
||||
Average daily volume. (provider: intrinio)
|
||||
short_interest : Optional[int]
|
||||
Number of shares reported as sold short. (provider: intrinio)
|
||||
shares_outstanding : Optional[int]
|
||||
Weighted average shares outstanding (TTM). (provider: intrinio)
|
||||
days_to_cover : Optional[float]
|
||||
Days to cover short interest, based on average daily volume. (provider: intrinio)
|
||||
forward_pe : Optional[float]
|
||||
Forward price-to-earnings ratio. (provider: yfinance)
|
||||
peg_ratio : Optional[float]
|
||||
@@ -2611,30 +2670,16 @@ class ROUTER_equity_fundamental(Container):
|
||||
Earnings growth (Year Over Year), as a normalized percent. (provider: yfinance)
|
||||
earnings_growth_quarterly : Optional[float]
|
||||
Quarterly earnings growth (Year Over Year), as a normalized percent. (provider: yfinance)
|
||||
revenue_growth : Optional[float]
|
||||
Revenue growth (Year Over Year), as a normalized percent. (provider: yfinance)
|
||||
enterprise_to_revenue : Optional[float]
|
||||
Enterprise value to revenue ratio. (provider: yfinance)
|
||||
quick_ratio : Optional[float]
|
||||
Quick ratio. (provider: yfinance)
|
||||
gross_margin : Optional[float]
|
||||
Gross margin, as a normalized percent. (provider: yfinance)
|
||||
operating_margin : Optional[float]
|
||||
Operating margin, as a normalized percent. (provider: yfinance)
|
||||
ebitda_margin : Optional[float]
|
||||
EBITDA margin, as a normalized percent. (provider: yfinance)
|
||||
profit_margin : Optional[float]
|
||||
Profit margin, as a normalized percent. (provider: yfinance)
|
||||
return_on_assets : Optional[float]
|
||||
Return on assets, as a normalized percent. (provider: yfinance)
|
||||
return_on_equity : Optional[float]
|
||||
Return on equity, as a normalized percent. (provider: yfinance)
|
||||
dividend_yield_5y_avg : Optional[float]
|
||||
5-year average dividend yield, as a normalized percent. (provider: yfinance)
|
||||
book_value : Optional[float]
|
||||
Book value per share. (provider: yfinance)
|
||||
price_to_book : Optional[float]
|
||||
Price-to-book ratio. (provider: yfinance)
|
||||
overall_risk : Optional[float]
|
||||
Overall risk score. (provider: yfinance)
|
||||
audit_risk : Optional[float]
|
||||
@@ -2673,7 +2718,11 @@ class ROUTER_equity_fundamental(Container):
|
||||
"limit": limit,
|
||||
},
|
||||
extra_params=kwargs,
|
||||
extra_info={"symbol": {"multiple_items_allowed": ["fmp", "yfinance"]}},
|
||||
extra_info={
|
||||
"symbol": {
|
||||
"multiple_items_allowed": ["fmp", "intrinio", "yfinance"]
|
||||
}
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# pylint: disable=unused-argument
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
from datetime import datetime
|
||||
from io import BytesIO
|
||||
from typing import Any, Dict, List, Literal, Optional
|
||||
@@ -213,70 +214,84 @@ class AVEquityHistoricalFetcher(
|
||||
if result:
|
||||
data = read_csv(BytesIO(result)) # type: ignore
|
||||
if len(data) > 0:
|
||||
data.rename(
|
||||
columns={
|
||||
"timestamp": "date",
|
||||
"dividend_amount": "dividend",
|
||||
"adjusted close": "adj_close",
|
||||
"dividend amount": "dividend",
|
||||
"adjusted_close": "adj_close",
|
||||
"split_coefficient": "split_factor",
|
||||
},
|
||||
inplace=True,
|
||||
)
|
||||
data["date"] = data["date"].apply(to_datetime)
|
||||
data.set_index("date", inplace=True)
|
||||
# The returned data when 'adjusted=true' from the API does not return a usable OHLCV data set.
|
||||
# We need to calculate the adjusted prices manually.
|
||||
if query.adjustment != "unadjusted":
|
||||
temp = data.copy()
|
||||
temp["dividend_factor"] = (
|
||||
temp["close"] - temp["dividend"]
|
||||
) / temp["close"]
|
||||
temp["volume_factor"] = temp["split_factor"]
|
||||
temp["split_factor"] = 1 / temp["split_factor"]
|
||||
adj_cols = ["open", "high", "low", "close", "volume"]
|
||||
divs = query.adjustment == "splits_and_dividends"
|
||||
for col in adj_cols:
|
||||
divs = False if col == "volume" else divs
|
||||
if col in temp.columns:
|
||||
temp = calculate_adjusted_prices(temp, col, divs)
|
||||
temp["adj_dividend"] = (
|
||||
temp["adj_close"] * (1 - temp["dividend_factor"])
|
||||
if query.adjustment == "splits_only"
|
||||
else temp["close"] * (1 - temp["dividend_factor"])
|
||||
if all(
|
||||
col in data.columns
|
||||
for col in [
|
||||
"timestamp",
|
||||
"dividend_amount",
|
||||
"adjusted close",
|
||||
"split_coefficient",
|
||||
]
|
||||
):
|
||||
data.rename(
|
||||
columns={
|
||||
"timestamp": "date",
|
||||
"dividend_amount": "dividend",
|
||||
"adjusted close": "adj_close",
|
||||
"split_coefficient": "split_factor",
|
||||
},
|
||||
inplace=True,
|
||||
)
|
||||
data["open"] = round(temp["adj_open"], 4)
|
||||
data["high"] = round(temp["adj_high"], 4)
|
||||
data["low"] = round(temp["adj_low"], 4)
|
||||
data["close"] = round(temp["adj_close"], 4)
|
||||
data["volume"] = round(temp["adj_volume"]).astype(int)
|
||||
data["dividend"] = round(temp["adj_dividend"], 4)
|
||||
data.drop(columns=["adj_close"], inplace=True)
|
||||
# Resample the daily data for the interval requested.
|
||||
freq = ""
|
||||
agg_dict = {
|
||||
"open": "first",
|
||||
"high": "max",
|
||||
"low": "min",
|
||||
"close": "last",
|
||||
"volume": "sum",
|
||||
"dividend": "sum",
|
||||
"split_factor": "prod",
|
||||
}
|
||||
if query.adjustment == "unadjusted":
|
||||
agg_dict.pop("dividend")
|
||||
agg_dict.pop("split_factor")
|
||||
if query.interval == "1M":
|
||||
freq = "M"
|
||||
if query.interval == "1W":
|
||||
freq = "W-FRI"
|
||||
if freq in ["M", "W-FRI"]:
|
||||
data = data.resample(freq).agg({**agg_dict})
|
||||
if len(query.symbol.split(",")) > 1:
|
||||
data.loc[:, "symbol"] = symbol
|
||||
data["date"] = data["date"].apply(to_datetime)
|
||||
data.set_index("date", inplace=True)
|
||||
# The returned data when 'adjusted=true' from the API does not return a usable OHLCV data set.
|
||||
# We need to calculate the adjusted prices manually.
|
||||
if query.adjustment != "unadjusted":
|
||||
temp = data.copy()
|
||||
temp["dividend_factor"] = (
|
||||
temp["close"] - temp["dividend"]
|
||||
) / temp["close"]
|
||||
temp["volume_factor"] = temp["split_factor"]
|
||||
temp["split_factor"] = 1 / temp["split_factor"]
|
||||
adj_cols = ["open", "high", "low", "close", "volume"]
|
||||
divs = query.adjustment == "splits_and_dividends"
|
||||
for col in adj_cols:
|
||||
divs = False if col == "volume" else divs
|
||||
if col in temp.columns:
|
||||
temp = calculate_adjusted_prices(temp, col, divs)
|
||||
temp["adj_dividend"] = (
|
||||
temp["adj_close"] * (1 - temp["dividend_factor"])
|
||||
if query.adjustment == "splits_only"
|
||||
else temp["close"] * (1 - temp["dividend_factor"])
|
||||
)
|
||||
data["open"] = round(temp["adj_open"], 4)
|
||||
data["high"] = round(temp["adj_high"], 4)
|
||||
data["low"] = round(temp["adj_low"], 4)
|
||||
data["close"] = round(temp["adj_close"], 4)
|
||||
data["volume"] = round(temp["adj_volume"]).astype(int)
|
||||
data["dividend"] = round(temp["adj_dividend"], 4)
|
||||
data.drop(columns=["adj_close"], inplace=True)
|
||||
# Resample the daily data for the interval requested.
|
||||
freq = ""
|
||||
agg_dict = {
|
||||
"open": "first",
|
||||
"high": "max",
|
||||
"low": "min",
|
||||
"close": "last",
|
||||
"volume": "sum",
|
||||
"dividend": "sum",
|
||||
"split_factor": "prod",
|
||||
}
|
||||
if query.adjustment == "unadjusted":
|
||||
agg_dict.pop("dividend")
|
||||
agg_dict.pop("split_factor")
|
||||
if query.interval == "1M":
|
||||
freq = "M"
|
||||
if query.interval == "1W":
|
||||
freq = "W-FRI"
|
||||
if freq in ["M", "W-FRI"]:
|
||||
data = data.resample(freq).agg({**agg_dict})
|
||||
if len(query.symbol.split(",")) > 1:
|
||||
data.loc[:, "symbol"] = symbol
|
||||
|
||||
results.extend(data.reset_index().to_dict("records"))
|
||||
results.extend(data.reset_index().to_dict("records"))
|
||||
else:
|
||||
try:
|
||||
data = json.loads(result.decode())
|
||||
if "Information" in data:
|
||||
warn(f"{data['Information']}")
|
||||
except json.JSONDecodeError:
|
||||
warn(f"Failed to parse data for {symbol}.")
|
||||
|
||||
return results
|
||||
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
"""Intrinio Key Metrics Model."""
|
||||
|
||||
from typing import Any, Dict, List, Optional
|
||||
# pylint: disable=unused-argument
|
||||
|
||||
import asyncio
|
||||
from typing import Any, Dict, List, Optional
|
||||
from warnings import warn
|
||||
|
||||
from openbb_core.provider.abstract.data import ForceInt
|
||||
from openbb_core.provider.abstract.fetcher import Fetcher
|
||||
from openbb_core.provider.standard_models.key_metrics import (
|
||||
KeyMetricsData,
|
||||
KeyMetricsQueryParams,
|
||||
)
|
||||
from openbb_core.provider.utils.errors import EmptyDataError
|
||||
from openbb_core.provider.utils.helpers import (
|
||||
ClientResponse,
|
||||
amake_requests,
|
||||
@@ -15,15 +21,13 @@ from pydantic import Field
|
||||
|
||||
|
||||
class IntrinioKeyMetricsQueryParams(KeyMetricsQueryParams):
|
||||
"""Intrinio Key Metrics Query.
|
||||
|
||||
Source: https://data.intrinio.com/data-tag/beta
|
||||
https://data.intrinio.com/data-tag/volume
|
||||
https://data.intrinio.com/data-tag/52_week_high
|
||||
https://data.intrinio.com/data-tag/52_week_low
|
||||
https://data.intrinio.com/data-tag/dividendyield
|
||||
https://data.intrinio.com/data-tag/pricetoearnings
|
||||
"""
|
||||
Intrinio Key Metrics Query.
|
||||
|
||||
Source: https://data.intrinio.com/data-tags/
|
||||
"""
|
||||
|
||||
__json_schema_extra__ = {"symbol": ["multiple_items_allowed"]}
|
||||
|
||||
|
||||
class IntrinioKeyMetricsData(KeyMetricsData):
|
||||
@@ -32,26 +36,200 @@ class IntrinioKeyMetricsData(KeyMetricsData):
|
||||
__alias_dict__ = {
|
||||
"market_cap": "marketcap",
|
||||
"pe_ratio": "pricetoearnings",
|
||||
"price_to_book": "pricetobook",
|
||||
"price_to_tangible_book": "pricetotangiblebook",
|
||||
"price_to_revenue": "pricetorevenue",
|
||||
"long_term_debt": "ltdebtandcapleases",
|
||||
"total_debt": "debt",
|
||||
"total_capital": "totalcapital",
|
||||
"enterprise_value": "enterprisevalue",
|
||||
"eps_growth": "epsgrowth",
|
||||
"ebit_growth": "ebitgrowth",
|
||||
"ebitda_growth": "ebitdagrowth",
|
||||
"revenue_growth": "revenuegrowth",
|
||||
"net_income_growth": "netincomegrowth",
|
||||
"free_cash_flow_to_firm_growth": "fcffgrowth",
|
||||
"invested_capital_growth": "investedcapitalgrowth",
|
||||
"quick_ratio": "quickratio",
|
||||
"gross_margin": "grossmargin",
|
||||
"ebit_margin": "ebitmargin",
|
||||
"profit_margin": "profitmargin",
|
||||
"return_on_assets": "roa",
|
||||
"return_on_equity": "roe",
|
||||
"return_on_invested_capital": "roic",
|
||||
"free_cash_flow_to_firm": "freecashflow",
|
||||
"altman_z_score": "altmanzscore",
|
||||
"earnings_yield": "earningsyield",
|
||||
"dividend_yield": "dividendyield",
|
||||
"year_high": "52_week_high",
|
||||
"year_low": "52_week_low",
|
||||
"volume_avg": "average_daily_volume",
|
||||
"shares_outstanding": "adjweightedavebasicsharesos",
|
||||
"eps": "basiceps",
|
||||
}
|
||||
|
||||
beta: float = Field(
|
||||
description="Beta relative to the broad market calculated on a rolling three-year basis."
|
||||
price_to_book: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Price to book ratio.",
|
||||
)
|
||||
volume: float = Field(description="Volume")
|
||||
fifty_two_week_high: float = Field(description="52 week high", alias="52_week_high")
|
||||
fifty_two_week_low: float = Field(description="52 week low", alias="52_week_low")
|
||||
dividend_yield: float = Field(
|
||||
price_to_tangible_book: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Price to tangible book ratio.",
|
||||
)
|
||||
price_to_revenue: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Price to revenue ratio.",
|
||||
)
|
||||
quick_ratio: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Quick ratio.",
|
||||
)
|
||||
gross_margin: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Gross margin, as a normalized percent.",
|
||||
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
|
||||
)
|
||||
ebit_margin: Optional[float] = Field(
|
||||
default=None,
|
||||
description="EBIT margin, as a normalized percent.",
|
||||
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
|
||||
)
|
||||
profit_margin: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Profit margin, as a normalized percent.",
|
||||
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
|
||||
)
|
||||
eps: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Basic earnings per share.",
|
||||
)
|
||||
eps_growth: Optional[float] = Field(
|
||||
default=None,
|
||||
description="EPS growth, as a normalized percent.",
|
||||
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
|
||||
)
|
||||
revenue_growth: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Revenue growth, as a normalized percent.",
|
||||
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
|
||||
)
|
||||
ebitda_growth: Optional[float] = Field(
|
||||
default=None,
|
||||
description="EBITDA growth, as a normalized percent.",
|
||||
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
|
||||
)
|
||||
ebit_growth: Optional[float] = Field(
|
||||
default=None,
|
||||
description="EBIT growth, as a normalized percent.",
|
||||
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
|
||||
)
|
||||
net_income_growth: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Net income growth, as a normalized percent.",
|
||||
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
|
||||
)
|
||||
free_cash_flow_to_firm_growth: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Free cash flow to firm growth, as a normalized percent.",
|
||||
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
|
||||
)
|
||||
invested_capital_growth: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Invested capital growth, as a normalized percent.",
|
||||
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
|
||||
)
|
||||
return_on_assets: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Return on assets, as a normalized percent.",
|
||||
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
|
||||
)
|
||||
return_on_equity: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Return on equity, as a normalized percent.",
|
||||
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
|
||||
)
|
||||
return_on_invested_capital: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Return on invested capital, as a normalized percent.",
|
||||
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
|
||||
)
|
||||
ebitda: Optional[ForceInt] = Field(
|
||||
default=None,
|
||||
description="Earnings before interest, taxes, depreciation, and amortization.",
|
||||
)
|
||||
ebit: Optional[ForceInt] = Field(
|
||||
default=None,
|
||||
description="Earnings before interest and taxes.",
|
||||
)
|
||||
long_term_debt: Optional[ForceInt] = Field(
|
||||
default=None,
|
||||
description="Long-term debt.",
|
||||
)
|
||||
total_debt: Optional[ForceInt] = Field(
|
||||
default=None,
|
||||
description="Total debt.",
|
||||
)
|
||||
total_capital: Optional[ForceInt] = Field(
|
||||
default=None,
|
||||
description="The sum of long-term debt and total shareholder equity.",
|
||||
)
|
||||
enterprise_value: Optional[ForceInt] = Field(
|
||||
default=None,
|
||||
description="Enterprise value.",
|
||||
)
|
||||
free_cash_flow_to_firm: Optional[ForceInt] = Field(
|
||||
default=None,
|
||||
description="Free cash flow to firm.",
|
||||
)
|
||||
altman_z_score: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Altman Z-score.",
|
||||
)
|
||||
beta: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Beta relative to the broad market (rolling three-year).",
|
||||
)
|
||||
dividend_yield: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Dividend yield, as a normalized percent.",
|
||||
json_schema_extra={"unit_measurement": "percent", "frontend_multiply": 100},
|
||||
alias="dividendyield",
|
||||
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
|
||||
)
|
||||
earnings_yield: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Earnings yield, as a normalized percent.",
|
||||
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
|
||||
)
|
||||
last_price: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Last price of the stock.",
|
||||
)
|
||||
year_high: Optional[float] = Field(
|
||||
default=None,
|
||||
description="52 week high",
|
||||
)
|
||||
year_low: float = Field(default=None, description="52 week low")
|
||||
volume_avg: Optional[ForceInt] = Field(
|
||||
default=None,
|
||||
description="Average daily volume.",
|
||||
)
|
||||
short_interest: Optional[ForceInt] = Field(
|
||||
default=None,
|
||||
description="Number of shares reported as sold short.",
|
||||
)
|
||||
shares_outstanding: Optional[ForceInt] = Field(
|
||||
default=None,
|
||||
description="Weighted average shares outstanding (TTM).",
|
||||
)
|
||||
days_to_cover: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Days to cover short interest, based on average daily volume.",
|
||||
)
|
||||
|
||||
|
||||
class IntrinioKeyMetricsFetcher(
|
||||
Fetcher[
|
||||
IntrinioKeyMetricsQueryParams,
|
||||
IntrinioKeyMetricsData,
|
||||
List[IntrinioKeyMetricsData],
|
||||
]
|
||||
):
|
||||
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
|
||||
@@ -59,44 +237,128 @@ class IntrinioKeyMetricsFetcher(
|
||||
@staticmethod
|
||||
def transform_query(params: Dict[str, Any]) -> IntrinioKeyMetricsQueryParams:
|
||||
"""Transform the query params."""
|
||||
|
||||
if params.get("period") is not None and params.get("period") != "annual":
|
||||
warn(
|
||||
"The period parameter is not available for this Intrinio endpoint, it will be ignored."
|
||||
)
|
||||
return IntrinioKeyMetricsQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
async def aextract_data(
|
||||
query: IntrinioKeyMetricsQueryParams, # pylint: disable=unused-argument
|
||||
query: IntrinioKeyMetricsQueryParams,
|
||||
credentials: Optional[Dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> Dict:
|
||||
) -> List[Dict]:
|
||||
"""Return the raw data from the Intrinio endpoint."""
|
||||
api_key = credentials.get("intrinio_api_key") if credentials else ""
|
||||
tags = [
|
||||
"beta",
|
||||
"volume",
|
||||
"average_daily_volume",
|
||||
"basiceps",
|
||||
"basicdilutedeps",
|
||||
"marketcap",
|
||||
"last_price",
|
||||
"52_week_high",
|
||||
"52_week_low",
|
||||
"dividendyield",
|
||||
"pricetoearnings",
|
||||
"pricetorevenue",
|
||||
"pricetobook",
|
||||
"pricetotangiblebook",
|
||||
"grossmargin",
|
||||
"ebitmargin",
|
||||
"profitmargin",
|
||||
"roa",
|
||||
"roe",
|
||||
"roic",
|
||||
"earningsyield",
|
||||
"days_to_cover",
|
||||
"short_interest",
|
||||
"revenuegrowth",
|
||||
"ebitgrowth",
|
||||
"ebitdagrowth",
|
||||
"epsgrowth",
|
||||
"netincomegrowth",
|
||||
"investedcapitalgrowth",
|
||||
"debt",
|
||||
"totalcapital",
|
||||
"enterprisevalue",
|
||||
"freecashflow",
|
||||
"fcffgrowth",
|
||||
"ltdebtandcapleases",
|
||||
"altmanzscore",
|
||||
"quickratio",
|
||||
"ebit",
|
||||
"ebitda",
|
||||
"adjweightedavebasicsharesos",
|
||||
]
|
||||
results = []
|
||||
urls = []
|
||||
symbols = query.symbol.split(",")
|
||||
|
||||
urls = [
|
||||
f"https://api-v2.intrinio.com/companies/{query.symbol}/data_point/{tag}?api_key={api_key}"
|
||||
for tag in tags
|
||||
]
|
||||
async def get_one(symbol: str):
|
||||
"""Get data for one symbol."""
|
||||
|
||||
async def callback(response: ClientResponse, _: Any) -> Dict:
|
||||
"""Return the response."""
|
||||
return {response.url.parts[-1]: await response.json()}
|
||||
_urls = [
|
||||
f"https://api-v2.intrinio.com/companies/{symbol}/data_point/{tag}?api_key={api_key}"
|
||||
for tag in tags
|
||||
]
|
||||
urls.extend(_urls)
|
||||
|
||||
data: Dict = {"symbol": query.symbol}
|
||||
for result in await amake_requests(urls, callback, **kwargs):
|
||||
data.update(result)
|
||||
async def callback(response: ClientResponse, _: Any) -> Dict:
|
||||
"""Return the response."""
|
||||
return {response.url.parts[-1]: await response.json()}
|
||||
|
||||
return data
|
||||
data = {}
|
||||
for result in await amake_requests(urls, callback, **kwargs):
|
||||
data.update(result)
|
||||
if data:
|
||||
data["symbol"] = symbol
|
||||
results.append(data)
|
||||
|
||||
tasks = [get_one(symbol) for symbol in symbols]
|
||||
|
||||
await asyncio.gather(*tasks)
|
||||
|
||||
if not results:
|
||||
raise EmptyDataError()
|
||||
|
||||
return results
|
||||
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
query: IntrinioKeyMetricsQueryParams, data: List[Dict], **kwargs: Any
|
||||
) -> IntrinioKeyMetricsData:
|
||||
"""Return the transformed data."""
|
||||
return IntrinioKeyMetricsData.model_validate(data)
|
||||
query: IntrinioKeyMetricsQueryParams,
|
||||
data: List[Dict],
|
||||
**kwargs: Any,
|
||||
) -> List[IntrinioKeyMetricsData]:
|
||||
"""Validate and transform the data."""
|
||||
|
||||
# Sort the results by the order of the symbols in the query.
|
||||
symbols = query.symbol.split(",")
|
||||
data = sorted(
|
||||
data,
|
||||
key=(
|
||||
lambda item: (
|
||||
symbols.index(item["symbol"])
|
||||
if item["symbol"] in symbols
|
||||
else len(symbols)
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
results: List[IntrinioKeyMetricsData] = []
|
||||
for item in data:
|
||||
|
||||
if item.get("marketcap") is None or isinstance(item.get("marketcap"), dict):
|
||||
warn(f"Symbol Error: No data found for {item.get('symbol')}")
|
||||
continue
|
||||
|
||||
for key, value in item.copy().items():
|
||||
# A bad response in a field will return a dict here, so we remove it.
|
||||
if isinstance(value, dict):
|
||||
_ = item.pop(key)
|
||||
|
||||
results.append(IntrinioKeyMetricsData.model_validate(item))
|
||||
|
||||
return results
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,9 +2,12 @@
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
import asyncio
|
||||
import warnings
|
||||
from datetime import datetime
|
||||
from datetime import (
|
||||
date as dateType,
|
||||
datetime,
|
||||
)
|
||||
from typing import Any, Dict, List, Literal, Optional, Union
|
||||
from warnings import warn
|
||||
|
||||
import pytz
|
||||
from openbb_core.provider.abstract.fetcher import Fetcher
|
||||
@@ -24,8 +27,6 @@ from openbb_tmx.utils.helpers import (
|
||||
from pandas import DataFrame, to_datetime
|
||||
from pydantic import Field, field_validator
|
||||
|
||||
_warn = warnings.warn
|
||||
|
||||
|
||||
class TmxEquityHistoricalQueryParams(EquityHistoricalQueryParams):
|
||||
"""
|
||||
@@ -112,6 +113,8 @@ class TmxEquityHistoricalData(EquityHistoricalData):
|
||||
@classmethod
|
||||
def date_validate(cls, v): # pylint: disable=W0221
|
||||
"""Validate the datetime format."""
|
||||
if isinstance(v, (datetime, dateType)):
|
||||
return v if v.hour != 0 and v.minute != 0 and v.second != 0 else v.date() # type: ignore
|
||||
try:
|
||||
dt = datetime.strptime(v, "%Y-%m-%d %H:%M:%S%z")
|
||||
return dt.astimezone(pytz.timezone("America/New_York"))
|
||||
@@ -133,7 +136,7 @@ class TmxEquityHistoricalFetcher(
|
||||
and adjustment != "splits_only"
|
||||
and params.get("interval") not in ["day", "1d"]
|
||||
):
|
||||
_warn("Adjustment parameter is only available for daily data.")
|
||||
warn("Adjustment parameter is only available for daily data.")
|
||||
return TmxEquityHistoricalQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
@@ -179,7 +182,7 @@ class TmxEquityHistoricalFetcher(
|
||||
results.extend(data)
|
||||
|
||||
if data == []:
|
||||
_warn(f"No data found for {symbol}.")
|
||||
warn(f"No data found for {symbol}.")
|
||||
|
||||
return results
|
||||
|
||||
|
||||
2
openbb_platform/providers/tmx/pyproject.toml
vendored
2
openbb_platform/providers/tmx/pyproject.toml
vendored
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "openbb-tmx"
|
||||
version = "1.0.0"
|
||||
version = "1.0.0b"
|
||||
description = "Unofficial TMX data provider extension for the OpenBB Platform - Public Canadian markets data for Python and Fast API."
|
||||
authors = ["OpenBB <hello@openbb.co>"]
|
||||
readme = "README.md"
|
||||
|
||||
@@ -20,6 +20,7 @@ tradier_provider = Provider(
|
||||
], # account_type is either "sandbox" or "live"
|
||||
fetcher_dict={
|
||||
"EquityHistorical": TradierEquityHistoricalFetcher,
|
||||
"EtfHistorical": TradierEquityHistoricalFetcher,
|
||||
"EquityQuote": TradierEquityQuoteFetcher,
|
||||
"EquitySearch": TradierEquitySearchFetcher,
|
||||
"OptionsChains": TradierOptionsChainsFetcher,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "openbb-tradier"
|
||||
version = "1.0.0"
|
||||
version = "1.0.0b"
|
||||
description = "Tradier Provider Extension for the OpenBB Platform"
|
||||
authors = ["OpenBB <hello@openbb.co>"]
|
||||
readme = "README.md"
|
||||
|
||||
4
openbb_platform/pyproject.toml
vendored
4
openbb_platform/pyproject.toml
vendored
@@ -45,8 +45,8 @@ openbb-government-us = { version = "^1.1.2", optional = true }
|
||||
openbb-nasdaq = { version = "^1.1.3", optional = true }
|
||||
openbb-seeking-alpha = { version = "^1.1.2", optional = true }
|
||||
openbb-stockgrid = { version = "^1.1.2", optional = true }
|
||||
openbb-tmx = { version = "^1.0.0", optional = true }
|
||||
openbb-tradier = { version = "^1.0.0", optional = true }
|
||||
openbb-tmx = { version = "^1.0.0b", optional = true }
|
||||
openbb-tradier = { version = "^1.0.0b", optional = true }
|
||||
openbb-wsj = { version = "^1.1.2", optional = true }
|
||||
|
||||
openbb-charting = { version = "^2.0.0", optional = true }
|
||||
|
||||
Reference in New Issue
Block a user