Trading crypto is foreign territory for me, and I needed a way to enter the market without a steep barrier to entry when it came to technical analysis and programmatic expertise.
By utilizing resources and tools available in the crypto trading space and the tech space, I created a multi-coin, multi-strategy algorithmic trading bot that focuses on a variety of crypto currencies and adjusts its strategy based on market data.
The bot never scrapes a website. Every price, balance and order it sees arrives through an exchange's public or authenticated REST API. Each exchange sits behind one shared interface, so a strategy never knows which platform it is talking to, and adding an exchange is a config entry plus one adapter. This section covers what each connection pulls, and the full scope of API work that had to be right before the numbers could be trusted.
Swipe to see more →
Auth: API key plus private key from environment variables, signed per request by the CCXT library.
Auth: none needed. Public market data only.
Auth: none needed for market data.
Auth: read-only key. Every request carries the key, a timestamp valid for 30 seconds and an Ed25519 signature.
Pulling a price is one line of code. Making it dependable is the actual scope. These are the concerns I made sure were specified, built and tested before any strategy result was trusted.
Swipe to see more →
Keys come from environment variables, never from code, config or logs. Coinbase's multi-line private key and Robinhood's signed headers each have their own handling. A missing or rejected key produces a plain message naming what to fix.
Reading and trading are separate powers. Keys are read-only where the exchange allows it, and placing or cancelling an order is blocked in the client code itself until it passes a review.
Built-in throttling, a per-exchange pause for strict ones (Bitfinex), and a back-off of 60 then 120 seconds if an exchange still answers "too many requests". Downloading six years of 5-minute data for seven coins is rate-limited, so it resumes where it stopped.
Network failures retry three times with doubling waits (1s up to 30s). Rejected credentials are never retried. Every library error is translated into one of six plain ones, such as bad credentials, network problem or unknown pair.
Coinbase documents 350 candles per request, but the live API returned 300. The first real download therefore had a 50-candle hole in every 350. The fix was to request 300 and continue from the last candle received, plus a repair command for the data already saved.
One SQLite file, keyed by exchange, pair, timeframe and time. It needs no install, writes atomically, and holds every pair and timeframe in one place for backtests, paper trading and the dashboard. Repeat syncs fetch only new candles.
Only closed candles are stored or served. Rows are validated, sorted and de-duplicated. Missing history is detected, never silently bridged. Timeframes an exchange lacks are built from smaller ones: 4h from 1h, weekly and monthly from daily.
Each venue's real maker and taker fees are applied to simulated fills, plus slippage. Robinhood's hidden cost is measured from its quoted spread instead of assumed to be zero.
Each build phase carries a written "done when" test. For the connection layer: the check script shows candles on every native timeframe and the right pair name, and orders stay disabled until the trading phase is reviewed.
I am a product owner, not a Python developer, and I built this with Claude acting as the engineer. I set the outcomes, constraints and trade-offs, and Claude wrote and tested the code. The decisions below are mine, and each one changed how the API layer works. Where I changed my mind after seeing results, that is listed too.
Swipe to see more →
Connect to a variety of exchanges, with a list where I toggle which ones to read and trade on.
Built: one shared exchange interface and a config file of exchanges and pairs with on and off switches. Live trading needs three separate confirmations.
I live in New York, so Kraken is out and Coinbase can't short. Longs only.
Built: Coinbase as the only traded venue, shorts switched off, and short setups recorded as simulated “ghost” trades that never reach an exchange.
Coinbase doesn't have enough history. Pull candles from other exchanges too.
Built: research-only exchanges (Bitstamp, Bitfinex) with a data policy for which history counts, kept apart from Coinbase data.
Never trade on data with holes. Later: treat gaps the way a real trade would experience an outage.
Built: gap detection first, then a rule that bridges short outages with flat, marked candles only when other exchanges kept moving, and never fills an order inside one.
Major code changes stay in review, and the AI must never be able to lose working core code.
Built: order placement hard-blocked in the exchange client, plus saved snapshots of the guarded core code with a restore command.
Robinhood says zero fees. I want to see the real cost. (I created the read-only key myself.)
Built: a read-only Robinhood client that reads bid, ask and buying power and can never trade.
Gemini's fees look much lower than Coinbase's. Add it, paper trading first.
Built: a Gemini connection with its own fee model, and the Coinbase fee schedule kept in mind with limit (maker) orders favoured.
I first assumed zero fees, then supplied Coinbase's actual fee tiers.
Changed: every backtest and paper trade now pays real fees plus slippage, which lowered the results and made them honest.
What this shows: I understand how the APIs work well enough to specify them, question them and catch what they get wrong, such as fee assumptions, missing history and hidden spreads. I also know how to run an AI engineer through requirements, acceptance tests and review, without pretending I wrote the code myself.
The bot needed to support multiple cryptocurrencies, as well as multiple trading strategies in a way to maximize the number of successful trades made each week and keep strategies organized in the process.
The bot also needed to effectively deploy AIML models to learn from trading data and suggest adjustments based on reports of the changing market conditions.
For the project scope, the bot was developed in Python and hooked languages like HTML, CSS, and Javascript to provide a live analysis dashboard to my computer and iPad. The bot is equipped with emailing and text messaging notifications to alert me of significant market movements and keep me updated on the unfoldin of trade opportunities.
Not much has been sacrificed in the trading bot's functionality apart from the overall limitation for trading in New York that disallows shorting positions.
Along with the limitation of shorts, New York is also particularly strict when it comes to trading on exchanges, limiting the bot's multi-exchange functionality to Coinbase primarily.
In progress!