KOSDAQ 150 Trading Backtest, Part 2: A Few Ways to Improve Performance (Feat. ATR)

🇰🇷 한국어 원문 · Originally written in Korean on Oct 18, 2026. Slides have been re-labeled in English.

Yesterday I wrote this post.

That post showed what happens when the rules run mechanically, with none of the judgment I add in practice.
Split the capital into 24 accounts, buy one more account every 1.5% drop, and sell each account once it is up 0.5%.
The result: CAGR +3.07%, maximum drawdown (MDD) -36.8%.
It lost less than Buy&Hold (-2.06%, -51.6%), but it was a long way from the returns I actually felt.

And I ended that post like this.

When and how do I decide the market is overheated, and how do I trade then? When and how do I decide it’s oversold, and how do I trade then?

In practice, I don’t run this strategy purely mechanically.
When the downtrend is strong I widen the gap to 3-4%, and when the market looks too hot I stop buying.
This post is the backtest of that judgment, translated into technical indicators.


First, the Basic Concepts

Before the results, here are the indicators this post uses.
Feel free to skip ahead if you know them.

Concepts ① Trend and position: moving averages, disparity, Bollinger band (%B)
Concepts ① Trend and position: moving averages, disparity, Bollinger band (%B)

A moving average is the average close over the last N days.
The 20-day MA is roughly one month’s average price, the 120-day MA roughly six months’.
A close above the 120-day MA is read as a medium-term uptrend.

Disparity (20-day) is the close divided by the 20-day MA (×100).
100 means price is at the average; 105 means it is 5% above it.
The higher it is, the more price has run up in a short time.

A Bollinger band is drawn two standard deviations above and below the 20-day MA.
Price spends most of its time inside the band.
%B shows where price sits within the band: 0 is the lower edge, 1 the upper edge.
A %B below 0 means price has been pushed under the band, a statistically rare drop.

Concepts ② Volatility and momentum: ATR%, RSI
Concepts ② Volatility and momentum: ATR%, RSI

ATR (Average True Range) is the 14-day average of the daily range (high minus low, including gaps from the prior close).
Divide it by the close and you get ATR%: 3% means “it moves about 3% a day lately.”
For the KOSDAQ 150 the average since 2015 is 2.3%, and the 12-month median is 4.0%. We are in a high-volatility phase.

RSI(14) measures, on a 0-100 scale, how strong the gains of the last 14 days were versus the losses.
Conventionally, above 70 is read as overbought and below 30 as oversold.
(As it turns out, that convention didn’t hold in this backtest. More on that below.)

Performance metrics and validation method
Performance metrics and validation method

The performance metrics, too.
CAGR is the compound annual growth rate; MDD is the largest fall from a prior peak, the worst loss an investor actually had to sit through.
Sharpe is return divided by volatility; Sortino counts only downside volatility as risk. Higher is better for both.
Beta is how much the strategy moves when the underlying ETF moves 1%.
And to avoid numbers that only fit the past, I picked the rules on the earlier period (2021.09-2024.06) and re-checked them on the later one (2024.07-2026.10).


Overbought and Oversold: Which Signals Were Real

Returns over the 20 trading days after each signal: RSI and the upper band were not overheating signals
Returns over the 20 trading days after each signal: RSI and the upper band were not overheating signals

Using 11 years of daily bars since the ETF listed in 2015, I looked at what happened over the 20 trading days after each signal.

  • After RSI above 70 or a break above the upper Bollinger band (%B>1), 20-day returns were +1.3-1.6%, above the +0.6% average. These weren’t overheating signals; they were signs the trend would continue.
  • Only 20-day disparity above 108 was different: -1.5% on average over the next 20 days, with a 43% chance of a -10% drop within those 20 days.
  • The oversold side mostly worked. Disparity below 92, RSI below 30, or -20% from the 60-day high led to +4-7% after 20 days, up 70-77% of the time.
  • But there was also a 14-35% chance of another -10% before the rebound. That’s why you shouldn’t go all in just because it looks oversold.

So I judge overheating with disparity above 105, not RSI, and oversold with %B below 0.


Set the Gap with ATR, Not Gut Feel

Next-day high-low range by today's ATR tercile
Next-day high-low range by today’s ATR tercile

Turn my gut rule of “widen the gap when the selloff is strong” into a number, and you get ATR.
Volatility tends to persist. If ATR is high today, tomorrow is likely to move a lot too.
After days in the top third of ATR, the next day’s high-low range averaged 2.97%; after the bottom third, 1.47%.

So each day, the prior day’s ATR% sets that day’s levels.

  • Buy gap = 1.0 × ATR%
  • Take-profit = 0.6 × ATR% (1.5 × ATR% when the close is above the 120-day MA)

Interestingly, only shrinking the take-profit in high volatility actually hurt performance.
The gap and the take-profit had to widen together.


Results: CAGR 3.1% → 7.0%, MDD -36.8% → -19.3%

I ran 375 settings over five rounds and boiled them down to three profiles.

Profiles compared: Conservative, Balanced, Aggressive
Profiles compared: Conservative, Balanced, Aggressive

Here is the recommended Balanced profile (20 accounts) over the full period (2021.09-2026.10). Buy&Hold in parentheses.

  • CAGR: +6.99% (-2.06%)
  • Total return (ROI): +41.3% (-10.1%)
  • Maximum drawdown (MDD): -19.3% (-51.6%)
  • Sharpe ratio: 0.52 (0.12)
  • Standard deviation (annualized): 15.7% (36.3%)
  • Beta: 0.35 (1.00)
  • Sortino ratio: 0.78 (0.18)

On the test period (2024.07-), which wasn’t used to pick the rules, CAGR held up at 6.4%.
Parking idle cash in a money-market account (assuming 2.5% a year) lifts CAGR to 8.6%.
For smaller drawdowns there’s Conservative (24 accounts, CAGR 6.0%, MDD -15.9%); for more return, Aggressive (16 accounts, CAGR 8.3%, MDD -26.6%).

12-month results by start date, and full-period portfolio value
12-month results by start date, and full-period portfolio value

I also checked whether the start date matters.
Starting every month from October 2021 and running for 12 months each, 49 runs in total,
Balanced’s worst run was -15%, Buy&Hold’s was -36%.
The share of positive runs was 80% vs 61%.
The medians were similar (5.1% vs 5.5%). The difference was how much less bad the bad runs were.

Some things didn’t work.
Widening the gap further on crash days, re-entering quickly after selling out, and keeping part of the position as a buy-and-hold core all hurt performance.


So How Do I Trade It

Trading Guide ① The rules and what they mean
Trading Guide ① The rules and what they mean

There are five rules. Each asks the market a different question.

  1. How much is it swinging? (ATR): Buy when price falls by a normal day’s move. Tight in calm markets, wide in choppy ones, so the accounts don’t run out too fast.
  2. When to sell? (ATR): Sell on a rebound of about 60% of a day’s range, a distance likely reached within a day or two.
  3. Which phase are we in? (120-day MA): Above the six-month average is a medium-term uptrend. Rebounds run longer there, so the take-profit widens to 1.5×ATR.
  4. Has it run too far? (disparity): If price is more than 5% above the 20-day MA, stop new buys. Leave the sell orders on accounts already bought.
  5. Has it fallen too far? (%B): If price is below the lower Bollinger band, buy two accounts’ worth this time. Twenty days later it was up 61% of the time, versus 52% normally.
Trading Guide ② Order levels by ATR and the decline absorbed
Trading Guide ② Order levels by ATR and the decline absorbed

The real point of linking to ATR is in the last column of this table.
With a fixed 1.5% gap, all 20 accounts are full once price is about 25% below the first buy.
In a turbulent phase with ATR at 5%, the gap widens to 5%, and the same 20 accounts can absorb a -62% decline.
The problem I described last time, “all my accounts filled up and I had no more chances,” is solved by volatility itself.

Trading Guide ③ Order steps and the Oct 16 example
Trading Guide ③ Order steps and the Oct 16 example

Using the October 16 close:
ATR is 4.91%, twice the long-run average, so a high-volatility phase: gap 4.9%, take-profit 2.9%.
The close is below the 120-day MA, so no wider take-profit.
Disparity is 93.6 and %B is 0.20, neither overheated nor oversold. Buy one account’s worth, as usual.


Limitations

  • One ETF (KOSDAQ 150) over five years, mostly a sideways-to-down market. In strong rallies it still lags Buy&Hold.
  • The results approximate fills with 5-minute bars, so the actual queue order of limit orders isn’t modeled.
  • Disparity 105 and %B<0 were chosen on the training period, so the test results may be a bit optimistic.
  • In a long decline beyond -30%, the accounts eventually fill up and unrealized losses linger.

What’s Next

The backtesting doesn’t stop here. Next on the list:

  • Download 1-minute/5-minute data for the inverse ETF (KODEX KOSDAQ 150 Futures Inverse) and test switching into it during overheated phases instead of just stopping buys
  • Find the market leaders at each point in time and run the same strategy on those leading stocks instead of the ETF
  • Apply the same rules to other ETFs such as the KOSPI 200, to check whether the numbers only fit the KOSDAQ 150

And starting tomorrow (October 19), I’ll trade with ATR for real.
How my actual KOSDAQ trading account has done over the past two years, and how closely real fills match the backtest from here on, I’ll share separately later.

Turning gut-feel judgment into numbers, some of it matched the textbook and some of it didn’t.
Dropping what didn’t work and keeping what did cut the drawdown nearly in half.
Now it’s time to run real money on those numbers.


Note: This post is a personal record of a backtest and is not a recommendation to buy or sell any product. Past returns do not guarantee future results.

My KOSDAQ 150 “Buy-Sell, Buy-Sell” Trading, Backtested on 5 Years of 5-Minute Bars (Feat. Volatility Harvesting)

🇰🇷 한국어 원문 · Originally written in Korean on Oct 17, 2026. Charts have been re-labeled in English.

I’ve introduced this strategy before.

It’s the KOSDAQ 150 ETF trading I started in November 2024, when the KOSDAQ had fallen into the 600s.

I split my capital across accounts and bought KODEX KOSDAQ 150 every time it fell, then sold every time it rose. I’ve been running this strategy since November 14.

I don’t care whether the index goes down. The core of this strategy is earning from the daily and intraday volatility. The catch is that to do that, you need bullets to buy at the lower prices as the market falls.

In the post where I first announced the strategy, I also explained why the KOSDAQ and not the KOSPI.

The reason is intraday volatility. … That spread is where the money is.

And in my four-month review, I summarized it like this.

From experience, the strengths of this strategy are that you don’t lose money,
and that it returns roughly 10-20% a year.

Last July, I also wrote that I had restarted the same strategy (I call it “4848”).


Why I Ran a Backtest

The basics of the strategy are simple.

You open several accounts and split your capital among them. In my case, 24 accounts.

Buy with the first account. If the price rises 0.5%, sell. If it falls 1.5%, buy with the next account.

If it keeps falling, you keep buying. If it rises, you sell as it rises.

It’s a simple strategy, but you can vary it endlessly.

If you think the downtrend is strong, you can wait for 3% or 4% declines instead of 1.5%.

If you think the market has run up too far, you can stop buying or buy less. You can even buy an inverse ETF.

The trouble is that I still rely on gut feeling for all of this discretion.

So I wanted to work out which signals help most, and what to do under each one.

The strong returns I’ve been getting in the recent volatile market also gave me a good reason to dig deeper into this strategy.

Academics call this kind of strategy volatility harvesting.

It also goes by names like Shannon’s Demon and the rebalancing premium.

The idea is that as long as the price keeps returning to where it was, the swings themselves become profit.

Of course, the story changes if that assumption of returning to where it was breaks down.

For now, let’s see what happens if I follow the basic rules as they are, without any discretion.


Data and Rules

I pulled the data through Daishin Securities’ Creon Plus API.

It’s about five years of 5-minute bars for KODEX KOSDAQ 150 (229200), from September 2, 2021 to October 16, 2026.

(Daishin provides two years of 1-minute bars and five years of 5-minute bars. Among free sources, that’s the longest I could find.)

The rules are as follows.

  1. Split ₩100 million of capital into 24 accounts.
  2. When the price falls 1.5% below the previous purchase price, buy with the next account.
  3. When the price rises 0.5% above an account’s own purchase price, sell that account entirely.
  4. Once every account has been sold, re-enter when the price falls 1.5% from the subsequent high.

I included realistic costs as well.

A 0.015% commission, and fills assumed to be one tick (₩5) worse than the quoted price.

Since these are domestic ETFs, there is no transaction tax and no capital gains tax.


What the Backtested Trades Actually Looked Like

5-minute bars, Mar 3-10, 2026: ▲ buys, ▼ sells, brown lines link each account's buy to its sell
5-minute bars, Mar 3-10, 2026: ▲ buys, ▼ sells, brown lines link each account’s buy to its sell

The chart above covers six trading days, March 3 to 10 this year.

On March 4, the price fell as much as 14.7% intraday from the previous close.

While it fell, the strategy filled up to 14 accounts.

The next day, the open jumped, and the lower accounts were sold all at once.

Over those six days there were 99 buys and 95 sells.

Realized profit was ₩3.78 million, or 3.8% of the ₩100 million total capital.

It shows how hard this strategy works in a “kangaroo” market.

Full period (Sep 2021 - Oct 2026): price and monthly sells, realized profit vs total P&L, accounts held
Full period (Sep 2021 – Oct 2026): price and monthly sells, realized profit vs total P&L, accounts held

Here is the full five years.

There were 1,892 sells, every one of them a +0.5% take-profit.

So realized profit (the blue line) climbs steadily to ₩51 million without a single dip.

But the losses didn’t disappear. They piled up as unrealized losses in the accounts I hadn’t sold.

In the 2022 bear market, total P&L fell as low as -₩20 million,

and as of October 16, unrealized losses stand at ₩34.3 million.

Still, since an entire KOSDAQ ETF, unlike an individual stock, won’t be delisted,

I think of it as a loss I can recover someday.

If anything, in a market like this one, I buy even at the cost of unrealized losses.


What If I Had Just Bought and Held?

Volatility harvesting vs Buy&Hold: portfolio value and drawdown
Volatility harvesting vs Buy&Hold: portfolio value and drawdown

I compared it with buying ₩100 million all at once on day one and simply holding over the same period.

  • CAGR (annualized return): volatility harvesting +3.07% / Buy&Hold -2.06%
  • Cumulative return (ROI): +16.73% / -10.11%
  • Maximum drawdown (MDD): -36.82% / -51.60%
  • Sharpe ratio: 0.25 / 0.12
  • Standard deviation (annualized): 24.80% / 36.26%
  • Beta: 0.61 / 1.00
  • Sortino ratio: 0.37 / 0.18

(Sharpe and Sortino assume a 0% risk-free rate, and I counted zero interest on idle cash.)

The short version: I lost less and made a little more.

In down years like 2022 (-18% vs -36%) and 2024 (-9% vs -19%), losses were about half.

In up years like 2023 (+34% vs +45%) and 2025 (+27% vs +37%), it rose less.

That’s because there are stretches where every account has been sold and I just watch the market climb.


Review: The Numbers Matched What I Lived Through

In my November 2024 review, I wrote this.

The rule is to fill an account every time the price falls 1-2%, but most of my 7 accounts got filled at similar average prices.
Then the price started to fall. … All my accounts were full, so I had no chances left.

The backtest showed exactly the same problem.

If you lay out 24 accounts at 1.5% intervals, you can only withstand a drop of about 29% from the first purchase price.

Over the five years, there were 191 days when all 24 accounts were full.

During those days, no matter how much the price swung, I had no money left to buy with, so I couldn’t earn anything.

I also need to address the gap between my actual returns (6% over four months, about 18% annualized) and the backtest (about 3% a year).

I can think of two reasons.

One, I only got in when I judged the index to be near the bottom.

The backtest ran mechanically for all five years, regardless of timing.

Two, I traded at tighter intervals of 0.5-1%, and I mixed in inverse ETFs.

In the end, it takes the art of managing it.

When and how do I decide the market is overheated, and how do I trade then? When and how do I decide it’s oversold, and how do I trade then?

This is what matters.


What’s Next

From here on, it’s optimization.

I’ll vary the buy interval (1.0-3.0%), the sell threshold (0.5-2.0%), and the number of accounts (12-40).

I’ll pick parameters on the earlier period (2021-2024) and validate them on the later one (2024-2026), to avoid numbers that only fit the past.

I’ll add CMA interest on idle cash.

I’ll also add a filter that adjusts entries based on where the index sits (moving averages, volume profile).

I’m leaving this result as a snapshot,

so I can compare against it after optimizing.

It’s a simple strategy, but taking it apart with numbers turned up more to talk about than I expected.

Let’s take it one step at a time.


Note: This post is a personal record of a backtest and is not a recommendation to buy or sell any product. Past returns do not guarantee future results.