← Back to list

I Built a Multi-User Trading Bot on Robinhood Testnet Chain for Arcus

How a weekend of API archaeology on dYdX’s new exchange turned into a full SaaS: Google login, auto-custody wallets, one-click funding, a…

izzet Cakmak · 2026-07-06 22:41 · 0 claps · 4.6 min read
#robin-hood #robinhood-crypto #arcus #dydx #trade
Open on Medium ↗
Wiki topics: CRY · Crypto & Web3 ECO · Economy · General HIS · History 🏺 · Archaeology & Anthropology

I Built a Multi-User Trading Bot on Robinhood Testnet Chain for Arcus

How a weekend of API archaeology on dYdX’s new exchange turned into a full SaaS: Google login, auto-custody wallets, one-click funding, a 41-market trading engine and Telegram alerts — all on testnet, all open source.

TL;DR

Arcus (https://arcus.xyz) is the new decentralized exchange built by dYdX Labs on Robinhood Chain, bringing together tokenized stocks and perpetual futures trading in one place.

Perpetual trading is still waitlisted (I’m somewhere around #32,000), but the testnet is open to everyone.

Instead of waiting, I built ArcusBot:

👉 https://www.atradebot.xyz

Users can:

  • Sign in with Google
  • Receive an automatically generated trading wallet
  • Fund it with $10,000 testnet collateral in one click
  • Choose a predefined or custom risk profile
  • Let a multi-signal trading engine trade across 41 different markets
  • Receive real-time Telegram notifications

This article tells the engineering story behind the project — including the three invisible-character bugs that almost broke production.

🎥 Video walkthrough: https://youtu.be/xqTsFjYLrGc

Why Arcus?

Arcus combines two products that rarely exist on the same exchange:

  • Tokenized stocks (spot, zero trading fees)
  • Cross-margined perpetual futures

Markets include:

  • Crypto
  • Equities
  • Commodities
  • Indices

with leverage up to 50× on Robinhood Chain.

Since Arcus is built by dYdX Labs, the API feels like it was designed by people who have operated real derivatives exchanges.

Some highlights:

  • REST + WebSocket APIs
  • Clean OpenAPI / AsyncAPI specifications
  • Ed25519 API keys generated locally
  • Registration authorized by a single EIP-191 signature
  • Two optimized signing schemes
  • Integer ticks and quantums instead of floating-point numbers

The testnet already supports paper trading across:

  • 8 crypto perpetuals
  • 26 stock perpetuals (AAPL, NVDA, TSLA…)
  • 3 commodities
  • 4 indices

Funding is permissionless through:

mint → approve → initiateDeposit

Step 1 — A Client, an Order, a Cancel

The initial milestone was intentionally simple:

  • Generate API keys
  • Register them
  • Place one limit order
  • Cancel it

Surprisingly, everything worked on the first try.

Then the testnet started teaching me lessons the documentation didn’t mention.

Lesson 1 — goodTilTime Is Always Required

Documentation says IOC orders ignore goodTilTime.

Reality says otherwise.

Every order requires an expiration timestamp at least one month into the future — even orders that exist for only milliseconds.

Lesson 2 — TP/SL Isn’t Live Yet

Arcus already exposes an elegant position-level Take Profit / Stop Loss API.

Unfortunately, testnet currently responds with:

501 NotImplemented

The trading engine now:

  1. Attempts native TPSL first
  2. Falls back to monitoring mark price
  3. Closes positions manually

Once Arcus enables the feature, the bot upgrades automatically.

Lesson 3 — Phantom Liquidity Exists

One order book displayed:

Bid: 1.12 BTC

My IOC sell order responded:

IOC_CANCELED

Seventeen consecutive times.

The reason?

The order book can display stale orders that only disappear when matching is attempted.

That discovery completely changed the execution strategy.

The engine now:

  • Tries several increasingly aggressive IOC orders
  • Falls back to a resting GTT order
  • Reprices every 60 seconds until filled

On a bursty-liquidity testnet, patience became an order type.

Step 2 — From Script to Product

Originally this was simply a personal trading script.

It used my Binance Futures strategy:

  • EMA 9 / 21 / 200
  • ADX
  • RSI
  • MACD
  • 15-minute candles

Eventually the question became:

Could anyone use this?

That evolved into:

https://www.atradebot.xyz

The platform now provides:

1. Google Login

No passwords.

No registration forms.

2. Instant Trading Wallet

Every user automatically receives a dedicated testnet wallet.

The backend:

  • generates keys
  • registers them with Arcus
  • encrypts them using Fernet

Private keys are shown exactly once.

Subsequent reveal attempts are permanently rejected.

3. One-Click Funding

A sponsor wallet:

  • sends gas
  • mints test USDG
  • approves spending
  • initiates deposit

About one minute later the account contains:

$10,000 testnet collateral

4. Flexible Risk Management

Users can choose:

  • Low
  • Balanced
  • High

or fully customize:

  • leverage
  • margin
  • stop loss
  • take profit
  • daily loss limit

The bot supports all 41 available markets with category-based selection.

Changes apply to the running engine without restart.

5. Telegram Alerts

Each user links their Telegram account through a deep link.

Notifications include:

  • Position opened
  • Position closed
  • Daily loss limit reached

The entire platform — including trading logs — is bilingual:

  • English
  • Turkish

Architecture

Browser
        │
        ▼
Vercel (FastAPI)
        │
        ▼
Neon PostgreSQL
        ▲
        │
Worker Engine
• Authentication
• Wallet generation
• Trading engine
• Funding queue
• Telegram polling
• User settings

The split exists because trading engines are the opposite of serverless workloads.

The website runs on:

  • Vercel
  • SSL
  • Custom domain
  • Always online

The worker currently runs on a desktop PC and will eventually move to an inexpensive cloud container.

Communication happens exclusively through PostgreSQL.

The API writes:

  • funding requests
  • user settings

The worker writes:

  • engine state
  • execution logs
  • trading events

The Bugs I’ll Never Forget

Three production incidents.

All caused by invisible characters.

1. Google OAuth

Google returned:

401 invalid_client

The client ID was correct.

Except PowerShell had prepended a hidden U+FEFF Byte Order Mark.

Google saw:

9194...

instead of

9194...

2. Fernet Encryption

While fixing the OAuth issue I accidentally used:

cut -d= -f2

which removed the trailing Base64 padding:

=

The entire application immediately started returning HTTP 500.

3. Telegram

Everything worked locally.

Production kept saying:

telegram bot not configured

The Telegram module only loaded tokens from:

.env

Vercel doesn’t use .env files at runtime.

Lesson learned.

Now every environment variable:

  • strips BOMs
  • removes carriage returns
  • checks os.environ first
  • validates expected string lengths

Cheap lessons.

Exactly what testnets are for.

What’s Next?

My roadmap includes:

  • 🤖 AI-generated trade commentary via Vercel AI Gateway
  • ☁️ Moving the worker to a cloud container for true 24/7 operation
  • 🚀 Switching to the production Arcus endpoint once my perpetual futures waitlist finally opens

Ideally, changing environments should require nothing more than updating a single base URL.

Try It Yourself

🌐 Live Demo (Testnet)

https://www.atradebot.xyz

💻 Open Source Repository

https://github.com/izzetcakmak/arcus-trade-bot

🎥 Video Walkthrough

https://youtu.be/xqTsFjYLrGc

Final Thoughts

Everything shown in this article runs entirely on Arcus Testnet using paper money.

This isn’t an investment strategy or financial advice.

It’s an engineering story about building a production-ready, multi-user trading platform while waiting for a very patient waitlist number to finally move.


메타데이터
post_id
2f2bf9309938
slug
i-built-a-multi-user-trading-bot-on-robinhood-testnet-chain-for-arcus-2f2bf9309938
url
https://medium.com/@izzetcakmak35700/i-built-a-multi-user-trading-bot-on-robinhood-testnet-chain-for-arcus-2f2bf9309938
canonical_url
https://medium.com/@izzetcakmak35700/i-built-a-multi-user-trading-bot-on-robinhood-testnet-chain-for-arcus-2f2bf9309938
author_url
https://medium.com/@izzetcakmak35700
status
ok
fetched_at
2026-07-08 18:29:56