量化交易多智能体系统,包含: - 分析师、投资组合经理、风险经理等智能体 - 股票分析、投资组合管理、风险控制工具 - React 前端界面 - FastAPI 后端服务 Co-Authored-By: Claude <noreply@anthropic.com>
108 lines
3.4 KiB
Python
108 lines
3.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from typing_extensions import Any
|
|
|
|
|
|
class Cache:
|
|
"""In-memory cache for API responses."""
|
|
|
|
def __init__(self):
|
|
self._prices_cache = {}
|
|
self._financial_metrics_cache = {}
|
|
self._line_items_cache = {}
|
|
self._insider_trades_cache = {}
|
|
self._company_news_cache = {}
|
|
|
|
def _merge_data(
|
|
self,
|
|
existing: list[dict] | None,
|
|
new_data: list[dict],
|
|
key_field: str,
|
|
) -> list[dict]:
|
|
"""Merge existing and new data"""
|
|
if not existing:
|
|
return new_data
|
|
|
|
# Create a set of existing keys for O(1) lookup
|
|
existing_keys = {item[key_field] for item in existing}
|
|
|
|
# Only add items that don't exist yet
|
|
merged = existing.copy()
|
|
merged.extend(
|
|
[
|
|
item
|
|
for item in new_data
|
|
if item[key_field] not in existing_keys
|
|
],
|
|
)
|
|
return merged
|
|
|
|
def get_prices(self, ticker: str) -> list[dict[str, Any]] | None:
|
|
"""Get cached price data if available."""
|
|
return self._prices_cache.get(ticker)
|
|
|
|
def set_prices(self, ticker: str, data: list[dict[str, Any]]):
|
|
"""Append new price data to cache."""
|
|
self._prices_cache[ticker] = self._merge_data(
|
|
self._prices_cache.get(ticker),
|
|
data,
|
|
key_field="time",
|
|
)
|
|
|
|
def get_financial_metrics(self, ticker: str) -> list[dict[str, Any]]:
|
|
"""Get cached financial metrics if available."""
|
|
return self._financial_metrics_cache.get(ticker)
|
|
|
|
def set_financial_metrics(self, ticker: str, data: list[dict[str, Any]]):
|
|
"""Append new financial metrics to cache."""
|
|
self._financial_metrics_cache[ticker] = self._merge_data(
|
|
self._financial_metrics_cache.get(ticker),
|
|
data,
|
|
key_field="report_period",
|
|
)
|
|
|
|
def get_line_items(self, ticker: str) -> list[dict[str, Any]] | None:
|
|
"""Get cached line items if available."""
|
|
return self._line_items_cache.get(ticker)
|
|
|
|
def set_line_items(self, ticker: str, data: list[dict[str, Any]]):
|
|
"""Append new line items to cache."""
|
|
self._line_items_cache[ticker] = self._merge_data(
|
|
self._line_items_cache.get(ticker),
|
|
data,
|
|
key_field="report_period",
|
|
)
|
|
|
|
def get_insider_trades(self, ticker: str) -> list[dict[str, Any]] | None:
|
|
"""Get cached insider trades if available."""
|
|
return self._insider_trades_cache.get(ticker)
|
|
|
|
def set_insider_trades(self, ticker: str, data: list[dict[str, Any]]):
|
|
"""Append new insider trades to cache."""
|
|
self._insider_trades_cache[ticker] = self._merge_data(
|
|
self._insider_trades_cache.get(ticker),
|
|
data,
|
|
key_field="filing_date",
|
|
) # Could also use transaction_date if preferred
|
|
|
|
def get_company_news(self, ticker: str) -> list[dict[str, Any]] | None:
|
|
"""Get cached company news if available."""
|
|
return self._company_news_cache.get(ticker)
|
|
|
|
def set_company_news(self, ticker: str, data: list[dict[str, Any]]):
|
|
"""Append new company news to cache."""
|
|
self._company_news_cache[ticker] = self._merge_data(
|
|
self._company_news_cache.get(ticker),
|
|
data,
|
|
key_field="date",
|
|
)
|
|
|
|
|
|
# Global cache instance
|
|
_cache = Cache()
|
|
|
|
|
|
def get_cache() -> Cache:
|
|
"""Get the global cache instance."""
|
|
return _cache
|