MetalSniper
I stopped looking for signals and built a risk machine instead
A supervisor-managed autonomous trading system I designed and built end to end. Recurrent PPO-LSTM signals and cross-listed statistical arbitrage run in Python, a C++17 bridge executes through Interactive Brokers, and an independent risk sentinel can shut trading down without waiting for the models. The supervisor restarts failed processes, records decisions, and sends operational alerts.
Direct answer
What is the MetalSniper quantitative trading system?
MetalSniper is a supervisor-managed autonomous quantitative trading system built by Isaacson Shoko. Its current Interactive Brokers runtime combines recurrent PPO-LSTM signal models for gold and silver with a five-pair, cross-listed statistical-arbitrage strategy. Python handles features, inference, portfolio decisions, and trade workflow; a C++17 bridge owns broker execution over ZeroMQ; and an independent C++ risk sentinel checks the book every second and can stop trading or flatten positions without relying on the ML processes. The documented deployment is live paper trading, with production-capital use still pending.
- Runtime
- Python 3.12 + C++17 over ZeroMQ
- Active ML
- Recurrent PPO-LSTM signals + gradient-boosted policy gates
- Strategies
- Gold/silver signals + five cross-listed equity pairs
- Safety
- Hard rules + policy vetoes + an independent one-second sentinel
The Project
MetalSniper trades two strategy families through Interactive Brokers: recurrent PPO-LSTM signals for gold and silver, and market-neutral statistical arbitrage on companies listed on two stock exchanges at once.
But the project did not start as an engineering exercise. It started as an uncomfortable realization, and that realization became the thesis the whole system is built around.
"Trading is not a prediction business. It is a risk management business that occasionally uses predictions."
The Problem
Every trading influencer sells the same fantasy: the signal. The magic indicator, the AI that predicts the market. I chased that too, until I studied my own trade history.
My wins and losses had less to do with when I got in than with what I did afterwards. The trades that hurt were not bad entries, they were good entries managed badly. Held too long. Added at the wrong time. Refused to admit a winner had turned. So the system I set out to build treats the entry as the least interesting decision, and pours its engineering into everything downstream: holding, exiting, adding, and surviving. The discipline a human cannot sustain at 3am.
Runtime System
Most retail bots are one script talking to a broker and hoping nothing freezes. MetalSniper is split the way a real trading desk splits people, because their failure modes differ.
The three runtime processes exchange commands and telemetry over ZeroMQ, and the supervisor manages them like cattle, not pets. One early bug made this philosophy concrete: the engine reported success to its supervisor even when it had crashed, so the watchdog never restarted it. The system failed politely. Getting exit codes, heartbeats, and readiness signals right turned out to matter more than any trading logic.
Trading engine
Python builds features, runs recurrent PPO-LSTM inference for gold and silver, generates stat-arb signals, and submits validated trade intents.
Signals, features, and execution workflow
Portfolio orchestrator
A separate Python process evaluates portfolio state, applies hard portfolio rules, and records autonomous entry, hold, scale, and exit decisions.
Portfolio judgment and audit
C++ execution bridge
C++17 owns the Interactive Brokers connection, market data, order placement, and ZeroMQ command and telemetry channels.
Broker execution, isolated from Python
Independent risk sentinel
A watchdog inside the C++ process checks the book every second and can block trading or flatten positions without depending on the model processes.
One-second checks, independent authority
Process supervisor
start_all.bat enters the supervisor, which runs preflight checks, starts the three runtime processes in order, waits for readiness, restarts failures with backoff, and stops crash loops.
Preflight, restart, contain, alert
start_all.bat -> python -m scripts.supervisor
-> preflight: environment, ports, broker session, execution mode
-> launch C++ IBKR bridge (orders + one-second risk sentinel)
-> launch Python portfolio orchestrator; wait for ready file
-> launch Python trading engine (PPO-LSTM inference + stat arb)
-> connect ZeroMQ: commands (req/rep), telemetry (pub/sub)
-> monitor processes, heartbeats, and readiness probes
-> on abnormal exit: restart with backoff
-> on crash loop: hard stop + Telegram alertQuant Core
The system supports two different trading paradigms without pretending they are the same thing.
Metals, with humility about direction
The active metal signal path builds hourly features and maintains recurrent state while PPO-LSTM models score hold, buy, and sell actions for gold and silver. Signals are then combined with regime context, learned pattern memory, and news sentiment before they can reach execution. Its opening workflow can hedge both directions, let the market invalidate the wrong leg, and then focus on holding, exiting, or adding to the surviving position under one non-negotiable rule.
You may only scale into a position whose profit is already locked in by a stop.
Floating gains are the market's money, not yours.
Dual listing arbitrage
Anglo American is one company whose shares trade in Johannesburg and London, simultaneously, in different currencies. Convert both to rand and they should match. They drift, and when they drift too far, they snap back. The system shorts the expensive listing, buys the cheap one, and collects on the reunion, indifferent to whether markets rise or fall. It watches five such pairs across Johannesburg, London, Amsterdam, and New York, while respecting a constraint most backtests ignore: two prices are only comparable when both exchanges are actually open. The signal engine normalizes currency and quote units, estimates hedge ratios and spread half-life, and uses z-score entry, exit, stop, and time rules while persisting pair state across restarts.
Machine Learning and Research
MetalSniper uses two different kinds of machine learning for two different jobs: recurrent reinforcement learning proposes market actions, while smaller supervised models act as policy guardrails around selected trade-management decisions.
The active gold and silver paths load recurrent PPO-LSTM model artifacts and preserve hidden state between decisions. Separately, gradient-boosted classifiers trained on the system's decision history replaced an earlier paid LLM dependency for entry-veto and ride-or-exit recommendations. Those policy models are deliberately VETO-shaped: they may block an entry or recommend an exit, but may not force a trade or override hard risk rules.
Recurrent signal layer
PPO-LSTM models score hold, buy, and sell actions for hourly gold and silver features while carrying temporal state between inference cycles.
Policy guardrails
Gradient-boosted entry-veto and ride-or-exit models advise the rules engine; they never outrank loss limits, exposure caps, or locked-profit rules.
Research gates
Cost-aware labels, automated leakage checks, chronological splits with purge gaps, shared features, and artifact checks guard training-serving parity.
Evidence boundary: the current policy dataset spans 539 simulated episodes and has thin regime coverage. The repository therefore treats these models as veto/exit recommendations and calls for shadow comparison before trusting them with position sizing. This is an engineering case study, not a profitability claim or investment advice.
Risk
Risk lives in three layers, each unable to depend on the layer above it.
Hard rules in code
Daily loss halts, exposure caps, and the locked profit rule. No model can override them.
Trained models as judges
Veto shaped by design. They can block a trade or recommend an exit, but they can never force one.
The independent watchdog
If the Python brain freezes or the machine chokes, the C++ sentinel still guards the book with daily loss flattening, rapid loss cuts, and trailing stops.
The component protecting the money does not depend on the component most likely to fail.
Architecture
Failure isolation
The system is split the way a trading desk splits people, because their failure modes differ. Risk logic lives outside the crash prone layer, so the part protecting capital does not depend on the part most likely to fail.
Execution that acts, not thinks
A C++17 core owns broker connectivity and order placement against the Interactive Brokers API, kept deliberately dumb and fast so heavy model work in Python can never stall an exit.
Research discipline
Leakage gates, cost aware labels, time respecting validation, postmortems, and a full audit trail all point to a builder who cares about whether a result is real, not just whether it looks good.
| Layer | Choice | Why |
|---|---|---|
| Brain | Python 3.12 | Model inference, the decision pipeline, and the statistical arbitrage engine |
| Execution core | C++17 + IBKR API | Broker connectivity and order placement, isolated from slow AI workloads |
| Messaging | ZeroMQ | Request and reply for commands, publish and subscribe for telemetry |
| Market signal models | Recurrent PPO-LSTM | Stateful reinforcement-learning inference for the active gold and silver signal paths |
| Policy models | Gradient-boosted trees | Veto and exit recommendations trained on decision history, with training and serving parity enforced at load |
| Control plane & audit | Supabase (Postgres) | System state plus a durable record of every autonomous decision |
| Supervision | Process supervisor | Readiness probes, exponential backoff restarts, and crash loop containment |
| Alerts | Telegram | Human facing notifications when something important happens |
Monitoring
Two discoveries taught me that silence is the most dangerous failure mode.
Dead for months
During an audit I found the old AI judge had been retired by its vendor. Every call was failing, and each component quietly fell back to its own default. No error, no alert. The system had degraded politely. Now every autonomous decision lands in an audit database, and the ones that matter hit my phone.
A 100 percent win rate
A backtest handed me a perfect result. The correct response is not celebration, it is an audit of your own measurement. Exchanges close at different times, so my simultaneous prices were not, and the strategy was harvesting a timestamp illusion. Tested honestly, most of the edge evaporated.
If the sentinel flattens the book at 3am, I know by 3:01. The pairs that survived, I trust because the process was built to kill the ones that lied.
Skills Demonstrated
Each of these is pinned to evidence in the sections above, not asserted in the abstract.
A supervisor coordinating three restartable Python and C++ runtime processes over ZeroMQ, with risk logic isolated from the model layer.
A supervisor with preflight gates, readiness probes, backoff restarts, and crash loop containment, born from the exit code bug that made self healing real.
Cointegration and mean reversion analysis across four exchanges, cost aware backtesting, and the scepticism to catch look ahead bias in my own results.
Recurrent PPO-LSTM signal inference plus gradient-boosted policy gates, backed by leakage checks, time-respecting validation, and enforced training-serving parity.
Layered controls where hard rules outrank models and an independent watchdog outranks everything.
Multi source market data with currency unit normalization, London quotes in pence and Johannesburg in cents, plus persistence and schema migrations.
Decision level audit trails, real time alerting, and the conviction that a system must confess its failures loudly.
AI wrote plenty of this code under my specification, review, and verification. Knowing what to build, how to check it, and owning the outcome is the skill.
One person carried this from thesis to data to models to infrastructure to a system running live paper trading, with real money consequences pending.
Takeaways
"In the AI age, writing code is the cheap part. What remains scarce is the judgment around it."
That is systems thinking. It is the same discipline whether the system trades metals, routes trucks, or serves customers, and it is what I bring to the table.
Repository
MetalSniper runs recurrent PPO-LSTM signal models and cross-listed statistical arbitrage in Python, with gradient-boosted policy guardrails, C++17 execution over ZeroMQ, an independent one-second risk sentinel, and a durable decision audit trail. For the technical deep dive, inspect the repository or get in touch.