| import sys |
| import os |
| sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
|
|
| from fastapi import FastAPI, HTTPException, Request |
| from fastapi.middleware.cors import CORSMiddleware |
| from models import AgentAction |
| from server.environment import TradingEnvironment |
| import uvicorn |
|
|
| app = FastAPI(title="Quant-Gym", description="Financial Analysis Environment") |
|
|
| app.add_middleware( |
| CORSMiddleware, |
| allow_origins=["*"], |
| allow_credentials=True, |
| allow_methods=["*"], |
| allow_headers=["*"], |
| ) |
|
|
| env = TradingEnvironment() |
|
|
| @app.get("/") |
| def root(): |
| return {"message": "Quant-Gym API is running"} |
|
|
| @app.get("/health") |
| def health(): |
| return {"status": "healthy"} |
|
|
| @app.post("/reset") |
| def reset(): |
| obs = env.reset() |
| return {"status": "reset", "observation": obs.dict()} |
|
|
| @app.post("/step") |
| def step(action: AgentAction): |
| try: |
| observation = env.step(action) |
| return {"observation": observation.dict()} |
| except Exception as e: |
| raise HTTPException(status_code=400, detail=str(e)) |
|
|
| @app.get("/state") |
| def get_state(): |
| return env.state() |
|
|
| @app.get("/tasks") |
| def get_tasks(): |
| return { |
| "tasks": [ |
| {"id": "1", "name": "Fetch Market Data", "description": "Get current price for AAPL"}, |
| {"id": "2", "name": "News Analysis", "description": "Analyze news and recommend action with explanation"}, |
| {"id": "3", "name": "Backtest Strategy", "description": "Backtest a trading strategy and return risk metrics"} |
| ] |
| } |
|
|
| |
|
|
| @app.get("/metadata") |
| def get_metadata(): |
| """Return environment metadata""" |
| return { |
| "name": "Quant-Gym", |
| "description": "Financial analysis environment for testing AI agents on market data, news sentiment, and trading strategies", |
| "version": "1.0.0" |
| } |
|
|
| @app.get("/schema") |
| def get_schema(): |
| """Return action, observation, and state schemas""" |
| from models import AgentAction, MarketObservation, EnvironmentState |
| |
| return { |
| "action": AgentAction.model_json_schema(), |
| "observation": MarketObservation.model_json_schema(), |
| "state": EnvironmentState.model_json_schema() |
| } |
|
|
| @app.post("/mcp") |
| async def mcp_endpoint(request: Request): |
| """MCP JSON-RPC endpoint""" |
| try: |
| body = await request.json() |
| return { |
| "jsonrpc": "2.0", |
| "id": body.get("id", 1), |
| "result": { |
| "endpoints": ["/health", "/reset", "/step", "/state", "/tasks", "/metadata", "/schema"] |
| } |
| } |
| except: |
| return { |
| "jsonrpc": "2.0", |
| "id": 1, |
| "result": { |
| "message": "MCP endpoint ready" |
| } |
| } |
|
|
| def main(): |
| """Entry point for the application""" |
| uvicorn.run( |
| "server.app:app", |
| host="0.0.0.0", |
| port=7860, |
| reload=False |
| ) |
|
|
| if __name__ == "__main__": |
| main() |
|
|