5.6%

Average Monthly Return

Driscoll Automated Forex Trader is a self-optimising, data-driven trading engine built to operate continuously in live foreign-exchange markets. Designed for precision, resilience, and consistency, it combines algorithmic grid trading with adaptive trend filtering to deliver steady, risk-managed returns under varying market conditions.

This project is a fully automated grid-based foreign exchange trading engine written in Go. At its core, it implements a structured price-spacing pattern: positions are opened at predefined intervals as price moves, and closed as price mean-reverts. The strategy does not attempt to predict direction; instead, it assumes that over time most currency pairs oscillate within broad ranges. An internal EMA calculator continuously classifies short- and medium-term trend conditions, allowing the engine to adjust behaviour based on prevailing direction rather than trading blindly into momentum.

To improve resilience, the system runs across ten major currency pairs simultaneously. Each pair operates as an independent state machine with its own capital allocation, but all follow identical logic. This diversification reduces exposure to structural shocks in any one currency. A sustained move in a single pair should not compromise the entire system; instead, risk is distributed across multiple instruments with differing macro drivers.

Trade spacing within each grid is dynamic. Rather than using fixed pip distances, the spacing adapts to observed volatility, expanding in more turbulent conditions and tightening in calmer markets. As a governing constraint, the full grid range is designed to approximately cover five years of historical price movement for a given pair. In addition to this structural envelope, the engine incorporates proprietary mechanisms that allow it to ride extended trends without prematurely collapsing positions, while still enforcing controlled drawdown from local peaks. These mechanisms are designed to balance mean-reversion harvesting with directional persistence.

Risk containment is further reinforced through internal margin management rules. The system monitors aggregate directional exposure and applies proprietary constraints to prevent excessive concentration in a single bias. When directional skew becomes too extreme, new exposure of that type is restricted, reducing the probability of runaway margin expansion during strong moves. The overall design treats trading as a deterministic, continuously running service: every decision is derived from price, volatility sampling, EMA state, and internal exposure metrics. From an engineering perspective, the interesting problem is building a real-time, stateful system that can operate autonomously under uncertainty and persist through prolonged directional phases without manual intervention.

Software

The trading engine is written in Go and built around a proprietary goroutine management library designed for long-running, stateful services. Rather than relying on ad-hoc concurrency patterns, the system uses structured lifecycle control for its internal processes: startup sequencing, supervised execution, graceful shutdown, and coordinated cancellation are all handled explicitly. The result is a deterministic service that can run continuously without orphaned routines or uncontrolled concurrency growth.

At runtime, a dedicated pricing process polls market data for all ten currency pairs once per second. This process acts as a central dispatcher: after aggregating the latest prices, it broadcasts structured price messages to individual trading processes. There is exactly one trading process per currency pair. Each operates independently, maintaining its own state machine, exposure calculations, EMA context, and open-position ledger. This separation ensures isolation at the strategy level while still allowing coordinated behaviour at the infrastructure level.

All trade state and analytical data are persisted to Google Cloud Firestore. Open positions, historical periods, volatility samples, and internal metrics are written at controlled intervals, allowing the service to recover cleanly after restart. Firestore functions as both persistence layer and recovery backbone; if the binary restarts, each trader reconstructs its internal state from stored data and resumes without manual intervention.

The entire system runs as a single compiled binary deployed inside Kubernetes. Pricing, trading, analytics, and persistence are composed within one cohesive service rather than separated into microservices. This design was chosen deliberately to minimise inter-service latency: when a price update arrives, trading decisions can be evaluated and executed within the same executable, without network hops or service-to-service overhead. Kubernetes provides orchestration and restart guarantees, while the internal goroutine management system governs logical process isolation. The result is a compact but highly concurrent service — one container, one binary, multiple supervised trading engines operating in parallel with minimal decision latency.