A Demo Order Execution Engine API with JWT Authentication. This is a simplified stock trading simulator where users can execute buy/sell orders with virtual money.
- JWT Authentication - Secure user registration and login
- Multi-user Support - Each user manages their own accounts
- Authorization - Users can only access their own accounts, orders, positions, and trades
- Create and manage trading accounts
- Buy and sell stocks at current market prices
- Track positions and portfolio value
- View trade history and performance
- Real-time P&L calculations
- RESTful API with automatic OpenAPI documentation
- Language: Python 3.11+
- Framework: FastAPI
- Database: PostgreSQL 15
- ORM: SQLAlchemy 2.x with Alembic migrations
- Validation: Pydantic v2
- Deployment: Docker & Docker Compose
- Docker and Docker Compose installed
- Git (to clone the repository)
-
Clone the repository (or navigate to the project directory)
-
Start the services:
docker-compose up --build
This will:
- Start PostgreSQL database
- Run database migrations
- Start the FastAPI application
- API will be available at
http://localhost:8000
-
Seed the database (optional, for test data):
docker-compose exec api python -m app.seed -
Access the API documentation:
- Swagger UI:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc - Health Check:
http://localhost:8000/health
- Swagger UI:
- Swagger UI:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc
- OpenAPI YAML:
openapi.yaml- Complete OpenAPI 3.1 spec in YAML format - OpenAPI JSON:
openapi.json- Complete OpenAPI 3.1 spec in JSON format - Postman Collection:
postman_collection.json- Ready-to-import Postman collection with examples
The API uses JWT (JSON Web Token) authentication. Most endpoints require authentication.
-
Register a new user:
curl -X POST "http://localhost:8000/api/v1/auth/register" \ -H "Content-Type: application/json" \ -d '{ "email": "user@example.com", "username": "myuser", "password": "mypassword", "full_name": "My Name" }'
-
Login to get an access token:
curl -X POST "http://localhost:8000/api/v1/auth/login" \ -H "Content-Type: application/json" \ -d '{ "username": "myuser", "password": "mypassword" }'
-
Save the access token from the response:
{ "access_token": "eyJhbGc...", "token_type": "bearer" } -
Use the token in subsequent requests:
curl -X GET "http://localhost:8000/api/v1/accounts" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
POST /auth/register- Register a new userPOST /auth/login- Login with JSON bodyGET /auth/me- Get current user info (requires auth)
Public (No authentication required):
- All
/stocksendpoints - Stock prices are public information - All
/authendpoints (except/auth/me) - Registration and login
Protected (Authentication required):
- All
/accountsendpoints - Users can only access their own accounts - All
/ordersendpoints - Users can only create/view orders for their accounts - All
/positionsendpoints - Users can only view their own positions - All
/tradesendpoints - Users can only view their own trades
Base URL: http://localhost:8000/api/v1
POST /auth/register- Register new userPOST /auth/login- Login with JSON bodyGET /auth/me- Get current user info
-
GET /accounts- List all your accounts -
POST /accounts- Create a new trading account -
GET /accounts/{account_id}- Get account details -
POST /accounts/{account_id}/deposit- Deposit cash -
POST /accounts/{account_id}/withdraw- Withdraw cash -
GET /accounts/{account_id}/performance- Get account performance summary
POST /orders- Create and execute an orderGET /orders- List all orders (with filters)GET /orders/{order_id}- Get specific order details
GET /positions- List all positionsGET /positions/{account_id}- Get positions for specific account
GET /trades- List all trades (with filters)GET /trades/{account_id}- Get trades for specific account
GET /stocks- List all available stocksGET /stocks/{symbol}- Get current price for symbolPUT /stocks/{symbol}- Update stock price (for testing)
curl -X POST "http://localhost:8000/api/v1/accounts" \
-H "Content-Type: application/json" \
-d '{
"account_number": "ACC001",
"holder_name": "John Doe",
"initial_cash": 10000.00
}'curl -X POST "http://localhost:8000/api/v1/orders" \
-H "Content-Type: application/json" \
-d '{
"account_id": 1,
"symbol": "AAPL",
"order_type": "BUY",
"quantity": 10
}'curl -X GET "http://localhost:8000/api/v1/positions/1"curl -X POST "http://localhost:8000/api/v1/orders" \
-H "Content-Type: application/json" \
-d '{
"account_id": 1,
"symbol": "AAPL",
"order_type": "SELL",
"quantity": 5
}'curl -X GET "http://localhost:8000/api/v1/accounts/1/performance"curl -X PUT "http://localhost:8000/api/v1/stocks/AAPL" \
-H "Content-Type: application/json" \
-d '{
"current_price": 155.50
}'- Account must exist and be ACTIVE
- Symbol must exist in stock_prices
- Account must have sufficient cash balance
- Order executes immediately at current market price
- Account must exist and be ACTIVE
- Account must have a position in the symbol
- Position must have sufficient quantity
- Order executes immediately at current market price
- Positions are created when buying stocks
- Average cost is calculated when buying more of the same stock
- Positions are deleted when quantity reaches 0
- Unrealized P&L is calculated as:
(current_price - average_cost) * quantity
- Total Value = Cash Balance + Sum of Position Values
- Recalculated after every order execution
- Updated when stock prices change
Complete Postman collections are included with all API endpoints and example requests.
postman_collection_with_auth.json(RECOMMENDED) - Full collection with JWT authenticationpostman_collection.json- Legacy collection (pre-authentication)
-
Import Collection:
- Open Postman
- Click "Import" button
- Select
postman_collection_with_auth.json(recommended) - Click "Import"
-
Import Environment:
- Click "Import" button
- Select
postman_environment.json - Click "Import"
- Select "OMS Demo API - Local (With Auth)" from the environment dropdown
- JWT Authentication - Login requests automatically save tokens
- Bearer Token Auth - Automatically applied to protected endpoints
- 70+ Requests organized by resource type
- Auto-saved Variables: access_token, account_id automatically saved
- Complete Workflow: Step-by-step authentication and trading workflow
- Error Cases: Examples of validation failures and authorization errors
- Query Parameters: Filtering and pagination examples
- Authentication - Register, login, get current user
- Stocks (Public) - List, get price, update price (no auth required)
- Accounts (Protected) - Create, list, get, deposit, withdraw, performance
- Orders (Protected) - Create buy/sell orders, list with filters
- Positions (Protected) - View positions and portfolio
- Trades (Protected) - Trade history and audit log
- Complete Workflow (With Auth) - 7-step end-to-end authenticated trading scenario
- Import
postman_collection.json - Run the "Complete Workflow" folder in order:
- Register a new user
- Login to get JWT token (automatically saved)
- Create trading account
- Buy/sell stocks with auto-authentication
- View performance and P&L
- All protected endpoints automatically use the saved token
- accounts - Trading accounts with cash balance
- positions - Stock holdings per account
- orders - Buy/sell orders with status
- trades - Immutable execution records
- stock_prices - Current market prices
The database comes pre-seeded with these stocks:
- AAPL: $150.00
- GOOGL: $140.00
- MSFT: $380.00
- TSLA: $200.00
- AMZN: $170.00
-
Install dependencies:
pip install -r requirements.txt
-
Set up PostgreSQL and create database
-
Configure environment:
cp .env.example .env # Edit .env with your database URL -
Run migrations:
alembic upgrade head
-
Seed database:
python -m app.seed
-
Start server:
uvicorn app.main:app --reload
# Run migrations
docker-compose exec api alembic upgrade head
# Seed test data
docker-compose exec api python -m app.seed
# View logs
docker-compose logs -f apioms-demo-api/
├── app/
│ ├── models/ # SQLAlchemy models
│ ├── schemas/ # Pydantic schemas
│ ├── services/ # Business logic
│ ├── routers/ # API endpoints
│ ├── utils/ # Helper functions
│ ├── config.py # Configuration
│ ├── database.py # Database setup
│ ├── main.py # FastAPI app
│ └── seed.py # Seed script
├── alembic/ # Database migrations
├── docker-compose.yml # Docker setup
├── Dockerfile # Container image
├── requirements.txt # Python dependencies
└── README.md # This file
If you see database connection errors:
# Check if database is running
docker-compose ps
# View database logs
docker-compose logs db
# Restart services
docker-compose down
docker-compose up --build# Stop services
docker-compose down -v
# Start fresh
docker-compose up --builddocker-compose logs -f api{
"id": 1,
"account_id": 1,
"symbol": "AAPL",
"order_type": "BUY",
"quantity": 10,
"price": 150.00,
"status": "FILLED",
"rejection_reason": null,
"total_amount": 1500.00,
"created_at": "2025-01-11T10:30:00Z",
"filled_at": "2025-01-11T10:30:00Z"
}{
"id": 2,
"account_id": 1,
"symbol": "AAPL",
"order_type": "BUY",
"quantity": 1000,
"price": 150.00,
"status": "REJECTED",
"rejection_reason": "Insufficient funds. Required: 150000.00, Available: 10000.00",
"total_amount": 150000.00,
"created_at": "2025-01-11T10:31:00Z",
"filled_at": null
}This is a demo project for testing purposes.
For issues or questions, please check the API documentation at /docs or review the implementation in the source code.