365 lines
11 KiB
Python
365 lines
11 KiB
Python
"""
|
|
Simple builder functions for dependency injection in TradingAgents services.
|
|
"""
|
|
|
|
import logging
|
|
|
|
from tradingagents.clients import (
|
|
FinnhubClient,
|
|
GoogleNewsClient,
|
|
RedditClient,
|
|
YFinanceClient,
|
|
)
|
|
from tradingagents.config import TradingAgentsConfig
|
|
from tradingagents.repositories import (
|
|
FundamentalDataRepository,
|
|
InsiderDataRepository,
|
|
MarketDataRepository,
|
|
NewsRepository,
|
|
OpenAIRepository,
|
|
SocialRepository,
|
|
)
|
|
|
|
from .fundamental_data_service import FundamentalDataService
|
|
from .insider_data_service import InsiderDataService
|
|
from .market_data_service import MarketDataService
|
|
from .news_service import NewsService
|
|
from .openai_data_service import OpenAIDataService
|
|
from .social_media_service import SocialMediaService
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def build_market_data_service(config: TradingAgentsConfig) -> MarketDataService:
|
|
"""
|
|
Build MarketDataService with appropriate client and repository.
|
|
|
|
Args:
|
|
config: TradingAgents configuration
|
|
|
|
Returns:
|
|
MarketDataService: Configured service
|
|
"""
|
|
client = None
|
|
repository = None
|
|
|
|
# Create client for online mode
|
|
if config.online_tools:
|
|
try:
|
|
client = YFinanceClient()
|
|
logger.info("Created YFinanceClient for live data")
|
|
except Exception as e:
|
|
logger.warning(f"Failed to create YFinanceClient: {e}")
|
|
|
|
# Always create repository for fallback/offline mode
|
|
try:
|
|
repository = MarketDataRepository(
|
|
data_dir=config.data_dir, cache_dir=config.data_cache_dir
|
|
)
|
|
logger.info(f"Created MarketDataRepository with data_dir: {config.data_dir}")
|
|
except Exception as e:
|
|
logger.error(f"Failed to create MarketDataRepository: {e}")
|
|
|
|
return MarketDataService(
|
|
client=client,
|
|
repository=repository,
|
|
online_mode=config.online_tools,
|
|
data_dir=config.data_dir,
|
|
)
|
|
|
|
|
|
def build_news_service(config: TradingAgentsConfig) -> NewsService:
|
|
"""
|
|
Build NewsService with appropriate clients and repository.
|
|
|
|
Args:
|
|
config: TradingAgents configuration
|
|
|
|
Returns:
|
|
NewsService: Configured service
|
|
"""
|
|
finnhub_client = None
|
|
google_client = None
|
|
repository = None
|
|
|
|
# Create clients for online mode
|
|
if config.online_tools:
|
|
# Finnhub client
|
|
if config.finnhub_api_key:
|
|
try:
|
|
finnhub_client = FinnhubClient(config.finnhub_api_key)
|
|
logger.info("Created FinnhubClient for live news data")
|
|
except Exception as e:
|
|
logger.warning(f"Failed to create FinnhubClient: {e}")
|
|
else:
|
|
logger.info("No Finnhub API key provided, skipping FinnhubClient")
|
|
|
|
# Google News client
|
|
try:
|
|
google_client = GoogleNewsClient()
|
|
logger.info("Created GoogleNewsClient for live news data")
|
|
except Exception as e:
|
|
logger.warning(f"Failed to create GoogleNewsClient: {e}")
|
|
|
|
# Always create repository for fallback/offline mode
|
|
try:
|
|
repository = NewsRepository(
|
|
data_dir=config.data_dir, cache_dir=config.data_cache_dir
|
|
)
|
|
logger.info(f"Created NewsRepository with data_dir: {config.data_dir}")
|
|
except Exception as e:
|
|
logger.error(f"Failed to create NewsRepository: {e}")
|
|
|
|
return NewsService(
|
|
finnhub_client=finnhub_client,
|
|
google_client=google_client,
|
|
repository=repository,
|
|
online_mode=config.online_tools,
|
|
data_dir=config.data_dir,
|
|
)
|
|
|
|
|
|
def build_social_media_service(config: TradingAgentsConfig) -> SocialMediaService:
|
|
"""
|
|
Build SocialMediaService with appropriate client and repository.
|
|
|
|
Args:
|
|
config: TradingAgents configuration
|
|
|
|
Returns:
|
|
SocialMediaService: Configured service
|
|
"""
|
|
client = None
|
|
repository = None
|
|
|
|
# Create client for online mode
|
|
if config.online_tools:
|
|
# Reddit client
|
|
if config.reddit_client_id and config.reddit_client_secret:
|
|
try:
|
|
client = RedditClient(
|
|
client_id=config.reddit_client_id,
|
|
client_secret=config.reddit_client_secret,
|
|
user_agent=config.reddit_user_agent,
|
|
)
|
|
logger.info("Created RedditClient for live social media data")
|
|
except Exception as e:
|
|
logger.warning(f"Failed to create RedditClient: {e}")
|
|
else:
|
|
logger.info("No Reddit credentials provided, skipping RedditClient")
|
|
|
|
# Always create repository for fallback/offline mode
|
|
try:
|
|
repository = SocialRepository(config.data_dir)
|
|
logger.info(f"Created SocialRepository with data_dir: {config.data_dir}")
|
|
except Exception as e:
|
|
logger.error(f"Failed to create SocialRepository: {e}")
|
|
|
|
return SocialMediaService(
|
|
client=client,
|
|
repository=repository,
|
|
online_mode=config.online_tools,
|
|
data_dir=config.data_dir,
|
|
)
|
|
|
|
|
|
def build_fundamental_service(config: TradingAgentsConfig) -> FundamentalDataService:
|
|
"""
|
|
Build FundamentalDataService with appropriate client and repository.
|
|
|
|
Args:
|
|
config: TradingAgents configuration
|
|
|
|
Returns:
|
|
FundamentalDataService: Configured service
|
|
"""
|
|
client = None
|
|
repository = None
|
|
|
|
# Create client for online mode
|
|
if config.online_tools:
|
|
# SimFin client (would be implemented when SimFinClient is available)
|
|
# try:
|
|
# client = SimFinClient() # This would need API key configuration
|
|
# logger.info("Created SimFinClient for live fundamental data")
|
|
# except Exception as e:
|
|
# logger.warning(f"Failed to create SimFinClient: {e}")
|
|
logger.info("SimFinClient not yet implemented, using repository only")
|
|
|
|
# Always create repository for fallback/offline mode
|
|
try:
|
|
repository = FundamentalDataRepository(config.data_dir)
|
|
logger.info(
|
|
f"Created FundamentalDataRepository with data_dir: {config.data_dir}"
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"Failed to create FundamentalDataRepository: {e}")
|
|
|
|
return FundamentalDataService(
|
|
simfin_client=client,
|
|
repository=repository,
|
|
online_mode=config.online_tools,
|
|
data_dir=config.data_dir,
|
|
)
|
|
|
|
|
|
def build_insider_service(config: TradingAgentsConfig) -> InsiderDataService:
|
|
"""
|
|
Build InsiderDataService with appropriate client and repository.
|
|
|
|
Args:
|
|
config: TradingAgents configuration
|
|
|
|
Returns:
|
|
InsiderDataService: Configured service
|
|
"""
|
|
client = None
|
|
repository = None
|
|
|
|
# Create client for online mode
|
|
if config.online_tools:
|
|
# Finnhub client for insider data
|
|
if config.finnhub_api_key:
|
|
try:
|
|
client = FinnhubClient(config.finnhub_api_key)
|
|
logger.info("Created FinnhubClient for live insider trading data")
|
|
except Exception as e:
|
|
logger.warning(f"Failed to create FinnhubClient for insider data: {e}")
|
|
else:
|
|
logger.info("No Finnhub API key provided, skipping insider data client")
|
|
|
|
# Always create repository for fallback/offline mode
|
|
try:
|
|
repository = InsiderDataRepository(config.data_dir)
|
|
logger.info(f"Created InsiderDataRepository with data_dir: {config.data_dir}")
|
|
except Exception as e:
|
|
logger.error(f"Failed to create InsiderDataRepository: {e}")
|
|
|
|
return InsiderDataService(
|
|
finnhub_client=client,
|
|
repository=repository,
|
|
online_mode=config.online_tools,
|
|
data_dir=config.data_dir,
|
|
)
|
|
|
|
|
|
def build_openai_service(config: TradingAgentsConfig) -> OpenAIDataService:
|
|
"""
|
|
Build OpenAIDataService with appropriate client and repository.
|
|
|
|
Args:
|
|
config: TradingAgents configuration
|
|
|
|
Returns:
|
|
OpenAIDataService: Configured service
|
|
"""
|
|
client = None
|
|
repository = None
|
|
|
|
# Create client for online mode
|
|
if config.online_tools:
|
|
# OpenAI client (would be implemented when OpenAIClient is available)
|
|
# if config.openai_api_key:
|
|
# try:
|
|
# client = OpenAIClient(api_key=config.openai_api_key)
|
|
# logger.info("Created OpenAIClient for AI-powered analysis")
|
|
# except Exception as e:
|
|
# logger.warning(f"Failed to create OpenAIClient: {e}")
|
|
# else:
|
|
# logger.info("No OpenAI API key provided, skipping OpenAI client")
|
|
logger.info("OpenAIClient not yet implemented, using repository only")
|
|
|
|
# Always create repository for fallback/offline mode
|
|
try:
|
|
repository = OpenAIRepository(config.data_dir)
|
|
logger.info(f"Created OpenAIRepository with data_dir: {config.data_dir}")
|
|
except Exception as e:
|
|
logger.error(f"Failed to create OpenAIRepository: {e}")
|
|
|
|
return OpenAIDataService(
|
|
openai_client=client,
|
|
repository=repository,
|
|
online_mode=config.online_tools,
|
|
data_dir=config.data_dir,
|
|
)
|
|
|
|
|
|
def build_all_services(config: TradingAgentsConfig) -> dict:
|
|
"""
|
|
Build all available services.
|
|
|
|
Args:
|
|
config: TradingAgents configuration
|
|
|
|
Returns:
|
|
dict: Dictionary of service name to service instance
|
|
"""
|
|
services = {}
|
|
|
|
# Build MarketDataService
|
|
try:
|
|
services["market_data"] = build_market_data_service(config)
|
|
logger.info("Built MarketDataService")
|
|
except Exception as e:
|
|
logger.error(f"Failed to build MarketDataService: {e}")
|
|
|
|
# Build NewsService
|
|
try:
|
|
services["news"] = build_news_service(config)
|
|
logger.info("Built NewsService")
|
|
except Exception as e:
|
|
logger.error(f"Failed to build NewsService: {e}")
|
|
|
|
# Build SocialMediaService
|
|
try:
|
|
services["social_media"] = build_social_media_service(config)
|
|
logger.info("Built SocialMediaService")
|
|
except Exception as e:
|
|
logger.error(f"Failed to build SocialMediaService: {e}")
|
|
|
|
# Build FundamentalDataService
|
|
try:
|
|
services["fundamental"] = build_fundamental_service(config)
|
|
logger.info("Built FundamentalDataService")
|
|
except Exception as e:
|
|
logger.error(f"Failed to build FundamentalDataService: {e}")
|
|
|
|
# Build InsiderDataService
|
|
try:
|
|
services["insider"] = build_insider_service(config)
|
|
logger.info("Built InsiderDataService")
|
|
except Exception as e:
|
|
logger.error(f"Failed to build InsiderDataService: {e}")
|
|
|
|
# Build OpenAIDataService
|
|
try:
|
|
services["openai"] = build_openai_service(config)
|
|
logger.info("Built OpenAIDataService")
|
|
except Exception as e:
|
|
logger.error(f"Failed to build OpenAIDataService: {e}")
|
|
|
|
logger.info(f"Built {len(services)} services: {list(services.keys())}")
|
|
return services
|
|
|
|
|
|
def build_toolkit_services(config: TradingAgentsConfig) -> dict:
|
|
"""
|
|
Build services specifically configured for Toolkit usage.
|
|
|
|
Args:
|
|
config: TradingAgents configuration
|
|
|
|
Returns:
|
|
dict: Dictionary of services for Toolkit
|
|
"""
|
|
return build_all_services(config)
|
|
|
|
|
|
# Aliases for the service toolkit
|
|
create_market_data_service = build_market_data_service
|
|
create_news_service = build_news_service
|
|
create_social_media_service = build_social_media_service
|
|
create_fundamental_data_service = build_fundamental_service
|
|
create_insider_data_service = build_insider_service
|
|
create_openai_data_service = build_openai_service
|