Vol. I · No. 07— · — · —--:--:-- EST
Tanmay DabhadeThe Journal

Build LogJune 4, 2026·9 min read·No. 02

Shorting Pepsi to Buy Coke: My First Market-Neutral Strategy (Day 4)

Day 4 of the quant challenge: I stopped betting on the market going up, built a dollar-neutral pairs trade on PEP/KO, and hit a 1.4 Sharpe, the highest I've ever seen on a backtest. Then I went hunting for the reasons it lies.

For the first three days of this challenge, every algorithm I built quietly assumed the same thing: the market goes up eventually. Trend following, regime filters, the risk-on/risk-off traffic light, all of it was just me trying to be on the right side of a direction. On Day 4 I wanted to throw that assumption out entirely and build something that doesn't care which way the market goes. That meant learning to short, and it meant building my first Statistical Arbitrage (Pairs Trading) system.

This was also the day I hit a number I genuinely did not expect to see this early. More on that in a bit.

First, I Had to Unlearn "Buy Low, Sell High"

Before I could write a line of execution logic, I had to get comfortable with short selling, and it took me longer than I'd like to admit. Humans are wired to buy something cheap and sell it for more. Shorting flips the whole order of operations on its head: you sell first, then buy. Once I wrote it out mechanically, it finally clicked.

Say I want to short 100 shares of Pepsi (PEP):

  1. Borrow. I don't own any PEP. My broker lends me 100 shares out of someone else's account.
  2. Sell. I immediately sell those borrowed shares at $150 each. Now I'm holding $15,000 in cash, but I owe the broker 100 shares of PEP.
  3. Wait. I wait for the price to fall. Say it drops to $100.
  4. Cover. I spend $10,000 buying 100 shares back on the open market.
  5. Return. I hand the 100 shares back to the broker. Debt cleared.
  6. Profit. The $5,000 I have left over is mine.

That's the whole trick: I made money on the stock going down.

But there's a catch that genuinely scared me when I sat with it. When you buy a stock the normal way, the worst case is it goes to zero and you lose 100% of your money. When you short, there is no ceiling on how high the price can climb. If PEP rockets to $1,000, buying back the shares I sold for $15,000 now costs me $100,000. The losses are, mathematically, infinite.

So no, I was not about to go naked-short a single stock and pray.

Why Pairing the Trade Kills the Risk

This is the part that made the whole strategy actually make sense to me. You don't short in isolation. You pair the short with a long.

If I short $50,000 of PEP and buy $50,000 of Coke (KO) at the same time, I'm market neutral. If the entire market falls off a cliff tomorrow, my KO long bleeds, but my PEP short makes almost exactly the same amount back. The market's direction gets cancelled out. The only thing left driving my P&L is whether the historical gap between PEP and KO snaps back to normal.

PEP and KO are basically twins. Two giant beverage companies, same sector, same macro forces pushing on both of them. Most of the time they move in lockstep. When one of them temporarily drifts too far from the other, I bet on the leash pulling them back together: short the expensive one, buy the cheap one, and wait for the rubber band to snap.

I'm not predicting the market. I'm trading the distance between two stocks.

The Execution Logic

In QuantConnect's LEAN engine, going short is almost insultingly simple. The sign of the weight you pass to SetHoldings decides everything: a positive weight buys, a negative weight borrows and sells. So one pair trade is just two calls with opposite signs:

  • SetHoldings("PEP", 0.5) → buy PEP (long).
  • SetHoldings("KO", -0.5) → borrow and sell KO (short).

I track the spread between the two stocks as a Z-Score, basically how many standard deviations the current gap sits away from its recent average. When the Z-Score blows past +2.0, PEP is unusually expensive relative to KO, so I short PEP and buy KO. When it drops below -2.0, I do the opposite. Then I sit on the position until the Z-Score crawls back toward 0 and the relationship has reverted to its mean.

Here's the entry and exit logic I bolted onto the bottom of my Day 4 architecture:

    # ... (Z-Score calculation logic lives above this) ...
    # Assume z_score is calculated and ready.

    # --- PORTFOLIO STATE ---
    # Check if we're already in a trade so we don't spam orders every minute.
    is_invested = self.Portfolio[self.asset1].Invested or self.Portfolio[self.asset2].Invested

    # --- ENTRY: the arbitrage ---
    if not is_invested:

        # SCENARIO A: PEP overvalued relative to KO
        if z_score > 2.0:
            self.Debug(f"[{self.Time}] Z > 2.0. Shorting PEP, buying KO.")
            # -50% PEP (short) + 50% KO (long) = dollar-neutral.
            self.SetHoldings(self.asset1, -0.5)
            self.SetHoldings(self.asset2, 0.5)

        # SCENARIO B: KO overvalued relative to PEP
        elif z_score < -2.0:
            self.Debug(f"[{self.Time}] Z < -2.0. Buying PEP, shorting KO.")
            self.SetHoldings(self.asset1, 0.5)
            self.SetHoldings(self.asset2, -0.5)

    # --- EXIT: mean reversion ---
    else:
        # Once the Z-Score collapses back near 0, the leash has snapped back.
        if abs(z_score) < 0.5:
            self.Debug(f"[{self.Time}] Spread reverted (Z={round(z_score, 2)}). Liquidating pair.")
            self.Liquidate(self.asset1)
            self.Liquidate(self.asset2)

The -0.5 and 0.5 are the whole game. On a $100,000 account, QuantConnect shorts exactly $50,000 of PEP and buys exactly $50,000 of KO. Because the dollar amounts are perfectly matched (dollar-neutral), a 1% move in the S&P 500 doesn't touch my portfolio's value at all. The market can do whatever it wants. I'm just waiting for the gap to close.

The Number I Didn't Expect

I ran the backtest over all of 2020, a year that included a 30%+ market crash, and the report came back with a Sharpe Ratio of 1.42.

I've never gotten anywhere near that. For context: the S&P 500 historically sits around a Sharpe of 0.5. The top-tier quant funds everyone name-drops, Renaissance and Citadel, generally target somewhere between 1.5 and 2.5 for their core market-neutral books. I had accidentally built a baseline that was knocking on the door of that range, on Day 4, with two beverage stocks.

BacktestJan 2020 – Jan 2021
$115,432+15.43%
StrategySPY buy & hold
Net Profit
15.432%
CAGR
15.402%
Sharpe Ratio
1.419
Max Drawdown
3.500%
Win Rate
72%
Profit-Loss Ratio
0.78
Beta
0.076
Total Orders
36

Once I stopped grinning, I dug into the actual report to understand why it looked so good, and where it was lying to me.

  • Beta of 0.0757. This was the metric that mattered most. A beta near zero means the portfolio is almost completely decoupled from the S&P 500. While the rest of the world was panicking about market direction during the COVID crash, my algorithm genuinely did not care.
  • Max drawdown of 3.5%. For the entire year of 2020. The dollar-neutral long/short pair hedged the panic so cleanly that my capital barely flinched.
  • 72.2% win rate. 13 winners out of 18 trades. The mean-reversion logic worked: when the leash stretched to a Z-Score anomaly, it reliably snapped back.
  • Profit factor of 1.99. Roughly $2 made for every $1 lost.
  • Trades lasted ~15 days on average. My Z-Score threshold was catching medium-term divergences instead of getting chopped up in intraday noise.

I ended the year at $115,432, a 15.4% return, by taking a fraction of the risk a normal index investor was carrying.

Why the Sharpe exploded

The Sharpe Ratio is just (Return − Risk-Free Rate) / Volatility. In my Day 2 and Day 3 algorithms, I was holding SPY, so when the market had a violent day, my portfolio had a violent day, and the denominator was huge. By going dollar-neutral, I mathematically erased the market's volatility from my equity curve. If the market gapped down 5% at the open, KO lost 5% and the PEP short made 5%. Net exposure to the panic: $0. A smooth equity curve means a tiny denominator, and dividing a decent return by a tiny volatility number is exactly how you manufacture a big Sharpe.

The Two Traps Hiding Behind That 1.4

A 1.4 Sharpe on a backtest is a masterpiece for Day 4. But I've already learned that pretty backtests lie, so I went looking for the reasons this one would fall apart in production. There are two big ones.

Trap 1: The leash actually snapping

My algorithm assumes PEP and KO will always pull back together. But what if Pepsi's CEO announces they're buying a massive snack company and fundamentally changing the business? The two stocks stop being twins. The Z-Score hits +2.0, I short PEP, and instead of reverting, it climbs to +3.0, +5.0, +10.0. The leash didn't stretch. It snapped. And because short losses have no ceiling, that's how an account gets wiped out.

The real fix isn't to assume they're twins forever. It's to run a live statistical test, the Augmented Dickey-Fuller (ADF) test, inside the algorithm to keep proving the leash is still mathematically intact before I'm allowed to put on a trade. More on that below.

Trap 2: Death by a thousand fees

Trend-following algorithms trade maybe ten times a year. Stat-arb algorithms want to trade constantly, and every crossing of the Z-Score line costs a commission plus the bid-ask spread. If I lowered my entry threshold to 1.0 or 1.5 to trade more often, the profit from each tiny reversion wouldn't even cover the cost of the round trip. This is exactly why I wait for an extreme, a Z-Score of 2.0, before entering: the expected profit has to clearly outpace the friction.

The Two Questions That Actually Taught Me Something

Sitting with the report, two things bugged me, and chasing them down was where the real learning happened.

"Why did I only make $15k? Is it the 50% allocation?"

My first instinct was that I'd capped my upside by only allocating 50% to each leg. That's not it. The ceiling is structural: I'm not making money on the stocks going up. I'm making money on the gap between them closing.

When you buy Tesla, your profit ceiling is the sky: it can run 50%, 700%, whatever. In stat-arb, I'm trading the Z-Score of a spread. If PEP temporarily floats 3% above KO, I capture that 3% when they reconverge, minus fees. Spread movements are tiny by nature. Pulling a 15% annual return out of stacking up little 2–3% micro-reversions, without ever needing the broader market to go up, turned out to be the whole point, not a disappointment.

And there's a quant secret buried in that 3.5% drawdown. When your risk is that microscopic, you can safely apply leverage. Retail thinks of leverage as a way to gamble harder. Quants treat it as a tool to scale a safe, low-volatility edge. If I apply 3x leverage to this exact PEP/KO strategy:

    self.SetHoldings(self.asset1, -1.5)
    self.SetHoldings(self.asset2, 1.5)

my 15% return scales toward 45%, and my 3.5% drawdown only grows to around 10.5%, still far safer than the S&P 500's 33% crash that same year. You don't apply leverage to a risky strategy. You apply it to a boring, bulletproof one. (The mechanical catch is the margin call: if the spread blows out instead of reverting, a leveraged position can drop below the broker's maintenance threshold and get force-liquidated at the worst possible moment. So leverage only belongs on strategies with tiny drawdowns in the first place.)

"Would a longer lookback than 30 days improve the results?"

Short answer: usually no, and it's a trap I almost walked straight into.

My Z-Score uses a 30-day lookback: today's gap compared to the last month's average. Stretch that to 90 days and the algorithm becomes slow and stubborn: it only reacts to massive macro divergences, trades maybe three times a year, and takes three full months to notice when a leash has permanently broken, keeping me trapped in a losing short. Shrink it to 10 days and it becomes hyperactive, trading on pure noise and bleeding out through fees.

Here's the part I had to be honest with myself about: nudging that number from 30 to 32 just to squeeze an extra 1% out of the backtest is curve fitting, the deadliest sin in quant research. You tune the parameters so perfectly to the past that the strategy shatters the instant it touches live data. The professional move isn't to guess a better lookback. It's to compute the optimal window dynamically instead of hardcoding a lucky guess.

The Thing I Noticed in the Equity Curve

When I actually looked at the curve, the algorithm went quiet after May 2020: flat, sitting in cash for the back half of the year. My first reaction was that something had broken. It hadn't.

Think about the macro backdrop. March through May was pure COVID panic: institutions liquidating everything, mispricings everywhere, PEP and KO getting thrown around violently. That chaos is exactly what stretched the leash far enough to trigger Z-Scores of 2.0 and hand me trades. Then the Fed stepped in, the panic drained out, and from June onward the market ground slowly upward with everything moving in near-perfect correlation. PEP and KO went back to lockstep. The Z-Score probably never left the −1.0 to +1.0 band again.

In traditional investing, making nothing for six months feels like failure. In quant, sitting in cash because your edge isn't present is the system working correctly: it refused to force a bad trade and protected my capital. The downside is capital efficiency: a fund that does nothing for six months watches its clients walk. So the answer isn't to lower my standards on the PEP/KO pair. It's to go find other pairs that are stretching while these two are asleep.

Where Day 4 Is Heading: The ADF Test and the Scanner

That's the natural next evolution, and it's a two-step jump.

First, the ADF test to fix Trap 1. Before trusting any pair, I run the Augmented Dickey-Fuller test on the spread and get back a p-value. If it's below 0.05, the math says the leash is real and the pair is genuinely cointegrated, safe to trade. If it's above 0.05, the relationship is an illusion (correlation that happens to look like a leash), and I don't touch it even if the Z-Score screams 2.0, because the spread might never come back.

Second, the scanner to fix the capital-efficiency problem. Hedge funds don't hand-pick PEP and KO. They point a scanner at a whole sector, pair every stock with every other stock, and run the ADF test across all the combinations to surface the tightest mathematical leashes, sometimes between two companies you'd never think to pair by hand. The catch is compute: scan all 500 names in the S&P and you're looking at 500 × 499 / 2 = 124,750 tests. Run that every minute inside OnData and the engine just dies. The institutional pattern is to separate research from execution: let a scheduled monthly event do the heavy ADF scan and lock in the best pair, then let the lightweight OnData loop track only that pair's Z-Score until the next scan.

I've got the scanner architecture roughed out, and I've already run a first version of it: an ADF scanner that hunts cointegrated pairs across the banking sector (JPM, BAC, C, WFC, GS, MS, PNC, USB and friends), locks onto the tightest leash each month, and trades it with leverage. Here's what that looked like over the same 2020 window:

BacktestJan 2020 – Jan 2021
$140,082+40.08%
StrategySPY buy & hold
Net Profit
40.082%
CAGR
39.996%
Sharpe Ratio
1.44
Max Drawdown
15.500%
Win Rate
67%
Profit-Loss Ratio
1.00
Beta
0.047
Total Orders
60

The shape is completely different from the hand-picked PEP/KO pair. It trades far more often (60 orders vs. 36), digs up pairs I'd never have put together by hand, and squeezes out a ~40% return, but it pays for that with a chunkier 15.5% drawdown when one of those bank "leashes" stretched hard during the autumn rotation. Same 1.4-ish Sharpe, very different ride. That trade-off, more opportunities versus messier risk, is exactly what Day 5 is about taming.

What's Next

Four days in, I've gone from lagging moving averages to a dollar-neutral arbitrage engine that posted an institutional-shaped Sharpe and survived a generational crash with a 3.5% drawdown. But I also watched it lie to me in two different ways, and the most important skill I'm building isn't writing the strategy. It's interrogating the backtest until I find where it's wrong.

Day 5 is the ADF test and the pair scanner: teaching the algorithm to prove the leash is real before risking a dollar, and to go hunting for hidden twins on its own when its favorite pair goes quiet.

If you're on your own quant journey, I'd love to hear how you handle cointegration breakdown in live trading. That's the trap I'm most paranoid about right now.

— ◆ —
TD
Tanmay Dabhade

Systems engineer and CS student at Michigan State ('27). Building backend systems, data pipelines, and full-stack tools — and writing about the messy middle.