diegoaquinoh/ai-trading-race

Competitive simulation where AI trading agents (LLMs) race against each other, each controlling a simulated crypto portfolio. Market prices are ingested from CoinGecko, an Azure Durable Functions orchestrator coordinates market cycles and agent decisions with fan-out/fan-in parallelism ; React frontend displays real-time equity curves and leaderboa

C#

1

168 commits

updated Sep 6, 2026

See the code

README

AI Trading Race ๐Ÿ

A competitive simulation where AI trading agents (LLMs) race against each other, each controlling a simulated crypto portfolio. Market prices are ingested from CoinGecko, an Azure Durable Functions orchestrator coordinates market cycles and agent decisions with fan-out/fan-in parallelism, and a React dashboard displays real-time equity curves and leaderboard.

Backend CI Functions CI Frontend CI ML Service CI License: MIT

๐ŸŒ Live Demo

Live demo is currently unavailable, since my Azure free trial unfortunately already ended

โœจ Features

  • Multi-agent competition โ€” Multiple AI agents (GPT, Claude, Llama, custom ML) competing simultaneously
  • Durable orchestration โ€” Azure Durable Functions MarketCycleOrchestrator coordinates the full market cycle with deterministic replays and idempotency
  • Fan-out/fan-in parallelism โ€” All agent decisions run in parallel via Durable Functions activities
  • Real market data โ€” Live OHLC candlestick data from CoinGecko API
  • Portfolio simulation โ€” Realistic portfolio management with positions, trades, and PnL tracking
  • Risk management โ€” Configurable constraints (max position size, min cash reserve, etc.)
  • Custom ML models โ€” Python FastAPI service for custom sklearn/PyTorch models
  • Real-time dashboard โ€” React frontend with equity curves and leaderboard

๐Ÿ“Š Project Status

PhaseDescriptionStatus
Phase 1-4Core architecture, data model, market data, simulation engineโœ… Complete
Phase 5AI agents integration (OpenAI, Anthropic, Groq, Llama)โœ… Complete
Phase 5bCustom ML model (Python + FastAPI)โœ… Complete
Phase 6-7Durable Functions orchestrator & React dashboardโœ… Complete
Phase 8CI/CD & local deployment (Docker Compose)โœ… Complete
Phase 9Cloud deployment (Azure)โœ… Complete
Phase 10Knowledge graph (GraphRAG-lite)โœ… Complete
Phase 10bLangChain + Neo4j refactor๐Ÿ”œ Planned
Phase 11Improve Monitoring & observability๐Ÿ”œ Planned

๐Ÿ—๏ธ Architecture

The system uses an Azure Durable Functions orchestrator (MarketCycleOrchestrator) as the central coordination engine. A timer trigger fires every 5 minutes, and the orchestrator sequences activities with built-in retry, idempotency, and replay safety.

                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚  Timer Trigger (*/5 min)   โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                  โ”‚
                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚   MarketCycleOrchestrator  โ”‚
                    โ”‚    (Durable Functions)     โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                  โ”‚
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚                       โ”‚                       โ”‚
  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  โ”‚ IngestMarket   โ”‚   โ”‚ CaptureSnapshots   โ”‚   โ”‚  GetActive     โ”‚
  โ”‚ DataActivity   โ”‚   โ”‚ Activity           โ”‚   โ”‚  AgentsActivityโ”‚
  โ”‚                โ”‚   โ”‚ (pre & post trade)  โ”‚   โ”‚                โ”‚
  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”‚                                             โ”‚
          โ”‚ prices                           agent IDs  โ”‚
          โ”‚                                             โ”‚
          โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚              โ”‚   Fan-out: RunAgentDecisionActivity  โ”‚
          โ”‚              โ”‚   (one per agent, in parallel)       โ”‚
          โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”‚                                 โ”‚ decisions
          โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚              โ”‚     ExecuteTradesActivity             โ”‚
          โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”‚
          โ””โ”€โ”€โ–บ Decision cycles run every 15 minutes (:00, :15, :30, :45)
               Market data ingestion runs every 5 minutes

Local Services (Docker Compose)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                     Docker Compose Services                     โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  โ€ข SQL Server 2022 (port 1433)                                  โ”‚
โ”‚  โ€ข Redis 7 (port 6379) โ€” Caching & idempotency                  โ”‚
โ”‚  โ€ข ML Service FastAPI (port 8000)                               โ”‚
โ”‚  โ€ข Azurite (ports 10000-10002) โ€” Durable Functions storage      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ASP.NET Core API (port 5001)                                 โ”‚
โ”‚  Azure Functions + Durable Orchestrator (port 7071)           โ”‚
โ”‚  React Dashboard (port 5173)                                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Cloud Services (Azure)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    Azure (francecentral)                        โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  App Service (F1)      โ€” ASP.NET Core API                       โ”‚
โ”‚  Azure SQL (Free tier) โ€” Database                               โ”‚
โ”‚  Container App         โ€” Python ML service (ghcr.io image)      โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                    Azure (westeurope)                           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  Functions (Consumption) โ€” Durable orchestrator                 โ”‚
โ”‚  Static Web App (Free)   โ€” React frontend                       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Project Structure

ai-trading-race/
โ”œโ”€โ”€ AiTradingRace.Web/              # ASP.NET Core Web API
โ”œโ”€โ”€ AiTradingRace.Domain/           # Domain entities
โ”œโ”€โ”€ AiTradingRace.Application/      # Business logic & interfaces
โ”œโ”€โ”€ AiTradingRace.Infrastructure/   # EF Core, external API clients
โ”œโ”€โ”€ AiTradingRace.Functions/        # Azure Functions
โ”‚   โ”œโ”€โ”€ Orchestrators/              #   โ””โ”€ MarketCycleOrchestrator
โ”‚   โ”œโ”€โ”€ Activities/                 #   โ””โ”€ Ingest, Snapshot, Decision, Trade
โ”‚   โ”œโ”€โ”€ Functions/                  #   โ””โ”€ Health check, manual triggers
โ”‚   โ””โ”€โ”€ Models/                     #   โ””โ”€ Orchestration request/result DTOs
โ”œโ”€โ”€ AiTradingRace.Tests/            # Unit & integration tests
โ”œโ”€โ”€ ai-trading-race-web/            # React frontend (Vite + TypeScript)
โ”œโ”€โ”€ ai-trading-race-ml/             # Python ML service (FastAPI + scikit-learn)
โ”œโ”€โ”€ infra/                          # Azure Bicep IaC
โ”œโ”€โ”€ scripts/                        # Database setup, deploy & credential scripts
โ””โ”€โ”€ .github/workflows/              # CI/CD pipelines (7 workflows)

๐Ÿ› ๏ธ Tech Stack

LayerTechnologies
Backend.NET 8, ASP.NET Core, Entity Framework Core
OrchestrationAzure Functions v4 (isolated worker), Durable Functions
DatabaseSQL Server 2022, Redis 7
ML ServicePython 3.11, FastAPI, scikit-learn
FrontendReact 18, TypeScript, Vite, TailwindCSS
InfrastructureDocker Compose (local), Azure Bicep (cloud)
CloudAzure App Service, Functions, Container Apps, Static Web App, Azure SQL
CI/CDGitHub Actions (7 workflows)

๐Ÿ“‹ Prerequisites

  • Docker Desktop โ€” SQL Server, Redis, Azurite, ML Service
  • .NET 8 SDK โ€” Backend API, Functions, and Tests
  • Node.js 20+ โ€” React frontend
  • Python 3.11+ โ€” ML service (optional if using Docker)
  • Azure Functions Core Tools v4 โ€” Local orchestrator
macOS Installation (Apple Silicon)
# .NET 8 SDK
brew install dotnet@8
brew link dotnet@8 --force
export PATH="/opt/homebrew/opt/dotnet@8/bin:$PATH"

# EF Core tools
dotnet tool install --global dotnet-ef
export PATH="$HOME/.dotnet/tools:$PATH"

# Azure Functions Core Tools
brew tap azure/functions
brew install azure-functions-core-tools@4

# Process manager (optional, recommended)
brew install overmind

๐Ÿš€ Quick Start

1. Configure environment

cp .env.example .env
# Edit .env with your API keys and passwords

โš ๏ธ SQL Server password requirements: Min 8 chars, uppercase, lowercase, digit, special char (@#$ โ€” avoid ! on macOS/zsh)

2. Start infrastructure

docker compose up -d

This starts SQL Server, Redis, Azurite (Durable Functions storage), and the ML service.

3. Initialize database

source .env
./scripts/setup-database.sh
./scripts/seed-database.sh

4. Start services

Option A: One command (recommended)

overmind start -f Procfile.dev

Option B: Manual (3 terminals)

# Terminal 1: Backend API
source .env && cd AiTradingRace.Web && dotnet run

# Terminal 2: Azure Functions (orchestrator + activities)
cd AiTradingRace.Functions && func start

# Terminal 3: Frontend
cd ai-trading-race-web && npm install && npm run dev

5. Access the app

6. Trigger a market cycle manually

curl -X POST http://localhost:7071/api/market-cycle/trigger

๐Ÿงช Testing

# Run all tests
dotnet test

# With verbosity
dotnet test --verbosity normal

Test coverage: 166 tests covering market data ingestion, portfolio operations, equity calculations, risk validation, agent decisions, and Azure Functions orchestration.

โ˜๏ธ Cloud Deployment (Azure)

First-time setup

# 1. Copy and fill in all values (API keys, passwords, domain)
cp .env.example .env

# 2. Log in to Azure
az login

# 3. Provision all Azure resources (Bicep IaC)
source .env
./scripts/deploy-infra.sh

# 4. Deploy all application code
./scripts/deploy-app.sh

deploy-infra.sh creates: resource group, App Service, Azure SQL, Azure Functions, Container App, Static Web App. deploy-app.sh builds & pushes the ML Docker image, runs DB migrations, deploys the API + Functions + Container App, and injects Function keys.

CI/CD (GitHub Actions)

On every push to main, the deploy.yml workflow runs automatically. Some deploy steps use publish profiles (automated), others require AZURE_CREDENTIALS service principal which isn't available when Entra ID is org-controlled (manual).

Automated deploys (on push to main):

Workflow JobTargetSecret
deploy-apiApp ServiceAZURE_WEBAPP_PUBLISH_PROFILE
deploy-functionsFunction AppAZURE_FUNCTIONAPP_PUBLISH_PROFILE
deploy-frontendStatic Web AppAZURE_STATIC_WEB_APPS_API_TOKEN

Manual operations (require az login):

TaskCommand
DB Migration./scripts/migrate-azure-db.sh
ML Service Deploy./scripts/deploy-app.sh (or see below)
Post-deploy checkscurl https://ai-trading-race-api.azurewebsites.net/api/health
Manual ML Service Deploy
# Build and push Docker image
docker build -t ghcr.io/diegoaquinoh/ai-trading-race-ml:latest ./ai-trading-race-ml
docker push ghcr.io/diegoaquinoh/ai-trading-race-ml:latest

# Update Container App
az containerapp update \
  --name ai-trading-ml \
  --resource-group ai-trading-rg \
  --image ghcr.io/diegoaquinoh/ai-trading-race-ml:latest
Manual DB Migration
# Option A: Use the existing script
./scripts/migrate-azure-db.sh

# Option B: Direct EF Core update (requires connection string)
dotnet ef database update \
  --project AiTradingRace.Infrastructure \
  --startup-project AiTradingRace.Web

Required GitHub Secrets

SecretHow to get it
AZURE_WEBAPP_PUBLISH_PROFILEAzure Portal โ†’ App Service โ†’ Download publish profile
AZURE_FUNCTIONAPP_PUBLISH_PROFILEAzure Portal โ†’ Function App โ†’ Download publish profile
AZURE_STATIC_WEB_APPS_API_TOKENAuto-created when SWA linked to GitHub

Required tools

brew install azure-cli jq sqlcmd
dotnet tool install --global dotnet-ef

๐Ÿ“š Documentation

DocumentDescription
docs/DEPLOYMENT_PLAN.mdFull Azure deployment plan
scripts/README.mdDatabase & deployment scripts guide
.github/SUMMARY.mdCI/CD pipeline summary
.github/WORKFLOWS.mdWorkflow documentation

๐Ÿ”’ Security

  • Environment variables via .env (excluded from git)
  • API keys in local.settings.json (not versioned)
  • JWT authentication with API key fallback
  • Rate limiting (global, per-user, auth-endpoint)
  • Service-to-service auth with X-API-Key headers
  • Production: Azure Key Vault for managed secrets

๐Ÿ“„ License

This project is licensed under the MIT License โ€” see LICENSE for details.

๐Ÿค Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

diegoaquinoh/ai-trading-race

Competitive simulation where AI trading agents (LLMs) race against each other, each controlling a simulated crypto portfolio. Market prices are ingested from CoinGecko, an Azure Durable Functions orchestrator coordinates market cycles and agent decisions with fan-out/fan-in parallelism ; React frontend displays real-time equity curves and leaderboa

C#

1

168 commits

updated Sep 6, 2026

See the code

README

AI Trading Race ๐Ÿ

A competitive simulation where AI trading agents (LLMs) race against each other, each controlling a simulated crypto portfolio. Market prices are ingested from CoinGecko, an Azure Durable Functions orchestrator coordinates market cycles and agent decisions with fan-out/fan-in parallelism, and a React dashboard displays real-time equity curves and leaderboard.

Backend CI Functions CI Frontend CI ML Service CI License: MIT

๐ŸŒ Live Demo

Live demo is currently unavailable, since my Azure free trial unfortunately already ended

โœจ Features

  • Multi-agent competition โ€” Multiple AI agents (GPT, Claude, Llama, custom ML) competing simultaneously
  • Durable orchestration โ€” Azure Durable Functions MarketCycleOrchestrator coordinates the full market cycle with deterministic replays and idempotency
  • Fan-out/fan-in parallelism โ€” All agent decisions run in parallel via Durable Functions activities
  • Real market data โ€” Live OHLC candlestick data from CoinGecko API
  • Portfolio simulation โ€” Realistic portfolio management with positions, trades, and PnL tracking
  • Risk management โ€” Configurable constraints (max position size, min cash reserve, etc.)
  • Custom ML models โ€” Python FastAPI service for custom sklearn/PyTorch models
  • Real-time dashboard โ€” React frontend with equity curves and leaderboard

๐Ÿ“Š Project Status

PhaseDescriptionStatus
Phase 1-4Core architecture, data model, market data, simulation engineโœ… Complete
Phase 5AI agents integration (OpenAI, Anthropic, Groq, Llama)โœ… Complete
Phase 5bCustom ML model (Python + FastAPI)โœ… Complete
Phase 6-7Durable Functions orchestrator & React dashboardโœ… Complete
Phase 8CI/CD & local deployment (Docker Compose)โœ… Complete
Phase 9Cloud deployment (Azure)โœ… Complete
Phase 10Knowledge graph (GraphRAG-lite)โœ… Complete
Phase 10bLangChain + Neo4j refactor๐Ÿ”œ Planned
Phase 11Improve Monitoring & observability๐Ÿ”œ Planned

๐Ÿ—๏ธ Architecture

The system uses an Azure Durable Functions orchestrator (MarketCycleOrchestrator) as the central coordination engine. A timer trigger fires every 5 minutes, and the orchestrator sequences activities with built-in retry, idempotency, and replay safety.

                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚  Timer Trigger (*/5 min)   โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                  โ”‚
                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚   MarketCycleOrchestrator  โ”‚
                    โ”‚    (Durable Functions)     โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                  โ”‚
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚                       โ”‚                       โ”‚
  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  โ”‚ IngestMarket   โ”‚   โ”‚ CaptureSnapshots   โ”‚   โ”‚  GetActive     โ”‚
  โ”‚ DataActivity   โ”‚   โ”‚ Activity           โ”‚   โ”‚  AgentsActivityโ”‚
  โ”‚                โ”‚   โ”‚ (pre & post trade)  โ”‚   โ”‚                โ”‚
  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”‚                                             โ”‚
          โ”‚ prices                           agent IDs  โ”‚
          โ”‚                                             โ”‚
          โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚              โ”‚   Fan-out: RunAgentDecisionActivity  โ”‚
          โ”‚              โ”‚   (one per agent, in parallel)       โ”‚
          โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”‚                                 โ”‚ decisions
          โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚              โ”‚     ExecuteTradesActivity             โ”‚
          โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”‚
          โ””โ”€โ”€โ–บ Decision cycles run every 15 minutes (:00, :15, :30, :45)
               Market data ingestion runs every 5 minutes

Local Services (Docker Compose)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                     Docker Compose Services                     โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  โ€ข SQL Server 2022 (port 1433)                                  โ”‚
โ”‚  โ€ข Redis 7 (port 6379) โ€” Caching & idempotency                  โ”‚
โ”‚  โ€ข ML Service FastAPI (port 8000)                               โ”‚
โ”‚  โ€ข Azurite (ports 10000-10002) โ€” Durable Functions storage      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ASP.NET Core API (port 5001)                                 โ”‚
โ”‚  Azure Functions + Durable Orchestrator (port 7071)           โ”‚
โ”‚  React Dashboard (port 5173)                                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Cloud Services (Azure)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    Azure (francecentral)                        โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  App Service (F1)      โ€” ASP.NET Core API                       โ”‚
โ”‚  Azure SQL (Free tier) โ€” Database                               โ”‚
โ”‚  Container App         โ€” Python ML service (ghcr.io image)      โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                    Azure (westeurope)                           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  Functions (Consumption) โ€” Durable orchestrator                 โ”‚
โ”‚  Static Web App (Free)   โ€” React frontend                       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Project Structure

ai-trading-race/
โ”œโ”€โ”€ AiTradingRace.Web/              # ASP.NET Core Web API
โ”œโ”€โ”€ AiTradingRace.Domain/           # Domain entities
โ”œโ”€โ”€ AiTradingRace.Application/      # Business logic & interfaces
โ”œโ”€โ”€ AiTradingRace.Infrastructure/   # EF Core, external API clients
โ”œโ”€โ”€ AiTradingRace.Functions/        # Azure Functions
โ”‚   โ”œโ”€โ”€ Orchestrators/              #   โ””โ”€ MarketCycleOrchestrator
โ”‚   โ”œโ”€โ”€ Activities/                 #   โ””โ”€ Ingest, Snapshot, Decision, Trade
โ”‚   โ”œโ”€โ”€ Functions/                  #   โ””โ”€ Health check, manual triggers
โ”‚   โ””โ”€โ”€ Models/                     #   โ””โ”€ Orchestration request/result DTOs
โ”œโ”€โ”€ AiTradingRace.Tests/            # Unit & integration tests
โ”œโ”€โ”€ ai-trading-race-web/            # React frontend (Vite + TypeScript)
โ”œโ”€โ”€ ai-trading-race-ml/             # Python ML service (FastAPI + scikit-learn)
โ”œโ”€โ”€ infra/                          # Azure Bicep IaC
โ”œโ”€โ”€ scripts/                        # Database setup, deploy & credential scripts
โ””โ”€โ”€ .github/workflows/              # CI/CD pipelines (7 workflows)

๐Ÿ› ๏ธ Tech Stack

LayerTechnologies
Backend.NET 8, ASP.NET Core, Entity Framework Core
OrchestrationAzure Functions v4 (isolated worker), Durable Functions
DatabaseSQL Server 2022, Redis 7
ML ServicePython 3.11, FastAPI, scikit-learn
FrontendReact 18, TypeScript, Vite, TailwindCSS
InfrastructureDocker Compose (local), Azure Bicep (cloud)
CloudAzure App Service, Functions, Container Apps, Static Web App, Azure SQL
CI/CDGitHub Actions (7 workflows)

๐Ÿ“‹ Prerequisites

  • Docker Desktop โ€” SQL Server, Redis, Azurite, ML Service
  • .NET 8 SDK โ€” Backend API, Functions, and Tests
  • Node.js 20+ โ€” React frontend
  • Python 3.11+ โ€” ML service (optional if using Docker)
  • Azure Functions Core Tools v4 โ€” Local orchestrator
macOS Installation (Apple Silicon)
# .NET 8 SDK
brew install dotnet@8
brew link dotnet@8 --force
export PATH="/opt/homebrew/opt/dotnet@8/bin:$PATH"

# EF Core tools
dotnet tool install --global dotnet-ef
export PATH="$HOME/.dotnet/tools:$PATH"

# Azure Functions Core Tools
brew tap azure/functions
brew install azure-functions-core-tools@4

# Process manager (optional, recommended)
brew install overmind

๐Ÿš€ Quick Start

1. Configure environment

cp .env.example .env
# Edit .env with your API keys and passwords

โš ๏ธ SQL Server password requirements: Min 8 chars, uppercase, lowercase, digit, special char (@#$ โ€” avoid ! on macOS/zsh)

2. Start infrastructure

docker compose up -d

This starts SQL Server, Redis, Azurite (Durable Functions storage), and the ML service.

3. Initialize database

source .env
./scripts/setup-database.sh
./scripts/seed-database.sh

4. Start services

Option A: One command (recommended)

overmind start -f Procfile.dev

Option B: Manual (3 terminals)

# Terminal 1: Backend API
source .env && cd AiTradingRace.Web && dotnet run

# Terminal 2: Azure Functions (orchestrator + activities)
cd AiTradingRace.Functions && func start

# Terminal 3: Frontend
cd ai-trading-race-web && npm install && npm run dev

5. Access the app

6. Trigger a market cycle manually

curl -X POST http://localhost:7071/api/market-cycle/trigger

๐Ÿงช Testing

# Run all tests
dotnet test

# With verbosity
dotnet test --verbosity normal

Test coverage: 166 tests covering market data ingestion, portfolio operations, equity calculations, risk validation, agent decisions, and Azure Functions orchestration.

โ˜๏ธ Cloud Deployment (Azure)

First-time setup

# 1. Copy and fill in all values (API keys, passwords, domain)
cp .env.example .env

# 2. Log in to Azure
az login

# 3. Provision all Azure resources (Bicep IaC)
source .env
./scripts/deploy-infra.sh

# 4. Deploy all application code
./scripts/deploy-app.sh

deploy-infra.sh creates: resource group, App Service, Azure SQL, Azure Functions, Container App, Static Web App. deploy-app.sh builds & pushes the ML Docker image, runs DB migrations, deploys the API + Functions + Container App, and injects Function keys.

CI/CD (GitHub Actions)

On every push to main, the deploy.yml workflow runs automatically. Some deploy steps use publish profiles (automated), others require AZURE_CREDENTIALS service principal which isn't available when Entra ID is org-controlled (manual).

Automated deploys (on push to main):

Workflow JobTargetSecret
deploy-apiApp ServiceAZURE_WEBAPP_PUBLISH_PROFILE
deploy-functionsFunction AppAZURE_FUNCTIONAPP_PUBLISH_PROFILE
deploy-frontendStatic Web AppAZURE_STATIC_WEB_APPS_API_TOKEN

Manual operations (require az login):

TaskCommand
DB Migration./scripts/migrate-azure-db.sh
ML Service Deploy./scripts/deploy-app.sh (or see below)
Post-deploy checkscurl https://ai-trading-race-api.azurewebsites.net/api/health
Manual ML Service Deploy
# Build and push Docker image
docker build -t ghcr.io/diegoaquinoh/ai-trading-race-ml:latest ./ai-trading-race-ml
docker push ghcr.io/diegoaquinoh/ai-trading-race-ml:latest

# Update Container App
az containerapp update \
  --name ai-trading-ml \
  --resource-group ai-trading-rg \
  --image ghcr.io/diegoaquinoh/ai-trading-race-ml:latest
Manual DB Migration
# Option A: Use the existing script
./scripts/migrate-azure-db.sh

# Option B: Direct EF Core update (requires connection string)
dotnet ef database update \
  --project AiTradingRace.Infrastructure \
  --startup-project AiTradingRace.Web

Required GitHub Secrets

SecretHow to get it
AZURE_WEBAPP_PUBLISH_PROFILEAzure Portal โ†’ App Service โ†’ Download publish profile
AZURE_FUNCTIONAPP_PUBLISH_PROFILEAzure Portal โ†’ Function App โ†’ Download publish profile
AZURE_STATIC_WEB_APPS_API_TOKENAuto-created when SWA linked to GitHub

Required tools

brew install azure-cli jq sqlcmd
dotnet tool install --global dotnet-ef

๐Ÿ“š Documentation

DocumentDescription
docs/DEPLOYMENT_PLAN.mdFull Azure deployment plan
scripts/README.mdDatabase & deployment scripts guide
.github/SUMMARY.mdCI/CD pipeline summary
.github/WORKFLOWS.mdWorkflow documentation

๐Ÿ”’ Security

  • Environment variables via .env (excluded from git)
  • API keys in local.settings.json (not versioned)
  • JWT authentication with API key fallback
  • Rate limiting (global, per-user, auth-endpoint)
  • Service-to-service auth with X-API-Key headers
  • Production: Azure Key Vault for managed secrets

๐Ÿ“„ License

This project is licensed under the MIT License โ€” see LICENSE for details.

๐Ÿค Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Languages

C#

66.8%

TypeScript

11.1%

Shell

7.2%

CSS

6.7%

Python

5.8%

Bicep

1.4%