From c360f2f8ebeba620e921d8df880cdd7a4ef5cae0 Mon Sep 17 00:00:00 2001 From: zhonghao lu Date: Tue, 23 Sep 2025 14:15:48 +0800 Subject: [PATCH] refactor:remove useless dir --- python/valuecell/examples/__init__.py | 2 - .../ai_hedge_fund_websocket_example.html | 286 -------------- .../ai_hedge_fund_websocket_example.py | 174 --------- .../examples/asset_adapter_example.py | 361 ------------------ .../valuecell/examples/trading_agents_demo.py | 183 --------- 5 files changed, 1006 deletions(-) delete mode 100644 python/valuecell/examples/__init__.py delete mode 100644 python/valuecell/examples/ai_hedge_fund_websocket_example.html delete mode 100644 python/valuecell/examples/ai_hedge_fund_websocket_example.py delete mode 100644 python/valuecell/examples/asset_adapter_example.py delete mode 100644 python/valuecell/examples/trading_agents_demo.py diff --git a/python/valuecell/examples/__init__.py b/python/valuecell/examples/__init__.py deleted file mode 100644 index d6ed70d8a..000000000 --- a/python/valuecell/examples/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Examples for ValueCell i18n system.""" -# TODO: This file is a temporary file, it will be removed in the future. diff --git a/python/valuecell/examples/ai_hedge_fund_websocket_example.html b/python/valuecell/examples/ai_hedge_fund_websocket_example.html deleted file mode 100644 index 30649ba9c..000000000 --- a/python/valuecell/examples/ai_hedge_fund_websocket_example.html +++ /dev/null @@ -1,286 +0,0 @@ - - - - - - AI Hedge Fund WebSocket Client - - - -
-

AI Hedge Fund Analysis

- -
- Status: Disconnected -
- -
- - -
- -
- - -
- -
- - -
- - - - - - -
-
- - - - \ No newline at end of file diff --git a/python/valuecell/examples/ai_hedge_fund_websocket_example.py b/python/valuecell/examples/ai_hedge_fund_websocket_example.py deleted file mode 100644 index 9482ccecf..000000000 --- a/python/valuecell/examples/ai_hedge_fund_websocket_example.py +++ /dev/null @@ -1,174 +0,0 @@ -import json -import logging -from typing import Optional - -from fastapi import FastAPI, WebSocket, WebSocketDisconnect -from pydantic import BaseModel, Field -from valuecell.core.coordinate.orchestrator import get_default_orchestrator -from valuecell.core.types import UserInput, UserInputMetadata - -logger = logging.getLogger(__name__) - -AGENT_ANALYST_MAP = { - "aswath_damodaran_agent": ("Aswath Damodaran", "aswath_damodaran"), - "ben_graham_agent": ("Ben Graham", "ben_graham"), - "bill_ackman_agent": ("Bill Ackman", "bill_ackman"), - "cathie_wood_agent": ("Cathie Wood", "cathie_wood"), - "charlie_munger_agent": ("Charlie Munger", "charlie_munger"), - "michael_burry_agent": ("Michael Burry", "michael_burry"), - "mohnish_pabrai_agent": ("Mohnish Pabrai", "mohnish_pabrai"), - "peter_lynch_agent": ("Peter Lynch", "peter_lynch"), - "phil_fisher_agent": ("Phil Fisher", "phil_fisher"), - "rakesh_jhunjhunwala_agent": ("Rakesh Jhunjhunwala", "rakesh_jhunjhunwala"), - "stanley_druckenmiller_agent": ("Stanley Druckenmiller", "stanley_druckenmiller"), - "warren_buffett_agent": ("Warren Buffett", "warren_buffett"), - "technical_analyst_agent": ("Technical Analyst", "technical_analyst"), - "fundamentals_analyst_agent": ("Fundamentals Analyst", "fundamentals_analyst"), - "sentiment_analyst_agent": ("Sentiment Analyst", "sentiment_analyst"), - "valuation_analyst_agent": ("Valuation Analyst", "valuation_analyst"), -} - - -class AnalysisRequest(BaseModel): - agent_name: str = Field(..., description="The name of the agent to use") - query: str = Field(..., description="The user's query for the agent") - session_id: Optional[str] = Field( - None, description="Session ID, will be auto-generated if not provided" - ) - user_id: str = Field("default_user", description="User ID") - - -def _parse_user_input(request: AnalysisRequest) -> UserInput: - """Parse user input into internal format""" - session_id = request.session_id or f"{request.agent_name}_session_{request.user_id}" - - meta = UserInputMetadata( - session_id=session_id, - user_id=request.user_id, - ) - - query = request.query - selected_analyst = AGENT_ANALYST_MAP.get(request.agent_name) - if selected_analyst: - query += f"\n\n**Hint**: Use {selected_analyst[0]} ({selected_analyst[1]}) in your analysis." - - return UserInput(desired_agent_name="AIHedgeFundAgent", query=query, meta=meta) - - -app = FastAPI( - title="AI Hedge Fund WebSocket API", - description="Real-time stock analysis via WebSocket", - version="1.0.0", -) - - -@app.get("/") -async def root(): - """Health check endpoint""" - return { - "message": "AI Hedge Fund WebSocket API is running", - "version": "1.0.0", - "websocket_endpoint": "/ws", - } - - -@app.websocket("/ws") -async def websocket_endpoint(websocket: WebSocket): - """WebSocket endpoint for real-time stock analysis""" - await websocket.accept() - logger.info("WebSocket connection established") - - try: - orchestrator = get_default_orchestrator() - - while True: - # Receive message from client - data = await websocket.receive_text() - logger.info(f"Received message: {data}") - - try: - # Parse the incoming message - message_data = json.loads(data) - - # Validate agent name - agent_name = message_data.get("agent_name") - if agent_name not in AGENT_ANALYST_MAP: - await websocket.send_text( - json.dumps( - { - "type": "error", - "message": f"Unsupported agent: {agent_name}. Available agents: {list(AGENT_ANALYST_MAP.keys())}", - } - ) - ) - continue - - # Create analysis request - request = AnalysisRequest(**message_data) - user_input = _parse_user_input(request) - - # Send analysis start notification - await websocket.send_text( - json.dumps( - { - "type": "analysis_started", - "agent_name": request.agent_name, - } - ) - ) - - # Stream analysis results - async for message_chunk in orchestrator.process_user_input(user_input): - response = { - "type": "analysis_chunk", - "message": str(message_chunk), - "agent_name": request.agent_name, - } - await websocket.send_text(json.dumps(response)) - logger.info(f"Sent message chunk: {message_chunk}") - - # Send completion notification - await websocket.send_text( - json.dumps( - { - "type": "analysis_completed", - "agent_name": request.agent_name, - } - ) - ) - - except json.JSONDecodeError: - await websocket.send_text( - json.dumps({"type": "error", "message": "Invalid JSON format"}) - ) - except Exception as e: - logger.error(f"Error processing request: {e}") - await websocket.send_text( - json.dumps( - {"type": "error", "message": f"Analysis failed: {str(e)}"} - ) - ) - - except WebSocketDisconnect: - logger.info("WebSocket connection closed") - except Exception as e: - logger.error(f"WebSocket error: {e}") - - -if __name__ == "__main__": - import uvicorn - - # Configure logging - logging.basicConfig( - level=logging.INFO, - format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", - ) - - # Start server - uvicorn.run( - "ai_hedge_fund_websocket_example:app", - host="0.0.0.0", - port=8000, - reload=True, - log_level="info", - ) diff --git a/python/valuecell/examples/asset_adapter_example.py b/python/valuecell/examples/asset_adapter_example.py deleted file mode 100644 index 852000cb6..000000000 --- a/python/valuecell/examples/asset_adapter_example.py +++ /dev/null @@ -1,361 +0,0 @@ -"""Example usage of the ValueCell Asset Data Adapter system. - -This example demonstrates how to configure and use the asset data adapters -for financial data retrieval, search, and watchlist management with i18n support. -""" - -import logging - -from valuecell.adapters.assets import get_adapter_manager -from valuecell.server.services.assets.asset_service import ( - get_asset_service, - search_assets, - get_asset_info, - get_asset_price, - add_to_watchlist, - get_watchlist, -) -from valuecell.server.config.i18n import set_i18n_config, I18nConfig - -# Configure logging -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - - -def setup_adapters(): - """Configure and initialize data adapters.""" - logger.info("Setting up data adapters...") - - # Get adapter manager - manager = get_adapter_manager() - - # Configure Yahoo Finance (free, no API key required) - try: - manager.configure_yfinance() - logger.info("✓ Yahoo Finance adapter configured") - except Exception as e: - logger.warning(f"✗ Yahoo Finance adapter failed: {e}") - - # Configure TuShare (requires API key) - try: - # Replace with your actual TuShare API key - tushare_api_key = "your_tushare_api_key_here" - if tushare_api_key != "your_tushare_api_key_here": - manager.configure_tushare(api_key=tushare_api_key) - logger.info("✓ TuShare adapter configured") - else: - logger.warning("✗ TuShare API key not provided, skipping") - except Exception as e: - logger.warning(f"✗ TuShare adapter failed: {e}") - - # Configure CoinMarketCap (requires API key for crypto data) - try: - # Replace with your actual CoinMarketCap API key - cmc_api_key = "your_coinmarketcap_api_key_here" - if cmc_api_key != "your_coinmarketcap_api_key_here": - manager.configure_coinmarketcap(api_key=cmc_api_key) - logger.info("✓ CoinMarketCap adapter configured") - else: - logger.warning("✗ CoinMarketCap API key not provided, skipping") - except Exception as e: - logger.warning(f"✗ CoinMarketCap adapter failed: {e}") - - # Configure AKShare (free, no API key required) - # Now supports A-shares, US stocks, Hong Kong stocks, and cryptocurrencies - try: - manager.configure_akshare() - logger.info( - "✓ AKShare adapter configured (supports A-shares, HK stocks, US stocks, and crypto)" - ) - except Exception as e: - logger.warning(f"✗ AKShare adapter failed: {e}") - - # Configure Finnhub (requires API key) - try: - # Replace with your actual Finnhub API key - finnhub_api_key = "your_finnhub_api_key_here" - if finnhub_api_key != "your_finnhub_api_key_here": - manager.configure_finnhub(api_key=finnhub_api_key) - logger.info("✓ Finnhub adapter configured") - else: - logger.warning("✗ Finnhub API key not provided, skipping") - except Exception as e: - logger.warning(f"✗ Finnhub adapter failed: {e}") - - # Check system health - service = get_asset_service() - health = service.get_system_health() - logger.info( - f"System health: {health['overall_status']} " - f"({health['healthy_adapters']}/{health['total_adapters']} adapters)" - ) - - return manager - - -def demonstrate_asset_search(): - """Demonstrate asset search functionality with i18n.""" - logger.info("\n=== Asset Search Demo ===") - - # Search in English - logger.info("Searching for 'AAPL' in English...") - results_en = search_assets("AAPL", language="en-US", limit=5) - - if results_en["success"]: - logger.info(f"Found {results_en['count']} results:") - for result in results_en["results"]: - logger.info( - f" - {result['ticker']}: {result['display_name']} " - f"({result['asset_type_display']})" - ) - - # Search in Chinese - logger.info("\nSearching for '00700.HK' in Chinese...") - results_zh = search_assets("00700.HK", language="zh-Hans", limit=5) - - if results_zh["success"]: - logger.info(f"Found {results_zh['count']} results:") - for result in results_zh["results"]: - logger.info( - f" - {result['ticker']}: {result['display_name']} " - f"({result['asset_type_display']})" - ) - - # Search for Chinese stocks - logger.info("\nSearching for Chinese stocks...") - results_cn = search_assets("600519", asset_types=["stock"], limit=3) - - if results_cn["success"]: - logger.info(f"Found {results_cn['count']} Chinese stocks:") - for result in results_cn["results"]: - logger.info(f" - {result['ticker']}: {result['display_name']}") - - # Search for cryptocurrencies - logger.info("\nSearching for cryptocurrencies...") - results_crypto = search_assets("BTC-USD", asset_types=["crypto"], limit=3) - - if results_crypto["success"]: - logger.info(f"Found {results_crypto['count']} cryptocurrencies:") - for result in results_crypto["results"]: - logger.info(f" - {result['ticker']}: {result['display_name']}") - - # Demonstrate enhanced AKShare multi-market search - logger.info("\n=== Enhanced Multi-Market Search (AKShare) ===") - - # Search Hong Kong stocks - logger.info("Searching for Hong Kong stocks (Tencent)...") - hk_results = search_assets("00700", limit=3) - if hk_results["success"]: - for result in hk_results["results"]: - logger.info(f" - HK Stock: {result['ticker']}: {result['display_name']}") - - # Search US stocks through AKShare - logger.info("\nSearching for US stocks through AKShare...") - us_results = search_assets("AAPL", exchanges=["NASDAQ", "NYSE"], limit=3) - if us_results["success"]: - for result in us_results["results"]: - logger.info(f" - US Stock: {result['ticker']}: {result['display_name']}") - - # Direct ticker lookup fallback - logger.info("\nDemonstrating semantic search fallback...") - direct_results = search_assets( - "000001", limit=3 - ) # Should find through direct lookup - if direct_results["success"]: - for result in direct_results["results"]: - logger.info( - f" - Direct Match: {result['ticker']}: {result['display_name']}" - ) - - -def demonstrate_asset_info(): - """Demonstrate getting detailed asset information.""" - logger.info("\n=== Asset Information Demo ===") - - # Get info for Apple stock - tickers = ["NASDAQ:AAPL", "HKEX:700", "SSE:600519", "CRYPTO:BTC"] - - for ticker in tickers: - logger.info(f"\nGetting info for {ticker}...") - - # Get in English - info_en = get_asset_info(ticker, language="en-US") - if info_en["success"]: - logger.info( - f" English: {info_en['display_name']} " - f"({info_en['asset_type_display']})" - ) - logger.info(f" Exchange: {info_en['market_info']['exchange']}") - logger.info(f" Country: {info_en['market_info']['country']}") - - # Get in Chinese - info_zh = get_asset_info(ticker, language="zh-Hans") - if info_zh["success"]: - logger.info( - f" Chinese: {info_zh['display_name']} ({info_zh['asset_type_display']})" - ) - - -def demonstrate_price_data(): - """Demonstrate real-time price data retrieval.""" - logger.info("\n=== Price Data Demo ===") - - tickers = ["NASDAQ:AAPL", "HKEX:700", "SSE:600519", "CRYPTO:BTC"] - - # Get individual price - logger.info("Getting individual price for AAPL...") - price_data = get_asset_price("NASDAQ:AAPL", language="en-US") - - if price_data["success"]: - logger.info(f" Price: {price_data['price_formatted']}") - if price_data["change_percent_formatted"]: - logger.info(f" Change: {price_data['change_percent_formatted']}") - if price_data["market_cap_formatted"]: - logger.info(f" Market Cap: {price_data['market_cap_formatted']}") - - # Get multiple prices - logger.info(f"\nGetting prices for multiple assets: {tickers}") - service = get_asset_service() - prices_data = service.get_multiple_prices(tickers, language="en-US") - - if prices_data["success"]: - logger.info(f"Successfully retrieved {prices_data['count']} prices:") - for ticker, price_info in prices_data["prices"].items(): - if price_info: - logger.info( - f" {ticker}: {price_info['price_formatted']} " - f"({price_info.get('change_percent_formatted', 'N/A')})" - ) - else: - logger.info(f" {ticker}: Price not available") - - -def demonstrate_watchlist_management(): - """Demonstrate watchlist creation and management.""" - logger.info("\n=== Watchlist Management Demo ===") - - user_id = "demo_user_123" - service = get_asset_service() - - # Create a watchlist - logger.info("Creating a new watchlist...") - create_result = service.create_watchlist( - user_id=user_id, - name="My Tech Stocks", - description="Technology companies I'm watching", - is_default=True, - ) - - if create_result["success"]: - logger.info("✓ Watchlist created successfully") - - # Add assets to watchlist - assets_to_add = [ - ("NASDAQ:AAPL", "Apple - iPhone maker"), - ("HKEX:700", "Tencent - Chinese tech giant"), - ("SSE:600519", "Kweichow Moutai - Chinese liquor company"), - ("CRYPTO:BTC", "Bitcoin - First and largest cryptocurrency"), - ] - - logger.info("Adding assets to watchlist...") - for ticker, notes in assets_to_add: - result = add_to_watchlist(user_id=user_id, ticker=ticker, notes=notes) - if result["success"]: - logger.info(f" ✓ Added {ticker}") - else: - logger.warning(f" ✗ Failed to add {ticker}: {result.get('error')}") - - # Get watchlist with prices - logger.info("\nRetrieving watchlist with current prices...") - watchlist_data = get_watchlist( - user_id=user_id, include_prices=True, language="zh-Hans" - ) - - if watchlist_data["success"]: - watchlist = watchlist_data["watchlist"] - logger.info(f"Watchlist: {watchlist['name']}") - logger.info(f"Number of assets: {watchlist['items_count']}") - - for asset in watchlist["assets"]: - display_name = asset["display_name"] - notes = asset["notes"] - - price_info = "" - if "price_data" in asset and asset["price_data"]: - price_data = asset["price_data"] - price_info = f" - {price_data['price_formatted']}" - if price_data.get("change_percent_formatted"): - price_info += f" ({price_data['change_percent_formatted']})" - - logger.info(f" • {display_name}{price_info}") - if notes: - logger.info(f" Notes: {notes}") - - # List all user watchlists - logger.info("\nListing all user watchlists...") - all_watchlists = service.get_user_watchlists(user_id) - - if all_watchlists["success"]: - logger.info(f"User {user_id} has {all_watchlists['count']} watchlists:") - for wl in all_watchlists["watchlists"]: - default_marker = " (Default)" if wl["is_default"] else "" - logger.info( - f" • {wl['name']}{default_marker} - {wl['items_count']} assets" - ) - - -def demonstrate_i18n_features(): - """Demonstrate internationalization features.""" - logger.info("\n=== Internationalization Demo ===") - - # Test different languages - languages = ["en-US", "zh-Hans", "zh-Hant"] - ticker = "NASDAQ:AAPL" - - for lang in languages: - logger.info(f"\nTesting language: {lang}") - - # Set language configuration - config = I18nConfig(language=lang) - set_i18n_config(config) - - # Search for assets - results = search_assets("APPL", language=lang, limit=1) - if results["success"] and results["results"]: - result = results["results"][0] - logger.info( - f" Search result: {result['display_name']} ({result['asset_type_display']})" - ) - - # Get price with localized formatting - price_data = get_asset_price(ticker, language=lang) - if price_data["success"]: - logger.info(f" Price: {price_data['price_formatted']}") - if price_data.get("change_percent_formatted"): - logger.info(f" Change: {price_data['change_percent_formatted']}") - - -def main(): - """Main demonstration function.""" - logger.info("=== ValueCell Asset Data Adapter Demo ===") - - try: - # Setup adapters - setup_adapters() - - # Run demonstrations - demonstrate_asset_search() - demonstrate_asset_info() - demonstrate_price_data() - demonstrate_watchlist_management() - demonstrate_i18n_features() - - logger.info("\n=== Demo completed successfully! ===") - - except Exception as e: - logger.error(f"Demo failed with error: {e}") - raise - - -if __name__ == "__main__": - main() diff --git a/python/valuecell/examples/trading_agents_demo.py b/python/valuecell/examples/trading_agents_demo.py deleted file mode 100644 index 58edc5f4f..000000000 --- a/python/valuecell/examples/trading_agents_demo.py +++ /dev/null @@ -1,183 +0,0 @@ -""" -TradingAgents Interactive Demo - -This script demonstrates how to: -1. Connect to TradingAgents -2. Run an interactive conversation -3. Select LLM, analysts, and stock -4. Get trading analysis results -""" - -import asyncio -import logging -from typing import Optional - -from valuecell.core.agent.connect import RemoteConnections - -# Set up logging -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - - -class TradingAgentsDemo: - """TradingAgents interactive demo class""" - - def __init__(self): - self.connections = RemoteConnections() - self.agent_name = "TradingAgentsAdapter" - self.client: Optional[object] = None - - async def setup(self): - """Set up connection""" - try: - # Connect to remote agent - # agent_url = await self.connections.connect_remote_agent(self.agent_name) - # logger.info(f"TradingAgents connected successfully: {agent_url}") - - # Get client connection - self.client = await self.connections.get_client(self.agent_name) - logger.info("Client connection established successfully") - - return True - except Exception as e: - logger.error(f"Setup failed: {e}") - return False - - async def interactive_session(self): - """Interactive session""" - print("\n" + "=" * 60) - print("🚀 TradingAgents interactive demo") - print("=" * 60) - print("Enter 'help' to get help information") - print("Enter 'quit' or 'exit' to exit") - print("=" * 60 + "\n") - - while True: - try: - # Get user input - user_input = input("💬 Please enter your query: ").strip() - - if not user_input: - continue - - if user_input.lower() in ["quit", "exit", "exit"]: - print("👋 Bye!") - break - - # Send message and get streaming response - print("\n🤖 TradingAgents response:") - print("-" * 50) - - async for task, event in await self.client.send_message( - user_input, - streaming=True, - ): - # Check artifact content (main response content) - if task and task.artifacts: - for artifact in task.artifacts: - if artifact.parts: - for part in artifact.parts: - if hasattr(part.root, "text") and part.root.text: - print(part.root.text, end="", flush=True) - - # Check event content - elif event and hasattr(event, "content") and event.content: - print(event.content, end="", flush=True) - - print("\n" + "-" * 50 + "\n") - - except KeyboardInterrupt: - print("\n👋 User interrupted, exiting...") - break - except Exception as e: - logger.error(f"Error processing message: {e}") - print(f"❌ Error: {e}\n") - - async def run_demo_queries(self): - """Run preset demo queries""" - demo_queries = [ - "help", # Get help information - "Analyze AAPL stock", # Basic analysis - "Use market and fundamentals analysts to analyze NVDA", # Specify analysts - "Use anthropic provider to analyze TSLA, date 2024-01-15", # Specify LLM and date - "Analyze SPY, use all analysts, enable debug mode", # Full parameters - ] - - print("\n" + "=" * 60) - print("🎯 Run demo queries") - print("=" * 60) - - for i, query in enumerate(demo_queries, 1): - print(f"\n📝 Demo query {i}: {query}") - print("-" * 50) - - try: - async for task, event in await self.client.send_message( - query, - streaming=True, - ): - # Check artifact content (main response content) - if task and task.artifacts: - for artifact in task.artifacts: - if artifact.parts: - for part in artifact.parts: - if hasattr(part.root, "text") and part.root.text: - print(part.root.text, end="", flush=True) - - # Check event content - elif event and hasattr(event, "content") and event.content: - print(event.content, end="", flush=True) - - print("\n" + "-" * 50) - - # Wait for user to confirm continue - if i < len(demo_queries): - input("\n⏸️ Press Enter to continue to the next demo...") - - except Exception as e: - logger.error(f"Demo query failed: {e}") - print(f"❌ Demo query failed: {e}\n") - - async def cleanup(self): - """Clean up resources""" - try: - await self.connections.stop_all() - logger.info("Resources cleaned up") - except Exception as e: - logger.error(f"Error cleaning up resources: {e}") - - -async def main(): - """Main function""" - demo = TradingAgentsDemo() - - # Set up connection - if not await demo.setup(): - print( - "❌ Cannot connect to TradingAgents, please ensure the service is running" - ) - return - - try: - print("\nPlease select the running mode:") - print("1. Interactive dialog mode") - print("2. Run preset demo") - - choice = input("Please enter the choice (1 or 2): ").strip() - - if choice == "1": - await demo.interactive_session() - elif choice == "2": - await demo.run_demo_queries() - else: - print("Invalid choice, default running interactive mode") - await demo.interactive_session() - - except KeyboardInterrupt: - print("\n👋 Program interrupted") - finally: - await demo.cleanup() - - -if __name__ == "__main__": - asyncio.run(main())