Source code accompanying the blog post series on softwaremill.com:
A Trading Accountability App — a tool that logs trades, enforces trading rules, and flags violations when discipline slips. Built with Kotlin-native libraries only.
- Kotlin 2.3.20
- Ktor 3.4.1 — HTTP server framework
- Koin 4.1.1 — Dependency injection
- Exposed 1.2.0 — Type-safe SQL
- H2 — In-memory database
- Gradle 9.4.1, JDK 25 (LTS)
./gradlew runThe server starts at http://localhost:8080.
curl http://localhost:8080/health{"status": "UP"}curl -X POST http://localhost:8080/rules \
-H "Content-Type: application/json" \
-d '{"name": "Always add notes", "description": "Every trade must have notes explaining the rationale"}'{"id": 1, "name": "Always add notes", "description": "Every trade must have notes explaining the rationale"}curl http://localhost:8080/rulescurl -X POST http://localhost:8080/trades \
-H "Content-Type: application/json" \
-d '{"ticker": "BTC/USD", "direction": "LONG", "entryPrice": "67000.00", "quantity": "0.5"}'{"id": 1, "ticker": "BTC/USD", "direction": "LONG", "entryPrice": "67000.0000", "quantity": "0.5000", "openedAt": "2026-04-02T10:48:54"}Closing a trade automatically checks active trading rules and logs any violations:
curl -X PUT http://localhost:8080/trades/1/close \
-H "Content-Type: application/json" \
-d '{"exitPrice": "68500.00", "notes": "Target hit"}'curl http://localhost:8080/trades/1curl http://localhost:8080/tradescurl -X POST http://localhost:8080/trades/1/violations \
-H "Content-Type: application/json" \
-d '{"ruleId": 1, "description": "Entered without checking higher timeframe"}'The repo is tagged by article progression:
v0— Minimal runnable scaffold: Ktor + Koin + Exposed configured, health endpoint onlyv1— You are here. Complete implementation from Part 1: full CRUD, trading rules, violation detection
src/main/kotlin/com/trading/
├── Application.kt — Entry point (fun main)
├── config/
│ ├── Database.kt — H2 connection + schema creation
│ ├── Koin.kt — DI module definitions
│ ├── Serialization.kt — JSON content negotiation
│ └── StatusPages.kt — Error handlers → HTTP status codes
├── db/
│ └── Tables.kt — Exposed table definitions
├── model/
│ ├── Models.kt — Domain models + request DTOs
│ └── BigDecimalSerializer.kt — Custom serializer for financial precision
├── repository/ — Data access layer (interface + Exposed implementation)
├── routes/ — HTTP endpoint definitions
└── service/ — Business logic with transaction management