diff --git a/.env.example b/.env.example index 6f5a8964..100d87c1 100644 --- a/.env.example +++ b/.env.example @@ -9,3 +9,13 @@ BYBIT_BASE_URL=https://api-demo.bybit.com BYBIT_API_KEY=bybit_api_key_placeholder BYBIT_API_SECRET=bybit_api_secret_placeholder COIN_GECKO_API_BASE_URL=https://api.coingecko.com/api/v3 + +# Model settings +LLM_PROVIDER=openai +BACKEND_URL=https://api.openai.com/v1 +DEEP_THINK_LLM=gpt-4o-mini +QUICK_THINK_LLM=gpt-4o-mini + +# App settings +APP_HOST=localhost +APP_PORT=8000 diff --git a/README.md b/README.md index 2c1f07d0..4173bf5e 100644 --- a/README.md +++ b/README.md @@ -239,3 +239,8 @@ Please reference our work if you find *TradingAgents* provides you with some hel url={https://arxiv.org/abs/2412.20138}, } ``` + +## How to Run +``` +python3 webapp.py +``` diff --git a/pyproject.toml b/pyproject.toml index 63af4721..664e7831 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,8 @@ dependencies = [ "rich>=14.0.0", "setuptools>=80.9.0", "stockstats>=0.6.5", + "fastapi>=0.115.0", + "uvicorn[standard]>=0.32.0", "tqdm>=4.67.1", "tushare>=1.4.21", "typing-extensions>=4.14.0", diff --git a/requirements.txt b/requirements.txt index 48de6aa7..57be465a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -26,3 +26,5 @@ langchain_anthropic langchain-google-genai binance-sdk-spot telethon +fastapi +uvicorn[standard] diff --git a/tradingagents/agents/utils/memory.py b/tradingagents/agents/utils/memory.py index 69b8ab8c..f8e1da2e 100644 --- a/tradingagents/agents/utils/memory.py +++ b/tradingagents/agents/utils/memory.py @@ -11,7 +11,7 @@ class FinancialSituationMemory: self.embedding = "text-embedding-3-small" self.client = OpenAI(base_url=config["backend_url"]) self.chroma_client = chromadb.Client(Settings(allow_reset=True)) - self.situation_collection = self.chroma_client.create_collection(name=name) + self.situation_collection = self.chroma_client.get_or_create_collection(name=name) def get_embedding(self, text): """Get OpenAI embedding for a text""" diff --git a/tradingagents/default_config.py b/tradingagents/default_config.py index 3709a302..d9e891c6 100644 --- a/tradingagents/default_config.py +++ b/tradingagents/default_config.py @@ -1,6 +1,10 @@ import os DEFAULT_CONFIG = { + # App config + "APP_HOST": "localhost", + "APP_PORT": 8000, + # Directory settings "project_dir": os.path.abspath(os.path.join(os.path.dirname(__file__), ".")), "results_dir": os.getenv("TRADINGAGENTS_RESULTS_DIR", "./results"), "data_dir": "/Users/yluo/Documents/Code/ScAI/FR1-data", @@ -9,10 +13,10 @@ DEFAULT_CONFIG = { "dataflows/data_cache", ), # LLM settings - "llm_provider": "openai", - "deep_think_llm": "o4-mini", - "quick_think_llm": "gpt-4o-mini", - "backend_url": "https://api.openai.com/v1", + "llm_provider": os.getenv("LLM_PROVIDER", "openai"), + "deep_think_llm": os.getenv("DEEP_THINK_LLM", "gpt-4o-mini"), + "quick_think_llm": os.getenv("QUICK_THINK_LLM", "gpt-4o-mini"), + "backend_url": os.getenv("BACKEND_URL","https://api.openai.com/v1"), # Debate and discussion settings "max_debate_rounds": 1, "max_risk_discuss_rounds": 1, @@ -29,9 +33,6 @@ DEFAULT_CONFIG = { "tool_vendors": { "get_global_news": "telegram" # Override category default }, - # Tool provider settings - "tool_providers": { - }, "external": { "BINANCE_API_KEY": os.getenv("BINANCE_API_KEY", ""), "TAAPI_BASE_URL": os.getenv("TAAPI_BASE_URL", "https://api.taapi.io"), diff --git a/webapp.py b/webapp.py new file mode 100644 index 00000000..a583fac7 --- /dev/null +++ b/webapp.py @@ -0,0 +1,105 @@ +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel +import uvicorn +from datetime import datetime +import asyncio + +# Import your trading agents +from tradingagents.graph.trading_graph import TradingAgentsGraph +from tradingagents.dataflows.config import get_config +from dotenv import load_dotenv + +# Load environment variables +load_dotenv() + +config = get_config() + +# Create FastAPI app instance +app = FastAPI( + title="TradingAgents API", + description="API for TradingAgents financial trading framework", + version="0.1.0" +) + +# Pydantic models for request/response +class TradingRequest(BaseModel): + symbol: str + date: str + +class TradingResponse(BaseModel): + symbol: str + date: str + decision: dict + timestamp: str + status: str + +# Initialize trading agent once at startup +def create_trading_agent(): + """Create trading agent with fixed configuration""" + return TradingAgentsGraph(debug=True, config=config) + +# Create the trading agent instance once +trading_agent = create_trading_agent() + +@app.get("/") +async def root(): + """Root endpoint""" + return {"message": "Welcome to TradingAgents API"} + +@app.get("/ping") +async def ping(): + """Simple ping endpoint that returns pong""" + return {"message": "pong"} + +@app.get("/health") +async def health_check(): + """Health check endpoint""" + return { + "status": "healthy", + "timestamp": datetime.now().isoformat(), + "service": "tradingagents-api" + } + +@app.post("/trading/analyze", response_model=TradingResponse) +async def analyze_trading_decision(request: TradingRequest): + """ + Analyze trading decision for a given symbol and date + + Example usage: + POST /trading/analyze + { + "symbol": "NVDA", + "date": "2024-05-10" + } + """ + try: + # Run the analysis (this might take a while, so we run it in a thread pool) + def run_analysis(): + _, decision = trading_agent.propagate(request.symbol, request.date) + return decision + + # Run in thread pool to avoid blocking + loop = asyncio.get_event_loop() + decision = await loop.run_in_executor(None, run_analysis) + + return TradingResponse( + symbol=request.symbol, + date=request.date, + decision=decision, + timestamp=datetime.now().isoformat(), + status="success" + ) + + except Exception as e: + raise HTTPException(status_code=500, detail=f"Trading analysis failed: {str(e)}") + + +if __name__ == "__main__": + # Run the server + uvicorn.run( + "webapp:app", + host=config.get("APP_HOST", "localhost"), + port=config.get("APP_PORT", 8000), + reload=True, + log_level="info" + )