update all files
Browse files- =0.2.0 +19 -0
- README.md +1 -0
- graders/__init__.py +1 -0
- graders/task2_grader.py +6 -5
- graders/task3_grader.py +7 -3
- openenv.yaml +16 -12
- pyproject.toml +35 -0
- requirements.txt +1 -1
- server/app.py +13 -0
- uv.lock +0 -0
=0.2.0
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Requirement already satisfied: openenv-core in /home/codespace/micromamba/lib/python3.9/site-packages (0.1.0)
|
| 2 |
+
Requirement already satisfied: requests>=2.25.0 in /home/codespace/micromamba/lib/python3.9/site-packages (from openenv-core) (2.32.5)
|
| 3 |
+
Requirement already satisfied: fastapi>=0.104.0 in /home/codespace/micromamba/lib/python3.9/site-packages (from openenv-core) (0.116.1)
|
| 4 |
+
Requirement already satisfied: uvicorn>=0.24.0 in /home/codespace/micromamba/lib/python3.9/site-packages (from openenv-core) (0.35.0)
|
| 5 |
+
Requirement already satisfied: starlette<0.48.0,>=0.40.0 in /home/codespace/micromamba/lib/python3.9/site-packages (from fastapi>=0.104.0->openenv-core) (0.47.2)
|
| 6 |
+
Requirement already satisfied: pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0,>=1.7.4 in /home/codespace/micromamba/lib/python3.9/site-packages (from fastapi>=0.104.0->openenv-core) (2.11.7)
|
| 7 |
+
Requirement already satisfied: typing-extensions>=4.8.0 in /home/codespace/micromamba/lib/python3.9/site-packages (from fastapi>=0.104.0->openenv-core) (4.14.1)
|
| 8 |
+
Requirement already satisfied: annotated-types>=0.6.0 in /home/codespace/micromamba/lib/python3.9/site-packages (from pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0,>=1.7.4->fastapi>=0.104.0->openenv-core) (0.7.0)
|
| 9 |
+
Requirement already satisfied: pydantic-core==2.33.2 in /home/codespace/micromamba/lib/python3.9/site-packages (from pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0,>=1.7.4->fastapi>=0.104.0->openenv-core) (2.33.2)
|
| 10 |
+
Requirement already satisfied: typing-inspection>=0.4.0 in /home/codespace/micromamba/lib/python3.9/site-packages (from pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0,>=1.7.4->fastapi>=0.104.0->openenv-core) (0.4.1)
|
| 11 |
+
Requirement already satisfied: anyio<5,>=3.6.2 in /home/codespace/micromamba/lib/python3.9/site-packages (from starlette<0.48.0,>=0.40.0->fastapi>=0.104.0->openenv-core) (4.10.0)
|
| 12 |
+
Requirement already satisfied: exceptiongroup>=1.0.2 in /home/codespace/micromamba/lib/python3.9/site-packages (from anyio<5,>=3.6.2->starlette<0.48.0,>=0.40.0->fastapi>=0.104.0->openenv-core) (1.3.0)
|
| 13 |
+
Requirement already satisfied: idna>=2.8 in /home/codespace/micromamba/lib/python3.9/site-packages (from anyio<5,>=3.6.2->starlette<0.48.0,>=0.40.0->fastapi>=0.104.0->openenv-core) (3.10)
|
| 14 |
+
Requirement already satisfied: sniffio>=1.1 in /home/codespace/micromamba/lib/python3.9/site-packages (from anyio<5,>=3.6.2->starlette<0.48.0,>=0.40.0->fastapi>=0.104.0->openenv-core) (1.3.1)
|
| 15 |
+
Requirement already satisfied: charset_normalizer<4,>=2 in /home/codespace/micromamba/lib/python3.9/site-packages (from requests>=2.25.0->openenv-core) (3.4.3)
|
| 16 |
+
Requirement already satisfied: urllib3<3,>=1.21.1 in /home/codespace/micromamba/lib/python3.9/site-packages (from requests>=2.25.0->openenv-core) (2.5.0)
|
| 17 |
+
Requirement already satisfied: certifi>=2017.4.17 in /home/codespace/micromamba/lib/python3.9/site-packages (from requests>=2.25.0->openenv-core) (2025.8.3)
|
| 18 |
+
Requirement already satisfied: click>=7.0 in /home/codespace/micromamba/lib/python3.9/site-packages (from uvicorn>=0.24.0->openenv-core) (8.1.8)
|
| 19 |
+
Requirement already satisfied: h11>=0.8 in /home/codespace/micromamba/lib/python3.9/site-packages (from uvicorn>=0.24.0->openenv-core) (0.16.0)
|
README.md
CHANGED
|
@@ -140,6 +140,7 @@ quant-gym-openenv/
|
|
| 140 |
├── inference.py # Baseline agent script
|
| 141 |
├── models.py # Pydantic schemas
|
| 142 |
├── openenv.yaml # OpenEnv configuration
|
|
|
|
| 143 |
├── requirements.txt # Python dependencies
|
| 144 |
├── README.md # This file
|
| 145 |
├── server/
|
|
|
|
| 140 |
├── inference.py # Baseline agent script
|
| 141 |
├── models.py # Pydantic schemas
|
| 142 |
├── openenv.yaml # OpenEnv configuration
|
| 143 |
+
├── pyproject.toml
|
| 144 |
├── requirements.txt # Python dependencies
|
| 145 |
├── README.md # This file
|
| 146 |
├── server/
|
graders/__init__.py
CHANGED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
# Graders package
|
graders/task2_grader.py
CHANGED
|
@@ -1,13 +1,14 @@
|
|
| 1 |
def grade_task2(agent_action, observation):
|
| 2 |
-
"""Task 2: News
|
| 3 |
score = 0.0
|
| 4 |
|
| 5 |
-
# Check if agent gave explanation
|
| 6 |
-
if agent_action.explanation and len(agent_action.explanation) > 10:
|
| 7 |
score += 0.5
|
| 8 |
|
| 9 |
-
# Check if
|
| 10 |
-
|
|
|
|
| 11 |
score += 0.5
|
| 12 |
|
| 13 |
return score
|
|
|
|
| 1 |
def grade_task2(agent_action, observation):
|
| 2 |
+
"""Grade Task 2: News Sentiment Analysis"""
|
| 3 |
score = 0.0
|
| 4 |
|
| 5 |
+
# Check if agent gave an explanation
|
| 6 |
+
if agent_action.get("explanation") and len(agent_action.get("explanation", "")) > 10:
|
| 7 |
score += 0.5
|
| 8 |
|
| 9 |
+
# Check if action is valid (BUY/SELL/HOLD recommendation)
|
| 10 |
+
action_type = agent_action.get("type", "")
|
| 11 |
+
if action_type in ["BUY", "SELL", "GET_NEWS"]:
|
| 12 |
score += 0.5
|
| 13 |
|
| 14 |
return score
|
graders/task3_grader.py
CHANGED
|
@@ -1,11 +1,15 @@
|
|
| 1 |
-
def grade_task3(
|
| 2 |
-
"""Task 3: Backtest Strategy"""
|
| 3 |
score = 0.0
|
| 4 |
|
|
|
|
|
|
|
| 5 |
if backtest_results:
|
|
|
|
| 6 |
if backtest_results.get("sharpe_ratio", 0) > 0:
|
| 7 |
score += 0.5
|
| 8 |
-
|
|
|
|
| 9 |
score += 0.5
|
| 10 |
|
| 11 |
return score
|
|
|
|
| 1 |
+
def grade_task3(agent_action, observation):
|
| 2 |
+
"""Grade Task 3: Backtest Strategy"""
|
| 3 |
score = 0.0
|
| 4 |
|
| 5 |
+
# Check if backtest results exist
|
| 6 |
+
backtest_results = observation.get("backtest_results")
|
| 7 |
if backtest_results:
|
| 8 |
+
# Check for Sharpe ratio
|
| 9 |
if backtest_results.get("sharpe_ratio", 0) > 0:
|
| 10 |
score += 0.5
|
| 11 |
+
# Check for max drawdown
|
| 12 |
+
if backtest_results.get("max_drawdown", 1) < 1:
|
| 13 |
score += 0.5
|
| 14 |
|
| 15 |
return score
|
openenv.yaml
CHANGED
|
@@ -1,26 +1,29 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
f.write('''name: "Quant-Gym"
|
| 4 |
-
description: "Benchmark environment for testing AI agents on financial data analysis and reasoning"
|
| 5 |
version: "1.0.0"
|
| 6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
tasks:
|
| 8 |
- id: "task1"
|
| 9 |
name: "Fetch Market Data"
|
| 10 |
description: "Agent must retrieve current price for AAPL"
|
| 11 |
-
|
| 12 |
max_score: 1.0
|
| 13 |
|
| 14 |
- id: "task2"
|
| 15 |
name: "News Sentiment Analysis"
|
| 16 |
-
description: "Agent must analyze news and recommend
|
| 17 |
-
|
| 18 |
max_score: 1.0
|
| 19 |
|
| 20 |
- id: "task3"
|
| 21 |
name: "Backtest Strategy"
|
| 22 |
-
description: "Agent must backtest a strategy and return risk metrics"
|
| 23 |
-
|
| 24 |
max_score: 1.0
|
| 25 |
|
| 26 |
action_schema:
|
|
@@ -31,12 +34,16 @@ action_schema:
|
|
| 31 |
enum: ["GET_PRICE", "GET_NEWS", "BUY", "SELL", "BACKTEST"]
|
| 32 |
symbol:
|
| 33 |
type: "string"
|
|
|
|
| 34 |
amount:
|
| 35 |
type: "integer"
|
|
|
|
| 36 |
explanation:
|
| 37 |
type: "string"
|
| 38 |
strategy:
|
| 39 |
type: "string"
|
|
|
|
|
|
|
| 40 |
|
| 41 |
observation_schema:
|
| 42 |
type: "object"
|
|
@@ -55,6 +62,3 @@ observation_schema:
|
|
| 55 |
type: "object"
|
| 56 |
backtest_results:
|
| 57 |
type: "object"
|
| 58 |
-
''')
|
| 59 |
-
print("openenv.yaml created")
|
| 60 |
-
PYTHON_EOF
|
|
|
|
| 1 |
+
name: "Quant-Gym"
|
| 2 |
+
description: "Financial analysis environment for testing AI agents on market data, news sentiment, and trading strategies"
|
|
|
|
|
|
|
| 3 |
version: "1.0.0"
|
| 4 |
|
| 5 |
+
environment:
|
| 6 |
+
name: "QuantGym"
|
| 7 |
+
class: "TradingEnvironment"
|
| 8 |
+
module: "server.environment"
|
| 9 |
+
|
| 10 |
tasks:
|
| 11 |
- id: "task1"
|
| 12 |
name: "Fetch Market Data"
|
| 13 |
description: "Agent must retrieve current price for AAPL"
|
| 14 |
+
grader: "graders.task1_grader.grade_task1"
|
| 15 |
max_score: 1.0
|
| 16 |
|
| 17 |
- id: "task2"
|
| 18 |
name: "News Sentiment Analysis"
|
| 19 |
+
description: "Agent must analyze news and recommend Buy/Sell/Hold with explanation"
|
| 20 |
+
grader: "graders.task2_grader.grade_task2"
|
| 21 |
max_score: 1.0
|
| 22 |
|
| 23 |
- id: "task3"
|
| 24 |
name: "Backtest Strategy"
|
| 25 |
+
description: "Agent must backtest a trading strategy and return risk metrics"
|
| 26 |
+
grader: "graders.task3_grader.grade_task3"
|
| 27 |
max_score: 1.0
|
| 28 |
|
| 29 |
action_schema:
|
|
|
|
| 34 |
enum: ["GET_PRICE", "GET_NEWS", "BUY", "SELL", "BACKTEST"]
|
| 35 |
symbol:
|
| 36 |
type: "string"
|
| 37 |
+
default: "AAPL"
|
| 38 |
amount:
|
| 39 |
type: "integer"
|
| 40 |
+
minimum: 0
|
| 41 |
explanation:
|
| 42 |
type: "string"
|
| 43 |
strategy:
|
| 44 |
type: "string"
|
| 45 |
+
required:
|
| 46 |
+
- "type"
|
| 47 |
|
| 48 |
observation_schema:
|
| 49 |
type: "object"
|
|
|
|
| 62 |
type: "object"
|
| 63 |
backtest_results:
|
| 64 |
type: "object"
|
|
|
|
|
|
|
|
|
pyproject.toml
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[build-system]
|
| 2 |
+
requires = ["setuptools>=45", "wheel"]
|
| 3 |
+
build-backend = "setuptools.build_meta"
|
| 4 |
+
|
| 5 |
+
[project]
|
| 6 |
+
name = "quant-gym-openenv"
|
| 7 |
+
version = "0.1.0"
|
| 8 |
+
description = "Financial analysis environment for AI agents"
|
| 9 |
+
requires-python = ">=3.10"
|
| 10 |
+
dependencies = [
|
| 11 |
+
"openenv-core[core]>=0.2.2",
|
| 12 |
+
"fastapi>=0.104.0",
|
| 13 |
+
"uvicorn>=0.24.0",
|
| 14 |
+
"pydantic>=2.0.0",
|
| 15 |
+
"yfinance>=0.2.0",
|
| 16 |
+
"pandas>=2.0.0",
|
| 17 |
+
"openai>=1.0.0",
|
| 18 |
+
"requests>=2.31.0",
|
| 19 |
+
"python-dotenv>=1.0.0",
|
| 20 |
+
"numpy>=1.24.0",
|
| 21 |
+
]
|
| 22 |
+
|
| 23 |
+
[project.optional-dependencies]
|
| 24 |
+
dev = [
|
| 25 |
+
"pytest>=8.0.0",
|
| 26 |
+
"pytest-cov>=4.0.0",
|
| 27 |
+
]
|
| 28 |
+
|
| 29 |
+
[project.scripts]
|
| 30 |
+
server = "server.app:main"
|
| 31 |
+
|
| 32 |
+
[tool.setuptools]
|
| 33 |
+
include-package-data = true
|
| 34 |
+
packages = ["server", "graders"]
|
| 35 |
+
package-dir = { "server" = "server", "graders" = "graders" }
|
requirements.txt
CHANGED
|
@@ -7,4 +7,4 @@ pandas>=2.0.0
|
|
| 7 |
openai>=1.0.0
|
| 8 |
requests>=2.31.0
|
| 9 |
python-dotenv>=1.0.0
|
| 10 |
-
numpy>=1.24.0
|
|
|
|
| 7 |
openai>=1.0.0
|
| 8 |
requests>=2.31.0
|
| 9 |
python-dotenv>=1.0.0
|
| 10 |
+
numpy>=1.24.0
|
server/app.py
CHANGED
|
@@ -6,6 +6,7 @@ from fastapi import FastAPI, HTTPException
|
|
| 6 |
from fastapi.middleware.cors import CORSMiddleware
|
| 7 |
from models import AgentAction
|
| 8 |
from server.environment import TradingEnvironment
|
|
|
|
| 9 |
|
| 10 |
app = FastAPI(title="Quant-Gym", description="Financial Analysis Environment")
|
| 11 |
|
|
@@ -53,3 +54,15 @@ def get_tasks():
|
|
| 53 |
{"id": "3", "name": "Backtest Strategy", "description": "Backtest a trading strategy and return risk metrics"}
|
| 54 |
]
|
| 55 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
from fastapi.middleware.cors import CORSMiddleware
|
| 7 |
from models import AgentAction
|
| 8 |
from server.environment import TradingEnvironment
|
| 9 |
+
import uvicorn
|
| 10 |
|
| 11 |
app = FastAPI(title="Quant-Gym", description="Financial Analysis Environment")
|
| 12 |
|
|
|
|
| 54 |
{"id": "3", "name": "Backtest Strategy", "description": "Backtest a trading strategy and return risk metrics"}
|
| 55 |
]
|
| 56 |
}
|
| 57 |
+
|
| 58 |
+
def main():
|
| 59 |
+
"""Entry point for the application"""
|
| 60 |
+
uvicorn.run(
|
| 61 |
+
"server.app:app",
|
| 62 |
+
host="0.0.0.0",
|
| 63 |
+
port=7860,
|
| 64 |
+
reload=False
|
| 65 |
+
)
|
| 66 |
+
|
| 67 |
+
if __name__ == "__main__":
|
| 68 |
+
main()
|
uv.lock
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|