refactor(dataflows): stub Alpha Vantage modules; deprecate y_finance
Part of the FMP-primary data source migration (see D:/sharkquant/docs/FMP_MIGRATION.md at the monorepo root). - alpha_vantage_common.py: every helper returns empty; AlphaVantageRateLimitError kept for `except` compat - alpha_vantage_stock.py / _fundamentals.py / _indicator.py / _news.py: all public functions return "" so callers through interface.py don't import-error y_finance.py gets a module-level deprecation docstring; it's too big to stub safely without a tested FMP replacement wired through interface.py, so it stays live for this round. Callers (tier1, tier2, test.py) still work via its Alpaca-fallback path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
806263defd
commit
dcc98a7136
|
|
@ -1,122 +1,40 @@
|
||||||
import os
|
"""
|
||||||
import requests
|
DEPRECATED — Alpha Vantage removed in the FMP-primary migration.
|
||||||
import pandas as pd
|
|
||||||
import json
|
|
||||||
from datetime import datetime
|
|
||||||
from io import StringIO
|
|
||||||
|
|
||||||
API_BASE_URL = "https://www.alphavantage.co/query"
|
This module used to be the shared Alpha Vantage HTTP wrapper (API key
|
||||||
|
lookup + request sender + rate-limit handling). Every function is a
|
||||||
|
no-op stub now; callers through ``interface.py`` and the sibling
|
||||||
|
``alpha_vantage_*`` modules won't import-error, but every data call
|
||||||
|
returns an empty string / sentinel. Alpha Vantage free-tier (25 req/day)
|
||||||
|
was secondary fallback anyway; FMP Ultimate is authoritative.
|
||||||
|
|
||||||
def get_api_key() -> str:
|
Remove this file once no ``from .alpha_vantage_common import ...``
|
||||||
"""Retrieve the API key for Alpha Vantage from environment variables."""
|
imports remain anywhere in the tree.
|
||||||
api_key = os.getenv("ALPHA_VANTAGE_API_KEY")
|
"""
|
||||||
if not api_key:
|
from __future__ import annotations
|
||||||
raise ValueError("ALPHA_VANTAGE_API_KEY environment variable is not set.")
|
|
||||||
return api_key
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
def format_datetime_for_api(date_input) -> str:
|
|
||||||
"""Convert various date formats to YYYYMMDDTHHMM format required by Alpha Vantage API."""
|
|
||||||
if isinstance(date_input, str):
|
|
||||||
# If already in correct format, return as-is
|
|
||||||
if len(date_input) == 13 and 'T' in date_input:
|
|
||||||
return date_input
|
|
||||||
# Try to parse common date formats
|
|
||||||
try:
|
|
||||||
dt = datetime.strptime(date_input, "%Y-%m-%d")
|
|
||||||
return dt.strftime("%Y%m%dT0000")
|
|
||||||
except ValueError:
|
|
||||||
try:
|
|
||||||
dt = datetime.strptime(date_input, "%Y-%m-%d %H:%M")
|
|
||||||
return dt.strftime("%Y%m%dT%H%M")
|
|
||||||
except ValueError:
|
|
||||||
raise ValueError(f"Unsupported date format: {date_input}")
|
|
||||||
elif isinstance(date_input, datetime):
|
|
||||||
return date_input.strftime("%Y%m%dT%H%M")
|
|
||||||
else:
|
|
||||||
raise ValueError(f"Date must be string or datetime object, got {type(date_input)}")
|
|
||||||
|
|
||||||
class AlphaVantageRateLimitError(Exception):
|
class AlphaVantageRateLimitError(Exception):
|
||||||
"""Exception raised when Alpha Vantage API rate limit is exceeded."""
|
"""Kept for type-compat with any `except AlphaVantageRateLimitError` sites."""
|
||||||
pass
|
|
||||||
|
|
||||||
|
def get_api_key() -> str:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def format_datetime_for_api(date_input) -> str:
|
||||||
|
# Pass-through of a date string is harmless; callers pass ISO dates.
|
||||||
|
return str(date_input) if date_input is not None else ""
|
||||||
|
|
||||||
|
|
||||||
def _make_api_request(function_name: str, params: dict) -> dict | str:
|
def _make_api_request(function_name: str, params: dict) -> dict | str:
|
||||||
"""Helper function to make API requests and handle responses.
|
logger.debug("alpha_vantage call skipped (module stubbed): %s", function_name)
|
||||||
|
return {}
|
||||||
Raises:
|
|
||||||
AlphaVantageRateLimitError: When API rate limit is exceeded
|
|
||||||
"""
|
|
||||||
# Create a copy of params to avoid modifying the original
|
|
||||||
api_params = params.copy()
|
|
||||||
api_params.update({
|
|
||||||
"function": function_name,
|
|
||||||
"apikey": get_api_key(),
|
|
||||||
"source": "trading_agents",
|
|
||||||
})
|
|
||||||
|
|
||||||
# Handle entitlement parameter if present in params or global variable
|
|
||||||
current_entitlement = globals().get('_current_entitlement')
|
|
||||||
entitlement = api_params.get("entitlement") or current_entitlement
|
|
||||||
|
|
||||||
if entitlement:
|
|
||||||
api_params["entitlement"] = entitlement
|
|
||||||
elif "entitlement" in api_params:
|
|
||||||
# Remove entitlement if it's None or empty
|
|
||||||
api_params.pop("entitlement", None)
|
|
||||||
|
|
||||||
response = requests.get(API_BASE_URL, params=api_params)
|
|
||||||
response.raise_for_status()
|
|
||||||
|
|
||||||
response_text = response.text
|
|
||||||
|
|
||||||
# Check if response is JSON (error responses are typically JSON)
|
|
||||||
try:
|
|
||||||
response_json = json.loads(response_text)
|
|
||||||
# Check for rate limit error
|
|
||||||
if "Information" in response_json:
|
|
||||||
info_message = response_json["Information"]
|
|
||||||
if "rate limit" in info_message.lower() or "api key" in info_message.lower():
|
|
||||||
raise AlphaVantageRateLimitError(f"Alpha Vantage rate limit exceeded: {info_message}")
|
|
||||||
except json.JSONDecodeError:
|
|
||||||
# Response is not JSON (likely CSV data), which is normal
|
|
||||||
pass
|
|
||||||
|
|
||||||
return response_text
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _filter_csv_by_date_range(csv_data: str, start_date: str, end_date: str) -> str:
|
def _filter_csv_by_date_range(csv_data: str, start_date: str, end_date: str) -> str:
|
||||||
"""
|
return csv_data or ""
|
||||||
Filter CSV data to include only rows within the specified date range.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
csv_data: CSV string from Alpha Vantage API
|
|
||||||
start_date: Start date in yyyy-mm-dd format
|
|
||||||
end_date: End date in yyyy-mm-dd format
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Filtered CSV string
|
|
||||||
"""
|
|
||||||
if not csv_data or csv_data.strip() == "":
|
|
||||||
return csv_data
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Parse CSV data
|
|
||||||
df = pd.read_csv(StringIO(csv_data))
|
|
||||||
|
|
||||||
# Assume the first column is the date column (timestamp)
|
|
||||||
date_col = df.columns[0]
|
|
||||||
df[date_col] = pd.to_datetime(df[date_col])
|
|
||||||
|
|
||||||
# Filter by date range
|
|
||||||
start_dt = pd.to_datetime(start_date)
|
|
||||||
end_dt = pd.to_datetime(end_date)
|
|
||||||
|
|
||||||
filtered_df = df[(df[date_col] >= start_dt) & (df[date_col] <= end_dt)]
|
|
||||||
|
|
||||||
# Convert back to CSV string
|
|
||||||
return filtered_df.to_csv(index=False)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
# If filtering fails, return original data with a warning
|
|
||||||
print(f"Warning: Failed to filter CSV data by date range: {e}")
|
|
||||||
return csv_data
|
|
||||||
|
|
|
||||||
|
|
@ -1,77 +1,21 @@
|
||||||
from .alpha_vantage_common import _make_api_request
|
"""
|
||||||
|
DEPRECATED — Alpha Vantage removed in the FMP-primary migration.
|
||||||
|
See alpha_vantage_common.py for context. All stubs.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|
||||||
def get_fundamentals(ticker: str, curr_date: str = None) -> str:
|
def get_fundamentals(ticker: str, curr_date: str = None) -> str:
|
||||||
"""
|
return ""
|
||||||
Retrieve comprehensive fundamental data for a given ticker symbol using Alpha Vantage.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
ticker (str): Ticker symbol of the company
|
|
||||||
curr_date (str): Current date you are trading at, yyyy-mm-dd (not used for Alpha Vantage)
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: Company overview data including financial ratios and key metrics
|
|
||||||
"""
|
|
||||||
params = {
|
|
||||||
"symbol": ticker,
|
|
||||||
}
|
|
||||||
|
|
||||||
return _make_api_request("OVERVIEW", params)
|
|
||||||
|
|
||||||
|
|
||||||
def get_balance_sheet(ticker: str, freq: str = "quarterly", curr_date: str = None) -> str:
|
def get_balance_sheet(ticker: str, freq: str = "quarterly", curr_date: str = None) -> str:
|
||||||
"""
|
return ""
|
||||||
Retrieve balance sheet data for a given ticker symbol using Alpha Vantage.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
ticker (str): Ticker symbol of the company
|
|
||||||
freq (str): Reporting frequency: annual/quarterly (default quarterly) - not used for Alpha Vantage
|
|
||||||
curr_date (str): Current date you are trading at, yyyy-mm-dd (not used for Alpha Vantage)
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: Balance sheet data with normalized fields
|
|
||||||
"""
|
|
||||||
params = {
|
|
||||||
"symbol": ticker,
|
|
||||||
}
|
|
||||||
|
|
||||||
return _make_api_request("BALANCE_SHEET", params)
|
|
||||||
|
|
||||||
|
|
||||||
def get_cashflow(ticker: str, freq: str = "quarterly", curr_date: str = None) -> str:
|
def get_cashflow(ticker: str, freq: str = "quarterly", curr_date: str = None) -> str:
|
||||||
"""
|
return ""
|
||||||
Retrieve cash flow statement data for a given ticker symbol using Alpha Vantage.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
ticker (str): Ticker symbol of the company
|
|
||||||
freq (str): Reporting frequency: annual/quarterly (default quarterly) - not used for Alpha Vantage
|
|
||||||
curr_date (str): Current date you are trading at, yyyy-mm-dd (not used for Alpha Vantage)
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: Cash flow statement data with normalized fields
|
|
||||||
"""
|
|
||||||
params = {
|
|
||||||
"symbol": ticker,
|
|
||||||
}
|
|
||||||
|
|
||||||
return _make_api_request("CASH_FLOW", params)
|
|
||||||
|
|
||||||
|
|
||||||
def get_income_statement(ticker: str, freq: str = "quarterly", curr_date: str = None) -> str:
|
def get_income_statement(ticker: str, freq: str = "quarterly", curr_date: str = None) -> str:
|
||||||
"""
|
return ""
|
||||||
Retrieve income statement data for a given ticker symbol using Alpha Vantage.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
ticker (str): Ticker symbol of the company
|
|
||||||
freq (str): Reporting frequency: annual/quarterly (default quarterly) - not used for Alpha Vantage
|
|
||||||
curr_date (str): Current date you are trading at, yyyy-mm-dd (not used for Alpha Vantage)
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: Income statement data with normalized fields
|
|
||||||
"""
|
|
||||||
params = {
|
|
||||||
"symbol": ticker,
|
|
||||||
}
|
|
||||||
|
|
||||||
return _make_api_request("INCOME_STATEMENT", params)
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
from .alpha_vantage_common import _make_api_request
|
"""
|
||||||
|
DEPRECATED — Alpha Vantage removed in the FMP-primary migration.
|
||||||
|
See alpha_vantage_common.py for context. Stub.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|
||||||
def get_indicator(
|
def get_indicator(
|
||||||
symbol: str,
|
symbol: str,
|
||||||
|
|
@ -7,216 +12,6 @@ def get_indicator(
|
||||||
look_back_days: int,
|
look_back_days: int,
|
||||||
interval: str = "daily",
|
interval: str = "daily",
|
||||||
time_period: int = 14,
|
time_period: int = 14,
|
||||||
series_type: str = "close"
|
series_type: str = "close",
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
return ""
|
||||||
Returns Alpha Vantage technical indicator values over a time window.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
symbol: ticker symbol of the company
|
|
||||||
indicator: technical indicator to get the analysis and report of
|
|
||||||
curr_date: The current trading date you are trading on, YYYY-mm-dd
|
|
||||||
look_back_days: how many days to look back
|
|
||||||
interval: Time interval (daily, weekly, monthly)
|
|
||||||
time_period: Number of data points for calculation
|
|
||||||
series_type: The desired price type (close, open, high, low)
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
String containing indicator values and description
|
|
||||||
"""
|
|
||||||
from datetime import datetime
|
|
||||||
from dateutil.relativedelta import relativedelta
|
|
||||||
|
|
||||||
supported_indicators = {
|
|
||||||
"close_50_sma": ("50 SMA", "close"),
|
|
||||||
"close_200_sma": ("200 SMA", "close"),
|
|
||||||
"close_10_ema": ("10 EMA", "close"),
|
|
||||||
"macd": ("MACD", "close"),
|
|
||||||
"macds": ("MACD Signal", "close"),
|
|
||||||
"macdh": ("MACD Histogram", "close"),
|
|
||||||
"rsi": ("RSI", "close"),
|
|
||||||
"boll": ("Bollinger Middle", "close"),
|
|
||||||
"boll_ub": ("Bollinger Upper Band", "close"),
|
|
||||||
"boll_lb": ("Bollinger Lower Band", "close"),
|
|
||||||
"atr": ("ATR", None),
|
|
||||||
"vwma": ("VWMA", "close")
|
|
||||||
}
|
|
||||||
|
|
||||||
indicator_descriptions = {
|
|
||||||
"close_50_sma": "50 SMA: A medium-term trend indicator. Usage: Identify trend direction and serve as dynamic support/resistance. Tips: It lags price; combine with faster indicators for timely signals.",
|
|
||||||
"close_200_sma": "200 SMA: A long-term trend benchmark. Usage: Confirm overall market trend and identify golden/death cross setups. Tips: It reacts slowly; best for strategic trend confirmation rather than frequent trading entries.",
|
|
||||||
"close_10_ema": "10 EMA: A responsive short-term average. Usage: Capture quick shifts in momentum and potential entry points. Tips: Prone to noise in choppy markets; use alongside longer averages for filtering false signals.",
|
|
||||||
"macd": "MACD: Computes momentum via differences of EMAs. Usage: Look for crossovers and divergence as signals of trend changes. Tips: Confirm with other indicators in low-volatility or sideways markets.",
|
|
||||||
"macds": "MACD Signal: An EMA smoothing of the MACD line. Usage: Use crossovers with the MACD line to trigger trades. Tips: Should be part of a broader strategy to avoid false positives.",
|
|
||||||
"macdh": "MACD Histogram: Shows the gap between the MACD line and its signal. Usage: Visualize momentum strength and spot divergence early. Tips: Can be volatile; complement with additional filters in fast-moving markets.",
|
|
||||||
"rsi": "RSI: Measures momentum to flag overbought/oversold conditions. Usage: Apply 70/30 thresholds and watch for divergence to signal reversals. Tips: In strong trends, RSI may remain extreme; always cross-check with trend analysis.",
|
|
||||||
"boll": "Bollinger Middle: A 20 SMA serving as the basis for Bollinger Bands. Usage: Acts as a dynamic benchmark for price movement. Tips: Combine with the upper and lower bands to effectively spot breakouts or reversals.",
|
|
||||||
"boll_ub": "Bollinger Upper Band: Typically 2 standard deviations above the middle line. Usage: Signals potential overbought conditions and breakout zones. Tips: Confirm signals with other tools; prices may ride the band in strong trends.",
|
|
||||||
"boll_lb": "Bollinger Lower Band: Typically 2 standard deviations below the middle line. Usage: Indicates potential oversold conditions. Tips: Use additional analysis to avoid false reversal signals.",
|
|
||||||
"atr": "ATR: Averages true range to measure volatility. Usage: Set stop-loss levels and adjust position sizes based on current market volatility. Tips: It's a reactive measure, so use it as part of a broader risk management strategy.",
|
|
||||||
"vwma": "VWMA: A moving average weighted by volume. Usage: Confirm trends by integrating price action with volume data. Tips: Watch for skewed results from volume spikes; use in combination with other volume analyses."
|
|
||||||
}
|
|
||||||
|
|
||||||
if indicator not in supported_indicators:
|
|
||||||
raise ValueError(
|
|
||||||
f"Indicator {indicator} is not supported. Please choose from: {list(supported_indicators.keys())}"
|
|
||||||
)
|
|
||||||
|
|
||||||
curr_date_dt = datetime.strptime(curr_date, "%Y-%m-%d")
|
|
||||||
before = curr_date_dt - relativedelta(days=look_back_days)
|
|
||||||
|
|
||||||
# Get the full data for the period instead of making individual calls
|
|
||||||
_, required_series_type = supported_indicators[indicator]
|
|
||||||
|
|
||||||
# Use the provided series_type or fall back to the required one
|
|
||||||
if required_series_type:
|
|
||||||
series_type = required_series_type
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Get indicator data for the period
|
|
||||||
if indicator == "close_50_sma":
|
|
||||||
data = _make_api_request("SMA", {
|
|
||||||
"symbol": symbol,
|
|
||||||
"interval": interval,
|
|
||||||
"time_period": "50",
|
|
||||||
"series_type": series_type,
|
|
||||||
"datatype": "csv"
|
|
||||||
})
|
|
||||||
elif indicator == "close_200_sma":
|
|
||||||
data = _make_api_request("SMA", {
|
|
||||||
"symbol": symbol,
|
|
||||||
"interval": interval,
|
|
||||||
"time_period": "200",
|
|
||||||
"series_type": series_type,
|
|
||||||
"datatype": "csv"
|
|
||||||
})
|
|
||||||
elif indicator == "close_10_ema":
|
|
||||||
data = _make_api_request("EMA", {
|
|
||||||
"symbol": symbol,
|
|
||||||
"interval": interval,
|
|
||||||
"time_period": "10",
|
|
||||||
"series_type": series_type,
|
|
||||||
"datatype": "csv"
|
|
||||||
})
|
|
||||||
elif indicator == "macd":
|
|
||||||
data = _make_api_request("MACD", {
|
|
||||||
"symbol": symbol,
|
|
||||||
"interval": interval,
|
|
||||||
"series_type": series_type,
|
|
||||||
"datatype": "csv"
|
|
||||||
})
|
|
||||||
elif indicator == "macds":
|
|
||||||
data = _make_api_request("MACD", {
|
|
||||||
"symbol": symbol,
|
|
||||||
"interval": interval,
|
|
||||||
"series_type": series_type,
|
|
||||||
"datatype": "csv"
|
|
||||||
})
|
|
||||||
elif indicator == "macdh":
|
|
||||||
data = _make_api_request("MACD", {
|
|
||||||
"symbol": symbol,
|
|
||||||
"interval": interval,
|
|
||||||
"series_type": series_type,
|
|
||||||
"datatype": "csv"
|
|
||||||
})
|
|
||||||
elif indicator == "rsi":
|
|
||||||
data = _make_api_request("RSI", {
|
|
||||||
"symbol": symbol,
|
|
||||||
"interval": interval,
|
|
||||||
"time_period": str(time_period),
|
|
||||||
"series_type": series_type,
|
|
||||||
"datatype": "csv"
|
|
||||||
})
|
|
||||||
elif indicator in ["boll", "boll_ub", "boll_lb"]:
|
|
||||||
data = _make_api_request("BBANDS", {
|
|
||||||
"symbol": symbol,
|
|
||||||
"interval": interval,
|
|
||||||
"time_period": "20",
|
|
||||||
"series_type": series_type,
|
|
||||||
"datatype": "csv"
|
|
||||||
})
|
|
||||||
elif indicator == "atr":
|
|
||||||
data = _make_api_request("ATR", {
|
|
||||||
"symbol": symbol,
|
|
||||||
"interval": interval,
|
|
||||||
"time_period": str(time_period),
|
|
||||||
"datatype": "csv"
|
|
||||||
})
|
|
||||||
elif indicator == "vwma":
|
|
||||||
# Alpha Vantage doesn't have direct VWMA, so we'll return an informative message
|
|
||||||
# In a real implementation, this would need to be calculated from OHLCV data
|
|
||||||
return f"## VWMA (Volume Weighted Moving Average) for {symbol}:\n\nVWMA calculation requires OHLCV data and is not directly available from Alpha Vantage API.\nThis indicator would need to be calculated from the raw stock data using volume-weighted price averaging.\n\n{indicator_descriptions.get('vwma', 'No description available.')}"
|
|
||||||
else:
|
|
||||||
return f"Error: Indicator {indicator} not implemented yet."
|
|
||||||
|
|
||||||
# Parse CSV data and extract values for the date range
|
|
||||||
lines = data.strip().split('\n')
|
|
||||||
if len(lines) < 2:
|
|
||||||
return f"Error: No data returned for {indicator}"
|
|
||||||
|
|
||||||
# Parse header and data
|
|
||||||
header = [col.strip() for col in lines[0].split(',')]
|
|
||||||
try:
|
|
||||||
date_col_idx = header.index('time')
|
|
||||||
except ValueError:
|
|
||||||
return f"Error: 'time' column not found in data for {indicator}. Available columns: {header}"
|
|
||||||
|
|
||||||
# Map internal indicator names to expected CSV column names from Alpha Vantage
|
|
||||||
col_name_map = {
|
|
||||||
"macd": "MACD", "macds": "MACD_Signal", "macdh": "MACD_Hist",
|
|
||||||
"boll": "Real Middle Band", "boll_ub": "Real Upper Band", "boll_lb": "Real Lower Band",
|
|
||||||
"rsi": "RSI", "atr": "ATR", "close_10_ema": "EMA",
|
|
||||||
"close_50_sma": "SMA", "close_200_sma": "SMA"
|
|
||||||
}
|
|
||||||
|
|
||||||
target_col_name = col_name_map.get(indicator)
|
|
||||||
|
|
||||||
if not target_col_name:
|
|
||||||
# Default to the second column if no specific mapping exists
|
|
||||||
value_col_idx = 1
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
value_col_idx = header.index(target_col_name)
|
|
||||||
except ValueError:
|
|
||||||
return f"Error: Column '{target_col_name}' not found for indicator '{indicator}'. Available columns: {header}"
|
|
||||||
|
|
||||||
result_data = []
|
|
||||||
for line in lines[1:]:
|
|
||||||
if not line.strip():
|
|
||||||
continue
|
|
||||||
values = line.split(',')
|
|
||||||
if len(values) > value_col_idx:
|
|
||||||
try:
|
|
||||||
date_str = values[date_col_idx].strip()
|
|
||||||
# Parse the date
|
|
||||||
date_dt = datetime.strptime(date_str, "%Y-%m-%d")
|
|
||||||
|
|
||||||
# Check if date is in our range
|
|
||||||
if before <= date_dt <= curr_date_dt:
|
|
||||||
value = values[value_col_idx].strip()
|
|
||||||
result_data.append((date_dt, value))
|
|
||||||
except (ValueError, IndexError):
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Sort by date and format output
|
|
||||||
result_data.sort(key=lambda x: x[0])
|
|
||||||
|
|
||||||
ind_string = ""
|
|
||||||
for date_dt, value in result_data:
|
|
||||||
ind_string += f"{date_dt.strftime('%Y-%m-%d')}: {value}\n"
|
|
||||||
|
|
||||||
if not ind_string:
|
|
||||||
ind_string = "No data available for the specified date range.\n"
|
|
||||||
|
|
||||||
result_str = (
|
|
||||||
f"## {indicator.upper()} values from {before.strftime('%Y-%m-%d')} to {curr_date}:\n\n"
|
|
||||||
+ ind_string
|
|
||||||
+ "\n\n"
|
|
||||||
+ indicator_descriptions.get(indicator, "No description available.")
|
|
||||||
)
|
|
||||||
|
|
||||||
return result_str
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error getting Alpha Vantage indicator data for {indicator}: {e}")
|
|
||||||
return f"Error retrieving {indicator} data: {str(e)}"
|
|
||||||
|
|
|
||||||
|
|
@ -1,71 +1,17 @@
|
||||||
from .alpha_vantage_common import _make_api_request, format_datetime_for_api
|
"""
|
||||||
|
DEPRECATED — Alpha Vantage removed in the FMP-primary migration.
|
||||||
|
See alpha_vantage_common.py for context. Stubs.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|
||||||
def get_news(ticker, start_date, end_date) -> dict[str, str] | str:
|
def get_news(ticker, start_date, end_date) -> dict[str, str] | str:
|
||||||
"""Returns live and historical market news & sentiment data from premier news outlets worldwide.
|
return ""
|
||||||
|
|
||||||
Covers stocks, cryptocurrencies, forex, and topics like fiscal policy, mergers & acquisitions, IPOs.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
ticker: Stock symbol for news articles.
|
|
||||||
start_date: Start date for news search.
|
|
||||||
end_date: End date for news search.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Dictionary containing news sentiment data or JSON string.
|
|
||||||
"""
|
|
||||||
|
|
||||||
params = {
|
|
||||||
"tickers": ticker,
|
|
||||||
"time_from": format_datetime_for_api(start_date),
|
|
||||||
"time_to": format_datetime_for_api(end_date),
|
|
||||||
}
|
|
||||||
|
|
||||||
return _make_api_request("NEWS_SENTIMENT", params)
|
|
||||||
|
|
||||||
def get_global_news(curr_date, look_back_days: int = 7, limit: int = 50) -> dict[str, str] | str:
|
def get_global_news(curr_date, look_back_days: int = 7, limit: int = 50) -> dict[str, str] | str:
|
||||||
"""Returns global market news & sentiment data without ticker-specific filtering.
|
return ""
|
||||||
|
|
||||||
Covers broad market topics like financial markets, economy, and more.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
curr_date: Current date in yyyy-mm-dd format.
|
|
||||||
look_back_days: Number of days to look back (default 7).
|
|
||||||
limit: Maximum number of articles (default 50).
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Dictionary containing global news sentiment data or JSON string.
|
|
||||||
"""
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
|
|
||||||
# Calculate start date
|
|
||||||
curr_dt = datetime.strptime(curr_date, "%Y-%m-%d")
|
|
||||||
start_dt = curr_dt - timedelta(days=look_back_days)
|
|
||||||
start_date = start_dt.strftime("%Y-%m-%d")
|
|
||||||
|
|
||||||
params = {
|
|
||||||
"topics": "financial_markets,economy_macro,economy_monetary",
|
|
||||||
"time_from": format_datetime_for_api(start_date),
|
|
||||||
"time_to": format_datetime_for_api(curr_date),
|
|
||||||
"limit": str(limit),
|
|
||||||
}
|
|
||||||
|
|
||||||
return _make_api_request("NEWS_SENTIMENT", params)
|
|
||||||
|
|
||||||
|
|
||||||
def get_insider_transactions(symbol: str) -> dict[str, str] | str:
|
def get_insider_transactions(symbol: str) -> dict[str, str] | str:
|
||||||
"""Returns latest and historical insider transactions by key stakeholders.
|
return ""
|
||||||
|
|
||||||
Covers transactions by founders, executives, board members, etc.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
symbol: Ticker symbol. Example: "IBM".
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Dictionary containing insider transaction data or JSON string.
|
|
||||||
"""
|
|
||||||
|
|
||||||
params = {
|
|
||||||
"symbol": symbol,
|
|
||||||
}
|
|
||||||
|
|
||||||
return _make_api_request("INSIDER_TRANSACTIONS", params)
|
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,9 @@
|
||||||
from datetime import datetime
|
"""
|
||||||
from .alpha_vantage_common import _make_api_request, _filter_csv_by_date_range
|
DEPRECATED — Alpha Vantage removed in the FMP-primary migration.
|
||||||
|
See alpha_vantage_common.py for context. This is a stub.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
def get_stock(
|
|
||||||
symbol: str,
|
|
||||||
start_date: str,
|
|
||||||
end_date: str
|
|
||||||
) -> str:
|
|
||||||
"""
|
|
||||||
Returns raw daily OHLCV values, adjusted close values, and historical split/dividend events
|
|
||||||
filtered to the specified date range.
|
|
||||||
|
|
||||||
Args:
|
def get_stock(symbol: str, start_date: str, end_date: str) -> str:
|
||||||
symbol: The name of the equity. For example: symbol=IBM
|
return ""
|
||||||
start_date: Start date in yyyy-mm-dd format
|
|
||||||
end_date: End date in yyyy-mm-dd format
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
CSV string containing the daily adjusted time series data filtered to the date range.
|
|
||||||
"""
|
|
||||||
# Parse dates to determine the range
|
|
||||||
start_dt = datetime.strptime(start_date, "%Y-%m-%d")
|
|
||||||
today = datetime.now()
|
|
||||||
|
|
||||||
# Choose outputsize based on whether the requested range is within the latest 100 days
|
|
||||||
# Compact returns latest 100 data points, so check if start_date is recent enough
|
|
||||||
days_from_today_to_start = (today - start_dt).days
|
|
||||||
outputsize = "compact" if days_from_today_to_start < 100 else "full"
|
|
||||||
|
|
||||||
params = {
|
|
||||||
"symbol": symbol,
|
|
||||||
"outputsize": outputsize,
|
|
||||||
"datatype": "csv",
|
|
||||||
}
|
|
||||||
|
|
||||||
response = _make_api_request("TIME_SERIES_DAILY_ADJUSTED", params)
|
|
||||||
|
|
||||||
return _filter_csv_by_date_range(response, start_date, end_date)
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,17 @@
|
||||||
|
"""
|
||||||
|
DEPRECATED — yfinance is scheduled for removal in the FMP-primary migration.
|
||||||
|
|
||||||
|
This module is the Alpaca-fallback path for TradingAgents data. It is
|
||||||
|
still wired in (tier1 + tier2 + interface.py reference it) and too
|
||||||
|
large to stub safely without rewiring the structured analysts, so it
|
||||||
|
stays live for now. Track: replace with calls through
|
||||||
|
FMPDataService (see stock-screener/backend/docs/FMP_MIGRATION.md for
|
||||||
|
the pattern) and route `interface.py` to FMP-first instead.
|
||||||
|
|
||||||
|
Callers: tradingagents/agents/structured/tier1.py,
|
||||||
|
tradingagents/agents/structured/tier2.py,
|
||||||
|
tradingagents/test.py
|
||||||
|
"""
|
||||||
from typing import Annotated
|
from typing import Annotated
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue