From Zero Lines of Code to Building One of the Most Complex Crypto Trading Bots in the Space: My Story

15 min read
From Zero Lines of Code to Building One of the Most Complex Crypto Trading Bots in the Space: My Story

By Felix – founder of unCoded, ArrowTrade AG. Born 1999. Started coding at 17. Still haven't stopped.


I want to tell you something that most founders won't admit.

When I started building unCoded, I barely knew how to code.

Not "I was a beginner." Not "I had some experience from a bootcamp." I mean someone who had taught himself the basics out of necessity, by breaking things repeatedly until they worked, with no formal background and no one around who really understood what I was trying to do.

I was 17 when I first wrote code for money. Well – for Bitcoin. Which at the time felt like the same thing, except it also felt like magic.


2016: Miners, Dogecoin, and becoming a nerd before it was cool

I was born in May 1999. By the time I was 16, I was already the kid who spent too much time on the computer, cared too much about technology, and couldn't really explain to my classmates why any of it mattered. The outsider type. The one who was reading about things that hadn't become mainstream yet and getting blank stares when he tried to explain them.

In 2016 I discovered Bitcoin and Dogecoin mining.

I was 17. This was before the 2017 mania, before crypto was on the news, before anyone's parents had heard of it. I set up my first miners. Wrote scripts to automate them. Watched the coins accumulate. Made my first trades from the profits.

That was the beginning of everything – both the crypto obsession and the coding.

Mining taught me something important about how I learn: I need a reason. Abstract programming exercises bored me. But write a script that earns you money while you sleep? That I could sit with for hours. The motivation was real, the feedback loop was immediate, and the market didn't care how old I was or whether I'd studied CS.

I was years ahead of most of my peers in understanding what crypto was and where it was going. At the time that felt lonely – nobody around me got it. Later I understood it was an advantage. The people who were early in this space, who went through the cycles before it became mainstream, developed an instinct for how these markets move that you genuinely can't get by reading about it afterward.

By 2020, that instinct combined with four years of watching, trading, and building is what drove me to build something that didn't exist yet.


2020: The decision that changed everything

By 2020 I was deep enough in crypto that I knew exactly what I wanted to build. A bot that traded the way I thought about trading. Not a grid. Not a basic DCA. Something that could express real strategy logic, manage risk properly, and execute without me being glued to a screen.

The problem: I couldn't build it yet. Not at that level.

I had two options. Hire a developer – which I couldn't really afford at the level I needed, and also meant explaining my entire trading philosophy to someone who may or may not understand markets. Or go deeper with the coding I'd started with those mining scripts and actually learn to build software properly.

I chose to go deeper.

I'm not going to make this sound romantic. Learning to build real software as a self-taught developer, while also running a trading operation and managing everything else in your life, is brutal. The first weeks of going beyond scripts feel like reading a foreign language where even the grammar makes no sense. You write something, it breaks, the error message is in a language you don't speak yet, and you spend three hours fixing something that should have taken ten minutes.

I started with JavaScript. Node.js specifically. I chose it because most of what I found about Binance API integrations was written in JS, and I was pragmatic enough to pick the tool that had the most resources available, not the one that was theoretically "best."

The first things I built beyond the mining scripts were rough. Absolute spaghetti. But they ran. They connected to Binance. They placed orders. That first moment when a bot you wrote executes a real trade – even a tiny one – is one of those moments you don't forget. The thing I built did something in the real world. That feeling kept me going through every frustrating hour that followed.


The first real version: everything that could go wrong

The first version of what would eventually become unCoded was not called unCoded. It had no name. It was a Node.js script running on my local machine that I had to keep running manually, that would crash if my internet dropped, and that had about twelve different ways to lose money if conditions weren't exactly right.

But it worked. Roughly.

The core logic was there from the beginning: micro-trading, multiple buy points on dips, scaled exits at different profit levels. Not because I read about it somewhere – because that's how I thought about trading manually and I was just trying to automate my own behavior.

The first real lesson from running this in live markets: the gap between "works in testing" and "works in production" is enormous, and the gap costs money to discover.

Race conditions. Orders that fired when they shouldn't have. Positions that didn't close because the sell condition evaluated a millisecond before the buy order confirmed. Binance API rate limits that I hadn't accounted for, causing the bot to get temporarily blocked at exactly the moment it needed to execute.

Every one of these was a tuition payment. Some of them were expensive. None of them were in any tutorial.

This is the part of building software that nobody tells you about: debugging production issues in a live trading system is nothing like debugging a local development environment. The stakes are different. The time pressure is different. You can't just roll back a bad deployment when the rollback itself might trigger more issues.

I was 20 years old, self-taught, running live capital through code I'd written myself, fixing bugs under market pressure. Looking back, I probably didn't fully appreciate how unusual that was at the time. It just felt like the only way forward.


PostgreSQL, Docker, CapRover: building real infrastructure

At some point – I think it was late 2023 into 2024 – the script became something that needed to be treated as actual software. It needed a database. It needed to run on a server, not my laptop. It needed proper deployment infrastructure.

This was another learning curve.

I picked PostgreSQL for the database because I needed something that could handle concurrent writes reliably – multiple positions updating simultaneously without corrupting data. I learned what transactions are and why they matter the hard way, after a race condition corrupted position state during a volatile market move and I spent two days untangling what happened.

Docker came next. The ability to containerize the application and deploy it consistently to any server changed how I thought about the infrastructure. No more "it works on my machine" problems. No more manual dependency management. Build the image, ship the image.

CapRover for orchestration. Railway for cloud hosting. The whole stack came together over months of iteration, each piece added in response to a real problem that the previous setup couldn't solve.

By mid-2024, there was something that could genuinely be called a platform rather than a script. It had a database with trade history. It had a dashboard. It ran on a server. Other people could theoretically run it.

That "theoretically" was doing a lot of work. The setup process was a nightmare. The configuration was opaque. The documentation was nonexistent because I was the only user and I already knew how everything worked.


The community: unCoded becomes real

The decision to make unCoded available to other people happened before I thought it was ready. Honestly, it probably always would have felt not ready if I waited until I felt ready.

The first people to use it were traders I knew from the community. People who understood crypto, understood bots conceptually, and were willing to deal with rough edges in exchange for being early. Their feedback was brutal and invaluable.

Things that seemed obvious to me as the developer were completely opaque to users. Error messages that made total sense in the context of the code made zero sense to someone looking at a dashboard. Features I thought were well-designed were confusing. The Telegram bot commands that seemed intuitive to me were a labyrinth to everyone else.

Every piece of negative feedback was a gift, even when it didn't feel like one at the time. The gap between "this makes sense to me" and "this makes sense to someone who isn't me" is one of the most important things a developer can learn, and you can only learn it by putting your work in front of real people and watching what happens.

The community also found bugs I never would have found myself – because they were using the bot in ways I hadn't anticipated, with configurations I hadn't tested, at times and under market conditions I hadn't encountered during development.

This is also where the YouTube channel came in. Explaining unCoded to people who hadn't built it forced me to understand my own product at a different level. You think you understand something until you have to explain it to someone who has no context. The teaching made the product better.


The architecture rewrites: versions 8, 9, 10

If you want to understand the real history of unCoded's technical development, look at the version numbers.

By version 8, the multi-symbol trading architecture was being rebuilt from scratch. The original single-symbol design didn't scale. Running multiple pairs concurrently exposed all the places where the code assumed only one position could be open at a time. Shared state. Race conditions. Database queries that worked fine with one active trade and fell apart with seven.

The multi-symbol rewrite was months of work. It wasn't adding a feature on top of existing code. It was rethinking the data model, the concurrency model, the way positions were tracked and updated. Every part of the bot that touched position state had to be reconsidered.

Version 9 was where the Trailing Stop Loss system got rebuilt properly. The original TSL implementation had a problem that showed up intermittently in production: under certain conditions of concurrent order updates, the trailing level could miscalculate. It happened rarely enough that I didn't catch it in development. In production, running across multiple symbols 24/7, it happened enough to matter.

Fixing it properly meant understanding exactly how Binance processes order updates, what the timing guarantees are, and designing the TSL state machine to be safe regardless of the order events arrived in. Not glamorous work. Absolutely necessary work.

Version 10 was the Sell Time Curves. This was the feature I'd wanted to build for a long time but kept pushing back because it required a rethinking of how sell logic worked at a fundamental level. The original sell logic was straightforward: hit a profit percentage, sell. Sell Time Curves meant the sell threshold had to be dynamic, evaluated continuously, changing based on how long the position had been open.

That sounds simple. In a concurrent multi-symbol environment where positions open and close constantly, maintaining and correctly evaluating a time-decay function for each position without introducing bugs or performance issues is not simple. It took longer than I expected. It was worth it.


The Signal Editor: the biggest technical challenge yet

Everything I described above was building an execution engine. The Signal Editor is a different category of problem entirely.

Building a system that lets users construct arbitrary strategy logic – combining 152 indicators through a 40+ condition engine with boolean gates, then backtesting that logic against real candle data – is not an execution problem. It's a compiler problem.

The user defines what they want in a visual interface. The backend has to take that definition, resolve it into a series of pandas-ta indicator calculations, evaluate the conditions in the correct order respecting boolean logic, map the resulting signals to candles, and run a backtest that accurately models fees, fill prices, trailing stops, and position sizing.

Getting the backtesting engine to produce Sharpe ratios that are correctly annualized per timeframe was a specific rabbit hole. A 1-minute backtest and a daily backtest use completely different annualization factors. Most retail backtesting tools ignore this entirely. Getting it right required going back to the original Sharpe methodology and implementing it properly.

The condition engine was its own project. Supporting crossover, crossunder, rising for N bars, falling for N bars, statistical divergence detection, time-based conditions, signal persistence windows – and being able to chain all of them with AND/OR/NOT/XOR/NAND/NOR gates – required a clean, extensible architecture from day one. I wrote it three times before I was happy with it.

FastAPI for the backend. React on the frontend. The whole thing integrates with the live bot so a strategy validated in the Signal Editor can be deployed to live trading directly.

I was 25 when I shipped the first version of the Signal Editor. I started learning to code properly at 17 with Bitcoin mining scripts. The distance between those two points is not a straight line – it's every rewrite, every 3am debugging session, every feature that took three times as long as I thought it would, every time the market forced me to rebuild something I thought was finished.


What I know now that I didn't know then

A few things I'd tell myself at the beginning:

Writing code that works is the easy part. Writing code that keeps working under production conditions, with real users, under unexpected market conditions, for months and years – that's the actual skill. Get obsessive about edge cases. They're not edge cases. They're the cases that happen when markets move.

Documentation is not optional. I wrote almost none for the first year. I paid for it every time a user had a question or hit a problem I'd already solved internally. Now the docs at docs.uncoded.ch are part of the product, not an afterthought.

Ship earlier than feels comfortable. The version I was about to release was always "not ready." The version I shipped was always "better than what existed before." These are both true simultaneously. Ship when it's better than nothing, not when it's perfect.

The community teaches you things you can't learn any other way. Every bug report, every confused user, every piece of negative feedback is information about the gap between what you built and what people need. Treat it as research.

Being early is uncomfortable in real time and an advantage in retrospect. In 2016 nobody I knew understood why I was spending time on Bitcoin miners. In 2020 nobody I knew understood why I was spending months building a trading bot from scratch. The pattern repeats. Being ahead of where the conversation currently is means being wrong about timing sometimes, but it also means being positioned when things shift. I'd rather be early than arrive after everyone else.

Self-hosting is a feature, not a compromise. I built unCoded as self-hosted partly for ideological reasons – I believe traders should own their infrastructure. Over time I've come to understand it's also just better software engineering. When users control their own deployment, they're invested in understanding it. That creates better users and forces better documentation and better design.


Where it is now – and where it's going

We're at a point with unCoded that genuinely surprises me when I look back at where it started.

A live trading bot with buy splits, sell time curves, automatic DIP rebuying, multi-symbol concurrent execution, trailing stop loss, and TradingView webhook integration. A Signal Editor with 152 indicators, a full boolean condition engine, Kelly Criterion position sizing, and a proper backtesting engine. A deployment process that gets you live in under 15 minutes. A community of traders actually using it in live markets.

I'm 26 now. I built the foundation of this starting from mining scripts at 17 and a burning frustration with what existed at 20. Neither of those people knew what they were building toward. That's fine. You don't need to see the full picture to start moving.

More exchanges are coming. Strategy templates are being built so the entry point doesn't require starting from scratch. The architecture is ready for both.

When I think about the next few years, the thing I'm most clear on is this: the depth of what's possible with unCoded's architecture is far from fully explored. We've built the foundation. The strategies, the configurations, the edge that traders can build on top of it – that's the interesting part, and it's barely started.

The nerd who set up Bitcoin miners at 17 and couldn't explain to anyone why it mattered – turns out he was just early.


unCoded — uncoded.com Docs — docs.uncoded.ch ArrowTrade AG — Switzerland