A year ago, I started this project with a specific problem to solve: I kept losing money on trades I understood intellectually but couldn't execute correctly under pressure. The plan was to build an algorithm that would execute rules I couldn't stick to manually. What I built over the following twelve months was substantially different from what I started with, and the distance between the original plan and the final result tells a clearer story about algorithmic trading than any single post in this series.
This is the retrospective. Not a highlight reel — a full accounting of what failed, what worked, and what I understand now that I didn't understand when I started.
Three Things I Got Completely Wrong
Wrong #1 — Thinking Automation Was the Hard Part
When I started, my mental model was: figure out the rules, write the code, and the hard part is done. Automation felt like the endpoint. If I could get the code to execute correctly, the problem was solved.
This was wrong in almost every important way. Automation is the easy part. The hard part is knowing what rules are worth automating. Writing Python code that places a buy order when certain conditions are met takes a few hours once you understand the API. Figuring out whether those conditions actually represent a meaningful signal — testing that belief against real data, watching it fail in ways you didn't anticipate, adjusting it, watching it fail differently, adjusting again — takes months. The ratio of time I spent on code versus time I spent on strategy design and validation was roughly 1:10. Most people starting this kind of project expect the opposite.
The practical consequence of getting this wrong was that I deployed live capital too early. After about six weeks of paper trading, the system felt stable. The logic was running correctly, the signals looked reasonable, and I was impatient. I moved to live trading before the strategy had been genuinely stress-tested across different market conditions. The first real test came about two weeks later when the KOSPI had a sharp three-day decline. The system handled the technical execution correctly but generated signals on stocks whose setups were valid by the pattern criteria and disastrous by any other measure — because the pattern criteria had been calibrated on data from a trending market and hadn't been tested against a declining one. I took losses I wouldn't have taken if I had waited another two months.
Wrong #2 — Using a 25-Step Grid With Back-Weighted Allocation
The original grid strategy is covered in detail in earlier posts, but the short version is this: I designed a system that bought in 25 stages with increasing position size in later stages, on the theory that buying more at lower prices was optimal. The theory was correct in isolation. The system was not.
What I failed to model before running it was the risk-reward profile at each individual stage. I knew the overall strategy had a positive expected value under normal conditions. What I didn't calculate was what happened to the risk-reward ratio specifically in the later stages — where the allocated capital was largest. When I finally modeled this out, I found that stages 15 through 25 had unfavorable risk-reward profiles embedded directly in the design: the take-profit target was fixed at a level that produced a smaller gain than the potential loss at the stop-loss level, specifically because the later stages had larger position sizes and the stop-loss level hadn't been adjusted to match.
This cost real money before I found it. The losses were modest in absolute terms because I was trading conservatively, but the error was structural — it would have scaled linearly with position size. Finding it required building a full simulation of every stage's expected outcome rather than looking at the aggregate performance, which is a lesson I now apply to any strategy before running it live: simulate every exit point at every stage, not just the overall expected value.
Wrong #3 — Trusting Visual Pattern Recognition Without Timestamps
This one I've covered in an earlier post, but it deserves emphasis in the context of the full-year retrospective because it affected my confidence in the system at a critical point.
About six weeks into live running, I reviewed a batch of completed signals against their charts and concluded that the system was consistently generating signals near price peaks. This was wrong — the system was generating signals near lows and pullback completions — but I couldn't see that without precise timestamps, because the human eye, reading a completed chart, anchors to the most dramatic price action rather than the specific moment a signal fired.
I nearly redesigned the signal detection logic based on this false conclusion. I spent three days developing an alternative entry framework before going back and annotating the charts with exact timestamps. The moment I did that, the apparent problem disappeared. The signals were firing exactly where the design intended.
The cost of this mistake was three days of wasted work and a period of doubt about whether the system's core logic was valid. The lesson was permanent: never evaluate signal quality from visual chart review alone. Always start with the exact timestamp from the trade log, mark it on the chart, and only then assess what happened before and after.
Three Things That Actually Worked
Worked #1 — The ATR-Based Pullback Threshold
Replacing the fixed 3% pullback threshold with a threshold calibrated to each stock's ATR was one of the higher-impact changes I made, and it worked better than I expected.
The most visible effect was on the false signal rate in volatile stocks. Before the change, the system regularly generated signals on high-volatility stocks where the pullback had been shallow in absolute percentage terms but was actually quite shallow relative to what was normal for that stock. These were almost always low-quality signals — the pullback hadn't been deep enough to suggest any real consolidation, just a momentary pause in a fast-moving stock. After the ATR adjustment, these signals stopped firing because the system now correctly recognized that a 2% pullback in a stock that typically moves 8% a day is not a meaningful pullback.
The false positive rate on confirmed signals dropped by roughly a third after this change. I estimated this by tracking outcomes over four-week periods before and after the adjustment and comparing the percentage of confirmed signals that led to a meaningful continuation move within two hours versus those that reversed immediately. The improvement wasn't subtle.
Worked #2 — The 09:00 to 10:30 Entry Window
Restricting new stock entries to the first 90 minutes of the trading session was a change I made reluctantly because it felt like I was leaving opportunities on the table. Stocks generate interesting setups throughout the day — why would I ignore them after 10:30?
What the data showed, after about two months of tracking signal quality by time of day, was that the gap in signal quality between the 09:00-10:30 window and the rest of the session was large enough to justify the restriction. Signals generated between 09:00 and 10:30 produced continuation moves at a meaningfully higher rate than signals from later in the session. The afternoon signals weren't uniformly bad — some of them led to good moves — but the hit rate was lower and the average subsequent move was smaller.
The mechanism behind this isn't mysterious. The opening session is when price discovery is most active. Overnight news, pre-market announcements, and accumulated order imbalances all get processed in the first hour or so of trading. Stocks that break out during this window are responding to genuine new information and fresh capital. Stocks that break out at 13:00 are more often responding to intraday noise or short-term order imbalances without the same underlying demand.
Restricting to the opening window also had a practical benefit I hadn't anticipated: it reduced the total number of signals to a manageable volume for manual review. Before the restriction, the system occasionally generated fifteen or twenty signals in a single session, making it impossible to review each one carefully before deciding whether to act. After the restriction, the typical session produced five to eight confirmed signals, which I could review thoughtfully.
Worked #3 — Firebase as the Real-Time Data Bridge
The technical decision to use Firebase Realtime Database as the bridge between the Python trading engine and the React web dashboard was one of the first technical decisions I made, and it's held up well across a full year of daily use.
The alternative I considered was building a local web server on the same machine as the trading engine. Firebase was the right choice for one reason that only became fully clear after months of use: reliability under variable conditions. A local web server adds a dependency that can fail independently of the trading engine — if the server crashes or the port becomes unavailable, the dashboard stops updating and the trading engine keeps running without any indication that monitoring has been lost. With Firebase, the only dependency is the internet connection and Firebase's own availability, both of which have been essentially continuous over the year. In twelve months of daily use during market hours, the dashboard has lost real-time updates twice — both times due to the rate limiting issue I described in an earlier post, which I fixed by reducing write frequency.
The dashboard showing real-time signal state has also changed how I use the information the system produces. Watching signals develop through the stages — wave forming, pullback in progress, breakout waiting — rather than just seeing the final confirmed signal has improved my ability to anticipate which signals are likely to be high quality before they fire. This wasn't something I planned for in the design; it emerged from having a live visual display and learning how to read it over time.
What Year Two Looks Like
Three specific improvements are in progress or planned for the coming months.
The first is automating the volume dry-up check during pullbacks. Right now, this is a manual visual check I run when reviewing each confirmed signal. Automating it requires tracking volume trend across the candles of the pullback phase and computing a slope or ratio that can be evaluated programmatically. The technical implementation isn't complex; the calibration — deciding what threshold separates meaningful volume decline from normal variation — requires more data than I currently have.
The second is adding a pre-signal risk-reward calculation to the dashboard. For each confirmed signal, the system should automatically display the ratio between the distance to the stop-loss (one tick below the valley low) and the distance to the first target (the reference high plus a percentage). This would let me screen out entries with unfavorable geometry without doing the calculation manually for each signal.
The third is exploring whether participant breakdown data — the institutional, foreign, and retail split of trading value — can be incorporated into the signal grade calculation. As I described in an earlier post, the composition of trading value matters alongside its absolute level, and automating that consideration would make the grade more informative.
None of these changes is urgent. The system is producing useful signals in its current form. But the nature of building something like this is that the improvements never stop — each version reveals the next set of questions. That ongoing iteration is, in the end, most of what algorithmic trading development actually is.
Today's Investing Insight — Survivorship Bias in Trading System Research
When you read about successful algorithmic trading systems, you're reading about the ones that worked. The systems that were designed with similar logic, tested with similar rigor, and run in similar markets but produced poor results don't get documented — their designers either abandoned them quietly or chalked them up to personal failure rather than publishable experience. This is survivorship bias: the sample of information available to you is systematically skewed toward successes. The practical implication for anyone building a trading system is that the documented approaches you study represent the distribution of outcomes for systems that worked, not the distribution of outcomes for all systems that were tried. The true base rate for retail algorithmic systems producing durable positive returns is almost certainly lower than the visible evidence suggests. This doesn't mean the effort isn't worthwhile — the learning value of building a serious system is real regardless of financial outcome — but it's worth holding the expectation of success with appropriate humility.
---
This post documents a personal journey of building an algorithmic trading system over approximately one year and reflects personal experience and perspective. It is not a recommendation of any specific strategy. Past performance described here does not predict future results, and all investment decisions and their outcomes are the sole responsibility of the investor.
Comments
Post a Comment