mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 04:31:13 +00:00
[Feature] Add Fama-French Data Library (#7163)
* add fama-french data library * lint * lint * lint * more lint and test function names * test shuffle * test params * use apply_date in get_breakpoint_data * unused import * not that import * ok fine, do it this way
This commit is contained in:
@@ -58,6 +58,7 @@ openbb-biztoc = { path = "./providers/biztoc", optional = true, develop = true }
|
||||
openbb-cboe = { path = "./providers/cboe", optional = true, develop = true }
|
||||
openbb-deribit = { path = "./providers/deribit", optional = true, develop = true }
|
||||
openbb-ecb = { path = "./providers/ecb", optional = true, develop = true }
|
||||
openbb-famafrench = { path = "./providers/famafrench", optional = true, develop = true }
|
||||
openbb-finra = { path = "./providers/finra", optional = true, develop = true }
|
||||
openbb-finviz = { path = "./providers/finviz", optional = true, develop = true }
|
||||
openbb-government-us = { path = "./providers/government_us", optional = true, develop = true }
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
"""OpenBB FamaFrench Integration Tests module."""
|
||||
@@ -0,0 +1,243 @@
|
||||
"""Test Fama-French API endpoints."""
|
||||
|
||||
import base64
|
||||
|
||||
import pytest
|
||||
import requests
|
||||
from openbb_core.env import Env
|
||||
from openbb_core.provider.utils.helpers import get_querystring
|
||||
|
||||
# pylint: disable=redefined-outer-name
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def headers():
|
||||
"""Get the headers for the API request."""
|
||||
userpass = f"{Env().API_USERNAME}:{Env().API_PASSWORD}"
|
||||
userpass_bytes = userpass.encode("ascii")
|
||||
base64_bytes = base64.b64encode(userpass_bytes)
|
||||
|
||||
return {"Authorization": f"Basic {base64_bytes.decode('ascii')}"}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"params",
|
||||
[
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
}
|
||||
),
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
"region": "america",
|
||||
"factor": "momentum",
|
||||
"frequency": "monthly",
|
||||
"start_date": None,
|
||||
"end_date": None,
|
||||
}
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.integration
|
||||
def test_famafrench_factors(params, headers):
|
||||
"""Test the Fama-French factors endpoint."""
|
||||
params = {p: v for p, v in params.items() if v}
|
||||
|
||||
query_str = get_querystring(params, [])
|
||||
url = f"http://0.0.0.0:8000/api/v1/famafrench/factors?{query_str}"
|
||||
result = requests.get(url, headers=headers, timeout=10)
|
||||
assert isinstance(result, requests.Response)
|
||||
assert result.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"params",
|
||||
[
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
}
|
||||
),
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
"portfolio": "5_industry_portfolios",
|
||||
"measure": "equal",
|
||||
"frequency": "annual",
|
||||
"start_date": None,
|
||||
"end_date": None,
|
||||
}
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.integration
|
||||
def test_famafrench_us_portfolio_returns(params, headers):
|
||||
"""Test the US portfolio returns endpoint."""
|
||||
params = {p: v for p, v in params.items() if v}
|
||||
|
||||
query_str = get_querystring(params, [])
|
||||
url = f"http://0.0.0.0:8000/api/v1/famafrench/us_portfolio_returns?{query_str}"
|
||||
result = requests.get(url, headers=headers, timeout=10)
|
||||
assert isinstance(result, requests.Response)
|
||||
assert result.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"params",
|
||||
[
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
}
|
||||
),
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
"portfolio": "developed_ex_us_6_portfolios_me_op",
|
||||
"measure": "equal",
|
||||
"frequency": "annual",
|
||||
"start_date": None,
|
||||
"end_date": None,
|
||||
}
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.integration
|
||||
def test_famafrench_regional_portfolio_returns(params, headers):
|
||||
"""Test the regional portfolio returns endpoint."""
|
||||
params = {p: v for p, v in params.items() if v}
|
||||
|
||||
query_str = get_querystring(params, [])
|
||||
url = (
|
||||
f"http://0.0.0.0:8000/api/v1/famafrench/regional_portfolio_returns?{query_str}"
|
||||
)
|
||||
result = requests.get(url, headers=headers, timeout=10)
|
||||
assert isinstance(result, requests.Response)
|
||||
assert result.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"params",
|
||||
[
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
}
|
||||
),
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
"country": "japan",
|
||||
"measure": "ratios",
|
||||
"frequency": None,
|
||||
"start_date": None,
|
||||
"end_date": None,
|
||||
"dividends": True,
|
||||
"all_data_items_required": True,
|
||||
}
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.integration
|
||||
def test_famafrench_country_portfolio_returns(params, headers):
|
||||
"""Test the country portfolio returns endpoint."""
|
||||
params = {p: v for p, v in params.items() if v}
|
||||
|
||||
query_str = get_querystring(params, [])
|
||||
url = f"http://0.0.0.0:8000/api/v1/famafrench/country_portfolio_returns?{query_str}"
|
||||
result = requests.get(url, headers=headers, timeout=10)
|
||||
assert isinstance(result, requests.Response)
|
||||
assert result.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"params",
|
||||
[
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
}
|
||||
),
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
"index": "asia_pacific",
|
||||
"measure": "local",
|
||||
"frequency": "annual",
|
||||
"start_date": None,
|
||||
"end_date": None,
|
||||
"dividends": True,
|
||||
"all_data_items_required": True,
|
||||
}
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.integration
|
||||
def test_famafrench_international_index_returns(params, headers):
|
||||
"""Test the international index returns endpoint."""
|
||||
params = {p: v for p, v in params.items() if v}
|
||||
|
||||
query_str = get_querystring(params, [])
|
||||
url = (
|
||||
f"http://0.0.0.0:8000/api/v1/famafrench/international_index_returns?{query_str}"
|
||||
)
|
||||
result = requests.get(url, headers=headers, timeout=10)
|
||||
assert isinstance(result, requests.Response)
|
||||
assert result.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"params",
|
||||
[
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
}
|
||||
),
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
"breakpoint_type": "op",
|
||||
"start_date": None,
|
||||
"end_date": None,
|
||||
}
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.integration
|
||||
def test_famafrench_breakpoints(params, headers):
|
||||
"""Test Fama-French breakpoints endpoint."""
|
||||
params = {p: v for p, v in params.items() if v}
|
||||
|
||||
query_str = get_querystring(params, [])
|
||||
url = f"http://0.0.0.0:8000/api/v1/famafrench/breakpoints?{query_str}"
|
||||
result = requests.get(url, headers=headers, timeout=10)
|
||||
assert isinstance(result, requests.Response)
|
||||
assert result.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"params",
|
||||
[
|
||||
(
|
||||
{
|
||||
"region": "america",
|
||||
"factor": "Momentum",
|
||||
"is_portfolio": None,
|
||||
"portfolio": None,
|
||||
}
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.integration
|
||||
def test_famafrench_factor_choices(params, headers):
|
||||
"""Test Fama-French available factors endpoint."""
|
||||
params = {p: v for p, v in params.items() if v}
|
||||
|
||||
query_str = get_querystring(params, [])
|
||||
url = f"http://0.0.0.0:8000/api/v1/famafrench/factor_choices?{query_str}"
|
||||
result = requests.get(url, headers=headers, timeout=10)
|
||||
assert isinstance(result, requests.Response)
|
||||
assert result.status_code == 200
|
||||
@@ -0,0 +1,227 @@
|
||||
"""Test Fama-French Python Interface."""
|
||||
|
||||
import pytest
|
||||
from openbb_core.app.model.obbject import OBBject
|
||||
|
||||
# pylint: disable=redefined-outer-name
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def obb(pytestconfig): # pylint: disable=inconsistent-return-statements
|
||||
"""Fixture to setup obb."""
|
||||
if pytestconfig.getoption("markexpr") != "not integration":
|
||||
import openbb # pylint: disable=import-outside-toplevel
|
||||
|
||||
return openbb.obb
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"params",
|
||||
[
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
}
|
||||
),
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
"region": "america",
|
||||
"factor": "momentum",
|
||||
"frequency": "monthly",
|
||||
"start_date": None,
|
||||
"end_date": None,
|
||||
}
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.integration
|
||||
def test_famafrench_factors(params, obb):
|
||||
"""Test the Fama-French factors endpoint."""
|
||||
params = {p: v for p, v in params.items() if v}
|
||||
|
||||
result = obb.famafrench.factors(**params)
|
||||
assert result
|
||||
assert isinstance(result, OBBject)
|
||||
assert len(result.results) > 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"params",
|
||||
[
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
}
|
||||
),
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
"portfolio": "5_industry_portfolios",
|
||||
"measure": "equal",
|
||||
"frequency": "annual",
|
||||
"start_date": None,
|
||||
"end_date": None,
|
||||
}
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.integration
|
||||
def test_famafrench_us_portfolio_returns(params, obb):
|
||||
"""Test the US portfolio returns endpoint."""
|
||||
params = {p: v for p, v in params.items() if v}
|
||||
|
||||
result = obb.famafrench.us_portfolio_returns(**params)
|
||||
assert result
|
||||
assert isinstance(result, OBBject)
|
||||
assert len(result.results) > 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"params",
|
||||
[
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
}
|
||||
),
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
"portfolio": "developed_ex_us_6_portfolios_me_op",
|
||||
"measure": "equal",
|
||||
"frequency": None,
|
||||
"start_date": None,
|
||||
"end_date": None,
|
||||
}
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.integration
|
||||
def test_famafrench_regional_portfolio_returns(params, obb):
|
||||
"""Test the regional portfolio returns endpoint."""
|
||||
params = {p: v for p, v in params.items() if v}
|
||||
|
||||
result = obb.famafrench.regional_portfolio_returns(**params)
|
||||
assert result
|
||||
assert isinstance(result, OBBject)
|
||||
assert len(result.results) > 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"params",
|
||||
[
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
}
|
||||
),
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
"country": "japan",
|
||||
"measure": "ratios",
|
||||
"frequency": None,
|
||||
"start_date": None,
|
||||
"end_date": None,
|
||||
"dividends": True,
|
||||
"all_data_items_required": True,
|
||||
}
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.integration
|
||||
def test_famafrench_country_portfolio_returns(params, obb):
|
||||
"""Test the country portfolio returns endpoint."""
|
||||
params = {p: v for p, v in params.items() if v}
|
||||
|
||||
result = obb.famafrench.country_portfolio_returns(**params)
|
||||
assert result
|
||||
assert isinstance(result, OBBject)
|
||||
assert len(result.results) > 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"params",
|
||||
[
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
}
|
||||
),
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
"index": "asia_pacific",
|
||||
"measure": "local",
|
||||
"frequency": "annual",
|
||||
"start_date": None,
|
||||
"end_date": None,
|
||||
"dividends": True,
|
||||
"all_data_items_required": True,
|
||||
}
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.integration
|
||||
def test_famafrench_international_index_returns(params, obb):
|
||||
"""Test the international index returns endpoint."""
|
||||
params = {p: v for p, v in params.items() if v}
|
||||
|
||||
result = obb.famafrench.international_index_returns(**params)
|
||||
assert result
|
||||
assert isinstance(result, OBBject)
|
||||
assert len(result.results) > 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"params",
|
||||
[
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
}
|
||||
),
|
||||
(
|
||||
{
|
||||
"provider": "famafrench",
|
||||
"breakpoint_type": "op",
|
||||
"start_date": None,
|
||||
"end_date": None,
|
||||
}
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.integration
|
||||
def test_famafrench_breakpoints(params, obb):
|
||||
"""Test the Fama-French breakpoints endpoint."""
|
||||
params = {p: v for p, v in params.items() if v}
|
||||
|
||||
result = obb.famafrench.breakpoints(**params)
|
||||
assert result
|
||||
assert isinstance(result, OBBject)
|
||||
assert len(result.results) > 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"params",
|
||||
[
|
||||
(
|
||||
{
|
||||
"region": "america",
|
||||
"factor": "Momentum",
|
||||
"is_portfolio": None,
|
||||
"portfolio": None,
|
||||
}
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.integration
|
||||
def test_famafrench_factor_choices(params, obb):
|
||||
"""Test Fama-French available factors endpoint."""
|
||||
params = {p: v for p, v in params.items() if v}
|
||||
|
||||
result = obb.famafrench.factor_choices(**params)
|
||||
assert result
|
||||
assert isinstance(result, list)
|
||||
assert len(result) > 0
|
||||
61
openbb_platform/providers/famafrench/README.md
vendored
Normal file
61
openbb_platform/providers/famafrench/README.md
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
# OpenBB Fama-French Extension
|
||||
|
||||
This extension implements the Ken French data library (Source: https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html)
|
||||
as an OpenBB Platform Provider and Router extension.
|
||||
|
||||
## Installation
|
||||
|
||||
Install this extension with:
|
||||
|
||||
```sh
|
||||
pip install openbb-famafrench
|
||||
```
|
||||
|
||||
## Coverage
|
||||
|
||||
The extension provides six API endpoints:
|
||||
|
||||
```python
|
||||
In [1]: from openbb import obb
|
||||
|
||||
In [2]: obb.famafrench
|
||||
Out[2]:
|
||||
/famafrench
|
||||
breakpoints
|
||||
country_portfolio_returns
|
||||
factor_choices <-- Utility function serving choices to the OpenBB Workspace widget
|
||||
factors
|
||||
international_index_returns
|
||||
regional_portfolio_returns
|
||||
us_portfolio_returns
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
The most common use will be for retrieving the 3 and 5-factor models, default state is 3-factors, at a monthly interval, for the United States.
|
||||
|
||||
```python
|
||||
from openbb import obb
|
||||
|
||||
factors = obb.famafrench.factors()
|
||||
```
|
||||
|
||||
Or, by region and factor:
|
||||
|
||||
```python
|
||||
momentum = obb.famafrench.factors(factor="momentum", region="europe")
|
||||
```
|
||||
|
||||
Metadata corresponding to the file downloaded is available under, `extra["results_metadata"]`, of the results object.
|
||||
|
||||
```python
|
||||
factors.extra["results_metadata"]
|
||||
|
||||
{
|
||||
'description': '### \n\nThis file was created using the 202504 CRSP database. The 1-month TBill rate data until 202405 are from Ibbotson Associates. Starting from 202406, the 1-month TBill rate is from ICE BofA US 1-Month Treasury Bill Index.\n\n',
|
||||
'frequency': 'monthly',
|
||||
'formations': ['Mkt-RF', 'SMB', 'HML', 'RF']
|
||||
}
|
||||
```
|
||||
|
||||
Refer to the endpoint's docstring for detailed descriptions.
|
||||
@@ -0,0 +1,36 @@
|
||||
"""OpenBB Fama-French Provider module."""
|
||||
|
||||
from openbb_core.provider.abstract.provider import Provider
|
||||
|
||||
from openbb_famafrench.models.breakpoints import FamaFrenchBreakpointFetcher
|
||||
from openbb_famafrench.models.country_portfolio_returns import (
|
||||
FamaFrenchCountryPortfolioReturnsFetcher,
|
||||
)
|
||||
from openbb_famafrench.models.factors import FamaFrenchFactorsFetcher
|
||||
from openbb_famafrench.models.international_index_returns import (
|
||||
FamaFrenchInternationalIndexReturnsFetcher,
|
||||
)
|
||||
from openbb_famafrench.models.regional_portfolio_returns import (
|
||||
FamaFrenchRegionalPortfolioReturnsFetcher,
|
||||
)
|
||||
from openbb_famafrench.models.us_portfolio_returns import (
|
||||
FamaFrenchUSPortfolioReturnsFetcher,
|
||||
)
|
||||
|
||||
famafrench_provider = Provider(
|
||||
name="famafrench",
|
||||
website="https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html",
|
||||
description="""
|
||||
This provider implements the Fama-French research portfolios and factors data library,
|
||||
maintained and hosted by Kenneth R. French at Dartmouth College.
|
||||
""",
|
||||
fetcher_dict={
|
||||
"FamaFrenchBreakpoints": FamaFrenchBreakpointFetcher,
|
||||
"FamaFrenchCountryPortfolioReturns": FamaFrenchCountryPortfolioReturnsFetcher,
|
||||
"FamaFrenchFactors": FamaFrenchFactorsFetcher,
|
||||
"FamaFrenchInternationalIndexReturns": FamaFrenchInternationalIndexReturnsFetcher,
|
||||
"FamaFrenchRegionalPortfolioReturns": FamaFrenchRegionalPortfolioReturnsFetcher,
|
||||
"FamaFrenchUSPortfolioReturns": FamaFrenchUSPortfolioReturnsFetcher,
|
||||
},
|
||||
repr_name="Fama-French Research Portfolios and Factors",
|
||||
)
|
||||
@@ -0,0 +1,518 @@
|
||||
# pylint: disable=import-outside-toplevel,unused-argument
|
||||
"""Fama-French Router."""
|
||||
|
||||
from typing import Annotated, Optional
|
||||
|
||||
from fastapi import Query as FastAPIQuery
|
||||
from openbb_core.app.model.command_context import CommandContext
|
||||
from openbb_core.app.model.example import APIEx
|
||||
from openbb_core.app.model.obbject import OBBject
|
||||
from openbb_core.app.provider_interface import (
|
||||
ExtraParams,
|
||||
ProviderChoices,
|
||||
StandardParams,
|
||||
)
|
||||
from openbb_core.app.query import Query as OpenBBQuery
|
||||
from openbb_core.app.router import Router
|
||||
|
||||
router = Router(prefix="", description="Fama-French research factors and portfolios.")
|
||||
|
||||
|
||||
@router.command(
|
||||
model="FamaFrenchFactors",
|
||||
methods=["GET"],
|
||||
examples=[
|
||||
APIEx(
|
||||
description="Fama-French 3-factors data for America, default is monthly.",
|
||||
parameters={
|
||||
"provider": "famafrench",
|
||||
},
|
||||
),
|
||||
APIEx(
|
||||
description="Fama-French 5-factors data for Europe.",
|
||||
parameters={
|
||||
"provider": "famafrench",
|
||||
"region": "europe",
|
||||
"factor": "5_factors",
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
async def factors(
|
||||
cc: CommandContext,
|
||||
provider_choices: ProviderChoices,
|
||||
standard_params: StandardParams,
|
||||
extra_params: ExtraParams,
|
||||
) -> OBBject:
|
||||
"""Fama-French factors.
|
||||
|
||||
Metadata for the selected dataset are returned in the
|
||||
`extra['results_metadata']` field of the response.
|
||||
|
||||
Source
|
||||
------
|
||||
|
||||
https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html
|
||||
|
||||
All returns are in U.S. dollars, include dividends and capital gains,
|
||||
and are not continuously compounded.
|
||||
|
||||
Market is the return on a region's value-weight market portfolio
|
||||
minus the U.S. one month T-bill rate.
|
||||
|
||||
The Fama/French 5 factors (2x3) are constructed using the 6,
|
||||
value-weight, portfolios formed on size and book-to-market, the 6,
|
||||
value-weight, portfolios formed on size and operating profitability,
|
||||
and the 6, value-weight, portfolios formed on size and investment.
|
||||
|
||||
To construct the SMB, HML, RMW, and CMA factors, we sort stocks in a
|
||||
region into two market cap and three respective book-to-market equity (B/M),
|
||||
operating profitability (OP), and investment (INV) groups at the end of each June.
|
||||
|
||||
Big stocks are those in the top 90% of June market cap for the region,
|
||||
and small stocks are those in the bottom 10%.
|
||||
The B/M, OP, and INV breakpoints for a region are the 30th and 70th percentiles
|
||||
of respective ratios for the big stocks of the region.
|
||||
|
||||
Rm–Rf for July of year t to June of t+1 include all stocks
|
||||
for which we have market equity data for June of t.
|
||||
SMB, HML, RMW, and CMA for July of year t to June of t+1 include all stocks
|
||||
for which we have market equity data for December of t-1
|
||||
and June of t, (positive) book equity data for t-1 (for SMB, HML, and RMW),
|
||||
non-missing revenues and at least one of the following: cost of goods sold,
|
||||
selling, general and administrative expenses, or interest expense for
|
||||
t-1 (for SMB and RMW), and total assets data for t-2 and t-1 (for SMB and CMA).
|
||||
|
||||
The momentum and short term reversal portfolios are reconstituted monthly
|
||||
and the other research portfolios are reconstituted annually.
|
||||
We reconstruct the full history of returns each month when we update the portfolios.
|
||||
"""
|
||||
return await OBBject.from_query(OpenBBQuery(**locals()))
|
||||
|
||||
|
||||
@router.command(
|
||||
methods=["GET"],
|
||||
include_in_schema=False,
|
||||
openapi_extra={"widget_config": {"exclude": True}},
|
||||
examples=[
|
||||
APIEx(
|
||||
description="Get region choices.",
|
||||
parameters={
|
||||
"provider": "famafrench",
|
||||
},
|
||||
),
|
||||
APIEx(
|
||||
description="Get factor choices by region.",
|
||||
parameters={
|
||||
"provider": "famafrench",
|
||||
"region": "europe",
|
||||
},
|
||||
),
|
||||
APIEx(
|
||||
description="Get interval choices for factors by region.",
|
||||
parameters={
|
||||
"provider": "famafrench",
|
||||
"region": "europe",
|
||||
"factor": "5_Factors",
|
||||
},
|
||||
),
|
||||
APIEx(
|
||||
description="Get regional choices by portfolio.",
|
||||
parameters={
|
||||
"provider": "famafrench",
|
||||
"portfolio": "6 Portfolios ME BE-ME",
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
async def factor_choices(
|
||||
region: Annotated[
|
||||
Optional[str],
|
||||
FastAPIQuery(description="Region to get factor choices for."),
|
||||
] = None,
|
||||
factor: Annotated[
|
||||
Optional[str],
|
||||
FastAPIQuery(
|
||||
description="Factor to get interval choices for.",
|
||||
),
|
||||
] = None,
|
||||
is_portfolio: Annotated[
|
||||
Optional[bool],
|
||||
FastAPIQuery(
|
||||
description="When True, returns portfolio choices by region.",
|
||||
),
|
||||
] = None,
|
||||
portfolio: Annotated[
|
||||
Optional[str],
|
||||
FastAPIQuery(
|
||||
description="When supplied, returns regional choices for the portfolio.",
|
||||
),
|
||||
] = None,
|
||||
) -> list:
|
||||
"""
|
||||
Endpoint (optionsEndpoint) for providing dynamic menu choices to OpenBB Workspace widgets.
|
||||
|
||||
Intended to be referenced in 'widgets.json', and returns a list of {'value': str, 'label': str}.
|
||||
"""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from openbb_famafrench.utils.helpers import get_factor_choices
|
||||
|
||||
return await get_factor_choices(
|
||||
region=region,
|
||||
factor=factor,
|
||||
is_portfolio=is_portfolio is True,
|
||||
portfolio=portfolio,
|
||||
)
|
||||
|
||||
|
||||
@router.command(
|
||||
model="FamaFrenchUSPortfolioReturns",
|
||||
methods=["GET"],
|
||||
examples=[
|
||||
APIEx(
|
||||
description="Get model US portfolio returns "
|
||||
+ "used for constructing the Fama-French Factor models.",
|
||||
parameters={
|
||||
"provider": "famafrench",
|
||||
},
|
||||
),
|
||||
APIEx(
|
||||
description="If the portfolio name does not have a frequency - i.e."
|
||||
+ " '_daily' - use the frequency parameter to specify the interval.",
|
||||
parameters={
|
||||
"provider": "famafrench",
|
||||
"portfolio": "5_industry_portfolios_wout_div",
|
||||
"frequency": "annual",
|
||||
"measure": "equal",
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
async def us_portfolio_returns(
|
||||
cc: CommandContext,
|
||||
provider_choices: ProviderChoices,
|
||||
standard_params: StandardParams,
|
||||
extra_params: ExtraParams,
|
||||
) -> OBBject:
|
||||
"""US Portfolio returns.
|
||||
|
||||
Metadata for the selected dataset are returned in the
|
||||
`extra['results_metadata']` field of the response.
|
||||
|
||||
Source
|
||||
------
|
||||
|
||||
https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html
|
||||
|
||||
All returns are in U.S. dollars, include dividends (unless the portfolio is 'wout_div')
|
||||
and capital gains, and are not continuously compounded.
|
||||
|
||||
|
||||
The momentum and short term reversal portfolios are reconstituted monthly
|
||||
and the other research portfolios are reconstituted annually.
|
||||
We reconstruct the full history of returns each month when we update the portfolios.
|
||||
|
||||
|
||||
Size and Book-to-Market Portfolios
|
||||
----------------------------------
|
||||
|
||||
- Small Value
|
||||
- Small Neutral
|
||||
- Small Growth
|
||||
- Big Value
|
||||
- Big Neutral
|
||||
- Big Growth
|
||||
|
||||
BE < 0; bottom 30%, middle 40%, top 30%; quintiles; deciles.
|
||||
Firms with negative book equity are in only the BE < 0 portfolio.
|
||||
|
||||
Size and Operating Profitability Portfolios
|
||||
-------------------------------------------
|
||||
|
||||
- Small Robust
|
||||
- Small Neutral
|
||||
- Small Weak
|
||||
- Big Robust
|
||||
- Big Neutral
|
||||
- Big Weak
|
||||
|
||||
Operating Profitability bottom 30%, middle 40%, top 30%; quintiles; deciles.
|
||||
|
||||
Size and Investment Portfolios
|
||||
------------------------------
|
||||
|
||||
- Small Conservative
|
||||
- Small Neutral
|
||||
- Small Aggressive
|
||||
- Big Conservative
|
||||
- Big Neutral
|
||||
- Big Aggressive
|
||||
|
||||
ME < 0 (not used); bottom 30%, middle 40%, top 30%; quintiles; deciles.
|
||||
Investment bottom 30%, middle 40%, top 30%; quintiles; deciles.
|
||||
|
||||
Definitions
|
||||
-----------
|
||||
|
||||
ME : Market Equity
|
||||
|
||||
Market equity (size) is price times shares outstanding.
|
||||
Price and shares outstanding are from CRSP.
|
||||
|
||||
BE : Book Equity
|
||||
|
||||
Book equity is constructed from Compustat data or collected from the
|
||||
Moody’s Industrial, Financial, and Utilities manuals.
|
||||
BE is the book value of stockholders’ equity, plus balance sheet deferred taxes
|
||||
and investment tax credit (if available), minus the book value of preferred stock.
|
||||
Depending on availability, we use the redemption, liquidation, or par value (in that order)
|
||||
to estimate the book value of preferred stock. Stockholders’ equity is the value reported
|
||||
by Moody’s or Compustat, if it is available. If not, we measure stockholders’ equity as
|
||||
the book value of common equity plus the par value of preferred stock,
|
||||
or the book value of assets minus total liabilities (in that order).
|
||||
|
||||
See Davis, Fama, and French, 2000,
|
||||
“Characteristics, Covariances, and Average Returns: 1929-1997”
|
||||
Journal of Finance, for more details.
|
||||
|
||||
BE/ME : Book-to-Market
|
||||
|
||||
The book-to-market ratio used to form portfolios in June of year t is book equity
|
||||
for the fiscal year ending in calendar year t-1,
|
||||
divided by market equity at the end of December of t-1.
|
||||
|
||||
OP : Operating Profitability
|
||||
|
||||
The operating profitability ratio used to form portfolios in June of year t is annual revenues
|
||||
minus cost of goods sold, interest expense, and selling, general, and administrative expense
|
||||
divided by the sum of book equity and minority interest for the last fiscal year ending in t-1.
|
||||
|
||||
INV : Investment
|
||||
|
||||
The investment ratio used to form portfolios in June of year t is the change in total assets
|
||||
from the fiscal year ending in year t-2 to the fiscal year ending in t-1,
|
||||
divided by t-2 total assets.
|
||||
|
||||
E/P : Earnings/Price
|
||||
|
||||
Earnings is total earnings before extraordinary items, from Compustat.
|
||||
The earnings/price ratio used to form portfolios in June of year t is earnings
|
||||
for the fiscal year ending in calendar year t-1,
|
||||
divided by market equity at the end of December of t-1.
|
||||
|
||||
CF/P : Cashflow/Price
|
||||
|
||||
Cashflow is total earnings before extraordinary items, plus equity’s share of depreciation,
|
||||
plus deferred taxes (if available), from Compustat. Equity’s share is defined as market equity
|
||||
divided by assets minus book equity plus market equity.
|
||||
The cashflow/price ratio used to form portfolios in June of year t is the cashflow for the
|
||||
fiscal year ending in calendar year t-1, divided by market equity at the end of December of t-1.
|
||||
|
||||
D/P : Dividend Yield
|
||||
|
||||
The dividend yield used to form portfolios in June of year t is the total dividends paid
|
||||
from July of t-1 to June of t per dollar of equity in June of t.
|
||||
The dividend yield is computed using the with and without dividend returns from CRSP,
|
||||
as described in Fama and French, 1988, “Dividend yields and expected stock returns,”
|
||||
Journal of Financial Economics 25.
|
||||
"""
|
||||
return await OBBject.from_query(OpenBBQuery(**locals()))
|
||||
|
||||
|
||||
@router.command(
|
||||
model="FamaFrenchRegionalPortfolioReturns",
|
||||
methods=["GET"],
|
||||
examples=[
|
||||
APIEx(
|
||||
description="Get model Regional portfolio returns "
|
||||
+ "used for constructing the Fama-French Factor models.",
|
||||
parameters={
|
||||
"provider": "famafrench",
|
||||
},
|
||||
),
|
||||
APIEx(
|
||||
description="Get portfolios formed by equal-weight, with annual returns.",
|
||||
parameters={
|
||||
"provider": "famafrench",
|
||||
"frequency": "annual",
|
||||
"measure": "equal",
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
async def regional_portfolio_returns(
|
||||
cc: CommandContext,
|
||||
provider_choices: ProviderChoices,
|
||||
standard_params: StandardParams,
|
||||
extra_params: ExtraParams,
|
||||
) -> OBBject:
|
||||
"""Regional portfolio returns.
|
||||
|
||||
Metadata for the selected dataset are returned in the
|
||||
`extra['results_metadata']` field of the response.
|
||||
|
||||
See the `us_portfolio_returns` endpoint for more details.
|
||||
"""
|
||||
return await OBBject.from_query(OpenBBQuery(**locals()))
|
||||
|
||||
|
||||
@router.command(
|
||||
model="FamaFrenchCountryPortfolioReturns",
|
||||
methods=["GET"],
|
||||
examples=[
|
||||
APIEx(
|
||||
description="Get model Country portfolio returns "
|
||||
+ "used for constructing the Fama-French Factor models.",
|
||||
parameters={
|
||||
"provider": "famafrench",
|
||||
},
|
||||
),
|
||||
APIEx(
|
||||
description="Parameters are different than the regional and US portfolio returns.",
|
||||
parameters={
|
||||
"provider": "famafrench",
|
||||
"frequency": "annual",
|
||||
"measure": "local",
|
||||
"country": "japan",
|
||||
"dividends": False,
|
||||
"all_data_items_required": False,
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
async def country_portfolio_returns(
|
||||
cc: CommandContext,
|
||||
provider_choices: ProviderChoices,
|
||||
standard_params: StandardParams,
|
||||
extra_params: ExtraParams,
|
||||
) -> OBBject:
|
||||
"""Country portfolio returns.
|
||||
|
||||
Metadata for the selected dataset are returned in the
|
||||
`extra['results_metadata']` field of the response.
|
||||
|
||||
Source
|
||||
------
|
||||
|
||||
https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html
|
||||
|
||||
We form value and growth portfolios in each country using four valuation ratios:
|
||||
|
||||
- book-to-market (B/M)
|
||||
- earnings-price (E/P)
|
||||
- cash earnings to price (CE/P)
|
||||
- dividend yield (D/P)
|
||||
|
||||
We form the portfolios at the end of December each year by sorting on one of the four ratios and
|
||||
then compute value-weighted returns for the following 12 months.
|
||||
|
||||
The value portfolios (High) contain firms in the top 30% of a ratio
|
||||
and the growth portfolios (Low) contain firms in the bottom 30%.
|
||||
|
||||
There are two sets of portfolios.
|
||||
|
||||
In one, firms are included only if we have data on all four ratios.
|
||||
|
||||
In the other, a firm is included in a sort variable's portfolios
|
||||
if we have data for that variable.
|
||||
|
||||
The market return (Mkt) for the first set is the value weighted average of the returns
|
||||
for only firms with all four ratios.
|
||||
|
||||
The market return for the second set includes all firms with book-to-market data,
|
||||
and Firms is the number of firms with B/M data.
|
||||
"""
|
||||
return await OBBject.from_query(OpenBBQuery(**locals()))
|
||||
|
||||
|
||||
@router.command(
|
||||
model="FamaFrenchInternationalIndexReturns",
|
||||
methods=["GET"],
|
||||
examples=[
|
||||
APIEx(
|
||||
description="Get benchmark index returns "
|
||||
+ "used for constructing the international Fama-French Factor models.",
|
||||
parameters={
|
||||
"provider": "famafrench",
|
||||
},
|
||||
),
|
||||
APIEx(
|
||||
description="Parameters are similar to the country portfolio returns.",
|
||||
parameters={
|
||||
"provider": "famafrench",
|
||||
"frequency": "annual",
|
||||
"measure": "ratios",
|
||||
"index": "europe_ex_uk",
|
||||
"dividends": False,
|
||||
"all_data_items_required": False,
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
async def international_index_returns(
|
||||
cc: CommandContext,
|
||||
provider_choices: ProviderChoices,
|
||||
standard_params: StandardParams,
|
||||
extra_params: ExtraParams,
|
||||
) -> OBBject:
|
||||
"""International index returns.
|
||||
|
||||
Metadata for the selected dataset are returned in the
|
||||
`extra['results_metadata']` field of the response.
|
||||
|
||||
See the `country_portfolio_returns` endpoint for more details.
|
||||
|
||||
Source
|
||||
------
|
||||
|
||||
https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html
|
||||
|
||||
The returns on the index portfolios are constructed by
|
||||
averaging the returns on the country portfolios.
|
||||
|
||||
We weight countries in the index portfolios in proportion to their EAFE + Canada weights.
|
||||
|
||||
Each country is added to the index portfolios when the return data for the country begin;
|
||||
the country start dates can be inferred from the country return files.
|
||||
"""
|
||||
return await OBBject.from_query(OpenBBQuery(**locals()))
|
||||
|
||||
|
||||
@router.command(
|
||||
model="FamaFrenchBreakpoints",
|
||||
methods=["GET"],
|
||||
examples=[
|
||||
APIEx(
|
||||
description="Get US breakpoints "
|
||||
+ "used for constructing the research portfolios.",
|
||||
parameters={
|
||||
"provider": "famafrench",
|
||||
},
|
||||
),
|
||||
APIEx(
|
||||
description="See the parameters description for details on the breakpoints.",
|
||||
parameters={
|
||||
"provider": "famafrench",
|
||||
"breakpoint": "op",
|
||||
"start_date": "1998-01-01",
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
async def breakpoints(
|
||||
cc: CommandContext,
|
||||
provider_choices: ProviderChoices,
|
||||
standard_params: StandardParams,
|
||||
extra_params: ExtraParams,
|
||||
) -> OBBject:
|
||||
"""Fama-French breakpoints.
|
||||
|
||||
Metadata for the selected dataset are returned in the
|
||||
`extra['results_metadata']` field of the response.
|
||||
|
||||
Source
|
||||
------
|
||||
|
||||
https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html#Breakpoints
|
||||
"""
|
||||
return await OBBject.from_query(OpenBBQuery(**locals()))
|
||||
@@ -0,0 +1 @@
|
||||
"""OpenBB Fama-French Models."""
|
||||
@@ -0,0 +1,306 @@
|
||||
"""Fama-French Breakpoints Model."""
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
|
||||
from datetime import date as dateType
|
||||
from typing import Any, Optional
|
||||
|
||||
from openbb_core.app.model.abstract.error import OpenBBError
|
||||
from openbb_core.provider.abstract.annotated_result import AnnotatedResult
|
||||
from openbb_core.provider.abstract.data import Data
|
||||
from openbb_core.provider.abstract.fetcher import Fetcher
|
||||
from openbb_core.provider.abstract.query_params import QueryParams
|
||||
from pydantic import Field
|
||||
|
||||
from openbb_famafrench.utils.constants import (
|
||||
BREAKPOINT_CHOICES,
|
||||
BreakpointChoices,
|
||||
)
|
||||
|
||||
|
||||
class FamaFrenchBreakpointQueryParams(QueryParams):
|
||||
"""Fama-French Breakpoints Query."""
|
||||
|
||||
__json_schema_extra__ = {
|
||||
"breakpoint_type": {
|
||||
"choices": BREAKPOINT_CHOICES,
|
||||
}
|
||||
}
|
||||
|
||||
breakpoint_type: BreakpointChoices = Field(
|
||||
default="me",
|
||||
description="""Type of breakpoint to fetch.
|
||||
|
||||
The breakpoints for month t use all NYSE stocks that have a CRSP share code of 10 or 11
|
||||
and have good shares and price data. We exclude closed end funds and REITs.
|
||||
|
||||
Breakpoints are computed either monthly or annually, see the description of each breakpoint type below.
|
||||
|
||||
Data contains every fifth percentile, from 5% to 100%.
|
||||
|
||||
ME
|
||||
--
|
||||
|
||||
Market Equity. Market equity (size) is price times shares outstanding.
|
||||
Price and shares outstanding are from CRSP.
|
||||
|
||||
ME breakpoints are computed for each month.
|
||||
It is price times shares outstanding (divided by 1,000,000) at month end.
|
||||
|
||||
BE/ME
|
||||
-----
|
||||
|
||||
BE/ME breakpoints are computed at the end of each June.
|
||||
The BE used in June of year t is the book equity for the last fiscal year end in t-1.
|
||||
ME is price times shares outstanding at the end of December of t-1.
|
||||
|
||||
The breakpoints for year t use all NYSE stocks for which we have ME for December of t-1
|
||||
and (positive) BE for the last fiscal year end in t-1.
|
||||
|
||||
Operating Profitability
|
||||
-----------------------
|
||||
|
||||
Operating Profitability breakpoints are computed at the end of each June.
|
||||
OP for June of year t is annual revenues minus
|
||||
|
||||
- cost of goods sold
|
||||
- interest expense
|
||||
- selling, general, and administrative expenses
|
||||
|
||||
divided by book equity for the last fiscal year end in t-1.
|
||||
|
||||
Please be aware that some of the value-weight averages of operating profitability for deciles 1 and 10 are extreme.
|
||||
These are driven by extraordinary values of OP for individual firms.
|
||||
We have spot checked the accounting data that produce the extraordinary values
|
||||
and all the numbers we examined accurately reflect the data in the firm's accounting statements.
|
||||
|
||||
The breakpoints for year t use all NYSE stocks for which we have (positive) book equity data for t-1,
|
||||
non-missing revenues data for t-1, and non-missing data for at least one of the following:
|
||||
|
||||
- cost of goods sold
|
||||
- selling, general and administrative expenses
|
||||
- interest expense for t-1.
|
||||
|
||||
Investment
|
||||
----------
|
||||
|
||||
Investment breakpoints are computed at the end of each June.
|
||||
Inv used in June of year t is the change in total assets from the fiscal year ending in year t-2
|
||||
to the fiscal year ending in t-1, divided by t-2 total assets.
|
||||
|
||||
The breakpoints for year t use all NYSE stocks for which we have total assets data for t-2 and t-1.
|
||||
|
||||
E/P
|
||||
---
|
||||
|
||||
E/P (in percent) breakpoints are computed at the end of each June.
|
||||
The E used in June of year t is the earnings for the last fiscal year end in t-1.
|
||||
P (actually ME) is price times shares outstanding at the end of December of t-1.
|
||||
|
||||
The breakpoints for year t use all NYSE stocks for which we have ME for December of t-1
|
||||
and (positive) earnings for the last fiscal year end in t-1.
|
||||
|
||||
CF/P
|
||||
----
|
||||
|
||||
CF/P (in percent) breakpoints is computed at the end of each June.
|
||||
The CF used in June of year t is the cash flow for the last fiscal year end in t-1.
|
||||
P (actually ME) is price times shares outstanding at the end of December of t-1.
|
||||
|
||||
The breakpoints for year t use all NYSE stocks for which we have ME for December of t-1
|
||||
and (positive) cash flow for the last fiscal year end in t-1.
|
||||
|
||||
D/P
|
||||
---
|
||||
|
||||
D/P (in percent) breakpoints are computed at the end of each June.
|
||||
The dividend yield in June of year t is the total dividends paid from July of t-1
|
||||
to June of t per dollar of equity in June of t.
|
||||
|
||||
The breakpoints for year t use NYSE stocks for which we have at least
|
||||
seven months (to compute the dividend yield) from July of t-1 to June of t.
|
||||
(Only six monthly returns are required in June 1926.)
|
||||
We do not include stocks that pay no dividends from July of t-1 to June of t.
|
||||
|
||||
Prior 2-12
|
||||
----------
|
||||
|
||||
Prior return breakpoints are computed for each month.
|
||||
The prior return at the end of month t is the cumulative return from month t-11 to month t-1.
|
||||
|
||||
The breakpoints for month t use NYSE stocks.
|
||||
To be included, a stock must have a price for the end of month t-12 and a good return for t-1.
|
||||
In addition, any missing returns from t-11 to t-2 must be -99.0, CRSP's code for a missing price.
|
||||
""",
|
||||
)
|
||||
|
||||
start_date: Optional[dateType] = Field(
|
||||
default=None,
|
||||
description="Start date for the data.",
|
||||
)
|
||||
end_date: Optional[dateType] = Field(
|
||||
default=None,
|
||||
description="End date for the data.",
|
||||
)
|
||||
|
||||
|
||||
class FamaFrenchBreakpointData(Data):
|
||||
"""Fama-French Breakpoints Data."""
|
||||
|
||||
date: dateType = Field(
|
||||
description="Date of the data.",
|
||||
)
|
||||
num_firms: Optional[int] = Field(
|
||||
default=None,
|
||||
description="Number of firms in the sample. Not returned for BE/ME breakpoints.",
|
||||
)
|
||||
num_firms_less_than_0: Optional[int] = Field(
|
||||
default=None,
|
||||
description="Number of firms with ratio less than or equal to 0."
|
||||
+ " This is only applicable for ratio breakpoints.",
|
||||
)
|
||||
num_firms_greater_than_0: Optional[int] = Field(
|
||||
default=None,
|
||||
description="Number of firms with ratio greater than 0."
|
||||
+ " This is only applicable for ratio breakpoints.",
|
||||
)
|
||||
percentile_5: float = Field(
|
||||
description="Fifth percentile of the sample.",
|
||||
title="5th Percentile",
|
||||
)
|
||||
percentile_10: float = Field(
|
||||
description="Tenth percentile of the sample.",
|
||||
title="10th Percentile",
|
||||
)
|
||||
percentile_15: float = Field(
|
||||
description="Fifteenth percentile of the sample.",
|
||||
title="15th Percentile",
|
||||
)
|
||||
percentile_20: float = Field(
|
||||
description="Twentieth percentile of the sample.",
|
||||
title="20th Percentile",
|
||||
)
|
||||
percentile_25: float = Field(
|
||||
description="Twenty-fifth percentile of the sample.",
|
||||
title="25th Percentile",
|
||||
)
|
||||
percentile_30: float = Field(
|
||||
description="Thirtieth percentile of the sample.",
|
||||
title="30th Percentile",
|
||||
)
|
||||
percentile_35: float = Field(
|
||||
description="Thirty-fifth percentile of the sample.",
|
||||
title="35th Percentile",
|
||||
)
|
||||
percentile_40: float = Field(
|
||||
description="Fortieth percentile of the sample.",
|
||||
title="40th Percentile",
|
||||
)
|
||||
percentile_45: float = Field(
|
||||
description="Forty-fifth percentile of the sample.",
|
||||
title="45th Percentile",
|
||||
)
|
||||
percentile_50: float = Field(
|
||||
description="Fiftieth percentile of the sample.",
|
||||
title="50th Percentile",
|
||||
)
|
||||
percentile_55: float = Field(
|
||||
description="Fifty-fifth percentile of the sample.",
|
||||
title="55th Percentile",
|
||||
)
|
||||
percentile_60: float = Field(
|
||||
description="Sixtieth percentile of the sample.",
|
||||
title="60th Percentile",
|
||||
)
|
||||
percentile_65: float = Field(
|
||||
description="Sixty-fifth percentile of the sample.",
|
||||
title="65th Percentile",
|
||||
)
|
||||
percentile_70: float = Field(
|
||||
description="Seventieth percentile of the sample.",
|
||||
title="70th Percentile",
|
||||
)
|
||||
percentile_75: float = Field(
|
||||
description="Seventy-fifth percentile of the sample.",
|
||||
title="75th Percentile",
|
||||
)
|
||||
percentile_80: float = Field(
|
||||
description="Eightieth percentile of the sample.",
|
||||
title="80th Percentile",
|
||||
)
|
||||
percentile_85: float = Field(
|
||||
description="Eighty-fifth percentile of the sample.",
|
||||
title="85th Percentile",
|
||||
)
|
||||
percentile_90: float = Field(
|
||||
description="Ninetieth percentile of the sample.",
|
||||
title="90th Percentile",
|
||||
)
|
||||
percentile_95: float = Field(
|
||||
description="Ninety-fifth percentile of the sample.",
|
||||
title="95th Percentile",
|
||||
)
|
||||
percentile_100: float = Field(
|
||||
description="Hundredth percentile of the sample.",
|
||||
title="100th Percentile",
|
||||
)
|
||||
|
||||
|
||||
class FamaFrenchBreakpointFetcher(
|
||||
Fetcher[FamaFrenchBreakpointQueryParams, list[FamaFrenchBreakpointData]]
|
||||
):
|
||||
"""Fama-French Breakpoints Fetcher."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(
|
||||
params: dict[str, Any],
|
||||
) -> FamaFrenchBreakpointQueryParams:
|
||||
"""Transform the query parameters into a QueryParams object."""
|
||||
return FamaFrenchBreakpointQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
async def aextract_data(
|
||||
query: FamaFrenchBreakpointQueryParams,
|
||||
credentials: Optional[dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> tuple:
|
||||
"""Extract data from the Fama-French FTP."""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from openbb_famafrench.utils.helpers import get_breakpoint_data
|
||||
|
||||
try:
|
||||
return get_breakpoint_data(
|
||||
breakpoint_type=query.breakpoint_type,
|
||||
)
|
||||
except Exception as e:
|
||||
raise OpenBBError(e) from e
|
||||
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
query: FamaFrenchBreakpointQueryParams,
|
||||
data: tuple,
|
||||
**kwargs: Any,
|
||||
) -> AnnotatedResult[list[FamaFrenchBreakpointData]]:
|
||||
"""Transform the extracted data."""
|
||||
dfs, meta = data
|
||||
|
||||
if not dfs:
|
||||
raise OpenBBError(
|
||||
f"The data is unexpectedly empty. -> {query.breakpoint_type}"
|
||||
)
|
||||
|
||||
df = dfs[0]
|
||||
metadata = meta[0]
|
||||
|
||||
if query.start_date:
|
||||
df = df[df["date"] >= query.start_date.strftime("%Y-%m-%d")]
|
||||
|
||||
if query.end_date:
|
||||
df = df[df["date"] <= query.end_date.strftime("%Y-%m-%d")]
|
||||
|
||||
return AnnotatedResult(
|
||||
result=[
|
||||
FamaFrenchBreakpointData(**d) for d in df.to_dict(orient="records")
|
||||
],
|
||||
metadata={"description": metadata},
|
||||
)
|
||||
@@ -0,0 +1,319 @@
|
||||
"""Fama-French Factors Fetcher Model."""
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
|
||||
from datetime import date as dateType
|
||||
from typing import Any, Literal, Optional
|
||||
|
||||
from openbb_core.app.model.abstract.error import OpenBBError
|
||||
from openbb_core.provider.abstract.annotated_result import AnnotatedResult
|
||||
from openbb_core.provider.abstract.data import Data
|
||||
from openbb_core.provider.abstract.fetcher import Fetcher
|
||||
from openbb_core.provider.abstract.query_params import QueryParams
|
||||
from pydantic import Field
|
||||
|
||||
from openbb_famafrench.utils.constants import CountryPortfolios
|
||||
|
||||
|
||||
class FamaFrenchCountryPortfolioReturnsQueryParams(QueryParams):
|
||||
"""Country Portfolio Returns Query parameters."""
|
||||
|
||||
__json_schema_extra__ = {
|
||||
"country": {
|
||||
"x-widget_config": {
|
||||
"options": [
|
||||
{"value": d, "label": d.replace("_", " ").title()}
|
||||
for d in getattr(CountryPortfolios, "__args__", [])
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
country: CountryPortfolios = Field(
|
||||
default="united_kingdom",
|
||||
description="Country to fetch the portfolio returns for.",
|
||||
)
|
||||
measure: Literal[
|
||||
"usd",
|
||||
"local",
|
||||
"ratios",
|
||||
] = Field(
|
||||
default="usd",
|
||||
description="The measure to fetch for the portfolio."
|
||||
+ " Only 'annual' frequency is supported for 'ratios'.",
|
||||
)
|
||||
frequency: Literal["monthly", "annual"] = Field(
|
||||
default="monthly",
|
||||
description="The frequency of the data to fetch."
|
||||
+ " Ignored when `measure` is set to 'ratios'.",
|
||||
)
|
||||
dividends: Optional[bool] = Field(
|
||||
default=None, description="When False, portoflios exclude dividends."
|
||||
)
|
||||
all_data_items_required: Optional[bool] = Field(
|
||||
default=None,
|
||||
description="If True (default), includes firms with data for all four ratios."
|
||||
+ " When False, includes only firms with Book-to-Market (B/M) data.",
|
||||
)
|
||||
start_date: Optional[dateType] = Field(
|
||||
default=None,
|
||||
description="The start date for the data. Defaults to the earliest available date.",
|
||||
)
|
||||
end_date: Optional[dateType] = Field(
|
||||
default=None,
|
||||
description="The end date for the data. Defaults to the latest available date.",
|
||||
)
|
||||
|
||||
|
||||
class FamaFrenchCountryPortfolioReturnsData(Data):
|
||||
"""US Portfolio Returns Data."""
|
||||
|
||||
__alias_dict__ = {
|
||||
"date": "Date",
|
||||
"mkt": "Mkt",
|
||||
"firms": "Firms",
|
||||
"bm": "B/M",
|
||||
"be_me_high": "BE/ME High",
|
||||
"be_me_low": "BE/ME Low",
|
||||
"ep": "E/P",
|
||||
"e_p_high": "E/P High",
|
||||
"e_p_low": "E/P Low",
|
||||
"ce_p": "CE/P",
|
||||
"ce_p_high": "CE/P High",
|
||||
"ce_p_low": "CE/P Low",
|
||||
"yld": "Yld",
|
||||
"yld_high": "Yld High",
|
||||
"yld_low": "Yld Low",
|
||||
"yld_zero": "Yld Zero",
|
||||
}
|
||||
|
||||
date: dateType = Field(
|
||||
description="The date of the data.",
|
||||
)
|
||||
mkt: Optional[float] = Field(
|
||||
default=None,
|
||||
description="""
|
||||
The market return (Mkt) for the first set is the value weighted average
|
||||
of the returns for only firms with all four ratios.
|
||||
|
||||
The market return for the second set includes all firms with book-to-market data,
|
||||
and Firms is the number of firms with B/M data.
|
||||
|
||||
Not returned if `measure` is set to 'ratios'.
|
||||
""",
|
||||
)
|
||||
firms: Optional[int] = Field(
|
||||
default=None,
|
||||
description="The number of firms, relative to `all_data_items_required` parameter."
|
||||
+ " Only returned when `measure` is set to 'ratios'.",
|
||||
)
|
||||
bm: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Book to Market equity ratio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="B/M",
|
||||
)
|
||||
be_me_high: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Book Equity to Market Equity returns for the value portfolio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="BE/ME High",
|
||||
)
|
||||
be_me_low: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Book Equity to Market Equity returns for the growth portfolio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="BE/ME Low",
|
||||
)
|
||||
ep: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Earnings to Price ratio."
|
||||
+ " Only returned when `measure` is set to 'ratios'.",
|
||||
title="E/P",
|
||||
)
|
||||
e_p_high: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Earnings to Price returns for the value portfolio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="E/P High",
|
||||
)
|
||||
e_p_low: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Earnings to Price returns for the growth portfolio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="E/P Low",
|
||||
)
|
||||
ce_p: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Cash Earnings to Price ratio."
|
||||
+ " Only returned when `measure` is set to 'ratios'.",
|
||||
title="CE/P",
|
||||
)
|
||||
ce_p_high: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Cash Earnings to Price returns for the value portfolio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="CE/P High",
|
||||
)
|
||||
ce_p_low: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Cash Earnings to Price returns for the growth portfolio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="CE/P Low",
|
||||
)
|
||||
yld: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Dividend Yield ratio."
|
||||
+ " Only returned when `measure` is set to 'ratios'.",
|
||||
title="Yld",
|
||||
)
|
||||
yld_high: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Dividend Yield returns for the value portfolio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="Yld High",
|
||||
)
|
||||
yld_low: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Dividend Yield returns for the growth portfolio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="Yld Low",
|
||||
)
|
||||
yld_zero: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Dividend Yield returns for firms not paying dividends."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="Yld Zero",
|
||||
)
|
||||
|
||||
|
||||
class FamaFrenchCountryPortfolioReturnsFetcher(
|
||||
Fetcher[
|
||||
FamaFrenchCountryPortfolioReturnsQueryParams,
|
||||
list[FamaFrenchCountryPortfolioReturnsData],
|
||||
]
|
||||
):
|
||||
"""Country Portfolio Returns Fetcher."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(
|
||||
params: dict[str, Any],
|
||||
) -> FamaFrenchCountryPortfolioReturnsQueryParams:
|
||||
"""Transform the query parameters into a QueryParams object."""
|
||||
return FamaFrenchCountryPortfolioReturnsQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
async def aextract_data(
|
||||
query: FamaFrenchCountryPortfolioReturnsQueryParams,
|
||||
credentials: Optional[dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> tuple:
|
||||
"""Extract data from the Fama-French FTP."""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from openbb_famafrench.utils.helpers import get_international_portfolio # noqa
|
||||
from warnings import warn
|
||||
|
||||
if query.measure == "ratios" and query.frequency != "annual":
|
||||
warn("Only 'annual' frequency is supported for 'ratios' measure.")
|
||||
query.frequency = "annual"
|
||||
|
||||
try:
|
||||
return get_international_portfolio(
|
||||
country=query.country,
|
||||
measure=query.measure,
|
||||
frequency=query.frequency,
|
||||
dividends=True if query.dividends is None else query.dividends,
|
||||
all_data_items_required=(
|
||||
True
|
||||
if query.all_data_items_required is None
|
||||
else query.all_data_items_required
|
||||
),
|
||||
)
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
raise OpenBBError(e) from e
|
||||
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
query: FamaFrenchCountryPortfolioReturnsQueryParams,
|
||||
data: tuple,
|
||||
**kwargs: Any,
|
||||
) -> AnnotatedResult[list[FamaFrenchCountryPortfolioReturnsData]]:
|
||||
"""Transform the extracted data."""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from pandas import MultiIndex
|
||||
|
||||
dfs, meta = data
|
||||
|
||||
if not dfs:
|
||||
raise OpenBBError(
|
||||
"The request was returned empty."
|
||||
+ " This may be due to an invalid, or incorrectly mapped, portfolio choice."
|
||||
)
|
||||
returns_data = dfs[0] if isinstance(dfs, list) else dfs
|
||||
|
||||
# Values of -99.99 or -999 indicate no data,
|
||||
# Drop columns that have no data.
|
||||
for col in returns_data.columns:
|
||||
if all(returns_data[col].values == "-99.99") or all(
|
||||
returns_data[col].values == "-999"
|
||||
):
|
||||
returns_data = returns_data.drop(columns=[col])
|
||||
else:
|
||||
returns_data[col] = (
|
||||
returns_data[col].astype(int)
|
||||
if query.measure == "ratios" and col == "firms"
|
||||
else returns_data[col].astype(float)
|
||||
)
|
||||
|
||||
if query.start_date:
|
||||
returns_data = returns_data[
|
||||
returns_data.index >= query.start_date.strftime("%Y-%m-%d")
|
||||
]
|
||||
|
||||
if query.end_date:
|
||||
returns_data = returns_data[
|
||||
returns_data.index <= query.end_date.strftime("%Y-%m-%d")
|
||||
]
|
||||
|
||||
if isinstance(returns_data.columns, MultiIndex):
|
||||
returns_data.columns = [
|
||||
" ".join([str(level) for level in col if str(level) != ""])
|
||||
for col in returns_data.columns.values
|
||||
]
|
||||
|
||||
metadata = meta[0] if isinstance(meta, list) else meta
|
||||
description = metadata.pop("description", "")
|
||||
new_description = """
|
||||
We form value and growth portfolios in each country using four ratios:
|
||||
|
||||
- book-to-market (B/M)
|
||||
- earnings-price (E/P)
|
||||
- cash earnings to price (CE/P)
|
||||
- dividend yield (D/P)
|
||||
|
||||
We form the portfolios at the end of December each year by sorting on one of the four ratios
|
||||
and then compute value-weighted returns for the following 12 months.
|
||||
|
||||
The value portfolios (High) contain firms in the top 30% of a ratio
|
||||
and the growth portfolios (Low) contain firms in the bottom 30%.
|
||||
|
||||
There are two sets of portfolios. In one, firms are included only if we have data on all four ratios.
|
||||
In the other, a firm is included in a sort variable's portfolios if we have data for that variable.
|
||||
|
||||
The market return (Mkt) for the first set is the value weighted average of the returns
|
||||
for only firms with all four ratios.
|
||||
The market return for the second set includes all firms with book-to-market data,
|
||||
and Firms is the number of firms with B/M data.
|
||||
|
||||
The raw data are from Morgan Stanley Capital International for 1975 to 2006 and from
|
||||
Bloomberg for 2007 to present.
|
||||
"""
|
||||
metadata["description"] = "### " + description + "\n\n" + new_description
|
||||
|
||||
return AnnotatedResult(
|
||||
result=[
|
||||
FamaFrenchCountryPortfolioReturnsData(**d)
|
||||
for d in returns_data.reset_index().to_dict(orient="records")
|
||||
],
|
||||
metadata=meta[0] if isinstance(meta, list) else meta,
|
||||
)
|
||||
@@ -0,0 +1,314 @@
|
||||
"""Fama-French Factors Fetcher Model."""
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
|
||||
from datetime import date as dateType
|
||||
from typing import Any, Literal, Optional
|
||||
|
||||
from openbb_core.app.model.abstract.error import OpenBBError
|
||||
from openbb_core.app.service.system_service import SystemService
|
||||
from openbb_core.provider.abstract.annotated_result import AnnotatedResult
|
||||
from openbb_core.provider.abstract.data import Data
|
||||
from openbb_core.provider.abstract.fetcher import Fetcher
|
||||
from openbb_core.provider.abstract.query_params import QueryParams
|
||||
from pydantic import Field, model_validator
|
||||
|
||||
from openbb_famafrench.utils.constants import FACTOR_REGION_MAP, REGIONS_MAP
|
||||
|
||||
api_prefix = SystemService().system_settings.api_settings.prefix
|
||||
factors_dict = {
|
||||
"5_factors": "5_Factors",
|
||||
"3_factors": "3_Factors",
|
||||
"momentum": "Momentum",
|
||||
"st_reversal": "ST_Reversal",
|
||||
"lt_reversal": "LT_Reversal",
|
||||
}
|
||||
|
||||
|
||||
class FamaFrenchFactorsQueryParams(QueryParams):
|
||||
"""Query parameters for Fama-French factors.
|
||||
|
||||
Source: https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html
|
||||
"""
|
||||
|
||||
region: Literal[
|
||||
"america",
|
||||
"north_america",
|
||||
"europe",
|
||||
"japan",
|
||||
"asia_pacific_ex_japan",
|
||||
"developed",
|
||||
"developed_ex_us",
|
||||
"emerging",
|
||||
] = Field(
|
||||
description="Region of focus. Default is America.",
|
||||
default="america",
|
||||
json_schema_extra={
|
||||
"x-widget_config": {
|
||||
"options": [
|
||||
{"label": k.replace("_", " ").title(), "value": v}
|
||||
for k, v in REGIONS_MAP.items()
|
||||
]
|
||||
}
|
||||
},
|
||||
)
|
||||
factor: Literal[
|
||||
"5_factors", "3_factors", "momentum", "st_reversal", "lt_reversal"
|
||||
] = Field(
|
||||
default="3_factors",
|
||||
description="Factor to fetch. "
|
||||
+ "Default is the 3-Factor Model."
|
||||
+ "Short/long-term reversals are available only for America.",
|
||||
json_schema_extra={
|
||||
"x-widget_config": {
|
||||
"type": "endpoint",
|
||||
"optionsEndpoint": f"{api_prefix}/famafrench/factor_choices",
|
||||
"optionsParams": {"region": "$region", "is_portfolio": False},
|
||||
},
|
||||
},
|
||||
)
|
||||
frequency: Literal[
|
||||
"daily",
|
||||
"weekly",
|
||||
"monthly",
|
||||
"annual",
|
||||
] = Field(
|
||||
default="monthly",
|
||||
description="Frequency of the factor data."
|
||||
+ "Not all are available for all regions, "
|
||||
+ "and intervals depend on the factor selected."
|
||||
+ " Weekly is only available for the US 3-Factor Model.",
|
||||
json_schema_extra={
|
||||
"x-widget_config": {
|
||||
"type": "endpoint",
|
||||
"optionsEndpoint": f"{api_prefix}/famafrench/get_factor_choices",
|
||||
"optionsParams": {
|
||||
"region": "$region",
|
||||
"factor": "$factor",
|
||||
"is_portfolio": False,
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
start_date: Optional[dateType] = Field(
|
||||
default=None,
|
||||
description="Start date of the data. Defaults to the complete data range.",
|
||||
json_schema_extra={
|
||||
"x-widget_config": {
|
||||
"value": "$currentDate-5y",
|
||||
"description": "Start date of the factor data.",
|
||||
}
|
||||
},
|
||||
)
|
||||
end_date: Optional[dateType] = Field(
|
||||
default=None,
|
||||
description="End date of the data. Defaults to the complete data range.",
|
||||
json_schema_extra={
|
||||
"x-widget_config": {
|
||||
"value": "$currentDate",
|
||||
"description": "End date of the factor data.",
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@model_validator(mode="before")
|
||||
@classmethod
|
||||
def validate_region_and_factor(cls, values):
|
||||
"""Validate region and factor combination."""
|
||||
region = values.get("region", "america")
|
||||
factor = factors_dict.get(values.get("factor", "3_factors"), "")
|
||||
frequency = values.get("frequency", "")
|
||||
|
||||
if factor and factor in ["st_reversal", "lt_reversal"] and region != "america":
|
||||
raise ValueError(
|
||||
f"Invalid region, '{region}', for factor '{factor}'. Only 'america' is supported."
|
||||
)
|
||||
|
||||
if region and region not in list(FACTOR_REGION_MAP):
|
||||
raise ValueError(
|
||||
f"Invalid region: '{region}'. "
|
||||
+ "Valid regions are: "
|
||||
+ ", ".join(FACTOR_REGION_MAP.keys())
|
||||
)
|
||||
|
||||
regional_factors = FACTOR_REGION_MAP[region]
|
||||
|
||||
if factor not in regional_factors.get("factors", {}):
|
||||
raise ValueError(
|
||||
f"Invalid factor: '{factor}' for region: '{region}'. "
|
||||
+ "Valid factors are: "
|
||||
+ ", ".join(regional_factors.get("factors", {}).keys())
|
||||
)
|
||||
|
||||
if frequency:
|
||||
intervals = regional_factors.get("intervals", {}).get(factor, {})
|
||||
if frequency not in list(intervals):
|
||||
raise ValueError(
|
||||
f"Invalid frequency: '{frequency}' for factor: '{factor}'"
|
||||
+ f" in region: '{region}'. "
|
||||
+ "Valid frequencies are: "
|
||||
+ ", ".join(intervals.keys())
|
||||
)
|
||||
|
||||
return values
|
||||
|
||||
|
||||
class FamaFrenchFactorsData(Data):
|
||||
"""Fama-French Factors Data.
|
||||
|
||||
Source: https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html
|
||||
"""
|
||||
|
||||
__alias_dict__ = {
|
||||
"date": "Date",
|
||||
"mkt_rf": "Mkt-RF",
|
||||
"smb": "SMB",
|
||||
"hml": "HML",
|
||||
"rmw": "RMW",
|
||||
"cma": "CMA",
|
||||
"rf": "RF",
|
||||
"mom": "Mom",
|
||||
"lt_rev": "LT_Rev",
|
||||
"st_rev": "ST_Rev",
|
||||
"wml": "WML",
|
||||
}
|
||||
|
||||
date: dateType = Field(
|
||||
description="Date of the factor data.",
|
||||
)
|
||||
mkt_rf: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Excess return on the market, value-weighted return of all firms,"
|
||||
+ " minus the one-month Treasury bill rate."
|
||||
+ " Not returned for momentum or reversal factors.",
|
||||
title="Mkt-RF",
|
||||
)
|
||||
smb: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Small minus big (SMB) factor returns."
|
||||
+ " Average return of small minus big stock portfolios."
|
||||
+ " Not returned for momentum or reversal factors.",
|
||||
title="SMB",
|
||||
)
|
||||
hml: Optional[float] = Field(
|
||||
default=None,
|
||||
description="High minus low (HML) factor returns."
|
||||
+ " Average return on value minus average return on growth portfolios."
|
||||
+ " Not returned for momentum or reversal factors.",
|
||||
title="HML",
|
||||
)
|
||||
rmw: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Robust minus weak (RMW) factor returns."
|
||||
+ " Average return on robust operating profitability portfolios,"
|
||||
" minus average return on weak operating profitability portfolios."
|
||||
+ " Only returned when 5 Factor model is selected.",
|
||||
title="RMW",
|
||||
)
|
||||
cma: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Conservative minus aggressive (CMA) factor returns."
|
||||
+ " Average return on conservative investment portfolios,"
|
||||
" minus average return on aggressive investment portfolios."
|
||||
+ " Only returned when 5 Factor model is selected.",
|
||||
title="CMA",
|
||||
)
|
||||
rf: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Risk-free rate (RF) returns."
|
||||
+ " The one-month US Treasury bill rate."
|
||||
+ " Not returned when momentum or reversal factors are selected.",
|
||||
title="RF",
|
||||
)
|
||||
mom: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Momentum (Mom) factor returns."
|
||||
+ " Returned only when the momentum factor is selected and the region is 'america'.",
|
||||
title="Mom",
|
||||
)
|
||||
wml: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Winners minus losers (WML) factor returns."
|
||||
+ " Equal-weight average of the returns for the winner portfolios"
|
||||
+ " minus the average of the returns for the loser portfolios."
|
||||
+ " Returned only when the momentum factor is selected, and the region is not 'america'.",
|
||||
title="WML",
|
||||
)
|
||||
lt_rev: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Long-term reversal (LT_Rev) factor returns."
|
||||
+ " Returned only when the long-term reversal factor is selected,"
|
||||
+ " and the region is 'america'.",
|
||||
title="LT_Rev",
|
||||
)
|
||||
st_rev: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Short-term reversal (ST_Rev) factor returns."
|
||||
+ " Returned only when the short-term reversal factor is selected,"
|
||||
+ " and the region is 'america'.",
|
||||
title="ST_Rev",
|
||||
)
|
||||
|
||||
|
||||
class FamaFrenchFactorsFetcher(
|
||||
Fetcher[FamaFrenchFactorsQueryParams, list[FamaFrenchFactorsData]]
|
||||
):
|
||||
"""Fama-French Factors Fetcher."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(params: dict[str, Any]) -> FamaFrenchFactorsQueryParams:
|
||||
"""Transform query parameters to FamaFrenchFactorsQueryParams."""
|
||||
return FamaFrenchFactorsQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
async def aextract_data(
|
||||
query: FamaFrenchFactorsQueryParams,
|
||||
credentials: Optional[dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> tuple:
|
||||
"""Extract the data from the FTP."""
|
||||
# pylint: disable=import-outside-toplevel, broad-except
|
||||
from openbb_famafrench.utils.helpers import get_portfolio_data
|
||||
|
||||
factors = FACTOR_REGION_MAP.get(query.region, {})
|
||||
factor = factors_dict.get(query.factor, "")
|
||||
portfolio = factors.get("factors", {}).get(factor, "")
|
||||
interval = factors.get("intervals", {}).get(factor, {}).get(query.frequency, "")
|
||||
dataset = portfolio + interval
|
||||
|
||||
if not dataset:
|
||||
raise OpenBBError(f"Invalid dataset, {dataset}")
|
||||
|
||||
try:
|
||||
return get_portfolio_data(
|
||||
dataset=dataset,
|
||||
frequency=query.frequency,
|
||||
)
|
||||
except Exception as e:
|
||||
raise OpenBBError(original=e) from e
|
||||
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
query: FamaFrenchFactorsQueryParams,
|
||||
data: tuple,
|
||||
**kwargs: Any,
|
||||
) -> AnnotatedResult[list[FamaFrenchFactorsData]]:
|
||||
"""Transform the raw data and insert metadata."""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from pandas import to_datetime
|
||||
|
||||
table = data[0][0].reset_index()
|
||||
|
||||
if query.start_date:
|
||||
table = table[to_datetime(table.Date) >= to_datetime(query.start_date)]
|
||||
|
||||
if query.end_date:
|
||||
table = table[to_datetime(table.Date) <= to_datetime(query.end_date)]
|
||||
|
||||
records = table.to_dict(orient="records")
|
||||
metadata = data[1][0]
|
||||
|
||||
return AnnotatedResult(
|
||||
result=[FamaFrenchFactorsData(**r) for r in records],
|
||||
metadata=metadata,
|
||||
)
|
||||
@@ -0,0 +1,314 @@
|
||||
"""Fama-French Factors Fetcher Model."""
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
|
||||
from datetime import date as dateType
|
||||
from typing import Any, Literal, Optional
|
||||
|
||||
from openbb_core.app.model.abstract.error import OpenBBError
|
||||
from openbb_core.provider.abstract.annotated_result import AnnotatedResult
|
||||
from openbb_core.provider.abstract.data import Data
|
||||
from openbb_core.provider.abstract.fetcher import Fetcher
|
||||
from openbb_core.provider.abstract.query_params import QueryParams
|
||||
from pydantic import Field
|
||||
|
||||
from openbb_famafrench.utils.constants import InternationalIndexPortfolios
|
||||
|
||||
|
||||
class FamaFrenchInternationalIndexReturnsQueryParams(QueryParams):
|
||||
"""International Index Returns Query parameters."""
|
||||
|
||||
__json_schema_extra__ = {
|
||||
"country": {
|
||||
"x-widget_config": {
|
||||
"options": [
|
||||
{
|
||||
"value": d,
|
||||
"label": d.replace("_", " ").title().replace("Ex ", "Ex-"),
|
||||
}
|
||||
for d in getattr(InternationalIndexPortfolios, "__args__", [])
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
index: InternationalIndexPortfolios = Field(
|
||||
default="all",
|
||||
description="International index to fetch the portfolio returns for. Defaults to 'all'.",
|
||||
)
|
||||
measure: Literal[
|
||||
"usd",
|
||||
"local",
|
||||
"ratios",
|
||||
] = Field(
|
||||
default="usd",
|
||||
description="The measure to fetch for the portfolio."
|
||||
+ " Only 'annual' frequency is supported for 'ratios'.",
|
||||
)
|
||||
frequency: Literal["monthly", "annual"] = Field(
|
||||
default="monthly",
|
||||
description="The frequency of the data to fetch."
|
||||
+ " Ignored when `measure` is set to 'ratios'.",
|
||||
)
|
||||
dividends: Optional[bool] = Field(
|
||||
default=None, description="When False, portoflios exclude dividends."
|
||||
)
|
||||
all_data_items_required: Optional[bool] = Field(
|
||||
default=None,
|
||||
description="If True (default), includes firms with data for all four ratios."
|
||||
+ " When False, includes only firms with Book-to-Market (B/M) data.",
|
||||
)
|
||||
start_date: Optional[dateType] = Field(
|
||||
default=None,
|
||||
description="The start date for the data. Defaults to the earliest available date.",
|
||||
)
|
||||
end_date: Optional[dateType] = Field(
|
||||
default=None,
|
||||
description="The end date for the data. Defaults to the latest available date.",
|
||||
)
|
||||
|
||||
|
||||
class FamaFrenchInternationalIndexReturnsData(Data):
|
||||
"""International Index Portfolio Returns Data."""
|
||||
|
||||
__alias_dict__ = {
|
||||
"date": "Date",
|
||||
"mkt": "Mkt",
|
||||
"firms": "Firms",
|
||||
"bm": "B/M",
|
||||
"be_me_high": "BE/ME High",
|
||||
"be_me_low": "BE/ME Low",
|
||||
"ep": "E/P",
|
||||
"e_p_high": "E/P High",
|
||||
"e_p_low": "E/P Low",
|
||||
"ce_p": "CE/P",
|
||||
"ce_p_high": "CE/P High",
|
||||
"ce_p_low": "CE/P Low",
|
||||
"yld": "Yld",
|
||||
"yld_high": "Yld High",
|
||||
"yld_low": "Yld Low",
|
||||
"yld_zero": "Yld Zero",
|
||||
}
|
||||
|
||||
date: dateType = Field(
|
||||
description="The date of the data.",
|
||||
)
|
||||
mkt: Optional[float] = Field(
|
||||
default=None,
|
||||
description="""
|
||||
The market return (Mkt) for the first set is the value weighted average
|
||||
of the returns for only firms with all four ratios.
|
||||
|
||||
The market return for the second set includes all firms with book-to-market data,
|
||||
and Firms is the number of firms with B/M data.
|
||||
|
||||
Not returned if `measure` is set to 'ratios'.
|
||||
""",
|
||||
)
|
||||
firms: Optional[int] = Field(
|
||||
default=None,
|
||||
description="The number of firms, relative to `all_data_items_required` parameter."
|
||||
+ " Only returned when `measure` is set to 'ratios'.",
|
||||
)
|
||||
bm: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Book to Market equity ratio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="B/M",
|
||||
)
|
||||
be_me_high: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Book Equity to Market Equity returns for the value portfolio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="BE/ME High",
|
||||
)
|
||||
be_me_low: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Book Equity to Market Equity returns for the growth portfolio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="BE/ME Low",
|
||||
)
|
||||
ep: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Earnings to Price ratio."
|
||||
+ " Only returned when `measure` is set to 'ratios'.",
|
||||
title="E/P",
|
||||
)
|
||||
e_p_high: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Earnings to Price returns for the value portfolio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="E/P High",
|
||||
)
|
||||
e_p_low: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Earnings to Price returns for the growth portfolio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="E/P Low",
|
||||
)
|
||||
ce_p: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Cash Earnings to Price ratio."
|
||||
+ " Only returned when `measure` is set to 'ratios'.",
|
||||
title="CE/P",
|
||||
)
|
||||
ce_p_high: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Cash Earnings to Price returns for the value portfolio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="CE/P High",
|
||||
)
|
||||
ce_p_low: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Cash Earnings to Price returns for the growth portfolio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="CE/P Low",
|
||||
)
|
||||
yld: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Dividend Yield ratio."
|
||||
+ " Only returned when `measure` is set to 'ratios'.",
|
||||
title="Yld",
|
||||
)
|
||||
yld_high: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Dividend Yield returns for the value portfolio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="Yld High",
|
||||
)
|
||||
yld_low: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Dividend Yield returns for the growth portfolio."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="Yld Low",
|
||||
)
|
||||
yld_zero: Optional[float] = Field(
|
||||
default=None,
|
||||
description="Dividend Yield returns for firms not paying dividends."
|
||||
+ " Not returned if `measure` is set to 'ratios'.",
|
||||
title="Yld Zero",
|
||||
)
|
||||
|
||||
|
||||
class FamaFrenchInternationalIndexReturnsFetcher(
|
||||
Fetcher[
|
||||
FamaFrenchInternationalIndexReturnsQueryParams,
|
||||
list[FamaFrenchInternationalIndexReturnsData],
|
||||
]
|
||||
):
|
||||
"""International Index Returns Fetcher."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(
|
||||
params: dict[str, Any],
|
||||
) -> FamaFrenchInternationalIndexReturnsQueryParams:
|
||||
"""Transform the query parameters into a QueryParams object."""
|
||||
return FamaFrenchInternationalIndexReturnsQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
async def aextract_data(
|
||||
query: FamaFrenchInternationalIndexReturnsQueryParams,
|
||||
credentials: Optional[dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> tuple:
|
||||
"""Extract data from the Fama-French FTP."""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from openbb_famafrench.utils.helpers import get_international_portfolio # noqa
|
||||
from warnings import warn
|
||||
|
||||
if query.measure == "ratios" and query.frequency != "annual":
|
||||
warn("Only 'annual' frequency is supported for 'ratios' measure.")
|
||||
query.frequency = "annual"
|
||||
|
||||
try:
|
||||
return get_international_portfolio(
|
||||
index=query.index,
|
||||
measure=query.measure,
|
||||
frequency=query.frequency,
|
||||
dividends=True if query.dividends is None else query.dividends,
|
||||
all_data_items_required=(
|
||||
True
|
||||
if query.all_data_items_required is None
|
||||
else query.all_data_items_required
|
||||
),
|
||||
)
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
raise OpenBBError(e) from e
|
||||
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
query: FamaFrenchInternationalIndexReturnsQueryParams,
|
||||
data: tuple,
|
||||
**kwargs: Any,
|
||||
) -> AnnotatedResult[list[FamaFrenchInternationalIndexReturnsData]]:
|
||||
"""Transform the extracted data."""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from pandas import MultiIndex
|
||||
|
||||
dfs, meta = data
|
||||
|
||||
if not dfs:
|
||||
raise OpenBBError(
|
||||
"The request was returned empty."
|
||||
+ " This may be due to an invalid, or incorrectly mapped, portfolio choice."
|
||||
)
|
||||
returns_data = dfs[0] if isinstance(dfs, list) else dfs
|
||||
|
||||
# Values of -99.99 or -999 indicate no data,
|
||||
# Drop columns that have no data.
|
||||
for col in returns_data.columns:
|
||||
if all(returns_data[col].values == "-99.99") or all(
|
||||
returns_data[col].values == "-999"
|
||||
):
|
||||
returns_data = returns_data.drop(columns=[col])
|
||||
else:
|
||||
returns_data[col] = (
|
||||
returns_data[col].astype(int)
|
||||
if query.measure == "ratios" and col == "firms"
|
||||
else returns_data[col].astype(float)
|
||||
)
|
||||
|
||||
if query.start_date:
|
||||
returns_data = returns_data[
|
||||
returns_data.index >= query.start_date.strftime("%Y-%m-%d")
|
||||
]
|
||||
|
||||
if query.end_date:
|
||||
returns_data = returns_data[
|
||||
returns_data.index <= query.end_date.strftime("%Y-%m-%d")
|
||||
]
|
||||
|
||||
if isinstance(returns_data.columns, MultiIndex):
|
||||
returns_data.columns = [
|
||||
" ".join([str(level) for level in col if str(level) != ""])
|
||||
for col in returns_data.columns.values
|
||||
]
|
||||
|
||||
metadata = meta[0] if isinstance(meta, list) else meta
|
||||
description = metadata.pop("description", "")
|
||||
new_description = """
|
||||
We form value and growth portfolios in each country using four ratios:
|
||||
|
||||
- book-to-market (B/M)
|
||||
- earnings-price (E/P)
|
||||
- cash earnings to price (CE/P)
|
||||
- dividend yield (D/P)
|
||||
|
||||
The returns on the index portfolios are constructed by averaging the returns on the country portfolios.
|
||||
Each country is added to the index portfolios when the return data for the country begin;
|
||||
the country start dates can be inferred from the country return files.
|
||||
|
||||
We weight countries in the index portfolios in proportion to their EAFE + Canada weights.
|
||||
|
||||
The raw data are from Morgan Stanley Capital International for 1975 to 2006 and from
|
||||
Bloomberg for 2007 to present.
|
||||
"""
|
||||
metadata["description"] = "### " + description + "\n" + new_description
|
||||
|
||||
return AnnotatedResult(
|
||||
result=[
|
||||
FamaFrenchInternationalIndexReturnsData(**d)
|
||||
for d in returns_data.reset_index().to_dict(orient="records")
|
||||
],
|
||||
metadata=meta[0] if isinstance(meta, list) else meta,
|
||||
)
|
||||
@@ -0,0 +1,188 @@
|
||||
"""Fama-French Factors Fetcher Model."""
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
|
||||
from datetime import date as dateType
|
||||
from typing import Any, Literal, Optional, Union
|
||||
|
||||
from openbb_core.app.model.abstract.error import OpenBBError
|
||||
from openbb_core.provider.abstract.annotated_result import AnnotatedResult
|
||||
from openbb_core.provider.abstract.data import Data
|
||||
from openbb_core.provider.abstract.fetcher import Fetcher
|
||||
from openbb_core.provider.abstract.query_params import QueryParams
|
||||
from pydantic import Field
|
||||
|
||||
from openbb_famafrench.utils.constants import RegionalPortfolios, portfolio_choices
|
||||
|
||||
|
||||
class FamaFrenchRegionalPortfolioReturnsQueryParams(QueryParams):
|
||||
"""Regional Portfolio Returns Query parameters."""
|
||||
|
||||
__json_schema_extra__ = {
|
||||
"portfolio": {
|
||||
"x-widget_config": {
|
||||
"options": [
|
||||
{"value": d, "label": d}
|
||||
for d in portfolio_choices
|
||||
if d.get("value") in getattr(RegionalPortfolios, "__args__", [])
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
portfolio: RegionalPortfolios = Field(
|
||||
default="developed_ex_us_6_portfolios_me_op",
|
||||
description="The specific portfolio file to fetch.",
|
||||
)
|
||||
measure: Literal[
|
||||
"value",
|
||||
"equal",
|
||||
"number_of_firms",
|
||||
"firm_size",
|
||||
] = Field(
|
||||
default="value",
|
||||
description="The measure to fetch for the portfolio.",
|
||||
)
|
||||
frequency: Literal["monthly", "annual"] = Field(
|
||||
default="monthly",
|
||||
description="The frequency of the data to fetch."
|
||||
+ " Ignored when the portfolio ends with 'daily'.",
|
||||
)
|
||||
start_date: Optional[dateType] = Field(
|
||||
default=None,
|
||||
description="The start date for the data. Defaults to the earliest available date.",
|
||||
)
|
||||
end_date: Optional[dateType] = Field(
|
||||
default=None,
|
||||
description="The end date for the data. Defaults to the latest available date.",
|
||||
)
|
||||
|
||||
|
||||
class FamaFrenchRegionalPortfolioReturnsData(Data):
|
||||
"""Regional Portfolio Returns Data."""
|
||||
|
||||
__alias_dict__ = {
|
||||
"date": "Date",
|
||||
}
|
||||
|
||||
date: dateType = Field(
|
||||
description="The date of the data.",
|
||||
)
|
||||
portfolio: str = Field(
|
||||
description="The individual portfolio formation within the portfolio file.",
|
||||
)
|
||||
measure: Literal[
|
||||
"value",
|
||||
"equal",
|
||||
"number_of_firms",
|
||||
"firm_size",
|
||||
] = Field(
|
||||
description="The measure of the portfolio.",
|
||||
)
|
||||
value: Union[int, float] = Field(
|
||||
description="The value represented by the 'measure'."
|
||||
+ " Missing data are indicated by -99.99 or -999",
|
||||
)
|
||||
|
||||
|
||||
class FamaFrenchRegionalPortfolioReturnsFetcher(
|
||||
Fetcher[
|
||||
FamaFrenchRegionalPortfolioReturnsQueryParams,
|
||||
list[FamaFrenchRegionalPortfolioReturnsData],
|
||||
]
|
||||
):
|
||||
"""Regional Portfolio Returns Fetcher."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(
|
||||
params: dict[str, Any],
|
||||
) -> FamaFrenchRegionalPortfolioReturnsQueryParams:
|
||||
"""Transform the query parameters into a QueryParams object."""
|
||||
return FamaFrenchRegionalPortfolioReturnsQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
async def aextract_data(
|
||||
query: FamaFrenchRegionalPortfolioReturnsQueryParams,
|
||||
credentials: Optional[dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> tuple:
|
||||
"""Extract data from the Fama-French FTP."""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from openbb_famafrench.utils.helpers import get_portfolio_data
|
||||
|
||||
dataset = ""
|
||||
|
||||
for item in portfolio_choices:
|
||||
if item.get("label") == query.portfolio:
|
||||
dataset = item["value"]
|
||||
break
|
||||
|
||||
try:
|
||||
return get_portfolio_data(
|
||||
dataset=dataset,
|
||||
measure=query.measure,
|
||||
frequency=(None if "daily" in dataset.lower() else query.frequency),
|
||||
)
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
raise OpenBBError(e) from e
|
||||
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
query: FamaFrenchRegionalPortfolioReturnsQueryParams,
|
||||
data: tuple,
|
||||
**kwargs: Any,
|
||||
) -> AnnotatedResult[list[FamaFrenchRegionalPortfolioReturnsData]]:
|
||||
"""Transform the extracted data."""
|
||||
dfs, meta = data
|
||||
|
||||
if not dfs:
|
||||
raise OpenBBError(
|
||||
"The request was returned empty."
|
||||
+ " This may be due to an invalid, or incorrectly mapped, portfolio choice."
|
||||
)
|
||||
returns_data = dfs[0] if isinstance(dfs, list) else dfs
|
||||
|
||||
# Values of -99.99 or -999 indicate no data,
|
||||
# Drop columns that have no data.
|
||||
for col in returns_data.columns:
|
||||
if all(returns_data[col].values == "-99.99") or all(
|
||||
returns_data[col].values == "-999"
|
||||
):
|
||||
returns_data = returns_data.drop(columns=[col])
|
||||
else:
|
||||
returns_data[col] = (
|
||||
returns_data[col].astype(int)
|
||||
if query.measure == "number_of_firms"
|
||||
else returns_data[col].astype(float)
|
||||
)
|
||||
|
||||
if query.start_date:
|
||||
returns_data = returns_data[
|
||||
returns_data.index >= query.start_date.strftime("%Y-%m-%d")
|
||||
]
|
||||
|
||||
if query.end_date:
|
||||
returns_data = returns_data[
|
||||
returns_data.index <= query.end_date.strftime("%Y-%m-%d")
|
||||
]
|
||||
|
||||
# Flatten the DataFrame to conform to the Data model
|
||||
# This avoids having undefined fields.
|
||||
flattened_data = (
|
||||
returns_data.reset_index()
|
||||
.melt(
|
||||
id_vars=["Date"],
|
||||
var_name="portfolio",
|
||||
value_name="value",
|
||||
)
|
||||
.copy()
|
||||
)
|
||||
flattened_data.loc[:, "measure"] = query.measure
|
||||
|
||||
return AnnotatedResult(
|
||||
result=[
|
||||
FamaFrenchRegionalPortfolioReturnsData(**d)
|
||||
for d in flattened_data.to_dict(orient="records")
|
||||
],
|
||||
metadata=meta[0] if isinstance(meta, list) else meta,
|
||||
)
|
||||
@@ -0,0 +1,192 @@
|
||||
"""Fama-French Factors Fetcher Model."""
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
|
||||
from datetime import date as dateType
|
||||
from typing import Any, Literal, Optional, Union
|
||||
|
||||
from openbb_core.app.model.abstract.error import OpenBBError
|
||||
from openbb_core.provider.abstract.annotated_result import AnnotatedResult
|
||||
from openbb_core.provider.abstract.data import Data
|
||||
from openbb_core.provider.abstract.fetcher import Fetcher
|
||||
from openbb_core.provider.abstract.query_params import QueryParams
|
||||
from pydantic import Field
|
||||
|
||||
from openbb_famafrench.utils.constants import USPortfolios, portfolio_choices
|
||||
|
||||
|
||||
class FamaFrenchUSPortfolioReturnsQueryParams(QueryParams):
|
||||
"""US Portfolio Returns Query parameters."""
|
||||
|
||||
__json_schema_extra__ = {
|
||||
"portfolio": {
|
||||
"x-widget_config": {
|
||||
"options": [
|
||||
{"label": d, "value": d}
|
||||
for d in portfolio_choices
|
||||
if d.get("value") in getattr(USPortfolios, "__args__", [])
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
portfolio: USPortfolios = Field(
|
||||
default="portfolios_formed_on_me",
|
||||
description="The specific portfolio file to fetch.",
|
||||
)
|
||||
measure: Literal[
|
||||
"value",
|
||||
"equal",
|
||||
"number_of_firms",
|
||||
"firm_size",
|
||||
] = Field(
|
||||
default="value",
|
||||
description="The measure to fetch for the portfolio.",
|
||||
)
|
||||
frequency: Literal["monthly", "annual"] = Field(
|
||||
default="monthly",
|
||||
description="The frequency of the data to fetch."
|
||||
+ " Ignored if the portfolio ends with 'daily' or 'weekly'.",
|
||||
)
|
||||
start_date: Optional[dateType] = Field(
|
||||
default=None,
|
||||
description="The start date for the data. Defaults to the earliest available date.",
|
||||
)
|
||||
end_date: Optional[dateType] = Field(
|
||||
default=None,
|
||||
description="The end date for the data. Defaults to the latest available date.",
|
||||
)
|
||||
|
||||
|
||||
class FamaFrenchUSPortfolioReturnsData(Data):
|
||||
"""US Portfolio Returns Data."""
|
||||
|
||||
__alias_dict__ = {
|
||||
"date": "Date",
|
||||
}
|
||||
|
||||
date: dateType = Field(
|
||||
description="The date of the data.",
|
||||
)
|
||||
portfolio: str = Field(
|
||||
description="The individual portfolio formation within the portfolio file.",
|
||||
)
|
||||
measure: Literal[
|
||||
"value",
|
||||
"equal",
|
||||
"number_of_firms",
|
||||
"firm_size",
|
||||
] = Field(
|
||||
description="The measure of the portfolio.",
|
||||
)
|
||||
value: Union[int, float] = Field(
|
||||
description="The value represented by the 'measure'."
|
||||
+ " Missing data are indicated by -99.99 or -999",
|
||||
)
|
||||
|
||||
|
||||
class FamaFrenchUSPortfolioReturnsFetcher(
|
||||
Fetcher[
|
||||
FamaFrenchUSPortfolioReturnsQueryParams, list[FamaFrenchUSPortfolioReturnsData]
|
||||
]
|
||||
):
|
||||
"""US Portfolio Returns Fetcher."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(
|
||||
params: dict[str, Any],
|
||||
) -> FamaFrenchUSPortfolioReturnsQueryParams:
|
||||
"""Transform the query parameters into a QueryParams object."""
|
||||
return FamaFrenchUSPortfolioReturnsQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
async def aextract_data(
|
||||
query: FamaFrenchUSPortfolioReturnsQueryParams,
|
||||
credentials: Optional[dict[str, str]],
|
||||
**kwargs: Any,
|
||||
) -> tuple:
|
||||
"""Extract data from the Fama-French FTP."""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from openbb_famafrench.utils.helpers import get_portfolio_data
|
||||
|
||||
dataset = ""
|
||||
|
||||
for item in portfolio_choices:
|
||||
if item.get("label") == query.portfolio:
|
||||
dataset = item["value"]
|
||||
break
|
||||
|
||||
try:
|
||||
return get_portfolio_data(
|
||||
dataset=dataset,
|
||||
measure=query.measure,
|
||||
frequency=(
|
||||
None
|
||||
if "daily" in dataset.lower() or "weekly" in dataset.lower()
|
||||
else query.frequency
|
||||
),
|
||||
)
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
raise OpenBBError(e) from e
|
||||
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
query: FamaFrenchUSPortfolioReturnsQueryParams,
|
||||
data: tuple,
|
||||
**kwargs: Any,
|
||||
) -> AnnotatedResult[list[FamaFrenchUSPortfolioReturnsData]]:
|
||||
"""Transform the extracted data."""
|
||||
dfs, meta = data
|
||||
|
||||
if not dfs:
|
||||
raise OpenBBError(
|
||||
"The request was returned empty."
|
||||
+ " This may be due to an invalid, or incorrectly mapped, portfolio choice."
|
||||
)
|
||||
|
||||
returns_data = dfs[0] if isinstance(dfs, list) else dfs
|
||||
|
||||
# Values of -99.99 or -999 indicate no data,
|
||||
# Drop columns that have no data.
|
||||
for col in returns_data.columns:
|
||||
if all(returns_data[col].values == "-99.99") or all(
|
||||
returns_data[col].values == "-999"
|
||||
):
|
||||
returns_data = returns_data.drop(columns=[col])
|
||||
else:
|
||||
returns_data[col] = (
|
||||
returns_data[col].astype(int)
|
||||
if query.measure == "number_of_firms"
|
||||
else returns_data[col].astype(float)
|
||||
)
|
||||
|
||||
if query.start_date:
|
||||
returns_data = returns_data[
|
||||
returns_data.index >= query.start_date.strftime("%Y-%m-%d")
|
||||
]
|
||||
|
||||
if query.end_date:
|
||||
returns_data = returns_data[
|
||||
returns_data.index <= query.end_date.strftime("%Y-%m-%d")
|
||||
]
|
||||
|
||||
# Flatten the DataFrame to conform to the Data model
|
||||
# This avoids having undefined fields.
|
||||
flattened_data = (
|
||||
returns_data.reset_index()
|
||||
.melt(
|
||||
id_vars=["Date"],
|
||||
var_name="portfolio",
|
||||
value_name="value",
|
||||
)
|
||||
.copy()
|
||||
)
|
||||
flattened_data.loc[:, "measure"] = query.measure
|
||||
|
||||
return AnnotatedResult(
|
||||
result=[
|
||||
FamaFrenchUSPortfolioReturnsData(**d)
|
||||
for d in flattened_data.to_dict(orient="records")
|
||||
],
|
||||
metadata=meta[0] if isinstance(meta, list) else meta,
|
||||
)
|
||||
0
openbb_platform/providers/famafrench/openbb_famafrench/py.typed
vendored
Normal file
0
openbb_platform/providers/famafrench/openbb_famafrench/py.typed
vendored
Normal file
@@ -0,0 +1 @@
|
||||
"""Fama-French Utilities Module."""
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,969 @@
|
||||
"""Fama-French utilities for handling US and International portfolios and factors."""
|
||||
|
||||
# pylint: disable=R0912,R0913,R0914,R0917,R1702,W0612,W0613
|
||||
|
||||
from functools import lru_cache
|
||||
from typing import Optional
|
||||
|
||||
from openbb_famafrench.utils.constants import (
|
||||
BASE_URL,
|
||||
BREAKPOINT_FILES,
|
||||
COUNTRY_PORTFOLIO_FILES,
|
||||
COUNTRY_PORTFOLIOS_URLS,
|
||||
DATASET_CHOICES,
|
||||
FACTOR_REGION_MAP,
|
||||
INTERNATIONAL_INDEX_PORTFOLIO_FILES,
|
||||
INTERNATIONAL_INDEX_PORTFOLIOS_URLS,
|
||||
REGIONS_MAP,
|
||||
)
|
||||
|
||||
|
||||
async def get_factor_choices(
|
||||
region: Optional[str] = None,
|
||||
factor: Optional[str] = None,
|
||||
is_portfolio: bool = False,
|
||||
portfolio: Optional[str] = None,
|
||||
):
|
||||
"""Get the list of choices for factors based on combinations of parameters.
|
||||
|
||||
This function is for generating choices for Workspace dropdown menus.
|
||||
It is not intended to be used directly.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
region : Optional[str]
|
||||
The region for which to get factor choices. If None, all regions are considered.
|
||||
factor : Optional[str]
|
||||
The specific factor for which to get choices. If None, all factors for the region are
|
||||
considered.
|
||||
is_portfolio : bool
|
||||
If True, the function will return portfolio choices instead of factor choices.
|
||||
portfolio : Optional[str]
|
||||
A specific portfolio.
|
||||
|
||||
Returns
|
||||
-------
|
||||
list
|
||||
A list of dictionaries representing the choices for factors or portfolios.
|
||||
Each dictionary contains a 'label' and a 'value' key.
|
||||
"""
|
||||
if region and not factor and not is_portfolio:
|
||||
factors = FACTOR_REGION_MAP.get(region, {}).get("factors", {})
|
||||
return [
|
||||
{
|
||||
"label": k.replace("_", " ")
|
||||
.title()
|
||||
.replace("Lt", "LT")
|
||||
.replace("St", "ST"),
|
||||
"value": k,
|
||||
}
|
||||
for k in list(factors)
|
||||
]
|
||||
if region and factor and not is_portfolio:
|
||||
intervals = (
|
||||
FACTOR_REGION_MAP.get(region, {}).get("intervals", {}).get(factor, {})
|
||||
)
|
||||
intervals = [
|
||||
{"label": k.replace("_", " ").title(), "value": k} for k in list(intervals)
|
||||
]
|
||||
return intervals
|
||||
|
||||
if not is_portfolio:
|
||||
return [
|
||||
{"label": k.replace("_", " ").title(), "value": k}
|
||||
for k in list(FACTOR_REGION_MAP)
|
||||
]
|
||||
region = region or ""
|
||||
mapped_region = REGIONS_MAP.get(region, "").replace("_", " ")
|
||||
if is_portfolio and region and not portfolio:
|
||||
|
||||
portfolios = (
|
||||
[
|
||||
{
|
||||
"label": (
|
||||
d["label"].replace(mapped_region, "").strip()
|
||||
if region != "america"
|
||||
else d["label"]
|
||||
),
|
||||
"value": d["value"],
|
||||
}
|
||||
for d in DATASET_CHOICES
|
||||
if "Portfolio" in d.get("value", "")
|
||||
and d["value"].startswith(REGIONS_MAP.get(region, region))
|
||||
and "daily" not in d.get("value", "").lower()
|
||||
]
|
||||
if region != "america"
|
||||
else [
|
||||
d
|
||||
for d in DATASET_CHOICES
|
||||
if "Portfolio" in d.get("value", "")
|
||||
and all(
|
||||
not d.get("value", "").startswith(reg)
|
||||
for reg in REGIONS_MAP.values()
|
||||
if reg
|
||||
)
|
||||
and "daily" not in d.get("value", "").lower()
|
||||
]
|
||||
)
|
||||
|
||||
if "ex_" not in region:
|
||||
portfolios = [d for d in portfolios if "ex_" not in d.get("value", "")]
|
||||
|
||||
return portfolios
|
||||
|
||||
if is_portfolio and region and portfolio:
|
||||
portfolios = (
|
||||
[
|
||||
d
|
||||
for d in DATASET_CHOICES
|
||||
if "Portfolio" in d.get("value", "")
|
||||
and d["value"].startswith(REGIONS_MAP.get(region, region))
|
||||
and portfolio in d.get("value", "")
|
||||
]
|
||||
if region != "america"
|
||||
else [
|
||||
d
|
||||
for d in DATASET_CHOICES
|
||||
if "Portfolio" in d.get("value", "")
|
||||
and all(
|
||||
not d.get("value", "").startswith(reg)
|
||||
for reg in REGIONS_MAP.values()
|
||||
if reg
|
||||
)
|
||||
and portfolio in d.get("value", "")
|
||||
]
|
||||
)
|
||||
has_daily = False
|
||||
frequencies = ["monthly", "annual"]
|
||||
|
||||
for d in portfolios:
|
||||
if "daily" in d.get("value", "").lower():
|
||||
has_daily = True
|
||||
break
|
||||
|
||||
frequencies = ["daily"] + frequencies if has_daily else frequencies
|
||||
|
||||
return [{"label": k.title(), "value": k} for k in frequencies]
|
||||
|
||||
return [{"label": "No choices found. Try a new parameter.", "value": None}]
|
||||
|
||||
|
||||
@lru_cache(maxsize=64)
|
||||
def download_file(dataset) -> str:
|
||||
"""Download the specified dataset file from the Ken French data library.
|
||||
|
||||
Note: This function is not intended for direct use, it is called by `get_portfolio_data`.
|
||||
"""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
import zipfile
|
||||
from io import BytesIO
|
||||
|
||||
from openbb_core.provider.utils.helpers import get_requests_session
|
||||
|
||||
url_map = {item["label"]: item["value"] for item in DATASET_CHOICES}
|
||||
|
||||
if dataset.replace("_", " ") not in list(url_map) and dataset not in list(
|
||||
url_map.values()
|
||||
):
|
||||
raise ValueError(
|
||||
f"Dataset {dataset} not found in available datasets: {list(url_map)}"
|
||||
)
|
||||
|
||||
url = (
|
||||
BASE_URL + dataset
|
||||
if dataset.endswith(".zip")
|
||||
else BASE_URL + url_map[dataset.replace("_", " ")]
|
||||
)
|
||||
|
||||
with get_requests_session() as session:
|
||||
response = session.get(url)
|
||||
response.raise_for_status()
|
||||
|
||||
data = ""
|
||||
|
||||
with zipfile.ZipFile(BytesIO(response.content)) as f:
|
||||
with f.open(f.namelist()[0]) as file: # type: ignore
|
||||
data = file.read() # type: ignore
|
||||
try:
|
||||
data = data.decode("utf-8") # type: ignore
|
||||
except UnicodeDecodeError:
|
||||
data = data.decode("latin-1") # type: ignore
|
||||
|
||||
return data
|
||||
|
||||
|
||||
@lru_cache(maxsize=64)
|
||||
def download_international_portfolios(url):
|
||||
"""Download the international index portfolios file.
|
||||
|
||||
Note: This function is not intended for direct use,
|
||||
it is called by `get_international_portfolio`.
|
||||
"""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from openbb_core.provider.utils.helpers import get_requests_session
|
||||
|
||||
with get_requests_session() as session:
|
||||
response = session.get(url)
|
||||
response.raise_for_status()
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def apply_date(x):
|
||||
"""Pandas Apply helper to convert various date formats to a standard YYYY-MM-DD format."""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from pandas import to_datetime
|
||||
|
||||
date = str(x).replace(" ", "")
|
||||
if len(date) == 6:
|
||||
date = date[:4] + "-" + date[4:]
|
||||
date = to_datetime(date, format="%Y-%m")
|
||||
date = date.date().strftime("%Y-%m-%d")
|
||||
elif len(date) == 8:
|
||||
date = date[:4] + "-" + date[4:6] + "-" + date[6:]
|
||||
elif len(date) == 4:
|
||||
date = date + "-12-31"
|
||||
return date
|
||||
|
||||
|
||||
def read_csv_file(data: str):
|
||||
"""Parse the raw data from a .csv file into a list of dictionaries representing tables.
|
||||
|
||||
Note: This function is not intended for direct use, it is called by `get_portfolio_data`.
|
||||
"""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
import re
|
||||
|
||||
lines = data.splitlines()
|
||||
tables: list = []
|
||||
general_description: list = []
|
||||
|
||||
# Extract general description from the top of the file
|
||||
description_end_idx = 0
|
||||
for idx, line in enumerate(lines):
|
||||
if line.strip().startswith(",") or re.match(r"^\s*\d{4,6}", line):
|
||||
description_end_idx = idx
|
||||
break
|
||||
if line.strip():
|
||||
general_description.append(line.strip())
|
||||
|
||||
# Extract initial table metadata from the last line of general description
|
||||
table_metadata: str = ""
|
||||
if general_description and (
|
||||
"Monthly" in general_description[-1]
|
||||
or "Annual" in general_description[-1]
|
||||
or "Returns" in general_description[-1]
|
||||
):
|
||||
table_metadata = general_description[-1]
|
||||
general_description = general_description[:-1]
|
||||
|
||||
general_desc_text = "\n".join(general_description)
|
||||
|
||||
# Process tables in the file
|
||||
i = description_end_idx
|
||||
|
||||
while i < len(lines):
|
||||
# Skip empty lines
|
||||
while i < len(lines) and not lines[i].strip():
|
||||
i += 1
|
||||
|
||||
if i >= len(lines):
|
||||
break
|
||||
|
||||
# Check if this is a table header (starts with comma)
|
||||
if lines[i].strip().startswith(","):
|
||||
# Look for metadata line before this header
|
||||
metadata = table_metadata # Default to initial metadata
|
||||
j = i - 1
|
||||
while j >= description_end_idx:
|
||||
if lines[j].strip():
|
||||
metadata = lines[j].strip()
|
||||
break
|
||||
j -= 1
|
||||
|
||||
# Parse headers
|
||||
header_line = lines[i].strip()
|
||||
headers = ["Date"] + header_line.split(",")[1:]
|
||||
|
||||
# Move past header row
|
||||
i += 1
|
||||
|
||||
# Collect data rows
|
||||
data_rows = []
|
||||
|
||||
# Look for data rows until we hit the next header or end of file
|
||||
while i < len(lines):
|
||||
line = lines[i].strip()
|
||||
if not line:
|
||||
break
|
||||
values = line.split(",")
|
||||
if values:
|
||||
data_rows.append([d.strip() for d in values])
|
||||
|
||||
i += 1
|
||||
|
||||
# Add table if it has data
|
||||
if data_rows:
|
||||
tables.append(
|
||||
{
|
||||
"meta": metadata,
|
||||
"headers": headers,
|
||||
"rows": data_rows,
|
||||
"is_annual": "Annual" in metadata,
|
||||
}
|
||||
)
|
||||
|
||||
# Check for standalone metadata
|
||||
elif "--" in lines[i] and any(
|
||||
d in lines[i] for d in ["Daily", "Monthly", "Annual", "Weekly"]
|
||||
):
|
||||
# Update metadata for next table
|
||||
table_metadata = lines[i].strip()
|
||||
i += 1
|
||||
else:
|
||||
# Skip other lines
|
||||
i += 1
|
||||
|
||||
return tables, general_desc_text
|
||||
|
||||
|
||||
def process_csv_tables(tables, general_description="") -> tuple:
|
||||
"""Convert parsed table dictionaries from CSV files to pandas DataFrames.
|
||||
|
||||
Note: This function is not intended for direct use, it is called by `get_portfolio_data`.
|
||||
"""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
import warnings # noqa
|
||||
from pandas import DataFrame
|
||||
|
||||
dataframes: list = []
|
||||
metadata: list = []
|
||||
|
||||
for table_idx, table in enumerate(tables):
|
||||
# Skip empty tables
|
||||
if not table["rows"]:
|
||||
continue
|
||||
|
||||
# Create DataFrame from rows
|
||||
rows_data = table.get("rows", [])
|
||||
headers = table["headers"]
|
||||
|
||||
# Check if we have enough headers
|
||||
max_cols = max(len(row) for row in rows_data)
|
||||
if len(headers) < max_cols:
|
||||
headers.extend([f"Column_{i}" for i in range(len(headers), max_cols)])
|
||||
|
||||
# Create dataframe with proper dimensions and headers
|
||||
df = DataFrame(rows_data)
|
||||
|
||||
if df.empty or df.shape[1] == 0:
|
||||
continue
|
||||
|
||||
# Set column names
|
||||
df.columns = headers[: df.shape[1]]
|
||||
|
||||
# Convert Date column to datetime
|
||||
try:
|
||||
# Convert YYYYMM format to datetime
|
||||
df["Date"] = df.Date.apply(apply_date)
|
||||
except Exception as e: # pylint: disable=W0718
|
||||
warnings.warn(f"Error parsing dates: {e}")
|
||||
df["Date"] = df["Date"].astype(str)
|
||||
|
||||
# Set Date as index
|
||||
df = df.set_index("Date")
|
||||
df = df.sort_index()
|
||||
dataframes.append(df)
|
||||
|
||||
# Get metadata from the table
|
||||
table_meta_desc = table["meta"].strip()
|
||||
|
||||
# Determine frequency from the table's metadata
|
||||
frequency = "monthly"
|
||||
if "Annual" in table_meta_desc:
|
||||
frequency = "annual"
|
||||
|
||||
# Create metadata entry
|
||||
table_meta = {
|
||||
"description": f"### {table_meta_desc}\n\n"
|
||||
+ general_description.replace("\n", " ")
|
||||
+ "\n\n",
|
||||
"frequency": frequency,
|
||||
"formations": headers[1:],
|
||||
}
|
||||
metadata.append(table_meta)
|
||||
|
||||
return dataframes, metadata
|
||||
|
||||
|
||||
def read_dat_file(data: str) -> list:
|
||||
"""Parse the raw data from a .dat file into a list of dictionaries representing tables.
|
||||
|
||||
Note: This function is not intended for direct use,
|
||||
it is called by `get_international_portfolio`.
|
||||
"""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
import re
|
||||
|
||||
lines = data.splitlines()
|
||||
tables: list = []
|
||||
|
||||
i = 0
|
||||
|
||||
current_table: dict = {}
|
||||
while i < len(lines):
|
||||
# Check for table separator or new table metadata indicator
|
||||
if re.match(r"\s*,", lines[i]) or (
|
||||
i > 1
|
||||
and "Data" in lines[i]
|
||||
and "current_table" in locals()
|
||||
and current_table["rows"]
|
||||
):
|
||||
# Add current table if it exists and has rows
|
||||
if "current_table" in locals() and current_table["rows"]:
|
||||
tables.append(current_table)
|
||||
|
||||
# If this is a separator line, skip it
|
||||
if re.match(r"\s*,", lines[i]):
|
||||
i += 1
|
||||
continue
|
||||
|
||||
# Start a new table
|
||||
current_table = {"meta": "", "spanners": "", "headers": [], "rows": []}
|
||||
meta_lines = []
|
||||
|
||||
# Process metadata (which may span multiple lines)
|
||||
while i < len(lines):
|
||||
line = lines[i].strip()
|
||||
# Check if this line looks like the start of data or spanner rows
|
||||
if (
|
||||
"--" in line # Spanner line
|
||||
or "Firms" in line.split()
|
||||
and any(c.isdigit() for c in lines[i + 1])
|
||||
if i + 1 < len(lines)
|
||||
else False # Firms header
|
||||
or line in ["", " "] # Empty separator
|
||||
or (line and line[0].isdigit() and len(line.split()) > 2) # Data row
|
||||
):
|
||||
break
|
||||
|
||||
if line: # Only add non-empty lines
|
||||
meta_lines.append(line)
|
||||
i += 1
|
||||
|
||||
# Join all metadata lines
|
||||
current_table["meta"] = "\n".join(meta_lines)
|
||||
|
||||
# Process spanners if we have a line with dashes
|
||||
if i < len(lines) and "--" in lines[i]:
|
||||
current_table["spanners"] = lines[i]
|
||||
i += 1
|
||||
else:
|
||||
# No spanners line found
|
||||
current_table["spanners"] = "" # Empty spanners for tables like "Firms"
|
||||
|
||||
# Process headers - handle special case for "Firms" tables
|
||||
if i < len(lines):
|
||||
header_line = lines[i].strip()
|
||||
# Check if this is a "Firms" table with its specific format
|
||||
if (
|
||||
"Firms" in header_line.split()
|
||||
or header_line
|
||||
and not header_line[0].isdigit()
|
||||
):
|
||||
current_table["headers"] = ["Date"] + header_line.split()
|
||||
i += 1
|
||||
elif "Firms" in current_table["meta"]:
|
||||
# Default headers for Firms tables if header row is missing
|
||||
current_table["headers"] = [
|
||||
"Date",
|
||||
"Firms",
|
||||
"B/M",
|
||||
"E/P",
|
||||
"CE/P",
|
||||
"Yld",
|
||||
]
|
||||
else:
|
||||
# Skip this table - malformed
|
||||
while i < len(lines) and not (
|
||||
re.match(r"\s*,", lines[i]) or "Data" in lines[i]
|
||||
):
|
||||
i += 1
|
||||
continue
|
||||
|
||||
# Process rows until next separator or next table start
|
||||
row_count = 0
|
||||
while i < len(lines) and not (
|
||||
re.match(r"\s*,", lines[i]) or "Data" in lines[i]
|
||||
):
|
||||
# Skip copyright lines, empty lines, and other non-data lines
|
||||
if (
|
||||
lines[i].strip()
|
||||
and not lines[i].strip().startswith("Copyright")
|
||||
and "©" not in lines[i]
|
||||
and any(c.isdigit() for c in lines[i])
|
||||
): # Ensure line has at least one digit (likely a date)
|
||||
current_table["rows"].append(lines[i].split())
|
||||
row_count += 1
|
||||
i += 1
|
||||
|
||||
# Add the last table if it has rows
|
||||
if "current_table" in locals() and current_table["rows"]:
|
||||
tables.append(current_table)
|
||||
|
||||
return tables
|
||||
|
||||
|
||||
def get_international_portfolio_data(
|
||||
index: Optional[str] = None,
|
||||
country: Optional[str] = None,
|
||||
dividends: bool = True,
|
||||
) -> str:
|
||||
"""Download and extract the international index or country portfolio data.
|
||||
|
||||
Note: Not intended for direct use, this function is called by `get_international_portfolio`.
|
||||
"""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
import zipfile
|
||||
from io import BytesIO
|
||||
|
||||
url: str = ""
|
||||
data: str = ""
|
||||
if not index and not country:
|
||||
raise ValueError("Please provide either an index or a country.")
|
||||
if index and country:
|
||||
raise ValueError(
|
||||
"Please provide either an index or a country, not both at the same time."
|
||||
)
|
||||
if index:
|
||||
index = INTERNATIONAL_INDEX_PORTFOLIO_FILES.get(index)
|
||||
|
||||
if not index:
|
||||
raise ValueError(
|
||||
f"Index {index} not found in available indexes: "
|
||||
+ f"{INTERNATIONAL_INDEX_PORTFOLIO_FILES}"
|
||||
)
|
||||
url = (
|
||||
BASE_URL
|
||||
+ INTERNATIONAL_INDEX_PORTFOLIOS_URLS["dividends" if dividends else "ex"]
|
||||
)
|
||||
if country:
|
||||
country = country.title().replace("_", " ")
|
||||
if country not in list(COUNTRY_PORTFOLIO_FILES):
|
||||
raise ValueError(
|
||||
f"Country {country} not found in available countries: "
|
||||
+ f"{COUNTRY_PORTFOLIO_FILES}"
|
||||
)
|
||||
url = BASE_URL + COUNTRY_PORTFOLIOS_URLS["dividends" if dividends else "ex"]
|
||||
index = COUNTRY_PORTFOLIO_FILES[country]
|
||||
|
||||
response = download_international_portfolios(url)
|
||||
|
||||
with zipfile.ZipFile(BytesIO(response.content)) as f:
|
||||
filenames = f.namelist()
|
||||
|
||||
if index in filenames:
|
||||
try:
|
||||
with f.open(index) as file:
|
||||
data = file.read().decode("utf-8")
|
||||
except UnicodeDecodeError:
|
||||
# Fallback to latin-1 encoding if utf-8 fails
|
||||
with f.open(index) as file:
|
||||
data = file.read().decode("latin-1")
|
||||
else:
|
||||
raise ValueError(
|
||||
f"Index {index} not found in available indexes: {filenames}"
|
||||
)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def process_international_portfolio_data(tables: list, dividends: bool = True) -> tuple:
|
||||
"""Convert parsed table dictionaries to pandas DataFrames with proper multi-index columns.
|
||||
|
||||
Note: Not intended for direct use, this function is called by `get_international_portfolio`.
|
||||
"""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
import re # noqa
|
||||
import warnings
|
||||
from pandas import DataFrame, MultiIndex
|
||||
|
||||
dataframes: list = []
|
||||
metadata: list = []
|
||||
|
||||
for table_idx, table in enumerate(tables):
|
||||
# Extract spanner groups
|
||||
spanner_groups = table["spanners"].replace("-", "").split()
|
||||
|
||||
# Create DataFrame from rows
|
||||
rows_data = table.get("rows", [])
|
||||
df = DataFrame(rows_data)
|
||||
|
||||
if df.empty:
|
||||
continue
|
||||
|
||||
# Set column names based on headers
|
||||
headers = table["headers"]
|
||||
if len(headers) == len(df.columns):
|
||||
df.columns = headers
|
||||
|
||||
# Check if this is a special case table with "Firms" column
|
||||
has_firms_column = "Firms" in df.columns
|
||||
|
||||
# Parse and set Date column
|
||||
try:
|
||||
df["Date"] = df["Date"].apply(apply_date)
|
||||
except Exception as e: # pylint: disable=W0718
|
||||
warnings.warn(f"Error parsing dates. Using string conversion. -> {e}")
|
||||
df["Date"] = df["Date"].astype(str)
|
||||
|
||||
# Set Date as index (or Date and Mkt if applicable)
|
||||
df = (
|
||||
df.set_index(["Date", "Mkt"])
|
||||
if "Mkt" in df.columns and not has_firms_column
|
||||
else df.set_index("Date")
|
||||
)
|
||||
|
||||
# Create multi-index columns only for regular tables (not those with Firms)
|
||||
if not has_firms_column and spanner_groups and len(df.columns) > 0:
|
||||
# Create multi-index columns
|
||||
remaining_headers = list(df.columns)
|
||||
bottom_level = remaining_headers
|
||||
|
||||
# Calculate columns per group
|
||||
cols_per_group = len(remaining_headers) // len(spanner_groups)
|
||||
|
||||
# Create top level for multi-index
|
||||
top_level = []
|
||||
for group in spanner_groups:
|
||||
top_level.extend([group] * cols_per_group)
|
||||
|
||||
# Handle Zero column specially
|
||||
if "Zero" in remaining_headers:
|
||||
zero_idx = remaining_headers.index("Zero")
|
||||
# Find Yld group
|
||||
for group in spanner_groups:
|
||||
if group.lower() == "yld":
|
||||
# Ensure top_level has enough elements
|
||||
while len(top_level) <= zero_idx:
|
||||
top_level.append("")
|
||||
top_level[zero_idx] = group
|
||||
break
|
||||
|
||||
# Create the multi-index columns
|
||||
if len(top_level) == len(bottom_level):
|
||||
df.columns = MultiIndex.from_arrays([top_level, bottom_level])
|
||||
|
||||
dataframes.append(df)
|
||||
|
||||
# Format metadata for description
|
||||
meta_text = table["meta"].strip().replace("\n", " - ")
|
||||
if dividends is False:
|
||||
meta_text += " - Ex-Dividends"
|
||||
|
||||
# Format metadata nicely, replacing multiple spaces with a single space
|
||||
meta_text = re.sub(r"\s{2,}", " ", meta_text)
|
||||
|
||||
is_annual = (
|
||||
df.index[0][0][-2:] in ["31", 31]
|
||||
if isinstance(df.index, MultiIndex)
|
||||
else df.index[0][-2:] in ["31", 31]
|
||||
)
|
||||
|
||||
table_meta = {
|
||||
"description": meta_text,
|
||||
"frequency": "annual" if is_annual else "monthly",
|
||||
"formations": (
|
||||
[d for d in df.columns.tolist() if d != "Firms"]
|
||||
if has_firms_column
|
||||
else spanner_groups
|
||||
),
|
||||
}
|
||||
metadata.append(table_meta)
|
||||
|
||||
return dataframes, metadata
|
||||
|
||||
|
||||
@lru_cache(maxsize=64)
|
||||
def get_international_portfolio(
|
||||
index: Optional[str] = None,
|
||||
country: Optional[str] = None,
|
||||
dividends: bool = True,
|
||||
frequency: Optional[str] = None,
|
||||
measure: Optional[str] = None,
|
||||
all_data_items_required: Optional[bool] = None,
|
||||
) -> tuple:
|
||||
"""Get the international portfolio data for a given index or country.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
index : Optional[str]
|
||||
The index for which to get the portfolio data. If None, country must be provided.
|
||||
country : Optional[str]
|
||||
The country for which to get the portfolio data. If None, index must be provided.
|
||||
dividends : bool
|
||||
When False, returns data with dividends excluded. Defaults to True.
|
||||
frequency : Optional[str]
|
||||
The frequency of the data to return. Can be 'monthly', or 'annual'.
|
||||
If None, defaults to 'monthly'.
|
||||
measure : Optional[str]
|
||||
The measure of the data to return. Can be 'usd', 'local', or 'ratios'.
|
||||
If None, defaults to 'usd'.
|
||||
all_data_items_required : Optional[bool]
|
||||
Default is True.
|
||||
If True, returns only data for firms with all 4 ratios of B/M, E/P, CE/P, and Yld.
|
||||
When False, returns data for firms with B/M data only.
|
||||
|
||||
Returns
|
||||
-------
|
||||
tuple
|
||||
A tuple containing a list of pandas DataFrames and a list of metadata dictionaries.
|
||||
In most scenarios, there will only be 1 DataFrame and 1 metadata dictionary.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
When an invalid combination of parameters or unsupported values are supplied.
|
||||
"""
|
||||
measure = measure.lower() if measure is not None else "usd"
|
||||
data = get_international_portfolio_data(index, country, dividends)
|
||||
tables = read_dat_file(data)
|
||||
dataframes, metadata = process_international_portfolio_data(tables, dividends)
|
||||
|
||||
if measure and measure not in ["usd", "local", "ratios"]:
|
||||
raise ValueError(
|
||||
f"Measure {measure} not supported. Choose from 'usd', 'local', or 'ratios'."
|
||||
)
|
||||
|
||||
if frequency == "monthly" and measure == "ratios":
|
||||
raise ValueError("Only annual frequency is available for 'ratios' measure.")
|
||||
|
||||
if frequency:
|
||||
dfs = [
|
||||
df
|
||||
for df, meta in zip(dataframes, metadata)
|
||||
if meta["frequency"] == frequency
|
||||
]
|
||||
dfs_meta = [meta for meta in metadata if meta["frequency"] == frequency]
|
||||
else:
|
||||
dfs = dataframes
|
||||
dfs_meta = metadata
|
||||
|
||||
if measure == "local":
|
||||
dfs = [df for df, meta in zip(dfs, dfs_meta) if "Local" in meta["description"]]
|
||||
dfs_meta = [meta for meta in dfs_meta if "Local" in meta["description"]]
|
||||
elif measure == "usd":
|
||||
dfs = [df for df, meta in zip(dfs, dfs_meta) if "Dollar" in meta["description"]]
|
||||
dfs_meta = [meta for meta in dfs_meta if "Dollar" in meta["description"]]
|
||||
elif measure == "ratios":
|
||||
dfs = [df for df, meta in zip(dfs, dfs_meta) if "Ratios" in meta["description"]]
|
||||
dfs_meta = [meta for meta in dfs_meta if "Ratios" in meta["description"]]
|
||||
|
||||
if all_data_items_required is False and measure != "ratios":
|
||||
dfs = [
|
||||
df
|
||||
for df, meta in zip(dfs, dfs_meta)
|
||||
if "Not Reqd" not in meta["description"]
|
||||
]
|
||||
dfs_meta = [
|
||||
meta
|
||||
for meta in dfs_meta
|
||||
if meta.get("description", "").endswith("Not Reqd")
|
||||
]
|
||||
elif all_data_items_required is True:
|
||||
dfs = [
|
||||
df for df, meta in zip(dfs, dfs_meta) if "Required" in meta["description"]
|
||||
]
|
||||
dfs_meta = [meta for meta in dfs_meta if "Required" in meta["description"]]
|
||||
|
||||
return dfs, dfs_meta
|
||||
|
||||
|
||||
@lru_cache(maxsize=64)
|
||||
def get_portfolio_data(
|
||||
dataset: str, frequency: Optional[str] = None, measure: Optional[str] = None
|
||||
) -> tuple:
|
||||
"""Get US portfolio data for a given dataset.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
dataset : str
|
||||
The dataset to retrieve. Must be one of the available datasets in DATASET_CHOICES.
|
||||
frequency : Optional[str]
|
||||
The frequency of the data to return. Can be 'monthly', 'annual', or 'daily'.
|
||||
If None, defaults to 'monthly'.
|
||||
measure : Optional[str]
|
||||
The measure of the data to return.
|
||||
Can be 'value', 'equal', 'number_of_firms', or 'firm_size'.
|
||||
If None, defaults to 'value'.
|
||||
|
||||
Returns
|
||||
-------
|
||||
tuple
|
||||
A tuple containing a list of pandas DataFrames and a list of metadata dictionaries.
|
||||
In most scenarios, there will only be 1 DataFrame and 1 metadata dictionary.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
When an invalid combination of parameters or unsupported values are supplied.
|
||||
"""
|
||||
if frequency and frequency.lower() not in ["monthly", "annual", "daily"]:
|
||||
raise ValueError(
|
||||
f"Frequency {frequency} not supported. Choose from 'monthly', 'annual', or 'daily'."
|
||||
)
|
||||
if measure and measure not in ["value", "equal", "number_of_firms", "firm_size"]:
|
||||
raise ValueError(
|
||||
f"Measure {measure} not supported. "
|
||||
+ "Choose from 'value', 'equal', 'number_of_firms', or 'firm_size'."
|
||||
)
|
||||
if measure in ["number_of_firms", "firm_size"] and frequency == "annual":
|
||||
raise ValueError(
|
||||
f"Measure '{measure}' is only available for monthly frequency."
|
||||
)
|
||||
if "Factor" in dataset:
|
||||
measure = None
|
||||
|
||||
file = download_file(dataset)
|
||||
table, desc = read_csv_file(file)
|
||||
dfs, metadata = process_csv_tables(table, desc)
|
||||
|
||||
if frequency:
|
||||
out_dfs = [
|
||||
df
|
||||
for df, meta in zip(dfs, metadata)
|
||||
if meta["frequency"].lower() == frequency.lower()
|
||||
]
|
||||
out_metadata = [
|
||||
meta for meta in metadata if meta["frequency"].lower() == frequency.lower()
|
||||
]
|
||||
else:
|
||||
out_dfs = dfs
|
||||
out_metadata = metadata
|
||||
|
||||
if measure is not None:
|
||||
if measure in ["value", "equal"]:
|
||||
out_dfs = [
|
||||
df
|
||||
for df, meta in zip(out_dfs, out_metadata)
|
||||
if "--" in meta["description"]
|
||||
and measure.lower() in meta["description"].split(" -- ")[0].lower()
|
||||
]
|
||||
out_metadata = [
|
||||
meta
|
||||
for meta in out_metadata
|
||||
if "--" in meta["description"]
|
||||
and measure.lower() in meta["description"].split(" -- ")[0].lower()
|
||||
]
|
||||
elif measure == "number_of_firms":
|
||||
out_dfs = [
|
||||
df
|
||||
for df, meta in zip(out_dfs, out_metadata)
|
||||
if "Number of Firms" in meta["description"]
|
||||
]
|
||||
out_metadata = [
|
||||
meta
|
||||
for meta in out_metadata
|
||||
if "Number of Firms" in meta["description"]
|
||||
]
|
||||
elif measure == "firm_size":
|
||||
out_dfs = [
|
||||
df
|
||||
for df, meta in zip(out_dfs, out_metadata)
|
||||
if "Average Firm Size" in meta["description"]
|
||||
]
|
||||
out_metadata = [
|
||||
meta
|
||||
for meta in out_metadata
|
||||
if "Average Firm Size" in meta["description"]
|
||||
]
|
||||
|
||||
return out_dfs, out_metadata
|
||||
|
||||
|
||||
@lru_cache(maxsize=8)
|
||||
def get_breakpoint_data(
|
||||
breakpoint_type: str,
|
||||
) -> tuple:
|
||||
"""Get US breakpoint data for a given dataset.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
breakpoint_type : str
|
||||
The breakpoint to retrieve. Must be one of the available breakpoints in BREAKPOINT_FILES.
|
||||
|
||||
Returns
|
||||
-------
|
||||
tuple
|
||||
A tuple containing a pandas DataFrames a metadata dictionary.
|
||||
"""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from io import StringIO # noqa
|
||||
from pandas import offsets, read_csv, to_datetime
|
||||
|
||||
col_names = [
|
||||
"num_firms",
|
||||
"percentile_5",
|
||||
"percentile_10",
|
||||
"percentile_15",
|
||||
"percentile_20",
|
||||
"percentile_25",
|
||||
"percentile_30",
|
||||
"percentile_35",
|
||||
"percentile_40",
|
||||
"percentile_45",
|
||||
"percentile_50",
|
||||
"percentile_55",
|
||||
"percentile_60",
|
||||
"percentile_65",
|
||||
"percentile_70",
|
||||
"percentile_75",
|
||||
"percentile_80",
|
||||
"percentile_85",
|
||||
"percentile_90",
|
||||
"percentile_95",
|
||||
"percentile_100",
|
||||
]
|
||||
breakpoint_file = BREAKPOINT_FILES.get(breakpoint_type)
|
||||
file = download_file(breakpoint_file)
|
||||
metadata = ""
|
||||
|
||||
for line in file.splitlines()[:3]:
|
||||
if not line.strip() or line.strip().startswith("19"):
|
||||
break
|
||||
metadata += line.strip() + " "
|
||||
|
||||
metadata = metadata.strip()
|
||||
|
||||
ratio_breakpoints = [
|
||||
"be-me",
|
||||
"e-p",
|
||||
"cf-p",
|
||||
"d-p",
|
||||
]
|
||||
|
||||
if breakpoint_type in ratio_breakpoints:
|
||||
col_names = ["num_firms_less_than_0", "num_firms_greater_than_0"] + col_names[
|
||||
1:
|
||||
]
|
||||
|
||||
breakpoint_data = StringIO(file)
|
||||
df = read_csv(
|
||||
breakpoint_data,
|
||||
skiprows=1 if breakpoint_type == "me" else 3,
|
||||
index_col=None,
|
||||
header=0,
|
||||
names=col_names,
|
||||
skipfooter=1,
|
||||
engine="python",
|
||||
).reset_index()
|
||||
df = df.rename(columns={"index": "date"})
|
||||
df.date = df.date.apply(
|
||||
lambda x: (
|
||||
(to_datetime(x, format="%Y%m") + offsets.MonthEnd(0)).strftime("%Y-%m-%d")
|
||||
if len(str(x)) == 6
|
||||
else str(x) + "-12-31"
|
||||
)
|
||||
)
|
||||
|
||||
return [df], [metadata]
|
||||
1741
openbb_platform/providers/famafrench/poetry.lock
generated
vendored
Normal file
1741
openbb_platform/providers/famafrench/poetry.lock
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
25
openbb_platform/providers/famafrench/pyproject.toml
vendored
Normal file
25
openbb_platform/providers/famafrench/pyproject.toml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
[tool.poetry]
|
||||
name = "openbb-famafrench"
|
||||
version = "1.0.0"
|
||||
description = "Fama-French data integration for OpenBB Platform."
|
||||
authors = ["OpenBB Team <hello@openbb.co>"]
|
||||
license = "AGPL-3.0-only"
|
||||
readme = "README.md"
|
||||
packages = [{ include = "openbb_famafrench" }]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.9.21,<3.13"
|
||||
openbb-core = "^1.4.7"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
[tool.poetry.plugins."openbb_provider_extension"]
|
||||
famafranch = "openbb_famafrench:famafrench_provider"
|
||||
|
||||
[tool.poetry.plugins."openbb_core_extension"]
|
||||
famafrench = "openbb_famafrench.famafrench_router:router"
|
||||
1
openbb_platform/providers/famafrench/tests/__init__.py
Normal file
1
openbb_platform/providers/famafrench/tests/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""OpenBB Fama-French Tests Module."""
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,105 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Connection:
|
||||
- keep-alive
|
||||
method: GET
|
||||
uri: https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/OP_Breakpoints_CSV.zip
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
AGQAAAAnDwAAAAA=
|
||||
headers:
|
||||
accept-ranges:
|
||||
- bytes
|
||||
content-length:
|
||||
- '4001'
|
||||
content-type:
|
||||
- application/x-zip-compressed
|
||||
date:
|
||||
- Mon, 07 Jul 2025 04:22:15 GMT
|
||||
etag:
|
||||
- '"804fcbe2cb71db1:0"'
|
||||
last-modified:
|
||||
- Tue, 28 Jan 2025 21:30:43 GMT
|
||||
server:
|
||||
- Microsoft-IIS/10.0
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
@@ -0,0 +1,105 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate, br, zstd
|
||||
Connection:
|
||||
- keep-alive
|
||||
method: GET
|
||||
uri: https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/OP_Breakpoints_CSV.zip
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
AGQAAAAnDwAAAAA=
|
||||
headers:
|
||||
accept-ranges:
|
||||
- bytes
|
||||
content-length:
|
||||
- '4001'
|
||||
content-type:
|
||||
- application/x-zip-compressed
|
||||
date:
|
||||
- Mon, 07 Jul 2025 04:50:30 GMT
|
||||
etag:
|
||||
- '"804fcbe2cb71db1:0"'
|
||||
last-modified:
|
||||
- Tue, 28 Jan 2025 21:30:43 GMT
|
||||
server:
|
||||
- Microsoft-IIS/10.0
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
@@ -0,0 +1,251 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Connection:
|
||||
- keep-alive
|
||||
method: GET
|
||||
uri: https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/F-F_Research_Data_Factors_CSV.zip
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
UEsDBBQAAAAIAAdQw1ofcX3rei8AANeUAAAdAAAARi1GX1Jlc2VhcmNoX0RhdGFfRmFjdG9ycy5j
|
||||
c3ZslV2OUzEMhd+R2MNdQBrFdn4fAYFAYiTEwAIKdJiKoZXajoDd03Ni4D7wEl3dL3bsE9v5cL8/
|
||||
L3f7h93yY3tePp9228vuy/J43h++Lpf73aJJS8rLi/e375Yv28v20/a8i0+ffLgi2Xw/Hi73y4fn
|
||||
+4eH5XQ15I7l8XDZP8Awp7JsT7vl7nT8vrz59Ol4OR8Py7Pz+fh5f919jsvtZXu64ChuoUkNy+X/
|
||||
zhEoPb14uTw/3j1bPt5et93MbdfAz4+nXwu3vzl82f28Rvn0Sbj5dtm8fxVub56H1zdvw/tXT5/I
|
||||
0Jpa0NhH2GgsBauNkKKq036lNYeNRMnBYhfA4hA7rQNavX6mAmgTSgobi9rCJsE0xa7YrU4laCyZ
|
||||
ULBWARWnilMV/1ODY3jXTtiS8H/BahpyLJ0xOcUfgRETawpWnVlALIi3NaYKS0tOEWSGJRWoZe21
|
||||
hBJzCQKNcuxpbVf/uipC37o+s4UWtboWkNHWtj1IHAOptIY9vawzHSH7/5qwpzRQmRQC56gjaEyG
|
||||
z0xanEqosSgk6NSrr03xn7c3OmNSQCXsSfyoHDUxMqFfpwqDynpJFbhCNzPHFnpsTMimaxoPpxlO
|
||||
oSCLScv6WKrLgFk5iRqrw4oEB0GbxQAqTpF4Na9DBJ/Xtj3UPwFnrGJrCv06SiXjwA5LbZNJChIN
|
||||
larTEDCLQwkiKOoNV50FY92pYivlG8aQlHVMOpKEHCuLwgocKKhlp0r5MlcLEmsFrU7prhcKItCs
|
||||
rW1zkJibXyoOX5miZyrvpcTMNigMMzuuYUB8Zoq1Id+iTlEQuSNmylV5rDnsodNoxEYZZvoOBw8s
|
||||
QTypxrlRJhUciG5lQiW0eXu5OkZL4YaYdQ9lThlrjjVI1A5bOJqjxqmlJKFgsljMA+n6AHCoGEFp
|
||||
FpMvlpxZaGgQizb4mwE7ozY+f+bqbUkMILxc9ZAoo1bHVyA1JgpZBusO2COmyoIC8HHRSJPTGSNd
|
||||
z0JHdGk4HVMqAc8C0ZPPcnJE030caKIea3MRtl1GSCxNznqxSRFTi519WBt81/FPTEkSKvrZUHw9
|
||||
agYrzjQI785mEVTDqdmhsSYLutA4JRNPdYoqTTHNUadYjdbdOcQ2DMECDE/ClBzXcKXDKAX7taW1
|
||||
dYNFNbQM54OSVqfdW1h5W+K25hQGPbZMHSmO5hWXFJpPdkXm7EZJDgWdIgUdlRCcUMvmVJlUQRWw
|
||||
8IdzJdckbF32o4Th9WUOlS8Vn3Puy21NMSQFJYQx+DdlqY6RTYsjz8mhMTVQcQqvfORyVMFdpE69
|
||||
HFd/xqhaib0AqsMWzGIVf7Ks+EA0xz1Yg0ZiKD7D07PGvJ0xh3CB1tZWWBIFk5n1YMnktjpd2Awd
|
||||
j223uXessULK30yXW67DMAhEN2RFBmyw97+xqxlz1fmJ2p5ACB4edVQHiqs70DTSgHDe2VaMRHjC
|
||||
cFT7c8aXwSjf2hJ9Q4zAnOQEry641WyNOKiygIAc8qBGmu7h9q1Arm4OO1+mGFPasDhfvo7DmL0p
|
||||
VZMLgE+PqfQMwzCk8kDnHhLyS2BuNphDwZSJOftIT9pZ+Lyu5MSgyVssxsLsLLX1Yb0JJoK7cg4L
|
||||
mXYkygICs2wV7MbeqsYMgJtUW7YF9tOWgUImokAr2NoC1JpSUc73CSrlTsUJM6P2Dq5nKy1ki9qE
|
||||
gPmlUm/AzNq8wM5K2esPbxRPXN0EG3/KhP5eD5tKbZwvIMnsma2wUxyfc9KYhLQnOz2FfJOZKaXO
|
||||
gwEN9rV1QL0p81fPwwsq1HiNy73Q8M7ri1LI+ZDd5XFSCnPs7wbPLmjvSustBo5SSfgWdt72ld+b
|
||||
QlfZBXMu7lwS1KmxJIPLDHf4UGhjofsuuDY0SskCOwbPkxWtckoGce7YOBdIYyt0vDdtFtITyvCF
|
||||
eU9uKyrhhISxYlGeb1gdxXv0FDl4472VJbcMpp1na3QcTQsKQmucBUuNiP2dJcolqq56vWD1P9ru
|
||||
Ejsm1qjK2HBqYmhw5Yn/CU/ymh/4QqqDqW9NT7KaMAwOTVayaKAmjpjhJvKquam3MXv2w+qbSy1Z
|
||||
uZGUtb/CAI7Gm1OYLvL+cDZOTrQAuIaruVrXOPgd6w8upuzAFL93y/KtQV/OqUQF9v6zydfjyO6F
|
||||
RGjNchFrM7ZohrWTO6BSf2MYrt+4WvXL85kGpwfyX/QcCv1/tC8DvKUQ5fsSsThKg0MRye4b1rAF
|
||||
3wlBMnSBm605ub5Wd0ZxnsMD8l79d6kU1qhuhnewNvSpbNvJ62LW64htlzBoyqLnj1LLhwuNjS3a
|
||||
ATPevti0NvU1+eBs7tBwAfDot7zPnW/UgAJAQP6ibu4jUDksPgcUFlz1Z/BlNg7ba6jxwjdDWSdB
|
||||
TH30RouC18NTKHWdCCvYgt8/Nz+KCz3N+WL43UL9Hi7Uh2q9fY4a1R3G3og1srDfVIpvY/J20IRO
|
||||
6op3Mwpqc215y/5U7MgSeyj1bT/bPzLNJLeCEAaiF2KBbcb7XyyqskmX9DctJa8NtPGcjN6rKWIt
|
||||
nHWqUm+Gjtir6I6lMJqz4KhE7VvhSOeKV+u7Qri1w3uhFX8RBrZVL6w3mshJ1jkqzdiKzWpAVL5C
|
||||
yJznVpfcaX1Cb+McL6rPsyHrWm+RSTuC2U0ZDXrhYy9vdyn0Sk1eHeoRDRs0nDYBUZRYciLLomJk
|
||||
Yl+NsorjzV76zXpUGHPeWDwZdDJMRXkzsf8nUcv0UAt+G3jDftgGw2OPJt0b2aFmsWod2roe6QIc
|
||||
vnT59C3YOt2Ggaxvdryyb+r4Tjxzn9UVe6YFCB/4oqbWgeaPA5TNXrrXubyg08pXs2pMbapo0A47
|
||||
SufUlykdDNoEdIV+lU5UZ1W6MVJu0Ci62oudznwWeqjNOEaFzgYnVEn2ZB2Qo6sIgVW8cbhHgxZm
|
||||
HSHModyLbLKV5eCCFueZn5Uig1nFbLrOB6MbKhcOMTnHCGGsPG0xL3K4qixQfgZWxmNcZYOpnyqF
|
||||
yS1h1OtmTZPFurLFXukzsj2V7kxkDB6Gp4dgKjZ6uQVTvNIaPPEVaEmY9Wc5aSvrKMyklX68mbSu
|
||||
YqgoGLg6onH/2OiWZumZz/wqq4T+BtVnKoxWRr3QQASZFxtvHE0XZ7srolQvVFEVbihbbeYwwwyK
|
||||
vsqYlXmL81B7rvRw7AqTzPeGQq7jLKEAvctx6a0c3dUz9LRmrVptVs1xlHkbOZzzYNz6Vp2dtmWv
|
||||
o9ILmzRa5xSZU45QuSpbq8vklSoebVeBwAmW6bIzL7OqwxjK2DpeiLAW1zWhWM+SqKreHSp6cFp6
|
||||
NUve0QXWn0O4MSfEwowtA9MeYpENZQaP7FmxDLEfMOxlkDOGa90wOzkfSO5Mt0eZc6RE16rItxXz
|
||||
kt64FratkGoJ2g8/RNnEdpziHxytK8uxbDaHM2slxdTtIr4GMIWyNqs0ejqdWymkUEtQ65GVvXDr
|
||||
/4ZuzMFTYSZkzw+lTSj1NmqxXMQ+uHO4NqHdmpUr9DekzpLchsIAXIdP0GVCmc2YWCL3PlMplXc3
|
||||
qIOGK11tvmuLDKBK2ZdyZowIsJeyU/0AJH8OfHljI13RyvVXQoZLhujpEDRlVpMyRjo26kodBZNV
|
||||
sR2lwUN4ulEBkZWtVUjZBXOeLi3PVBrt5Dly2OFgt9ho8Y0dMVXRPWfbqdCz0y8UMupV3wSnOkPX
|
||||
3XAqFkV5VDOVPa2GZdl1+BXRGhHf3PEbao3E1qt+gV8xqivkOD7Sl7OMnYqdA4sc/fEqhN5ePQUj
|
||||
d00zrBdzHiroc/srmW/haANK9/T1MBUdn9DNqY2r6OTKB7hqgKvSiz9wx5UlvdKNzDde7RN6JjYW
|
||||
k2tRH1NhFuc0QQh6CLPOgA8WzJgqmBnW+DGDzw56ilZF5pmq97fs7Fk1YO1g8JnKPMPkiz37Kgzc
|
||||
xnptR82LrBdlVOeWrIJCJSeyBK/Ogu2xCmZJnsnCclfFO7uRdPSAvwo8bbD8q+o8tsIL6JC8gNYF
|
||||
5lXapYWuFzzMixoC0QA8TLvc1Ao6Lrui8qY3PoaebUK52VjVl0QxKreXIXjBXjC+v0GuHIEtXXfw
|
||||
Q8vbAlAWpukGZTNgDgf2wgt4BUA2HPcI5rjycok+eX2yNBXMsHBnNnAKK49YXsHSTa2/uXNZtWX3
|
||||
W9QYMb6E0EmtqLfg7/1N8ue3stN+x6Si5jNXmwWd38r+IF9xFQ0UbFT+3Sz8vl3ZrlVaHdlKh4rO
|
||||
1/ungroDRsHVokZ7i04y9EgcOBg9mM9wpadmJ/Y8UeH7Hwvk7O9eV1Lrz1gqQpSeRmFjgOby3qxO
|
||||
3At689d0MEjeb+E/Ls4kSXIcBoIf0oEA9/9/rIwRrhStLmNt7c0NIrHn1BK0S1Qb11w3dCld4tMf
|
||||
ixeFVns1+jeaZkkWCyzZL9maoRLCPXOn4Yc5U3AC7WZt/1eHLffE7jc5VIk6Bneo82eDkKjiEjC1
|
||||
RM5mu7RQu3YV5WnynWmFQVQVGrK4okW0Sw1D0zeFmTk5Y1sJB7c6Cg5gBCx/eca40iETWo+3MCwF
|
||||
CdyrQh0jKLM+P1d5Q7tiSVupZGSHDXL+uDXusIHNp1u1F9qNrnHrV5gY6J+bKp1gfSA9sa7tUJGb
|
||||
uJt4hhMYz9ajUTWqsdkBTKcFVETszLrEeonXHc92/kG5mdw7ClisWjas8g1RLs5+RjGVicPTOkNn
|
||||
v2F/XlOcdobHoQ06nkHBbMhy30Nl4ny1kw/zQftorimM36IDuH/ft/ryx0WDvNJRkr66ogsaLtzQ
|
||||
soB/PYGyVftIQN/2HjnsAxduLn2ImYYS71yEA++uY0NVUKBpTBR9J+rcr8byJTwWqjx16sv5PWrd
|
||||
Ch1PpU+rf/nFLND5K74MK/d579kV3XPcJTqRhahz9tEcQ/PtX1loFee4I7+JO9SpB7QhyfkswHwq
|
||||
Ft9mK/qhTXRayH0+9TzGV2lOYJIJVQ4LM3CNrQ+eVrVd0NgKlHogOfH1s3QoFWVSqekblQNqcyJF
|
||||
jY28l9Ur1j8hyaF7CVxUGQpdjq3fy27KsKKUeFnVfZn4j4Tb6+ANjifl6qNktna8gCmHx32DfrqX
|
||||
pJb7BrudnGaPOBcsuUycOO0PAOvjSJf0AN0SwCavngpnoNQWUJmofPD26BcK4MAuE+pWh+DAeba4
|
||||
7UBXgtYJU99rwY3A/W6w7eZIuVlUqIKtRlGJ2mr9jQNjAcORcL7Qri4wn06OB0PxvSjHcJNGHEpt
|
||||
GTBVt3Hd2G9sWLUGwMPjgySwyexdCSLRAlUCzW60fNJyDx1v9VP6ENXRgUqv2hvtemU31EqVuFDN
|
||||
nfd+t7IigdngqdUw1T50mp7e14EFGCiUt5nZTc7ApGmw/Oq9v57UodrbcAotvkbZClQCbtgAvlmn
|
||||
3IbkePAWFYVobAe3g92e7B1zWFHpBveHbpXerJKA43FbHxocKTao20EmjbuIIip0PbQnSzkTKzDx
|
||||
EfEg06XFh+gwpSHUzXP7pycTquethlNC+mtVZWGmfWC88G9i+i9J61XC/Q3LB9WMK6odNWB1+3+1
|
||||
1cY6FmDTx6CZntc2Yd0+rD8Z6ZoF0xWxRiY62de0mmw5wmui92BnICafltL1t1/XH109o4p17coK
|
||||
Yh3qv9fMGxj2ygKDkg5tgPmV/NbE+r1D0/ZtkXzutLU3YJLdQD0gQ2BFAxD8WPxQhXHD1gkvyyoE
|
||||
qsq+GsUPSO5wg45De5F5Uo/Pva4C5Zy85kqT8gTqMSr4+3JLWQ1l3QT4wFWrhihxnHs1dj+0HDqg
|
||||
8YR7kHC2+rUlvQdJ0sKt16pVtm03VDjKssPevXDQ6PfA+rx3retY5YbtaTTCpsIFQaa1DiaKoBqY
|
||||
DWZTUX4h8PCaUEcqfk6+MiHxgtdDGtMimveqio0ZlS6+X0N9gds3MW8QGl9KL4YsyDVW8uVd2YLE
|
||||
N7YhViwLRelagG+EIRXNaQZMye6wGazWBzVgjURj4Dj2di/ZNZLAOv5Nq75Gi6ESaH374aURwM59
|
||||
s0XUbjuDD7uAqhnbmVFSNi8YUpA4e8SOuWHxM1wjSWR81J4gwju01U8KvYSSD9ZbFPVywdJWuNo7
|
||||
ytRJYFWCa2ef++cMDSDxG+0b0wvC+s/A4/f1iypHqVvfEI7Gduh8kN7SW9r3yGUlk+Sj9jqwAveT
|
||||
5M5ul89Q93bo8nKVLhY431i3GNd2XqWQ2JjLORj2y1T5VA7ehgamc6dUetPfa1Kg+0hDhyR8u4Y2
|
||||
a79K6qeOz1tx3KZkBokULkyAB5cvKPLue+KJv/L6Zju+TSlum7J4ZET7PbHVgqenA08xgqnrm4MG
|
||||
jqQC2oGh0s4Rk7dd75FO/Sk7YIX0wRO2rSPypXq9BdEqLB85GZVYJiWlAaxueSIe42dzsCZXQ3+t
|
||||
gRJRAjvREVH6cjAPlBWjwxCWEzb1Uz/3ROEIvpOiaiXOc1IeJ3D7HVXSB21eI6PgqYQ2W9nshgZ9
|
||||
hvK339r8AKY7lbr0BZqPk6zix4eUGh2TBehWsMaPGoL3uaG2tl+SboguqBqs86xqK+BDA7vL1DRB
|
||||
rzysw5SOoY4gZ+QeSOmYDp5OgLqgqk51PAzHvS1hmxoWZc97O+yNxF+ynwaMpx+YFN720KzApG5Z
|
||||
KZO2b9pdgk5edLyP0qEU5l05OMA3cUDfbu+CcFvetJF8wp6XvCfudmQ/jyA/GSlkm6rQdB2IL9MD
|
||||
PN8+3mrrG+ueeqEa5UVWUhYFuKkABH3G6cVNVdhUNmlLZiFYgPZay9WfqpkTnG+ppdIdu9xBffBU
|
||||
3IZi2KF3p6mBrtkRplDoGgms1mWicS6ITjuhRzzuahxnCv1H5zXuChcL2cdqYfcKlW3TkTxr09gF
|
||||
VXUof9WFXXVcQ0m5lzeSb3FPu90eslQA7kAEEVotpVslhAxdGlGiNl9Yudvrhqn+Ql/+4B6nWMjj
|
||||
XSrKrZ/JXLD0DgNnL61cgPVphNJFy2pkAcpt6L9s5bIzAuy0bFF5eH37DR5ccdKSb2w3wZJAM6bn
|
||||
Q2oNvFRDpA2WulabwI3n6iIAvWEVGkUzp5Ss/ci4cTjGUQbANnbeOJ/l9E3yy+MPpvui1Osps586
|
||||
L0y+rjMsX6mnAyuuYNG0BJQ5oYTGeDOl3tMqxNzabei/dvqgrh1rwNIfxz3W0cQnoiE5BXQ9VRcR
|
||||
s9LvofpuvMkxfr5JMyX1S8sVwW8rwPiVjUJFaksQmAgiKLzGRVV+Y0/8LqPoVULdzdppXAouRUKr
|
||||
rRzledznNqBNntjS2HaM0tYRoNqKf2eGY3hoQH8Z43ToEe2m0538U7qi27UZDegFk/iPZOksUDWh
|
||||
Nec9E128zGi4qIReGKbRocds+ef4E6dW5xngt/RPr1qJb0+tBPWFfeTR/eJHBX7llvK1ES1glQjy
|
||||
SWcKEMSANhr8SVE49Tk7VL7a9F2saNwLD6RLrtLPZxSofhlor+NsOfSnFy513Lw556SaBtVFDgd9
|
||||
OeUmyDSaRjk/IojfL9C2vewOPqChveILsnsDp8apeu74Mr99nUAuqnKuMl8LP31B8+l+cmrSxvWt
|
||||
wPro2cl6J35FwFTESJ32619qDdqfrt88Scjypi6ofuOp88sLu6edxANamIxVW8D1fp2KHHbceLtr
|
||||
g3tFDr5zGHkVNbUbx1UHDmAoiUsGLf0+WgDTIdOXRivfqsO/8IzuMy0ilQlMlxDGedUdZ7vB5Cjm
|
||||
91HDFRSohEqmcQnbmwRrr3hlUpL28llXIi6DGh2RdqvAiStDon+2a8daCy2jrzb3vex+0iP17/Cp
|
||||
OZB9ipb019Cr0gLqQMPOMVWdVmD5dHdCSyh5sfkLO5qbymtqHmCScQ0+mXPpwEoOpzis4//tAnSH
|
||||
iLYpn3zdsFOWw7tcWG5ByXbqljhZm9duCZclpi1aJD6oQy4aL2T5JT/oJmsf6LUknhGlBrfd3Bss
|
||||
u4HySJUmVwLIlWFYPsxahy3/N3CVILevIAsxAKm/yRfu9uQPHEBSKtWZA2ovMLVZT34SXWnMa0BS
|
||||
lNZoeLU9gAP5cS1HuUbKxvk4dvcEB1CumrKU9HDdcDvFgQsZRAVpqmRfyD/fMulYzwWOJymljc9i
|
||||
FCBdoX6GSWLLI3cJK8l6Dpnk/SYs318yIsB5YAXW8yAmHU8YshVAHcOpJS2sLRRgp58Ae10FE0ib
|
||||
VNDtKxawaXMXKIV7r/7Bd6MZQfHABfflIkj025bTOIpDLiXsNXpViQwc/v9cJHFihp4rMM9OlruT
|
||||
35TX7gf+cXVmuXKDQBTdkJ/kKub9byzqew8G5SeKcgK2Mabm6ulOKO0l93i7V8zwpOkAsILuOmKo
|
||||
Sg31vjv+gyXPbcDrQyBAe5W0S5gkW3dEFg1tMs6x4/nEHYPvhrLjqM3QdXPpgwFqyZUn70PU2htw
|
||||
7b2zOhakNBZBRTjl/Ss2qu8lUvpO/7pWkfy8uikS34cCcelAL5/hWk4/0k+AjaoLAVNP9hXhrPGD
|
||||
A6jkqLHzW3toaWGVLMtq/0naaQ1sn1/PX2rRwWKI6V3ZbOSDlE3HriDgWOayFSwNFWnxkyJDdELX
|
||||
dnSkddG4xyr/bKX8qwQ5z/PICUfam5J1QgsBTMqFZYIgSqehw29s0VRcV/SF4vJxeKjT2SqB3teJ
|
||||
44vQ05rQ+hTCIfXzBEYBNrxQr8+OofXvQGKc39o3zbvp2L1sKMXQO2/A+YQ/uMo71fnRoYuuUxIK
|
||||
iKcw+21g2reUqfWy1SCKFSdfUjllHgWo//k1uSADog/R8oblVrJSw7WewHROeNGbwapJmCRb+ItM
|
||||
Ji2w+nQsUf0hOypgpE920lTre1+w74SRVbAcr1sd2ljdkp9E9lEN0chojfajLK0oG2Pn0a2bxbsN
|
||||
iuImb6vfNCxAcqea2yYE2m+xjY2db1dEq92VKwkK0E+DiasNZJwaapHkXBRoIfKIN7Hc81b8JMQC
|
||||
+SYY6TDGml98zIYYsBOwJprFDTfosM/i5Npp4oROFYCPq0UVEkwYAfdaYWyohN0QA9mKeGjnKiYL
|
||||
jbOMI90C4jyug5v2a5Fzd479prrNNeh30kiFaMDE37FDMzbqgMWHJAkF2/BOKL5pKpOtYg2gxBu5
|
||||
IhaM/jygxDd3ZpnLtGH7IZMr97wvKskvm59vvZ6xWG4tGEbPmP6axivllo4yZIn0BgwaGHF+L40M
|
||||
oJbc34/zovsZ2r0qDeXVrHVY/opmr5h1x5YUlTWyQrQ6bH7uF9NNEnXYn6B9kdCGbxV9nBZ8C6rQ
|
||||
vbUoqR3vNVTGMd9zLaSUHTqfTrRMHZDoOQdcSqygRrZgYjVDLbBzQlmmvIY6XjtO7Y6N2gXNHfsj
|
||||
7NrP0wzbxrXtnHFO25rg/NlzbqJ2xF0BFgL66HhiA6Z7tVI/fAoJV7ATuXntO0A9gQoshCaQZNZK
|
||||
bDioI6Ax5fIaAudDC7MTSr7uyf1GqcTaxlszlGksEe+2FhWx84JDDjRKzgth6AZMl4W/uyfmtfzT
|
||||
FkaQFFot2ROo9R2DWo5tc3dgIQLadTyw+BVYH68A/RjjHtj2OZlKECBcEVBZxxOpsr07CzhOmCuL
|
||||
EsfvoRL/Bd0icest4HrE8HqQEdrTVFpwdJqVJQdpAMOxDmr7Am/igFJx9dU2lCPu1xt8U0mEMXRq
|
||||
AS1OrC2crkLAQh9L+/Wr/warrtn9E6R+79DmI5+wBUHgsaDdIQ4B1YBYuELHM6h49VNPjX2hk0Ay
|
||||
N5ZHy8CKG/1LZE9OWVFrEl3KI+WKtpDB0novZ1RoERc0pQCTfyghutdpva+2/jw9PabvD5rbvl2+
|
||||
nYtphaerVk9ooQKl+uqANeaRF7g9kxq61o86NqH90+eLLQq0TlFv4kWUHbXzDJakszu1+Ohqwh2s
|
||||
ECF9X7TBER2i8W7FancTnNfUknX+oJJIwVkOEla1VRwoOPOGs6xlKsxTMJpAybolPeE4tKYhPmDk
|
||||
aBANr8CK7cghXW3TApuThU9WmeYdprS/rU5ECAKfCVSn3uo9fq66oNOO0y9r1NFw4O4zRiE1kg7q
|
||||
fGC7NrByzlXtZs/36KDDOSBg9/xsHJv04ECurHyD2tKpRlOE8yow9Yje3t3naU5YcXkNT1t2jAu6
|
||||
a8+6ipZJ7Elg+/ITJKTvabGXi6SuRH69R46vSKRewcmA+mMVjtNWNTsYJ+Tu0RM31BLLvKLI2w5J
|
||||
YNAomZfT8oZ6pRL7jVjrfpoiEbWKT2m6GWaBJeELtbbt3tyZQHnZ8Rni2MsGs31MmeJJl4SqgSsO
|
||||
b5qknWk5KFFnudkGHF/m/OoYvWda+Sm/iviY98BFGQvFC6SMdtOgr0nQLW/4OYGxFTQyEMENnF7W
|
||||
4GW1s371xTCnNXO8Z9xuUNnQZfcbC2hxRyuKVYhh54BWnV2fLtv7DZsUJfS4HRNOQxwRnxOIDzGg
|
||||
A5ue7MvubQ9UztguUeKVlgHcXQY9OeM3jdcHPmXA3HCZUOIQuhb28jU2twoVw5L7HJMKwdG4oalJ
|
||||
vGAC86GlHBa84AuUkuSt8J7q7Q6tPxp8vqx+bcCmbjUo9ckpXYHdjeQdR0tshQHU2UBzH7y9Z1pa
|
||||
c+HP6WIMtI7WvYAnolVMwxYc+Tt44s9gedJWJ3V7S4sEkmnylVkdcdC1fellUI5jBphO9g52qU/M
|
||||
BSyuW48tB25W/eE3LXyhLLkDmzMLi+BO00ugngFfoUxdh7Ogw8X2tBOkw2VtUBmNg5avO90tgOtp
|
||||
EtFBudqoZ5O5Dm4OgkS7C2MC3cv6B50Q9l7z4ut5v9qSeR51SHPwa1mUFp/7HcTpdz/W5i1cFtTN
|
||||
VJMq80LpVIHWp9Kxd7iZ2wXVzm/IzZvWZs8bdwTOojx24m8ZMHVNjK8NT5R71t1VffyU0AAGcD3K
|
||||
c+NryGtxyamclLp87zSh8bhPx/YceyMBvQNp1Fh4aVNwvkEUMvxi+Z6KqRSzl6fQKXrmnY6IdnRu
|
||||
+qAAZb+xqp3Y6JlVWry8ufYFVMedod2uaELsydiA6p+qM2AK5tI1eLoTvKz5OlSjc195PZ3TjOgX
|
||||
dqWo2p+p2JU/ix43oVhiFGuhzYShTGQSxKyZtXNyLzmCMbEc8fjBBiQjQGFQydZ206KhevlOQrpO
|
||||
NOw4UoMp5igD1ojjFGcGo9QBO4b5nf5YX+DJO6rWwOb9MNbCnf2gjXPvCjIrNXUkVtGhWmIrk6uS
|
||||
HHnR8GboOkYaRW0d+NuLXUXUSgvt212Q7ysjrlJFdE7wGlAsk7Tpv4h6F2h5mnODx+/ikxTyAVUx
|
||||
UdkVaN0R/tqhOtGgSoVcMkWg3bGDcM7aJFURylbeKSXk9dQJnfr0ToF/GffM6/zexOm02MI0SP7i
|
||||
x08aTqEODTfU/rK087/RWMs6/If1F64b2snZfsvg6JxgBaYm1k3T4BkDxfwHBppf3/0FawKVOVZI
|
||||
ZazWZ8sC0oLNJxgnTcI6GRhdqtPWsLkmrpOdA1R3Xqcp/bte6zgUYpQQlCG3ZATS7K3lNXG8vpuh
|
||||
FJmxC1GA8Vu4ghcvqZodQGnC4RwO3A3RxNJn8A7Hl53LAkx7xVF2cWFHgRabrMQH33kxUtLil7CZ
|
||||
uOPPNdt2BRdyP+6LOgc7y044LuOe1zHdpdkbB+o1s+1y3ECFyzIx3dEk72r6WD3UHYIrIoLitkNp
|
||||
bFIoOgzBBKYkeqfQKzFzQrS8gS8GN97uwQO1Um+ztJ4fYVrgYls4EE0R99j6TMKsHRl8WHsklXbs
|
||||
/L0n7VhVpyHbGTck6uVXPW2jB3AapjdMrzdbZDjfJZDvNPQpTFOqpD/+gAV1CRbcI2+WqpInSo1X
|
||||
lkltxEV7tk/WA2H0PcIrRLOvDixkiVF5Rwcs4LaS/kT/CniCG549DUNUnZm7w1vpCGLet0vEs7K3
|
||||
yn5fUMf4sDf31xRA+Xa8oanbPBAb+VOZst8wlHRkJYy1iAZLfe+a8OqZ1EWbt+1oWIV6OxfNh13r
|
||||
nV3jhl9RsEASuwwoWgVReT/Noc2Fz26buwMLFdhtQcuFiac3C2y4eiIJ2YxrILE4Win5S9ShDF0O
|
||||
7+EIZOgytGh76/HJuVgTGr/bjd3KAMUlgLljs7uCvx0x0iXZpArUvo3g0mCJm+U0cHIeJRgXMOZF
|
||||
FxswlxnSQOAr+AL6yLSvQUq9lW9oJ7pN4duud4J6WZ22Lm9V3nQSg6AuYWloApV/9i0hekcY2lOX
|
||||
cnlgNl2QxnFEI6m8gKVukeMY25D7GS/VdEQUsDIqMKmuDT5i+g9BneHwDZ3XGrksjt8ZQnTeEzcC
|
||||
jfcvO9UAdq6638/r5YWO3Vk8qRXv88bza/WD38u6DHSX/qekIvK/QOMlu42A8TQEhntsCtjStt4O
|
||||
5veLTngxzvYnl7IUDPRKFXRAU/tsnWj/8DEFtoVXWW06Jw5gteiieQ7R+5jQ5vbXuTvvvxd0RT2Z
|
||||
VJK998Rs4+a6G3IMogElZGQBKYxx3661s0LPApfunZFy9QxcVgra0SVymhPv1OmvVUM4FDD7vxAD
|
||||
cUW52HqtyS9ql0NLfTBKcFSSkDs9YQNcnoXY0JdGp0VgVffx4da6jQ8mgA0zJbGX475qt/so8WiO
|
||||
fo8cj541HKGd62bzC87awHpvuKz15X59Fzvd/SrBiBjXDUlD645v0fX1pml50fdSxDdzyJZTR2oO
|
||||
d0YCU8espD65U4eVp9N7myLsa9Jqr3V1xdLqN2uqIdbOw01yUQq/uzSQJTOz3JjquN2hq703nPQT
|
||||
Z5vFf2PXs372lStjChsJ6OpkpbhR0XRDEn0KdZfrvSHxejJ+2jUw3vi894mwumB6R4aDaTFvRnZ7
|
||||
Uqs26w0rrt4dGKyiL7RdMYGiwe3GXtrqoD6e5oPJBdIcV80FWCbcP6bO7MhhGIahLZnUQav/xjIB
|
||||
QAs/md15sezIOiieyh2qz2ldLM/KRf1gWuUVYvn+ja8+wnYY95GCwlU6Rg/TdgXHuXlhPqqolRrh
|
||||
ZzhUbbTuxpkOh1QnCsSN43Be548hCcDxgpmuZI6yOkmgm4oiLfxr+ZUlu232yWk7faWU5MDI4a0e
|
||||
5VBRIcI0Ro17yZqN5dRpSLrr0JbtUFqIUGrE97JBx+tqk9rD8SAmBXLnuMlwOKjx/bzF0+Gkqby9
|
||||
BOZ0uNo9uWBtK2db4my0F+hyWgwt6XI1rzHMbG23iiJ0CnM5SwlTmjUYT5fB4ejLdBhKc6Fd/Dhr
|
||||
V/fvF144tfayyikzZDvNdvkakk0dYgi0wzsKyxqcPYkmX2qm09X5xTS043G6KRy0obTCoVTEbJjC
|
||||
o+OXSpGW21c5PDcf7sLf03E8rLI19Wh7OIw/xGChFB9OIzUMZPqKvFCV4lSXh9WvlmOokuk+xD3H
|
||||
IXfq+DpjvE4xQ5W0GxY/h6rp0lrbCIdtWk1JtW86hVaIjn383E6luqZyCIdUg/iBcAWQL51TaHl4
|
||||
qNXuUU4xXyCFySPcYXbOquxg/LpLxGbwQEmBhLxkTvl+WvbvbTBJIUcceu9iqDqDTb2zeIgFGeOK
|
||||
pDGnJ6nTfR1s6Z19vN3q3NmTu+V0yJioVgpGOVNAZxdUjWNQp+X4bHIRTgMZpVlU7+0af2KpBYvO
|
||||
Eip0AlaUIeSEdaXNKapoI70drN9GP8f/GFhqhjc8v4Jzmll/uAjRu5juTL6lIbpJ+S6lzcI9jZW0
|
||||
I0opqP2rSHE/vS8q9UCP6IHEgxxnyAFgLB7ZfTtJ7HAYdxtndi+eP0jRvRYe+Vi7L7c3WsDuVyJE
|
||||
sz23uvj543RQWtKqpf0vUlRXhcKkWU9BDGcw2JsZ3zod7m8EBi1jDjtMLNsu/odb8CtRHEwfEgbZ
|
||||
J53QptfYWKTxwM7TAdNDuucjKl2EZCAl9nsJ/x1/uva+9F/32oMUPb1Ytfd0hqAUcakn24WGBemg
|
||||
QrcdLoXWLuO2usY0JoC1yxwcqhZJSdXx/g4Scsz02ypTSWss1mN3pRShH8sTCq7dwudLGHbqb9Te
|
||||
1nBgbaweTHyAWILxBQwocv+OJZ7hChCK4jsi8ulTXW90W9rVIZwwG2BC00gFmqKsJjyK7x3/vMO/
|
||||
wCoA2J5pGqMcIwqDF5OBW31Xwc0VNnuul8NCYbM7ZmYYhUFOqSv4/sPp6Vmpza6cah1GpZyA3OaQ
|
||||
Purzf3PuVA6TkUerzfPnwmA30+U27TRMmB1EdP5PHmGMZ4z2zyvvwGShgUOhRkETTmk/UzcUN9GG
|
||||
6F5qGljafBiUpveW26kyiiPGWZY8dDg9X+WizQARgzBnUNeQMpg6DboQXcftOQyj4zizNv6ct4OT
|
||||
qqFgeYr8v6aT91oa5BhnweV+G1QKxZtk+S2nqOs/g5ZdRGw5VeZbRdm9Xc6IVBq1R3v+1sazReuv
|
||||
VCglpZ9t+SHkdKv6bBQHH4Lnlmwpbr1GaZFTbsVSTtkhxhzKSlct0SaPYLJstdy75ZE/eOmvqXPJ
|
||||
cTIGgvAeiTvkAAal2682O55CPDZwggEiQEBAAyy4PXRVmWQzo5lPf2L7t93tdrldIXAfVroUGcsT
|
||||
dkGnYydjuXMWNtEqhULHz8W+WIdoU4aVqu+2609mN2ZCb4QC4/rRwSM9tvUPDGUT0topI3JT8LyT
|
||||
SbY6NO9pzXbB3ChVjCk/HrSS0qoYB4ihdZNO0TRZEarIPn3fBJ3p0AZzWMe6fGxjvj8JoS42eoo6
|
||||
R5PStFYVyUnRwrEzvDUdU6qC6F6DZkc33l5/ctddzJezRigwoTaMFBeryuNgpLR2imJ1VbWLhd4Z
|
||||
4/47WVuILs09DID4vjqfVEpiKubW1kvWJWplyNVLZv36Sb/okSZjddTaAHcKWCmdZxDkGioihgNG
|
||||
ELNZ0ipaqS+RH731Mk0Ug1HngQKVNvXiu3cOD8/n3zdfD89u3v/6fvvzweHFzb+/b//ce3J6f/r2
|
||||
7nR7uHunvP7y696bZ+Xt60fl+etX5c2zVNP4LL5QJIcx20kAHTBKRcCzqtv4QBQRLJt8sSjYxTGt
|
||||
9mdPjOuJjTdq8ySXsVLNgHMhgggs5V9W991boPDZBnKv1ZJPUr8MVkvny2H+MmkE6xFQuda9M8PQ
|
||||
VEJxPtnzmZjFePXiVj1PwFEq7KMF8go2bckGYI4H2d2mcamEocBRPLKXLnoLe+l3dFBl6+1Y2NqC
|
||||
bRBrmHEw4c92FdEAozinb8WX7RXdAHVc4G90B2zRHfAJVotH/rtWHJcIbtTVDtiKG+RlgeljXCc/
|
||||
y5VNwOPt6L7GsgkiPyYX0oMm7fKpU/ECyOaWwoqoB6Y3Gjn3nTw7DGhlybEuiOwQXLHtW5myEtHo
|
||||
VfqkCMHJUGPXPbA8xAJbA+joiobC9lIl4x9gVfOEIsiTh+/DAVtpK11CDgUfkj7xyV6cpxRGzl+d
|
||||
PmufYPm3LiALrRtdWkIYfHlYmCGHTtg30CitYkuloZhaH3XCVaBP69zJmHSLkihqMCnbUjDGVcdh
|
||||
xWECjOkzG9MFADmTTbgUaEEB6SSsxSC0kfqw368oqAO2YlhYsOFWDq+qcmZEk4ncEcSe91uyVcEG
|
||||
qk/RPkO71IoCzixpP2azz6V8VtkJAIN3uzsUlBa8mFNsYU+vZ3Uk1MYW3PifqXAfTjWDJ53L/aQO
|
||||
aoVDtDMlJwKcGRUB9GKakpznvhsTlQCmvaZ42aEuz0JAKlqBG6aJ2JmoVr7w0HDOrogWtJYWZ7EX
|
||||
BRkEieuYbAxUOeExAKGs8l4cDjWq3fValDIhn6tKQDc1Z82livhO0lsx81VQNsoapVPFwzsXL4km
|
||||
0L5cIzq6U+R3TAP1wjYLRLoZYdx6/qjFqGlhEAtbGqF6BqzBYqLeiTGcLREdsBeHRVQ8jn1pOtjg
|
||||
qXgs5Qe3ytIbB5tbEmtHtL2x9doEhWEavDUYdeiQB4ItlK8zcdy+ETW2blbrzYFfi7Mx5Hxh4FYc
|
||||
U5oN9hcoFfs+5+bMDz/vo5frAi0DQstBvoohp9MRQA1SJKmH5SbXDXupkq1SyzmPl68bKMZRfliQ
|
||||
uYHN4mQT+xbB9vEBGPkaKvvAYiNO3I9DnE2EXqtEp0G94pA2NfsJXGMuZzvT28YCzSajBecXr/vM
|
||||
XVxB0z5LHrwiSwwXvIPVkj4Fyl2d2nJTsJI741Mu5eQpWj8CYb6iT905wlK/DYQORJPuGP6IeErD
|
||||
oXDiZBABsZcciIBpfjn8uA5wrhTAVvHIxglskcSVcAy5cCakbFUS5tovIROTrqlLDVz9EhhFh4K0
|
||||
ky7FsksAs6Y/ZoPVdu0zOlCTn6Q4mUL+grwmgOttjKF6YaMY5rIBtd5OTs9KzOKIoCqLoSnwFqQw
|
||||
huE7d8xS8iMDRNtUGjyMHb6OHRcqjp0W43n7NnXkgtSSxtbdeNe2CGH2mwyEIosOaMD4O2gtzhyn
|
||||
SoXzX+sL2ootbkLy3EoozDnSiX78/cef288fP/06pL99ePr74+l8Ojy7/8+r/nZzuDl/OLw8nc+n
|
||||
X58Ob/797/Z0fv/p7p2/UEsBAj8AFAAAAAgAB1DDWh9xfet6LwAA15QAAB0AJAAAAAAAAAAgAAAA
|
||||
AAAAAEYtRl9SZXNlYXJjaF9EYXRhX0ZhY3RvcnMuY3N2CgAgAAAAAAABABgA4F+kNZjU2wEAAAAA
|
||||
AAAAAAAAAAAAAAAAUEsFBgAAAAABAAEAbwAAALUvAAAAAA==
|
||||
headers:
|
||||
accept-ranges:
|
||||
- bytes
|
||||
content-length:
|
||||
- '12346'
|
||||
content-type:
|
||||
- application/x-zip-compressed
|
||||
date:
|
||||
- Sun, 22 Jun 2025 21:11:29 GMT
|
||||
etag:
|
||||
- '"e6caea1580d5db1:0"'
|
||||
last-modified:
|
||||
- Wed, 04 Jun 2025 18:40:03 GMT
|
||||
server:
|
||||
- Microsoft-IIS/10.0
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
@@ -0,0 +1,251 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate, br, zstd
|
||||
Connection:
|
||||
- keep-alive
|
||||
method: GET
|
||||
uri: https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/F-F_Research_Data_Factors_CSV.zip
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
headers:
|
||||
accept-ranges:
|
||||
- bytes
|
||||
content-length:
|
||||
- '12346'
|
||||
content-type:
|
||||
- application/x-zip-compressed
|
||||
date:
|
||||
- Mon, 07 Jul 2025 04:50:25 GMT
|
||||
etag:
|
||||
- '"e6caea1580d5db1:0"'
|
||||
last-modified:
|
||||
- Wed, 04 Jun 2025 18:40:03 GMT
|
||||
server:
|
||||
- Microsoft-IIS/10.0
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,530 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Connection:
|
||||
- keep-alive
|
||||
method: GET
|
||||
uri: https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/Developed_ex_US_6_Portfolios_ME_OP_CSV.zip
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
63mYzzW4XHJ+3cY5LnAh1weXcvY8d4rBOS7lAufnng+4xOXjNJ+9F87lZuHsOvLBtVyFnBWO95f7
|
||||
cRu35GzYX5bc7scFbnD7w+3dcjkfzxHW2eSNG/Zdl1uDs8etT/fsn7uPnN9+gWtyy7nJWeAKx3Xw
|
||||
jYvHsZ/tkiucLdySm4NzXMjVwd395eD6cfwDJaOfLblIubkucJs8OPWLnXI+OH/celzK1eBCbtcv
|
||||
ruScfoZb/J7WuHxccxwW+1LiAleP27glt7fcbLneuMD54/bHdWE9+b85dubabsaNXLncOnI2n+vP
|
||||
fzLuyPnGJY73k+c68sgxn54tl8Z1Keo2bpMXzuV85GLJ9evyccHxmHJ+vvQL8v3HUi63Ss5uv0Xd
|
||||
wtnj6JfD+TdydahLOfvJuJTzjXNc/+KK437JTeCMOsftm3Ett0pu47KoM1zfjFtybXKr5IK62F/c
|
||||
Zn9p1oPfdfQ+n74ZN3I1cnNdPfdh3Yw7crHk7vvr26+eeWk5NzlzuXWdU5e4eJyz/rZct1xt6gLn
|
||||
5MKFXKdcfbl/z5yF0S9aLk0uF3X23ndcsC/9nNM4e9x6XMqtkrOSi1JdHFw/ruSCfWLo5+udF/LB
|
||||
tZwbrnC3rr64xcfawbmcHeoSl4/j+9EKuXWdP+dY34wbuSy5lutTj0ty4Y6cLbkK3O2X/3d3Pifk
|
||||
suVmU+c4JyfO5VbjXG6vLy5wIZdHzjcuqLP/ujT6WcjZyP083z84wxmO9TCFC5zh5otLuW3sny3X
|
||||
hdvX3YwruXa5WXL1Pu845Ma1XG6cyeXcOtw8bsl5yu3G3X6J249j/wz61dz97HmOt8iJ43w/C5e4
|
||||
ps5xSQ7ckdstl4Mz6uz/zu3zesaRK3/czY5zuRicyWU9zxvtZlzIucm545y6+a8r5tNny1nLxaJu
|
||||
ydV5XMixT+Q5cn4eN49LuTJc4dYXN7iS85SblrNb17j1uOZzj8vtg+tf3JLbhmtcUFdf3GZegjkr
|
||||
uf25z69zyNeNXOOycU7dws3jjlwazuRWfPk+tuTc5MzlIuS6qWvcetydF/r5xr39+mbcnZeFc7m6
|
||||
Lv/r2uhXKWcll/W4mwNHv7hzNnIxv7hkXg7OcPaLK7ldchNy/lP3xbVc4/b+PKf94BLnuCWXLbca
|
||||
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
|
||||
headers:
|
||||
accept-ranges:
|
||||
- bytes
|
||||
content-length:
|
||||
- '28250'
|
||||
content-type:
|
||||
- application/x-zip-compressed
|
||||
date:
|
||||
- Sun, 06 Jul 2025 05:29:48 GMT
|
||||
etag:
|
||||
- '"6083a4bb53ebdb1:0"'
|
||||
last-modified:
|
||||
- Wed, 02 Jul 2025 13:18:00 GMT
|
||||
server:
|
||||
- Microsoft-IIS/10.0
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
@@ -0,0 +1,530 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate, br, zstd
|
||||
Connection:
|
||||
- keep-alive
|
||||
method: GET
|
||||
uri: https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/Developed_ex_US_6_Portfolios_ME_OP_CSV.zip
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
63mYzzW4XHJ+3cY5LnAh1weXcvY8d4rBOS7lAufnng+4xOXjNJ+9F87lZuHsOvLBtVyFnBWO95f7
|
||||
cRu35GzYX5bc7scFbnD7w+3dcjkfzxHW2eSNG/Zdl1uDs8etT/fsn7uPnN9+gWtyy7nJWeAKx3Xw
|
||||
jYvHsZ/tkiucLdySm4NzXMjVwd395eD6cfwDJaOfLblIubkucJs8OPWLnXI+OH/celzK1eBCbtcv
|
||||
ruScfoZb/J7WuHxccxwW+1LiAleP27glt7fcbLneuMD54/bHdWE9+b85dubabsaNXLncOnI2n+vP
|
||||
fzLuyPnGJY73k+c68sgxn54tl8Z1Keo2bpMXzuV85GLJ9evyccHxmHJ+vvQL8v3HUi63Ss5uv0Xd
|
||||
wtnj6JfD+TdydahLOfvJuJTzjXNc/+KK437JTeCMOsftm3Ett0pu47KoM1zfjFtybXKr5IK62F/c
|
||||
Zn9p1oPfdfQ+n74ZN3I1cnNdPfdh3Yw7crHk7vvr26+eeWk5NzlzuXWdU5e4eJyz/rZct1xt6gLn
|
||||
5MKFXKdcfbl/z5yF0S9aLk0uF3X23ndcsC/9nNM4e9x6XMqtkrOSi1JdHFw/ruSCfWLo5+udF/LB
|
||||
tZwbrnC3rr64xcfawbmcHeoSl4/j+9EKuXWdP+dY34wbuSy5lutTj0ty4Y6cLbkK3O2X/3d3Pifk
|
||||
suVmU+c4JyfO5VbjXG6vLy5wIZdHzjcuqLP/ujT6WcjZyP083z84wxmO9TCFC5zh5otLuW3sny3X
|
||||
hdvX3YwruXa5WXL1Pu845Ma1XG6cyeXcOtw8bsl5yu3G3X6J249j/wz61dz97HmOt8iJ43w/C5e4
|
||||
ps5xSQ7ckdstl4Mz6uz/zu3zesaRK3/czY5zuRicyWU9zxvtZlzIucm545y6+a8r5tNny1nLxaJu
|
||||
ydV5XMixT+Q5cn4eN49LuTJc4dYXN7iS85SblrNb17j1uOZzj8vtg+tf3JLbhmtcUFdf3GZegjkr
|
||||
uf25z69zyNeNXOOycU7dws3jjlwazuRWfPk+tuTc5MzlIuS6qWvcetydF/r5xr39+mbcnZeFc7m6
|
||||
Lv/r2uhXKWcll/W4mwNHv7hzNnIxv7hkXg7OcPaLK7ldchNy/lP3xbVc4/b+PKf94BLnuCWXLbca
|
||||
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
|
||||
headers:
|
||||
accept-ranges:
|
||||
- bytes
|
||||
content-length:
|
||||
- '28250'
|
||||
content-type:
|
||||
- application/x-zip-compressed
|
||||
date:
|
||||
- Mon, 07 Jul 2025 04:50:27 GMT
|
||||
etag:
|
||||
- '"6083a4bb53ebdb1:0"'
|
||||
last-modified:
|
||||
- Wed, 02 Jul 2025 13:18:00 GMT
|
||||
server:
|
||||
- Microsoft-IIS/10.0
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,105 @@
|
||||
"""Fama-French fetchers tests."""
|
||||
|
||||
import pytest
|
||||
from openbb_core.app.service.user_service import UserService
|
||||
from openbb_famafrench.models.breakpoints import FamaFrenchBreakpointFetcher
|
||||
from openbb_famafrench.models.country_portfolio_returns import (
|
||||
FamaFrenchCountryPortfolioReturnsFetcher,
|
||||
)
|
||||
from openbb_famafrench.models.factors import FamaFrenchFactorsFetcher
|
||||
from openbb_famafrench.models.international_index_returns import (
|
||||
FamaFrenchInternationalIndexReturnsFetcher,
|
||||
)
|
||||
from openbb_famafrench.models.regional_portfolio_returns import (
|
||||
FamaFrenchRegionalPortfolioReturnsFetcher,
|
||||
)
|
||||
from openbb_famafrench.models.us_portfolio_returns import (
|
||||
FamaFrenchUSPortfolioReturnsFetcher,
|
||||
)
|
||||
|
||||
test_credentials = UserService().default_user_settings.credentials.model_dump(
|
||||
mode="json"
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vcr_config():
|
||||
"""VCR configuration."""
|
||||
return {
|
||||
"filter_headers": [
|
||||
("User-Agent", None),
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.record_http
|
||||
def test_famafrench_factors(credentials=test_credentials):
|
||||
"""Test Fama-French factors fetcher."""
|
||||
params = {"region": "america", "factor": "3_factors", "interval": "annual"}
|
||||
|
||||
fetcher = FamaFrenchFactorsFetcher()
|
||||
result = fetcher.test(params, credentials)
|
||||
assert result is None
|
||||
|
||||
|
||||
@pytest.mark.record_http
|
||||
def test_us_portfolio_returns(credentials=test_credentials):
|
||||
"""Test US portfolio returns fetcher."""
|
||||
params = {
|
||||
"portfolio": "5_industry_portfolios",
|
||||
"measure": "value",
|
||||
"frequency": "monthly",
|
||||
}
|
||||
|
||||
fetcher = FamaFrenchUSPortfolioReturnsFetcher()
|
||||
result = fetcher.test(params, credentials)
|
||||
assert result is None
|
||||
|
||||
|
||||
@pytest.mark.record_http
|
||||
def test_regional_portfolio_returns(credentials=test_credentials):
|
||||
"""Test regional portfolio returns fetcher."""
|
||||
params = {
|
||||
"region": "europe",
|
||||
}
|
||||
|
||||
fetcher = FamaFrenchRegionalPortfolioReturnsFetcher()
|
||||
result = fetcher.test(params, credentials)
|
||||
assert result is None
|
||||
|
||||
|
||||
@pytest.mark.record_http
|
||||
def test_country_portfolio_returns(credentials=test_credentials):
|
||||
"""Test country portfolio returns fetcher."""
|
||||
params = {
|
||||
"country": "japan",
|
||||
}
|
||||
|
||||
fetcher = FamaFrenchCountryPortfolioReturnsFetcher()
|
||||
result = fetcher.test(params, credentials)
|
||||
assert result is None
|
||||
|
||||
|
||||
@pytest.mark.record_http
|
||||
def test_international_index_returns(credentials=test_credentials):
|
||||
"""Test international index returns fetcher."""
|
||||
params = {
|
||||
"index": "europe_ex_uk",
|
||||
"frequency": "annual",
|
||||
}
|
||||
|
||||
fetcher = FamaFrenchInternationalIndexReturnsFetcher()
|
||||
result = fetcher.test(params, credentials)
|
||||
assert result is None
|
||||
|
||||
|
||||
@pytest.mark.record_http
|
||||
def test_fama_french_breakpoints(credentials=test_credentials):
|
||||
"""Test Fama-French breakpoints fetcher."""
|
||||
params = {
|
||||
"breakpoint_type": "op",
|
||||
}
|
||||
|
||||
fetcher = FamaFrenchBreakpointFetcher()
|
||||
result = fetcher.test(params, credentials)
|
||||
assert result is None
|
||||
4
openbb_platform/pyproject.toml
vendored
4
openbb_platform/pyproject.toml
vendored
@@ -47,6 +47,7 @@ openbb-biztoc = { version = "^1.4.2", optional = true }
|
||||
openbb-cboe = { version = "^1.4.1", optional = true }
|
||||
openbb-deribit = { version = "^1.0.1", optional = true }
|
||||
openbb-ecb = { version = "^1.4.2", optional = true }
|
||||
openbb-famafrench = { version = "^1.0.0", optional = true }
|
||||
openbb-finra = { version = "^1.4.1", optional = true }
|
||||
openbb-finviz = { version = "^1.3.1", optional = true }
|
||||
openbb-government-us = { version = "^1.4.1", optional = true }
|
||||
@@ -69,8 +70,10 @@ alpha_vantage = ["openbb-alpha-vantage"]
|
||||
biztoc = ["openbb-biztoc"]
|
||||
cboe = ["openbb-cboe"]
|
||||
charting = ["openbb-charting"]
|
||||
deribit = ["openbb-deribit"]
|
||||
ecb = ["openbb-ecb"]
|
||||
econometrics = ["openbb-econometrics"]
|
||||
famafrench = ["openbb-famafrench"]
|
||||
finra = ["openbb-finra"]
|
||||
finviz = ["openbb-finviz"]
|
||||
government_us = ["openbb-government-us"]
|
||||
@@ -94,6 +97,7 @@ all = [
|
||||
"openbb-deribit",
|
||||
"openbb-ecb",
|
||||
"openbb-econometrics",
|
||||
"openbb-famafrench",
|
||||
"openbb-finra",
|
||||
"openbb-finviz",
|
||||
"openbb-government-us",
|
||||
|
||||
Reference in New Issue
Block a user