Spaces:
Running
Running
File size: 7,867 Bytes
4ed8ca0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
import os
import requests
import numpy as np
import pandas as pd
from datetime import datetime, timedelta
from ..utils import decorate_all_methods, get_next_weekday
# from finrobot.utils import decorate_all_methods, get_next_weekday
from functools import wraps
from typing import Annotated
def init_fmp_api(func):
@wraps(func)
def wrapper(*args, **kwargs):
global fmp_api_key
if os.environ.get("FMP_API_KEY") is None:
print("Please set the environment variable FMP_API_KEY to use the FMP API.")
return None
else:
fmp_api_key = os.environ["FMP_API_KEY"]
print("FMP api key found successfully.")
return func(*args, **kwargs)
return wrapper
@decorate_all_methods(init_fmp_api)
class FMPUtils:
def get_target_price(
ticker_symbol: Annotated[str, "ticker symbol"],
date: Annotated[str, "date of the target price, should be 'yyyy-mm-dd'"],
) -> str:
"""Get the target price for a given stock on a given date"""
# API URL
url = f"https://financialmodelingprep.com/api/v4/price-target?symbol={ticker_symbol}&apikey={fmp_api_key}"
# 发送GET请求
price_target = "Not Given"
response = requests.get(url)
# 确保请求成功
if response.status_code == 200:
# 解析JSON数据
data = response.json()
est = []
date = datetime.strptime(date, "%Y-%m-%d")
for tprice in data:
tdate = tprice["publishedDate"].split("T")[0]
tdate = datetime.strptime(tdate, "%Y-%m-%d")
if abs((tdate - date).days) <= 1:
est.append(tprice["priceTarget"])
if est:
price_target = f"{np.min(est)} - {np.max(est)} (md. {np.median(est)})"
else:
price_target = "N/A"
else:
return f"Failed to retrieve data: {response.status_code}"
return price_target
def get_sec_report(
ticker_symbol: Annotated[str, "ticker symbol"],
fyear: Annotated[
str,
"year of the 10-K report, should be 'yyyy' or 'latest'. Default to 'latest'",
] = "latest",
) -> str:
"""Get the url and filing date of the 10-K report for a given stock and year"""
url = f"https://financialmodelingprep.com/api/v3/sec_filings/{ticker_symbol}?type=10-k&page=0&apikey={fmp_api_key}"
# 发送GET请求
filing_url = None
response = requests.get(url)
# 确保请求成功
if response.status_code == 200:
# 解析JSON数据
data = response.json()
# print(data)
if fyear == "latest":
filing_url = data[0]["finalLink"]
filing_date = data[0]["fillingDate"]
else:
for filing in data:
if filing["fillingDate"].split("-")[0] == fyear:
filing_url = filing["finalLink"]
filing_date = filing["fillingDate"]
break
return f"Link: {filing_url}\nFiling Date: {filing_date}"
else:
return f"Failed to retrieve data: {response.status_code}"
def get_historical_market_cap(
ticker_symbol: Annotated[str, "ticker symbol"],
date: Annotated[str, "date of the market cap, should be 'yyyy-mm-dd'"],
) -> str:
"""Get the historical market capitalization for a given stock on a given date"""
date = get_next_weekday(date).strftime("%Y-%m-%d")
url = f"https://financialmodelingprep.com/api/v3/historical-market-capitalization/{ticker_symbol}?limit=100&from={date}&to={date}&apikey={fmp_api_key}"
# 发送GET请求
mkt_cap = None
response = requests.get(url)
# 确保请求成功
if response.status_code == 200:
# 解析JSON数据
data = response.json()
mkt_cap = data[0]["marketCap"]
return mkt_cap
else:
return f"Failed to retrieve data: {response.status_code}"
def get_historical_bvps(
ticker_symbol: Annotated[str, "ticker symbol"],
target_date: Annotated[str, "date of the BVPS, should be 'yyyy-mm-dd'"],
) -> str:
"""Get the historical book value per share for a given stock on a given date"""
# 从FMP API获取历史关键财务指标数据
url = f"https://financialmodelingprep.com/api/v3/key-metrics/{ticker_symbol}?limit=40&apikey={fmp_api_key}"
response = requests.get(url)
data = response.json()
if not data:
return "No data available"
# 找到最接近目标日期的数据
closest_data = None
min_date_diff = float("inf")
target_date = datetime.strptime(target_date, "%Y-%m-%d")
for entry in data:
date_of_data = datetime.strptime(entry["date"], "%Y-%m-%d")
date_diff = abs(target_date - date_of_data).days
if date_diff < min_date_diff:
min_date_diff = date_diff
closest_data = entry
if closest_data:
return closest_data.get("bookValuePerShare", "No BVPS data available")
else:
return "No close date data found"
def get_financial_metrics(
ticker_symbol: Annotated[str, "ticker symbol"],
years: Annotated[int, "number of the years to search from, default to 4"] = 4,
):
"""Get the financial metrics for a given stock for the last 'years' years"""
# Base URL setup for FMP API
base_url = "https://financialmodelingprep.com/api/v3"
# Create DataFrame
df = pd.DataFrame()
# Iterate over the last 'years' years of data
for year_offset in range(years):
# Construct URL for income statement and ratios for each year
income_statement_url = f"{base_url}/income-statement/{ticker_symbol}?limit={years}&apikey={fmp_api_key}"
ratios_url = (
f"{base_url}/ratios/{ticker_symbol}?limit={years}&apikey={fmp_api_key}"
)
key_metrics_url = f"{base_url}/key-metrics/{ticker_symbol}?limit={years}&apikey={fmp_api_key}"
# Requesting data from the API
income_data = requests.get(income_statement_url).json()
key_metrics_data = requests.get(key_metrics_url).json()
ratios_data = requests.get(ratios_url).json()
# Extracting needed metrics for each year
if income_data and key_metrics_data and ratios_data:
metrics = {
"Operating Revenue": income_data[year_offset]["revenue"] / 1e6,
"Adjusted Net Profit": income_data[year_offset]["netIncome"] / 1e6,
"Adjusted EPS": income_data[year_offset]["eps"],
"EBIT Margin": ratios_data[year_offset]["ebitPerRevenue"],
"ROE": key_metrics_data[year_offset]["roe"],
"PE Ratio": ratios_data[year_offset]["priceEarningsRatio"],
"EV/EBITDA": key_metrics_data[year_offset][
"enterpriseValueOverEBITDA"
],
"PB Ratio": key_metrics_data[year_offset]["pbRatio"],
}
# Append the year and metrics to the DataFrame
# Extracting the year from the date
year = income_data[year_offset]["date"][:4]
df[year] = pd.Series(metrics)
df = df.sort_index(axis=1)
df = df.round(2)
return df
if __name__ == "__main__":
from finrobot.utils import register_keys_from_json
register_keys_from_json("config_api_keys")
FMPUtils.get_sec_report("MSFT", "2023")
|